format.c (015eb0b08150c6fef843efe22609589ead3d4fb8) | format.c (29088fef3e3f62147c1dd53d764da4f04bf3188d) |
---|---|
1/* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of --- 23 unchanged lines hidden (view full) --- 32 * parse the audio format type I descriptor 33 * and returns the corresponding pcm format 34 * 35 * @dev: usb device 36 * @fp: audioformat record 37 * @format: the format tag (wFormatTag) 38 * @fmt: the format type descriptor 39 */ | 1/* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of --- 23 unchanged lines hidden (view full) --- 32 * parse the audio format type I descriptor 33 * and returns the corresponding pcm format 34 * 35 * @dev: usb device 36 * @fp: audioformat record 37 * @format: the format tag (wFormatTag) 38 * @fmt: the format type descriptor 39 */ |
40static int parse_audio_format_i_type(struct snd_usb_audio *chip, | 40static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, |
41 struct audioformat *fp, 42 int format, void *_fmt, 43 int protocol) 44{ | 41 struct audioformat *fp, 42 int format, void *_fmt, 43 int protocol) 44{ |
45 int pcm_format, i; | |
46 int sample_width, sample_bytes; | 45 int sample_width, sample_bytes; |
46 u64 pcm_formats; |
|
47 48 switch (protocol) { 49 case UAC_VERSION_1: { 50 struct uac_format_type_i_discrete_descriptor *fmt = _fmt; 51 sample_width = fmt->bBitResolution; 52 sample_bytes = fmt->bSubframeSize; | 47 48 switch (protocol) { 49 case UAC_VERSION_1: { 50 struct uac_format_type_i_discrete_descriptor *fmt = _fmt; 51 sample_width = fmt->bBitResolution; 52 sample_bytes = fmt->bSubframeSize; |
53 format = 1 << format; |
|
53 break; 54 } 55 56 case UAC_VERSION_2: { 57 struct uac_format_type_i_ext_descriptor *fmt = _fmt; 58 sample_width = fmt->bBitResolution; 59 sample_bytes = fmt->bSubslotSize; | 54 break; 55 } 56 57 case UAC_VERSION_2: { 58 struct uac_format_type_i_ext_descriptor *fmt = _fmt; 59 sample_width = fmt->bBitResolution; 60 sample_bytes = fmt->bSubslotSize; |
60 61 /* 62 * FIXME 63 * USB audio class v2 devices specify a bitmap of possible 64 * audio formats rather than one fix value. For now, we just 65 * pick one of them and report that as the only possible 66 * value for this setting. 67 * The bit allocation map is in fact compatible to the 68 * wFormatTag of the v1 AS streaming descriptors, which is why 69 * we can simply map the matrix. 70 */ 71 72 for (i = 0; i < 5; i++) 73 if (format & (1UL << i)) { 74 format = i + 1; 75 break; 76 } 77 | 61 format <<= 1; |
78 break; 79 } 80 81 default: 82 return -EINVAL; 83 } 84 | 62 break; 63 } 64 65 default: 66 return -EINVAL; 67 } 68 |
85 /* FIXME: correct endianess and sign? */ 86 pcm_format = -1; | 69 pcm_formats = 0; |
87 | 70 |
88 switch (format) { 89 case UAC_FORMAT_TYPE_I_UNDEFINED: /* some devices don't define this correctly... */ | 71 if (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED)) { 72 /* some devices don't define this correctly... */ |
90 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", 91 chip->dev->devnum, fp->iface, fp->altsetting); | 73 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", 74 chip->dev->devnum, fp->iface, fp->altsetting); |
92 /* fall-through */ 93 case UAC_FORMAT_TYPE_I_PCM: | 75 format = 1 << UAC_FORMAT_TYPE_I_PCM; 76 } 77 if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) { |
94 if (sample_width > sample_bytes * 8) { 95 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n", 96 chip->dev->devnum, fp->iface, fp->altsetting, 97 sample_width, sample_bytes); 98 } 99 /* check the format byte size */ 100 switch (sample_bytes) { 101 case 1: | 78 if (sample_width > sample_bytes * 8) { 79 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n", 80 chip->dev->devnum, fp->iface, fp->altsetting, 81 sample_width, sample_bytes); 82 } 83 /* check the format byte size */ 84 switch (sample_bytes) { 85 case 1: |
102 pcm_format = SNDRV_PCM_FORMAT_S8; | 86 pcm_formats |= SNDRV_PCM_FMTBIT_S8; |
103 break; 104 case 2: 105 if (snd_usb_is_big_endian_format(chip, fp)) | 87 break; 88 case 2: 89 if (snd_usb_is_big_endian_format(chip, fp)) |
106 pcm_format = SNDRV_PCM_FORMAT_S16_BE; /* grrr, big endian!! */ | 90 pcm_formats |= SNDRV_PCM_FMTBIT_S16_BE; /* grrr, big endian!! */ |
107 else | 91 else |
108 pcm_format = SNDRV_PCM_FORMAT_S16_LE; | 92 pcm_formats |= SNDRV_PCM_FMTBIT_S16_LE; |
109 break; 110 case 3: 111 if (snd_usb_is_big_endian_format(chip, fp)) | 93 break; 94 case 3: 95 if (snd_usb_is_big_endian_format(chip, fp)) |
112 pcm_format = SNDRV_PCM_FORMAT_S24_3BE; /* grrr, big endian!! */ | 96 pcm_formats |= SNDRV_PCM_FMTBIT_S24_3BE; /* grrr, big endian!! */ |
113 else | 97 else |
114 pcm_format = SNDRV_PCM_FORMAT_S24_3LE; | 98 pcm_formats |= SNDRV_PCM_FMTBIT_S24_3LE; |
115 break; 116 case 4: | 99 break; 100 case 4: |
117 pcm_format = SNDRV_PCM_FORMAT_S32_LE; | 101 pcm_formats |= SNDRV_PCM_FMTBIT_S32_LE; |
118 break; 119 default: 120 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n", 121 chip->dev->devnum, fp->iface, fp->altsetting, 122 sample_width, sample_bytes); 123 break; 124 } | 102 break; 103 default: 104 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n", 105 chip->dev->devnum, fp->iface, fp->altsetting, 106 sample_width, sample_bytes); 107 break; 108 } |
125 break; 126 case UAC_FORMAT_TYPE_I_PCM8: 127 pcm_format = SNDRV_PCM_FORMAT_U8; 128 | 109 } 110 if (format & (1 << UAC_FORMAT_TYPE_I_PCM8)) { |
129 /* Dallas DS4201 workaround: it advertises U8 format, but really 130 supports S8. */ 131 if (chip->usb_id == USB_ID(0x04fa, 0x4201)) | 111 /* Dallas DS4201 workaround: it advertises U8 format, but really 112 supports S8. */ 113 if (chip->usb_id == USB_ID(0x04fa, 0x4201)) |
132 pcm_format = SNDRV_PCM_FORMAT_S8; 133 break; 134 case UAC_FORMAT_TYPE_I_IEEE_FLOAT: 135 pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE; 136 break; 137 case UAC_FORMAT_TYPE_I_ALAW: 138 pcm_format = SNDRV_PCM_FORMAT_A_LAW; 139 break; 140 case UAC_FORMAT_TYPE_I_MULAW: 141 pcm_format = SNDRV_PCM_FORMAT_MU_LAW; 142 break; 143 default: 144 snd_printk(KERN_INFO "%d:%u:%d : unsupported format type %d\n", | 114 pcm_formats |= SNDRV_PCM_FMTBIT_S8; 115 else 116 pcm_formats |= SNDRV_PCM_FMTBIT_U8; 117 } 118 if (format & (1 << UAC_FORMAT_TYPE_I_IEEE_FLOAT)) { 119 pcm_formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; 120 } 121 if (format & (1 << UAC_FORMAT_TYPE_I_ALAW)) { 122 pcm_formats |= SNDRV_PCM_FMTBIT_A_LAW; 123 } 124 if (format & (1 << UAC_FORMAT_TYPE_I_MULAW)) { 125 pcm_formats |= SNDRV_PCM_FMTBIT_MU_LAW; 126 } 127 if (format & ~0x3f) { 128 snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n", |
145 chip->dev->devnum, fp->iface, fp->altsetting, format); | 129 chip->dev->devnum, fp->iface, fp->altsetting, format); |
146 break; | |
147 } | 130 } |
148 return pcm_format; | 131 return pcm_formats; |
149} 150 151 152/* 153 * parse the format descriptor and stores the possible sample rates 154 * on the audioformat table (audio class v1). 155 * 156 * @dev: usb device --- 155 unchanged lines hidden (view full) --- 312 fp->altsetting == 6) 313 pcm_format = SNDRV_PCM_FORMAT_S16_BE; 314 else 315 pcm_format = SNDRV_PCM_FORMAT_S16_LE; 316 break; 317 default: 318 pcm_format = SNDRV_PCM_FORMAT_S16_LE; 319 } | 132} 133 134 135/* 136 * parse the format descriptor and stores the possible sample rates 137 * on the audioformat table (audio class v1). 138 * 139 * @dev: usb device --- 155 unchanged lines hidden (view full) --- 295 fp->altsetting == 6) 296 pcm_format = SNDRV_PCM_FORMAT_S16_BE; 297 else 298 pcm_format = SNDRV_PCM_FORMAT_S16_LE; 299 break; 300 default: 301 pcm_format = SNDRV_PCM_FORMAT_S16_LE; 302 } |
303 fp->formats = 1uLL << pcm_format; |
|
320 } else { | 304 } else { |
321 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt, protocol); 322 if (pcm_format < 0) | 305 fp->formats = parse_audio_format_i_type(chip, fp, format, 306 fmt, protocol); 307 if (!fp->formats) |
323 return -1; 324 } 325 | 308 return -1; 309 } 310 |
326 fp->formats = 1uLL << pcm_format; 327 | |
328 /* gather possible sample rates */ 329 /* audio class v1 reports possible sample rates as part of the 330 * proprietary class specific descriptor. 331 * audio class v2 uses class specific EP0 range requests for that. 332 */ 333 switch (protocol) { 334 case UAC_VERSION_1: 335 fp->channels = fmt->bNrChannels; --- 110 unchanged lines hidden --- | 311 /* gather possible sample rates */ 312 /* audio class v1 reports possible sample rates as part of the 313 * proprietary class specific descriptor. 314 * audio class v2 uses class specific EP0 range requests for that. 315 */ 316 switch (protocol) { 317 case UAC_VERSION_1: 318 fp->channels = fmt->bNrChannels; --- 110 unchanged lines hidden --- |