All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs
@ 2010-05-26 16:11 Daniel Mack
  2010-05-26 16:11 ` [PATCH 2/4] ALSA: usb-audio: fix return values Daniel Mack
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Daniel Mack @ 2010-05-26 16:11 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, gregkh, clemens

Signed-off-by: Daniel Mack <daniel@caiaq.de>
---
 sound/usb/endpoint.c |   11 +++++++----
 sound/usb/format.c   |   20 ++++++++++----------
 sound/usb/format.h   |    7 ++++---
 3 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index ef07a6d..4887342 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -158,8 +158,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 	int i, altno, err, stream;
 	int format = 0, num_channels = 0;
 	struct audioformat *fp = NULL;
-	unsigned char *fmt, *csep;
+	unsigned char *csep;
 	int num, protocol;
+	struct uac_format_type_i_continuous_descriptor *fmt;
 
 	dev = chip->dev;
 
@@ -256,8 +257,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 				   dev->devnum, iface_no, altno);
 			continue;
 		}
-		if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
-		    ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
+		if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
+		    ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) {
 			snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
 				   dev->devnum, iface_no, altno);
 			continue;
@@ -268,7 +269,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 		 * with the previous one, except for a larger packet size, but
 		 * is actually a mislabeled two-channel setting; ignore it.
 		 */
-		if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
+		if (fmt->bNrChannels == 1 &&
+		    fmt->bSubframeSize == 2 &&
+		    altno == 2 && num == 3 &&
 		    fp && fp->altsetting == 1 && fp->channels == 1 &&
 		    fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
 		    protocol == UAC_VERSION_1 &&
diff --git a/sound/usb/format.c b/sound/usb/format.c
index b87cf87..caaa3ef 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -278,12 +278,11 @@ err:
  * parse the format type I and III descriptors
  */
 static int parse_audio_format_i(struct snd_usb_audio *chip,
-				struct audioformat *fp,
-				int format, void *_fmt,
+				struct audioformat *fp, int format,
+				struct uac_format_type_i_continuous_descriptor *fmt,
 				struct usb_host_interface *iface)
 {
 	struct usb_interface_descriptor *altsd = get_iface_desc(iface);
-	struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
 	int protocol = altsd->bInterfaceProtocol;
 	int pcm_format, ret;
 
@@ -320,7 +319,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
 	switch (protocol) {
 	case UAC_VERSION_1:
 		fp->channels = fmt->bNrChannels;
-		ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7);
+		ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
 		break;
 	case UAC_VERSION_2:
 		/* fp->channels is already set in this case */
@@ -392,12 +391,12 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
 }
 
 int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
-		       int format, unsigned char *fmt, int stream,
-		       struct usb_host_interface *iface)
+			       int format, struct uac_format_type_i_continuous_descriptor *fmt,
+			       int stream, struct usb_host_interface *iface)
 {
 	int err;
 
-	switch (fmt[3]) {
+	switch (fmt->bFormatType) {
 	case UAC_FORMAT_TYPE_I:
 	case UAC_FORMAT_TYPE_III:
 		err = parse_audio_format_i(chip, fp, format, fmt, iface);
@@ -407,10 +406,11 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f
 		break;
 	default:
 		snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
-			   chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]);
+			   chip->dev->devnum, fp->iface, fp->altsetting,
+			   fmt->bFormatType);
 		return -1;
 	}
-	fp->fmt_type = fmt[3];
+	fp->fmt_type = fmt->bFormatType;
 	if (err < 0)
 		return err;
 #if 1
@@ -421,7 +421,7 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f
 	if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
 	    chip->usb_id == USB_ID(0x041e, 0x3020) ||
 	    chip->usb_id == USB_ID(0x041e, 0x3061)) {
-		if (fmt[3] == UAC_FORMAT_TYPE_I &&
+		if (fmt->bFormatType == UAC_FORMAT_TYPE_I &&
 		    fp->rates != SNDRV_PCM_RATE_48000 &&
 		    fp->rates != SNDRV_PCM_RATE_96000)
 			return -1;
diff --git a/sound/usb/format.h b/sound/usb/format.h
index 8298c4e..387924f 100644
--- a/sound/usb/format.h
+++ b/sound/usb/format.h
@@ -1,8 +1,9 @@
 #ifndef __USBAUDIO_FORMAT_H
 #define __USBAUDIO_FORMAT_H
 
-int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
-			       int format, unsigned char *fmt, int stream,
-			       struct usb_host_interface *iface);
+int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
+			       struct audioformat *fp, int format,
+			       struct uac_format_type_i_continuous_descriptor *fmt,
+			       int stream, struct usb_host_interface *iface);
 
 #endif /*  __USBAUDIO_FORMAT_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] ALSA: usb-audio: fix return values
  2010-05-26 16:11 [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs Daniel Mack
@ 2010-05-26 16:11 ` Daniel Mack
  2010-05-26 16:11 ` [PATCH 3/4] ALSA: usb-audio: parse UAC2 endpoint descriptors correctly Daniel Mack
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Daniel Mack @ 2010-05-26 16:11 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, gregkh, clemens

-1 is not a good return value as it means -EPERM, "not permitted".
Choose -ENOTSUPP instead, which is what the code really wants to tell
its callers.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
---
 sound/usb/format.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/usb/format.c b/sound/usb/format.c
index caaa3ef..fe29d61 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -408,7 +408,7 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f
 		snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
 			   chip->dev->devnum, fp->iface, fp->altsetting,
 			   fmt->bFormatType);
-		return -1;
+		return -ENOTSUPP;
 	}
 	fp->fmt_type = fmt->bFormatType;
 	if (err < 0)
@@ -424,7 +424,7 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f
 		if (fmt->bFormatType == UAC_FORMAT_TYPE_I &&
 		    fp->rates != SNDRV_PCM_RATE_48000 &&
 		    fp->rates != SNDRV_PCM_RATE_96000)
-			return -1;
+			return -ENOTSUPP;
 	}
 #endif
 	return 0;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/4] ALSA: usb-audio: parse UAC2 endpoint descriptors correctly
  2010-05-26 16:11 [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs Daniel Mack
  2010-05-26 16:11 ` [PATCH 2/4] ALSA: usb-audio: fix return values Daniel Mack
