diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2010-03-04 13:46:15 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-03-05 02:18:32 -0500 |
commit | 015eb0b08150c6fef843efe22609589ead3d4fb8 (patch) | |
tree | 3ffcb8b5be54355761d94001a8c5415c965daccd /sound | |
parent | e11b4e0e4f5ab40ec342dc07b7201c09a45f9574 (diff) |
ALSA: usb-audio: use a format bitmask per alternate setting
In preparation for USB audio 2.0 support, change the audioformat
structure so that it uses a bitmask to specify possible formats.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/usb/card.h | 2 | ||||
-rw-r--r-- | sound/usb/endpoint.c | 4 | ||||
-rw-r--r-- | sound/usb/format.c | 10 | ||||
-rw-r--r-- | sound/usb/pcm.c | 13 | ||||
-rw-r--r-- | sound/usb/proc.c | 9 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 12 | ||||
-rw-r--r-- | sound/usb/quirks.c | 2 | ||||
-rw-r--r-- | sound/usb/urb.c | 4 |
8 files changed, 34 insertions, 22 deletions
diff --git a/sound/usb/card.h b/sound/usb/card.h index 856d71b7407d..ed92420c1095 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | struct audioformat { | 10 | struct audioformat { |
11 | struct list_head list; | 11 | struct list_head list; |
12 | snd_pcm_format_t format; /* format type */ | 12 | u64 formats; /* ALSA format bits */ |
13 | unsigned int channels; /* # channels */ | 13 | unsigned int channels; /* # channels */ |
14 | unsigned int fmt_type; /* USB audio format type (1-3) */ | 14 | unsigned int fmt_type; /* USB audio format type (1-3) */ |
15 | unsigned int frame_size; /* samples per frame for non-audio */ | 15 | unsigned int frame_size; /* samples per frame for non-audio */ |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 3f53dee1270f..d65235c0106a 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -94,7 +94,7 @@ int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct au | |||
94 | if (subs->endpoint == fp->endpoint) { | 94 | if (subs->endpoint == fp->endpoint) { |
95 | list_add_tail(&fp->list, &subs->fmt_list); | 95 | list_add_tail(&fp->list, &subs->fmt_list); |
96 | subs->num_formats++; | 96 | subs->num_formats++; |
97 | subs->formats |= 1ULL << fp->format; | 97 | subs->formats |= fp->formats; |
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
100 | } | 100 | } |
@@ -268,7 +268,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
268 | */ | 268 | */ |
269 | if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && | 269 | if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && |
270 | fp && fp->altsetting == 1 && fp->channels == 1 && | 270 | fp && fp->altsetting == 1 && fp->channels == 1 && |
271 | fp->format == SNDRV_PCM_FORMAT_S16_LE && | 271 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && |
272 | protocol == UAC_VERSION_1 && | 272 | protocol == UAC_VERSION_1 && |
273 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | 273 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == |
274 | fp->maxpacksize * 2) | 274 | fp->maxpacksize * 2) |
diff --git a/sound/usb/format.c b/sound/usb/format.c index cbfe0c23dbd6..87f07f042c63 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -323,7 +323,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
323 | return -1; | 323 | return -1; |
324 | } | 324 | } |
325 | 325 | ||
326 | fp->format = pcm_format; | 326 | fp->formats = 1uLL << pcm_format; |
327 | 327 | ||
328 | /* gather possible sample rates */ | 328 | /* gather possible sample rates */ |
329 | /* audio class v1 reports possible sample rates as part of the | 329 | /* audio class v1 reports possible sample rates as part of the |
@@ -365,16 +365,16 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
365 | switch (format) { | 365 | switch (format) { |
366 | case UAC_FORMAT_TYPE_II_AC3: | 366 | case UAC_FORMAT_TYPE_II_AC3: |
367 | /* FIXME: there is no AC3 format defined yet */ | 367 | /* FIXME: there is no AC3 format defined yet */ |
368 | // fp->format = SNDRV_PCM_FORMAT_AC3; | 368 | // fp->formats = SNDRV_PCM_FMTBIT_AC3; |
369 | fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */ | 369 | fp->formats = SNDRV_PCM_FMTBIT_U8; /* temporary hack to receive byte streams */ |
370 | break; | 370 | break; |
371 | case UAC_FORMAT_TYPE_II_MPEG: | 371 | case UAC_FORMAT_TYPE_II_MPEG: |
372 | fp->format = SNDRV_PCM_FORMAT_MPEG; | 372 | fp->formats = SNDRV_PCM_FMTBIT_MPEG; |
373 | break; | 373 | break; |
374 | default: | 374 | default: |
375 | snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n", | 375 | snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n", |
376 | chip->dev->devnum, fp->iface, fp->altsetting, format); | 376 | chip->dev->devnum, fp->iface, fp->altsetting, format); |
377 | fp->format = SNDRV_PCM_FORMAT_MPEG; | 377 | fp->formats = SNDRV_PCM_FMTBIT_MPEG; |
378 | break; | 378 | break; |
379 | } | 379 | } |
380 | 380 | ||
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index c3d5a977cfed..bd0f84f3a9d2 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -58,7 +58,9 @@ static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned | |||
58 | list_for_each(p, &subs->fmt_list) { | 58 | list_for_each(p, &subs->fmt_list) { |
59 | struct audioformat *fp; | 59 | struct audioformat *fp; |
60 | fp = list_entry(p, struct audioformat, list); | 60 | fp = list_entry(p, struct audioformat, list); |
61 | if (fp->format != format || fp->channels != channels) | 61 | if (!(fp->formats & (1uLL << format))) |
62 | continue; | ||
63 | if (fp->channels != channels) | ||
62 | continue; | 64 | continue; |
63 | if (rate < fp->rate_min || rate > fp->rate_max) | 65 | if (rate < fp->rate_min || rate > fp->rate_max) |
64 | continue; | 66 | continue; |
@@ -428,10 +430,15 @@ static int hw_check_valid_format(struct snd_usb_substream *subs, | |||
428 | struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | 430 | struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); |
429 | struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 431 | struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
430 | struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME); | 432 | struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME); |
433 | struct snd_mask check_fmts; | ||
431 | unsigned int ptime; | 434 | unsigned int ptime; |
432 | 435 | ||
433 | /* check the format */ | 436 | /* check the format */ |
434 | if (!snd_mask_test(fmts, fp->format)) { | 437 | snd_mask_none(&check_fmts); |
438 | check_fmts.bits[0] = (u32)fp->formats; | ||
439 | check_fmts.bits[1] = (u32)(fp->formats >> 32); | ||
440 | snd_mask_intersect(&check_fmts, fmts); | ||
441 | if (snd_mask_empty(&check_fmts)) { | ||
435 | hwc_debug(" > check: no supported format %d\n", fp->format); | 442 | hwc_debug(" > check: no supported format %d\n", fp->format); |
436 | return 0; | 443 | return 0; |
437 | } | 444 | } |
@@ -584,7 +591,7 @@ static int hw_rule_format(struct snd_pcm_hw_params *params, | |||
584 | fp = list_entry(p, struct audioformat, list); | 591 | fp = list_entry(p, struct audioformat, list); |
585 | if (!hw_check_valid_format(subs, params, fp)) | 592 | if (!hw_check_valid_format(subs, params, fp)) |
586 | continue; | 593 | continue; |
587 | fbits |= (1ULL << fp->format); | 594 | fbits |= fp->formats; |
588 | } | 595 | } |
589 | 596 | ||
590 | oldbits[0] = fmt->bits[0]; | 597 | oldbits[0] = fmt->bits[0]; |
diff --git a/sound/usb/proc.c b/sound/usb/proc.c index 78fc3ba2522c..f5e3f356b95f 100644 --- a/sound/usb/proc.c +++ b/sound/usb/proc.c | |||
@@ -79,11 +79,16 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s | |||
79 | 79 | ||
80 | list_for_each(p, &subs->fmt_list) { | 80 | list_for_each(p, &subs->fmt_list) { |
81 | struct audioformat *fp; | 81 | struct audioformat *fp; |
82 | snd_pcm_format_t fmt; | ||
82 | fp = list_entry(p, struct audioformat, list); | 83 | fp = list_entry(p, struct audioformat, list); |
83 | snd_iprintf(buffer, " Interface %d\n", fp->iface); | 84 | snd_iprintf(buffer, " Interface %d\n", fp->iface); |
84 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); | 85 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); |
85 | snd_iprintf(buffer, " Format: %s\n", | 86 | snd_iprintf(buffer, " Format:"); |
86 | snd_pcm_format_name(fp->format)); | 87 | for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt) |
88 | if (fp->formats & (1uLL << fmt)) | ||
89 | snd_iprintf(buffer, " %s", | ||
90 | snd_pcm_format_name(fmt)); | ||
91 | snd_iprintf(buffer, "\n"); | ||
87 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); | 92 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); |
88 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", | 93 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", |
89 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, | 94 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 2b426c1fd0e8..6e8651d2ee9d 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -279,7 +279,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
279 | .ifnum = 0, | 279 | .ifnum = 0, |
280 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | 280 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, |
281 | .data = & (const struct audioformat) { | 281 | .data = & (const struct audioformat) { |
282 | .format = SNDRV_PCM_FORMAT_S16_LE, | 282 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
283 | .channels = 4, | 283 | .channels = 4, |
284 | .iface = 0, | 284 | .iface = 0, |
285 | .altsetting = 1, | 285 | .altsetting = 1, |
@@ -296,7 +296,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
296 | .ifnum = 1, | 296 | .ifnum = 1, |
297 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | 297 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, |
298 | .data = & (const struct audioformat) { | 298 | .data = & (const struct audioformat) { |
299 | .format = SNDRV_PCM_FORMAT_S16_LE, | 299 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
300 | .channels = 2, | 300 | .channels = 2, |
301 | .iface = 1, | 301 | .iface = 1, |
302 | .altsetting = 1, | 302 | .altsetting = 1, |
@@ -580,7 +580,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
580 | .ifnum = 0, | 580 | .ifnum = 0, |
581 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | 581 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, |
582 | .data = & (const struct audioformat) { | 582 | .data = & (const struct audioformat) { |
583 | .format = SNDRV_PCM_FORMAT_S24_3LE, | 583 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, |
584 | .channels = 2, | 584 | .channels = 2, |
585 | .iface = 0, | 585 | .iface = 0, |
586 | .altsetting = 1, | 586 | .altsetting = 1, |
@@ -597,7 +597,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
597 | .ifnum = 1, | 597 | .ifnum = 1, |
598 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | 598 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, |
599 | .data = & (const struct audioformat) { | 599 | .data = & (const struct audioformat) { |
600 | .format = SNDRV_PCM_FORMAT_S24_3LE, | 600 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, |
601 | .channels = 2, | 601 | .channels = 2, |
602 | .iface = 1, | 602 | .iface = 1, |
603 | .altsetting = 1, | 603 | .altsetting = 1, |
@@ -793,7 +793,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
793 | .ifnum = 1, | 793 | .ifnum = 1, |
794 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | 794 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, |
795 | .data = & (const struct audioformat) { | 795 | .data = & (const struct audioformat) { |
796 | .format = SNDRV_PCM_FORMAT_S24_3LE, | 796 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, |
797 | .channels = 2, | 797 | .channels = 2, |
798 | .iface = 1, | 798 | .iface = 1, |
799 | .altsetting = 1, | 799 | .altsetting = 1, |
@@ -810,7 +810,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
810 | .ifnum = 2, | 810 | .ifnum = 2, |
811 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | 811 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, |
812 | .data = & (const struct audioformat) { | 812 | .data = & (const struct audioformat) { |
813 | .format = SNDRV_PCM_FORMAT_S24_3LE, | 813 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, |
814 | .channels = 2, | 814 | .channels = 2, |
815 | .iface = 2, | 815 | .iface = 2, |
816 | .altsetting = 1, | 816 | .altsetting = 1, |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 4c16920844ea..99a19ba43207 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -174,7 +174,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, | |||
174 | const struct snd_usb_audio_quirk *quirk) | 174 | const struct snd_usb_audio_quirk *quirk) |
175 | { | 175 | { |
176 | static const struct audioformat ua_format = { | 176 | static const struct audioformat ua_format = { |
177 | .format = SNDRV_PCM_FORMAT_S24_3LE, | 177 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, |
178 | .channels = 2, | 178 | .channels = 2, |
179 | .fmt_type = UAC_FORMAT_TYPE_I, | 179 | .fmt_type = UAC_FORMAT_TYPE_I, |
180 | .altsetting = 1, | 180 | .altsetting = 1, |
diff --git a/sound/usb/urb.c b/sound/usb/urb.c index e9c339f75861..ad50d4398921 100644 --- a/sound/usb/urb.c +++ b/sound/usb/urb.c | |||
@@ -662,7 +662,7 @@ static int prepare_nodata_playback_urb(struct snd_usb_substream *subs, | |||
662 | urb->number_of_packets = ctx->packets; | 662 | urb->number_of_packets = ctx->packets; |
663 | urb->transfer_buffer_length = offs * stride; | 663 | urb->transfer_buffer_length = offs * stride; |
664 | memset(urb->transfer_buffer, | 664 | memset(urb->transfer_buffer, |
665 | subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0, | 665 | runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0, |
666 | offs * stride); | 666 | offs * stride); |
667 | return 0; | 667 | return 0; |
668 | } | 668 | } |
@@ -924,7 +924,7 @@ void snd_usb_init_substream(struct snd_usb_stream *as, | |||
924 | snd_usb_set_pcm_ops(as->pcm, stream); | 924 | snd_usb_set_pcm_ops(as->pcm, stream); |
925 | 925 | ||
926 | list_add_tail(&fp->list, &subs->fmt_list); | 926 | list_add_tail(&fp->list, &subs->fmt_list); |
927 | subs->formats |= 1ULL << fp->format; | 927 | subs->formats |= fp->formats; |
928 | subs->endpoint = fp->endpoint; | 928 | subs->endpoint = fp->endpoint; |
929 | subs->num_formats++; | 929 | subs->num_formats++; |
930 | subs->fmt_type = fp->fmt_type; | 930 | subs->fmt_type = fp->fmt_type; |