aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2010-05-26 12:11:36 -0400
committerTakashi Iwai <tiwai@suse.de>2010-05-27 03:48:31 -0400
commit74754f974b36c5a1156be46d0da05ab2c0a0960b (patch)
tree50d154e6d4c27fb18aad81795ec1b7f4970e358e /sound/usb
parent1efddcc981c95e62c4e305fd462e3e98b6f9c5cd (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>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/endpoint.c11
-rw-r--r--sound/usb/format.c20
-rw-r--r--sound/usb/format.h7
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 */
280static int parse_audio_format_i(struct snd_usb_audio *chip, 280static 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
394int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, 393int 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
4int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, 4int 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 */