@ 2010-05-26 16:11 ` Daniel Mack
  2010-05-26 16:17   ` Daniel Mack
  2010-05-26 16:11 ` [PATCH 4/4] ALSA: usb-audio: add support for UAC2 pitch control Daniel Mack
  2010-05-27  8:09 ` [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs Takashi Iwai
  3 siblings, 1 reply; 9+ messages in thread
From: Daniel Mack @ 2010-05-26 16:11 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, gregkh, clemens

UAC2 devices have their information about pitch control stored in a
different field. Parse it, and emulate the bits for a v1 device.

A new struct uac2_iso_endpoint_descriptor is added.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
---
 include/linux/usb/audio-v2.h |   16 ++++++++++++
 sound/usb/endpoint.c         |   55 ++++++++++++++++++++++++++++++++----------
 2 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h
index 2389f93..92f1d99 100644
--- a/include/linux/usb/audio-v2.h
+++ b/include/linux/usb/audio-v2.h
@@ -105,6 +105,22 @@ struct uac_as_header_descriptor_v2 {
 	__u8 iChannelNames;
 } __attribute__((packed));
 
+/* 4.10.1.2 Class-Specific AS Isochronous Audio Data Endpoint Descriptor */
+
+struct uac2_iso_endpoint_descriptor {
+	__u8  bLength;			/* in bytes: 8 */
+	__u8  bDescriptorType;		/* USB_DT_CS_ENDPOINT */
+	__u8  bDescriptorSubtype;	/* EP_GENERAL */
+	__u8  bmAttributes;
+	__u8  bmControls;
+	__u8  bLockDelayUnits;
+	__le16 wLockDelay;
+} __attribute__((packed));
+
+#define UAC2_CONTROL_PITCH		(3 << 0)
+#define UAC2_CONTROL_DATA_OVERRUN	(3 << 2)
+#define UAC2_CONTROL_DATA_UNDERRUN	(3 << 4)
+
 /* 6.1 Interrupt Data Message */
 
 #define UAC2_INTERRUPT_DATA_MSG_VENDOR	(1 << 0)
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 4887342..28ee1ce 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -149,6 +149,47 @@ int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct au
 	return 0;
 }
 
