From 9998f7c4275b2f5e3ca5ce0b8b8686ffd97e89fc Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 9 Aug 2022 13:27:40 +0300 Subject: [PATCH 1/3] ASoC: SOF: stream: Add new IPC stream structure Added new ipc stream structure that will be used by the FW in order to notify the host that the drain operation is done. For the moment, the structure contains only the reply header since that's the only information we care about but, by adding a new ipc stream structure, we can send more information from FW regarding the drain operation if need be. Signed-off-by: Laurentiu Mihalcea --- include/sound/sof/stream.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/sound/sof/stream.h b/include/sound/sof/stream.h index 9377113f13e49e..35a59fe2d5f43b 100644 --- a/include/sound/sof/stream.h +++ b/include/sound/sof/stream.h @@ -148,4 +148,8 @@ struct sof_ipc_stream_posn { int32_t xrun_size; /**< XRUN size in bytes */ } __packed; +struct sof_ipc_stream_drain { + struct sof_ipc_reply rhdr; +} __packed; + #endif From a4d7670ecadc68af7d8b9a9d6045adb991a77b6c Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 9 Aug 2022 15:00:00 +0300 Subject: [PATCH 2/3] ASoC: SOF: ipc3: Handle SOF_IPC_STREAM_TRIG_DRAIN IPC from FW Since we want to notify the host when the drain operation is done in the FW, this change will enable the FW to send an IPC message to the host in order to signal that the draining is done. Upon receiving the notification, the host signals to ALSA's compress-offload API that the draining is over so it can continue its workflow. As of now, the drain operation is only implemented for compress streams. Signed-off-by: Laurentiu Mihalcea --- sound/soc/sof/ipc3.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index b28af3a48b7075..46d4e5184b506d 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -898,6 +898,35 @@ static void ipc3_xrun(struct snd_sof_dev *sdev, u32 msg_id) #endif } +static void ipc3_drain(struct snd_sof_dev *sdev, u32 msg_id) +{ + struct snd_soc_component *scomp = sdev->component; + struct snd_sof_pcm *spcm; + struct snd_sof_pcm_stream *stream; + struct sof_ipc_stream_drain drain; + int direction; + + spcm = snd_sof_find_spcm_comp(scomp, msg_id, &direction); + if (!spcm) { + dev_err(sdev->dev, + "error: drain for unknown stream, msg_id %d\n", + msg_id); + return; + } + + stream = &spcm->stream[direction]; + snd_sof_ipc_msg_data(sdev, stream->substream, &drain, sizeof(drain)); + + /* since struct sof_ipc_stream drain only contains the reply + * header there's no need for additional checks. + * + * we're assuming that since we're receiving the drain-related + * reply then the drain operation finished successfully. + */ + if (spcm->pcm.compress) + snd_compr_drain_notify(stream->cstream); +} + /* stream notifications from firmware */ static void ipc3_stream_message(struct snd_sof_dev *sdev, void *msg_buf) { @@ -912,6 +941,9 @@ static void ipc3_stream_message(struct snd_sof_dev *sdev, void *msg_buf) case SOF_IPC_STREAM_TRIG_XRUN: ipc3_xrun(sdev, msg_id); break; + case SOF_IPC_STREAM_TRIG_DRAIN: + ipc3_drain(sdev, msg_id); + break; default: dev_err(sdev->dev, "unhandled stream message %#x\n", msg_id); From de20f58e4425d57a6cd32bda4638c8cfe771caeb Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 9 Aug 2022 13:35:02 +0300 Subject: [PATCH 3/3] ASoc: SoF: compress: Add support for TRIG_DRAIN The purpose of this change is to allow the compress API to send the TRIG_DRAIN IPC message to the FW so it can start the draining operation. Signed-off-by: Laurentiu Mihalcea --- sound/soc/sof/compress.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 67139e15f862a1..fe517cd306e39e 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -287,6 +287,9 @@ static int sof_compr_trigger(struct snd_soc_component *component, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE; break; + case SNDRV_PCM_TRIGGER_DRAIN: + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_DRAIN; + break; default: dev_err(component->dev, "error: unhandled trigger cmd %d\n", cmd); break;