diff options
author | Daniel Mack <daniel@caiaq.de> | 2010-05-26 12:11:36 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-05-27 03:48:31 -0400 |
commit | 74754f974b36c5a1156be46d0da05ab2c0a0960b (patch) | |
tree | 50d154e6d4c27fb18aad81795ec1b7f4970e358e | |
parent | 1efddcc981c95e62c4e305fd462e3e98b6f9c5cd (diff) |
ALSA: usb-audio: parse more format descriptors with structs
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/usb/endpoint.c | 11 | ||||
-rw-r--r-- | sound/usb/format.c | 20 | ||||
-rw-r--r-- | 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 ef07a6d0dd5f..4887342cae27 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) | |||
158 | int i, altno, err, stream; | 158 | int i, altno, err, stream; |
159 | int format = 0, num_channels = 0; | 159 | int format = 0, num_channels = 0; |
160 | struct audioformat *fp = NULL; | 160 | struct audioformat *fp = NULL; |
161 | unsigned char *fmt, *csep; | 161 | unsigned char *csep; |
162 | int num, protocol; | 162 | int num, protocol; |
163 | struct uac_format_type_i_continuous_descriptor *fmt; | ||
163 | 164 | ||
164 | dev = chip->dev; | 165 | dev = chip->dev; |
165 | 166 | ||
@@ -256,8 +257,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
256 | dev->devnum, iface_no, altno); | 257 | dev->devnum, iface_no, altno); |
257 | continue; | 258 | continue; |
258 | } | 259 | } |
259 | if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) || | 260 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || |
260 | ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) { | 261 | ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) { |
261 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | 262 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", |
262 | dev->devnum, iface_no, altno); | 263 | dev->devnum, iface_no, altno); |
263 | continue; | 264 | continue; |
@@ -268,7 +269,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
268 | * with the previous one, except for a larger packet size, but | 269 | * with the previous one, except for a larger packet size, but |
269 | * is actually a mislabeled two-channel setting; ignore it. | 270 | * is actually a mislabeled two-channel setting; ignore it. |
270 | */ | 271 | */ |
271 | if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && | 272 | if (fmt->bNrChannels == 1 && |
273 | fmt->bSubframeSize == 2 && | ||
274 | altno == 2 && num == 3 && | ||
272 | fp && fp->altsetting == 1 && fp->channels == 1 && | 275 | fp && fp->altsetting == 1 && fp->channels == 1 && |
273 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | 276 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && |
274 | protocol == UAC_VERSION_1 && | 277 | protocol == UAC_VERSION_1 && |
diff --git a/sound/usb/format.c b/sound/usb/format.c index b87cf87c4e7b..caaa3ef9e622 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -278,12 +278,11 @@ err: | |||
278 | * parse the format type I and III descriptors | 278 | * parse the format type I and III descriptors |
279 | */ | 279 | */ |
280 | static int parse_audio_format_i(struct snd_usb_audio *chip, | 280 | static int parse_audio_format_i(struct snd_usb_audio *chip, |
281 | struct audioformat *fp, | 281 | struct audioformat *fp, int format, |
282 | int format, void *_fmt, | 282 | struct uac_format_type_i_continuous_descriptor *fmt, |
283 | struct usb_host_interface *iface) | 283 | struct usb_host_interface *iface) |
284 | { | 284 | { |
285 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); | 285 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); |
286 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; | ||
287 | int protocol = altsd->bInterfaceProtocol; | 286 | int protocol = altsd->bInterfaceProtocol; |
288 | int pcm_format, ret; | 287 | int pcm_format, ret; |
289 | 288 | ||
@@ -320,7 +319,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
320 | switch (protocol) { | 319 | switch (protocol) { |
321 | case UAC_VERSION_1: | 320 | case UAC_VERSION_1: |
322 | fp->channels = fmt->bNrChannels; | 321 | fp->channels = fmt->bNrChannels; |
323 | ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7); | 322 | ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); |
324 | break; | 323 | break; |
325 | case UAC_VERSION_2: | 324 | case UAC_VERSION_2: |
326 | /* fp->channels is already set in this case */ | 325 | /* fp->channels is already set in this case */ |
@@ -392,12 +391,12 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
392 | } | 391 | } |
393 | 392 | ||
394 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, | 393 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, |
395 | int format, unsigned char *fmt, int stream, | 394 | int format, struct uac_format_type_i_continuous_descriptor *fmt, |
396 | struct usb_host_interface *iface) | 395 | int stream, struct usb_host_interface *iface) |
397 | { | 396 | { |
398 | int err; | 397 | int err; |
399 | 398 | ||
400 | switch (fmt[3]) { | 399 | switch (fmt->bFormatType) { |
401 | case UAC_FORMAT_TYPE_I: | 400 | case UAC_FORMAT_TYPE_I: |
402 | case UAC_FORMAT_TYPE_III: | 401 | case UAC_FORMAT_TYPE_III: |
403 | err = parse_audio_format_i(chip, fp, format, fmt, iface); | 402 | 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 | break; | 406 | break; |
408 | default: | 407 | default: |
409 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", | 408 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", |
410 | chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]); | 409 | chip->dev->devnum, fp->iface, fp->altsetting, |
410 | fmt->bFormatType); | ||
411 | return -1; | 411 | return -1; |
412 | } | 412 | } |
413 | fp->fmt_type = fmt[3]; | 413 | fp->fmt_type = fmt->bFormatType; |
414 | if (err < 0) | 414 | if (err < 0) |
415 | return err; | 415 | return err; |
416 | #if 1 | 416 | #if 1 |
@@ -421,7 +421,7 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f | |||
421 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || | 421 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || |
422 | chip->usb_id == USB_ID(0x041e, 0x3020) || | 422 | chip->usb_id == USB_ID(0x041e, 0x3020) || |
423 | chip->usb_id == USB_ID(0x041e, 0x3061)) { | 423 | chip->usb_id == USB_ID(0x041e, 0x3061)) { |
424 | if (fmt[3] == UAC_FORMAT_TYPE_I && | 424 | if (fmt->bFormatType == UAC_FORMAT_TYPE_I && |
425 | fp->rates != SNDRV_PCM_RATE_48000 && | 425 | fp->rates != SNDRV_PCM_RATE_48000 && |
426 | fp->rates != SNDRV_PCM_RATE_96000) | 426 | fp->rates != SNDRV_PCM_RATE_96000) |
427 | return -1; | 427 | return -1; |
diff --git a/sound/usb/format.h b/sound/usb/format.h index 8298c4e8ddfa..387924f0af85 100644 --- a/sound/usb/format.h +++ b/sound/usb/format.h | |||
@@ -1,8 +1,9 @@ | |||
1 | #ifndef __USBAUDIO_FORMAT_H | 1 | #ifndef __USBAUDIO_FORMAT_H |
2 | #define __USBAUDIO_FORMAT_H | 2 | #define __USBAUDIO_FORMAT_H |
3 | 3 | ||
4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, | 4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, |
5 | int format, unsigned char *fmt, int stream, | 5 | struct audioformat *fp, int format, |
6 | struct usb_host_interface *iface); | 6 | struct uac_format_type_i_continuous_descriptor *fmt, |
7 | int stream, struct usb_host_interface *iface); | ||
7 | 8 | ||
8 | #endif /* __USBAUDIO_FORMAT_H */ | 9 | #endif /* __USBAUDIO_FORMAT_H */ |