Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/drivers/aloop.c
10814 views
1
/*
2
* Loopback soundcard
3
*
4
* Original code:
5
* Copyright (c) by Jaroslav Kysela <[email protected]>
6
*
7
* More accurate positioning and full-duplex support:
8
* Copyright (c) Ahmet İnan <ainan at mathematik.uni-freiburg.de>
9
*
10
* Major (almost complete) rewrite:
11
* Copyright (c) by Takashi Iwai <[email protected]>
12
*
13
* A next major update in 2010 (separate timers for playback and capture):
14
* Copyright (c) Jaroslav Kysela <[email protected]>
15
*
16
* This program is free software; you can redistribute it and/or modify
17
* it under the terms of the GNU General Public License as published by
18
* the Free Software Foundation; either version 2 of the License, or
19
* (at your option) any later version.
20
*
21
* This program is distributed in the hope that it will be useful,
22
* but WITHOUT ANY WARRANTY; without even the implied warranty of
23
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
* GNU General Public License for more details.
25
*
26
* You should have received a copy of the GNU General Public License
27
* along with this program; if not, write to the Free Software
28
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29
*
30
*/
31
32
#include <linux/init.h>
33
#include <linux/jiffies.h>
34
#include <linux/slab.h>
35
#include <linux/time.h>
36
#include <linux/wait.h>
37
#include <linux/moduleparam.h>
38
#include <linux/platform_device.h>
39
#include <sound/core.h>
40
#include <sound/control.h>
41
#include <sound/pcm.h>
42
#include <sound/info.h>
43
#include <sound/initval.h>
44
45
MODULE_AUTHOR("Jaroslav Kysela <[email protected]>");
46
MODULE_DESCRIPTION("A loopback soundcard");
47
MODULE_LICENSE("GPL");
48
MODULE_SUPPORTED_DEVICE("{{ALSA,Loopback soundcard}}");
49
50
#define MAX_PCM_SUBSTREAMS 8
51
52
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
53
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
54
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
55
static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
56
static int pcm_notify[SNDRV_CARDS];
57
58
module_param_array(index, int, NULL, 0444);
59
MODULE_PARM_DESC(index, "Index value for loopback soundcard.");
60
module_param_array(id, charp, NULL, 0444);
61
MODULE_PARM_DESC(id, "ID string for loopback soundcard.");
62
module_param_array(enable, bool, NULL, 0444);
63
MODULE_PARM_DESC(enable, "Enable this loopback soundcard.");
64
module_param_array(pcm_substreams, int, NULL, 0444);
65
MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver.");
66
module_param_array(pcm_notify, int, NULL, 0444);
67
MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes.");
68
69
#define NO_PITCH 100000
70
71
struct loopback_pcm;
72
73
struct loopback_cable {
74
spinlock_t lock;
75
struct loopback_pcm *streams[2];
76
struct snd_pcm_hardware hw;
77
/* flags */
78
unsigned int valid;
79
unsigned int running;
80
unsigned int pause;
81
};
82
83
struct loopback_setup {
84
unsigned int notify: 1;
85
unsigned int rate_shift;
86
unsigned int format;
87
unsigned int rate;
88
unsigned int channels;
89
struct snd_ctl_elem_id active_id;
90
struct snd_ctl_elem_id format_id;
91
struct snd_ctl_elem_id rate_id;
92
struct snd_ctl_elem_id channels_id;
93
};
94
95
struct loopback {
96
struct snd_card *card;
97
struct mutex cable_lock;
98
struct loopback_cable *cables[MAX_PCM_SUBSTREAMS][2];
99
struct snd_pcm *pcm[2];
100
struct loopback_setup setup[MAX_PCM_SUBSTREAMS][2];
101
};
102
103
struct loopback_pcm {
104
struct loopback *loopback;
105
struct snd_pcm_substream *substream;
106
struct loopback_cable *cable;
107
unsigned int pcm_buffer_size;
108
unsigned int buf_pos; /* position in buffer */
109
unsigned int silent_size;
110
/* PCM parameters */
111
unsigned int pcm_period_size;
112
unsigned int pcm_bps; /* bytes per second */
113
unsigned int pcm_salign; /* bytes per sample * channels */
114
unsigned int pcm_rate_shift; /* rate shift value */
115
/* flags */
116
unsigned int period_update_pending :1;
117
/* timer stuff */
118
unsigned int irq_pos; /* fractional IRQ position */
119
unsigned int period_size_frac;
120
unsigned long last_jiffies;
121
struct timer_list timer;
122
};
123
124
static struct platform_device *devices[SNDRV_CARDS];
125
126
static inline unsigned int byte_pos(struct loopback_pcm *dpcm, unsigned int x)
127
{
128
if (dpcm->pcm_rate_shift == NO_PITCH) {
129
x /= HZ;
130
} else {
131
x = div_u64(NO_PITCH * (unsigned long long)x,
132
HZ * (unsigned long long)dpcm->pcm_rate_shift);
133
}
134
return x - (x % dpcm->pcm_salign);
135
}
136
137
static inline unsigned int frac_pos(struct loopback_pcm *dpcm, unsigned int x)
138
{
139
if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */
140
return x * HZ;
141
} else {
142
x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ,
143
NO_PITCH);
144
}
145
return x;
146
}
147
148
static inline struct loopback_setup *get_setup(struct loopback_pcm *dpcm)
149
{
150
int device = dpcm->substream->pstr->pcm->device;
151
152
if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
153
device ^= 1;
154
return &dpcm->loopback->setup[dpcm->substream->number][device];
155
}
156
157
static inline unsigned int get_notify(struct loopback_pcm *dpcm)
158
{
159
return get_setup(dpcm)->notify;
160
}
161
162
static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm)
163
{
164
return get_setup(dpcm)->rate_shift;
165
}
166
167
static void loopback_timer_start(struct loopback_pcm *dpcm)
168
{
169
unsigned long tick;
170
unsigned int rate_shift = get_rate_shift(dpcm);
171
172
if (rate_shift != dpcm->pcm_rate_shift) {
173
dpcm->pcm_rate_shift = rate_shift;
174
dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
175
}
176
if (dpcm->period_size_frac <= dpcm->irq_pos) {
177
dpcm->irq_pos %= dpcm->period_size_frac;
178
dpcm->period_update_pending = 1;
179
}
180
tick = dpcm->period_size_frac - dpcm->irq_pos;
181
tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
182
dpcm->timer.expires = jiffies + tick;
183
add_timer(&dpcm->timer);
184
}
185
186
static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
187
{
188
del_timer(&dpcm->timer);
189
dpcm->timer.expires = 0;
190
}
191
192
#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK)
193
#define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE)
194
#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
195
196
static int loopback_check_format(struct loopback_cable *cable, int stream)
197
{
198
struct snd_pcm_runtime *runtime, *cruntime;
199
struct loopback_setup *setup;
200
struct snd_card *card;
201
int check;
202
203
if (cable->valid != CABLE_VALID_BOTH) {
204
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
205
goto __notify;
206
return 0;
207
}
208
runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
209
substream->runtime;
210
cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
211
substream->runtime;
212
check = runtime->format != cruntime->format ||
213
runtime->rate != cruntime->rate ||
214
runtime->channels != cruntime->channels;
215
if (!check)
216
return 0;
217
if (stream == SNDRV_PCM_STREAM_CAPTURE) {
218
return -EIO;
219
} else {
220
snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
221
substream, SNDRV_PCM_STATE_DRAINING);
222
__notify:
223
runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
224
substream->runtime;
225
setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
226
card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
227
if (setup->format != runtime->format) {
228
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
229
&setup->format_id);
230
setup->format = runtime->format;
231
}
232
if (setup->rate != runtime->rate) {
233
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
234
&setup->rate_id);
235
setup->rate = runtime->rate;
236
}
237
if (setup->channels != runtime->channels) {
238
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
239
&setup->channels_id);
240
setup->channels = runtime->channels;
241
}
242
}
243
return 0;
244
}
245
246
static void loopback_active_notify(struct loopback_pcm *dpcm)
247
{
248
snd_ctl_notify(dpcm->loopback->card,
249
SNDRV_CTL_EVENT_MASK_VALUE,
250
&get_setup(dpcm)->active_id);
251
}
252
253
static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
254
{
255
struct snd_pcm_runtime *runtime = substream->runtime;
256
struct loopback_pcm *dpcm = runtime->private_data;
257
struct loopback_cable *cable = dpcm->cable;
258
int err, stream = 1 << substream->stream;
259
260
switch (cmd) {
261
case SNDRV_PCM_TRIGGER_START:
262
err = loopback_check_format(cable, substream->stream);
263
if (err < 0)
264
return err;
265
dpcm->last_jiffies = jiffies;
266
dpcm->pcm_rate_shift = 0;
267
spin_lock(&cable->lock);
268
cable->running |= stream;
269
cable->pause &= ~stream;
270
spin_unlock(&cable->lock);
271
loopback_timer_start(dpcm);
272
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
273
loopback_active_notify(dpcm);
274
break;
275
case SNDRV_PCM_TRIGGER_STOP:
276
spin_lock(&cable->lock);
277
cable->running &= ~stream;
278
cable->pause &= ~stream;
279
spin_unlock(&cable->lock);
280
loopback_timer_stop(dpcm);
281
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
282
loopback_active_notify(dpcm);
283
break;
284
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
285
spin_lock(&cable->lock);
286
cable->pause |= stream;
287
spin_unlock(&cable->lock);
288
loopback_timer_stop(dpcm);
289
break;
290
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
291
spin_lock(&cable->lock);
292
dpcm->last_jiffies = jiffies;
293
cable->pause &= ~stream;
294
spin_unlock(&cable->lock);
295
loopback_timer_start(dpcm);
296
break;
297
default:
298
return -EINVAL;
299
}
300
return 0;
301
}
302
303
static void params_change_substream(struct loopback_pcm *dpcm,
304
struct snd_pcm_runtime *runtime)
305
{
306
struct snd_pcm_runtime *dst_runtime;
307
308
if (dpcm == NULL || dpcm->substream == NULL)
309
return;
310
dst_runtime = dpcm->substream->runtime;
311
if (dst_runtime == NULL)
312
return;
313
dst_runtime->hw = dpcm->cable->hw;
314
}
315
316
static void params_change(struct snd_pcm_substream *substream)
317
{
318
struct snd_pcm_runtime *runtime = substream->runtime;
319
struct loopback_pcm *dpcm = runtime->private_data;
320
struct loopback_cable *cable = dpcm->cable;
321
322
cable->hw.formats = (1ULL << runtime->format);
323
cable->hw.rate_min = runtime->rate;
324
cable->hw.rate_max = runtime->rate;
325
cable->hw.channels_min = runtime->channels;
326
cable->hw.channels_max = runtime->channels;
327
params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
328
runtime);
329
params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
330
runtime);
331
}
332
333
static int loopback_prepare(struct snd_pcm_substream *substream)
334
{
335
struct snd_pcm_runtime *runtime = substream->runtime;
336
struct loopback_pcm *dpcm = runtime->private_data;
337
struct loopback_cable *cable = dpcm->cable;
338
int bps, salign;
339
340
salign = (snd_pcm_format_width(runtime->format) *
341
runtime->channels) / 8;
342
bps = salign * runtime->rate;
343
if (bps <= 0 || salign <= 0)
344
return -EINVAL;
345
346
dpcm->buf_pos = 0;
347
dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
348
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
349
/* clear capture buffer */
350
dpcm->silent_size = dpcm->pcm_buffer_size;
351
snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
352
runtime->buffer_size * runtime->channels);
353
}
354
355
dpcm->irq_pos = 0;
356
dpcm->period_update_pending = 0;
357
dpcm->pcm_bps = bps;
358
dpcm->pcm_salign = salign;
359
dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size);
360
361
mutex_lock(&dpcm->loopback->cable_lock);
362
if (!(cable->valid & ~(1 << substream->stream)) ||
363
(get_setup(dpcm)->notify &&
364
substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
365
params_change(substream);
366
cable->valid |= 1 << substream->stream;
367
mutex_unlock(&dpcm->loopback->cable_lock);
368
369
return 0;
370
}
371
372
static void clear_capture_buf(struct loopback_pcm *dpcm, unsigned int bytes)
373
{
374
struct snd_pcm_runtime *runtime = dpcm->substream->runtime;
375
char *dst = runtime->dma_area;
376
unsigned int dst_off = dpcm->buf_pos;
377
378
if (dpcm->silent_size >= dpcm->pcm_buffer_size)
379
return;
380
if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size)
381
bytes = dpcm->pcm_buffer_size - dpcm->silent_size;
382
383
for (;;) {
384
unsigned int size = bytes;
385
if (dst_off + size > dpcm->pcm_buffer_size)
386
size = dpcm->pcm_buffer_size - dst_off;
387
snd_pcm_format_set_silence(runtime->format, dst + dst_off,
388
bytes_to_frames(runtime, size) *
389
runtime->channels);
390
dpcm->silent_size += size;
391
bytes -= size;
392
if (!bytes)
393
break;
394
dst_off = 0;
395
}
396
}
397
398
static void copy_play_buf(struct loopback_pcm *play,
399
struct loopback_pcm *capt,
400
unsigned int bytes)
401
{
402
struct snd_pcm_runtime *runtime = play->substream->runtime;
403
char *src = runtime->dma_area;
404
char *dst = capt->substream->runtime->dma_area;
405
unsigned int src_off = play->buf_pos;
406
unsigned int dst_off = capt->buf_pos;
407
unsigned int clear_bytes = 0;
408
409
/* check if playback is draining, trim the capture copy size
410
* when our pointer is at the end of playback ring buffer */
411
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
412
snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) {
413
snd_pcm_uframes_t appl_ptr, appl_ptr1, diff;
414
appl_ptr = appl_ptr1 = runtime->control->appl_ptr;
415
appl_ptr1 -= appl_ptr1 % runtime->buffer_size;
416
appl_ptr1 += play->buf_pos / play->pcm_salign;
417
if (appl_ptr < appl_ptr1)
418
appl_ptr1 -= runtime->buffer_size;
419
diff = (appl_ptr - appl_ptr1) * play->pcm_salign;
420
if (diff < bytes) {
421
clear_bytes = bytes - diff;
422
bytes = diff;
423
}
424
}
425
426
for (;;) {
427
unsigned int size = bytes;
428
if (src_off + size > play->pcm_buffer_size)
429
size = play->pcm_buffer_size - src_off;
430
if (dst_off + size > capt->pcm_buffer_size)
431
size = capt->pcm_buffer_size - dst_off;
432
memcpy(dst + dst_off, src + src_off, size);
433
capt->silent_size = 0;
434
bytes -= size;
435
if (!bytes)
436
break;
437
src_off = (src_off + size) % play->pcm_buffer_size;
438
dst_off = (dst_off + size) % capt->pcm_buffer_size;
439
}
440
441
if (clear_bytes > 0) {
442
clear_capture_buf(capt, clear_bytes);
443
capt->silent_size = 0;
444
}
445
}
446
447
#define BYTEPOS_UPDATE_POSONLY 0
448
#define BYTEPOS_UPDATE_CLEAR 1
449
#define BYTEPOS_UPDATE_COPY 2
450
451
static void loopback_bytepos_update(struct loopback_pcm *dpcm,
452
unsigned int delta,
453
unsigned int cmd)
454
{
455
unsigned int count;
456
unsigned long last_pos;
457
458
last_pos = byte_pos(dpcm, dpcm->irq_pos);
459
dpcm->irq_pos += delta * dpcm->pcm_bps;
460
count = byte_pos(dpcm, dpcm->irq_pos) - last_pos;
461
if (!count)
462
return;
463
if (cmd == BYTEPOS_UPDATE_CLEAR)
464
clear_capture_buf(dpcm, count);
465
else if (cmd == BYTEPOS_UPDATE_COPY)
466
copy_play_buf(dpcm->cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
467
dpcm->cable->streams[SNDRV_PCM_STREAM_CAPTURE],
468
count);
469
dpcm->buf_pos += count;
470
dpcm->buf_pos %= dpcm->pcm_buffer_size;
471
if (dpcm->irq_pos >= dpcm->period_size_frac) {
472
dpcm->irq_pos %= dpcm->period_size_frac;
473
dpcm->period_update_pending = 1;
474
}
475
}
476
477
static unsigned int loopback_pos_update(struct loopback_cable *cable)
478
{
479
struct loopback_pcm *dpcm_play =
480
cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
481
struct loopback_pcm *dpcm_capt =
482
cable->streams[SNDRV_PCM_STREAM_CAPTURE];
483
unsigned long delta_play = 0, delta_capt = 0;
484
unsigned int running;
485
unsigned long flags;
486
487
spin_lock_irqsave(&cable->lock, flags);
488
running = cable->running ^ cable->pause;
489
if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
490
delta_play = jiffies - dpcm_play->last_jiffies;
491
dpcm_play->last_jiffies += delta_play;
492
}
493
494
if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
495
delta_capt = jiffies - dpcm_capt->last_jiffies;
496
dpcm_capt->last_jiffies += delta_capt;
497
}
498
499
if (delta_play == 0 && delta_capt == 0)
500
goto unlock;
501
502
if (delta_play > delta_capt) {
503
loopback_bytepos_update(dpcm_play, delta_play - delta_capt,
504
BYTEPOS_UPDATE_POSONLY);
505
delta_play = delta_capt;
506
} else if (delta_play < delta_capt) {
507
loopback_bytepos_update(dpcm_capt, delta_capt - delta_play,
508
BYTEPOS_UPDATE_CLEAR);
509
delta_capt = delta_play;
510
}
511
512
if (delta_play == 0 && delta_capt == 0)
513
goto unlock;
514
515
/* note delta_capt == delta_play at this moment */
516
loopback_bytepos_update(dpcm_capt, delta_capt, BYTEPOS_UPDATE_COPY);
517
loopback_bytepos_update(dpcm_play, delta_play, BYTEPOS_UPDATE_POSONLY);
518
unlock:
519
spin_unlock_irqrestore(&cable->lock, flags);
520
return running;
521
}
522
523
static void loopback_timer_function(unsigned long data)
524
{
525
struct loopback_pcm *dpcm = (struct loopback_pcm *)data;
526
unsigned int running;
527
528
running = loopback_pos_update(dpcm->cable);
529
if (running & (1 << dpcm->substream->stream)) {
530
loopback_timer_start(dpcm);
531
if (dpcm->period_update_pending) {
532
dpcm->period_update_pending = 0;
533
snd_pcm_period_elapsed(dpcm->substream);
534
}
535
}
536
}
537
538
static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
539
{
540
struct snd_pcm_runtime *runtime = substream->runtime;
541
struct loopback_pcm *dpcm = runtime->private_data;
542
543
loopback_pos_update(dpcm->cable);
544
return bytes_to_frames(runtime, dpcm->buf_pos);
545
}
546
547
static struct snd_pcm_hardware loopback_pcm_hardware =
548
{
549
.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
550
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
551
.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
552
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |
553
SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE),
554
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
555
.rate_min = 8000,
556
.rate_max = 192000,
557
.channels_min = 1,
558
.channels_max = 32,
559
.buffer_bytes_max = 2 * 1024 * 1024,
560
.period_bytes_min = 64,
561
/* note check overflow in frac_pos() using pcm_rate_shift before
562
changing period_bytes_max value */
563
.period_bytes_max = 1024 * 1024,
564
.periods_min = 1,
565
.periods_max = 1024,
566
.fifo_size = 0,
567
};
568
569
static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
570
{
571
struct loopback_pcm *dpcm = runtime->private_data;
572
kfree(dpcm);
573
}
574
575
static int loopback_hw_params(struct snd_pcm_substream *substream,
576
struct snd_pcm_hw_params *params)
577
{
578
return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
579
}
580
581
static int loopback_hw_free(struct snd_pcm_substream *substream)
582
{
583
struct snd_pcm_runtime *runtime = substream->runtime;
584
struct loopback_pcm *dpcm = runtime->private_data;
585
struct loopback_cable *cable = dpcm->cable;
586
587
mutex_lock(&dpcm->loopback->cable_lock);
588
cable->valid &= ~(1 << substream->stream);
589
mutex_unlock(&dpcm->loopback->cable_lock);
590
return snd_pcm_lib_free_pages(substream);
591
}
592
593
static unsigned int get_cable_index(struct snd_pcm_substream *substream)
594
{
595
if (!substream->pcm->device)
596
return substream->stream;
597
else
598
return !substream->stream;
599
}
600
601
static int rule_format(struct snd_pcm_hw_params *params,
602
struct snd_pcm_hw_rule *rule)
603
{
604
605
struct snd_pcm_hardware *hw = rule->private;
606
struct snd_mask *maskp = hw_param_mask(params, rule->var);
607
608
maskp->bits[0] &= (u_int32_t)hw->formats;
609
maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
610
memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
611
if (! maskp->bits[0] && ! maskp->bits[1])
612
return -EINVAL;
613
return 0;
614
}
615
616
static int rule_rate(struct snd_pcm_hw_params *params,
617
struct snd_pcm_hw_rule *rule)
618
{
619
struct snd_pcm_hardware *hw = rule->private;
620
struct snd_interval t;
621
622
t.min = hw->rate_min;
623
t.max = hw->rate_max;
624
t.openmin = t.openmax = 0;
625
t.integer = 0;
626
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
627
}
628
629
static int rule_channels(struct snd_pcm_hw_params *params,
630
struct snd_pcm_hw_rule *rule)
631
{
632
struct snd_pcm_hardware *hw = rule->private;
633
struct snd_interval t;
634
635
t.min = hw->channels_min;
636
t.max = hw->channels_max;
637
t.openmin = t.openmax = 0;
638
t.integer = 0;
639
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
640
}
641
642
static int loopback_open(struct snd_pcm_substream *substream)
643
{
644
struct snd_pcm_runtime *runtime = substream->runtime;
645
struct loopback *loopback = substream->private_data;
646
struct loopback_pcm *dpcm;
647
struct loopback_cable *cable;
648
int err = 0;
649
int dev = get_cable_index(substream);
650
651
mutex_lock(&loopback->cable_lock);
652
dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
653
if (!dpcm) {
654
err = -ENOMEM;
655
goto unlock;
656
}
657
dpcm->loopback = loopback;
658
dpcm->substream = substream;
659
setup_timer(&dpcm->timer, loopback_timer_function,
660
(unsigned long)dpcm);
661
662
cable = loopback->cables[substream->number][dev];
663
if (!cable) {
664
cable = kzalloc(sizeof(*cable), GFP_KERNEL);
665
if (!cable) {
666
kfree(dpcm);
667
err = -ENOMEM;
668
goto unlock;
669
}
670
spin_lock_init(&cable->lock);
671
cable->hw = loopback_pcm_hardware;
672
loopback->cables[substream->number][dev] = cable;
673
}
674
dpcm->cable = cable;
675
cable->streams[substream->stream] = dpcm;
676
677
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
678
679
/* use dynamic rules based on actual runtime->hw values */
680
/* note that the default rules created in the PCM midlevel code */
681
/* are cached -> they do not reflect the actual state */
682
err = snd_pcm_hw_rule_add(runtime, 0,
683
SNDRV_PCM_HW_PARAM_FORMAT,
684
rule_format, &runtime->hw,
685
SNDRV_PCM_HW_PARAM_FORMAT, -1);
686
if (err < 0)
687
goto unlock;
688
err = snd_pcm_hw_rule_add(runtime, 0,
689
SNDRV_PCM_HW_PARAM_RATE,
690
rule_rate, &runtime->hw,
691
SNDRV_PCM_HW_PARAM_RATE, -1);
692
if (err < 0)
693
goto unlock;
694
err = snd_pcm_hw_rule_add(runtime, 0,
695
SNDRV_PCM_HW_PARAM_CHANNELS,
696
rule_channels, &runtime->hw,
697
SNDRV_PCM_HW_PARAM_CHANNELS, -1);
698
if (err < 0)
699
goto unlock;
700
701
runtime->private_data = dpcm;
702
runtime->private_free = loopback_runtime_free;
703
if (get_notify(dpcm))
704
runtime->hw = loopback_pcm_hardware;
705
else
706
runtime->hw = cable->hw;
707
unlock:
708
mutex_unlock(&loopback->cable_lock);
709
return err;
710
}
711
712
static int loopback_close(struct snd_pcm_substream *substream)
713
{
714
struct loopback *loopback = substream->private_data;
715
struct loopback_pcm *dpcm = substream->runtime->private_data;
716
struct loopback_cable *cable;
717
int dev = get_cable_index(substream);
718
719
loopback_timer_stop(dpcm);
720
mutex_lock(&loopback->cable_lock);
721
cable = loopback->cables[substream->number][dev];
722
if (cable->streams[!substream->stream]) {
723
/* other stream is still alive */
724
cable->streams[substream->stream] = NULL;
725
} else {
726
/* free the cable */
727
loopback->cables[substream->number][dev] = NULL;
728
kfree(cable);
729
}
730
mutex_unlock(&loopback->cable_lock);
731
return 0;
732
}
733
734
static struct snd_pcm_ops loopback_playback_ops = {
735
.open = loopback_open,
736
.close = loopback_close,
737
.ioctl = snd_pcm_lib_ioctl,
738
.hw_params = loopback_hw_params,
739
.hw_free = loopback_hw_free,
740
.prepare = loopback_prepare,
741
.trigger = loopback_trigger,
742
.pointer = loopback_pointer,
743
};
744
745
static struct snd_pcm_ops loopback_capture_ops = {
746
.open = loopback_open,
747
.close = loopback_close,
748
.ioctl = snd_pcm_lib_ioctl,
749
.hw_params = loopback_hw_params,
750
.hw_free = loopback_hw_free,
751
.prepare = loopback_prepare,
752
.trigger = loopback_trigger,
753
.pointer = loopback_pointer,
754
};
755
756
static int __devinit loopback_pcm_new(struct loopback *loopback,
757
int device, int substreams)
758
{
759
struct snd_pcm *pcm;
760
int err;
761
762
err = snd_pcm_new(loopback->card, "Loopback PCM", device,
763
substreams, substreams, &pcm);
764
if (err < 0)
765
return err;
766
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_playback_ops);
767
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_capture_ops);
768
769
pcm->private_data = loopback;
770
pcm->info_flags = 0;
771
strcpy(pcm->name, "Loopback PCM");
772
773
loopback->pcm[device] = pcm;
774
775
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
776
snd_dma_continuous_data(GFP_KERNEL),
777
0, 2 * 1024 * 1024);
778
return 0;
779
}
780
781
static int loopback_rate_shift_info(struct snd_kcontrol *kcontrol,
782
struct snd_ctl_elem_info *uinfo)
783
{
784
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
785
uinfo->count = 1;
786
uinfo->value.integer.min = 80000;
787
uinfo->value.integer.max = 120000;
788
uinfo->value.integer.step = 1;
789
return 0;
790
}
791
792
static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
793
struct snd_ctl_elem_value *ucontrol)
794
{
795
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
796
797
ucontrol->value.integer.value[0] =
798
loopback->setup[kcontrol->id.subdevice]
799
[kcontrol->id.device].rate_shift;
800
return 0;
801
}
802
803
static int loopback_rate_shift_put(struct snd_kcontrol *kcontrol,
804
struct snd_ctl_elem_value *ucontrol)
805
{
806
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
807
unsigned int val;
808
int change = 0;
809
810
val = ucontrol->value.integer.value[0];
811
if (val < 80000)
812
val = 80000;
813
if (val > 120000)
814
val = 120000;
815
mutex_lock(&loopback->cable_lock);
816
if (val != loopback->setup[kcontrol->id.subdevice]
817
[kcontrol->id.device].rate_shift) {
818
loopback->setup[kcontrol->id.subdevice]
819
[kcontrol->id.device].rate_shift = val;
820
change = 1;
821
}
822
mutex_unlock(&loopback->cable_lock);
823
return change;
824
}
825
826
static int loopback_notify_get(struct snd_kcontrol *kcontrol,
827
struct snd_ctl_elem_value *ucontrol)
828
{
829
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
830
831
ucontrol->value.integer.value[0] =
832
loopback->setup[kcontrol->id.subdevice]
833
[kcontrol->id.device].notify;
834
return 0;
835
}
836
837
static int loopback_notify_put(struct snd_kcontrol *kcontrol,
838
struct snd_ctl_elem_value *ucontrol)
839
{
840
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
841
unsigned int val;
842
int change = 0;
843
844
val = ucontrol->value.integer.value[0] ? 1 : 0;
845
if (val != loopback->setup[kcontrol->id.subdevice]
846
[kcontrol->id.device].notify) {
847
loopback->setup[kcontrol->id.subdevice]
848
[kcontrol->id.device].notify = val;
849
change = 1;
850
}
851
return change;
852
}
853
854
static int loopback_active_get(struct snd_kcontrol *kcontrol,
855
struct snd_ctl_elem_value *ucontrol)
856
{
857
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
858
struct loopback_cable *cable = loopback->cables
859
[kcontrol->id.subdevice][kcontrol->id.device ^ 1];
860
unsigned int val = 0;
861
862
if (cable != NULL)
863
val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
864
1 : 0;
865
ucontrol->value.integer.value[0] = val;
866
return 0;
867
}
868
869
static int loopback_format_info(struct snd_kcontrol *kcontrol,
870
struct snd_ctl_elem_info *uinfo)
871
{
872
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
873
uinfo->count = 1;
874
uinfo->value.integer.min = 0;
875
uinfo->value.integer.max = SNDRV_PCM_FORMAT_LAST;
876
uinfo->value.integer.step = 1;
877
return 0;
878
}
879
880
static int loopback_format_get(struct snd_kcontrol *kcontrol,
881
struct snd_ctl_elem_value *ucontrol)
882
{
883
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
884
885
ucontrol->value.integer.value[0] =
886
loopback->setup[kcontrol->id.subdevice]
887
[kcontrol->id.device].format;
888
return 0;
889
}
890
891
static int loopback_rate_info(struct snd_kcontrol *kcontrol,
892
struct snd_ctl_elem_info *uinfo)
893
{
894
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
895
uinfo->count = 1;
896
uinfo->value.integer.min = 0;
897
uinfo->value.integer.max = 192000;
898
uinfo->value.integer.step = 1;
899
return 0;
900
}
901
902
static int loopback_rate_get(struct snd_kcontrol *kcontrol,
903
struct snd_ctl_elem_value *ucontrol)
904
{
905
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
906
907
ucontrol->value.integer.value[0] =
908
loopback->setup[kcontrol->id.subdevice]
909
[kcontrol->id.device].rate;
910
return 0;
911
}
912
913
static int loopback_channels_info(struct snd_kcontrol *kcontrol,
914
struct snd_ctl_elem_info *uinfo)
915
{
916
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
917
uinfo->count = 1;
918
uinfo->value.integer.min = 1;
919
uinfo->value.integer.max = 1024;
920
uinfo->value.integer.step = 1;
921
return 0;
922
}
923
924
static int loopback_channels_get(struct snd_kcontrol *kcontrol,
925
struct snd_ctl_elem_value *ucontrol)
926
{
927
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
928
929
ucontrol->value.integer.value[0] =
930
loopback->setup[kcontrol->id.subdevice]
931
[kcontrol->id.device].channels;
932
return 0;
933
}
934
935
static struct snd_kcontrol_new loopback_controls[] __devinitdata = {
936
{
937
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
938
.name = "PCM Rate Shift 100000",
939
.info = loopback_rate_shift_info,
940
.get = loopback_rate_shift_get,
941
.put = loopback_rate_shift_put,
942
},
943
{
944
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
945
.name = "PCM Notify",
946
.info = snd_ctl_boolean_mono_info,
947
.get = loopback_notify_get,
948
.put = loopback_notify_put,
949
},
950
#define ACTIVE_IDX 2
951
{
952
.access = SNDRV_CTL_ELEM_ACCESS_READ,
953
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
954
.name = "PCM Slave Active",
955
.info = snd_ctl_boolean_mono_info,
956
.get = loopback_active_get,
957
},
958
#define FORMAT_IDX 3
959
{
960
.access = SNDRV_CTL_ELEM_ACCESS_READ,
961
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
962
.name = "PCM Slave Format",
963
.info = loopback_format_info,
964
.get = loopback_format_get
965
},
966
#define RATE_IDX 4
967
{
968
.access = SNDRV_CTL_ELEM_ACCESS_READ,
969
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
970
.name = "PCM Slave Rate",
971
.info = loopback_rate_info,
972
.get = loopback_rate_get
973
},
974
#define CHANNELS_IDX 5
975
{
976
.access = SNDRV_CTL_ELEM_ACCESS_READ,
977
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
978
.name = "PCM Slave Channels",
979
.info = loopback_channels_info,
980
.get = loopback_channels_get
981
}
982
};
983
984
static int __devinit loopback_mixer_new(struct loopback *loopback, int notify)
985
{
986
struct snd_card *card = loopback->card;
987
struct snd_pcm *pcm;
988
struct snd_kcontrol *kctl;
989
struct loopback_setup *setup;
990
int err, dev, substr, substr_count, idx;
991
992
strcpy(card->mixername, "Loopback Mixer");
993
for (dev = 0; dev < 2; dev++) {
994
pcm = loopback->pcm[dev];
995
substr_count =
996
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count;
997
for (substr = 0; substr < substr_count; substr++) {
998
setup = &loopback->setup[substr][dev];
999
setup->notify = notify;
1000
setup->rate_shift = NO_PITCH;
1001
setup->format = SNDRV_PCM_FORMAT_S16_LE;
1002
setup->rate = 48000;
1003
setup->channels = 2;
1004
for (idx = 0; idx < ARRAY_SIZE(loopback_controls);
1005
idx++) {
1006
kctl = snd_ctl_new1(&loopback_controls[idx],
1007
loopback);
1008
if (!kctl)
1009
return -ENOMEM;
1010
kctl->id.device = dev;
1011
kctl->id.subdevice = substr;
1012
switch (idx) {
1013
case ACTIVE_IDX:
1014
setup->active_id = kctl->id;
1015
break;
1016
case FORMAT_IDX:
1017
setup->format_id = kctl->id;
1018
break;
1019
case RATE_IDX:
1020
setup->rate_id = kctl->id;
1021
break;
1022
case CHANNELS_IDX:
1023
setup->channels_id = kctl->id;
1024
break;
1025
default:
1026
break;
1027
}
1028
err = snd_ctl_add(card, kctl);
1029
if (err < 0)
1030
return err;
1031
}
1032
}
1033
}
1034
return 0;
1035
}
1036
1037
#ifdef CONFIG_PROC_FS
1038
1039
static void print_dpcm_info(struct snd_info_buffer *buffer,
1040
struct loopback_pcm *dpcm,
1041
const char *id)
1042
{
1043
snd_iprintf(buffer, " %s\n", id);
1044
if (dpcm == NULL) {
1045
snd_iprintf(buffer, " inactive\n");
1046
return;
1047
}
1048
snd_iprintf(buffer, " buffer_size:\t%u\n", dpcm->pcm_buffer_size);
1049
snd_iprintf(buffer, " buffer_pos:\t\t%u\n", dpcm->buf_pos);
1050
snd_iprintf(buffer, " silent_size:\t%u\n", dpcm->silent_size);
1051
snd_iprintf(buffer, " period_size:\t%u\n", dpcm->pcm_period_size);
1052
snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps);
1053
snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign);
1054
snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift);
1055
snd_iprintf(buffer, " update_pending:\t%u\n",
1056
dpcm->period_update_pending);
1057
snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos);
1058
snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac);
1059
snd_iprintf(buffer, " last_jiffies:\t%lu (%lu)\n",
1060
dpcm->last_jiffies, jiffies);
1061
snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires);
1062
}
1063
1064
static void print_substream_info(struct snd_info_buffer *buffer,
1065
struct loopback *loopback,
1066
int sub,
1067
int num)
1068
{
1069
struct loopback_cable *cable = loopback->cables[sub][num];
1070
1071
snd_iprintf(buffer, "Cable %i substream %i:\n", num, sub);
1072
if (cable == NULL) {
1073
snd_iprintf(buffer, " inactive\n");
1074
return;
1075
}
1076
snd_iprintf(buffer, " valid: %u\n", cable->valid);
1077
snd_iprintf(buffer, " running: %u\n", cable->running);
1078
snd_iprintf(buffer, " pause: %u\n", cable->pause);
1079
print_dpcm_info(buffer, cable->streams[0], "Playback");
1080
print_dpcm_info(buffer, cable->streams[1], "Capture");
1081
}
1082
1083
static void print_cable_info(struct snd_info_entry *entry,
1084
struct snd_info_buffer *buffer)
1085
{
1086
struct loopback *loopback = entry->private_data;
1087
int sub, num;
1088
1089
mutex_lock(&loopback->cable_lock);
1090
num = entry->name[strlen(entry->name)-1];
1091
num = num == '0' ? 0 : 1;
1092
for (sub = 0; sub < MAX_PCM_SUBSTREAMS; sub++)
1093
print_substream_info(buffer, loopback, sub, num);
1094
mutex_unlock(&loopback->cable_lock);
1095
}
1096
1097
static int __devinit loopback_proc_new(struct loopback *loopback, int cidx)
1098
{
1099
char name[32];
1100
struct snd_info_entry *entry;
1101
int err;
1102
1103
snprintf(name, sizeof(name), "cable#%d", cidx);
1104
err = snd_card_proc_new(loopback->card, name, &entry);
1105
if (err < 0)
1106
return err;
1107
1108
snd_info_set_text_ops(entry, loopback, print_cable_info);
1109
return 0;
1110
}
1111
1112
#else /* !CONFIG_PROC_FS */
1113
1114
#define loopback_proc_new(loopback, cidx) do { } while (0)
1115
1116
#endif
1117
1118
static int __devinit loopback_probe(struct platform_device *devptr)
1119
{
1120
struct snd_card *card;
1121
struct loopback *loopback;
1122
int dev = devptr->id;
1123
int err;
1124
1125
err = snd_card_create(index[dev], id[dev], THIS_MODULE,
1126
sizeof(struct loopback), &card);
1127
if (err < 0)
1128
return err;
1129
loopback = card->private_data;
1130
1131
if (pcm_substreams[dev] < 1)
1132
pcm_substreams[dev] = 1;
1133
if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
1134
pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
1135
1136
loopback->card = card;
1137
mutex_init(&loopback->cable_lock);
1138
1139
err = loopback_pcm_new(loopback, 0, pcm_substreams[dev]);
1140
if (err < 0)
1141
goto __nodev;
1142
err = loopback_pcm_new(loopback, 1, pcm_substreams[dev]);
1143
if (err < 0)
1144
goto __nodev;
1145
err = loopback_mixer_new(loopback, pcm_notify[dev] ? 1 : 0);
1146
if (err < 0)
1147
goto __nodev;
1148
loopback_proc_new(loopback, 0);
1149
loopback_proc_new(loopback, 1);
1150
strcpy(card->driver, "Loopback");
1151
strcpy(card->shortname, "Loopback");
1152
sprintf(card->longname, "Loopback %i", dev + 1);
1153
err = snd_card_register(card);
1154
if (!err) {
1155
platform_set_drvdata(devptr, card);
1156
return 0;
1157
}
1158
__nodev:
1159
snd_card_free(card);
1160
return err;
1161
}
1162
1163
static int __devexit loopback_remove(struct platform_device *devptr)
1164
{
1165
snd_card_free(platform_get_drvdata(devptr));
1166
platform_set_drvdata(devptr, NULL);
1167
return 0;
1168
}
1169
1170
#ifdef CONFIG_PM
1171
static int loopback_suspend(struct platform_device *pdev,
1172
pm_message_t state)
1173
{
1174
struct snd_card *card = platform_get_drvdata(pdev);
1175
struct loopback *loopback = card->private_data;
1176
1177
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1178
1179
snd_pcm_suspend_all(loopback->pcm[0]);
1180
snd_pcm_suspend_all(loopback->pcm[1]);
1181
return 0;
1182
}
1183
1184
static int loopback_resume(struct platform_device *pdev)
1185
{
1186
struct snd_card *card = platform_get_drvdata(pdev);
1187
1188
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1189
return 0;
1190
}
1191
#endif
1192
1193
#define SND_LOOPBACK_DRIVER "snd_aloop"
1194
1195
static struct platform_driver loopback_driver = {
1196
.probe = loopback_probe,
1197
.remove = __devexit_p(loopback_remove),
1198
#ifdef CONFIG_PM
1199
.suspend = loopback_suspend,
1200
.resume = loopback_resume,
1201
#endif
1202
.driver = {
1203
.name = SND_LOOPBACK_DRIVER
1204
},
1205
};
1206
1207
static void loopback_unregister_all(void)
1208
{
1209
int i;
1210
1211
for (i = 0; i < ARRAY_SIZE(devices); ++i)
1212
platform_device_unregister(devices[i]);
1213
platform_driver_unregister(&loopback_driver);
1214
}
1215
1216
static int __init alsa_card_loopback_init(void)
1217
{
1218
int i, err, cards;
1219
1220
err = platform_driver_register(&loopback_driver);
1221
if (err < 0)
1222
return err;
1223
1224
1225
cards = 0;
1226
for (i = 0; i < SNDRV_CARDS; i++) {
1227
struct platform_device *device;
1228
if (!enable[i])
1229
continue;
1230
device = platform_device_register_simple(SND_LOOPBACK_DRIVER,
1231
i, NULL, 0);
1232
if (IS_ERR(device))
1233
continue;
1234
if (!platform_get_drvdata(device)) {
1235
platform_device_unregister(device);
1236
continue;
1237
}
1238
devices[i] = device;
1239
cards++;
1240
}
1241
if (!cards) {
1242
#ifdef MODULE
1243
printk(KERN_ERR "aloop: No loopback enabled\n");
1244
#endif
1245
loopback_unregister_all();
1246
return -ENODEV;
1247
}
1248
return 0;
1249
}
1250
1251
static void __exit alsa_card_loopback_exit(void)
1252
{
1253
loopback_unregister_all();
1254
}
1255
1256
module_init(alsa_card_loopback_init)
1257
module_exit(alsa_card_loopback_exit)
1258
1259