+static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
+					 struct usb_host_interface *alts,
+					 int protocol, int iface_no)
+{
+	/* parsed with a v1 header here. that's ok as we only look at the
+	 * header first which is the same for both versions */
+	struct uac_iso_endpoint_descriptor *csep;
+	struct usb_interface_descriptor *altsd = get_iface_desc(alts);
+	int attributes = 0;
+
+	csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
+
+	/* Creamware Noah has this descriptor after the 2nd endpoint */
+	if (!csep && altsd->bNumEndpoints >= 2)
+		csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
+
+	if (!csep || csep->bLength < 7 ||
+	    csep->bDescriptorSubtype != UAC_EP_GENERAL) {
+		snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
+			   " class specific endpoint descriptor\n",
+			   chip->dev->devnum, iface_no,
+			   altsd->bAlternateSetting);
+		return 0;
+	}
+
+	if (protocol == UAC_VERSION_1) {
+		attributes = csep->bmAttributes;
+	} else {
+		struct uac2_iso_endpoint_descriptor *csep2 =
+			(struct uac2_iso_endpoint_descriptor *) csep;
+
+		attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX;
+
+		/* emulate the endpoint attributes of a v1 device */
+		if (csep2->bmControls & UAC2_CONTROL_PITCH)
+			attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL;
+	}
+
+	return attributes;
+}
+
 int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 {
 	struct usb_device *dev;
@@ -158,7 +199,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 	int i, altno, err, stream;
 	int format = 0, num_channels = 0;
 	struct audioformat *fp = NULL;
-	unsigned char *csep;
 	int num, protocol;
 	struct uac_format_type_i_continuous_descriptor *fmt;
 
@@ -279,17 +319,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 							fp->maxpacksize * 2)
 			continue;
 
-		csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
-		/* Creamware Noah has this descriptor after the 2nd endpoint */
-		if (!csep && altsd->bNumEndpoints >= 2)
-			csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
-		if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
-			snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
-				   " class specific endpoint descriptor\n",
-				   dev->devnum, iface_no, altno);
-			csep = NULL;
-		}
-
 		fp = kzalloc(sizeof(*fp), GFP_KERNEL);
 		if (! fp) {
 			snd_printk(KERN_ERR "cannot malloc\n");
@@ -308,7 +337,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 		if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
 			fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
 					* (fp->maxpacksize & 0x7ff);
-		fp->attributes = csep ? csep[3] : 0;
+		fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
 
 		/* some quirks for attributes here */
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/4] ALSA: usb-audio: add support for UAC2 pitch control
  2010-05-26 16:11 [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs Daniel Mack
  2010-05-26 16:11 ` [PATCH 2/4] ALSA: usb-audio: fix return values Daniel Mack
  2010-05-26 16:11 ` [PATCH 3/4] ALSA: usb-audio: parse UAC2 endpoint descriptors correctly Daniel Mack
@ 2010-05-26 16:11 ` Daniel Mack
  2010-05-27  8:09 ` [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs Takashi Iwai
  3 siblings, 0 replies; 9+ messages in thread
From: Daniel Mack @ 2010-05-26 16:11 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, gregkh, clemens

This request is again handled differently in comparison to UAC1.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
---
 sound/usb/pcm.c |   37 ++++++++++++++++++++++++++++++-------
 1 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 2bf0d77..056587d 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -120,10 +120,6 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
 
 	ep = get_endpoint(alts, 0)->bEndpointAddress;
 
-	/* if endpoint doesn't have pitch control, bail out */
-	if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
-		return 0;
-
 	data[0] = 1;
 	if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
 				   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
@@ -137,8 +133,32 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
 	return 0;
 }
 
+static int init_pitch_v2(struct snd_usb_audio *chip, int iface,
+			 struct usb_host_interface *alts,
+			 struct audioformat *fmt)
+{
+	struct usb_device *dev = chip->dev;
+	unsigned char data[1];
+	unsigned int ep;
+	int err;
+
+	ep = get_endpoint(alts, 0)->bEndpointAddress;
+
+	data[0] = 1;
+	if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
+				   USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+				   UAC2_EP_CS_PITCH << 8, 0,
+				   data, sizeof(data), 1000)) < 0) {
+		snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n",
+			   dev->devnum, iface, fmt->altsetting);
+		return err;
+	}
+
+	return 0;
+}
+
 /*
- * initialize the picth control and sample rate
+ * initialize the pitch control and sample rate
  */
 int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
 		       struct usb_host_interface *alts,
