ASoC: SOF: ipc4-pcm: Introduce generic sof_ipc4_pcm_stream_priv

Using the sof_ipc4_timestamp_info struct directly as sps->private data
is too restrictive, add a new generic sof_ipc4_pcm_stream_priv struct
containing the time_info to allow new information to be stored in a
generic way.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://msgid.link/r/20240409110036.9411-4-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Peter Ujfalusi 2024-04-09 14:00:35 +03:00 committed by Mark Brown
parent 36e980050b
commit 551af3280c
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
1 changed files with 35 additions and 8 deletions

View File

@ -37,6 +37,22 @@ struct sof_ipc4_timestamp_info {
snd_pcm_sframes_t delay;
};
/**
* struct sof_ipc4_pcm_stream_priv - IPC4 specific private data
* @time_info: pointer to time info struct if it is supported, otherwise NULL
*/
struct sof_ipc4_pcm_stream_priv {
struct sof_ipc4_timestamp_info *time_info;
};
static inline struct sof_ipc4_timestamp_info *
sof_ipc4_sps_to_time_info(struct snd_sof_pcm_stream *sps)
{
struct sof_ipc4_pcm_stream_priv *stream_priv = sps->private;
return stream_priv->time_info;
}
static int sof_ipc4_set_multi_pipeline_state(struct snd_sof_dev *sdev, u32 state,
struct ipc4_pipeline_set_state_data *trigger_list)
{
@ -452,7 +468,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 = spcm->stream[substream->stream].private;
time_info = sof_ipc4_sps_to_time_info(&spcm->stream[substream->stream]);
if (time_info)
time_info->stream_start_offset = SOF_IPC4_INVALID_STREAM_POSITION;
@ -706,12 +722,16 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
static void sof_ipc4_pcm_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm)
{
struct snd_sof_pcm_stream_pipeline_list *pipeline_list;
struct sof_ipc4_pcm_stream_priv *stream_priv;
int stream;
for_each_pcm_streams(stream) {
pipeline_list = &spcm->stream[stream].pipeline_list;
kfree(pipeline_list->pipelines);
pipeline_list->pipelines = NULL;
stream_priv = spcm->stream[stream].private;
kfree(stream_priv->time_info);
kfree(spcm->stream[stream].private);
spcm->stream[stream].private = NULL;
}
@ -721,6 +741,7 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm
{
struct snd_sof_pcm_stream_pipeline_list *pipeline_list;
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
struct sof_ipc4_pcm_stream_priv *stream_priv;
struct sof_ipc4_timestamp_info *time_info;
bool support_info = true;
u32 abi_version;
@ -749,6 +770,14 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm
return -ENOMEM;
}
stream_priv = kzalloc(sizeof(*stream_priv), GFP_KERNEL);
if (!stream_priv) {
sof_ipc4_pcm_free(sdev, spcm);
return -ENOMEM;
}
spcm->stream[stream].private = stream_priv;
if (!support_info)
continue;
@ -758,7 +787,7 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm
return -ENOMEM;
}
spcm->stream[stream].private = time_info;
stream_priv->time_info = time_info;
}
return 0;
@ -795,7 +824,7 @@ static void sof_ipc4_build_time_info(struct snd_sof_dev *sdev, struct snd_sof_pc
return;
}
time_info = sps->private;
time_info = sof_ipc4_sps_to_time_info(sps);
time_info->host_copier = host_copier;
time_info->dai_copier = dai_copier;
time_info->llp_offset = offsetof(struct sof_ipc4_fw_registers,
@ -849,7 +878,7 @@ static int sof_ipc4_pcm_hw_params(struct snd_soc_component *component,
if (!spcm)
return -EINVAL;
time_info = spcm->stream[substream->stream].private;
time_info = sof_ipc4_sps_to_time_info(&spcm->stream[substream->stream]);
/* delay calculation is not supported by current fw_reg ABI */
if (!time_info)
return 0;
@ -928,7 +957,7 @@ static int sof_ipc4_pcm_pointer(struct snd_soc_component *component,
return -EOPNOTSUPP;
sps = &spcm->stream[substream->stream];
time_info = sps->private;
time_info = sof_ipc4_sps_to_time_info(sps);
if (!time_info)
return -EOPNOTSUPP;
@ -1030,15 +1059,13 @@ static snd_pcm_sframes_t sof_ipc4_pcm_delay(struct snd_soc_component *component,
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sof_ipc4_timestamp_info *time_info;
struct snd_sof_pcm_stream *sps;
struct snd_sof_pcm *spcm;
spcm = snd_sof_find_spcm_dai(component, rtd);
if (!spcm)
return 0;
sps = &spcm->stream[substream->stream];
time_info = sps->private;
time_info = sof_ipc4_sps_to_time_info(&spcm->stream[substream->stream]);
/*
* Report the stored delay value calculated in the pointer callback.
* In the unlikely event that the calculation was skipped/aborted, the