Skip to content

Commit

Permalink
ALSA: usb-audio - Fix the missing volume quirks at delayed init
Browse files Browse the repository at this point in the history
commit dcaaf9f upstream.

In the recent usb-audio driver, the initialization of volume ranges
may be delayed when the device doesn't respond well at the probing time.
But the volume quirks for certain devices are applied only in
mixer_ctl_feature_info() thus only at the very first probe and will be
missing when the volume range is initialized later.

This patch moves the volume quirk code to be always called from the
volume-range extraction (get_min_max()), so that the quirks are properly
applied in the later init time.

Reported-and-tested-by: Alexey Fisher <bug-track@fisher-privat.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Takashi Iwai authored and Greg Kroah-Hartman committed Nov 21, 2011
1 parent 3485c04 commit f80f338
Showing 1 changed file with 59 additions and 50 deletions.
109 changes: 59 additions & 50 deletions sound/usb/mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,10 +765,60 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
* interface to ALSA control for feature/mixer units
*/

/* volume control quirks */
static void volume_control_quirks(struct usb_mixer_elem_info *cval,
struct snd_kcontrol *kctl)
{
switch (cval->mixer->chip->usb_id) {
case USB_ID(0x0471, 0x0101):
case USB_ID(0x0471, 0x0104):
case USB_ID(0x0471, 0x0105):
case USB_ID(0x0672, 0x1041):
/* quirk for UDA1321/N101.
* note that detection between firmware 2.1.1.7 (N101)
* and later 2.1.1.21 is not very clear from datasheets.
* I hope that the min value is -15360 for newer firmware --jk
*/
if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
cval->min == -15616) {
snd_printk(KERN_INFO
"set volume quirk for UDA1321/N101 chip\n");
cval->max = -256;
}
break;

case USB_ID(0x046d, 0x09a4):
if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
snd_printk(KERN_INFO
"set volume quirk for QuickCam E3500\n");
cval->min = 6080;
cval->max = 8768;
cval->res = 192;
}
break;

case USB_ID(0x046d, 0x0808):
case USB_ID(0x046d, 0x0809):
case USB_ID(0x046d, 0x0991):
/* Most audio usb devices lie about volume resolution.
* Most Logitech webcams have res = 384.
* Proboly there is some logitech magic behind this number --fishor
*/
if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
snd_printk(KERN_INFO
"set resolution quirk: cval->res = 384\n");
cval->res = 384;
}
break;

}
}

/*
* retrieve the minimum and maximum values for the specified control
*/
static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
int default_min, struct snd_kcontrol *kctl)
{
/* for failsafe */
cval->min = default_min;
Expand Down Expand Up @@ -844,6 +894,9 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
cval->initialized = 1;
}

if (kctl)
volume_control_quirks(cval, kctl);

/* USB descriptions contain the dB scale in 1/256 dB unit
* while ALSA TLV contains in 1/100 dB unit
*/
Expand All @@ -864,6 +917,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
return 0;
}

#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)

/* get a feature/mixer unit info */
static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Expand All @@ -882,7 +936,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
uinfo->value.integer.max = 1;
} else {
if (!cval->initialized) {
get_min_max(cval, 0);
get_min_max_with_quirks(cval, 0, kcontrol);
if (cval->initialized && cval->dBmin >= cval->dBmax) {
kcontrol->vd[0].access &=
~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
Expand Down Expand Up @@ -1045,9 +1099,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
cval->ch_readonly = readonly_mask;
}

/* get min/max values */
get_min_max(cval, 0);

/* if all channels in the mask are marked read-only, make the control
* read-only. set_cur_mix_value() will check the mask again and won't
* issue write commands to read-only channels. */
Expand All @@ -1069,6 +1120,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
len = snd_usb_copy_string_desc(state, nameid,
kctl->id.name, sizeof(kctl->id.name));

/* get min/max values */
get_min_max_with_quirks(cval, 0, kctl);

switch (control) {
case UAC_FU_MUTE:
case UAC_FU_VOLUME:
Expand Down Expand Up @@ -1118,51 +1172,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
break;
}

/* volume control quirks */
switch (state->chip->usb_id) {
case USB_ID(0x0471, 0x0101):
case USB_ID(0x0471, 0x0104):
case USB_ID(0x0471, 0x0105):
case USB_ID(0x0672, 0x1041):
/* quirk for UDA1321/N101.
* note that detection between firmware 2.1.1.7 (N101)
* and later 2.1.1.21 is not very clear from datasheets.
* I hope that the min value is -15360 for newer firmware --jk
*/
if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
cval->min == -15616) {
snd_printk(KERN_INFO
"set volume quirk for UDA1321/N101 chip\n");
cval->max = -256;
}
break;

case USB_ID(0x046d, 0x09a4):
if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
snd_printk(KERN_INFO
"set volume quirk for QuickCam E3500\n");
cval->min = 6080;
cval->max = 8768;
cval->res = 192;
}
break;

case USB_ID(0x046d, 0x0808):
case USB_ID(0x046d, 0x0809):
case USB_ID(0x046d, 0x0991):
/* Most audio usb devices lie about volume resolution.
* Most Logitech webcams have res = 384.
* Proboly there is some logitech magic behind this number --fishor
*/
if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
snd_printk(KERN_INFO
"set resolution quirk: cval->res = 384\n");
cval->res = 384;
}
break;

}

range = (cval->max - cval->min) / cval->res;
/* Are there devices with volume range more than 255? I use a bit more
* to be sure. 384 is a resolution magic number found on Logitech
Expand Down

0 comments on commit f80f338

Please sign in to comment.