aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/pcm.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/pcm.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/pcm.c')
-rw-r--r--sound/usb/pcm.c845
1 files changed, 845 insertions, 0 deletions
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
new file mode 100644
index 000000000000..87863ccf9068
--- /dev/null
+++ b/sound/usb/pcm.c
@@ -0,0 +1,845 @@
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#include <linux/init.h>
18#include <linux/usb.h>
19#include <linux/usb/audio.h>
20
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24
25#include "usbaudio.h"
26#include "card.h"
27#include "quirks.h"
28#include "debug.h"
29#include "urb.h"
30#include "helper.h"
31#include "pcm.h"
32
33/*
34 * return the current pcm pointer. just based on the hwptr_done value.
35 */
36static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
37{
38 struct snd_usb_substream *subs;
39 unsigned int hwptr_done;
40
41 subs = (struct snd_usb_substream *)substream->runtime->private_data;
42 spin_lock(&subs->lock);
43 hwptr_done = subs->hwptr_done;
44 spin_unlock(&subs->lock);
45 return hwptr_done / (substream->runtime->frame_bits >> 3);
46}
47
48/*
49 * find a matching audio format
50 */
51static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
52 unsigned int rate, unsigned int channels)
53{
54 struct list_head *p;
55 struct audioformat *found = NULL;
56 int cur_attr = 0, attr;
57
58 list_for_each(p, &subs->fmt_list) {
59 struct audioformat *fp;
60 fp = list_entry(p, struct audioformat, list);
61 if (fp->format != format || fp->channels != channels)
62 continue;
63 if (rate < fp->rate_min || rate > fp->rate_max)
64 continue;
65 if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
66 unsigned int i;
67 for (i = 0; i < fp->nr_rates; i++)
68 if (fp->rate_table[i] == rate)
69 break;
70 if (i >= fp->nr_rates)
71 continue;
72 }
73 attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
74 if (! found) {
75 found = fp;
76 cur_attr = attr;
77 continue;
78 }
79 /* avoid async out and adaptive in if the other method
80 * supports the same format.
81 * this is a workaround for the case like
82 * M-audio audiophile USB.
83 */
84 if (attr != cur_attr) {
85 if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
86 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
87 (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
88 subs->direction == SNDRV_PCM_STREAM_CAPTURE))
89 continue;
90 if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
91 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
92 (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
93 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
94 found = fp;
95 cur_attr = attr;
96 continue;
97 }
98 }
99 /* find the format with the largest max. packet size */
100 if (fp->maxpacksize > found->maxpacksize) {
101 found = fp;
102 cur_attr = attr;
103 }
104 }
105 return found;
106}
107
108
109/*
110 * initialize the picth control and sample rate
111 */
112int snd_usb_init_pitch(struct usb_device *dev, int iface,
113 struct usb_host_interface *alts,
114 struct audioformat *fmt)
115{
116 unsigned int ep;
117 unsigned char data[1];
118 int err;
119
120 ep = get_endpoint(alts, 0)->bEndpointAddress;
121 /* if endpoint has pitch control, enable it */
122 if (fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL) {
123 data[0] = 1;
124 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
125 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
126 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) {
127 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
128 dev->devnum, iface, ep);
129 return err;
130 }
131 }
132 return 0;
133}
134
135int snd_usb_init_sample_rate(struct usb_device *dev, int iface,
136 struct usb_host_interface *alts,
137 struct audioformat *fmt, int rate)
138{
139 unsigned int ep;
140 unsigned char data[3];
141 int err;
142
143 ep = get_endpoint(alts, 0)->bEndpointAddress;
144 /* if endpoint has sampling rate control, set it */
145 if (fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE) {
146 int crate;
147 data[0] = rate;
148 data[1] = rate >> 8;
149 data[2] = rate >> 16;
150 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
151 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
152 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
153 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
154 dev->devnum, iface, fmt->altsetting, rate, ep);
155 return err;
156 }
157 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
158 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
159 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
160 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
161 dev->devnum, iface, fmt->altsetting, ep);
162 return 0; /* some devices don't support reading */
163 }
164 crate = data[0] | (data[1] << 8) | (data[2] << 16);
165 if (crate != rate) {
166 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
167 // runtime->rate = crate;
168 }
169 }
170 return 0;
171}
172
173/*
174 * find a matching format and set up the interface
175 */
176static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
177{
178 struct usb_device *dev = subs->dev;
179 struct usb_host_interface *alts;
180 struct usb_interface_descriptor *altsd;
181 struct usb_interface *iface;
182 unsigned int ep, attr;
183 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
184 int err;
185
186 iface = usb_ifnum_to_if(dev, fmt->iface);
187 if (WARN_ON(!iface))
188 return -EINVAL;
189 alts = &iface->altsetting[fmt->altset_idx];
190 altsd = get_iface_desc(alts);
191 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
192 return -EINVAL;
193
194 if (fmt == subs->cur_audiofmt)
195 return 0;
196
197 /* close the old interface */
198 if (subs->interface >= 0 && subs->interface != fmt->iface) {
199 if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
200 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
201 dev->devnum, fmt->iface, fmt->altsetting);
202 return -EIO;
203 }
204 subs->interface = -1;
205 subs->format = 0;
206 }
207
208 /* set interface */
209 if (subs->interface != fmt->iface || subs->format != fmt->altset_idx) {
210 if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) {
211 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
212 dev->devnum, fmt->iface, fmt->altsetting);
213 return -EIO;
214 }
215 snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting);
216 subs->interface = fmt->iface;
217 subs->format = fmt->altset_idx;
218 }
219
220 /* create a data pipe */
221 ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
222 if (is_playback)
223 subs->datapipe = usb_sndisocpipe(dev, ep);
224 else
225 subs->datapipe = usb_rcvisocpipe(dev, ep);
226 subs->datainterval = fmt->datainterval;
227 subs->syncpipe = subs->syncinterval = 0;
228 subs->maxpacksize = fmt->maxpacksize;
229 subs->fill_max = 0;
230
231 /* we need a sync pipe in async OUT or adaptive IN mode */
232 /* check the number of EP, since some devices have broken
233 * descriptors which fool us. if it has only one EP,
234 * assume it as adaptive-out or sync-in.
235 */
236 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
237 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
238 (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
239 altsd->bNumEndpoints >= 2) {
240 /* check sync-pipe endpoint */
241 /* ... and check descriptor size before accessing bSynchAddress
242 because there is a version of the SB Audigy 2 NX firmware lacking
243 the audio fields in the endpoint descriptors */
244 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
245 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
246 get_endpoint(alts, 1)->bSynchAddress != 0)) {
247 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
248 dev->devnum, fmt->iface, fmt->altsetting);
249 return -EINVAL;
250 }
251 ep = get_endpoint(alts, 1)->bEndpointAddress;
252 if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
253 (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
254 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
255 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
256 dev->devnum, fmt->iface, fmt->altsetting);
257 return -EINVAL;
258 }
259 ep &= USB_ENDPOINT_NUMBER_MASK;
260 if (is_playback)
261 subs->syncpipe = usb_rcvisocpipe(dev, ep);
262 else
263 subs->syncpipe = usb_sndisocpipe(dev, ep);
264 if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
265 get_endpoint(alts, 1)->bRefresh >= 1 &&
266 get_endpoint(alts, 1)->bRefresh <= 9)
267 subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
268 else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
269 subs->syncinterval = 1;
270 else if (get_endpoint(alts, 1)->bInterval >= 1 &&
271 get_endpoint(alts, 1)->bInterval <= 16)
272 subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
273 else
274 subs->syncinterval = 3;
275 }
276
277 /* always fill max packet size */
278 if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
279 subs->fill_max = 1;
280
281 if ((err = snd_usb_init_pitch(dev, subs->interface, alts, fmt)) < 0)
282 return err;
283
284 subs->cur_audiofmt = fmt;
285
286 snd_usb_set_format_quirk(subs, fmt);
287
288#if 0
289 printk(KERN_DEBUG
290 "setting done: format = %d, rate = %d..%d, channels = %d\n",
291 fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
292 printk(KERN_DEBUG
293 " datapipe = 0x%0x, syncpipe = 0x%0x\n",
294 subs->datapipe, subs->syncpipe);
295#endif
296
297 return 0;
298}
299
300/*
301 * hw_params callback
302 *
303 * allocate a buffer and set the given audio format.
304 *
305 * so far we use a physically linear buffer although packetize transfer
306 * doesn't need a continuous area.
307 * if sg buffer is supported on the later version of alsa, we'll follow
308 * that.
309 */
310static int snd_usb_hw_params(struct snd_pcm_substream *substream,
311 struct snd_pcm_hw_params *hw_params)
312{
313 struct snd_usb_substream *subs = substream->runtime->private_data;
314 struct audioformat *fmt;
315 unsigned int channels, rate, format;
316 int ret, changed;
317
318 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
319 params_buffer_bytes(hw_params));
320 if (ret < 0)
321 return ret;
322
323 format = params_format(hw_params);
324 rate = params_rate(hw_params);
325 channels = params_channels(hw_params);
326 fmt = find_format(subs, format, rate, channels);
327 if (!fmt) {
328 snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
329 format, rate, channels);
330 return -EINVAL;
331 }
332
333 changed = subs->cur_audiofmt != fmt ||
334 subs->period_bytes != params_period_bytes(hw_params) ||
335 subs->cur_rate != rate;
336 if ((ret = set_format(subs, fmt)) < 0)
337 return ret;
338
339 if (subs->cur_rate != rate) {
340 struct usb_host_interface *alts;
341 struct usb_interface *iface;
342 iface = usb_ifnum_to_if(subs->dev, fmt->iface);
343 alts = &iface->altsetting[fmt->altset_idx];
344 ret = snd_usb_init_sample_rate(subs->dev, subs->interface, alts, fmt, rate);
345 if (ret < 0)
346 return ret;
347 subs->cur_rate = rate;
348 }
349
350 if (changed) {
351 /* format changed */
352 snd_usb_release_substream_urbs(subs, 0);
353 /* influenced: period_bytes, channels, rate, format, */
354 ret = snd_usb_init_substream_urbs(subs, params_period_bytes(hw_params),
355 params_rate(hw_params),
356 snd_pcm_format_physical_width(params_format(hw_params)) *
357 params_channels(hw_params));
358 }
359
360 return ret;
361}
362
363/*
364 * hw_free callback
365 *
366 * reset the audio format and release the buffer
367 */
368static int snd_usb_hw_free(struct snd_pcm_substream *substream)
369{
370 struct snd_usb_substream *subs = substream->runtime->private_data;
371
372 subs->cur_audiofmt = NULL;
373 subs->cur_rate = 0;
374 subs->period_bytes = 0;
375 if (!subs->stream->chip->shutdown)
376 snd_usb_release_substream_urbs(subs, 0);
377 return snd_pcm_lib_free_vmalloc_buffer(substream);
378}
379
380/*
381 * prepare callback
382 *
383 * only a few subtle things...
384 */
385static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
386{
387 struct snd_pcm_runtime *runtime = substream->runtime;
388 struct snd_usb_substream *subs = runtime->private_data;
389
390 if (! subs->cur_audiofmt) {
391 snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
392 return -ENXIO;
393 }
394
395 /* some unit conversions in runtime */
396 subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
397 subs->curframesize = bytes_to_frames(runtime, subs->curpacksize);
398
399 /* reset the pointer */
400 subs->hwptr_done = 0;
401 subs->transfer_done = 0;
402 subs->phase = 0;
403 runtime->delay = 0;
404
405 return snd_usb_substream_prepare(subs, runtime);
406}
407
408static struct snd_pcm_hardware snd_usb_hardware =
409{
410 .info = SNDRV_PCM_INFO_MMAP |
411 SNDRV_PCM_INFO_MMAP_VALID |
412 SNDRV_PCM_INFO_BATCH |
413 SNDRV_PCM_INFO_INTERLEAVED |
414 SNDRV_PCM_INFO_BLOCK_TRANSFER |
415 SNDRV_PCM_INFO_PAUSE,
416 .buffer_bytes_max = 1024 * 1024,
417 .period_bytes_min = 64,
418 .period_bytes_max = 512 * 1024,
419 .periods_min = 2,
420 .periods_max = 1024,
421};
422
423static int hw_check_valid_format(struct snd_usb_substream *subs,
424 struct snd_pcm_hw_params *params,
425 struct audioformat *fp)
426{
427 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
428 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);
430 struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
431 unsigned int ptime;
432
433 /* check the format */
434 if (!snd_mask_test(fmts, fp->format)) {
435 hwc_debug(" > check: no supported format %d\n", fp->format);
436 return 0;
437 }
438 /* check the channels */
439 if (fp->channels < ct->min || fp->channels > ct->max) {
440 hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
441 return 0;
442 }
443 /* check the rate is within the range */
444 if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
445 hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max);
446 return 0;
447 }
448 if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
449 hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
450 return 0;
451 }
452 /* check whether the period time is >= the data packet interval */
453 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
454 ptime = 125 * (1 << fp->datainterval);
455 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
456 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
457 return 0;
458 }
459 }
460 return 1;
461}
462
463static int hw_rule_rate(struct snd_pcm_hw_params *params,
464 struct snd_pcm_hw_rule *rule)
465{
466 struct snd_usb_substream *subs = rule->private;
467 struct list_head *p;
468 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
469 unsigned int rmin, rmax;
470 int changed;
471
472 hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
473 changed = 0;
474 rmin = rmax = 0;
475 list_for_each(p, &subs->fmt_list) {
476 struct audioformat *fp;
477 fp = list_entry(p, struct audioformat, list);
478 if (!hw_check_valid_format(subs, params, fp))
479 continue;
480 if (changed++) {
481 if (rmin > fp->rate_min)
482 rmin = fp->rate_min;
483 if (rmax < fp->rate_max)
484 rmax = fp->rate_max;
485 } else {
486 rmin = fp->rate_min;
487 rmax = fp->rate_max;
488 }
489 }
490
491 if (!changed) {
492 hwc_debug(" --> get empty\n");
493 it->empty = 1;
494 return -EINVAL;
495 }
496
497 changed = 0;
498 if (it->min < rmin) {
499 it->min = rmin;
500 it->openmin = 0;
501 changed = 1;
502 }
503 if (it->max > rmax) {
504 it->max = rmax;
505 it->openmax = 0;
506 changed = 1;
507 }
508 if (snd_interval_checkempty(it)) {
509 it->empty = 1;
510 return -EINVAL;
511 }
512 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
513 return changed;
514}
515
516
517static int hw_rule_channels(struct snd_pcm_hw_params *params,
518 struct snd_pcm_hw_rule *rule)
519{
520 struct snd_usb_substream *subs = rule->private;
521 struct list_head *p;
522 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
523 unsigned int rmin, rmax;
524 int changed;
525
526 hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
527 changed = 0;
528 rmin = rmax = 0;
529 list_for_each(p, &subs->fmt_list) {
530 struct audioformat *fp;
531 fp = list_entry(p, struct audioformat, list);
532 if (!hw_check_valid_format(subs, params, fp))
533 continue;
534 if (changed++) {
535 if (rmin > fp->channels)
536 rmin = fp->channels;
537 if (rmax < fp->channels)
538 rmax = fp->channels;
539 } else {
540 rmin = fp->channels;
541 rmax = fp->channels;
542 }
543 }
544
545 if (!changed) {
546 hwc_debug(" --> get empty\n");
547 it->empty = 1;
548 return -EINVAL;
549 }
550
551 changed = 0;
552 if (it->min < rmin) {
553 it->min = rmin;
554 it->openmin = 0;
555 changed = 1;
556 }
557 if (it->max > rmax) {
558 it->max = rmax;
559 it->openmax = 0;
560 changed = 1;
561 }
562 if (snd_interval_checkempty(it)) {
563 it->empty = 1;
564 return -EINVAL;
565 }
566 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
567 return changed;
568}
569
570static int hw_rule_format(struct snd_pcm_hw_params *params,
571 struct snd_pcm_hw_rule *rule)
572{
573 struct snd_usb_substream *subs = rule->private;
574 struct list_head *p;
575 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
576 u64 fbits;
577 u32 oldbits[2];
578 int changed;
579
580 hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
581 fbits = 0;
582 list_for_each(p, &subs->fmt_list) {
583 struct audioformat *fp;
584 fp = list_entry(p, struct audioformat, list);
585 if (!hw_check_valid_format(subs, params, fp))
586 continue;
587 fbits |= (1ULL << fp->format);
588 }
589
590 oldbits[0] = fmt->bits[0];
591 oldbits[1] = fmt->bits[1];
592 fmt->bits[0] &= (u32)fbits;
593 fmt->bits[1] &= (u32)(fbits >> 32);
594 if (!fmt->bits[0] && !fmt->bits[1]) {
595 hwc_debug(" --> get empty\n");
596 return -EINVAL;
597 }
598 changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
599 hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
600 return changed;
601}
602
603static int hw_rule_period_time(struct snd_pcm_hw_params *params,
604 struct snd_pcm_hw_rule *rule)
605{
606 struct snd_usb_substream *subs = rule->private;
607 struct audioformat *fp;
608 struct snd_interval *it;
609 unsigned char min_datainterval;
610 unsigned int pmin;
611 int changed;
612
613 it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
614 hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
615 min_datainterval = 0xff;
616 list_for_each_entry(fp, &subs->fmt_list, list) {
617 if (!hw_check_valid_format(subs, params, fp))
618 continue;
619 min_datainterval = min(min_datainterval, fp->datainterval);
620 }
621 if (min_datainterval == 0xff) {
622 hwc_debug(" --> get emtpy\n");
623 it->empty = 1;
624 return -EINVAL;
625 }
626 pmin = 125 * (1 << min_datainterval);
627 changed = 0;
628 if (it->min < pmin) {
629 it->min = pmin;
630 it->openmin = 0;
631 changed = 1;
632 }
633 if (snd_interval_checkempty(it)) {
634 it->empty = 1;
635 return -EINVAL;
636 }
637 hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
638 return changed;
639}
640
641/*
642 * If the device supports unusual bit rates, does the request meet these?
643 */
644static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
645 struct snd_usb_substream *subs)
646{
647 struct audioformat *fp;
648 int count = 0, needs_knot = 0;
649 int err;
650
651 list_for_each_entry(fp, &subs->fmt_list, list) {
652 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
653 return 0;
654 count += fp->nr_rates;
655 if (fp->rates & SNDRV_PCM_RATE_KNOT)
656 needs_knot = 1;
657 }
658 if (!needs_knot)
659 return 0;
660
661 subs->rate_list.count = count;
662 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
663 subs->rate_list.mask = 0;
664 count = 0;
665 list_for_each_entry(fp, &subs->fmt_list, list) {
666 int i;
667 for (i = 0; i < fp->nr_rates; i++)
668 subs->rate_list.list[count++] = fp->rate_table[i];
669 }
670 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
671 &subs->rate_list);
672 if (err < 0)
673 return err;
674
675 return 0;
676}
677
678
679/*
680 * set up the runtime hardware information.
681 */
682
683static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
684{
685 struct list_head *p;
686 unsigned int pt, ptmin;
687 int param_period_time_if_needed;
688 int err;
689
690 runtime->hw.formats = subs->formats;
691
692 runtime->hw.rate_min = 0x7fffffff;
693 runtime->hw.rate_max = 0;
694 runtime->hw.channels_min = 256;
695 runtime->hw.channels_max = 0;
696 runtime->hw.rates = 0;
697 ptmin = UINT_MAX;
698 /* check min/max rates and channels */
699 list_for_each(p, &subs->fmt_list) {
700 struct audioformat *fp;
701 fp = list_entry(p, struct audioformat, list);
702 runtime->hw.rates |= fp->rates;
703 if (runtime->hw.rate_min > fp->rate_min)
704 runtime->hw.rate_min = fp->rate_min;
705 if (runtime->hw.rate_max < fp->rate_max)
706 runtime->hw.rate_max = fp->rate_max;
707 if (runtime->hw.channels_min > fp->channels)
708 runtime->hw.channels_min = fp->channels;
709 if (runtime->hw.channels_max < fp->channels)
710 runtime->hw.channels_max = fp->channels;
711 if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
712 /* FIXME: there might be more than one audio formats... */
713 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
714 fp->frame_size;
715 }
716 pt = 125 * (1 << fp->datainterval);
717 ptmin = min(ptmin, pt);
718 }
719
720 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
721 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
722 /* full speed devices have fixed data packet interval */
723 ptmin = 1000;
724 if (ptmin == 1000)
725 /* if period time doesn't go below 1 ms, no rules needed */
726 param_period_time_if_needed = -1;
727 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
728 ptmin, UINT_MAX);
729
730 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
731 hw_rule_rate, subs,
732 SNDRV_PCM_HW_PARAM_FORMAT,
733 SNDRV_PCM_HW_PARAM_CHANNELS,
734 param_period_time_if_needed,
735 -1)) < 0)
736 return err;
737 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
738 hw_rule_channels, subs,
739 SNDRV_PCM_HW_PARAM_FORMAT,
740 SNDRV_PCM_HW_PARAM_RATE,
741 param_period_time_if_needed,
742 -1)) < 0)
743 return err;
744 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
745 hw_rule_format, subs,
746 SNDRV_PCM_HW_PARAM_RATE,
747 SNDRV_PCM_HW_PARAM_CHANNELS,
748 param_period_time_if_needed,
749 -1)) < 0)
750 return err;
751 if (param_period_time_if_needed >= 0) {
752 err = snd_pcm_hw_rule_add(runtime, 0,
753 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
754 hw_rule_period_time, subs,
755 SNDRV_PCM_HW_PARAM_FORMAT,
756 SNDRV_PCM_HW_PARAM_CHANNELS,
757 SNDRV_PCM_HW_PARAM_RATE,
758 -1);
759 if (err < 0)
760 return err;
761 }
762 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
763 return err;
764 return 0;
765}
766
767static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
768{
769 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
770 struct snd_pcm_runtime *runtime = substream->runtime;
771 struct snd_usb_substream *subs = &as->substream[direction];
772
773 subs->interface = -1;
774 subs->format = 0;
775 runtime->hw = snd_usb_hardware;
776 runtime->private_data = subs;
777 subs->pcm_substream = substream;
778 return setup_hw_info(runtime, subs);
779}
780
781static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
782{
783 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
784 struct snd_usb_substream *subs = &as->substream[direction];
785
786 if (!as->chip->shutdown && subs->interface >= 0) {
787 usb_set_interface(subs->dev, subs->interface, 0);
788 subs->interface = -1;
789 }
790 subs->pcm_substream = NULL;
791 return 0;
792}
793
794static int snd_usb_playback_open(struct snd_pcm_substream *substream)
795{
796 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
797}
798
799static int snd_usb_playback_close(struct snd_pcm_substream *substream)
800{
801 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
802}
803
804static int snd_usb_capture_open(struct snd_pcm_substream *substream)
805{
806 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
807}
808
809static int snd_usb_capture_close(struct snd_pcm_substream *substream)
810{
811 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
812}
813
814static struct snd_pcm_ops snd_usb_playback_ops = {
815 .open = snd_usb_playback_open,
816 .close = snd_usb_playback_close,
817 .ioctl = snd_pcm_lib_ioctl,
818 .hw_params = snd_usb_hw_params,
819 .hw_free = snd_usb_hw_free,
820 .prepare = snd_usb_pcm_prepare,
821 .trigger = snd_usb_substream_playback_trigger,
822 .pointer = snd_usb_pcm_pointer,
823 .page = snd_pcm_lib_get_vmalloc_page,
824 .mmap = snd_pcm_lib_mmap_vmalloc,
825};
826
827static struct snd_pcm_ops snd_usb_capture_ops = {
828 .open = snd_usb_capture_open,
829 .close = snd_usb_capture_close,
830 .ioctl = snd_pcm_lib_ioctl,
831 .hw_params = snd_usb_hw_params,
832 .hw_free = snd_usb_hw_free,
833 .prepare = snd_usb_pcm_prepare,
834 .trigger = snd_usb_substream_capture_trigger,
835 .pointer = snd_usb_pcm_pointer,
836 .page = snd_pcm_lib_get_vmalloc_page,
837 .mmap = snd_pcm_lib_mmap_vmalloc,
838};
839
840void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream)
841{
842 snd_pcm_set_ops(pcm, stream,
843 stream == SNDRV_PCM_STREAM_PLAYBACK ?
844 &snd_usb_playback_ops : &snd_usb_capture_ops);
845}