alsa-devel.alsa-project.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).