Commit 4f4e8f69895c8696a4bcc751817d4b186023ac44
Committed by
Takashi Iwai
1 parent
31cbd97726
Exists in
master
and in
39 other branches
ALSA: usb: USB3 SuperSpeed sound support
This is V2 of the patch, after feedback from Clemens and Daniel. This patch adds SuperSpeed support to the USB drivers under sound/. It adds tests for USB_SPEED_SUPER to the appropriate places that check for the USB speed. This patch has been tested with our SS USB3 device emulating a set of Yamaha speakers and a Logitech microphone, but with the descriptors modified to add USB3 support. It has also been tested with the real speakers and microphone, to make sure that USB2 devices still work. Signed-off-by: Paul Zimmerman <paulz@synopsys.com> Cc: Clemens Ladisch <clemens@ladisch.de> Cc: Daniel Mack <daniel@caiaq.de> Cc: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 6 changed files with 46 additions and 19 deletions Side-by-side Diff
sound/usb/card.c
... | ... | @@ -299,9 +299,13 @@ |
299 | 299 | |
300 | 300 | *rchip = NULL; |
301 | 301 | |
302 | - if (snd_usb_get_speed(dev) != USB_SPEED_LOW && | |
303 | - snd_usb_get_speed(dev) != USB_SPEED_FULL && | |
304 | - snd_usb_get_speed(dev) != USB_SPEED_HIGH) { | |
302 | + switch (snd_usb_get_speed(dev)) { | |
303 | + case USB_SPEED_LOW: | |
304 | + case USB_SPEED_FULL: | |
305 | + case USB_SPEED_HIGH: | |
306 | + case USB_SPEED_SUPER: | |
307 | + break; | |
308 | + default: | |
305 | 309 | snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev)); |
306 | 310 | return -ENXIO; |
307 | 311 | } |
... | ... | @@ -377,11 +381,22 @@ |
377 | 381 | if (len < sizeof(card->longname)) |
378 | 382 | usb_make_path(dev, card->longname + len, sizeof(card->longname) - len); |
379 | 383 | |
380 | - strlcat(card->longname, | |
381 | - snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" : | |
382 | - snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" : | |
383 | - ", high speed", | |
384 | - sizeof(card->longname)); | |
384 | + switch (snd_usb_get_speed(dev)) { | |
385 | + case USB_SPEED_LOW: | |
386 | + strlcat(card->longname, ", low speed", sizeof(card->longname)); | |
387 | + break; | |
388 | + case USB_SPEED_FULL: | |
389 | + strlcat(card->longname, ", full speed", sizeof(card->longname)); | |
390 | + break; | |
391 | + case USB_SPEED_HIGH: | |
392 | + strlcat(card->longname, ", high speed", sizeof(card->longname)); | |
393 | + break; | |
394 | + case USB_SPEED_SUPER: | |
395 | + strlcat(card->longname, ", super speed", sizeof(card->longname)); | |
396 | + break; | |
397 | + default: | |
398 | + break; | |
399 | + } | |
385 | 400 | |
386 | 401 | snd_usb_audio_create_proc(chip); |
387 | 402 |
sound/usb/helper.c
... | ... | @@ -103,11 +103,16 @@ |
103 | 103 | unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, |
104 | 104 | struct usb_host_interface *alts) |
105 | 105 | { |
106 | - if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH && | |
107 | - get_endpoint(alts, 0)->bInterval >= 1 && | |
108 | - get_endpoint(alts, 0)->bInterval <= 4) | |
109 | - return get_endpoint(alts, 0)->bInterval - 1; | |
110 | - else | |
111 | - return 0; | |
106 | + switch (snd_usb_get_speed(chip->dev)) { | |
107 | + case USB_SPEED_HIGH: | |
108 | + case USB_SPEED_SUPER: | |
109 | + if (get_endpoint(alts, 0)->bInterval >= 1 && | |
110 | + get_endpoint(alts, 0)->bInterval <= 4) | |
111 | + return get_endpoint(alts, 0)->bInterval - 1; | |
112 | + break; | |
113 | + default: | |
114 | + break; | |
115 | + } | |
116 | + return 0; | |
112 | 117 | } |
sound/usb/midi.c
... | ... | @@ -834,7 +834,14 @@ |
834 | 834 | |
835 | 835 | if (!ep->ports[0].active) |
836 | 836 | return; |
837 | - count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2; | |
837 | + switch (snd_usb_get_speed(ep->umidi->dev)) { | |
838 | + case USB_SPEED_HIGH: | |
839 | + case USB_SPEED_SUPER: | |
840 | + count = 1; | |
841 | + break; | |
842 | + default: | |
843 | + count = 2; | |
844 | + } | |
838 | 845 | count = snd_rawmidi_transmit(ep->ports[0].substream, |
839 | 846 | urb->transfer_buffer, |
840 | 847 | count); |
sound/usb/pcm.c
... | ... | @@ -467,7 +467,7 @@ |
467 | 467 | return 0; |
468 | 468 | } |
469 | 469 | /* check whether the period time is >= the data packet interval */ |
470 | - if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) { | |
470 | + if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) { | |
471 | 471 | ptime = 125 * (1 << fp->datainterval); |
472 | 472 | if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { |
473 | 473 | hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); |
... | ... | @@ -735,7 +735,7 @@ |
735 | 735 | } |
736 | 736 | |
737 | 737 | param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; |
738 | - if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH) | |
738 | + if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) | |
739 | 739 | /* full speed devices have fixed data packet interval */ |
740 | 740 | ptmin = 1000; |
741 | 741 | if (ptmin == 1000) |
sound/usb/proc.c
... | ... | @@ -107,7 +107,7 @@ |
107 | 107 | } |
108 | 108 | snd_iprintf(buffer, "\n"); |
109 | 109 | } |
110 | - if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) | |
110 | + if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) | |
111 | 111 | snd_iprintf(buffer, " Data packet interval: %d us\n", |
112 | 112 | 125 * (1 << fp->datainterval)); |
113 | 113 | // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); |
sound/usb/urb.c