All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Przemysław Rudy" <prudy1@o2.pl>
To: Takashi Iwai <tiwai@suse.de>
Cc: alsa-devel@alsa-project.org
Subject: Re: [PATCH - microII 1/1] ALSA: usb-audio: Add Audio Advantage Micro II
Date: Fri, 28 Jun 2013 13:07:22 +0200	[thread overview]
Message-ID: <51CD6E6A.1030805@o2.pl> (raw)
In-Reply-To: <s5hwqpemtqa.wl%tiwai@suse.de>

Sure Takashi, here you are:

------------------
This patch is adding extensive support (beside standard usb audio class)
for Audio Advantage Micro II usb sound card.
Features included:
- Access to AES bits (so now sending the IEC61937 compliant stream is
possible).
- Mixer SPDIF control added to turn on/off the optical transmitter.
------------------

Best,
Przemek

On 2013-06-28 12:10, Takashi Iwai wrote:
> At Thu, 27 Jun 2013 23:52:33 +0200,
> Przemek Rudy wrote:
>>
>>
>> Signed-off-by: Przemek Rudy <prudy1@o2.pl>
> 
> The changes look OK to me, but the patch description is completely
> missing.  Please give a bit more details in the patch description
> part.
> 
> 
> thanks,
> 
> Takashi
> 
>> diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
>> index ebe9144..d42a584 100644
>> --- a/sound/usb/mixer_quirks.c
>> +++ b/sound/usb/mixer_quirks.c
>> @@ -9,6 +9,8 @@
>>   *	    Alan Cox (alan@lxorguk.ukuu.org.uk)
>>   *	    Thomas Sailer (sailer@ife.ee.ethz.ch)
>>   *
>> + *   Audio Advantage Micro II support added by:
>> + *	    Przemek Rudy (prudy1@o2.pl)
>>   *
>>   *   This program is free software; you can redistribute it and/or modify
>>   *   it under the terms of the GNU General Public License as published by
>> @@ -30,6 +32,7 @@
>>  #include <linux/usb.h>
>>  #include <linux/usb/audio.h>
>>  
>> +#include <sound/asoundef.h>
>>  #include <sound/core.h>
>>  #include <sound/control.h>
>>  #include <sound/hwdep.h>
>> @@ -1315,6 +1318,211 @@ static struct std_mono_table ebox44_table[] = {
>>  	{}
>>  };
>>  
>> +/* Audio Advantage Micro II findings:
>> + *
>> + * Mapping spdif AES bits to vendor register.bit:
>> + * AES0: [0 0 0 0 2.3 2.2 2.1 2.0] - default 0x00
>> + * AES1: [3.3 3.2.3.1.3.0 2.7 2.6 2.5 2.4] - default: 0x01
>> + * AES2: [0 0 0 0 0 0 0 0]
>> + * AES3: [0 0 0 0 0 0 x 0] - 'x' bit is set basing on standard usb request
>> + *                           (UAC_EP_CS_ATTR_SAMPLE_RATE) for Audio Devices
>> + *
>> + * power on values:
>> + * r2: 0x10
>> + * r3: 0x20 (b7 is zeroed just before playback (except IEC61937) and set
>> + *           just after it to 0xa0, presumably it disables/mutes some analog
>> + *           parts when there is no audio.)
>> + * r9: 0x28
>> + *
>> + * Optical transmitter on/off:
>> + * vendor register.bit: 9.1
>> + * 0 - on (0x28 register value)
>> + * 1 - off (0x2a register value)
>> + *
>> + */
>> +static int snd_microii_spdif_info(struct snd_kcontrol *kcontrol,
>> +	struct snd_ctl_elem_info *uinfo)
>> +{
>> +	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
>> +	uinfo->count = 1;
>> +	return 0;
>> +}
>> +
>> +static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
>> +	struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
>> +	int err;
>> +	struct usb_interface *iface;
>> +	struct usb_host_interface *alts;
>> +	unsigned int ep;
>> +	unsigned char data[3];
>> +	int rate;
>> +
>> +	ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff;
>> +	ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff;
>> +	ucontrol->value.iec958.status[2] = 0x00;
>> +
>> +	/* use known values for that card: interface#1 altsetting#1 */
>> +	iface = usb_ifnum_to_if(mixer->chip->dev, 1);
>> +	alts = &iface->altsetting[1];
>> +	ep = get_endpoint(alts, 0)->bEndpointAddress;
>> +
>> +	err = snd_usb_ctl_msg(mixer->chip->dev,
>> +			usb_rcvctrlpipe(mixer->chip->dev, 0),
>> +			UAC_GET_CUR,
>> +			USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
>> +			UAC_EP_CS_ATTR_SAMPLE_RATE << 8,
>> +			ep,
>> +			data,
>> +			sizeof(data));
>> +	if (err < 0)
>> +		goto end;
>> +
>> +	rate = data[0] | (data[1] << 8) | (data[2] << 16);
>> +	ucontrol->value.iec958.status[3] = (rate == 48000) ?
>> +			IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100;
>> +
>> +	err = 0;
>> +end:
>> +	return err;
>> +}
>> +
>> +static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol,
>> +	struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
>> +	int err;
>> +	u8 reg;
>> +	unsigned long priv_backup = kcontrol->private_value;
>> +
>> +	reg = ((ucontrol->value.iec958.status[1] & 0x0f) << 4) |
>> +			(ucontrol->value.iec958.status[0] & 0x0f);
>> +	err = snd_usb_ctl_msg(mixer->chip->dev,
>> +			usb_sndctrlpipe(mixer->chip->dev, 0),
>> +			UAC_SET_CUR,
>> +			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
>> +			reg,
>> +			2,
>> +			NULL,
>> +			0);
>> +	if (err < 0)
>> +		goto end;
>> +
>> +	kcontrol->private_value &= 0xfffff0f0;
>> +	kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0x0f) << 8;
>> +	kcontrol->private_value |= (ucontrol->value.iec958.status[0] & 0x0f);
>> +
>> +	reg = (ucontrol->value.iec958.status[0] & IEC958_AES0_NONAUDIO) ?
>> +			0xa0 : 0x20;
>> +	reg |= (ucontrol->value.iec958.status[1] >> 4) & 0x0f;
>> +	err = snd_usb_ctl_msg(mixer->chip->dev,
>> +			usb_sndctrlpipe(mixer->chip->dev, 0),
>> +			UAC_SET_CUR,
>> +			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
>> +			reg,
>> +			3,
>> +			NULL,
>> +			0);
>> +	if (err < 0)
>> +		goto end;
>> +
>> +	kcontrol->private_value &= 0xffff0fff;
>> +	kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0xf0) << 8;
>> +
>> +	/* The frequency bits in AES3 cannot be set via register access. */
>> +
>> +	/* Silently ignore any bits from the request that cannot be set. */
>> +
>> +	err = (priv_backup != kcontrol->private_value);
>> +end:
>> +	return err;
>> +}
>> +
>> +static int snd_microii_spdif_mask_get(struct snd_kcontrol *kcontrol,
>> +	struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	ucontrol->value.iec958.status[0] = 0x0f;
>> +	ucontrol->value.iec958.status[1] = 0xff;
>> +	ucontrol->value.iec958.status[2] = 0x00;
>> +	ucontrol->value.iec958.status[3] = 0x00;
>> +
>> +	return 0;
>> +}
>> +
>> +static int snd_microii_spdif_switch_get(struct snd_kcontrol *kcontrol,
>> +	struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	ucontrol->value.integer.value[0] = !(kcontrol->private_value & 0x02);
>> +
>> +	return 0;
>> +}
>> +
>> +static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol,
>> +	struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
>> +	int err;
>> +	u8 reg = ucontrol->value.integer.value[0] ? 0x28 : 0x2a;
>> +
>> +	err = snd_usb_ctl_msg(mixer->chip->dev,
>> +			usb_sndctrlpipe(mixer->chip->dev, 0),
>> +			UAC_SET_CUR,
>> +			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
>> +			reg,
>> +			9,
>> +			NULL,
>> +			0);
>> +
>> +	if (!err) {
>> +		err = (reg != (kcontrol->private_value & 0x0ff));
>> +		if (err)
>> +			kcontrol->private_value = reg;
>> +	}
>> +
>> +	return err;
>> +}
>> +
>> +static struct snd_kcontrol_new snd_microii_mixer_spdif[] = {
>> +	{
>> +		.iface =    SNDRV_CTL_ELEM_IFACE_PCM,
>> +		.name =     SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
>> +		.info =     snd_microii_spdif_info,
>> +		.get =      snd_microii_spdif_default_get,
>> +		.put =      snd_microii_spdif_default_put,
>> +		.private_value = 0x00000100UL,/* reset value */
>> +	},
>> +	{
>> +		.access =   SNDRV_CTL_ELEM_ACCESS_READ,
>> +		.iface =    SNDRV_CTL_ELEM_IFACE_PCM,
>> +		.name =     SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
>> +		.info =     snd_microii_spdif_info,
>> +		.get =      snd_microii_spdif_mask_get,
>> +	},
>> +	{
>> +		.iface =    SNDRV_CTL_ELEM_IFACE_MIXER,
>> +		.name =     SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
>> +		.info =     snd_ctl_boolean_mono_info,
>> +		.get =      snd_microii_spdif_switch_get,
>> +		.put =      snd_microii_spdif_switch_put,
>> +		.private_value = 0x00000028UL,/* reset value */
>> +	}
>> +};
>> +
>> +static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
>> +{
>> +	int err, i;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(snd_microii_mixer_spdif); ++i) {
>> +		err = snd_ctl_add(mixer->chip->card,
>> +			snd_ctl_new1(&snd_microii_mixer_spdif[i], mixer));
>> +		if (err < 0)
>> +			return err;
>> +	}
>> +
>> +	return err;
>> +}
>> +
>>  int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
>>  {
>>  	int err = 0;
>> @@ -1353,6 +1561,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
>>  		err = snd_xonar_u1_controls_create(mixer);
>>  		break;
>>  
>> +	case USB_ID(0x0d8c, 0x0103): /* Audio Advantage Micro II */
>> +		err = snd_microii_controls_create(mixer);
>> +		break;
>> +
>>  	case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
>>  		err = snd_nativeinstruments_create_mixer(mixer,
>>  				snd_nativeinstruments_ta6_mixers,
>> diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
>> index 8b75bcf..2be7410 100644
>> --- a/sound/usb/quirks-table.h
>> +++ b/sound/usb/quirks-table.h
>> @@ -3434,4 +3434,16 @@ YAMAHA_DEVICE(0x7010, "UB99"),
>>  	}
>>  },
>>  
>> +{
>> +	/*
>> +	 * The original product_name is "USB Sound Device", however this name
>> +	 * is also used by the CM106 based cards, so make it unique.
>> +	 */
>> +	USB_DEVICE(0x0d8c, 0x0103),
>> +	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
>> +		.product_name = "Audio Advantage MicroII",
>> +		.ifnum = QUIRK_NO_INTERFACE
>> +	}
>> +},
>> +
>>  #undef USB_DEVICE_VENDOR_SPEC
>> -- 
>> 1.8.1.4
>>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

  reply	other threads:[~2013-06-28 11:07 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-27 21:52 [PATCH - microII 1/1] ALSA: usb-audio: Add Audio Advantage Micro II Przemek Rudy
2013-06-27 21:52 ` [PATCH - microII 1/1] conf/cards: add " Przemek Rudy
2013-06-28 10:11   ` Takashi Iwai
2013-06-28 11:13     ` Przemysław Rudy
2013-07-29 18:29       ` Przemek Rudy
2013-07-30  5:56         ` Takashi Iwai
2013-06-28 10:10 ` [PATCH - microII 1/1] ALSA: usb-audio: Add " Takashi Iwai
2013-06-28 11:07   ` Przemysław Rudy [this message]
2013-06-28 11:39     ` Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51CD6E6A.1030805@o2.pl \
    --to=prudy1@o2.pl \
    --cc=alsa-devel@alsa-project.org \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.