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>
This commit is contained in:
parent
621fd48c8c
commit
beac3f4cb6
@ -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,
|
||||
};
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user