Lines Matching +full:min +full:- +full:sample +full:- +full:time +full:- +full:nsecs

1 // SPDX-License-Identifier: GPL-2.0-or-later
12 #include <linux/time.h>
47 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49 static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
50 static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
51 static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
52 static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
53 //static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
68 MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
70 MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
72 //MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
99 (*(const struct dummy_timer_ops **)(substream)->runtime->private_data)
196 .buffer_bytes_max = ((65536-64)*8),
197 .period_bytes_max = (65536-64),
227 unsigned int frac_pos; /* fractional sample position (based HZ) */
238 mod_timer(&dpcm->timer, jiffies + in dummy_systimer_rearm()
239 (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate); in dummy_systimer_rearm()
246 delta = jiffies - dpcm->base_time; in dummy_systimer_update()
249 dpcm->base_time += delta; in dummy_systimer_update()
250 delta *= dpcm->rate; in dummy_systimer_update()
251 dpcm->frac_pos += delta; in dummy_systimer_update()
252 while (dpcm->frac_pos >= dpcm->frac_buffer_size) in dummy_systimer_update()
253 dpcm->frac_pos -= dpcm->frac_buffer_size; in dummy_systimer_update()
254 while (dpcm->frac_period_rest <= delta) { in dummy_systimer_update()
255 dpcm->elapsed++; in dummy_systimer_update()
256 dpcm->frac_period_rest += dpcm->frac_period_size; in dummy_systimer_update()
258 dpcm->frac_period_rest -= delta; in dummy_systimer_update()
263 struct dummy_systimer_pcm *dpcm = substream->runtime->private_data; in dummy_systimer_start()
264 spin_lock(&dpcm->lock); in dummy_systimer_start()
265 dpcm->base_time = jiffies; in dummy_systimer_start()
267 spin_unlock(&dpcm->lock); in dummy_systimer_start()
273 struct dummy_systimer_pcm *dpcm = substream->runtime->private_data; in dummy_systimer_stop()
274 spin_lock(&dpcm->lock); in dummy_systimer_stop()
275 del_timer(&dpcm->timer); in dummy_systimer_stop()
276 spin_unlock(&dpcm->lock); in dummy_systimer_stop()
282 struct snd_pcm_runtime *runtime = substream->runtime; in dummy_systimer_prepare()
283 struct dummy_systimer_pcm *dpcm = runtime->private_data; in dummy_systimer_prepare()
285 dpcm->frac_pos = 0; in dummy_systimer_prepare()
286 dpcm->rate = runtime->rate; in dummy_systimer_prepare()
287 dpcm->frac_buffer_size = runtime->buffer_size * HZ; in dummy_systimer_prepare()
288 dpcm->frac_period_size = runtime->period_size * HZ; in dummy_systimer_prepare()
289 dpcm->frac_period_rest = dpcm->frac_period_size; in dummy_systimer_prepare()
290 dpcm->elapsed = 0; in dummy_systimer_prepare()
301 spin_lock_irqsave(&dpcm->lock, flags); in dummy_systimer_callback()
304 elapsed = dpcm->elapsed; in dummy_systimer_callback()
305 dpcm->elapsed = 0; in dummy_systimer_callback()
306 spin_unlock_irqrestore(&dpcm->lock, flags); in dummy_systimer_callback()
308 snd_pcm_period_elapsed(dpcm->substream); in dummy_systimer_callback()
314 struct dummy_systimer_pcm *dpcm = substream->runtime->private_data; in dummy_systimer_pointer()
317 spin_lock(&dpcm->lock); in dummy_systimer_pointer()
319 pos = dpcm->frac_pos / HZ; in dummy_systimer_pointer()
320 spin_unlock(&dpcm->lock); in dummy_systimer_pointer()
330 return -ENOMEM; in dummy_systimer_create()
331 substream->runtime->private_data = dpcm; in dummy_systimer_create()
332 timer_setup(&dpcm->timer, dummy_systimer_callback, 0); in dummy_systimer_create()
333 spin_lock_init(&dpcm->lock); in dummy_systimer_create()
334 dpcm->substream = substream; in dummy_systimer_create()
340 kfree(substream->runtime->private_data); in dummy_systimer_free()
372 if (!atomic_read(&dpcm->running)) in dummy_hrtimer_callback()
378 snd_pcm_period_elapsed(dpcm->substream); in dummy_hrtimer_callback()
379 if (!atomic_read(&dpcm->running)) in dummy_hrtimer_callback()
382 hrtimer_forward_now(timer, dpcm->period_time); in dummy_hrtimer_callback()
388 struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; in dummy_hrtimer_start()
390 dpcm->base_time = hrtimer_cb_get_time(&dpcm->timer); in dummy_hrtimer_start()
391 hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL_SOFT); in dummy_hrtimer_start()
392 atomic_set(&dpcm->running, 1); in dummy_hrtimer_start()
398 struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; in dummy_hrtimer_stop()
400 atomic_set(&dpcm->running, 0); in dummy_hrtimer_stop()
401 if (!hrtimer_callback_running(&dpcm->timer)) in dummy_hrtimer_stop()
402 hrtimer_cancel(&dpcm->timer); in dummy_hrtimer_stop()
408 hrtimer_cancel(&dpcm->timer); in dummy_hrtimer_sync()
414 struct snd_pcm_runtime *runtime = substream->runtime; in dummy_hrtimer_pointer()
415 struct dummy_hrtimer_pcm *dpcm = runtime->private_data; in dummy_hrtimer_pointer()
419 delta = ktime_us_delta(hrtimer_cb_get_time(&dpcm->timer), in dummy_hrtimer_pointer()
420 dpcm->base_time); in dummy_hrtimer_pointer()
421 delta = div_u64(delta * runtime->rate + 999999, 1000000); in dummy_hrtimer_pointer()
422 div_u64_rem(delta, runtime->buffer_size, &pos); in dummy_hrtimer_pointer()
428 struct snd_pcm_runtime *runtime = substream->runtime; in dummy_hrtimer_prepare()
429 struct dummy_hrtimer_pcm *dpcm = runtime->private_data; in dummy_hrtimer_prepare()
432 unsigned long nsecs; in dummy_hrtimer_prepare() local
435 period = runtime->period_size; in dummy_hrtimer_prepare()
436 rate = runtime->rate; in dummy_hrtimer_prepare()
439 nsecs = div_u64((u64)period * 1000000000UL + rate - 1, rate); in dummy_hrtimer_prepare()
440 dpcm->period_time = ktime_set(sec, nsecs); in dummy_hrtimer_prepare()
451 return -ENOMEM; in dummy_hrtimer_create()
452 substream->runtime->private_data = dpcm; in dummy_hrtimer_create()
453 hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); in dummy_hrtimer_create()
454 dpcm->timer.function = dummy_hrtimer_callback; in dummy_hrtimer_create()
455 dpcm->substream = substream; in dummy_hrtimer_create()
456 atomic_set(&dpcm->running, 0); in dummy_hrtimer_create()
462 struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; in dummy_hrtimer_free()
487 return get_dummy_ops(substream)->start(substream); in dummy_pcm_trigger()
490 return get_dummy_ops(substream)->stop(substream); in dummy_pcm_trigger()
492 return -EINVAL; in dummy_pcm_trigger()
497 return get_dummy_ops(substream)->prepare(substream); in dummy_pcm_prepare()
502 return get_dummy_ops(substream)->pointer(substream); in dummy_pcm_pointer()
528 /* runtime->dma_bytes has to be set manually to allow mmap */ in dummy_pcm_hw_params()
529 substream->runtime->dma_bytes = params_buffer_bytes(hw_params); in dummy_pcm_hw_params()
538 const struct dummy_model *model = dummy->model; in dummy_pcm_open()
539 struct snd_pcm_runtime *runtime = substream->runtime; in dummy_pcm_open()
549 err = ops->create(substream); in dummy_pcm_open()
554 runtime->hw = dummy->pcm_hw; in dummy_pcm_open()
555 if (substream->pcm->device & 1) { in dummy_pcm_open()
556 runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; in dummy_pcm_open()
557 runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; in dummy_pcm_open()
559 if (substream->pcm->device & 2) in dummy_pcm_open()
560 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | in dummy_pcm_open()
566 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in dummy_pcm_open()
567 if (model->playback_constraints) in dummy_pcm_open()
568 err = model->playback_constraints(substream->runtime); in dummy_pcm_open()
570 if (model->capture_constraints) in dummy_pcm_open()
571 err = model->capture_constraints(substream->runtime); in dummy_pcm_open()
574 get_dummy_ops(substream)->free(substream); in dummy_pcm_open()
582 get_dummy_ops(substream)->free(substream); in dummy_pcm_close()
614 return -ENOMEM; in alloc_fake_buffer()
644 return virt_to_page(dummy_page[substream->stream]); /* the same page */ in dummy_pcm_page()
676 err = snd_pcm_new(dummy->card, "Dummy PCM", device, in snd_card_dummy_pcm()
680 dummy->pcm = pcm; in snd_card_dummy_pcm()
687 pcm->private_data = dummy; in snd_card_dummy_pcm()
688 pcm->info_flags = 0; in snd_card_dummy_pcm()
689 strcpy(pcm->name, "Dummy PCM"); in snd_card_dummy_pcm()
715 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_dummy_volume_info()
716 uinfo->count = 2; in snd_dummy_volume_info()
717 uinfo->value.integer.min = -50; in snd_dummy_volume_info()
718 uinfo->value.integer.max = 100; in snd_dummy_volume_info()
726 int addr = kcontrol->private_value; in snd_dummy_volume_get()
728 spin_lock_irq(&dummy->mixer_lock); in snd_dummy_volume_get()
729 ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0]; in snd_dummy_volume_get()
730 ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1]; in snd_dummy_volume_get()
731 spin_unlock_irq(&dummy->mixer_lock); in snd_dummy_volume_get()
739 int change, addr = kcontrol->private_value; in snd_dummy_volume_put()
742 left = ucontrol->value.integer.value[0]; in snd_dummy_volume_put()
743 if (left < -50) in snd_dummy_volume_put()
744 left = -50; in snd_dummy_volume_put()
747 right = ucontrol->value.integer.value[1]; in snd_dummy_volume_put()
748 if (right < -50) in snd_dummy_volume_put()
749 right = -50; in snd_dummy_volume_put()
752 spin_lock_irq(&dummy->mixer_lock); in snd_dummy_volume_put()
753 change = dummy->mixer_volume[addr][0] != left || in snd_dummy_volume_put()
754 dummy->mixer_volume[addr][1] != right; in snd_dummy_volume_put()
755 dummy->mixer_volume[addr][0] = left; in snd_dummy_volume_put()
756 dummy->mixer_volume[addr][1] = right; in snd_dummy_volume_put()
757 spin_unlock_irq(&dummy->mixer_lock); in snd_dummy_volume_put()
761 static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0);
775 int addr = kcontrol->private_value; in snd_dummy_capsrc_get()
777 spin_lock_irq(&dummy->mixer_lock); in snd_dummy_capsrc_get()
778 ucontrol->value.integer.value[0] = dummy->capture_source[addr][0]; in snd_dummy_capsrc_get()
779 ucontrol->value.integer.value[1] = dummy->capture_source[addr][1]; in snd_dummy_capsrc_get()
780 spin_unlock_irq(&dummy->mixer_lock); in snd_dummy_capsrc_get()
787 int change, addr = kcontrol->private_value; in snd_dummy_capsrc_put()
790 left = ucontrol->value.integer.value[0] & 1; in snd_dummy_capsrc_put()
791 right = ucontrol->value.integer.value[1] & 1; in snd_dummy_capsrc_put()
792 spin_lock_irq(&dummy->mixer_lock); in snd_dummy_capsrc_put()
793 change = dummy->capture_source[addr][0] != left && in snd_dummy_capsrc_put()
794 dummy->capture_source[addr][1] != right; in snd_dummy_capsrc_put()
795 dummy->capture_source[addr][0] = left; in snd_dummy_capsrc_put()
796 dummy->capture_source[addr][1] = right; in snd_dummy_capsrc_put()
797 spin_unlock_irq(&dummy->mixer_lock); in snd_dummy_capsrc_put()
814 value->value.enumerated.item[0] = dummy->iobox; in snd_dummy_iobox_get()
824 if (value->value.enumerated.item[0] > 1) in snd_dummy_iobox_put()
825 return -EINVAL; in snd_dummy_iobox_put()
827 changed = value->value.enumerated.item[0] != dummy->iobox; in snd_dummy_iobox_put()
829 dummy->iobox = value->value.enumerated.item[0]; in snd_dummy_iobox_put()
831 if (dummy->iobox) { in snd_dummy_iobox_put()
832 dummy->cd_volume_ctl->vd[0].access &= in snd_dummy_iobox_put()
834 dummy->cd_switch_ctl->vd[0].access &= in snd_dummy_iobox_put()
837 dummy->cd_volume_ctl->vd[0].access |= in snd_dummy_iobox_put()
839 dummy->cd_switch_ctl->vd[0].access |= in snd_dummy_iobox_put()
843 snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO, in snd_dummy_iobox_put()
844 &dummy->cd_volume_ctl->id); in snd_dummy_iobox_put()
845 snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO, in snd_dummy_iobox_put()
846 &dummy->cd_switch_ctl->id); in snd_dummy_iobox_put()
874 struct snd_card *card = dummy->card; in snd_card_dummy_new_mixer()
879 spin_lock_init(&dummy->mixer_lock); in snd_card_dummy_new_mixer()
880 strcpy(card->mixername, "Dummy Mixer"); in snd_card_dummy_new_mixer()
881 dummy->iobox = 1; in snd_card_dummy_new_mixer()
888 if (!strcmp(kcontrol->id.name, "CD Volume")) in snd_card_dummy_new_mixer()
889 dummy->cd_volume_ctl = kcontrol; in snd_card_dummy_new_mixer()
890 else if (!strcmp(kcontrol->id.name, "CD Capture Switch")) in snd_card_dummy_new_mixer()
891 dummy->cd_switch_ctl = kcontrol; in snd_card_dummy_new_mixer()
907 if (dummy->pcm_hw.formats & pcm_format_to_bits(i)) in print_formats()
921 if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS) in print_rates()
923 if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_KNOT) in print_rates()
926 if (dummy->pcm_hw.rates & (1 << i)) in print_rates()
931 (unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs))
933 (unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs))
964 struct snd_dummy *dummy = entry->private_data; in dummy_proc_read()
986 struct snd_dummy *dummy = entry->private_data; in dummy_proc_write()
1014 snd_card_rw_proc_new(chip->card, "dummy_pcm", chip, in dummy_proc_init()
1027 int dev = devptr->id; in snd_dummy_probe()
1029 err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE, in snd_dummy_probe()
1033 dummy = card->private_data; in snd_dummy_probe()
1034 dummy->card = card; in snd_dummy_probe()
1036 if (strcmp(model[dev], (*mdl)->name) == 0) { in snd_dummy_probe()
1038 "snd-dummy: Using model '%s' for card %i\n", in snd_dummy_probe()
1039 (*mdl)->name, card->number); in snd_dummy_probe()
1040 m = dummy->model = *mdl; in snd_dummy_probe()
1054 dummy->pcm_hw = dummy_pcm_hardware; in snd_dummy_probe()
1056 if (m->formats) in snd_dummy_probe()
1057 dummy->pcm_hw.formats = m->formats; in snd_dummy_probe()
1058 if (m->buffer_bytes_max) in snd_dummy_probe()
1059 dummy->pcm_hw.buffer_bytes_max = m->buffer_bytes_max; in snd_dummy_probe()
1060 if (m->period_bytes_min) in snd_dummy_probe()
1061 dummy->pcm_hw.period_bytes_min = m->period_bytes_min; in snd_dummy_probe()
1062 if (m->period_bytes_max) in snd_dummy_probe()
1063 dummy->pcm_hw.period_bytes_max = m->period_bytes_max; in snd_dummy_probe()
1064 if (m->periods_min) in snd_dummy_probe()
1065 dummy->pcm_hw.periods_min = m->periods_min; in snd_dummy_probe()
1066 if (m->periods_max) in snd_dummy_probe()
1067 dummy->pcm_hw.periods_max = m->periods_max; in snd_dummy_probe()
1068 if (m->rates) in snd_dummy_probe()
1069 dummy->pcm_hw.rates = m->rates; in snd_dummy_probe()
1070 if (m->rate_min) in snd_dummy_probe()
1071 dummy->pcm_hw.rate_min = m->rate_min; in snd_dummy_probe()
1072 if (m->rate_max) in snd_dummy_probe()
1073 dummy->pcm_hw.rate_max = m->rate_max; in snd_dummy_probe()
1074 if (m->channels_min) in snd_dummy_probe()
1075 dummy->pcm_hw.channels_min = m->channels_min; in snd_dummy_probe()
1076 if (m->channels_max) in snd_dummy_probe()
1077 dummy->pcm_hw.channels_max = m->channels_max; in snd_dummy_probe()
1083 strcpy(card->driver, "Dummy"); in snd_dummy_probe()
1084 strcpy(card->shortname, "Dummy"); in snd_dummy_probe()
1085 sprintf(card->longname, "Dummy %i", dev + 1); in snd_dummy_probe()
1184 return -ENODEV; in alsa_card_dummy_init()