MLK-21002-1: ASoC: imx-pcm-rpmsg: fix data consumed faster with pause
In LPA, we use the timer to simulate the interrupt, if the period time
is 1s, the timer is 500ms, which means the interrupt is more frequent
than actual.
With pause ALSA will update the hw_ptr_jiffies, because the interrupt
is more frequent, so sometimes in snd_pcm_update_hw_ptr0, the condition
delta > new_hw_ptr will be true, then the new_hw_ptr will be added whole
buffer_size, which cause the whole buffer be flushed.
if (in_interrupt) {
/* we know that one period was processed */
/* delta = "expected next hw_ptr" for in_interrupt != 0 */
delta = runtime->hw_ptr_interrupt + runtime->period_size;
if (delta > new_hw_ptr) {
/* check for double acknowledged interrupts */
hdelta = curr_jiffies - runtime->hw_ptr_jiffies;
if (hdelta > runtime->hw_ptr_buffer_jiffies/2 + 1) {
hw_base += runtime->buffer_size;
if (hw_base >= runtime->boundary) {
hw_base = 0;
crossed_boundary++;
}
new_hw_ptr = hw_base + pos;
goto __delta;
}
}
}
So even we use the timer to simulate the interrupt, the timer should
be same as the period time, otherwise will cause issue.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
(cherry picked from commit 9a9af932118774083119dba72c5c6133852ba926)
diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c
index e46b80a..64f9632 100644
--- a/sound/soc/fsl/imx-pcm-rpmsg.c
+++ b/sound/soc/fsl/imx-pcm-rpmsg.c
@@ -147,8 +147,7 @@ static void imx_rpmsg_timer_callback(unsigned long data)
i2s_info->work_index %= WORK_MAX_NUM;
if (rpmsg_i2s->force_lpa) {
- time_msec = min(500,
- (int)(runtime->period_size*1000/runtime->rate));
+ time_msec = (int)(runtime->period_size*1000/runtime->rate);
mod_timer(&i2s_info->stream_timer[substream->stream],
jiffies + msecs_to_jiffies(time_msec));
}
@@ -311,8 +310,7 @@ static void imx_rpmsg_pcm_dma_complete(void *arg)
int time_msec;
substream->runtime->status->state = SNDRV_PCM_STATE_RUNNING;
- time_msec = min(500,
- (int)(runtime->period_size*1000/runtime->rate));
+ time_msec = (int)(runtime->period_size*1000/runtime->rate);
mod_timer(&i2s_info->stream_timer[substream->stream],
jiffies + msecs_to_jiffies(time_msec));
}
@@ -387,8 +385,7 @@ static void imx_rpmsg_async_issue_pending(struct snd_pcm_substream *substream)
i2s_info->work_index %= WORK_MAX_NUM;
if (rpmsg_i2s->force_lpa) {
- time_msec = min(500,
- (int)(runtime->period_size*1000/runtime->rate));
+ time_msec = (int)(runtime->period_size*1000/runtime->rate);
mod_timer(&i2s_info->stream_timer[substream->stream],
jiffies + msecs_to_jiffies(time_msec));
}