[From nobody Wed Aug 11 10:58:28 2010
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on alsa2.suse.de
X-Spam-Level: 
X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00 autolearn=ham
	version=3.3.1
X-Original-To: tiwai@wotan.suse.de
From: Paul Zimmerman &lt;Paul.Zimmerman@synopsys.com&gt;
To: Jaroslav Kysela &lt;perex@perex.cz&gt;
Cc: Takashi Iwai &lt;tiwai@suse.de&gt;, Greg Kroah-Hartman &lt;gregkh@suse.de&gt;,
	&quot;linux-usb@vger.kernel.org&quot; &lt;linux-usb@vger.kernel.org&gt;
Date: Tue, 10 Aug 2010 18:28:44 -0700
Subject: [PATCH] sound: usb: USB3 Super Speed patch
Thread-Topic: [PATCH] sound: usb: USB3 Super Speed patch
Thread-Index: Acs49InnAAVjr5ajRO+tHl/FSGIjGw==
Message-ID: &lt;F6C4814A9B336243ABC3D1FB44E08AE8012C2846E3@US01WXMBX1.internal.synopsys.com&gt;
Accept-Language: en-US
Content-Language: en-US
acceptlanguage: en-US
Content-Type: text/plain; charset=&quot;us-ascii&quot;
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-Virus-Scanned: by amavisd-new at localhost
X-Sanity-OK: YES

This patch adds Super Speed support to the USB drivers under sound/. It add=
s
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 Yamah=
a
speakers and a Logitech microphone, but with the descriptors modified to ad=
d
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 &lt;paulz@synopsys.com&gt;

Cc: Takashi Iwai &lt;tiwai@suse.de&gt;
Cc: Greg Kroah-Hartman &lt;gregkh@suse.de&gt;
---=20
 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,
=20
 	if (snd_usb_get_speed(dev) !=3D USB_SPEED_LOW &amp;&amp;
 	    snd_usb_get_speed(dev) !=3D USB_SPEED_FULL &amp;&amp;
-	    snd_usb_get_speed(dev) !=3D USB_SPEED_HIGH) {
+	    snd_usb_get_speed(dev) !=3D USB_SPEED_HIGH &amp;&amp;
+	    snd_usb_get_speed(dev) !=3D USB_SPEED_SUPER) {
 		snd_printk(KERN_ERR &quot;unknown device speed %d\n&quot;, 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-&gt;longname,
 		snd_usb_get_speed(dev) =3D=3D USB_SPEED_LOW ? &quot;, low speed&quot; :
 		snd_usb_get_speed(dev) =3D=3D USB_SPEED_FULL ? &quot;, full speed&quot; :
-		&quot;, high speed&quot;,
+		snd_usb_get_speed(dev) =3D=3D USB_SPEED_HIGH ? &quot;, high speed&quot; :
+		&quot;, super speed&quot;,
 		sizeof(card-&gt;longname));
=20
 	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-&gt;maxpacksize =3D le16_to_cpu(get_endpoint(alts, 0)-&gt;wMaxPacketSize);
 		/* num_channels is only set for v2 interfaces */
 		fp-&gt;channels =3D num_channels;
-		if (snd_usb_get_speed(dev) =3D=3D USB_SPEED_HIGH)
+		if (snd_usb_get_speed(dev) =3D=3D USB_SPEED_HIGH ||
+		    snd_usb_get_speed(dev) =3D=3D USB_SPEED_SUPER)
 			fp-&gt;maxpacksize =3D (((fp-&gt;maxpacksize &gt;&gt; 11) &amp; 3) + 1)
 					* (fp-&gt;maxpacksize &amp; 0x7ff);
 		fp-&gt;attributes =3D parse_uac_endpoint_attributes(chip, alts, protocol, i=
face_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 in=
t 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-&gt;dev) =3D=3D USB_SPEED_HIGH &amp;&amp;
+	if ((snd_usb_get_speed(chip-&gt;dev) =3D=3D USB_SPEED_HIGH ||
+	     snd_usb_get_speed(chip-&gt;dev) =3D=3D USB_SPEED_SUPER) &amp;&amp;
 	    get_endpoint(alts, 0)-&gt;bInterval &gt;=3D 1 &amp;&amp;
 	    get_endpoint(alts, 0)-&gt;bInterval &lt;=3D 4)
 		return get_endpoint(alts, 0)-&gt;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_mi=
di_out_endpoint *ep,
=20
 	if (!ep-&gt;ports[0].active)
 		return;
-	count =3D snd_usb_get_speed(ep-&gt;umidi-&gt;dev) =3D=3D USB_SPEED_HIGH ? 1 : 2=
;
+	count =3D snd_usb_get_speed(ep-&gt;umidi-&gt;dev) =3D=3D USB_SPEED_SUPER ? 1 :
+		snd_usb_get_speed(ep-&gt;umidi-&gt;dev) =3D=3D USB_SPEED_HIGH ? 1 : 2;
 	count =3D snd_rawmidi_transmit(ep-&gt;ports[0].substream,
 				     urb-&gt;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-&gt;packets_per_second =3D 1000;
 		break;
 	case USB_SPEED_HIGH:
+	case USB_SPEED_SUPER:
 		ua-&gt;packets_per_second =3D 8000;
 		break;
 	default:
@@ -1273,6 +1274,7 @@ static int ua101_probe(struct usb_interface *interfac=
e,
 	snprintf(ua-&gt;card-&gt;longname, sizeof(ua-&gt;card-&gt;longname),
 		 &quot;EDIROL %s (serial %s), %u Hz at %s, %s speed&quot;, name,
 		 ua-&gt;dev-&gt;serial ? ua-&gt;dev-&gt;serial : &quot;?&quot;, ua-&gt;rate, usb_path,
+		 ua-&gt;dev-&gt;speed =3D=3D USB_SPEED_SUPER ? &quot;super&quot; :
 		 ua-&gt;dev-&gt;speed =3D=3D USB_SPEED_HIGH ? &quot;high&quot; : &quot;full&quot;);
=20
 	err =3D alloc_stream_buffers(ua, &amp;ua-&gt;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_substre=
am *subs,
 		return 0;
 	}
 	/* check whether the period time is &gt;=3D the data packet interval */
-	if (snd_usb_get_speed(subs-&gt;dev) =3D=3D USB_SPEED_HIGH) {
+	if (snd_usb_get_speed(subs-&gt;dev) =3D=3D USB_SPEED_HIGH ||
+	    snd_usb_get_speed(subs-&gt;dev) =3D=3D USB_SPEED_SUPER) {
 		ptime =3D 125 * (1 &lt;&lt; fp-&gt;datainterval);
 		if (ptime &gt; pt-&gt;max || (ptime =3D=3D pt-&gt;max &amp;&amp; pt-&gt;openmax)) {
 			hwc_debug(&quot;   &gt; check: ptime %u &gt; max %u\n&quot;, ptime, pt-&gt;max);
@@ -735,7 +736,8 @@ static int setup_hw_info(struct snd_pcm_runtime *runtim=
e, struct snd_usb_substre
 	}
=20
 	param_period_time_if_needed =3D SNDRV_PCM_HW_PARAM_PERIOD_TIME;
-	if (snd_usb_get_speed(subs-&gt;dev) !=3D USB_SPEED_HIGH)
+	if (snd_usb_get_speed(subs-&gt;dev) !=3D USB_SPEED_HIGH &amp;&amp;
+	    snd_usb_get_speed(subs-&gt;dev) !=3D USB_SPEED_SUPER)
 		/* full speed devices have fixed data packet interval */
 		ptmin =3D 1000;
 	if (ptmin =3D=3D 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, &quot;\n&quot;);
 		}
-		if (snd_usb_get_speed(subs-&gt;dev) =3D=3D USB_SPEED_HIGH)
+		if (snd_usb_get_speed(subs-&gt;dev) =3D=3D USB_SPEED_HIGH ||
+		    snd_usb_get_speed(subs-&gt;dev) =3D=3D USB_SPEED_SUPER)
 			snd_iprintf(buffer, &quot;    Data packet interval: %d us\n&quot;,
 				    125 * (1 &lt;&lt; fp-&gt;datainterval));
 		// snd_iprintf(buffer, &quot;    Max Packet Size =3D %d\n&quot;, fp-&gt;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_substrea=
m *subs,
 	else
 		subs-&gt;curpacksize =3D maxsize;
=20
-	if (snd_usb_get_speed(subs-&gt;dev) =3D=3D USB_SPEED_HIGH)
+	if (snd_usb_get_speed(subs-&gt;dev) =3D=3D USB_SPEED_HIGH ||
+	    snd_usb_get_speed(subs-&gt;dev) =3D=3D USB_SPEED_SUPER)
 		packs_per_ms =3D 8 &gt;&gt; subs-&gt;datainterval;
 	else
 		packs_per_ms =3D 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 =3D 0;
 	bool success =3D false;
=20
-	if (us122l-&gt;dev-&gt;speed =3D=3D USB_SPEED_HIGH) {
+	if (us122l-&gt;dev-&gt;speed =3D=3D USB_SPEED_HIGH ||
+	    us122l-&gt;dev-&gt;speed =3D=3D USB_SPEED_SUPER) {
 		/* The us-122l's descriptor defaults to iso max_packsize 78,
 		   which isn't needed for samplerates &lt;=3D 48000.
 		   Lets save some memory:
@@ -396,7 +397,8 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw,=
 struct file *file,
 		err =3D -ENXIO;
 		goto free;
 	}
-	high_speed =3D us122l-&gt;dev-&gt;speed =3D=3D USB_SPEED_HIGH;
+	high_speed =3D us122l-&gt;dev-&gt;speed =3D=3D USB_SPEED_HIGH ||
+		     us122l-&gt;dev-&gt;speed =3D=3D USB_SPEED_SUPER;
 	if ((cfg-&gt;sample_rate !=3D 44100 &amp;&amp; cfg-&gt;sample_rate !=3D 48000  &amp;&amp;
 	     (!high_speed ||
 	      (cfg-&gt;sample_rate !=3D 88200 &amp;&amp; cfg-&gt;sample_rate !=3D 96000))) ||
@@ -607,7 +609,8 @@ static int snd_us122l_probe(struct usb_interface *intf,
=20
 	if ((device-&gt;descriptor.idProduct =3D=3D USB_ID_US144 ||
 	     device-&gt;descriptor.idProduct =3D=3D USB_ID_US144MKII)
-		&amp;&amp; device-&gt;speed =3D=3D USB_SPEED_HIGH) {
+		&amp;&amp; (device-&gt;speed =3D=3D USB_SPEED_HIGH ||
+		    device-&gt;speed =3D=3D USB_SPEED_SUPER)) {
 		snd_printk(KERN_ERR &quot;disable ehci-hcd to run US-144 \n&quot;);
 		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_ker=
nel *sk,
 	int in_pipe, out_pipe;
 	int read_size =3D sizeof(struct usb_stream);
 	int write_size;
-	int usb_frames =3D dev-&gt;speed =3D=3D USB_SPEED_HIGH ? 8000 : 1000;
+	int usb_frames =3D (dev-&gt;speed =3D=3D USB_SPEED_HIGH ||
+			  dev-&gt;speed =3D=3D USB_SPEED_SUPER) ? 8000 : 1000;
 	int pg;
=20
 	in_pipe =3D usb_rcvisocpipe(dev, in_endpoint);
@@ -177,7 +178,7 @@ struct usb_stream *usb_stream_new(struct usb_stream_ker=
nel *sk,
=20
 	packets =3D period_frames * usb_frames / sample_rate + 1;
=20
-	if (dev-&gt;speed =3D=3D USB_SPEED_HIGH)
+	if (dev-&gt;speed =3D=3D USB_SPEED_HIGH || dev-&gt;speed =3D=3D USB_SPEED_SUPER=
)
 		packets =3D (packets + 7) &amp; ~7;
=20
 	read_size +=3D packets * USB_STREAM_URBDEPTH *
--=20

Paul

]