Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/drivers/dummy.c
29266 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Dummy soundcard
4
* Copyright (c) by Jaroslav Kysela <[email protected]>
5
*/
6
7
#include <linux/init.h>
8
#include <linux/err.h>
9
#include <linux/platform_device.h>
10
#include <linux/jiffies.h>
11
#include <linux/slab.h>
12
#include <linux/string.h>
13
#include <linux/time.h>
14
#include <linux/wait.h>
15
#include <linux/hrtimer.h>
16
#include <linux/math64.h>
17
#include <linux/module.h>
18
#include <sound/core.h>
19
#include <sound/control.h>
20
#include <sound/tlv.h>
21
#include <sound/pcm.h>
22
#include <sound/rawmidi.h>
23
#include <sound/info.h>
24
#include <sound/initval.h>
25
26
MODULE_AUTHOR("Jaroslav Kysela <[email protected]>");
27
MODULE_DESCRIPTION("Dummy soundcard (/dev/null)");
28
MODULE_LICENSE("GPL");
29
30
#define MAX_PCM_DEVICES 4
31
#define MAX_PCM_SUBSTREAMS 128
32
#define MAX_MIDI_DEVICES 2
33
34
/* defaults */
35
#define MAX_BUFFER_SIZE (64*1024)
36
#define MIN_PERIOD_SIZE 64
37
#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE
38
#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
39
#define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000
40
#define USE_RATE_MIN 5500
41
#define USE_RATE_MAX 48000
42
#define USE_CHANNELS_MIN 1
43
#define USE_CHANNELS_MAX 2
44
#define USE_PERIODS_MIN 1
45
#define USE_PERIODS_MAX 1024
46
#define USE_MIXER_VOLUME_LEVEL_MIN -50
47
#define USE_MIXER_VOLUME_LEVEL_MAX 100
48
49
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
50
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
51
static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
52
static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
53
static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
54
static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
55
//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
56
static int mixer_volume_level_min = USE_MIXER_VOLUME_LEVEL_MIN;
57
static int mixer_volume_level_max = USE_MIXER_VOLUME_LEVEL_MAX;
58
#ifdef CONFIG_HIGH_RES_TIMERS
59
static bool hrtimer = 1;
60
#endif
61
static bool fake_buffer = 1;
62
63
module_param_array(index, int, NULL, 0444);
64
MODULE_PARM_DESC(index, "Index value for dummy soundcard.");
65
module_param_array(id, charp, NULL, 0444);
66
MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
67
module_param_array(enable, bool, NULL, 0444);
68
MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
69
module_param_array(model, charp, NULL, 0444);
70
MODULE_PARM_DESC(model, "Soundcard model.");
71
module_param_array(pcm_devs, int, NULL, 0444);
72
MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
73
module_param_array(pcm_substreams, int, NULL, 0444);
74
MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
75
//module_param_array(midi_devs, int, NULL, 0444);
76
//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
77
module_param(mixer_volume_level_min, int, 0444);
78
MODULE_PARM_DESC(mixer_volume_level_min, "Minimum mixer volume level for dummy driver. Default: -50");
79
module_param(mixer_volume_level_max, int, 0444);
80
MODULE_PARM_DESC(mixer_volume_level_max, "Maximum mixer volume level for dummy driver. Default: 100");
81
module_param(fake_buffer, bool, 0444);
82
MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations.");
83
#ifdef CONFIG_HIGH_RES_TIMERS
84
module_param(hrtimer, bool, 0644);
85
MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source.");
86
#endif
87
88
static struct platform_device *devices[SNDRV_CARDS];
89
90
#define MIXER_ADDR_MASTER 0
91
#define MIXER_ADDR_LINE 1
92
#define MIXER_ADDR_MIC 2
93
#define MIXER_ADDR_SYNTH 3
94
#define MIXER_ADDR_CD 4
95
#define MIXER_ADDR_LAST 4
96
97
struct dummy_timer_ops {
98
int (*create)(struct snd_pcm_substream *);
99
void (*free)(struct snd_pcm_substream *);
100
int (*prepare)(struct snd_pcm_substream *);
101
int (*start)(struct snd_pcm_substream *);
102
int (*stop)(struct snd_pcm_substream *);
103
snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
104
};
105
106
#define get_dummy_ops(substream) \
107
(*(const struct dummy_timer_ops **)(substream)->runtime->private_data)
108
109
struct dummy_model {
110
const char *name;
111
int (*playback_constraints)(struct snd_pcm_runtime *runtime);
112
int (*capture_constraints)(struct snd_pcm_runtime *runtime);
113
u64 formats;
114
size_t buffer_bytes_max;
115
size_t period_bytes_min;
116
size_t period_bytes_max;
117
unsigned int periods_min;
118
unsigned int periods_max;
119
unsigned int rates;
120
unsigned int rate_min;
121
unsigned int rate_max;
122
unsigned int channels_min;
123
unsigned int channels_max;
124
};
125
126
struct snd_dummy {
127
struct snd_card *card;
128
const struct dummy_model *model;
129
struct snd_pcm *pcm;
130
struct snd_pcm_hardware pcm_hw;
131
spinlock_t mixer_lock;
132
int mixer_volume[MIXER_ADDR_LAST+1][2];
133
int capture_source[MIXER_ADDR_LAST+1][2];
134
int iobox;
135
struct snd_kcontrol *cd_volume_ctl;
136
struct snd_kcontrol *cd_switch_ctl;
137
};
138
139
/*
140
* card models
141
*/
142
143
static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
144
{
145
int err;
146
err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
147
if (err < 0)
148
return err;
149
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
150
if (err < 0)
151
return err;
152
return 0;
153
}
154
155
static const struct dummy_model model_emu10k1 = {
156
.name = "emu10k1",
157
.playback_constraints = emu10k1_playback_constraints,
158
.buffer_bytes_max = 128 * 1024,
159
};
160
161
static const struct dummy_model model_rme9652 = {
162
.name = "rme9652",
163
.buffer_bytes_max = 26 * 64 * 1024,
164
.formats = SNDRV_PCM_FMTBIT_S32_LE,
165
.channels_min = 26,
166
.channels_max = 26,
167
.periods_min = 2,
168
.periods_max = 2,
169
};
170
171
static const struct dummy_model model_ice1712 = {
172
.name = "ice1712",
173
.buffer_bytes_max = 256 * 1024,
174
.formats = SNDRV_PCM_FMTBIT_S32_LE,
175
.channels_min = 10,
176
.channels_max = 10,
177
.periods_min = 1,
178
.periods_max = 1024,
179
};
180
181
static const struct dummy_model model_uda1341 = {
182
.name = "uda1341",
183
.buffer_bytes_max = 16380,
184
.formats = SNDRV_PCM_FMTBIT_S16_LE,
185
.channels_min = 2,
186
.channels_max = 2,
187
.periods_min = 2,
188
.periods_max = 255,
189
};
190
191
static const struct dummy_model model_ac97 = {
192
.name = "ac97",
193
.formats = SNDRV_PCM_FMTBIT_S16_LE,
194
.channels_min = 2,
195
.channels_max = 2,
196
.rates = SNDRV_PCM_RATE_48000,
197
.rate_min = 48000,
198
.rate_max = 48000,
199
};
200
201
static const struct dummy_model model_ca0106 = {
202
.name = "ca0106",
203
.formats = SNDRV_PCM_FMTBIT_S16_LE,
204
.buffer_bytes_max = ((65536-64)*8),
205
.period_bytes_max = (65536-64),
206
.periods_min = 2,
207
.periods_max = 8,
208
.channels_min = 2,
209
.channels_max = 2,
210
.rates = SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000,
211
.rate_min = 48000,
212
.rate_max = 192000,
213
};
214
215
static const struct dummy_model *dummy_models[] = {
216
&model_emu10k1,
217
&model_rme9652,
218
&model_ice1712,
219
&model_uda1341,
220
&model_ac97,
221
&model_ca0106,
222
NULL
223
};
224
225
/*
226
* system timer interface
227
*/
228
229
struct dummy_systimer_pcm {
230
/* ops must be the first item */
231
const struct dummy_timer_ops *timer_ops;
232
spinlock_t lock;
233
struct timer_list timer;
234
unsigned long base_time;
235
unsigned int frac_pos; /* fractional sample position (based HZ) */
236
unsigned int frac_period_rest;
237
unsigned int frac_buffer_size; /* buffer_size * HZ */
238
unsigned int frac_period_size; /* period_size * HZ */
239
unsigned int rate;
240
int elapsed;
241
struct snd_pcm_substream *substream;
242
};
243
244
static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
245
{
246
mod_timer(&dpcm->timer, jiffies +
247
DIV_ROUND_UP(dpcm->frac_period_rest, dpcm->rate));
248
}
249
250
static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm)
251
{
252
unsigned long delta;
253
254
delta = jiffies - dpcm->base_time;
255
if (!delta)
256
return;
257
dpcm->base_time += delta;
258
delta *= dpcm->rate;
259
dpcm->frac_pos += delta;
260
while (dpcm->frac_pos >= dpcm->frac_buffer_size)
261
dpcm->frac_pos -= dpcm->frac_buffer_size;
262
while (dpcm->frac_period_rest <= delta) {
263
dpcm->elapsed++;
264
dpcm->frac_period_rest += dpcm->frac_period_size;
265
}
266
dpcm->frac_period_rest -= delta;
267
}
268
269
static int dummy_systimer_start(struct snd_pcm_substream *substream)
270
{
271
struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
272
273
guard(spinlock)(&dpcm->lock);
274
dpcm->base_time = jiffies;
275
dummy_systimer_rearm(dpcm);
276
return 0;
277
}
278
279
static int dummy_systimer_stop(struct snd_pcm_substream *substream)
280
{
281
struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
282
283
guard(spinlock)(&dpcm->lock);
284
timer_delete(&dpcm->timer);
285
return 0;
286
}
287
288
static int dummy_systimer_prepare(struct snd_pcm_substream *substream)
289
{
290
struct snd_pcm_runtime *runtime = substream->runtime;
291
struct dummy_systimer_pcm *dpcm = runtime->private_data;
292
293
dpcm->frac_pos = 0;
294
dpcm->rate = runtime->rate;
295
dpcm->frac_buffer_size = runtime->buffer_size * HZ;
296
dpcm->frac_period_size = runtime->period_size * HZ;
297
dpcm->frac_period_rest = dpcm->frac_period_size;
298
dpcm->elapsed = 0;
299
300
return 0;
301
}
302
303
static void dummy_systimer_callback(struct timer_list *t)
304
{
305
struct dummy_systimer_pcm *dpcm = timer_container_of(dpcm, t, timer);
306
int elapsed = 0;
307
308
scoped_guard(spinlock_irqsave, &dpcm->lock) {
309
dummy_systimer_update(dpcm);
310
dummy_systimer_rearm(dpcm);
311
elapsed = dpcm->elapsed;
312
dpcm->elapsed = 0;
313
}
314
if (elapsed)
315
snd_pcm_period_elapsed(dpcm->substream);
316
}
317
318
static snd_pcm_uframes_t
319
dummy_systimer_pointer(struct snd_pcm_substream *substream)
320
{
321
struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
322
323
guard(spinlock)(&dpcm->lock);
324
dummy_systimer_update(dpcm);
325
return dpcm->frac_pos / HZ;
326
}
327
328
static int dummy_systimer_create(struct snd_pcm_substream *substream)
329
{
330
struct dummy_systimer_pcm *dpcm;
331
332
dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
333
if (!dpcm)
334
return -ENOMEM;
335
substream->runtime->private_data = dpcm;
336
timer_setup(&dpcm->timer, dummy_systimer_callback, 0);
337
spin_lock_init(&dpcm->lock);
338
dpcm->substream = substream;
339
return 0;
340
}
341
342
static void dummy_systimer_free(struct snd_pcm_substream *substream)
343
{
344
kfree(substream->runtime->private_data);
345
}
346
347
static const struct dummy_timer_ops dummy_systimer_ops = {
348
.create = dummy_systimer_create,
349
.free = dummy_systimer_free,
350
.prepare = dummy_systimer_prepare,
351
.start = dummy_systimer_start,
352
.stop = dummy_systimer_stop,
353
.pointer = dummy_systimer_pointer,
354
};
355
356
#ifdef CONFIG_HIGH_RES_TIMERS
357
/*
358
* hrtimer interface
359
*/
360
361
struct dummy_hrtimer_pcm {
362
/* ops must be the first item */
363
const struct dummy_timer_ops *timer_ops;
364
ktime_t base_time;
365
ktime_t period_time;
366
atomic_t running;
367
struct hrtimer timer;
368
struct snd_pcm_substream *substream;
369
};
370
371
static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer)
372
{
373
struct dummy_hrtimer_pcm *dpcm;
374
375
dpcm = container_of(timer, struct dummy_hrtimer_pcm, timer);
376
if (!atomic_read(&dpcm->running))
377
return HRTIMER_NORESTART;
378
/*
379
* In cases of XRUN and draining, this calls .trigger to stop PCM
380
* substream.
381
*/
382
snd_pcm_period_elapsed(dpcm->substream);
383
if (!atomic_read(&dpcm->running))
384
return HRTIMER_NORESTART;
385
386
hrtimer_forward_now(timer, dpcm->period_time);
387
return HRTIMER_RESTART;
388
}
389
390
static int dummy_hrtimer_start(struct snd_pcm_substream *substream)
391
{
392
struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
393
394
dpcm->base_time = hrtimer_cb_get_time(&dpcm->timer);
395
hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL_SOFT);
396
atomic_set(&dpcm->running, 1);
397
return 0;
398
}
399
400
static int dummy_hrtimer_stop(struct snd_pcm_substream *substream)
401
{
402
struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
403
404
atomic_set(&dpcm->running, 0);
405
if (!hrtimer_callback_running(&dpcm->timer))
406
hrtimer_cancel(&dpcm->timer);
407
return 0;
408
}
409
410
static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
411
{
412
hrtimer_cancel(&dpcm->timer);
413
}
414
415
static snd_pcm_uframes_t
416
dummy_hrtimer_pointer(struct snd_pcm_substream *substream)
417
{
418
struct snd_pcm_runtime *runtime = substream->runtime;
419
struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
420
u64 delta;
421
u32 pos;
422
423
delta = ktime_us_delta(hrtimer_cb_get_time(&dpcm->timer),
424
dpcm->base_time);
425
delta = div_u64(delta * runtime->rate + 999999, 1000000);
426
div_u64_rem(delta, runtime->buffer_size, &pos);
427
return pos;
428
}
429
430
static int dummy_hrtimer_prepare(struct snd_pcm_substream *substream)
431
{
432
struct snd_pcm_runtime *runtime = substream->runtime;
433
struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
434
unsigned int period, rate;
435
long sec;
436
unsigned long nsecs;
437
438
dummy_hrtimer_sync(dpcm);
439
period = runtime->period_size;
440
rate = runtime->rate;
441
sec = period / rate;
442
period %= rate;
443
nsecs = div_u64((u64)period * 1000000000UL + rate - 1, rate);
444
dpcm->period_time = ktime_set(sec, nsecs);
445
446
return 0;
447
}
448
449
static int dummy_hrtimer_create(struct snd_pcm_substream *substream)
450
{
451
struct dummy_hrtimer_pcm *dpcm;
452
453
dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
454
if (!dpcm)
455
return -ENOMEM;
456
substream->runtime->private_data = dpcm;
457
hrtimer_setup(&dpcm->timer, dummy_hrtimer_callback, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT);
458
dpcm->substream = substream;
459
atomic_set(&dpcm->running, 0);
460
return 0;
461
}
462
463
static void dummy_hrtimer_free(struct snd_pcm_substream *substream)
464
{
465
struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
466
dummy_hrtimer_sync(dpcm);
467
kfree(dpcm);
468
}
469
470
static const struct dummy_timer_ops dummy_hrtimer_ops = {
471
.create = dummy_hrtimer_create,
472
.free = dummy_hrtimer_free,
473
.prepare = dummy_hrtimer_prepare,
474
.start = dummy_hrtimer_start,
475
.stop = dummy_hrtimer_stop,
476
.pointer = dummy_hrtimer_pointer,
477
};
478
479
#endif /* CONFIG_HIGH_RES_TIMERS */
480
481
/*
482
* PCM interface
483
*/
484
485
static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
486
{
487
switch (cmd) {
488
case SNDRV_PCM_TRIGGER_START:
489
case SNDRV_PCM_TRIGGER_RESUME:
490
return get_dummy_ops(substream)->start(substream);
491
case SNDRV_PCM_TRIGGER_STOP:
492
case SNDRV_PCM_TRIGGER_SUSPEND:
493
return get_dummy_ops(substream)->stop(substream);
494
}
495
return -EINVAL;
496
}
497
498
static int dummy_pcm_prepare(struct snd_pcm_substream *substream)
499
{
500
return get_dummy_ops(substream)->prepare(substream);
501
}
502
503
static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
504
{
505
return get_dummy_ops(substream)->pointer(substream);
506
}
507
508
static const struct snd_pcm_hardware dummy_pcm_hardware = {
509
.info = (SNDRV_PCM_INFO_MMAP |
510
SNDRV_PCM_INFO_INTERLEAVED |
511
SNDRV_PCM_INFO_RESUME |
512
SNDRV_PCM_INFO_MMAP_VALID),
513
.formats = USE_FORMATS,
514
.rates = USE_RATE,
515
.rate_min = USE_RATE_MIN,
516
.rate_max = USE_RATE_MAX,
517
.channels_min = USE_CHANNELS_MIN,
518
.channels_max = USE_CHANNELS_MAX,
519
.buffer_bytes_max = MAX_BUFFER_SIZE,
520
.period_bytes_min = MIN_PERIOD_SIZE,
521
.period_bytes_max = MAX_PERIOD_SIZE,
522
.periods_min = USE_PERIODS_MIN,
523
.periods_max = USE_PERIODS_MAX,
524
.fifo_size = 0,
525
};
526
527
static int dummy_pcm_hw_params(struct snd_pcm_substream *substream,
528
struct snd_pcm_hw_params *hw_params)
529
{
530
if (fake_buffer) {
531
/* runtime->dma_bytes has to be set manually to allow mmap */
532
substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
533
return 0;
534
}
535
return 0;
536
}
537
538
static int dummy_pcm_open(struct snd_pcm_substream *substream)
539
{
540
struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
541
const struct dummy_model *model = dummy->model;
542
struct snd_pcm_runtime *runtime = substream->runtime;
543
const struct dummy_timer_ops *ops;
544
int err;
545
546
ops = &dummy_systimer_ops;
547
#ifdef CONFIG_HIGH_RES_TIMERS
548
if (hrtimer)
549
ops = &dummy_hrtimer_ops;
550
#endif
551
552
err = ops->create(substream);
553
if (err < 0)
554
return err;
555
get_dummy_ops(substream) = ops;
556
557
runtime->hw = dummy->pcm_hw;
558
if (substream->pcm->device & 1) {
559
runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
560
runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
561
}
562
if (substream->pcm->device & 2)
563
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
564
SNDRV_PCM_INFO_MMAP_VALID);
565
566
if (model == NULL)
567
return 0;
568
569
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
570
if (model->playback_constraints)
571
err = model->playback_constraints(substream->runtime);
572
} else {
573
if (model->capture_constraints)
574
err = model->capture_constraints(substream->runtime);
575
}
576
if (err < 0) {
577
get_dummy_ops(substream)->free(substream);
578
return err;
579
}
580
return 0;
581
}
582
583
static int dummy_pcm_close(struct snd_pcm_substream *substream)
584
{
585
get_dummy_ops(substream)->free(substream);
586
return 0;
587
}
588
589
/*
590
* dummy buffer handling
591
*/
592
593
static void *dummy_page[2];
594
595
static void free_fake_buffer(void)
596
{
597
if (fake_buffer) {
598
int i;
599
for (i = 0; i < 2; i++)
600
if (dummy_page[i]) {
601
free_page((unsigned long)dummy_page[i]);
602
dummy_page[i] = NULL;
603
}
604
}
605
}
606
607
static int alloc_fake_buffer(void)
608
{
609
int i;
610
611
if (!fake_buffer)
612
return 0;
613
for (i = 0; i < 2; i++) {
614
dummy_page[i] = (void *)get_zeroed_page(GFP_KERNEL);
615
if (!dummy_page[i]) {
616
free_fake_buffer();
617
return -ENOMEM;
618
}
619
}
620
return 0;
621
}
622
623
static int dummy_pcm_copy(struct snd_pcm_substream *substream,
624
int channel, unsigned long pos,
625
struct iov_iter *iter, unsigned long bytes)
626
{
627
return 0; /* do nothing */
628
}
629
630
static int dummy_pcm_silence(struct snd_pcm_substream *substream,
631
int channel, unsigned long pos,
632
unsigned long bytes)
633
{
634
return 0; /* do nothing */
635
}
636
637
static struct page *dummy_pcm_page(struct snd_pcm_substream *substream,
638
unsigned long offset)
639
{
640
return virt_to_page(dummy_page[substream->stream]); /* the same page */
641
}
642
643
static const struct snd_pcm_ops dummy_pcm_ops = {
644
.open = dummy_pcm_open,
645
.close = dummy_pcm_close,
646
.hw_params = dummy_pcm_hw_params,
647
.prepare = dummy_pcm_prepare,
648
.trigger = dummy_pcm_trigger,
649
.pointer = dummy_pcm_pointer,
650
};
651
652
static const struct snd_pcm_ops dummy_pcm_ops_no_buf = {
653
.open = dummy_pcm_open,
654
.close = dummy_pcm_close,
655
.hw_params = dummy_pcm_hw_params,
656
.prepare = dummy_pcm_prepare,
657
.trigger = dummy_pcm_trigger,
658
.pointer = dummy_pcm_pointer,
659
.copy = dummy_pcm_copy,
660
.fill_silence = dummy_pcm_silence,
661
.page = dummy_pcm_page,
662
};
663
664
static int snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
665
int substreams)
666
{
667
struct snd_pcm *pcm;
668
const struct snd_pcm_ops *ops;
669
int err;
670
671
err = snd_pcm_new(dummy->card, "Dummy PCM", device,
672
substreams, substreams, &pcm);
673
if (err < 0)
674
return err;
675
dummy->pcm = pcm;
676
if (fake_buffer)
677
ops = &dummy_pcm_ops_no_buf;
678
else
679
ops = &dummy_pcm_ops;
680
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ops);
681
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, ops);
682
pcm->private_data = dummy;
683
pcm->info_flags = 0;
684
strscpy(pcm->name, "Dummy PCM");
685
if (!fake_buffer) {
686
snd_pcm_set_managed_buffer_all(pcm,
687
SNDRV_DMA_TYPE_CONTINUOUS,
688
NULL,
689
0, 64*1024);
690
}
691
return 0;
692
}
693
694
/*
695
* mixer interface
696
*/
697
698
#define DUMMY_VOLUME(xname, xindex, addr) \
699
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
700
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
701
.name = xname, .index = xindex, \
702
.info = snd_dummy_volume_info, \
703
.get = snd_dummy_volume_get, .put = snd_dummy_volume_put, \
704
.private_value = addr, \
705
.tlv = { .p = db_scale_dummy } }
706
707
static int snd_dummy_volume_info(struct snd_kcontrol *kcontrol,
708
struct snd_ctl_elem_info *uinfo)
709
{
710
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
711
uinfo->count = 2;
712
uinfo->value.integer.min = mixer_volume_level_min;
713
uinfo->value.integer.max = mixer_volume_level_max;
714
return 0;
715
}
716
717
static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol,
718
struct snd_ctl_elem_value *ucontrol)
719
{
720
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
721
int addr = kcontrol->private_value;
722
723
guard(spinlock_irq)(&dummy->mixer_lock);
724
ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0];
725
ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1];
726
return 0;
727
}
728
729
static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol,
730
struct snd_ctl_elem_value *ucontrol)
731
{
732
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
733
int change, addr = kcontrol->private_value;
734
int left, right;
735
736
left = ucontrol->value.integer.value[0];
737
if (left < mixer_volume_level_min)
738
left = mixer_volume_level_min;
739
if (left > mixer_volume_level_max)
740
left = mixer_volume_level_max;
741
right = ucontrol->value.integer.value[1];
742
if (right < mixer_volume_level_min)
743
right = mixer_volume_level_min;
744
if (right > mixer_volume_level_max)
745
right = mixer_volume_level_max;
746
guard(spinlock_irq)(&dummy->mixer_lock);
747
change = dummy->mixer_volume[addr][0] != left ||
748
dummy->mixer_volume[addr][1] != right;
749
dummy->mixer_volume[addr][0] = left;
750
dummy->mixer_volume[addr][1] = right;
751
return change;
752
}
753
754
static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0);
755
756
#define DUMMY_CAPSRC(xname, xindex, addr) \
757
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
758
.info = snd_dummy_capsrc_info, \
759
.get = snd_dummy_capsrc_get, .put = snd_dummy_capsrc_put, \
760
.private_value = addr }
761
762
#define snd_dummy_capsrc_info snd_ctl_boolean_stereo_info
763
764
static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol,
765
struct snd_ctl_elem_value *ucontrol)
766
{
767
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
768
int addr = kcontrol->private_value;
769
770
guard(spinlock_irq)(&dummy->mixer_lock);
771
ucontrol->value.integer.value[0] = dummy->capture_source[addr][0];
772
ucontrol->value.integer.value[1] = dummy->capture_source[addr][1];
773
return 0;
774
}
775
776
static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
777
{
778
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
779
int change, addr = kcontrol->private_value;
780
int left, right;
781
782
left = ucontrol->value.integer.value[0] & 1;
783
right = ucontrol->value.integer.value[1] & 1;
784
guard(spinlock_irq)(&dummy->mixer_lock);
785
change = dummy->capture_source[addr][0] != left &&
786
dummy->capture_source[addr][1] != right;
787
dummy->capture_source[addr][0] = left;
788
dummy->capture_source[addr][1] = right;
789
return change;
790
}
791
792
static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol,
793
struct snd_ctl_elem_info *info)
794
{
795
static const char *const names[] = { "None", "CD Player" };
796
797
return snd_ctl_enum_info(info, 1, 2, names);
798
}
799
800
static int snd_dummy_iobox_get(struct snd_kcontrol *kcontrol,
801
struct snd_ctl_elem_value *value)
802
{
803
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
804
805
value->value.enumerated.item[0] = dummy->iobox;
806
return 0;
807
}
808
809
static int snd_dummy_iobox_put(struct snd_kcontrol *kcontrol,
810
struct snd_ctl_elem_value *value)
811
{
812
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
813
int changed;
814
815
if (value->value.enumerated.item[0] > 1)
816
return -EINVAL;
817
818
changed = value->value.enumerated.item[0] != dummy->iobox;
819
if (changed) {
820
dummy->iobox = value->value.enumerated.item[0];
821
822
if (dummy->iobox) {
823
dummy->cd_volume_ctl->vd[0].access &=
824
~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
825
dummy->cd_switch_ctl->vd[0].access &=
826
~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
827
} else {
828
dummy->cd_volume_ctl->vd[0].access |=
829
SNDRV_CTL_ELEM_ACCESS_INACTIVE;
830
dummy->cd_switch_ctl->vd[0].access |=
831
SNDRV_CTL_ELEM_ACCESS_INACTIVE;
832
}
833
834
snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
835
&dummy->cd_volume_ctl->id);
836
snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
837
&dummy->cd_switch_ctl->id);
838
}
839
840
return changed;
841
}
842
843
static const struct snd_kcontrol_new snd_dummy_controls[] = {
844
DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
845
DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER),
846
DUMMY_VOLUME("Synth Volume", 0, MIXER_ADDR_SYNTH),
847
DUMMY_CAPSRC("Synth Capture Switch", 0, MIXER_ADDR_SYNTH),
848
DUMMY_VOLUME("Line Volume", 0, MIXER_ADDR_LINE),
849
DUMMY_CAPSRC("Line Capture Switch", 0, MIXER_ADDR_LINE),
850
DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC),
851
DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC),
852
DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD),
853
DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD),
854
{
855
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
856
.name = "External I/O Box",
857
.info = snd_dummy_iobox_info,
858
.get = snd_dummy_iobox_get,
859
.put = snd_dummy_iobox_put,
860
},
861
};
862
863
static int snd_card_dummy_new_mixer(struct snd_dummy *dummy)
864
{
865
struct snd_card *card = dummy->card;
866
struct snd_kcontrol *kcontrol;
867
unsigned int idx;
868
int err;
869
870
spin_lock_init(&dummy->mixer_lock);
871
strscpy(card->mixername, "Dummy Mixer");
872
dummy->iobox = 1;
873
874
for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
875
kcontrol = snd_ctl_new1(&snd_dummy_controls[idx], dummy);
876
err = snd_ctl_add(card, kcontrol);
877
if (err < 0)
878
return err;
879
if (!strcmp(kcontrol->id.name, "CD Volume"))
880
dummy->cd_volume_ctl = kcontrol;
881
else if (!strcmp(kcontrol->id.name, "CD Capture Switch"))
882
dummy->cd_switch_ctl = kcontrol;
883
884
}
885
return 0;
886
}
887
888
#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_PROC_FS)
889
/*
890
* proc interface
891
*/
892
static void print_formats(struct snd_dummy *dummy,
893
struct snd_info_buffer *buffer)
894
{
895
snd_pcm_format_t i;
896
897
pcm_for_each_format(i) {
898
if (dummy->pcm_hw.formats & pcm_format_to_bits(i))
899
snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
900
}
901
}
902
903
static void print_rates(struct snd_dummy *dummy,
904
struct snd_info_buffer *buffer)
905
{
906
static const int rates[] = {
907
5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
908
64000, 88200, 96000, 176400, 192000,
909
};
910
int i;
911
912
if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS)
913
snd_iprintf(buffer, " continuous");
914
if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_KNOT)
915
snd_iprintf(buffer, " knot");
916
for (i = 0; i < ARRAY_SIZE(rates); i++)
917
if (dummy->pcm_hw.rates & (1 << i))
918
snd_iprintf(buffer, " %d", rates[i]);
919
}
920
921
#define get_dummy_int_ptr(dummy, ofs) \
922
(unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs))
923
#define get_dummy_ll_ptr(dummy, ofs) \
924
(unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs))
925
926
struct dummy_hw_field {
927
const char *name;
928
const char *format;
929
unsigned int offset;
930
unsigned int size;
931
};
932
#define FIELD_ENTRY(item, fmt) { \
933
.name = #item, \
934
.format = fmt, \
935
.offset = offsetof(struct snd_pcm_hardware, item), \
936
.size = sizeof(dummy_pcm_hardware.item) }
937
938
static const struct dummy_hw_field fields[] = {
939
FIELD_ENTRY(formats, "%#llx"),
940
FIELD_ENTRY(rates, "%#x"),
941
FIELD_ENTRY(rate_min, "%d"),
942
FIELD_ENTRY(rate_max, "%d"),
943
FIELD_ENTRY(channels_min, "%d"),
944
FIELD_ENTRY(channels_max, "%d"),
945
FIELD_ENTRY(buffer_bytes_max, "%ld"),
946
FIELD_ENTRY(period_bytes_min, "%ld"),
947
FIELD_ENTRY(period_bytes_max, "%ld"),
948
FIELD_ENTRY(periods_min, "%d"),
949
FIELD_ENTRY(periods_max, "%d"),
950
};
951
952
static void dummy_proc_read(struct snd_info_entry *entry,
953
struct snd_info_buffer *buffer)
954
{
955
struct snd_dummy *dummy = entry->private_data;
956
int i;
957
958
for (i = 0; i < ARRAY_SIZE(fields); i++) {
959
snd_iprintf(buffer, "%s ", fields[i].name);
960
if (fields[i].size == sizeof(int))
961
snd_iprintf(buffer, fields[i].format,
962
*get_dummy_int_ptr(dummy, fields[i].offset));
963
else
964
snd_iprintf(buffer, fields[i].format,
965
*get_dummy_ll_ptr(dummy, fields[i].offset));
966
if (!strcmp(fields[i].name, "formats"))
967
print_formats(dummy, buffer);
968
else if (!strcmp(fields[i].name, "rates"))
969
print_rates(dummy, buffer);
970
snd_iprintf(buffer, "\n");
971
}
972
}
973
974
static void dummy_proc_write(struct snd_info_entry *entry,
975
struct snd_info_buffer *buffer)
976
{
977
struct snd_dummy *dummy = entry->private_data;
978
char line[64];
979
980
while (!snd_info_get_line(buffer, line, sizeof(line))) {
981
char item[20];
982
const char *ptr;
983
unsigned long long val;
984
int i;
985
986
ptr = snd_info_get_str(item, line, sizeof(item));
987
for (i = 0; i < ARRAY_SIZE(fields); i++) {
988
if (!strcmp(item, fields[i].name))
989
break;
990
}
991
if (i >= ARRAY_SIZE(fields))
992
continue;
993
snd_info_get_str(item, ptr, sizeof(item));
994
if (kstrtoull(item, 0, &val))
995
continue;
996
if (fields[i].size == sizeof(int))
997
*get_dummy_int_ptr(dummy, fields[i].offset) = val;
998
else
999
*get_dummy_ll_ptr(dummy, fields[i].offset) = val;
1000
}
1001
}
1002
1003
static void dummy_proc_init(struct snd_dummy *chip)
1004
{
1005
snd_card_rw_proc_new(chip->card, "dummy_pcm", chip,
1006
dummy_proc_read, dummy_proc_write);
1007
}
1008
#else
1009
#define dummy_proc_init(x)
1010
#endif /* CONFIG_SND_DEBUG && CONFIG_SND_PROC_FS */
1011
1012
static int snd_dummy_probe(struct platform_device *devptr)
1013
{
1014
struct snd_card *card;
1015
struct snd_dummy *dummy;
1016
const struct dummy_model *m = NULL, **mdl;
1017
int idx, err;
1018
int dev = devptr->id;
1019
1020
err = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
1021
sizeof(struct snd_dummy), &card);
1022
if (err < 0)
1023
return err;
1024
dummy = card->private_data;
1025
dummy->card = card;
1026
for (mdl = dummy_models; *mdl && model[dev]; mdl++) {
1027
if (strcmp(model[dev], (*mdl)->name) == 0) {
1028
pr_info("snd-dummy: Using model '%s' for card %i\n",
1029
(*mdl)->name, card->number);
1030
m = dummy->model = *mdl;
1031
break;
1032
}
1033
}
1034
for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) {
1035
if (pcm_substreams[dev] < 1)
1036
pcm_substreams[dev] = 1;
1037
if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
1038
pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
1039
err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev]);
1040
if (err < 0)
1041
return err;
1042
}
1043
1044
dummy->pcm_hw = dummy_pcm_hardware;
1045
if (m) {
1046
if (m->formats)
1047
dummy->pcm_hw.formats = m->formats;
1048
if (m->buffer_bytes_max)
1049
dummy->pcm_hw.buffer_bytes_max = m->buffer_bytes_max;
1050
if (m->period_bytes_min)
1051
dummy->pcm_hw.period_bytes_min = m->period_bytes_min;
1052
if (m->period_bytes_max)
1053
dummy->pcm_hw.period_bytes_max = m->period_bytes_max;
1054
if (m->periods_min)
1055
dummy->pcm_hw.periods_min = m->periods_min;
1056
if (m->periods_max)
1057
dummy->pcm_hw.periods_max = m->periods_max;
1058
if (m->rates)
1059
dummy->pcm_hw.rates = m->rates;
1060
if (m->rate_min)
1061
dummy->pcm_hw.rate_min = m->rate_min;
1062
if (m->rate_max)
1063
dummy->pcm_hw.rate_max = m->rate_max;
1064
if (m->channels_min)
1065
dummy->pcm_hw.channels_min = m->channels_min;
1066
if (m->channels_max)
1067
dummy->pcm_hw.channels_max = m->channels_max;
1068
}
1069
1070
if (mixer_volume_level_min > mixer_volume_level_max) {
1071
pr_warn("snd-dummy: Invalid mixer volume level: min=%d, max=%d. Fall back to default value.\n",
1072
mixer_volume_level_min, mixer_volume_level_max);
1073
mixer_volume_level_min = USE_MIXER_VOLUME_LEVEL_MIN;
1074
mixer_volume_level_max = USE_MIXER_VOLUME_LEVEL_MAX;
1075
}
1076
err = snd_card_dummy_new_mixer(dummy);
1077
if (err < 0)
1078
return err;
1079
strscpy(card->driver, "Dummy");
1080
strscpy(card->shortname, "Dummy");
1081
sprintf(card->longname, "Dummy %i", dev + 1);
1082
1083
dummy_proc_init(dummy);
1084
1085
err = snd_card_register(card);
1086
if (err < 0)
1087
return err;
1088
platform_set_drvdata(devptr, card);
1089
return 0;
1090
}
1091
1092
static int snd_dummy_suspend(struct device *pdev)
1093
{
1094
struct snd_card *card = dev_get_drvdata(pdev);
1095
1096
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1097
return 0;
1098
}
1099
1100
static int snd_dummy_resume(struct device *pdev)
1101
{
1102
struct snd_card *card = dev_get_drvdata(pdev);
1103
1104
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1105
return 0;
1106
}
1107
1108
static DEFINE_SIMPLE_DEV_PM_OPS(snd_dummy_pm, snd_dummy_suspend, snd_dummy_resume);
1109
1110
#define SND_DUMMY_DRIVER "snd_dummy"
1111
1112
static struct platform_driver snd_dummy_driver = {
1113
.probe = snd_dummy_probe,
1114
.driver = {
1115
.name = SND_DUMMY_DRIVER,
1116
.pm = &snd_dummy_pm,
1117
},
1118
};
1119
1120
static void snd_dummy_unregister_all(void)
1121
{
1122
int i;
1123
1124
for (i = 0; i < ARRAY_SIZE(devices); ++i)
1125
platform_device_unregister(devices[i]);
1126
platform_driver_unregister(&snd_dummy_driver);
1127
free_fake_buffer();
1128
}
1129
1130
static int __init alsa_card_dummy_init(void)
1131
{
1132
int i, cards, err;
1133
1134
err = platform_driver_register(&snd_dummy_driver);
1135
if (err < 0)
1136
return err;
1137
1138
err = alloc_fake_buffer();
1139
if (err < 0) {
1140
platform_driver_unregister(&snd_dummy_driver);
1141
return err;
1142
}
1143
1144
cards = 0;
1145
for (i = 0; i < SNDRV_CARDS; i++) {
1146
struct platform_device *device;
1147
if (! enable[i])
1148
continue;
1149
device = platform_device_register_simple(SND_DUMMY_DRIVER,
1150
i, NULL, 0);
1151
if (IS_ERR(device))
1152
continue;
1153
if (!platform_get_drvdata(device)) {
1154
platform_device_unregister(device);
1155
continue;
1156
}
1157
devices[i] = device;
1158
cards++;
1159
}
1160
if (!cards) {
1161
#ifdef MODULE
1162
pr_err("Dummy soundcard not found or device busy\n");
1163
#endif
1164
snd_dummy_unregister_all();
1165
return -ENODEV;
1166
}
1167
return 0;
1168
}
1169
1170
static void __exit alsa_card_dummy_exit(void)
1171
{
1172
snd_dummy_unregister_all();
1173
}
1174
1175
module_init(alsa_card_dummy_init)
1176
module_exit(alsa_card_dummy_exit)
1177
1178