Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/usb/hiface/pcm.c
26425 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Linux driver for M2Tech hiFace compatible devices
4
*
5
* Copyright 2012-2013 (C) M2TECH S.r.l and Amarula Solutions B.V.
6
*
7
* Authors: Michael Trimarchi <[email protected]>
8
* Antonio Ospite <[email protected]>
9
*
10
* The driver is based on the work done in TerraTec DMX 6Fire USB
11
*/
12
13
#include <linux/slab.h>
14
#include <sound/pcm.h>
15
16
#include "pcm.h"
17
#include "chip.h"
18
19
#define OUT_EP 0x2
20
#define PCM_N_URBS 8
21
#define PCM_PACKET_SIZE 4096
22
#define PCM_BUFFER_SIZE (2 * PCM_N_URBS * PCM_PACKET_SIZE)
23
24
struct pcm_urb {
25
struct hiface_chip *chip;
26
27
struct urb instance;
28
struct usb_anchor submitted;
29
u8 *buffer;
30
};
31
32
struct pcm_substream {
33
spinlock_t lock;
34
struct snd_pcm_substream *instance;
35
36
bool active;
37
snd_pcm_uframes_t dma_off; /* current position in alsa dma_area */
38
snd_pcm_uframes_t period_off; /* current position in current period */
39
};
40
41
enum { /* pcm streaming states */
42
STREAM_DISABLED, /* no pcm streaming */
43
STREAM_STARTING, /* pcm streaming requested, waiting to become ready */
44
STREAM_RUNNING, /* pcm streaming running */
45
STREAM_STOPPING
46
};
47
48
struct pcm_runtime {
49
struct hiface_chip *chip;
50
struct snd_pcm *instance;
51
52
struct pcm_substream playback;
53
bool panic; /* if set driver won't do anymore pcm on device */
54
55
struct pcm_urb out_urbs[PCM_N_URBS];
56
57
struct mutex stream_mutex;
58
u8 stream_state; /* one of STREAM_XXX */
59
u8 extra_freq;
60
wait_queue_head_t stream_wait_queue;
61
bool stream_wait_cond;
62
};
63
64
static const unsigned int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000,
65
352800, 384000 };
66
static const struct snd_pcm_hw_constraint_list constraints_extra_rates = {
67
.count = ARRAY_SIZE(rates),
68
.list = rates,
69
.mask = 0,
70
};
71
72
static const struct snd_pcm_hardware pcm_hw = {
73
.info = SNDRV_PCM_INFO_MMAP |
74
SNDRV_PCM_INFO_INTERLEAVED |
75
SNDRV_PCM_INFO_BLOCK_TRANSFER |
76
SNDRV_PCM_INFO_PAUSE |
77
SNDRV_PCM_INFO_MMAP_VALID |
78
SNDRV_PCM_INFO_BATCH,
79
80
.formats = SNDRV_PCM_FMTBIT_S32_LE,
81
82
.rates = SNDRV_PCM_RATE_44100 |
83
SNDRV_PCM_RATE_48000 |
84
SNDRV_PCM_RATE_88200 |
85
SNDRV_PCM_RATE_96000 |
86
SNDRV_PCM_RATE_176400 |
87
SNDRV_PCM_RATE_192000,
88
89
.rate_min = 44100,
90
.rate_max = 192000, /* changes in hiface_pcm_open to support extra rates */
91
.channels_min = 2,
92
.channels_max = 2,
93
.buffer_bytes_max = PCM_BUFFER_SIZE,
94
.period_bytes_min = PCM_PACKET_SIZE,
95
.period_bytes_max = PCM_BUFFER_SIZE,
96
.periods_min = 2,
97
.periods_max = 1024
98
};
99
100
/* message values used to change the sample rate */
101
#define HIFACE_SET_RATE_REQUEST 0xb0
102
103
#define HIFACE_RATE_44100 0x43
104
#define HIFACE_RATE_48000 0x4b
105
#define HIFACE_RATE_88200 0x42
106
#define HIFACE_RATE_96000 0x4a
107
#define HIFACE_RATE_176400 0x40
108
#define HIFACE_RATE_192000 0x48
109
#define HIFACE_RATE_352800 0x58
110
#define HIFACE_RATE_384000 0x68
111
112
static int hiface_pcm_set_rate(struct pcm_runtime *rt, unsigned int rate)
113
{
114
struct usb_device *device = rt->chip->dev;
115
u16 rate_value;
116
int ret;
117
118
/* We are already sure that the rate is supported here thanks to
119
* ALSA constraints
120
*/
121
switch (rate) {
122
case 44100:
123
rate_value = HIFACE_RATE_44100;
124
break;
125
case 48000:
126
rate_value = HIFACE_RATE_48000;
127
break;
128
case 88200:
129
rate_value = HIFACE_RATE_88200;
130
break;
131
case 96000:
132
rate_value = HIFACE_RATE_96000;
133
break;
134
case 176400:
135
rate_value = HIFACE_RATE_176400;
136
break;
137
case 192000:
138
rate_value = HIFACE_RATE_192000;
139
break;
140
case 352800:
141
rate_value = HIFACE_RATE_352800;
142
break;
143
case 384000:
144
rate_value = HIFACE_RATE_384000;
145
break;
146
default:
147
dev_err(&device->dev, "Unsupported rate %d\n", rate);
148
return -EINVAL;
149
}
150
151
/*
152
* USBIO: Vendor 0xb0(wValue=0x0043, wIndex=0x0000)
153
* 43 b0 43 00 00 00 00 00
154
* USBIO: Vendor 0xb0(wValue=0x004b, wIndex=0x0000)
155
* 43 b0 4b 00 00 00 00 00
156
* This control message doesn't have any ack from the
157
* other side
158
*/
159
ret = usb_control_msg_send(device, 0,
160
HIFACE_SET_RATE_REQUEST,
161
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
162
rate_value, 0, NULL, 0, 100, GFP_KERNEL);
163
if (ret)
164
dev_err(&device->dev, "Error setting samplerate %d.\n", rate);
165
166
return ret;
167
}
168
169
static struct pcm_substream *hiface_pcm_get_substream(struct snd_pcm_substream
170
*alsa_sub)
171
{
172
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
173
struct device *device = &rt->chip->dev->dev;
174
175
if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
176
return &rt->playback;
177
178
dev_err(device, "Error getting pcm substream slot.\n");
179
return NULL;
180
}
181
182
/* call with stream_mutex locked */
183
static void hiface_pcm_stream_stop(struct pcm_runtime *rt)
184
{
185
int i, time;
186
187
if (rt->stream_state != STREAM_DISABLED) {
188
rt->stream_state = STREAM_STOPPING;
189
190
for (i = 0; i < PCM_N_URBS; i++) {
191
time = usb_wait_anchor_empty_timeout(
192
&rt->out_urbs[i].submitted, 100);
193
if (!time)
194
usb_kill_anchored_urbs(
195
&rt->out_urbs[i].submitted);
196
usb_kill_urb(&rt->out_urbs[i].instance);
197
}
198
199
rt->stream_state = STREAM_DISABLED;
200
}
201
}
202
203
/* call with stream_mutex locked */
204
static int hiface_pcm_stream_start(struct pcm_runtime *rt)
205
{
206
int ret = 0;
207
int i;
208
209
if (rt->stream_state == STREAM_DISABLED) {
210
211
/* reset panic state when starting a new stream */
212
rt->panic = false;
213
214
/* submit our out urbs zero init */
215
rt->stream_state = STREAM_STARTING;
216
for (i = 0; i < PCM_N_URBS; i++) {
217
memset(rt->out_urbs[i].buffer, 0, PCM_PACKET_SIZE);
218
usb_anchor_urb(&rt->out_urbs[i].instance,
219
&rt->out_urbs[i].submitted);
220
ret = usb_submit_urb(&rt->out_urbs[i].instance,
221
GFP_ATOMIC);
222
if (ret) {
223
hiface_pcm_stream_stop(rt);
224
return ret;
225
}
226
}
227
228
/* wait for first out urb to return (sent in urb handler) */
229
wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond,
230
HZ);
231
if (rt->stream_wait_cond) {
232
struct device *device = &rt->chip->dev->dev;
233
dev_dbg(device, "%s: Stream is running wakeup event\n",
234
__func__);
235
rt->stream_state = STREAM_RUNNING;
236
} else {
237
hiface_pcm_stream_stop(rt);
238
return -EIO;
239
}
240
}
241
return ret;
242
}
243
244
/* The hardware wants word-swapped 32-bit values */
245
static void memcpy_swahw32(u8 *dest, u8 *src, unsigned int n)
246
{
247
unsigned int i;
248
249
for (i = 0; i < n / 4; i++)
250
((u32 *)dest)[i] = swahw32(((u32 *)src)[i]);
251
}
252
253
/* call with substream locked */
254
/* returns true if a period elapsed */
255
static bool hiface_pcm_playback(struct pcm_substream *sub, struct pcm_urb *urb)
256
{
257
struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
258
struct device *device = &urb->chip->dev->dev;
259
u8 *source;
260
unsigned int pcm_buffer_size;
261
262
WARN_ON(alsa_rt->format != SNDRV_PCM_FORMAT_S32_LE);
263
264
pcm_buffer_size = snd_pcm_lib_buffer_bytes(sub->instance);
265
266
if (sub->dma_off + PCM_PACKET_SIZE <= pcm_buffer_size) {
267
dev_dbg(device, "%s: (1) buffer_size %#x dma_offset %#x\n", __func__,
268
(unsigned int) pcm_buffer_size,
269
(unsigned int) sub->dma_off);
270
271
source = alsa_rt->dma_area + sub->dma_off;
272
memcpy_swahw32(urb->buffer, source, PCM_PACKET_SIZE);
273
} else {
274
/* wrap around at end of ring buffer */
275
unsigned int len;
276
277
dev_dbg(device, "%s: (2) buffer_size %#x dma_offset %#x\n", __func__,
278
(unsigned int) pcm_buffer_size,
279
(unsigned int) sub->dma_off);
280
281
len = pcm_buffer_size - sub->dma_off;
282
283
source = alsa_rt->dma_area + sub->dma_off;
284
memcpy_swahw32(urb->buffer, source, len);
285
286
source = alsa_rt->dma_area;
287
memcpy_swahw32(urb->buffer + len, source,
288
PCM_PACKET_SIZE - len);
289
}
290
sub->dma_off += PCM_PACKET_SIZE;
291
if (sub->dma_off >= pcm_buffer_size)
292
sub->dma_off -= pcm_buffer_size;
293
294
sub->period_off += PCM_PACKET_SIZE;
295
if (sub->period_off >= alsa_rt->period_size) {
296
sub->period_off %= alsa_rt->period_size;
297
return true;
298
}
299
return false;
300
}
301
302
static void hiface_pcm_out_urb_handler(struct urb *usb_urb)
303
{
304
struct pcm_urb *out_urb = usb_urb->context;
305
struct pcm_runtime *rt = out_urb->chip->pcm;
306
struct pcm_substream *sub;
307
bool do_period_elapsed = false;
308
unsigned long flags;
309
int ret;
310
311
if (rt->panic || rt->stream_state == STREAM_STOPPING)
312
return;
313
314
if (unlikely(usb_urb->status == -ENOENT || /* unlinked */
315
usb_urb->status == -ENODEV || /* device removed */
316
usb_urb->status == -ECONNRESET || /* unlinked */
317
usb_urb->status == -ESHUTDOWN)) { /* device disabled */
318
goto out_fail;
319
}
320
321
if (rt->stream_state == STREAM_STARTING) {
322
rt->stream_wait_cond = true;
323
wake_up(&rt->stream_wait_queue);
324
}
325
326
/* now send our playback data (if a free out urb was found) */
327
sub = &rt->playback;
328
spin_lock_irqsave(&sub->lock, flags);
329
if (sub->active)
330
do_period_elapsed = hiface_pcm_playback(sub, out_urb);
331
else
332
memset(out_urb->buffer, 0, PCM_PACKET_SIZE);
333
334
spin_unlock_irqrestore(&sub->lock, flags);
335
336
if (do_period_elapsed)
337
snd_pcm_period_elapsed(sub->instance);
338
339
ret = usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
340
if (ret < 0)
341
goto out_fail;
342
343
return;
344
345
out_fail:
346
rt->panic = true;
347
}
348
349
static int hiface_pcm_open(struct snd_pcm_substream *alsa_sub)
350
{
351
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
352
struct pcm_substream *sub = NULL;
353
struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
354
int ret;
355
356
if (rt->panic)
357
return -EPIPE;
358
359
mutex_lock(&rt->stream_mutex);
360
alsa_rt->hw = pcm_hw;
361
362
if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
363
sub = &rt->playback;
364
365
if (!sub) {
366
struct device *device = &rt->chip->dev->dev;
367
mutex_unlock(&rt->stream_mutex);
368
dev_err(device, "Invalid stream type\n");
369
return -EINVAL;
370
}
371
372
if (rt->extra_freq) {
373
alsa_rt->hw.rates |= SNDRV_PCM_RATE_KNOT;
374
alsa_rt->hw.rate_max = 384000;
375
376
/* explicit constraints needed as we added SNDRV_PCM_RATE_KNOT */
377
ret = snd_pcm_hw_constraint_list(alsa_sub->runtime, 0,
378
SNDRV_PCM_HW_PARAM_RATE,
379
&constraints_extra_rates);
380
if (ret < 0) {
381
mutex_unlock(&rt->stream_mutex);
382
return ret;
383
}
384
}
385
386
sub->instance = alsa_sub;
387
sub->active = false;
388
mutex_unlock(&rt->stream_mutex);
389
return 0;
390
}
391
392
static int hiface_pcm_close(struct snd_pcm_substream *alsa_sub)
393
{
394
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
395
struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
396
unsigned long flags;
397
398
if (rt->panic)
399
return 0;
400
401
mutex_lock(&rt->stream_mutex);
402
if (sub) {
403
hiface_pcm_stream_stop(rt);
404
405
/* deactivate substream */
406
spin_lock_irqsave(&sub->lock, flags);
407
sub->instance = NULL;
408
sub->active = false;
409
spin_unlock_irqrestore(&sub->lock, flags);
410
411
}
412
mutex_unlock(&rt->stream_mutex);
413
return 0;
414
}
415
416
static int hiface_pcm_prepare(struct snd_pcm_substream *alsa_sub)
417
{
418
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
419
struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
420
struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
421
int ret;
422
423
if (rt->panic)
424
return -EPIPE;
425
if (!sub)
426
return -ENODEV;
427
428
mutex_lock(&rt->stream_mutex);
429
430
hiface_pcm_stream_stop(rt);
431
432
sub->dma_off = 0;
433
sub->period_off = 0;
434
435
if (rt->stream_state == STREAM_DISABLED) {
436
437
ret = hiface_pcm_set_rate(rt, alsa_rt->rate);
438
if (ret) {
439
mutex_unlock(&rt->stream_mutex);
440
return ret;
441
}
442
ret = hiface_pcm_stream_start(rt);
443
if (ret) {
444
mutex_unlock(&rt->stream_mutex);
445
return ret;
446
}
447
}
448
mutex_unlock(&rt->stream_mutex);
449
return 0;
450
}
451
452
static int hiface_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
453
{
454
struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
455
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
456
457
if (rt->panic)
458
return -EPIPE;
459
if (!sub)
460
return -ENODEV;
461
462
switch (cmd) {
463
case SNDRV_PCM_TRIGGER_START:
464
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
465
spin_lock_irq(&sub->lock);
466
sub->active = true;
467
spin_unlock_irq(&sub->lock);
468
return 0;
469
470
case SNDRV_PCM_TRIGGER_STOP:
471
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
472
spin_lock_irq(&sub->lock);
473
sub->active = false;
474
spin_unlock_irq(&sub->lock);
475
return 0;
476
477
default:
478
return -EINVAL;
479
}
480
}
481
482
static snd_pcm_uframes_t hiface_pcm_pointer(struct snd_pcm_substream *alsa_sub)
483
{
484
struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
485
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
486
unsigned long flags;
487
snd_pcm_uframes_t dma_offset;
488
489
if (rt->panic || !sub)
490
return SNDRV_PCM_POS_XRUN;
491
492
spin_lock_irqsave(&sub->lock, flags);
493
dma_offset = sub->dma_off;
494
spin_unlock_irqrestore(&sub->lock, flags);
495
return bytes_to_frames(alsa_sub->runtime, dma_offset);
496
}
497
498
static const struct snd_pcm_ops pcm_ops = {
499
.open = hiface_pcm_open,
500
.close = hiface_pcm_close,
501
.prepare = hiface_pcm_prepare,
502
.trigger = hiface_pcm_trigger,
503
.pointer = hiface_pcm_pointer,
504
};
505
506
static int hiface_pcm_init_urb(struct pcm_urb *urb,
507
struct hiface_chip *chip,
508
unsigned int ep,
509
void (*handler)(struct urb *))
510
{
511
urb->chip = chip;
512
usb_init_urb(&urb->instance);
513
514
urb->buffer = kzalloc(PCM_PACKET_SIZE, GFP_KERNEL);
515
if (!urb->buffer)
516
return -ENOMEM;
517
518
usb_fill_bulk_urb(&urb->instance, chip->dev,
519
usb_sndbulkpipe(chip->dev, ep), (void *)urb->buffer,
520
PCM_PACKET_SIZE, handler, urb);
521
if (usb_urb_ep_type_check(&urb->instance))
522
return -EINVAL;
523
init_usb_anchor(&urb->submitted);
524
525
return 0;
526
}
527
528
void hiface_pcm_abort(struct hiface_chip *chip)
529
{
530
struct pcm_runtime *rt = chip->pcm;
531
532
if (rt) {
533
rt->panic = true;
534
535
mutex_lock(&rt->stream_mutex);
536
hiface_pcm_stream_stop(rt);
537
mutex_unlock(&rt->stream_mutex);
538
}
539
}
540
541
static void hiface_pcm_destroy(struct hiface_chip *chip)
542
{
543
struct pcm_runtime *rt = chip->pcm;
544
int i;
545
546
for (i = 0; i < PCM_N_URBS; i++)
547
kfree(rt->out_urbs[i].buffer);
548
549
kfree(chip->pcm);
550
chip->pcm = NULL;
551
}
552
553
static void hiface_pcm_free(struct snd_pcm *pcm)
554
{
555
struct pcm_runtime *rt = pcm->private_data;
556
557
if (rt)
558
hiface_pcm_destroy(rt->chip);
559
}
560
561
int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq)
562
{
563
int i;
564
int ret;
565
struct snd_pcm *pcm;
566
struct pcm_runtime *rt;
567
568
rt = kzalloc(sizeof(*rt), GFP_KERNEL);
569
if (!rt)
570
return -ENOMEM;
571
572
rt->chip = chip;
573
rt->stream_state = STREAM_DISABLED;
574
if (extra_freq)
575
rt->extra_freq = 1;
576
577
init_waitqueue_head(&rt->stream_wait_queue);
578
mutex_init(&rt->stream_mutex);
579
spin_lock_init(&rt->playback.lock);
580
581
for (i = 0; i < PCM_N_URBS; i++) {
582
ret = hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP,
583
hiface_pcm_out_urb_handler);
584
if (ret < 0)
585
goto error;
586
}
587
588
ret = snd_pcm_new(chip->card, "USB-SPDIF Audio", 0, 1, 0, &pcm);
589
if (ret < 0) {
590
dev_err(&chip->dev->dev, "Cannot create pcm instance\n");
591
goto error;
592
}
593
594
pcm->private_data = rt;
595
pcm->private_free = hiface_pcm_free;
596
597
strscpy(pcm->name, "USB-SPDIF Audio", sizeof(pcm->name));
598
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
599
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC,
600
NULL, 0, 0);
601
602
rt->instance = pcm;
603
604
chip->pcm = rt;
605
return 0;
606
607
error:
608
for (i = 0; i < PCM_N_URBS; i++)
609
kfree(rt->out_urbs[i].buffer);
610
kfree(rt);
611
return ret;
612
}
613
614