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 | |||
1083 | } else | 1083 | } else |
1084 | urb_packs = 1; | 1084 | urb_packs = 1; |
1085 | urb_packs *= packs_per_ms; | 1085 | urb_packs *= packs_per_ms; |
1086 | if (subs->syncpipe) | ||
1087 | urb_packs = min(urb_packs, 1U << subs->syncinterval); | ||
1086 | 1088 | ||
1087 | /* decide how many packets to be used */ | 1089 | /* decide how many packets to be used */ |
1088 | if (is_playback) { | 1090 | if (is_playback) { |
@@ -2124,8 +2126,8 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s | |||
2124 | fp = list_entry(p, struct audioformat, list); | 2126 | fp = list_entry(p, struct audioformat, list); |
2125 | snd_iprintf(buffer, " Interface %d\n", fp->iface); | 2127 | snd_iprintf(buffer, " Interface %d\n", fp->iface); |
2126 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); | 2128 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); |
2127 | snd_iprintf(buffer, " Format: %#x (%d bits)\n", | 2129 | snd_iprintf(buffer, " Format: %s\n", |
2128 | fp->format, snd_pcm_format_width(fp->format)); | 2130 | snd_pcm_format_name(fp->format)); |
2129 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); | 2131 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); |
2130 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", | 2132 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", |
2131 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, | 2133 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, |
@@ -2661,7 +2663,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2661 | struct usb_interface_descriptor *altsd; | 2663 | struct usb_interface_descriptor *altsd; |
2662 | int i, altno, err, stream; | 2664 | int i, altno, err, stream; |
2663 | int format; | 2665 | int format; |
2664 | struct audioformat *fp; | 2666 | struct audioformat *fp = NULL; |
2665 | unsigned char *fmt, *csep; | 2667 | unsigned char *fmt, *csep; |
2666 | int num; | 2668 | int num; |
2667 | 2669 | ||
@@ -2734,6 +2736,18 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2734 | continue; | 2736 | continue; |
2735 | } | 2737 | } |
2736 | 2738 | ||
2739 | /* | ||
2740 | * Blue Microphones workaround: The last altsetting is identical | ||
2741 | * with the previous one, except for a larger packet size, but | ||
2742 | * is actually a mislabeled two-channel setting; ignore it. | ||
2743 | */ | ||
2744 | if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && | ||
2745 | fp && fp->altsetting == 1 && fp->channels == 1 && | ||
2746 | fp->format == SNDRV_PCM_FORMAT_S16_LE && | ||
2747 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | ||
2748 | fp->maxpacksize * 2) | ||
2749 | continue; | ||
2750 | |||
2737 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); | 2751 | 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 */ | 2752 | /* Creamware Noah has this descriptor after the 2nd endpoint */ |
2739 | if (!csep && altsd->bNumEndpoints >= 2) | 2753 | if (!csep && altsd->bNumEndpoints >= 2) |