cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dummy.c (31473B)


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