diff options
author | Ranjani Sridharan <ranjani.sridharan@linux.intel.com> | 2022-03-17 20:50:40 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2022-03-18 19:04:49 +0300 |
commit | beac3f4cb66fa05e902768ae75ea691c4a2c0911 (patch) | |
tree | ae19e8899a9fbd87e223e13a8e87c426edca3954 /sound/soc | |
parent | 621fd48c8cc8d77101a3ac69f7f058d3f8afdbcc (diff) | |
download | linux-beac3f4cb66fa05e902768ae75ea691c4a2c0911.tar.xz |
ASoC: SOF: Add trigger PCM op for IPC3
Add the trigger PCM op for IPC3 and use it.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20220317175044.1752400-16-ranjani.sridharan@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/sof/ipc3-pcm.c | 43 | ||||
-rw-r--r-- | sound/soc/sof/pcm.c | 23 |
2 files changed, 49 insertions, 17 deletions
diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c index b715199a2aaa..d83d54540bbe 100644 --- a/sound/soc/sof/ipc3-pcm.c +++ b/sound/soc/sof/ipc3-pcm.c @@ -137,7 +137,50 @@ static int sof_ipc3_pcm_hw_params(struct snd_soc_component *component, return ret; } +static int sof_ipc3_pcm_trigger(struct snd_soc_component *component, + struct snd_pcm_substream *substream, int cmd) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); + struct sof_ipc_stream stream; + struct sof_ipc_reply reply; + struct snd_sof_pcm *spcm; + + 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; + stream.comp_id = spcm->stream[substream->stream].comp_id; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_PAUSE; + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE; + break; + case SNDRV_PCM_TRIGGER_START: + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_START; + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + fallthrough; + case SNDRV_PCM_TRIGGER_STOP: + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; + break; + default: + dev_err(component->dev, "Unhandled trigger cmd %d\n", cmd); + return -EINVAL; + } + + /* send IPC to the DSP */ + return sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream, + sizeof(stream), &reply, sizeof(reply)); +} + const struct sof_ipc_pcm_ops ipc3_pcm_ops = { .hw_params = sof_ipc3_pcm_hw_params, .hw_free = sof_ipc3_pcm_hw_free, + .trigger = sof_ipc3_pcm_trigger, }; diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 8a194c130981..dc55a04a1588 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -274,13 +274,12 @@ static int sof_pcm_trigger(struct snd_soc_component *component, { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); + const struct sof_ipc_pcm_ops *pcm_ops = sdev->ipc->ops->pcm; struct snd_sof_pcm *spcm; - struct sof_ipc_stream stream; - struct sof_ipc_reply reply; bool reset_hw_params = false; bool free_widget_list = false; bool ipc_first = false; - int ret; + int ret = 0; /* nothing to do for BE */ if (rtd->dai_link->no_pcm) @@ -293,17 +292,11 @@ static int sof_pcm_trigger(struct snd_soc_component *component, dev_dbg(component->dev, "pcm: trigger stream %d dir %d cmd %d\n", spcm->pcm.pcm_id, substream->stream, cmd); - stream.hdr.size = sizeof(stream); - stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG; - stream.comp_id = spcm->stream[substream->stream].comp_id; - switch (cmd) { case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_PAUSE; ipc_first = true; break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE; break; case SNDRV_PCM_TRIGGER_START: if (spcm->stream[substream->stream].suspend_ignored) { @@ -315,7 +308,6 @@ static int sof_pcm_trigger(struct snd_soc_component *component, spcm->stream[substream->stream].suspend_ignored = false; return 0; } - stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_START; break; case SNDRV_PCM_TRIGGER_SUSPEND: if (sdev->system_suspend_target == SOF_SUSPEND_S0IX && @@ -332,13 +324,11 @@ static int sof_pcm_trigger(struct snd_soc_component *component, free_widget_list = true; fallthrough; case SNDRV_PCM_TRIGGER_STOP: - stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; ipc_first = true; reset_hw_params = true; break; default: - dev_err(component->dev, "error: unhandled trigger cmd %d\n", - cmd); + dev_err(component->dev, "Unhandled trigger cmd %d\n", cmd); return -EINVAL; } @@ -349,11 +339,10 @@ static int sof_pcm_trigger(struct snd_soc_component *component, if (!ipc_first) snd_sof_pcm_platform_trigger(sdev, substream, cmd); - /* send IPC to the DSP */ - ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream, - sizeof(stream), &reply, sizeof(reply)); + if (pcm_ops->trigger) + ret = pcm_ops->trigger(component, substream, cmd); - /* need to STOP DMA even if STOP IPC failed */ + /* need to STOP DMA even if trigger IPC failed */ if (ipc_first) snd_sof_pcm_platform_trigger(sdev, substream, cmd); |