| From e1ee1d875f24ebb9fc43706e2198c08e65d14179 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 16 Jul 2021 18:00:12 +0530 |
| Subject: ASoC: soc-pcm: add a flag to reverse the stop sequence |
| |
| From: Vijendar Mukunda <vijendar.mukunda@amd.com> |
| |
| [ Upstream commit 59dd33f82dc0975c55d3d46801e7ca45532d7673 ] |
| |
| On stream stop, currently CPU DAI stop sequence invoked first |
| followed by DMA. For Few platforms, it is required to stop the |
| DMA first before stopping CPU DAI. |
| |
| Introduced new flag in dai_link structure for reordering stop sequence. |
| Based on flag check, ASoC core will re-order the stop sequence. |
| |
| Fixes: 4378f1fbe92405 ("ASoC: soc-pcm: Use different sequence for start/stop trigger") |
| Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com> |
| Link: https://lore.kernel.org/r/20210716123015.15697-1-vijendar.mukunda@amd.com |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/sound/soc.h | 6 ++++++ |
| sound/soc/soc-pcm.c | 22 ++++++++++++++++------ |
| 2 files changed, 22 insertions(+), 6 deletions(-) |
| |
| diff --git a/include/sound/soc.h b/include/sound/soc.h |
| index e746da996351..723eeb1c3f78 100644 |
| --- a/include/sound/soc.h |
| +++ b/include/sound/soc.h |
| @@ -712,6 +712,12 @@ struct snd_soc_dai_link { |
| /* Do not create a PCM for this DAI link (Backend link) */ |
| unsigned int ignore:1; |
| |
| + /* This flag will reorder stop sequence. By enabling this flag |
| + * DMA controller stop sequence will be invoked first followed by |
| + * CPU DAI driver stop sequence |
| + */ |
| + unsigned int stop_dma_first:1; |
| + |
| #ifdef CONFIG_SND_SOC_TOPOLOGY |
| struct snd_soc_dobj dobj; /* For topology */ |
| #endif |
| diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c |
| index 46513bb97904..d1c570ca21ea 100644 |
| --- a/sound/soc/soc-pcm.c |
| +++ b/sound/soc/soc-pcm.c |
| @@ -1015,6 +1015,7 @@ out: |
| |
| static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
| { |
| + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| int ret = -EINVAL, _ret = 0; |
| int rollback = 0; |
| |
| @@ -1055,14 +1056,23 @@ start_err: |
| case SNDRV_PCM_TRIGGER_STOP: |
| case SNDRV_PCM_TRIGGER_SUSPEND: |
| case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| - ret = snd_soc_pcm_dai_trigger(substream, cmd, rollback); |
| - if (ret < 0) |
| - break; |
| + if (rtd->dai_link->stop_dma_first) { |
| + ret = snd_soc_pcm_component_trigger(substream, cmd, rollback); |
| + if (ret < 0) |
| + break; |
| |
| - ret = snd_soc_pcm_component_trigger(substream, cmd, rollback); |
| - if (ret < 0) |
| - break; |
| + ret = snd_soc_pcm_dai_trigger(substream, cmd, rollback); |
| + if (ret < 0) |
| + break; |
| + } else { |
| + ret = snd_soc_pcm_dai_trigger(substream, cmd, rollback); |
| + if (ret < 0) |
| + break; |
| |
| + ret = snd_soc_pcm_component_trigger(substream, cmd, rollback); |
| + if (ret < 0) |
| + break; |
| + } |
| ret = snd_soc_link_trigger(substream, cmd, rollback); |
| break; |
| } |
| -- |
| 2.30.2 |
| |