Commit 74754f97 authored by Daniel Mack's avatar Daniel Mack Committed by Takashi Iwai

ALSA: usb-audio: parse more format descriptors with structs

Signed-off-by: default avatarDaniel Mack <daniel@caiaq.de>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 1efddcc9
...@@ -158,8 +158,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) ...@@ -158,8 +158,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
int i, altno, err, stream; int i, altno, err, stream;
int format = 0, num_channels = 0; int format = 0, num_channels = 0;
struct audioformat *fp = NULL; struct audioformat *fp = NULL;
unsigned char *fmt, *csep; unsigned char *csep;
int num, protocol; int num, protocol;
struct uac_format_type_i_continuous_descriptor *fmt;
dev = chip->dev; dev = chip->dev;
...@@ -256,8 +257,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) ...@@ -256,8 +257,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
dev->devnum, iface_no, altno); dev->devnum, iface_no, altno);
continue; continue;
} }
if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) || if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
((protocol == UAC_VERSION_2) && (fmt[0] != 6))) { ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) {
snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
dev->devnum, iface_no, altno); dev->devnum, iface_no, altno);
continue; continue;
...@@ -268,7 +269,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) ...@@ -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 * with the previous one, except for a larger packet size, but
* is actually a mislabeled two-channel setting; ignore it. * 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 && fp->altsetting == 1 && fp->channels == 1 &&
fp->formats == SNDRV_PCM_FMTBIT_S16_LE && fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
protocol == UAC_VERSION_1 && protocol == UAC_VERSION_1 &&
......
...@@ -278,12 +278,11 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, ...@@ -278,12 +278,11 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
* parse the format type I and III descriptors * parse the format type I and III descriptors
*/ */
static int parse_audio_format_i(struct snd_usb_audio *chip, static int parse_audio_format_i(struct snd_usb_audio *chip,
struct audioformat *fp, struct audioformat *fp, int format,
int format, void *_fmt, struct uac_format_type_i_continuous_descriptor *fmt,
struct usb_host_interface *iface) struct usb_host_interface *iface)
{ {
struct usb_interface_descriptor *altsd = get_iface_desc(iface); struct usb_interface_descriptor *altsd = get_iface_desc(iface);
struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
int protocol = altsd->bInterfaceProtocol; int protocol = altsd->bInterfaceProtocol;
int pcm_format, ret; int pcm_format, ret;
...@@ -320,7 +319,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, ...@@ -320,7 +319,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
switch (protocol) { switch (protocol) {
case UAC_VERSION_1: case UAC_VERSION_1:
fp->channels = fmt->bNrChannels; 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; break;
case UAC_VERSION_2: case UAC_VERSION_2:
/* fp->channels is already set in this case */ /* fp->channels is already set in this case */
...@@ -392,12 +391,12 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, ...@@ -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 snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
int format, unsigned char *fmt, int stream, int format, struct uac_format_type_i_continuous_descriptor *fmt,
struct usb_host_interface *iface) int stream, struct usb_host_interface *iface)
{ {
int err; int err;
switch (fmt[3]) { switch (fmt->bFormatType) {
case UAC_FORMAT_TYPE_I: case UAC_FORMAT_TYPE_I:
case UAC_FORMAT_TYPE_III: case UAC_FORMAT_TYPE_III:
err = parse_audio_format_i(chip, fp, format, fmt, iface); 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 ...@@ -407,10 +406,11 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f
break; break;
default: default:
snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", 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; return -1;
} }
fp->fmt_type = fmt[3]; fp->fmt_type = fmt->bFormatType;
if (err < 0) if (err < 0)
return err; return err;
#if 1 #if 1
...@@ -421,7 +421,7 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f ...@@ -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) || if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
chip->usb_id == USB_ID(0x041e, 0x3020) || chip->usb_id == USB_ID(0x041e, 0x3020) ||
chip->usb_id == USB_ID(0x041e, 0x3061)) { 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_48000 &&
fp->rates != SNDRV_PCM_RATE_96000) fp->rates != SNDRV_PCM_RATE_96000)
return -1; return -1;
......
#ifndef __USBAUDIO_FORMAT_H #ifndef __USBAUDIO_FORMAT_H
#define __USBAUDIO_FORMAT_H #define __USBAUDIO_FORMAT_H
int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
int format, unsigned char *fmt, int stream, struct audioformat *fp, int format,
struct usb_host_interface *iface); struct uac_format_type_i_continuous_descriptor *fmt,
int stream, struct usb_host_interface *iface);
#endif /* __USBAUDIO_FORMAT_H */ #endif /* __USBAUDIO_FORMAT_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment