diff options
Diffstat (limited to 'sound/usb/format.c')
-rw-r--r-- | sound/usb/format.c | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/sound/usb/format.c b/sound/usb/format.c new file mode 100644 index 000000000000..cbfe0c23dbd6 --- /dev/null +++ b/sound/usb/format.c | |||
@@ -0,0 +1,445 @@ | |||
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 | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * along with this program; if not, write to the Free Software | ||
14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/usb.h> | ||
20 | #include <linux/usb/audio.h> | ||
21 | |||
22 | #include <sound/core.h> | ||
23 | #include <sound/pcm.h> | ||
24 | |||
25 | #include "usbaudio.h" | ||
26 | #include "card.h" | ||
27 | #include "quirks.h" | ||
28 | #include "helper.h" | ||
29 | #include "debug.h" | ||
30 | |||
31 | /* | ||
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 | */ | ||
40 | static int parse_audio_format_i_type(struct snd_usb_audio *chip, | ||
41 | struct audioformat *fp, | ||
42 | int format, void *_fmt, | ||
43 | int protocol) | ||
44 | { | ||
45 | int pcm_format, i; | ||
46 | int sample_width, sample_bytes; | ||
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 | 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; | ||
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 | |||
78 | break; | ||
79 | } | ||
80 | |||
81 | default: | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | |||
85 | /* FIXME: correct endianess and sign? */ | ||
86 | pcm_format = -1; | ||
87 | |||
88 | switch (format) { | ||
89 | case UAC_FORMAT_TYPE_I_UNDEFINED: /* 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); | ||
92 | /* fall-through */ | ||
93 | case 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: | ||
102 | pcm_format = SNDRV_PCM_FORMAT_S8; | ||
103 | break; | ||
104 | case 2: | ||
105 | if (snd_usb_is_big_endian_format(chip, fp)) | ||
106 | pcm_format = SNDRV_PCM_FORMAT_S16_BE; /* grrr, big endian!! */ | ||
107 | else | ||
108 | pcm_format = SNDRV_PCM_FORMAT_S16_LE; | ||
109 | break; | ||
110 | case 3: | ||
111 | if (snd_usb_is_big_endian_format(chip, fp)) | ||
112 | pcm_format = SNDRV_PCM_FORMAT_S24_3BE; /* grrr, big endian!! */ | ||
113 | else | ||
114 | pcm_format = SNDRV_PCM_FORMAT_S24_3LE; | ||
115 | break; | ||
116 | case 4: | ||
117 | pcm_format = SNDRV_PCM_FORMAT_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 | } | ||
125 | break; | ||
126 | case UAC_FORMAT_TYPE_I_PCM8: | ||
127 | pcm_format = SNDRV_PCM_FORMAT_U8; | ||
128 | |||
129 | /* Dallas DS4201 workaround: it advertises U8 format, but really | ||
130 | supports S8. */ | ||
131 | 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", | ||
145 | chip->dev->devnum, fp->iface, fp->altsetting, format); | ||
146 | break; | ||
147 | } | ||
148 | return pcm_format; | ||
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 | ||
157 | * @fp: audioformat record | ||
158 | * @fmt: the format descriptor | ||
159 | * @offset: the start offset of descriptor pointing the rate type | ||
160 | * (7 for type I and II, 8 for type II) | ||
161 | */ | ||
162 | static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp, | ||
163 | unsigned char *fmt, int offset) | ||
164 | { | ||
165 | int nr_rates = fmt[offset]; | ||
166 | |||
167 | if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { | ||
168 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
169 | chip->dev->devnum, fp->iface, fp->altsetting); | ||
170 | return -1; | ||
171 | } | ||
172 | |||
173 | if (nr_rates) { | ||
174 | /* | ||
175 | * build the rate table and bitmap flags | ||
176 | */ | ||
177 | int r, idx; | ||
178 | |||
179 | fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); | ||
180 | if (fp->rate_table == NULL) { | ||
181 | snd_printk(KERN_ERR "cannot malloc\n"); | ||
182 | return -1; | ||
183 | } | ||
184 | |||
185 | fp->nr_rates = 0; | ||
186 | fp->rate_min = fp->rate_max = 0; | ||
187 | for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { | ||
188 | unsigned int rate = combine_triple(&fmt[idx]); | ||
189 | if (!rate) | ||
190 | continue; | ||
191 | /* C-Media CM6501 mislabels its 96 kHz altsetting */ | ||
192 | if (rate == 48000 && nr_rates == 1 && | ||
193 | (chip->usb_id == USB_ID(0x0d8c, 0x0201) || | ||
194 | chip->usb_id == USB_ID(0x0d8c, 0x0102)) && | ||
195 | fp->altsetting == 5 && fp->maxpacksize == 392) | ||
196 | rate = 96000; | ||
197 | /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */ | ||
198 | if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068)) | ||
199 | rate = 8000; | ||
200 | |||
201 | fp->rate_table[fp->nr_rates] = rate; | ||
202 | if (!fp->rate_min || rate < fp->rate_min) | ||
203 | fp->rate_min = rate; | ||
204 | if (!fp->rate_max || rate > fp->rate_max) | ||
205 | fp->rate_max = rate; | ||
206 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); | ||
207 | fp->nr_rates++; | ||
208 | } | ||
209 | if (!fp->nr_rates) { | ||
210 | hwc_debug("All rates were zero. Skipping format!\n"); | ||
211 | return -1; | ||
212 | } | ||
213 | } else { | ||
214 | /* continuous rates */ | ||
215 | fp->rates = SNDRV_PCM_RATE_CONTINUOUS; | ||
216 | fp->rate_min = combine_triple(&fmt[offset + 1]); | ||
217 | fp->rate_max = combine_triple(&fmt[offset + 4]); | ||
218 | } | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * parse the format descriptor and stores the possible sample rates | ||
224 | * on the audioformat table (audio class v2). | ||
225 | */ | ||
226 | static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | ||
227 | struct audioformat *fp, | ||
228 | struct usb_host_interface *iface) | ||
229 | { | ||
230 | struct usb_device *dev = chip->dev; | ||
231 | unsigned char tmp[2], *data; | ||
232 | int i, nr_rates, data_size, ret = 0; | ||
233 | |||
234 | /* get the number of sample rates first by only fetching 2 bytes */ | ||
235 | ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, | ||
236 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
237 | 0x0100, chip->clock_id << 8, tmp, sizeof(tmp), 1000); | ||
238 | |||
239 | if (ret < 0) { | ||
240 | snd_printk(KERN_ERR "unable to retrieve number of sample rates\n"); | ||
241 | goto err; | ||
242 | } | ||
243 | |||
244 | nr_rates = (tmp[1] << 8) | tmp[0]; | ||
245 | data_size = 2 + 12 * nr_rates; | ||
246 | data = kzalloc(data_size, GFP_KERNEL); | ||
247 | if (!data) { | ||
248 | ret = -ENOMEM; | ||
249 | goto err; | ||
250 | } | ||
251 | |||
252 | /* now get the full information */ | ||
253 | ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, | ||
254 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
255 | 0x0100, chip->clock_id << 8, data, data_size, 1000); | ||
256 | |||
257 | if (ret < 0) { | ||
258 | snd_printk(KERN_ERR "unable to retrieve sample rate range\n"); | ||
259 | ret = -EINVAL; | ||
260 | goto err_free; | ||
261 | } | ||
262 | |||
263 | fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); | ||
264 | if (!fp->rate_table) { | ||
265 | ret = -ENOMEM; | ||
266 | goto err_free; | ||
267 | } | ||
268 | |||
269 | fp->nr_rates = 0; | ||
270 | fp->rate_min = fp->rate_max = 0; | ||
271 | |||
272 | for (i = 0; i < nr_rates; i++) { | ||
273 | int rate = combine_quad(&data[2 + 12 * i]); | ||
274 | |||
275 | fp->rate_table[fp->nr_rates] = rate; | ||
276 | if (!fp->rate_min || rate < fp->rate_min) | ||
277 | fp->rate_min = rate; | ||
278 | if (!fp->rate_max || rate > fp->rate_max) | ||
279 | fp->rate_max = rate; | ||
280 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); | ||
281 | fp->nr_rates++; | ||
282 | } | ||
283 | |||
284 | err_free: | ||
285 | kfree(data); | ||
286 | err: | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | /* | ||
291 | * parse the format type I and III descriptors | ||
292 | */ | ||
293 | static int parse_audio_format_i(struct snd_usb_audio *chip, | ||
294 | struct audioformat *fp, | ||
295 | int format, void *_fmt, | ||
296 | struct usb_host_interface *iface) | ||
297 | { | ||
298 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); | ||
299 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; | ||
300 | int protocol = altsd->bInterfaceProtocol; | ||
301 | int pcm_format, ret; | ||
302 | |||
303 | if (fmt->bFormatType == UAC_FORMAT_TYPE_III) { | ||
304 | /* FIXME: the format type is really IECxxx | ||
305 | * but we give normal PCM format to get the existing | ||
306 | * apps working... | ||
307 | */ | ||
308 | switch (chip->usb_id) { | ||
309 | |||
310 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | ||
311 | if (chip->setup == 0x00 && | ||
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 | } | ||
320 | } else { | ||
321 | pcm_format = parse_audio_format_i_type(chip, fp, format, fmt, protocol); | ||
322 | if (pcm_format < 0) | ||
323 | return -1; | ||
324 | } | ||
325 | |||
326 | fp->format = 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; | ||
336 | ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7); | ||
337 | break; | ||
338 | case UAC_VERSION_2: | ||
339 | /* fp->channels is already set in this case */ | ||
340 | ret = parse_audio_format_rates_v2(chip, fp, iface); | ||
341 | break; | ||
342 | } | ||
343 | |||
344 | if (fp->channels < 1) { | ||
345 | snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", | ||
346 | chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); | ||
347 | return -1; | ||
348 | } | ||
349 | |||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | /* | ||
354 | * parse the format type II descriptor | ||
355 | */ | ||
356 | static int parse_audio_format_ii(struct snd_usb_audio *chip, | ||
357 | struct audioformat *fp, | ||
358 | int format, void *_fmt, | ||
359 | struct usb_host_interface *iface) | ||
360 | { | ||
361 | int brate, framesize, ret; | ||
362 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); | ||
363 | int protocol = altsd->bInterfaceProtocol; | ||
364 | |||
365 | switch (format) { | ||
366 | case UAC_FORMAT_TYPE_II_AC3: | ||
367 | /* FIXME: there is no AC3 format defined yet */ | ||
368 | // fp->format = SNDRV_PCM_FORMAT_AC3; | ||
369 | fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */ | ||
370 | break; | ||
371 | case UAC_FORMAT_TYPE_II_MPEG: | ||
372 | fp->format = SNDRV_PCM_FORMAT_MPEG; | ||
373 | break; | ||
374 | default: | ||
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); | ||
377 | fp->format = SNDRV_PCM_FORMAT_MPEG; | ||
378 | break; | ||
379 | } | ||
380 | |||
381 | fp->channels = 1; | ||
382 | |||
383 | switch (protocol) { | ||
384 | case UAC_VERSION_1: { | ||
385 | struct uac_format_type_ii_discrete_descriptor *fmt = _fmt; | ||
386 | brate = le16_to_cpu(fmt->wMaxBitRate); | ||
387 | framesize = le16_to_cpu(fmt->wSamplesPerFrame); | ||
388 | snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); | ||
389 | fp->frame_size = framesize; | ||
390 | ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */ | ||
391 | break; | ||
392 | } | ||
393 | case UAC_VERSION_2: { | ||
394 | struct uac_format_type_ii_ext_descriptor *fmt = _fmt; | ||
395 | brate = le16_to_cpu(fmt->wMaxBitRate); | ||
396 | framesize = le16_to_cpu(fmt->wSamplesPerFrame); | ||
397 | snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); | ||
398 | fp->frame_size = framesize; | ||
399 | ret = parse_audio_format_rates_v2(chip, fp, iface); | ||
400 | break; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | return ret; | ||
405 | } | ||
406 | |||
407 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, | ||
408 | int format, unsigned char *fmt, int stream, | ||
409 | struct usb_host_interface *iface) | ||
410 | { | ||
411 | int err; | ||
412 | |||
413 | switch (fmt[3]) { | ||
414 | case UAC_FORMAT_TYPE_I: | ||
415 | case UAC_FORMAT_TYPE_III: | ||
416 | err = parse_audio_format_i(chip, fp, format, fmt, iface); | ||
417 | break; | ||
418 | case UAC_FORMAT_TYPE_II: | ||
419 | err = parse_audio_format_ii(chip, fp, format, fmt, iface); | ||
420 | break; | ||
421 | default: | ||
422 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", | ||
423 | chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]); | ||
424 | return -1; | ||
425 | } | ||
426 | fp->fmt_type = fmt[3]; | ||
427 | if (err < 0) | ||
428 | return err; | ||
429 | #if 1 | ||
430 | /* FIXME: temporary hack for extigy/audigy 2 nx/zs */ | ||
431 | /* extigy apparently supports sample rates other than 48k | ||
432 | * but not in ordinary way. so we enable only 48k atm. | ||
433 | */ | ||
434 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || | ||
435 | chip->usb_id == USB_ID(0x041e, 0x3020) || | ||
436 | chip->usb_id == USB_ID(0x041e, 0x3061)) { | ||
437 | if (fmt[3] == UAC_FORMAT_TYPE_I && | ||
438 | fp->rates != SNDRV_PCM_RATE_48000 && | ||
439 | fp->rates != SNDRV_PCM_RATE_96000) | ||
440 | return -1; | ||
441 | } | ||
442 | #endif | ||
443 | return 0; | ||
444 | } | ||
445 | |||