summaryrefslogtreecommitdiff
path: root/sound/soc/sof
diff options
context:
space:
mode:
authorDaniel Baluta <daniel.baluta@nxp.com>2021-08-12 08:14:17 +0300
committerDong Aisheng <aisheng.dong@nxp.com>2021-11-02 16:28:48 +0800
commitd7f2835b39db83304731904aab72d8216ea70b3b (patch)
tree8f200869f41a850fa2c8cb66e4304b18deea4326 /sound/soc/sof
parentc920d74c5cad3f27212728466ac0abedf2317840 (diff)
LF-3880: ASoC: SOF: Fix compress stream cleanup path
Consecutive runs of cplay now fails because after first cplay the Firmware components states is not reset. We need to send SOF_IPC_STREAM_PCM_FREE command when a stream is closed in order to cleanup components states in Firmware. This will cause a pipeline reset and it will put the pipeline + components in a known state. Reviewed-by: Peng Zhang <peng.zhang_8@nxp.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/compress.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c
index a7de209f3de3..9392f2ae9e9f 100644
--- a/sound/soc/sof/compress.c
+++ b/sound/soc/sof/compress.c
@@ -117,19 +117,35 @@ int sof_compr_open(struct snd_soc_component *component,
int sof_compr_free(struct snd_soc_component *component,
struct snd_compr_stream *cstream)
{
+ struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_compr_runtime *runtime = cstream->runtime;
struct sof_compr_stream *sstream = runtime->private_data;
+ struct sof_ipc_stream stream;
+ struct sof_ipc_reply reply;
struct snd_sof_pcm *spcm;
+ int ret = 0;
spcm = snd_sof_find_spcm_dai(component, rtd);
if (!spcm)
return -EINVAL;
+ stream.hdr.size = sizeof(stream);
+ stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
+ stream.comp_id = spcm->stream[cstream->direction].comp_id;
+
+ if (spcm->prepared[cstream->direction]) {
+ ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd,
+ &stream, sizeof(stream),
+ &reply, sizeof(reply));
+ if (!ret)
+ spcm->prepared[cstream->direction] = false;
+ }
+
cancel_work_sync(&spcm->stream[cstream->direction].period_elapsed_work);
kfree(sstream);
- return 0;
+ return ret;
}
int sof_compr_set_params(struct snd_soc_component *component,