mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
ASoC: SOF: pcm: Modify the signature of a couple of PCM IPC ops
In order to reuse the pipeline triggering logic for compressed support with IPC4, modify the signature of the trigger and hw_free PCM IPC ops so that they can be reused. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com> Link: https://patch.msgid.link/20261007084955.1256-15-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
e1135ddec7
commit
9de51be869
|
|
@ -14,23 +14,18 @@
|
|||
#include "sof-audio.h"
|
||||
|
||||
static int sof_ipc3_pcm_hw_free(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_sof_pcm *spcm, int dir)
|
||||
{
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
|
||||
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
||||
struct sof_ipc_stream stream;
|
||||
struct snd_sof_pcm *spcm;
|
||||
|
||||
spcm = snd_sof_find_spcm_dai(component, rtd);
|
||||
if (!spcm)
|
||||
return -EINVAL;
|
||||
|
||||
if (!spcm->prepared[substream->stream])
|
||||
if (!spcm->prepared[dir])
|
||||
return 0;
|
||||
|
||||
stream.hdr.size = sizeof(stream);
|
||||
stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
|
||||
stream.comp_id = spcm->stream[substream->stream].comp_id;
|
||||
stream.comp_id = spcm->stream[dir].comp_id;
|
||||
|
||||
/* send IPC to the DSP */
|
||||
return sof_ipc_tx_message_no_reply(sdev->ipc, &stream, sizeof(stream));
|
||||
|
|
@ -141,20 +136,15 @@ static int sof_ipc3_pcm_hw_params(struct snd_soc_component *component,
|
|||
}
|
||||
|
||||
static int sof_ipc3_pcm_trigger(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream, int cmd)
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_sof_pcm *spcm, int cmd, int dir)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
|
||||
struct sof_ipc_stream stream;
|
||||
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;
|
||||
stream.comp_id = spcm->stream[dir].comp_id;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
|
|
@ -172,7 +162,7 @@ static int sof_ipc3_pcm_trigger(struct snd_soc_component *component,
|
|||
stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP;
|
||||
break;
|
||||
default:
|
||||
spcm_err(spcm, substream->stream, "Unhandled trigger cmd %d\n", cmd);
|
||||
spcm_err(spcm, dir, "Unhandled trigger cmd %d\n", cmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -412,28 +412,23 @@ static int sof_ipc4_chain_dma_trigger(struct snd_sof_dev *sdev,
|
|||
}
|
||||
|
||||
static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream, int state, int cmd)
|
||||
struct snd_pcm_substream *substream, int state, int cmd,
|
||||
struct snd_sof_pcm *spcm, int dir)
|
||||
{
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
|
||||
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
||||
struct snd_sof_pcm_stream_pipeline_list *pipeline_list;
|
||||
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
|
||||
struct ipc4_pipeline_set_state_data *trigger_list;
|
||||
struct snd_sof_widget *pipe_widget;
|
||||
struct sof_ipc4_pipeline *pipeline;
|
||||
struct snd_sof_pipeline *spipe;
|
||||
struct snd_sof_pcm *spcm;
|
||||
u8 *pipe_priority;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
spcm = snd_sof_find_spcm_dai(component, rtd);
|
||||
if (!spcm)
|
||||
return -EINVAL;
|
||||
spcm_dbg(spcm, dir, "cmd: %d, state: %d\n", cmd, state);
|
||||
|
||||
spcm_dbg(spcm, substream->stream, "cmd: %d, state: %d\n", cmd, state);
|
||||
|
||||
pipeline_list = &spcm->stream[substream->stream].pipeline_list;
|
||||
pipeline_list = &spcm->stream[dir].pipeline_list;
|
||||
guard(mutex)(&ipc4_data->pipeline_state_mutex);
|
||||
|
||||
/* nothing to trigger if the list is empty */
|
||||
|
|
@ -451,9 +446,9 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
|
|||
if (pipeline->use_chain_dma) {
|
||||
struct sof_ipc4_timestamp_info *time_info;
|
||||
|
||||
time_info = sof_ipc4_sps_to_time_info(&spcm->stream[substream->stream]);
|
||||
time_info = sof_ipc4_sps_to_time_info(&spcm->stream[dir]);
|
||||
|
||||
ret = sof_ipc4_chain_dma_trigger(sdev, spcm, substream->stream,
|
||||
ret = sof_ipc4_chain_dma_trigger(sdev, spcm, dir,
|
||||
pipeline_list, state, cmd);
|
||||
if (ret || !time_info)
|
||||
return ret;
|
||||
|
|
@ -462,12 +457,16 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
|
|||
/*
|
||||
* Record the DAI position for delay reporting
|
||||
* To handle multiple pause/resume/xrun we need to add
|
||||
* the positions to simulate how the firmware behaves
|
||||
* the positions to simulate how the firmware behaves.
|
||||
* Chained DMA does not support compress streams. We should
|
||||
* never get here with compress.
|
||||
*/
|
||||
u64 pos = snd_sof_pcm_get_dai_frame_counter(sdev, component,
|
||||
substream);
|
||||
if (substream) {
|
||||
u64 pos = snd_sof_pcm_get_dai_frame_counter(sdev, component,
|
||||
substream);
|
||||
|
||||
time_info->stream_end_offset += pos;
|
||||
time_info->stream_end_offset += pos;
|
||||
}
|
||||
} else if (state == SOF_IPC4_PIPE_RESET) {
|
||||
/* Reset the end offset as the stream is stopped */
|
||||
time_info->stream_end_offset = 0;
|
||||
|
|
@ -526,7 +525,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
|
|||
*/
|
||||
ret = sof_ipc4_set_multi_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, trigger_list);
|
||||
if (ret < 0) {
|
||||
spcm_err(spcm, substream->stream, "failed to pause all pipelines\n");
|
||||
spcm_err(spcm, dir, "failed to pause all pipelines\n");
|
||||
/*
|
||||
* workaround: if the firmware is crashed or the IPC timed out
|
||||
* while setting the pipeline state we must ignore the error
|
||||
|
|
@ -557,7 +556,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
|
|||
* Invalidate the stream_start_offset to make sure that it is
|
||||
* going to be updated if the stream resumes
|
||||
*/
|
||||
time_info = sof_ipc4_sps_to_time_info(&spcm->stream[substream->stream]);
|
||||
time_info = sof_ipc4_sps_to_time_info(&spcm->stream[dir]);
|
||||
if (time_info)
|
||||
time_info->stream_start_offset = SOF_IPC4_INVALID_STREAM_POSITION;
|
||||
|
||||
|
|
@ -567,7 +566,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
|
|||
/* else set the RUNNING/RESET state in the DSP */
|
||||
ret = sof_ipc4_set_multi_pipeline_state(sdev, state, trigger_list);
|
||||
if (ret < 0) {
|
||||
spcm_err(spcm, substream->stream,
|
||||
spcm_err(spcm, dir,
|
||||
"failed to set final state %d for all pipelines\n",
|
||||
state);
|
||||
/*
|
||||
|
|
@ -598,7 +597,8 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
|
|||
}
|
||||
|
||||
static int sof_ipc4_pcm_trigger(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream, int cmd)
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_sof_pcm *spcm, int cmd, int dir)
|
||||
{
|
||||
int state;
|
||||
|
||||
|
|
@ -620,14 +620,15 @@ static int sof_ipc4_pcm_trigger(struct snd_soc_component *component,
|
|||
}
|
||||
|
||||
/* set the pipeline state */
|
||||
return sof_ipc4_trigger_pipelines(component, substream, state, cmd);
|
||||
return sof_ipc4_trigger_pipelines(component, substream, state, cmd, spcm, dir);
|
||||
}
|
||||
|
||||
static int sof_ipc4_pcm_hw_free(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_sof_pcm *spcm, int dir)
|
||||
{
|
||||
/* command is not relevant with RESET, so just pass 0 */
|
||||
return sof_ipc4_trigger_pipelines(component, substream, SOF_IPC4_PIPE_RESET, 0);
|
||||
return sof_ipc4_trigger_pipelines(component, substream, SOF_IPC4_PIPE_RESET, 0, spcm, dir);
|
||||
}
|
||||
|
||||
static int ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev,
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
|
|||
* between. At least ALSA OSS emulation depends on this.
|
||||
*/
|
||||
if (spcm->prepared[substream->stream] && pcm_ops && pcm_ops->hw_free) {
|
||||
ret = pcm_ops->hw_free(component, substream);
|
||||
ret = pcm_ops->hw_free(component, substream, spcm, substream->stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
@ -223,7 +223,8 @@ static int sof_pcm_stream_free(struct snd_sof_dev *sdev,
|
|||
|
||||
/* free PCM in the DSP */
|
||||
if (pcm_ops && pcm_ops->hw_free) {
|
||||
ret = pcm_ops->hw_free(sdev->component, substream);
|
||||
ret = pcm_ops->hw_free(sdev->component, substream, spcm,
|
||||
substream->stream);
|
||||
if (ret < 0) {
|
||||
spcm_err(spcm, substream->stream,
|
||||
"pcm_ops->hw_free failed %d\n", ret);
|
||||
|
|
@ -458,7 +459,7 @@ static int sof_pcm_trigger(struct snd_soc_component *component,
|
|||
snd_sof_pcm_platform_trigger(sdev, substream, cmd);
|
||||
|
||||
if (pcm_ops && pcm_ops->trigger)
|
||||
ret = pcm_ops->trigger(component, substream, cmd);
|
||||
ret = pcm_ops->trigger(component, substream, spcm, cmd, substream->stream);
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
|
|
|
|||
|
|
@ -125,9 +125,10 @@ struct sof_ipc_pcm_ops {
|
|||
int (*hw_params)(struct snd_soc_component *component, struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_sof_platform_stream_params *platform_params);
|
||||
int (*hw_free)(struct snd_soc_component *component, struct snd_pcm_substream *substream);
|
||||
int (*trigger)(struct snd_soc_component *component, struct snd_pcm_substream *substream,
|
||||
int cmd);
|
||||
int (*hw_free)(struct snd_soc_component *component, struct snd_pcm_substream *substream,
|
||||
struct snd_sof_pcm *spcm, int dir);
|
||||
int (*trigger)(struct snd_soc_component *component, struct snd_pcm_substream *substream,
|
||||
struct snd_sof_pcm *spcm, int cmd, int dir);
|
||||
int (*dai_link_fixup)(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params);
|
||||
int (*pcm_setup)(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm);
|
||||
void (*pcm_free)(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user