[PATCH] sound: usb: USB3 Super Speed patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds Super Speed support to the USB drivers under sound/. It adds
tests for USB_SPEED_SUPER to all the 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@xxxxxxxxxxxx>

Cc: Takashi Iwai <tiwai@xxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxx>
--- 
 sound/usb/card.c             |    6 ++++--
 sound/usb/endpoint.c         |    3 ++-
 sound/usb/helper.c           |    3 ++-
 sound/usb/midi.c             |    3 ++-
 sound/usb/misc/ua101.c       |    2 ++
 sound/usb/pcm.c              |    6 ++++--
 sound/usb/proc.c             |    3 ++-
 sound/usb/urb.c              |    3 ++-
 sound/usb/usx2y/us122l.c     |    9 ++++++---
 sound/usb/usx2y/usb_stream.c |    5 +++--
 10 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index 7a8ac1d..9f35ffb 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -301,7 +301,8 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
 
 	if (snd_usb_get_speed(dev) != USB_SPEED_LOW &&
 	    snd_usb_get_speed(dev) != USB_SPEED_FULL &&
-	    snd_usb_get_speed(dev) != USB_SPEED_HIGH) {
+	    snd_usb_get_speed(dev) != USB_SPEED_HIGH &&
+	    snd_usb_get_speed(dev) != USB_SPEED_SUPER) {
 		snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
 		return -ENXIO;
 	}
@@ -380,7 +381,8 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
 	strlcat(card->longname,
 		snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" :
 		snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" :
-		", high speed",
+		snd_usb_get_speed(dev) == USB_SPEED_HIGH ? ", high speed" :
+		", super speed",
 		sizeof(card->longname));
 
 	snd_usb_audio_create_proc(chip);
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 6f6596c..59b518d 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -386,7 +386,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 		fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
 		/* num_channels is only set for v2 interfaces */
 		fp->channels = num_channels;
-		if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
+		if (snd_usb_get_speed(dev) == USB_SPEED_HIGH ||
+		    snd_usb_get_speed(dev) == USB_SPEED_SUPER)
 			fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
 					* (fp->maxpacksize & 0x7ff);
 		fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
index d48d6f8..a86ee2d 100644
--- a/sound/usb/helper.c
+++ b/sound/usb/helper.c
@@ -103,7 +103,8 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
 unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
 					 struct usb_host_interface *alts)
 {
-	if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH &&
+	if ((snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH ||
+	     snd_usb_get_speed(chip->dev) == USB_SPEED_SUPER) &&
 	    get_endpoint(alts, 0)->bInterval >= 1 &&
 	    get_endpoint(alts, 0)->bInterval <= 4)
 		return get_endpoint(alts, 0)->bInterval - 1;
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 4678564..4c7808f 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -834,7 +834,8 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
 
 	if (!ep->ports[0].active)
 		return;
-	count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2;
+	count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_SUPER ? 1 :
+		snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2;
 	count = snd_rawmidi_transmit(ep->ports[0].substream,
 				     urb->transfer_buffer,
 				     count);
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index fb5d68f..c15b189 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -1013,6 +1013,7 @@ static int detect_usb_format(struct ua101 *ua)
 		ua->packets_per_second = 1000;
 		break;
 	case USB_SPEED_HIGH:
+	case USB_SPEED_SUPER:
 		ua->packets_per_second = 8000;
 		break;
 	default:
@@ -1273,6 +1274,7 @@ static int ua101_probe(struct usb_interface *interface,
 	snprintf(ua->card->longname, sizeof(ua->card->longname),
 		 "EDIROL %s (serial %s), %u Hz at %s, %s speed", name,
 		 ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path,
+		 ua->dev->speed == USB_SPEED_SUPER ? "super" :
 		 ua->dev->speed == USB_SPEED_HIGH ? "high" : "full");
 
 	err = alloc_stream_buffers(ua, &ua->capture);
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 4568298..4fc33d1 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -467,7 +467,8 @@ static int hw_check_valid_format(struct snd_usb_substream *subs,
 		return 0;
 	}
 	/* check whether the period time is >= the data packet interval */
-	if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
+	if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH ||
+	    snd_usb_get_speed(subs->dev) == USB_SPEED_SUPER) {
 		ptime = 125 * (1 << fp->datainterval);
 		if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
 			hwc_debug("   > check: ptime %u > max %u\n", ptime, pt->max);
@@ -735,7 +736,8 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
 	}
 
 	param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
-	if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
+	if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH &&
+	    snd_usb_get_speed(subs->dev) != USB_SPEED_SUPER)
 		/* full speed devices have fixed data packet interval */
 		ptmin = 1000;
 	if (ptmin == 1000)
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
index f5e3f35..b2b5760 100644
--- a/sound/usb/proc.c
+++ b/sound/usb/proc.c
@@ -107,7 +107,8 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
 			}
 			snd_iprintf(buffer, "\n");
 		}
