Clemens,
On Tue, Nov 17, 2009 at 10:04, Clemens Ladisch clemens@ladisch.de wrote:
Javier Kohen wrote:
I've written the attached patch to disable the master volume control in this chipset. The datasheet [1] documents two independent channel volume controls, one master mute control and one master volume control. However, at least on my device (a Fubar USB DAC), the master volume control always returns USB stalls when queried for any of its parameters (min/max/res/cur).
I'd guess that Windows ignores the master volume when it finds channel volume controls, so this function was never actually tested.
However, it seems that either the USB specs are wrong,
They are abominations written by committees.
or my USB hub or the card are buggy.
Your hub is certainly buggy ...
the PCM2702 and my motherboard don't interact well. After a while the sound is degraded, first into a hiss, then into pure noise.
... the card too.
Your patch looks good; please provide a log message and a Signed-off-by tag.
Thanks for the prompt review!
Disable the master volume controlĀ in the PCM2702 chipset.
The datasheet documents two independent channel volume controls, one master mute control and one master volume control. All controls are fully functional except for the master volume control, which returns USB stalls on all GET requests.
Signed-off-by: Javier Kohen jkohen@users.sourceforge.net --- diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 9efcfd0..406315e 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c @@ -1071,6 +1071,16 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig channels = (ftr[0] - 7) / csize - 1;
master_bits = snd_usb_combine_bytes(ftr + 6, csize); + /* master configuration quirks */ + switch (state->chip->usb_id) { + case USB_ID(0x08bb, 0x2702): + snd_printk(KERN_INFO + "master volume quirk for PCM2702 chip\n"); + /* disable non-functional volume control */ + master_bits &= ~(1 << (USB_FEATURE_VOLUME - 1)); + break; + + } if (channels > 0) first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize); else