@@ -146,13 +166,16 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
 {
 	struct usb_interface_descriptor *altsd = get_iface_desc(alts);
 
+	/* if endpoint doesn't have pitch control, bail out */
+	if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
+		return 0;
+
 	switch (altsd->bInterfaceProtocol) {
 	case UAC_VERSION_1:
 		return init_pitch_v1(chip, iface, alts, fmt);
 
 	case UAC_VERSION_2:
-		/* not implemented yet */
-		return 0;
+		return init_pitch_v2(chip, iface, alts, fmt);
 	}
 
 	return -EINVAL;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] ALSA: usb-audio: parse UAC2 endpoint descriptors correctly
  2010-05-26 16:11 ` [PATCH 3/4] ALSA: usb-audio: parse UAC2 endpoint descriptors correctly Daniel Mack
@ 2010-05-26 16:17   ` Daniel Mack
       [not found]     ` <20100526204657.GB7343@suse.de>
  0 siblings, 1 reply; 9+ messages in thread
From: Daniel Mack @ 2010-05-26 16:17 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, gregkh, clemens

On Wed, May 26, 2010 at 06:11:38PM +0200, Daniel Mack wrote:
> UAC2 devices have their information about pitch control stored in a
> different field. Parse it, and emulate the bits for a v1 device.
> 
> A new struct uac2_iso_endpoint_descriptor is added.

> 
> Signed-off-by: Daniel Mack <daniel@caiaq.de>
> ---
>  include/linux/usb/audio-v2.h |   16 ++++++++++++

Greg, I copied you because of this patch, just to let you know we're
having fun in your area of responsibility again :)


Daniel

>  sound/usb/endpoint.c         |   55 ++++++++++++++++++++++++++++++++----------
>  2 files changed, 58 insertions(+), 13 deletions(-)
> 
> diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h
> index 2389f93..92f1d99 100644
> --- a/include/linux/usb/audio-v2.h
> +++ b/include/linux/usb/audio-v2.h
> @@ -105,6 +105,22 @@ struct uac_as_header_descriptor_v2 {
>  	__u8 iChannelNames;
>  } __attribute__((packed));
>  
> +/* 4.10.1.2 Class-Specific AS Isochronous Audio Data Endpoint Descriptor */
> +
> +struct uac2_iso_endpoint_descriptor {
> +	__u8  bLength;			/* in bytes: 8 */
> +	__u8  bDescriptorType;		/* USB_DT_CS_ENDPOINT */
> +	__u8  bDescriptorSubtype;	/* EP_GENERAL */
> +	__u8  bmAttributes;
> +	__u8  bmControls;
> +	__u8  bLockDelayUnits;
> +	__le16 wLockDelay;
> +} __attribute__((packed));
> +
> +#define UAC2_CONTROL_PITCH		(3 << 0)
> +#define UAC2_CONTROL_DATA_OVERRUN	(3 << 2)
> +#define UAC2_CONTROL_DATA_UNDERRUN	(3 << 4)
> +
>  /* 6.1 Interrupt Data Message */
>  
>  #define UAC2_INTERRUPT_DATA_MSG_VENDOR	(1 << 0)
> diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
> index 4887342..28ee1ce 100644
> --- a/sound/usb/endpoint.c
> +++ b/sound/usb/endpoint.c
> @@ -149,6 +149,47 @@ int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct au
>  	return 0;
>  }
>  
> +static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
> +					 struct usb_host_interface *alts,
> +					 int protocol, int iface_no)
> +{
> +	/* parsed with a v1 header here. that's ok as we only look at the
> +	 * header first which is the same for both versions */
> +	struct uac_iso_endpoint_descriptor *csep;
> +	struct usb_interface_descriptor *altsd = get_iface_desc(alts);
> +	int attributes = 0;
> +
> +	csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
> +
> +	/* Creamware Noah has this descriptor after the 2nd endpoint */
> +	if (!csep && altsd->bNumEndpoints >= 2)
> +		csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
> +
> +	if (!csep || csep->bLength < 7 ||
> +	    csep->bDescriptorSubtype != UAC_EP_GENERAL) {
> +		snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
> +			   " class specific endpoint descriptor\n",
> +			   chip->dev->devnum, iface_no,
> +			   altsd->bAlternateSetting);
> +		return 0;
> +	}
> +
> +	if (protocol == UAC_VERSION_1) {
> +		attributes = csep->bmAttributes;
> +	} else {
> +		struct uac2_iso_endpoint_descriptor *csep2 =
> +			(struct uac2_iso_endpoint_descriptor *) csep;
> +
> +		attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX;
> +
> +		/* emulate the endpoint attributes of a v1 device */
> +		if (csep2->bmControls & UAC2_CONTROL_PITCH)
> +			attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL;
> +	}
> +
> +	return attributes;
> +}
> +
>  int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
>  {
>  	struct usb_device *dev;
> @@ -158,7 +199,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
>  	int i, altno, err, stream;
>  	int format = 0, num_channels = 0;
>  	struct audioformat *fp = NULL;
> -	unsigned char *csep;
>  	int num, protocol;
>  	struct uac_format_type_i_continuous_descriptor *fmt;
>  
> @@ -279,17 +319,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
>  							fp->maxpacksize * 2)
>  			continue;
>  
> -		csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
> -		/* Creamware Noah has this descriptor after the 2nd endpoint */
> -		if (!csep && altsd->bNumEndpoints >= 2)
> -			csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
> -		if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
> -			snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
> -				   " class specific endpoint descriptor\n",
> -				   dev->devnum, iface_no, altno);
> -			csep = NULL;
> -		}
> -
>  		fp = kzalloc(sizeof(*fp), GFP_KERNEL);
>  		if (! fp) {
>  			snd_printk(KERN_ERR "cannot malloc\n");
> @@ -308,7 +337,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
>  		if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
>  			fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
>  					* (fp->maxpacksize & 0x7ff);
> -		fp->attributes = csep ? csep[3] : 0;
> +		fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
>  
>  		/* some quirks for attributes here */
>  
> -- 
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs
  2010-05-26 16:11 [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs Daniel Mack
                   ` (2 preceding siblings ...)
  2010-05-26 16:11 ` [PATCH 4/4] ALSA: usb-audio: add support for UAC2 pitch control Daniel Mack
@ 2010-05-27  8:09 ` Takashi Iwai
  3 siblings, 0 replies; 9+ messages in thread
From: Takashi Iwai @ 2010-05-27  8:09 UTC (permalink / raw)
  To: Daniel Mack; +Cc: alsa-devel, gregkh, clemens

At Wed, 26 May 2010 18:11:36 +0200,
Daniel Mack wrote:
> 
> Signed-off-by: Daniel Mack <daniel@caiaq.de>

Applied all patches now.  Thanks.


Takashi

> ---
>  sound/usb/endpoint.c |   11 +++++++----
>  sound/usb/format.c   |   20 ++++++++++----------
>  sound/usb/format.h   |    7 ++++---
>  3 files changed, 21 insertions(+), 17 deletions(-)
> 
> diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
> index ef07a6d..4887342 100644
> --- a/sound/usb/endpoint.c
> +++ b/sound/usb/endpoint.c
> @@ -158,8 +158,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
>  	int i, altno, err, stream;
>  	int format = 0, num_channels = 0;
>  	struct audioformat *fp = NULL;
> -	unsigned char *fmt, *csep;
> +	unsigned char *csep;
>  	int num, protocol;
> +	struct uac_format_type_i_continuous_descriptor *fmt;
>  
>  	dev = chip->dev;
>  
> @@ -256,8 +257,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
>  				   dev->devnum, iface_no, altno);
>  			continue;
>  		}
> -		if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
> -		    ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
> +		if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
> +		    ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) {
>  			snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
>  				   dev->devnum, iface_no, altno);
>  			continue;
> @@ -268,7 +269,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
>  		 * with the previous one, except for a larger packet size, but
>  		 * is actually a mislabeled two-channel setting; ignore it.
>  		 */
> -		if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
> +		if (fmt->bNrChannels == 1 &&
> +		    fmt->bSubframeSize == 2 &&
> +		    altno == 2 && num == 3 &&
>  		    fp && fp->altsetting == 1 && fp->channels == 1 &&
>  		    fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
>  		    protocol == UAC_VERSION_1 &&
> diff --git a/sound/usb/format.c b/sound/usb/format.c
> index b87cf87..caaa3ef 100644
> --- a/sound/usb/format.c
> +++ b/sound/usb/format.c
> @@ -278,12 +278,11 @@ err:
>   * parse the format type I and III descriptors
>   */
>  static int parse_audio_format_i(struct snd_usb_audio *chip,
> -				struct audioformat *fp,
> -				int format, void *_fmt,
> +				struct audioformat *fp, int format,
> +				struct uac_format_type_i_continuous_descriptor *fmt,
>  				struct usb_host_interface *iface)
>  {
>  	struct usb_interface_descriptor *altsd = get_iface_desc(iface);
> -	struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
>  	int protocol = altsd->bInterfaceProtocol;
>  	int pcm_format, ret;
>  
> @@ -320,7 +319,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
>  	switch (protocol) {
>  	case UAC_VERSION_1:
>  		fp->channels = fmt->bNrChannels;
> -		ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7);
> +		ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
>  		break;
>  	case UAC_VERSION_2:
>  		/* fp->channels is already set in this case */
> @@ -392,12 +391,12 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
>  }
>  
>  int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
> -		       int format, unsigned char *fmt, int stream,
> -		       struct usb_host_interface *iface)
> +			       int format, struct uac_format_type_i_continuous_descriptor *fmt,
> +			       int stream, struct usb_host_interface *iface)
>  {
>  	int err;
>  
> -	switch (fmt[3]) {
> +	switch (fmt->bFormatType) {
>  	case UAC_FORMAT_TYPE_I:
>  	case UAC_FORMAT_TYPE_III:
>  		err = parse_audio_format_i(chip, fp, format, fmt, iface);
> @@ -407,10 +406,11 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f
>  		break;
>  	default:
>  		snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
> -			   chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]);
> +			   chip->dev->devnum, fp->iface, fp->altsetting,
> +			   fmt->bFormatType);
>  		return -1;
>  	}
> -	fp->fmt_type = fmt[3];
> +	fp->fmt_type = fmt->bFormatType;
>  	if (err < 0)
>  		return err;
>  #if 1
> @@ -421,7 +421,7 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f
>  	if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
>  	    chip->usb_id == USB_ID(0x041e, 0x3020) ||
>  	    chip->usb_id == USB_ID(0x041e, 0x3061)) {
> -		if (fmt[3] == UAC_FORMAT_TYPE_I &&
> +		if (fmt->bFormatType == UAC_FORMAT_TYPE_I &&
>  		    fp->rates != SNDRV_PCM_RATE_48000 &&
>  		    fp->rates != SNDRV_PCM_RATE_96000)
>  			return -1;
> diff --git a/sound/usb/format.h b/sound/usb/format.h
> index 8298c4e..387924f 100644
> --- a/sound/usb/format.h
> +++ b/sound/usb/format.h
> @@ -1,8 +1,9 @@
>  #ifndef __USBAUDIO_FORMAT_H
>  #define __USBAUDIO_FORMAT_H
>  
> -int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
> -			       int format, unsigned char *fmt, int stream,
> -			       struct usb_host_interface *iface);
> +int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
> +			       struct audioformat *fp, int format,
> +			       struct uac_format_type_i_continuous_descriptor *fmt,
> +			       int stream, struct usb_host_interface *iface);
>  
>  #endif /*  __USBAUDIO_FORMAT_H */
> -- 
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] ALSA: usb-audio: parse UAC2 endpoint descriptors correctly
       [not found]     ` <20100526204657.GB7343@suse.de>
@ 2010-05-27  8:10       ` Takashi Iwai
  2010-05-27 18:15         ` Daniel Mack
  0 siblings, 1 reply; 9+ messages in thread
From: Takashi Iwai @ 2010-05-27  8:10 UTC (permalink / raw)
  To: Greg KH; +Cc: alsa-devel, clemens

At Wed, 26 May 2010 13:46:57 -0700,
Greg KH wrote:
> 
> On Wed, May 26, 2010 at 06:17:46PM +0200, Daniel Mack wrote:
> > On Wed, May 26, 2010 at 06:11:38PM +0200, Daniel Mack wrote:
> > > UAC2 devices have their information about pitch control stored in a
> > > different field. Parse it, and emulate the bits for a v1 device.
> > > 
> > > A new struct uac2_iso_endpoint_descriptor is added.
> > 
> > > 
> > > Signed-off-by: Daniel Mack <daniel@caiaq.de>
> > > ---
> > >  include/linux/usb/audio-v2.h |   16 ++++++++++++
> > 
> > Greg, I copied you because of this patch, just to let you know we're
> > having fun in your area of responsibility again :)
> 
> Heh, no problem at all.
> 
> Takashi, feel free to add an:
> 	Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
> to this patch when you take it.

OK, I put this to my tree.  Will be included in the next pull request
in this week.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] ALSA: usb-audio: parse UAC2 endpoint descriptors correctly
  2010-05-27  8:10       ` Takashi Iwai