-		if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
+		if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH ||
+		    snd_usb_get_speed(subs->dev) == USB_SPEED_SUPER)
 			snd_iprintf(buffer, "    Data packet interval: %d us\n",
 				    125 * (1 << fp->datainterval));
 		// snd_iprintf(buffer, "    Max Packet Size = %d\n", fp->maxpacksize);
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
index de607d4..235263f 100644
--- a/sound/usb/urb.c
+++ b/sound/usb/urb.c
@@ -244,7 +244,8 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
 	else
 		subs->curpacksize = maxsize;
 
-	if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
+	if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH ||
+	    snd_usb_get_speed(subs->dev) == USB_SPEED_SUPER)
 		packs_per_ms = 8 >> subs->datainterval;
 	else
 		packs_per_ms = 1;
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 6ef68e4..24c7f40 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -336,7 +336,8 @@ static bool us122l_start(struct us122l *us122l,
 	unsigned use_packsize = 0;
 	bool success = false;
 
-	if (us122l->dev->speed == USB_SPEED_HIGH) {
+	if (us122l->dev->speed == USB_SPEED_HIGH ||
+	    us122l->dev->speed == USB_SPEED_SUPER) {
 		/* The us-122l's descriptor defaults to iso max_packsize 78,
 		   which isn't needed for samplerates <= 48000.
 		   Lets save some memory:
@@ -396,7 +397,8 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
 		err = -ENXIO;
 		goto free;
 	}
-	high_speed = us122l->dev->speed == USB_SPEED_HIGH;
+	high_speed = us122l->dev->speed == USB_SPEED_HIGH ||
+		     us122l->dev->speed == USB_SPEED_SUPER;
 	if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000  &&
 	     (!high_speed ||
 	      (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) ||
@@ -607,7 +609,8 @@ static int snd_us122l_probe(struct usb_interface *intf,
 
 	if ((device->descriptor.idProduct == USB_ID_US144 ||
 	     device->descriptor.idProduct == USB_ID_US144MKII)
-		&& device->speed == USB_SPEED_HIGH) {
+		&& (device->speed == USB_SPEED_HIGH ||
+		    device->speed == USB_SPEED_SUPER)) {
 		snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
 		return -ENODEV;
 	}
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index c400ade..518eaba 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -160,7 +160,8 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
 	int in_pipe, out_pipe;
 	int read_size = sizeof(struct usb_stream);
 	int write_size;
-	int usb_frames = dev->speed == USB_SPEED_HIGH ? 8000 : 1000;
+	int usb_frames = (dev->speed == USB_SPEED_HIGH ||
+			  dev->speed == USB_SPEED_SUPER) ? 8000 : 1000;
 	int pg;
 
 	in_pipe = usb_rcvisocpipe(dev, in_endpoint);
@@ -177,7 +178,7 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
 
 	packets = period_frames * usb_frames / sample_rate + 1;
 
-	if (dev->speed == USB_SPEED_HIGH)
+	if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER)
 		packets = (packets + 7) & ~7;
 
 	read_size += packets * USB_STREAM_URBDEPTH *
-- 

Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux