diff options
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r-- | sound/usb/usbaudio.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index c7b902358b7b..8db0374e10d5 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -1083,6 +1083,8 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri } else urb_packs = 1; urb_packs *= packs_per_ms; + if (subs->syncpipe) + urb_packs = min(urb_packs, 1U << subs->syncinterval); /* decide how many packets to be used */ if (is_playback) { @@ -2124,8 +2126,8 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s fp = list_entry(p, struct audioformat, list); snd_iprintf(buffer, " Interface %d\n", fp->iface); snd_iprintf(buffer, " Altset %d\n", fp->altsetting); - snd_iprintf(buffer, " Format: %#x (%d bits)\n", - fp->format, snd_pcm_format_width(fp->format)); + snd_iprintf(buffer, " Format: %s\n", + snd_pcm_format_name(fp->format)); snd_iprintf(buffer, " Channels: %d\n", fp->channels); snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", fp->endpoint & USB_ENDPOINT_NUMBER_MASK, @@ -2661,7 +2663,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) struct usb_interface_descriptor *altsd; int i, altno, err, stream; int format; - struct audioformat *fp; + struct audioformat *fp = NULL; unsigned char *fmt, *csep; int num; @@ -2734,6 +2736,18 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) continue; } + /* + * Blue Microphones workaround: The last altsetting is identical + * with the previous one, except for a larger packet size, but + * is actually a mislabeled two-channel setting; ignore it. + */ + if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && + fp && fp->altsetting == 1 && fp->channels == 1 && + fp->format == SNDRV_PCM_FORMAT_S16_LE && + le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == + fp->maxpacksize * 2) + continue; + csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); /* Creamware Noah has this descriptor after the 2nd endpoint */ if (!csep && altsd->bNumEndpoints >= 2) |