@ 2010-05-27 18:15         ` Daniel Mack
  2010-05-28  5:48           ` Takashi Iwai
  0 siblings, 1 reply; 9+ messages in thread
From: Daniel Mack @ 2010-05-27 18:15 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Greg KH, clemens

On Thu, May 27, 2010 at 10:10:12AM +0200, Takashi Iwai wrote:
> At Wed, 26 May 2010 13:46:57 -0700,
> Greg KH wrote:
> > 
> > On Wed, May 26, 2010 at 06:17:46PM +0200, Daniel Mack wrote:
> > > On Wed, May 26, 2010 at 06:11:38PM +0200, Daniel Mack wrote:
> > > > UAC2 devices have their information about pitch control stored in a
> > > > different field. Parse it, and emulate the bits for a v1 device.
> > > > 
> > > > A new struct uac2_iso_endpoint_descriptor is added.
> > > 
> > > > 
> > > > Signed-off-by: Daniel Mack <daniel@caiaq.de>
> > > > ---
> > > >  include/linux/usb/audio-v2.h |   16 ++++++++++++
> > > 
> > > Greg, I copied you because of this patch, just to let you know we're
> > > having fun in your area of responsibility again :)
> > 
> > Heh, no problem at all.
> > 
> > Takashi, feel free to add an:
> > 	Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
> > to this patch when you take it.
> 
> OK, I put this to my tree.  Will be included in the next pull request
> in this week.

