2 * Linux driver for TerraTec DMX 6Fire USB
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Copyright: (C) Torsten Schenk
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
22 OUT_N_CHANNELS
= 6, IN_N_CHANNELS
= 4
25 /* keep next two synced with
26 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE
27 * and CONTROL_RATE_XXX in control.h */
28 static const int rates_in_packet_size
[] = { 228, 228, 420, 420, 404, 404 };
29 static const int rates_out_packet_size
[] = { 228, 228, 420, 420, 604, 604 };
30 static const int rates
[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
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
};
36 enum { /* settings for pcm */
37 OUT_EP
= 6, IN_EP
= 2, MAX_BUFSIZE
= 128 * 1024
40 enum { /* pcm streaming states */
41 STREAM_DISABLED
, /* no pcm streaming */
42 STREAM_STARTING
, /* pcm streaming requested, waiting to become ready */
43 STREAM_RUNNING
, /* pcm streaming running */
47 static const struct snd_pcm_hardware pcm_hw
= {
48 .info
= SNDRV_PCM_INFO_MMAP
|
49 SNDRV_PCM_INFO_INTERLEAVED
|
50 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
51 SNDRV_PCM_INFO_MMAP_VALID
|
54 .formats
= SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S32_LE
,
56 .rates
= SNDRV_PCM_RATE_44100
|
57 SNDRV_PCM_RATE_48000
|
58 SNDRV_PCM_RATE_88200
|
59 SNDRV_PCM_RATE_96000
|
60 SNDRV_PCM_RATE_176400
|
61 SNDRV_PCM_RATE_192000
,
66 .channels_max
= 0, /* set in pcm_open, depending on capture/playback */
67 .buffer_bytes_max
= MAX_BUFSIZE
,
68 .period_bytes_min
= PCM_N_PACKETS_PER_URB
* (PCM_MAX_PACKET_SIZE
- 4),
69 .period_bytes_max
= MAX_BUFSIZE
,
74 static int usb6fire_pcm_set_rate(struct pcm_runtime
*rt
)
77 struct control_runtime
*ctrl_rt
= rt
->chip
->control
;
79 ctrl_rt
->usb_streaming
= false;
80 ret
= ctrl_rt
->update_streaming(ctrl_rt
);
82 snd_printk(KERN_ERR PREFIX
"error stopping streaming while "
83 "setting samplerate %d.\n", rates
[rt
->rate
]);
87 ret
= ctrl_rt
->set_rate(ctrl_rt
, rt
->rate
);
89 snd_printk(KERN_ERR PREFIX
"error setting samplerate %d.\n",
94 ret
= ctrl_rt
->set_channels(ctrl_rt
, OUT_N_CHANNELS
, IN_N_CHANNELS
,
97 snd_printk(KERN_ERR PREFIX
"error initializing channels "
98 "while setting samplerate %d.\n",
103 ctrl_rt
->usb_streaming
= true;
104 ret
= ctrl_rt
->update_streaming(ctrl_rt
);
106 snd_printk(KERN_ERR PREFIX
"error starting streaming while "
107 "setting samplerate %d.\n", rates
[rt
->rate
]);
111 rt
->in_n_analog
= IN_N_CHANNELS
;
112 rt
->out_n_analog
= OUT_N_CHANNELS
;
113 rt
->in_packet_size
= rates_in_packet_size
[rt
->rate
];
114 rt
->out_packet_size
= rates_out_packet_size
[rt
->rate
];
118 static struct pcm_substream
*usb6fire_pcm_get_substream(
119 struct snd_pcm_substream
*alsa_sub
)
121 struct pcm_runtime
*rt
= snd_pcm_substream_chip(alsa_sub
);
123 if (alsa_sub
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
124 return &rt
->playback
;
125 else if (alsa_sub
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
127 snd_printk(KERN_ERR PREFIX
"error getting pcm substream slot.\n");
131 /* call with stream_mutex locked */
132 static void usb6fire_pcm_stream_stop(struct pcm_runtime
*rt
)
135 struct control_runtime
*ctrl_rt
= rt
->chip
->control
;
137 if (rt
->stream_state
!= STREAM_DISABLED
) {
138 for (i
= 0; i
< PCM_N_URBS
; i
++) {
139 usb_kill_urb(&rt
->in_urbs
[i
].instance
);
140 usb_kill_urb(&rt
->out_urbs
[i
].instance
);
142 ctrl_rt
->usb_streaming
= false;
143 ctrl_rt
->update_streaming(ctrl_rt
);
144 rt
->stream_state
= STREAM_DISABLED
;
148 /* call with stream_mutex locked */
149 static int usb6fire_pcm_stream_start(struct pcm_runtime
*rt
)
154 struct usb_iso_packet_descriptor
*packet
;
156 if (rt
->stream_state
== STREAM_DISABLED
) {
157 /* submit our in urbs */
158 rt
->stream_wait_cond
= false;
159 rt
->stream_state
= STREAM_STARTING
;
160 for (i
= 0; i
< PCM_N_URBS
; i
++) {
161 for (k
= 0; k
< PCM_N_PACKETS_PER_URB
; k
++) {
162 packet
= &rt
->in_urbs
[i
].packets
[k
];
163 packet
->offset
= k
* rt
->in_packet_size
;
164 packet
->length
= rt
->in_packet_size
;
165 packet
->actual_length
= 0;
168 ret
= usb_submit_urb(&rt
->in_urbs
[i
].instance
,
171 usb6fire_pcm_stream_stop(rt
);
176 /* wait for first out urb to return (sent in in urb handler) */
177 wait_event_timeout(rt
->stream_wait_queue
, rt
->stream_wait_cond
,
179 if (rt
->stream_wait_cond
)
180 rt
->stream_state
= STREAM_RUNNING
;
182 usb6fire_pcm_stream_stop(rt
);
189 /* call with substream locked */
190 static void usb6fire_pcm_capture(struct pcm_substream
*sub
, struct pcm_urb
*urb
)
195 unsigned int total_length
= 0;
196 struct pcm_runtime
*rt
= snd_pcm_substream_chip(sub
->instance
);
197 struct snd_pcm_runtime
*alsa_rt
= sub
->instance
->runtime
;
199 u32
*dest
= (u32
*) (alsa_rt
->dma_area
+ sub
->dma_off
200 * (alsa_rt
->frame_bits
>> 3));
201 u32
*dest_end
= (u32
*) (alsa_rt
->dma_area
+ alsa_rt
->buffer_size
202 * (alsa_rt
->frame_bits
>> 3));
203 int bytes_per_frame
= alsa_rt
->channels
<< 2;
205 for (i
= 0; i
< PCM_N_PACKETS_PER_URB
; i
++) {
206 /* at least 4 header bytes for valid packet.
207 * after that: 32 bits per sample for analog channels */
208 if (urb
->packets
[i
].actual_length
> 4)
209 frame_count
= (urb
->packets
[i
].actual_length
- 4)
210 / (rt
->in_n_analog
<< 2);
214 if (alsa_rt
->format
== SNDRV_PCM_FORMAT_S24_LE
)
215 src
= (u32
*) (urb
->buffer
+ total_length
);
216 else if (alsa_rt
->format
== SNDRV_PCM_FORMAT_S32_LE
)
217 src
= (u32
*) (urb
->buffer
- 1 + total_length
);
220 src
++; /* skip leading 4 bytes of every packet */
221 total_length
+= urb
->packets
[i
].length
;
222 for (frame
= 0; frame
< frame_count
; frame
++) {
223 memcpy(dest
, src
, bytes_per_frame
);
224 dest
+= alsa_rt
->channels
;
225 src
+= rt
->in_n_analog
;
228 if (dest
== dest_end
) {
230 dest
= (u32
*) alsa_rt
->dma_area
;
236 /* call with substream locked */
237 static void usb6fire_pcm_playback(struct pcm_substream
*sub
,
243 struct pcm_runtime
*rt
= snd_pcm_substream_chip(sub
->instance
);
244 struct snd_pcm_runtime
*alsa_rt
= sub
->instance
->runtime
;
245 u32
*src
= (u32
*) (alsa_rt
->dma_area
+ sub
->dma_off
246 * (alsa_rt
->frame_bits
>> 3));
247 u32
*src_end
= (u32
*) (alsa_rt
->dma_area
+ alsa_rt
->buffer_size
248 * (alsa_rt
->frame_bits
>> 3));
250 int bytes_per_frame
= alsa_rt
->channels
<< 2;
252 if (alsa_rt
->format
== SNDRV_PCM_FORMAT_S32_LE
)
253 dest
= (u32
*) (urb
->buffer
- 1);
254 else if (alsa_rt
->format
== SNDRV_PCM_FORMAT_S24_LE
)
255 dest
= (u32
*) (urb
->buffer
);
257 snd_printk(KERN_ERR PREFIX
"Unknown sample format.");
261 for (i
= 0; i
< PCM_N_PACKETS_PER_URB
; i
++) {
262 /* at least 4 header bytes for valid packet.
263 * after that: 32 bits per sample for analog channels */
264 if (urb
->packets
[i
].length
> 4)
265 frame_count
= (urb
->packets
[i
].length
- 4)
266 / (rt
->out_n_analog
<< 2);
269 dest
++; /* skip leading 4 bytes of every frame */
270 for (frame
= 0; frame
< frame_count
; frame
++) {
271 memcpy(dest
, src
, bytes_per_frame
);
272 src
+= alsa_rt
->channels
;
273 dest
+= rt
->out_n_analog
;
276 if (src
== src_end
) {
277 src
= (u32
*) alsa_rt
->dma_area
;
284 static void usb6fire_pcm_in_urb_handler(struct urb
*usb_urb
)
286 struct pcm_urb
*in_urb
= usb_urb
->context
;
287 struct pcm_urb
*out_urb
= in_urb
->peer
;
288 struct pcm_runtime
*rt
= in_urb
->chip
->pcm
;
289 struct pcm_substream
*sub
;
291 int total_length
= 0;
298 if (usb_urb
->status
|| rt
->panic
|| rt
->stream_state
== STREAM_STOPPING
)
300 for (i
= 0; i
< PCM_N_PACKETS_PER_URB
; i
++)
301 if (in_urb
->packets
[i
].status
) {
306 if (rt
->stream_state
== STREAM_DISABLED
) {
307 snd_printk(KERN_ERR PREFIX
"internal error: "
308 "stream disabled in in-urb handler.\n");
312 /* receive our capture data */
314 spin_lock_irqsave(&sub
->lock
, flags
);
316 usb6fire_pcm_capture(sub
, in_urb
);
317 if (sub
->period_off
>= sub
->instance
->runtime
->period_size
) {
318 sub
->period_off
%= sub
->instance
->runtime
->period_size
;
319 spin_unlock_irqrestore(&sub
->lock
, flags
);
320 snd_pcm_period_elapsed(sub
->instance
);
322 spin_unlock_irqrestore(&sub
->lock
, flags
);
324 spin_unlock_irqrestore(&sub
->lock
, flags
);
326 /* setup out urb structure */
327 for (i
= 0; i
< PCM_N_PACKETS_PER_URB
; i
++) {
328 out_urb
->packets
[i
].offset
= total_length
;
329 out_urb
->packets
[i
].length
= (in_urb
->packets
[i
].actual_length
330 - 4) / (rt
->in_n_analog
<< 2)
331 * (rt
->out_n_analog
<< 2) + 4;
332 out_urb
->packets
[i
].status
= 0;
333 total_length
+= out_urb
->packets
[i
].length
;
335 memset(out_urb
->buffer
, 0, total_length
);
337 /* now send our playback data (if a free out urb was found) */
339 spin_lock_irqsave(&sub
->lock
, flags
);
341 usb6fire_pcm_playback(sub
, out_urb
);
342 if (sub
->period_off
>= sub
->instance
->runtime
->period_size
) {
343 sub
->period_off
%= sub
->instance
->runtime
->period_size
;
344 spin_unlock_irqrestore(&sub
->lock
, flags
);
345 snd_pcm_period_elapsed(sub
->instance
);
347 spin_unlock_irqrestore(&sub
->lock
, flags
);
349 spin_unlock_irqrestore(&sub
->lock
, flags
);
351 /* setup the 4th byte of each sample (0x40 for analog channels) */
352 dest
= out_urb
->buffer
;
353 for (i
= 0; i
< PCM_N_PACKETS_PER_URB
; i
++)
354 if (out_urb
->packets
[i
].length
>= 4) {
355 frame_count
= (out_urb
->packets
[i
].length
- 4)
356 / (rt
->out_n_analog
<< 2);
359 *(dest
++) = frame_count
;
361 for (frame
= 0; frame
< frame_count
; frame
++)
363 channel
< rt
->out_n_analog
;
365 dest
+= 3; /* skip sample data */
369 usb_submit_urb(&out_urb
->instance
, GFP_ATOMIC
);
370 usb_submit_urb(&in_urb
->instance
, GFP_ATOMIC
);
373 static void usb6fire_pcm_out_urb_handler(struct urb
*usb_urb
)
375 struct pcm_urb
*urb
= usb_urb
->context
;
376 struct pcm_runtime
*rt
= urb
->chip
->pcm
;
378 if (rt
->stream_state
== STREAM_STARTING
) {
379 rt
->stream_wait_cond
= true;
380 wake_up(&rt
->stream_wait_queue
);
384 static int usb6fire_pcm_open(struct snd_pcm_substream
*alsa_sub
)
386 struct pcm_runtime
*rt
= snd_pcm_substream_chip(alsa_sub
);
387 struct pcm_substream
*sub
= NULL
;
388 struct snd_pcm_runtime
*alsa_rt
= alsa_sub
->runtime
;
393 mutex_lock(&rt
->stream_mutex
);
394 alsa_rt
->hw
= pcm_hw
;
396 if (alsa_sub
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
397 if (rt
->rate
< ARRAY_SIZE(rates
))
398 alsa_rt
->hw
.rates
= rates_alsaid
[rt
->rate
];
399 alsa_rt
->hw
.channels_max
= OUT_N_CHANNELS
;
401 } else if (alsa_sub
->stream
== SNDRV_PCM_STREAM_CAPTURE
) {
402 if (rt
->rate
< ARRAY_SIZE(rates
))
403 alsa_rt
->hw
.rates
= rates_alsaid
[rt
->rate
];
404 alsa_rt
->hw
.channels_max
= IN_N_CHANNELS
;
409 mutex_unlock(&rt
->stream_mutex
);
410 snd_printk(KERN_ERR PREFIX
"invalid stream type.\n");
414 sub
->instance
= alsa_sub
;
416 mutex_unlock(&rt
->stream_mutex
);
420 static int usb6fire_pcm_close(struct snd_pcm_substream
*alsa_sub
)
422 struct pcm_runtime
*rt
= snd_pcm_substream_chip(alsa_sub
);
423 struct pcm_substream
*sub
= usb6fire_pcm_get_substream(alsa_sub
);
429 mutex_lock(&rt
->stream_mutex
);
431 /* deactivate substream */
432 spin_lock_irqsave(&sub
->lock
, flags
);
433 sub
->instance
= NULL
;
435 spin_unlock_irqrestore(&sub
->lock
, flags
);
437 /* all substreams closed? if so, stop streaming */
438 if (!rt
->playback
.instance
&& !rt
->capture
.instance
) {
439 usb6fire_pcm_stream_stop(rt
);
440 rt
->rate
= ARRAY_SIZE(rates
);
443 mutex_unlock(&rt
->stream_mutex
);
447 static int usb6fire_pcm_hw_params(struct snd_pcm_substream
*alsa_sub
,
448 struct snd_pcm_hw_params
*hw_params
)
450 return snd_pcm_lib_malloc_pages(alsa_sub
,
451 params_buffer_bytes(hw_params
));
454 static int usb6fire_pcm_hw_free(struct snd_pcm_substream
*alsa_sub
)
456 return snd_pcm_lib_free_pages(alsa_sub
);
459 static int usb6fire_pcm_prepare(struct snd_pcm_substream
*alsa_sub
)
461 struct pcm_runtime
*rt
= snd_pcm_substream_chip(alsa_sub
);
462 struct pcm_substream
*sub
= usb6fire_pcm_get_substream(alsa_sub
);
463 struct snd_pcm_runtime
*alsa_rt
= alsa_sub
->runtime
;
471 mutex_lock(&rt
->stream_mutex
);
475 if (rt
->stream_state
== STREAM_DISABLED
) {
476 for (rt
->rate
= 0; rt
->rate
< ARRAY_SIZE(rates
); rt
->rate
++)
477 if (alsa_rt
->rate
== rates
[rt
->rate
])
479 if (rt
->rate
== ARRAY_SIZE(rates
)) {
480 mutex_unlock(&rt
->stream_mutex
);
481 snd_printk("invalid rate %d in prepare.\n",
486 ret
= usb6fire_pcm_set_rate(rt
);
488 mutex_unlock(&rt
->stream_mutex
);
491 ret
= usb6fire_pcm_stream_start(rt
);
493 mutex_unlock(&rt
->stream_mutex
);
494 snd_printk(KERN_ERR PREFIX
495 "could not start pcm stream.\n");
499 mutex_unlock(&rt
->stream_mutex
);
503 static int usb6fire_pcm_trigger(struct snd_pcm_substream
*alsa_sub
, int cmd
)
505 struct pcm_substream
*sub
= usb6fire_pcm_get_substream(alsa_sub
);
506 struct pcm_runtime
*rt
= snd_pcm_substream_chip(alsa_sub
);
515 case SNDRV_PCM_TRIGGER_START
:
516 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
517 spin_lock_irqsave(&sub
->lock
, flags
);
519 spin_unlock_irqrestore(&sub
->lock
, flags
);
522 case SNDRV_PCM_TRIGGER_STOP
:
523 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
524 spin_lock_irqsave(&sub
->lock
, flags
);
526 spin_unlock_irqrestore(&sub
->lock
, flags
);
534 static snd_pcm_uframes_t
usb6fire_pcm_pointer(
535 struct snd_pcm_substream
*alsa_sub
)
537 struct pcm_substream
*sub
= usb6fire_pcm_get_substream(alsa_sub
);
538 struct pcm_runtime
*rt
= snd_pcm_substream_chip(alsa_sub
);
540 snd_pcm_uframes_t ret
;
542 if (rt
->panic
|| !sub
)
543 return SNDRV_PCM_STATE_XRUN
;
545 spin_lock_irqsave(&sub
->lock
, flags
);
547 spin_unlock_irqrestore(&sub
->lock
, flags
);
551 static struct snd_pcm_ops pcm_ops
= {
552 .open
= usb6fire_pcm_open
,
553 .close
= usb6fire_pcm_close
,
554 .ioctl
= snd_pcm_lib_ioctl
,
555 .hw_params
= usb6fire_pcm_hw_params
,
556 .hw_free
= usb6fire_pcm_hw_free
,
557 .prepare
= usb6fire_pcm_prepare
,
558 .trigger
= usb6fire_pcm_trigger
,
559 .pointer
= usb6fire_pcm_pointer
,
562 static void __devinit
usb6fire_pcm_init_urb(struct pcm_urb
*urb
,
563 struct sfire_chip
*chip
, bool in
, int ep
,
564 void (*handler
)(struct urb
*))
567 usb_init_urb(&urb
->instance
);
568 urb
->instance
.transfer_buffer
= urb
->buffer
;
569 urb
->instance
.transfer_buffer_length
=
570 PCM_N_PACKETS_PER_URB
* PCM_MAX_PACKET_SIZE
;
571 urb
->instance
.dev
= chip
->dev
;
572 urb
->instance
.pipe
= in
? usb_rcvisocpipe(chip
->dev
, ep
)
573 : usb_sndisocpipe(chip
->dev
, ep
);
574 urb
->instance
.interval
= 1;
575 urb
->instance
.transfer_flags
= URB_ISO_ASAP
;
576 urb
->instance
.complete
= handler
;
577 urb
->instance
.context
= urb
;
578 urb
->instance
.number_of_packets
= PCM_N_PACKETS_PER_URB
;
581 int __devinit
usb6fire_pcm_init(struct sfire_chip
*chip
)
586 struct pcm_runtime
*rt
=
587 kzalloc(sizeof(struct pcm_runtime
), GFP_KERNEL
);
593 rt
->stream_state
= STREAM_DISABLED
;
594 rt
->rate
= ARRAY_SIZE(rates
);
595 init_waitqueue_head(&rt
->stream_wait_queue
);
596 mutex_init(&rt
->stream_mutex
);
598 spin_lock_init(&rt
->playback
.lock
);
599 spin_lock_init(&rt
->capture
.lock
);
601 for (i
= 0; i
< PCM_N_URBS
; i
++) {
602 usb6fire_pcm_init_urb(&rt
->in_urbs
[i
], chip
, true, IN_EP
,
603 usb6fire_pcm_in_urb_handler
);
604 usb6fire_pcm_init_urb(&rt
->out_urbs
[i
], chip
, false, OUT_EP
,
605 usb6fire_pcm_out_urb_handler
);
607 rt
->in_urbs
[i
].peer
= &rt
->out_urbs
[i
];
608 rt
->out_urbs
[i
].peer
= &rt
->in_urbs
[i
];
611 ret
= snd_pcm_new(chip
->card
, "DMX6FireUSB", 0, 1, 1, &pcm
);
614 snd_printk(KERN_ERR PREFIX
"cannot create pcm instance.\n");
618 pcm
->private_data
= rt
;
619 strcpy(pcm
->name
, "DMX 6Fire USB");
620 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_PLAYBACK
, &pcm_ops
);
621 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_CAPTURE
, &pcm_ops
);
623 ret
= snd_pcm_lib_preallocate_pages_for_all(pcm
,
624 SNDRV_DMA_TYPE_CONTINUOUS
,
625 snd_dma_continuous_data(GFP_KERNEL
),
626 MAX_BUFSIZE
, MAX_BUFSIZE
);
629 snd_printk(KERN_ERR PREFIX
630 "error preallocating pcm buffers.\n");
639 void usb6fire_pcm_abort(struct sfire_chip
*chip
)
641 struct pcm_runtime
*rt
= chip
->pcm
;
647 if (rt
->playback
.instance
)
648 snd_pcm_stop(rt
->playback
.instance
,
649 SNDRV_PCM_STATE_XRUN
);
650 if (rt
->capture
.instance
)
651 snd_pcm_stop(rt
->capture
.instance
,
652 SNDRV_PCM_STATE_XRUN
);
654 for (i
= 0; i
< PCM_N_URBS
; i
++) {
655 usb_poison_urb(&rt
->in_urbs
[i
].instance
);
656 usb_poison_urb(&rt
->out_urbs
[i
].instance
);
662 void usb6fire_pcm_destroy(struct sfire_chip
*chip
)