1 /*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * PCM driver
5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17 #include "pcm.h"
18 #include "chip.h"
19 #include "comm.h"
20
21 enum {
22 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4
23 };
24
25 /* keep next two synced with
26 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE */
27 static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 };
28 static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 };
29 static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
30 static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
31 static const int rates_alsaid[] = {
32 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000,
33 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000,
34 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 };
35
36 /* values to write to soundcard register for all samplerates */
37 static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
38 static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
39
40 enum { /* settings for pcm */
41 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024
42 };
43
44 enum { /* pcm streaming states */
45 STREAM_DISABLED, /* no pcm streaming */
46 STREAM_STARTING, /* pcm streaming requested, waiting to become ready */
47 STREAM_RUNNING, /* pcm streaming running */
48 STREAM_STOPPING
49 };
50
51 enum { /* pcm sample rates (also index into RATES_XXX[]) */
52 RATE_44KHZ,
53 RATE_48KHZ,
54 RATE_88KHZ,
55 RATE_96KHZ,
56 RATE_176KHZ,
57 RATE_192KHZ
58 };
59
60 static const struct snd_pcm_hardware pcm_hw = {
61 .info = SNDRV_PCM_INFO_MMAP |
62 SNDRV_PCM_INFO_INTERLEAVED |
63 SNDRV_PCM_INFO_BLOCK_TRANSFER |
64 SNDRV_PCM_INFO_MMAP_VALID |
65 SNDRV_PCM_INFO_BATCH,
66
67 .formats = SNDRV_PCM_FMTBIT_S24_LE,
68
69 .rates = SNDRV_PCM_RATE_44100 |
70 SNDRV_PCM_RATE_48000 |
71 SNDRV_PCM_RATE_88200 |
72 SNDRV_PCM_RATE_96000 |
73 SNDRV_PCM_RATE_176400 |
74 SNDRV_PCM_RATE_192000,
75
76 .rate_min = 44100,
77 .rate_max = 192000,
78 .channels_min = 1,
79 .channels_max = 0, /* set in pcm_open, depending on capture/playback */
80 .buffer_bytes_max = MAX_BUFSIZE,
81 .period_bytes_min = PCM_N_PACKETS_PER_URB * (PCM_MAX_PACKET_SIZE - 4),
82 .period_bytes_max = MAX_BUFSIZE,
83 .periods_min = 2,
84 .periods_max = 1024
85 };
86
usb6fire_pcm_set_rate(struct pcm_runtime * rt)87 static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)
88 {
89 int ret;
90 struct usb_device *device = rt->chip->dev;
91 struct comm_runtime *comm_rt = rt->chip->comm;
92
93 if (rt->rate >= ARRAY_SIZE(rates))
94 return -EINVAL;
95 /* disable streaming */
96 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x00);
97 if (ret < 0) {
98 snd_printk(KERN_ERR PREFIX "error stopping streaming while "
99 "setting samplerate %d.\n", rates[rt->rate]);
100 return ret;
101 }
102
103 ret = usb_set_interface(device, 1, rates_altsetting[rt->rate]);
104 if (ret < 0) {
105 snd_printk(KERN_ERR PREFIX "error setting interface "
106 "altsetting %d for samplerate %d.\n",
107 rates_altsetting[rt->rate], rates[rt->rate]);
108 return ret;
109 }
110
111 /* set soundcard clock */
112 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rt->rate],
113 rates_6fire_vh[rt->rate]);
114 if (ret < 0) {
115 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n",
116 rates[rt->rate]);
117 return ret;
118 }
119
120 /* enable analog inputs and outputs
121 * (one bit per stereo-channel) */
122 ret = comm_rt->write16(comm_rt, 0x02, 0x02,
123 (1 << (OUT_N_CHANNELS / 2)) - 1,
124 (1 << (IN_N_CHANNELS / 2)) - 1);
125 if (ret < 0) {
126 snd_printk(KERN_ERR PREFIX "error initializing analog channels "
127 "while setting samplerate %d.\n",
128 rates[rt->rate]);
129 return ret;
130 }
131 /* disable digital inputs and outputs */
132 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
133 if (ret < 0) {
134 snd_printk(KERN_ERR PREFIX "error initializing digital "
135 "channels while setting samplerate %d.\n",
136 rates[rt->rate]);
137 return ret;
138 }
139
140 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x01);
141 if (ret < 0) {
142 snd_printk(KERN_ERR PREFIX "error starting streaming while "
143 "setting samplerate %d.\n", rates[rt->rate]);
144 return ret;
145 }
146
147 rt->in_n_analog = IN_N_CHANNELS;
148 rt->out_n_analog = OUT_N_CHANNELS;
149 rt->in_packet_size = rates_in_packet_size[rt->rate];
150 rt->out_packet_size = rates_out_packet_size[rt->rate];
151 return 0;
152 }
153
usb6fire_pcm_get_substream(struct snd_pcm_substream * alsa_sub)154 static struct pcm_substream *usb6fire_pcm_get_substream(
155 struct snd_pcm_substream *alsa_sub)
156 {
157 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
158
159 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
160 return &rt->playback;
161 else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE)
162 return &rt->capture;
163 snd_printk(KERN_ERR PREFIX "error getting pcm substream slot.\n");
164 return NULL;
165 }
166
167 /* call with stream_mutex locked */
usb6fire_pcm_stream_stop(struct pcm_runtime * rt)168 static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
169 {
170 int i;
171
172 if (rt->stream_state != STREAM_DISABLED) {
173 for (i = 0; i < PCM_N_URBS; i++) {
174 usb_kill_urb(&rt->in_urbs[i].instance);
175 usb_kill_urb(&rt->out_urbs[i].instance);
176 }
177 rt->stream_state = STREAM_DISABLED;
178 }
179 }
180
181 /* call with stream_mutex locked */
usb6fire_pcm_stream_start(struct pcm_runtime * rt)182 static int usb6fire_pcm_stream_start(struct pcm_runtime *rt)
183 {
184 int ret;
185 int i;
186 int k;
187 struct usb_iso_packet_descriptor *packet;
188
189 if (rt->stream_state == STREAM_DISABLED) {
190 /* submit our in urbs */
191 rt->stream_wait_cond = false;
192 rt->stream_state = STREAM_STARTING;
193 for (i = 0; i < PCM_N_URBS; i++) {
194 for (k = 0; k < PCM_N_PACKETS_PER_URB; k++) {
195 packet = &rt->in_urbs[i].packets[k];
196 packet->offset = k * rt->in_packet_size;
197 packet->length = rt->in_packet_size;
198 packet->actual_length = 0;
199 packet->status = 0;
200 }
201 ret = usb_submit_urb(&rt->in_urbs[i].instance,
202 GFP_ATOMIC);
203 if (ret) {
204 usb6fire_pcm_stream_stop(rt);
205 return ret;
206 }
207 }
208
209 /* wait for first out urb to return (sent in in urb handler) */
210 wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond,
211 HZ);
212 if (rt->stream_wait_cond)
213 rt->stream_state = STREAM_RUNNING;
214 else {
215 usb6fire_pcm_stream_stop(rt);
216 return -EIO;
217 }
218 }
219 return 0;
220 }
221
222 /* call with substream locked */
usb6fire_pcm_capture(struct pcm_substream * sub,struct pcm_urb * urb)223 static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
224 {
225 int i;
226 int frame;
227 int frame_count;
228 unsigned int total_length = 0;
229 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
230 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
231 u32 *src = (u32 *) urb->buffer;
232 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
233 * (alsa_rt->frame_bits >> 3));
234 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
235 * (alsa_rt->frame_bits >> 3));
236 int bytes_per_frame = alsa_rt->channels << 2;
237
238 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
239 /* at least 4 header bytes for valid packet.
240 * after that: 32 bits per sample for analog channels */
241 if (urb->packets[i].actual_length > 4)
242 frame_count = (urb->packets[i].actual_length - 4)
243 / (rt->in_n_analog << 2);
244 else
245 frame_count = 0;
246
247 src = (u32 *) (urb->buffer + total_length);
248 src++; /* skip leading 4 bytes of every packet */
249 total_length += urb->packets[i].length;
250 for (frame = 0; frame < frame_count; frame++) {
251 memcpy(dest, src, bytes_per_frame);
252 dest += alsa_rt->channels;
253 src += rt->in_n_analog;
254 sub->dma_off++;
255 sub->period_off++;
256 if (dest == dest_end) {
257 sub->dma_off = 0;
258 dest = (u32 *) alsa_rt->dma_area;
259 }
260 }
261 }
262 }
263
264 /* call with substream locked */
usb6fire_pcm_playback(struct pcm_substream * sub,struct pcm_urb * urb)265 static void usb6fire_pcm_playback(struct pcm_substream *sub,
266 struct pcm_urb *urb)
267 {
268 int i;
269 int frame;
270 int frame_count;
271 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
272 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
273 u32 *src = (u32 *) (alsa_rt->dma_area + sub->dma_off
274 * (alsa_rt->frame_bits >> 3));
275 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
276 * (alsa_rt->frame_bits >> 3));
277 u32 *dest = (u32 *) urb->buffer;
278 int bytes_per_frame = alsa_rt->channels << 2;
279
280 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
281 /* at least 4 header bytes for valid packet.
282 * after that: 32 bits per sample for analog channels */
283 if (urb->packets[i].length > 4)
284 frame_count = (urb->packets[i].length - 4)
285 / (rt->out_n_analog << 2);
286 else
287 frame_count = 0;
288 dest++; /* skip leading 4 bytes of every frame */
289 for (frame = 0; frame < frame_count; frame++) {
290 memcpy(dest, src, bytes_per_frame);
291 src += alsa_rt->channels;
292 dest += rt->out_n_analog;
293 sub->dma_off++;
294 sub->period_off++;
295 if (src == src_end) {
296 src = (u32 *) alsa_rt->dma_area;
297 sub->dma_off = 0;
298 }
299 }
300 }
301 }
302
usb6fire_pcm_in_urb_handler(struct urb * usb_urb)303 static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
304 {
305 struct pcm_urb *in_urb = usb_urb->context;
306 struct pcm_urb *out_urb = in_urb->peer;
307 struct pcm_runtime *rt = in_urb->chip->pcm;
308 struct pcm_substream *sub;
309 unsigned long flags;
310 int total_length = 0;
311 int frame_count;
312 int frame;
313 int channel;
314 int i;
315 u8 *dest;
316
317 if (usb_urb->status || rt->panic || rt->stream_state == STREAM_STOPPING)
318 return;
319 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
320 if (in_urb->packets[i].status) {
321 rt->panic = true;
322 return;
323 }
324
325 if (rt->stream_state == STREAM_DISABLED) {
326 snd_printk(KERN_ERR PREFIX "internal error: "
327 "stream disabled in in-urb handler.\n");
328 return;
329 }
330
331 /* receive our capture data */
332 sub = &rt->capture;
333 spin_lock_irqsave(&sub->lock, flags);
334 if (sub->active) {
335 usb6fire_pcm_capture(sub, in_urb);
336 if (sub->period_off >= sub->instance->runtime->period_size) {
337 sub->period_off %= sub->instance->runtime->period_size;
338 spin_unlock_irqrestore(&sub->lock, flags);
339 snd_pcm_period_elapsed(sub->instance);
340 } else
341 spin_unlock_irqrestore(&sub->lock, flags);
342 } else
343 spin_unlock_irqrestore(&sub->lock, flags);
344
345 /* setup out urb structure */
346 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
347 out_urb->packets[i].offset = total_length;
348 out_urb->packets[i].length = (in_urb->packets[i].actual_length
349 - 4) / (rt->in_n_analog << 2)
350 * (rt->out_n_analog << 2) + 4;
351 out_urb->packets[i].status = 0;
352 total_length += out_urb->packets[i].length;
353 }
354 memset(out_urb->buffer, 0, total_length);
355
356 /* now send our playback data (if a free out urb was found) */
357 sub = &rt->playback;
358 spin_lock_irqsave(&sub->lock, flags);
359 if (sub->active) {
360 usb6fire_pcm_playback(sub, out_urb);
361 if (sub->period_off >= sub->instance->runtime->period_size) {
362 sub->period_off %= sub->instance->runtime->period_size;
363 spin_unlock_irqrestore(&sub->lock, flags);
364 snd_pcm_period_elapsed(sub->instance);
365 } else
366 spin_unlock_irqrestore(&sub->lock, flags);
367 } else
368 spin_unlock_irqrestore(&sub->lock, flags);
369
370 /* setup the 4th byte of each sample (0x40 for analog channels) */
371 dest = out_urb->buffer;
372 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
373 if (out_urb->packets[i].length >= 4) {
374 frame_count = (out_urb->packets[i].length - 4)
375 / (rt->out_n_analog << 2);
376 *(dest++) = 0xaa;
377 *(dest++) = 0xaa;
378 *(dest++) = frame_count;
379 *(dest++) = 0x00;
380 for (frame = 0; frame < frame_count; frame++)
381 for (channel = 0;
382 channel < rt->out_n_analog;
383 channel++) {
384 dest += 3; /* skip sample data */
385 *(dest++) = 0x40;
386 }
387 }
388 usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
389 usb_submit_urb(&in_urb->instance, GFP_ATOMIC);
390 }
391
usb6fire_pcm_out_urb_handler(struct urb * usb_urb)392 static void usb6fire_pcm_out_urb_handler(struct urb *usb_urb)
393 {
394 struct pcm_urb *urb = usb_urb->context;
395 struct pcm_runtime *rt = urb->chip->pcm;
396
397 if (rt->stream_state == STREAM_STARTING) {
398 rt->stream_wait_cond = true;
399 wake_up(&rt->stream_wait_queue);
400 }
401 }
402
usb6fire_pcm_open(struct snd_pcm_substream * alsa_sub)403 static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
404 {
405 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
406 struct pcm_substream *sub = NULL;
407 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
408
409 if (rt->panic)
410 return -EPIPE;
411
412 mutex_lock(&rt->stream_mutex);
413 alsa_rt->hw = pcm_hw;
414
415 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
416 if (rt->rate >= 0)
417 alsa_rt->hw.rates = rates_alsaid[rt->rate];
418 alsa_rt->hw.channels_max = OUT_N_CHANNELS;
419 sub = &rt->playback;
420 } else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) {
421 if (rt->rate >= 0)
422 alsa_rt->hw.rates = rates_alsaid[rt->rate];
423 alsa_rt->hw.channels_max = IN_N_CHANNELS;
424 sub = &rt->capture;
425 }
426
427 if (!sub) {
428 mutex_unlock(&rt->stream_mutex);
429 snd_printk(KERN_ERR PREFIX "invalid stream type.\n");
430 return -EINVAL;
431 }
432
433 sub->instance = alsa_sub;
434 sub->active = false;
435 mutex_unlock(&rt->stream_mutex);
436 return 0;
437 }
438
usb6fire_pcm_close(struct snd_pcm_substream * alsa_sub)439 static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
440 {
441 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
442 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
443 unsigned long flags;
444
445 if (rt->panic)
446 return 0;
447
448 mutex_lock(&rt->stream_mutex);
449 if (sub) {
450 /* deactivate substream */
451 spin_lock_irqsave(&sub->lock, flags);
452 sub->instance = NULL;
453 sub->active = false;
454 spin_unlock_irqrestore(&sub->lock, flags);
455
456 /* all substreams closed? if so, stop streaming */
457 if (!rt->playback.instance && !rt->capture.instance) {
458 usb6fire_pcm_stream_stop(rt);
459 rt->rate = -1;
460 }
461 }
462 mutex_unlock(&rt->stream_mutex);
463 return 0;
464 }
465
usb6fire_pcm_hw_params(struct snd_pcm_substream * alsa_sub,struct snd_pcm_hw_params * hw_params)466 static int usb6fire_pcm_hw_params(struct snd_pcm_substream *alsa_sub,
467 struct snd_pcm_hw_params *hw_params)
468 {
469 return snd_pcm_lib_malloc_pages(alsa_sub,
470 params_buffer_bytes(hw_params));
471 }
472
usb6fire_pcm_hw_free(struct snd_pcm_substream * alsa_sub)473 static int usb6fire_pcm_hw_free(struct snd_pcm_substream *alsa_sub)
474 {
475 return snd_pcm_lib_free_pages(alsa_sub);
476 }
477
usb6fire_pcm_prepare(struct snd_pcm_substream * alsa_sub)478 static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
479 {
480 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
481 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
482 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
483 int i;
484 int ret;
485
486 if (rt->panic)
487 return -EPIPE;
488 if (!sub)
489 return -ENODEV;
490
491 mutex_lock(&rt->stream_mutex);
492 sub->dma_off = 0;
493 sub->period_off = 0;
494
495 if (rt->stream_state == STREAM_DISABLED) {
496 for (i = 0; i < ARRAY_SIZE(rates); i++)
497 if (alsa_rt->rate == rates[i]) {
498 rt->rate = i;
499 break;
500 }
501 if (i == ARRAY_SIZE(rates)) {
502 mutex_unlock(&rt->stream_mutex);
503 snd_printk("invalid rate %d in prepare.\n",
504 alsa_rt->rate);
505 return -EINVAL;
506 }
507
508 ret = usb6fire_pcm_set_rate(rt);
509 if (ret) {
510 mutex_unlock(&rt->stream_mutex);
511 return ret;
512 }
513 ret = usb6fire_pcm_stream_start(rt);
514 if (ret) {
515 mutex_unlock(&rt->stream_mutex);
516 snd_printk(KERN_ERR PREFIX
517 "could not start pcm stream.\n");
518 return ret;
519 }
520 }
521 mutex_unlock(&rt->stream_mutex);
522 return 0;
523 }
524
usb6fire_pcm_trigger(struct snd_pcm_substream * alsa_sub,int cmd)525 static int usb6fire_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
526 {
527 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
528 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
529 unsigned long flags;
530
531 if (rt->panic)
532 return -EPIPE;
533 if (!sub)
534 return -ENODEV;
535
536 switch (cmd) {
537 case SNDRV_PCM_TRIGGER_START:
538 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
539 spin_lock_irqsave(&sub->lock, flags);
540 sub->active = true;
541 spin_unlock_irqrestore(&sub->lock, flags);
542 return 0;
543
544 case SNDRV_PCM_TRIGGER_STOP:
545 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
546 spin_lock_irqsave(&sub->lock, flags);
547 sub->active = false;
548 spin_unlock_irqrestore(&sub->lock, flags);
549 return 0;
550
551 default:
552 return -EINVAL;
553 }
554 }
555
usb6fire_pcm_pointer(struct snd_pcm_substream * alsa_sub)556 static snd_pcm_uframes_t usb6fire_pcm_pointer(
557 struct snd_pcm_substream *alsa_sub)
558 {
559 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
560 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
561 unsigned long flags;
562 snd_pcm_uframes_t ret;
563
564 if (rt->panic || !sub)
565 return SNDRV_PCM_STATE_XRUN;
566
567 spin_lock_irqsave(&sub->lock, flags);
568 ret = sub->dma_off;
569 spin_unlock_irqrestore(&sub->lock, flags);
570 return ret;
571 }
572
573 static struct snd_pcm_ops pcm_ops = {
574 .open = usb6fire_pcm_open,
575 .close = usb6fire_pcm_close,
576 .ioctl = snd_pcm_lib_ioctl,
577 .hw_params = usb6fire_pcm_hw_params,
578 .hw_free = usb6fire_pcm_hw_free,
579 .prepare = usb6fire_pcm_prepare,
580 .trigger = usb6fire_pcm_trigger,
581 .pointer = usb6fire_pcm_pointer,
582 };
583
usb6fire_pcm_init_urb(struct pcm_urb * urb,struct sfire_chip * chip,bool in,int ep,void (* handler)(struct urb *))584 static void __devinit usb6fire_pcm_init_urb(struct pcm_urb *urb,
585 struct sfire_chip *chip, bool in, int ep,
586 void (*handler)(struct urb *))
587 {
588 urb->chip = chip;
589 usb_init_urb(&urb->instance);
590 urb->instance.transfer_buffer = urb->buffer;
591 urb->instance.transfer_buffer_length =
592 PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE;
593 urb->instance.dev = chip->dev;
594 urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep)
595 : usb_sndisocpipe(chip->dev, ep);
596 urb->instance.interval = 1;
597 urb->instance.transfer_flags = URB_ISO_ASAP;
598 urb->instance.complete = handler;
599 urb->instance.context = urb;
600 urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
601 }
602
usb6fire_pcm_init(struct sfire_chip * chip)603 int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
604 {
605 int i;
606 int ret;
607 struct snd_pcm *pcm;
608 struct pcm_runtime *rt =
609 kzalloc(sizeof(struct pcm_runtime), GFP_KERNEL);
610
611 if (!rt)
612 return -ENOMEM;
613
614 rt->chip = chip;
615 rt->stream_state = STREAM_DISABLED;
616 rt->rate = -1;
617 init_waitqueue_head(&rt->stream_wait_queue);
618 mutex_init(&rt->stream_mutex);
619
620 spin_lock_init(&rt->playback.lock);
621 spin_lock_init(&rt->capture.lock);
622
623 for (i = 0; i < PCM_N_URBS; i++) {
624 usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP,
625 usb6fire_pcm_in_urb_handler);
626 usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP,
627 usb6fire_pcm_out_urb_handler);
628
629 rt->in_urbs[i].peer = &rt->out_urbs[i];
630 rt->out_urbs[i].peer = &rt->in_urbs[i];
631 }
632
633 ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
634 if (ret < 0) {
635 kfree(rt);
636 snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n");
637 return ret;
638 }
639
640 pcm->private_data = rt;
641 strcpy(pcm->name, "DMX 6Fire USB");
642 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
643 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops);
644
645 ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
646 SNDRV_DMA_TYPE_CONTINUOUS,
647 snd_dma_continuous_data(GFP_KERNEL),
648 MAX_BUFSIZE, MAX_BUFSIZE);
649 if (ret) {
650 kfree(rt);
651 snd_printk(KERN_ERR PREFIX
652 "error preallocating pcm buffers.\n");
653 return ret;
654 }
655 rt->instance = pcm;
656
657 chip->pcm = rt;
658 return 0;
659 }
660
usb6fire_pcm_abort(struct sfire_chip * chip)661 void usb6fire_pcm_abort(struct sfire_chip *chip)
662 {
663 struct pcm_runtime *rt = chip->pcm;
664 int i;
665
666 if (rt) {
667 rt->panic = true;
668
669 if (rt->playback.instance)
670 snd_pcm_stop(rt->playback.instance,
671 SNDRV_PCM_STATE_XRUN);
672 if (rt->capture.instance)
673 snd_pcm_stop(rt->capture.instance,
674 SNDRV_PCM_STATE_XRUN);
675
676 for (i = 0; i < PCM_N_URBS; i++) {
677 usb_poison_urb(&rt->in_urbs[i].instance);
678 usb_poison_urb(&rt->out_urbs[i].instance);
679 }
680
681 }
682 }
683
usb6fire_pcm_destroy(struct sfire_chip * chip)684 void usb6fire_pcm_destroy(struct sfire_chip *chip)
685 {
686 kfree(chip->pcm);
687 chip->pcm = NULL;
688 }
689