aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-03-04 13:46:15 -0500
committerTakashi Iwai <tiwai@suse.de>2010-03-05 02:18:32 -0500
commit015eb0b08150c6fef843efe22609589ead3d4fb8 (patch)
tree3ffcb8b5be54355761d94001a8c5415c965daccd /sound
parente11b4e0e4f5ab40ec342dc07b7201c09a45f9574 (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.h2
-rw-r--r--sound/usb/endpoint.c4
-rw-r--r--sound/usb/format.c10
-rw-r--r--sound/usb/pcm.c13
-rw-r--r--sound/usb/proc.c9
-rw-r--r--sound/usb/quirks-table.h12
-rw-r--r--sound/usb/quirks.c2
-rw-r--r--sound/usb/urb.c4
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
10struct audioformat { 10struct 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;