aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/format.c
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2010-03-04 13:46:13 -0500
committerTakashi Iwai <tiwai@suse.de>2010-03-05 02:17:14 -0500
commite5779998bf8b70e48a6cc208c8b61b33bd6117ea (patch)
tree512568f0fc4b81eac8019522c10df5b81483bcca /sound/usb/format.c
parent3e1aebef6fb55e35668d2d7cf608cf03f30c904f (diff)
ALSA: usb-audio: refactor code
Clean up the usb audio driver by factoring out a lot of functions to separate files. Code for procfs, quirks, urbs, format parsers etc all got a new home now. Moved almost all special quirk handling to quirks.c and introduced new generic functions to handle them, so the exceptions do not pollute the whole driver. Renamed usbaudio.c to card.c because this is what it actually does now. Renamed usbmidi.c to midi.c for namespace clarity. Removed more things from usbaudio.h. The non-standard drivers were adopted accordingly. Signed-off-by: Daniel Mack <daniel@caiaq.de> Cc: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/format.c')
-rw-r--r--sound/usb/format.c445
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 */
40static 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 */
162static 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 */
226static 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
284err_free:
285 kfree(data);
286err:
287 return ret;
288}
289
290/*
291 * parse the format type I and III descriptors
292 */
293static 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 */
356static 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
407int 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