Lines Matching +full:min +full:- +full:sample +full:- +full:time +full:- +full:nsecs
1 // SPDX-License-Identifier: GPL-2.0-or-later
13 #include <linux/time.h>
46 #define USE_MIXER_VOLUME_LEVEL_MIN -50
49 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
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};
72 MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
74 MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
76 //MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
78 MODULE_PARM_DESC(mixer_volume_level_min, "Minimum mixer volume level for dummy driver. Default: -50");
107 (*(const struct dummy_timer_ops **)(substream)->runtime->private_data)
204 .buffer_bytes_max = ((65536-64)*8),
205 .period_bytes_max = (65536-64),
235 unsigned int frac_pos; /* fractional sample position (based HZ) */
246 mod_timer(&dpcm->timer, jiffies +
247 DIV_ROUND_UP(dpcm->frac_period_rest, dpcm->rate));
254 delta = jiffies - dpcm->base_time;
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;
266 dpcm->frac_period_rest -= delta;
271 struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
273 guard(spinlock)(&dpcm->lock);
274 dpcm->base_time = jiffies;
281 struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
283 guard(spinlock)(&dpcm->lock);
284 timer_delete(&dpcm->timer);
290 struct snd_pcm_runtime *runtime = substream->runtime;
291 struct dummy_systimer_pcm *dpcm = runtime->private_data;
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;
308 scoped_guard(spinlock_irqsave, &dpcm->lock) {
311 elapsed = dpcm->elapsed;
312 dpcm->elapsed = 0;
315 snd_pcm_period_elapsed(dpcm->substream);
321 struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
323 guard(spinlock)(&dpcm->lock);
325 return dpcm->frac_pos / HZ;
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;
344 kfree(substream->runtime->private_data);
376 if (!atomic_read(&dpcm->running))
382 snd_pcm_period_elapsed(dpcm->substream);
383 if (!atomic_read(&dpcm->running))
386 hrtimer_forward_now(timer, dpcm->period_time);
392 struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
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);
402 struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
404 atomic_set(&dpcm->running, 0);
405 if (!hrtimer_callback_running(&dpcm->timer))
406 hrtimer_cancel(&dpcm->timer);
412 hrtimer_cancel(&dpcm->timer);
418 struct snd_pcm_runtime *runtime = substream->runtime;
419 struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
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);
432 struct snd_pcm_runtime *runtime = substream->runtime;
433 struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
436 unsigned long nsecs;
439 period = runtime->period_size;
440 rate = runtime->rate;
443 nsecs = div_u64((u64)period * 1000000000UL + rate - 1, rate);
444 dpcm->period_time = ktime_set(sec, nsecs);
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);
465 struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
490 return get_dummy_ops(substream)->start(substream);
493 return get_dummy_ops(substream)->stop(substream);
495 return -EINVAL;
500 return get_dummy_ops(substream)->prepare(substream);
505 return get_dummy_ops(substream)->pointer(substream);
531 /* runtime->dma_bytes has to be set manually to allow mmap */
532 substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
541 const struct dummy_model *model = dummy->model;
542 struct snd_pcm_runtime *runtime = substream->runtime;
552 err = ops->create(substream);
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;
562 if (substream->pcm->device & 2)
563 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
569 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
570 if (model->playback_constraints)
571 err = model->playback_constraints(substream->runtime);
573 if (model->capture_constraints)
574 err = model->capture_constraints(substream->runtime);
577 get_dummy_ops(substream)->free(substream);
585 get_dummy_ops(substream)->free(substream);
617 return -ENOMEM;
640 return virt_to_page(dummy_page[substream->stream]); /* the same page */
671 err = snd_pcm_new(dummy->card, "Dummy PCM", device,
675 dummy->pcm = pcm;
682 pcm->private_data = dummy;
683 pcm->info_flags = 0;
684 strscpy(pcm->name, "Dummy PCM");
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;
721 int addr = kcontrol->private_value;
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];
733 int change, addr = kcontrol->private_value;
736 left = ucontrol->value.integer.value[0];
741 right = ucontrol->value.integer.value[1];
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;
754 static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0);
768 int addr = kcontrol->private_value;
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];
779 int change, addr = kcontrol->private_value;
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;
805 value->value.enumerated.item[0] = dummy->iobox;
815 if (value->value.enumerated.item[0] > 1)
816 return -EINVAL;
818 changed = value->value.enumerated.item[0] != dummy->iobox;
820 dummy->iobox = value->value.enumerated.item[0];
822 if (dummy->iobox) {
823 dummy->cd_volume_ctl->vd[0].access &=
825 dummy->cd_switch_ctl->vd[0].access &=
828 dummy->cd_volume_ctl->vd[0].access |=
830 dummy->cd_switch_ctl->vd[0].access |=
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);
865 struct snd_card *card = dummy->card;
870 spin_lock_init(&dummy->mixer_lock);
871 strscpy(card->mixername, "Dummy Mixer");
872 dummy->iobox = 1;
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;
898 if (dummy->pcm_hw.formats & pcm_format_to_bits(i))
912 if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS)
914 if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_KNOT)
917 if (dummy->pcm_hw.rates & (1 << i))
922 (unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs))
924 (unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs))
955 struct snd_dummy *dummy = entry->private_data;
977 struct snd_dummy *dummy = entry->private_data;
1005 snd_card_rw_proc_new(chip->card, "dummy_pcm", chip,
1018 int dev = devptr->id;
1020 err = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
1024 dummy = card->private_data;
1025 dummy->card = card;
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;
1044 dummy->pcm_hw = dummy_pcm_hardware;
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;
1071 pr_warn("snd-dummy: Invalid mixer volume level: min=%d, max=%d. Fall back to default value.\n",
1079 strscpy(card->driver, "Dummy");
1080 strscpy(card->shortname, "Dummy");
1081 sprintf(card->longname, "Dummy %i", dev + 1);
1165 return -ENODEV;