Thanks Takashi!

Here's another small one that needs attention.

Daniel

>From 3beee40982b98314f8d58c775cc8b40a8e25ce18 Mon Sep 17 00:00:00 2001
From: Daniel Mack <daniel@caiaq.de>
Date: Thu, 27 May 2010 18:28:25 +0200
Subject: [PATCH] ALSA: usb-audio: fix feature unit parser for UAC2

Fix a small off-by-one bug which causes the feature unit to announce a
wrong number of channels. This leads to illegal requests sent to the
firmware eventually.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
---
 sound/usb/mixer.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 97dd176..03ce971 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1126,7 +1126,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
 	} else {
 		struct uac2_feature_unit_descriptor *ftr = _ftr;
 		csize = 4;
-		channels = (hdr->bLength - 6) / 4;
+		channels = (hdr->bLength - 6) / 4 - 1;
 		bmaControls = ftr->bmaControls;
 	}
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] ALSA: usb-audio: parse UAC2 endpoint descriptors correctly
  2010-05-27 18:15         ` Daniel Mack
@ 2010-05-28  5:48           ` Takashi Iwai
  0 siblings, 0 replies; 9+ messages in thread
From: Takashi Iwai @ 2010-05-28  5:48 UTC (permalink / raw)
  To: Daniel Mack; +Cc: alsa-devel, Greg KH, clemens

