Skip to content

Commit 22459ef

Browse files
ivanorlov2206tiwai
authored andcommitted
ALSA: pcmtest: Add support for pcm pausing
Add pause push/release support to the virtual PCM test driver. Add 'suspend' boolean field to the pcmtst_buf_iter structure, so we can pause the timer without shutting it down. Update the trigger callback handler correspondingly. Extract buffer initialization to the 'reset_buf_iterator' function since it is used in multiple places now. Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com> Link: https://lore.kernel.org/r/20230822150541.8450-1-ivan.orlov0322@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 93dc18e commit 22459ef

1 file changed

Lines changed: 41 additions & 8 deletions

File tree

sound/drivers/pcmtest.c

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,16 @@ struct pcmtst_buf_iter {
108108
size_t total_bytes; // Total bytes read/written
109109
size_t chan_block; // Bytes in one channel buffer when non-interleaved
110110
struct snd_pcm_substream *substream;
111+
bool suspend; // We need to pause timer without shutting it down
111112
struct timer_list timer_instance;
112113
};
113114

114115
static struct snd_pcm_hardware snd_pcmtst_hw = {
115116
.info = (SNDRV_PCM_INFO_INTERLEAVED |
116117
SNDRV_PCM_INFO_BLOCK_TRANSFER |
117118
SNDRV_PCM_INFO_NONINTERLEAVED |
118-
SNDRV_PCM_INFO_MMAP_VALID),
119+
SNDRV_PCM_INFO_MMAP_VALID |
120+
SNDRV_PCM_INFO_PAUSE),
119121
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
120122
.rates = SNDRV_PCM_RATE_8000_48000,
121123
.rate_min = 8000,
@@ -346,6 +348,9 @@ static void timer_timeout(struct timer_list *data)
346348
v_iter = from_timer(v_iter, data, timer_instance);
347349
substream = v_iter->substream;
348350

351+
if (v_iter->suspend)
352+
return;
353+
349354
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !v_iter->is_buf_corrupted)
350355
check_buf_block(v_iter, substream->runtime);
351356
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -358,7 +363,9 @@ static void timer_timeout(struct timer_list *data)
358363
v_iter->period_pos %= v_iter->period_bytes;
359364
snd_pcm_period_elapsed(substream);
360365
}
361-
mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL + inject_delay);
366+
367+
if (!v_iter->suspend)
368+
mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL + inject_delay);
362369
}
363370

364371
static int snd_pcmtst_pcm_open(struct snd_pcm_substream *substream)
@@ -373,19 +380,15 @@ static int snd_pcmtst_pcm_open(struct snd_pcm_substream *substream)
373380
if (!v_iter)
374381
return -ENOMEM;
375382

383+
v_iter->substream = substream;
376384
runtime->hw = snd_pcmtst_hw;
377385
runtime->private_data = v_iter;
378-
v_iter->substream = substream;
379-
v_iter->buf_pos = 0;
380-
v_iter->is_buf_corrupted = false;
381-
v_iter->period_pos = 0;
382-
v_iter->total_bytes = 0;
383386

384387
playback_capture_test = 0;
385388
ioctl_reset_test = 0;
386389

387390
timer_setup(&v_iter->timer_instance, timer_timeout, 0);
388-
mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL);
391+
389392
return 0;
390393
}
391394

@@ -400,10 +403,40 @@ static int snd_pcmtst_pcm_close(struct snd_pcm_substream *substream)
400403
return 0;
401404
}
402405

406+
static inline void reset_buf_iterator(struct pcmtst_buf_iter *v_iter)
407+
{
408+
v_iter->buf_pos = 0;
409+
v_iter->is_buf_corrupted = false;
410+
v_iter->period_pos = 0;
411+
v_iter->total_bytes = 0;
412+
}
413+
414+
static inline void start_pcmtest_timer(struct pcmtst_buf_iter *v_iter)
415+
{
416+
v_iter->suspend = false;
417+
mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL);
418+
}
419+
403420
static int snd_pcmtst_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
404421
{
422+
struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
423+
405424
if (inject_trigger_err)
406425
return -EINVAL;
426+
switch (cmd) {
427+
case SNDRV_PCM_TRIGGER_START:
428+
reset_buf_iterator(v_iter);
429+
start_pcmtest_timer(v_iter);
430+
break;
431+
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
432+
start_pcmtest_timer(v_iter);
433+
break;
434+
case SNDRV_PCM_TRIGGER_STOP:
435+
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
436+
// We can't call timer_shutdown_sync here, as it is forbidden to sleep here
437+
v_iter->suspend = true;
438+
break;
439+
}
407440

408441
return 0;
409442
}

0 commit comments

Comments
 (0)