Commit 4f4e8f69895c8696a4bcc751817d4b186023ac44

Authored by Paul Zimmerman
Committed by Takashi Iwai
1 parent 31cbd97726

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

... ... @@ -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  
... ... @@ -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 }
... ... @@ -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);
... ... @@ -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)
... ... @@ -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);
... ... @@ -244,7 +244,7 @@
244 244 else
245 245 subs->curpacksize = maxsize;
246 246  
247   - if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
  247 + if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
248 248 packs_per_ms = 8 >> subs->datainterval;
249 249 else
250 250 packs_per_ms = 1;