aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usbaudio.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-07-13 07:21:58 -0400
committerTakashi Iwai <tiwai@suse.de>2009-07-15 05:55:00 -0400
commit8886f33f25083a47d5fa24ad7b57bb708c5c5403 (patch)
tree6f6e50f07811c01cd7ec469223ba70fb71ae50f6 /sound/usb/usbaudio.c
parent6847e154e3cd74fca6084124c097980a7634285a (diff)
sound: usb-audio: add workaround for Blue Microphones devices
Blue Microphones USB devices have an alternate setting that sends two channels of data to the computer. Unfortunately, the descriptors of that altsetting have a wrong channel setting, which means that any recorded data from such a device has twice the sample rate from what would be expected. This patch adds a workaround to ignore that altsetting. Since these devices have only one actual channel, no data is lost. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Cc: <stable@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r--sound/usb/usbaudio.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c7b902358b7b..44b9cdc8a83b 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2661,7 +2661,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2661 struct usb_interface_descriptor *altsd; 2661 struct usb_interface_descriptor *altsd;
2662 int i, altno, err, stream; 2662 int i, altno, err, stream;
2663 int format; 2663 int format;
2664 struct audioformat *fp; 2664 struct audioformat *fp = NULL;
2665 unsigned char *fmt, *csep; 2665 unsigned char *fmt, *csep;
2666 int num; 2666 int num;
2667 2667
@@ -2734,6 +2734,18 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2734 continue; 2734 continue;
2735 } 2735 }
2736 2736
2737 /*
2738 * Blue Microphones workaround: The last altsetting is identical
2739 * with the previous one, except for a larger packet size, but
2740 * is actually a mislabeled two-channel setting; ignore it.
2741 */
2742 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
2743 fp && fp->altsetting == 1 && fp->channels == 1 &&
2744 fp->format == SNDRV_PCM_FORMAT_S16_LE &&
2745 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
2746 fp->maxpacksize * 2)
2747 continue;
2748
2737 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); 2749 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
2738 /* Creamware Noah has this descriptor after the 2nd endpoint */ 2750 /* Creamware Noah has this descriptor after the 2nd endpoint */
2739 if (!csep && altsd->bNumEndpoints >= 2) 2751 if (!csep && altsd->bNumEndpoints >= 2)