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