At Thu, 27 May 2010 20:15:14 +0200,
Daniel Mack wrote:
> 
> On Thu, May 27, 2010 at 10:10:12AM +0200, Takashi Iwai wrote:
> > At Wed, 26 May 2010 13:46:57 -0700,
> > Greg KH wrote:
> > > 
> > > On Wed, May 26, 2010 at 06:17:46PM +0200, Daniel Mack wrote:
> > > > On Wed, May 26, 2010 at 06:11:38PM +0200, Daniel Mack wrote:
> > > > > UAC2 devices have their information about pitch control stored in a
> > > > > different field. Parse it, and emulate the bits for a v1 device.
> > > > > 
> > > > > A new struct uac2_iso_endpoint_descriptor is added.
> > > > 
> > > > > 
> > > > > Signed-off-by: Daniel Mack <daniel@caiaq.de>
> > > > > ---
> > > > >  include/linux/usb/audio-v2.h |   16 ++++++++++++
> > > > 
> > > > Greg, I copied you because of this patch, just to let you know we're
> > > > having fun in your area of responsibility again :)
> > > 
> > > Heh, no problem at all.
> > > 
> > > Takashi, feel free to add an:
> > > 	Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
> > > to this patch when you take it.
> > 
> > OK, I put this to my tree.  Will be included in the next pull request
> > in this week.
> 
> Thanks Takashi!
> 
> Here's another small one that needs attention.
> 
> Daniel
> 
> >From 3beee40982b98314f8d58c775cc8b40a8e25ce18 Mon Sep 17 00:00:00 2001
> From: Daniel Mack <daniel@caiaq.de>
> Date: Thu, 27 May 2010 18:28:25 +0200
> Subject: [PATCH] ALSA: usb-audio: fix feature unit parser for UAC2
> 
> Fix a small off-by-one bug which causes the feature unit to announce a
> wrong number of channels. This leads to illegal requests sent to the
> firmware eventually.
> 
> Signed-off-by: Daniel Mack <daniel@caiaq.de>

OK, applied now.  Thanks.


Takashi

> ---
>  sound/usb/mixer.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> index 97dd176..03ce971 100644
> --- a/sound/usb/mixer.c
> +++ b/sound/usb/mixer.c
> @@ -1126,7 +1126,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
>  	} else {
>  		struct uac2_feature_unit_descriptor *ftr = _ftr;
>  		csize = 4;
> -		channels = (hdr->bLength - 6) / 4;
> +		channels = (hdr->bLength - 6) / 4 - 1;
>  		bmaControls = ftr->bmaControls;
>  	}
>  
> -- 
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-05-28  5:48 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-26 16:11 [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs Daniel Mack
2010-05-26 16:11 ` [PATCH 2/4] ALSA: usb-audio: fix return values Daniel Mack
2010-05-26 16:11 ` [PATCH 3/4] ALSA: usb-audio: parse UAC2 endpoint descriptors correctly Daniel Mack
2010-05-26 16:17   ` Daniel Mack
     [not found]     ` <20100526204657.GB7343@suse.de>
2010-05-27  8:10       ` Takashi Iwai
2010-05-27 18:15         ` Daniel Mack
2010-05-28  5:48           ` Takashi Iwai
2010-05-26 16:11 ` [PATCH 4/4] ALSA: usb-audio: add support for UAC2 pitch control Daniel Mack
2010-05-27  8:09 ` [PATCH 1/4] ALSA: usb-audio: parse more format descriptors with structs Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.