ASoC: SOF: Add trigger PCM op for IPC3
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Thu, 17 Mar 2022 17:50:40 +0000 (10:50 -0700)
committerMark Brown <broonie@kernel.org>
Fri, 18 Mar 2022 16:04:49 +0000 (16:04 +0000)
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>
sound/soc/sof/ipc3-pcm.c
sound/soc/sof/pcm.c

index b715199a2aaa1c80b1779b92b42177e41b12248b..d83d54540bbe4aed1a1819bfaebf1bfaeb99f720 100644 (file)
@@ -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,
 };
index 8a194c130981ba5cabc2c3ca7400523301ca5690..dc55a04a158891f479f11aa9cf740323aa515cc3 100644 (file)
@@ -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);