aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2013-01-31 15:39:17 -0500
committerClemens Ladisch <clemens@ladisch.de>2013-06-27 15:59:47 -0400
commit8f898e92aea2c24c7f379ee265d178f69ebb9c07 (patch)
tree6877a827d7541f0a3c779cd298bd65a69c550e06 /sound/usb
parentf722406faae2d073cc1d01063d1123c35425939e (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.h1
-rw-r--r--sound/usb/clock.c4
-rw-r--r--sound/usb/format.c34
-rw-r--r--sound/usb/format.h2
-rw-r--r--sound/usb/pcm.c4
-rw-r--r--sound/usb/stream.c3
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 */
44static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, 44static 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 */
361static int parse_audio_format_i(struct snd_usb_audio *chip, 360static 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 */
428static int parse_audio_format_ii(struct snd_usb_audio *chip, 420static 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,
483int snd_usb_parse_audio_format(struct snd_usb_audio *chip, 469int 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 @@
4int snd_usb_parse_audio_format(struct snd_usb_audio *chip, 4int 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);