aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/format.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/format.c')
-rw-r--r--sound/usb/format.c93
1 files changed, 76 insertions, 17 deletions
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 2c44386e5569..49e7ec6d2399 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -20,6 +20,7 @@
20#include <linux/usb.h> 20#include <linux/usb.h>
21#include <linux/usb/audio.h> 21#include <linux/usb/audio.h>
22#include <linux/usb/audio-v2.h> 22#include <linux/usb/audio-v2.h>
23#include <linux/usb/audio-v3.h>
23 24
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
@@ -39,11 +40,11 @@
39 * @dev: usb device 40 * @dev: usb device
40 * @fp: audioformat record 41 * @fp: audioformat record
41 * @format: the format tag (wFormatTag) 42 * @format: the format tag (wFormatTag)
42 * @fmt: the format type descriptor 43 * @fmt: the format type descriptor (v1/v2) or AudioStreaming descriptor (v3)
43 */ 44 */
44static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, 45static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
45 struct audioformat *fp, 46 struct audioformat *fp,
46 unsigned int format, void *_fmt) 47 u64 format, void *_fmt)
47{ 48{
48 int sample_width, sample_bytes; 49 int sample_width, sample_bytes;
49 u64 pcm_formats = 0; 50 u64 pcm_formats = 0;
@@ -54,7 +55,7 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
54 struct uac_format_type_i_discrete_descriptor *fmt = _fmt; 55 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
55 sample_width = fmt->bBitResolution; 56 sample_width = fmt->bBitResolution;
56 sample_bytes = fmt->bSubframeSize; 57 sample_bytes = fmt->bSubframeSize;
57 format = 1 << format; 58 format = 1ULL << format;
58 break; 59 break;
59 } 60 }
60 61
@@ -69,6 +70,18 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
69 format <<= 1; 70 format <<= 1;
70 break; 71 break;
71 } 72 }
73 case UAC_VERSION_3: {
74 struct uac3_as_header_descriptor *as = _fmt;
75
76 sample_width = as->bBitResolution;
77 sample_bytes = as->bSubslotSize;
78
79 if (format & UAC3_FORMAT_TYPE_I_RAW_DATA)
80 pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL;
81
82 format <<= 1;
83 break;
84 }
72 } 85 }
73 86
74 if ((pcm_formats == 0) && 87 if ((pcm_formats == 0) &&
@@ -137,7 +150,7 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
137 } 150 }
138 if (format & ~0x3f) { 151 if (format & ~0x3f) {
139 usb_audio_info(chip, 152 usb_audio_info(chip,
140 "%u:%d : unsupported format bits %#x\n", 153 "%u:%d : unsupported format bits %#llx\n",
141 fp->iface, fp->altsetting, format); 154 fp->iface, fp->altsetting, format);
142 } 155 }
143 156
@@ -281,15 +294,16 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip,
281 294
282/* 295/*
283 * parse the format descriptor and stores the possible sample rates 296 * parse the format descriptor and stores the possible sample rates
284 * on the audioformat table (audio class v2). 297 * on the audioformat table (audio class v2 and v3).
285 */ 298 */
286static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, 299static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip,
287 struct audioformat *fp) 300 struct audioformat *fp)
288{ 301{
289 struct usb_device *dev = chip->dev; 302 struct usb_device *dev = chip->dev;
290 unsigned char tmp[2], *data; 303 unsigned char tmp[2], *data;
291 int nr_triplets, data_size, ret = 0; 304 int nr_triplets, data_size, ret = 0;
292 int clock = snd_usb_clock_find_source(chip, fp->clock, false); 305 int clock = snd_usb_clock_find_source(chip, fp->protocol,
306 fp->clock, false);
293 307
294 if (clock < 0) { 308 if (clock < 0) {
295 dev_err(&dev->dev, 309 dev_err(&dev->dev,
@@ -368,13 +382,30 @@ err:
368 * parse the format type I and III descriptors 382 * parse the format type I and III descriptors
369 */ 383 */
370static int parse_audio_format_i(struct snd_usb_audio *chip, 384static int parse_audio_format_i(struct snd_usb_audio *chip,
371 struct audioformat *fp, unsigned int format, 385 struct audioformat *fp, u64 format,
372 struct uac_format_type_i_continuous_descriptor *fmt) 386 void *_fmt)
373{ 387{
374 snd_pcm_format_t pcm_format; 388 snd_pcm_format_t pcm_format;
389 unsigned int fmt_type;
375 int ret; 390 int ret;
376 391
377 if (fmt->bFormatType == UAC_FORMAT_TYPE_III) { 392 switch (fp->protocol) {
393 default:
394 case UAC_VERSION_1:
395 case UAC_VERSION_2: {
396 struct uac_format_type_i_continuous_descriptor *fmt = _fmt;
397
398 fmt_type = fmt->bFormatType;
399 break;
400 }
401 case UAC_VERSION_3: {
402 /* fp->fmt_type is already set in this case */
403 fmt_type = fp->fmt_type;
404 break;
405 }
406 }
407
408 if (fmt_type == UAC_FORMAT_TYPE_III) {
378 /* FIXME: the format type is really IECxxx 409 /* FIXME: the format type is really IECxxx
379 * but we give normal PCM format to get the existing 410 * but we give normal PCM format to get the existing
380 * apps working... 411 * apps working...
@@ -393,7 +424,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
393 } 424 }
394 fp->formats = pcm_format_to_bits(pcm_format); 425 fp->formats = pcm_format_to_bits(pcm_format);
395 } else { 426 } else {
396 fp->formats = parse_audio_format_i_type(chip, fp, format, fmt); 427 fp->formats = parse_audio_format_i_type(chip, fp, format, _fmt);
397 if (!fp->formats) 428 if (!fp->formats)
398 return -EINVAL; 429 return -EINVAL;
399 } 430 }
@@ -405,15 +436,20 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
405 */ 436 */
406 switch (fp->protocol) { 437 switch (fp->protocol) {
407 default: 438 default:
408 case UAC_VERSION_1: 439 case UAC_VERSION_1: {
440 struct uac_format_type_i_continuous_descriptor *fmt = _fmt;
441
409 fp->channels = fmt->bNrChannels; 442 fp->channels = fmt->bNrChannels;
410 ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); 443 ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
411 break; 444 break;
445 }
412 case UAC_VERSION_2: 446 case UAC_VERSION_2:
447 case UAC_VERSION_3: {
413 /* fp->channels is already set in this case */ 448 /* fp->channels is already set in this case */
414 ret = parse_audio_format_rates_v2(chip, fp); 449 ret = parse_audio_format_rates_v2v3(chip, fp);
415 break; 450 break;
416 } 451 }
452 }
417 453
418 if (fp->channels < 1) { 454 if (fp->channels < 1) {
419 usb_audio_err(chip, 455 usb_audio_err(chip,
@@ -430,7 +466,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
430 */ 466 */
431static int parse_audio_format_ii(struct snd_usb_audio *chip, 467static int parse_audio_format_ii(struct snd_usb_audio *chip,
432 struct audioformat *fp, 468 struct audioformat *fp,
433 int format, void *_fmt) 469 u64 format, void *_fmt)
434{ 470{
435 int brate, framesize, ret; 471 int brate, framesize, ret;
436 472
@@ -445,7 +481,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
445 break; 481 break;
446 default: 482 default:
447 usb_audio_info(chip, 483 usb_audio_info(chip,
448 "%u:%d : unknown format tag %#x is detected. processed as MPEG.\n", 484 "%u:%d : unknown format tag %#llx is detected. processed as MPEG.\n",
449 fp->iface, fp->altsetting, format); 485 fp->iface, fp->altsetting, format);
450 fp->formats = SNDRV_PCM_FMTBIT_MPEG; 486 fp->formats = SNDRV_PCM_FMTBIT_MPEG;
451 break; 487 break;
@@ -470,7 +506,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
470 framesize = le16_to_cpu(fmt->wSamplesPerFrame); 506 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
471 usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); 507 usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
472 fp->frame_size = framesize; 508 fp->frame_size = framesize;
473 ret = parse_audio_format_rates_v2(chip, fp); 509 ret = parse_audio_format_rates_v2v3(chip, fp);
474 break; 510 break;
475 } 511 }
476 } 512 }
@@ -479,7 +515,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
479} 515}
480 516
481int snd_usb_parse_audio_format(struct snd_usb_audio *chip, 517int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
482 struct audioformat *fp, unsigned int format, 518 struct audioformat *fp, u64 format,
483 struct uac_format_type_i_continuous_descriptor *fmt, 519 struct uac_format_type_i_continuous_descriptor *fmt,
484 int stream) 520 int stream)
485{ 521{
@@ -520,3 +556,26 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
520 return 0; 556 return 0;
521} 557}
522 558
559int snd_usb_parse_audio_format_v3(struct snd_usb_audio *chip,
560 struct audioformat *fp,
561 struct uac3_as_header_descriptor *as,
562 int stream)
563{
564 u64 format = le64_to_cpu(as->bmFormats);
565 int err;
566
567 /*
568 * Type I format bits are D0..D6
569 * This test works because type IV is not supported
570 */
571 if (format & 0x7f)
572 fp->fmt_type = UAC_FORMAT_TYPE_I;
573 else
574 fp->fmt_type = UAC_FORMAT_TYPE_III;
575
576 err = parse_audio_format_i(chip, fp, format, as);
577 if (err < 0)
578 return err;
579
580 return 0;
581}