diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2013-01-31 15:39:17 -0500 |
---|---|---|
committer | Clemens Ladisch <clemens@ladisch.de> | 2013-06-27 15:59:47 -0400 |
commit | 8f898e92aea2c24c7f379ee265d178f69ebb9c07 (patch) | |
tree | 6877a827d7541f0a3c779cd298bd65a69c550e06 /sound/usb | |
parent | f722406faae2d073cc1d01063d1123c35425939e (diff) |
ALSA: usb-audio: store protocol version in struct audioformat
Instead of reading bInterfaceProtocol from the descriptor whenever it's
needed, store this value in the audioformat structure. Besides
simplifying some code, this will allow us to correctly handle vendor-
specific devices where the descriptors are marked with other values.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/card.h | 1 | ||||
-rw-r--r-- | sound/usb/clock.c | 4 | ||||
-rw-r--r-- | sound/usb/format.c | 34 | ||||
-rw-r--r-- | sound/usb/format.h | 2 | ||||
-rw-r--r-- | sound/usb/pcm.c | 4 | ||||
-rw-r--r-- | sound/usb/stream.c | 3 |
6 files changed, 16 insertions, 32 deletions
diff --git a/sound/usb/card.h b/sound/usb/card.h index bf2889a2cae5..5ecacaa90b53 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -21,6 +21,7 @@ struct audioformat { | |||
21 | unsigned char endpoint; /* endpoint */ | 21 | unsigned char endpoint; /* endpoint */ |
22 | unsigned char ep_attr; /* endpoint attributes */ | 22 | unsigned char ep_attr; /* endpoint attributes */ |
23 | unsigned char datainterval; /* log_2 of data packet interval */ | 23 | unsigned char datainterval; /* log_2 of data packet interval */ |
24 | unsigned char protocol; /* UAC_VERSION_1/2 */ | ||
24 | unsigned int maxpacksize; /* max. packet size */ | 25 | unsigned int maxpacksize; /* max. packet size */ |
25 | unsigned int rates; /* rate bitmasks */ | 26 | unsigned int rates; /* rate bitmasks */ |
26 | unsigned int rate_min, rate_max; /* min/max rates */ | 27 | unsigned int rate_min, rate_max; /* min/max rates */ |
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 3a2ce390e278..86f80c60b21f 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
@@ -407,9 +407,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, | |||
407 | struct usb_host_interface *alts, | 407 | struct usb_host_interface *alts, |
408 | struct audioformat *fmt, int rate) | 408 | struct audioformat *fmt, int rate) |
409 | { | 409 | { |
410 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | 410 | switch (fmt->protocol) { |
411 | |||
412 | switch (altsd->bInterfaceProtocol) { | ||
413 | case UAC_VERSION_1: | 411 | case UAC_VERSION_1: |
414 | default: | 412 | default: |
415 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); | 413 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); |
diff --git a/sound/usb/format.c b/sound/usb/format.c index 99299ffb33ac..3525231c6b97 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -43,13 +43,12 @@ | |||
43 | */ | 43 | */ |
44 | static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | 44 | static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, |
45 | struct audioformat *fp, | 45 | struct audioformat *fp, |
46 | unsigned int format, void *_fmt, | 46 | unsigned int format, void *_fmt) |
47 | int protocol) | ||
48 | { | 47 | { |
49 | int sample_width, sample_bytes; | 48 | int sample_width, sample_bytes; |
50 | u64 pcm_formats = 0; | 49 | u64 pcm_formats = 0; |
51 | 50 | ||
52 | switch (protocol) { | 51 | switch (fp->protocol) { |
53 | case UAC_VERSION_1: | 52 | case UAC_VERSION_1: |
54 | default: { | 53 | default: { |
55 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; | 54 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; |
@@ -360,11 +359,8 @@ err: | |||
360 | */ | 359 | */ |
361 | static int parse_audio_format_i(struct snd_usb_audio *chip, | 360 | static int parse_audio_format_i(struct snd_usb_audio *chip, |
362 | struct audioformat *fp, unsigned int format, | 361 | struct audioformat *fp, unsigned int format, |
363 | struct uac_format_type_i_continuous_descriptor *fmt, | 362 | struct uac_format_type_i_continuous_descriptor *fmt) |
364 | struct usb_host_interface *iface) | ||
365 | { | 363 | { |
366 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); | ||
367 | int protocol = altsd->bInterfaceProtocol; | ||
368 | snd_pcm_format_t pcm_format; | 364 | snd_pcm_format_t pcm_format; |
369 | int ret; | 365 | int ret; |
370 | 366 | ||
@@ -387,8 +383,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
387 | } | 383 | } |
388 | fp->formats = pcm_format_to_bits(pcm_format); | 384 | fp->formats = pcm_format_to_bits(pcm_format); |
389 | } else { | 385 | } else { |
390 | fp->formats = parse_audio_format_i_type(chip, fp, format, | 386 | fp->formats = parse_audio_format_i_type(chip, fp, format, fmt); |
391 | fmt, protocol); | ||
392 | if (!fp->formats) | 387 | if (!fp->formats) |
393 | return -EINVAL; | 388 | return -EINVAL; |
394 | } | 389 | } |
@@ -398,11 +393,8 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
398 | * proprietary class specific descriptor. | 393 | * proprietary class specific descriptor. |
399 | * audio class v2 uses class specific EP0 range requests for that. | 394 | * audio class v2 uses class specific EP0 range requests for that. |
400 | */ | 395 | */ |
401 | switch (protocol) { | 396 | switch (fp->protocol) { |
402 | default: | 397 | default: |
403 | snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n", | ||
404 | chip->dev->devnum, fp->iface, fp->altsetting, protocol); | ||
405 | /* fall through */ | ||
406 | case UAC_VERSION_1: | 398 | case UAC_VERSION_1: |
407 | fp->channels = fmt->bNrChannels; | 399 | fp->channels = fmt->bNrChannels; |
408 | ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); | 400 | ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); |
@@ -427,12 +419,9 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
427 | */ | 419 | */ |
428 | static int parse_audio_format_ii(struct snd_usb_audio *chip, | 420 | static int parse_audio_format_ii(struct snd_usb_audio *chip, |
429 | struct audioformat *fp, | 421 | struct audioformat *fp, |
430 | int format, void *_fmt, | 422 | int format, void *_fmt) |
431 | struct usb_host_interface *iface) | ||
432 | { | 423 | { |
433 | int brate, framesize, ret; | 424 | int brate, framesize, ret; |
434 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); | ||
435 | int protocol = altsd->bInterfaceProtocol; | ||
436 | 425 | ||
437 | switch (format) { | 426 | switch (format) { |
438 | case UAC_FORMAT_TYPE_II_AC3: | 427 | case UAC_FORMAT_TYPE_II_AC3: |
@@ -452,11 +441,8 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
452 | 441 | ||
453 | fp->channels = 1; | 442 | fp->channels = 1; |
454 | 443 | ||
455 | switch (protocol) { | 444 | switch (fp->protocol) { |
456 | default: | 445 | default: |
457 | snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n", | ||
458 | chip->dev->devnum, fp->iface, fp->altsetting, protocol); | ||
459 | /* fall through */ | ||
460 | case UAC_VERSION_1: { | 446 | case UAC_VERSION_1: { |
461 | struct uac_format_type_ii_discrete_descriptor *fmt = _fmt; | 447 | struct uac_format_type_ii_discrete_descriptor *fmt = _fmt; |
462 | brate = le16_to_cpu(fmt->wMaxBitRate); | 448 | brate = le16_to_cpu(fmt->wMaxBitRate); |
@@ -483,17 +469,17 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
483 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, | 469 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, |
484 | struct audioformat *fp, unsigned int format, | 470 | struct audioformat *fp, unsigned int format, |
485 | struct uac_format_type_i_continuous_descriptor *fmt, | 471 | struct uac_format_type_i_continuous_descriptor *fmt, |
486 | int stream, struct usb_host_interface *iface) | 472 | int stream) |
487 | { | 473 | { |
488 | int err; | 474 | int err; |
489 | 475 | ||
490 | switch (fmt->bFormatType) { | 476 | switch (fmt->bFormatType) { |
491 | case UAC_FORMAT_TYPE_I: | 477 | case UAC_FORMAT_TYPE_I: |
492 | case UAC_FORMAT_TYPE_III: | 478 | case UAC_FORMAT_TYPE_III: |
493 | err = parse_audio_format_i(chip, fp, format, fmt, iface); | 479 | err = parse_audio_format_i(chip, fp, format, fmt); |
494 | break; | 480 | break; |
495 | case UAC_FORMAT_TYPE_II: | 481 | case UAC_FORMAT_TYPE_II: |
496 | err = parse_audio_format_ii(chip, fp, format, fmt, iface); | 482 | err = parse_audio_format_ii(chip, fp, format, fmt); |
497 | break; | 483 | break; |
498 | default: | 484 | default: |
499 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", | 485 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", |
diff --git a/sound/usb/format.h b/sound/usb/format.h index 6f315226f320..4b8a01129f24 100644 --- a/sound/usb/format.h +++ b/sound/usb/format.h | |||
@@ -4,6 +4,6 @@ | |||
4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, | 4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, |
5 | struct audioformat *fp, unsigned int format, | 5 | struct audioformat *fp, unsigned int format, |
6 | struct uac_format_type_i_continuous_descriptor *fmt, | 6 | struct uac_format_type_i_continuous_descriptor *fmt, |
7 | int stream, struct usb_host_interface *iface); | 7 | int stream); |
8 | 8 | ||
9 | #endif /* __USBAUDIO_FORMAT_H */ | 9 | #endif /* __USBAUDIO_FORMAT_H */ |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 93b6e32cfead..776c58c7cba0 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -202,13 +202,11 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | |||
202 | struct usb_host_interface *alts, | 202 | struct usb_host_interface *alts, |
203 | struct audioformat *fmt) | 203 | struct audioformat *fmt) |
204 | { | 204 | { |
205 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | ||
206 | |||
207 | /* if endpoint doesn't have pitch control, bail out */ | 205 | /* if endpoint doesn't have pitch control, bail out */ |
208 | if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL)) | 206 | if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL)) |
209 | return 0; | 207 | return 0; |
210 | 208 | ||
211 | switch (altsd->bInterfaceProtocol) { | 209 | switch (fmt->protocol) { |
212 | case UAC_VERSION_1: | 210 | case UAC_VERSION_1: |
213 | default: | 211 | default: |
214 | return init_pitch_v1(chip, iface, alts, fmt); | 212 | return init_pitch_v1(chip, iface, alts, fmt); |
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 7db2f8958e79..1ea5871cb980 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c | |||
@@ -635,6 +635,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
635 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | 635 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; |
636 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | 636 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; |
637 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); | 637 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); |
638 | fp->protocol = protocol; | ||
638 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | 639 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); |
639 | fp->channels = num_channels; | 640 | fp->channels = num_channels; |
640 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | 641 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) |
@@ -676,7 +677,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
676 | } | 677 | } |
677 | 678 | ||
678 | /* ok, let's parse further... */ | 679 | /* ok, let's parse further... */ |
679 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { | 680 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream) < 0) { |
680 | kfree(fp->rate_table); | 681 | kfree(fp->rate_table); |
681 | kfree(fp->chmap); | 682 | kfree(fp->chmap); |
682 | kfree(fp); | 683 | kfree(fp); |