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:
parent
36e980050b
commit
551af3280c
|
@ -37,6 +37,22 @@ struct sof_ipc4_timestamp_info {
|
||||||
snd_pcm_sframes_t delay;
|
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,
|
static int sof_ipc4_set_multi_pipeline_state(struct snd_sof_dev *sdev, u32 state,
|
||||||
struct ipc4_pipeline_set_state_data *trigger_list)
|
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
|
* Invalidate the stream_start_offset to make sure that it is
|
||||||
* going to be updated if the stream resumes
|
* 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)
|
if (time_info)
|
||||||
time_info->stream_start_offset = SOF_IPC4_INVALID_STREAM_POSITION;
|
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)
|
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 snd_sof_pcm_stream_pipeline_list *pipeline_list;
|
||||||
|
struct sof_ipc4_pcm_stream_priv *stream_priv;
|
||||||
int stream;
|
int stream;
|
||||||
|
|
||||||
for_each_pcm_streams(stream) {
|
for_each_pcm_streams(stream) {
|
||||||
pipeline_list = &spcm->stream[stream].pipeline_list;
|
pipeline_list = &spcm->stream[stream].pipeline_list;
|
||||||
kfree(pipeline_list->pipelines);
|
kfree(pipeline_list->pipelines);
|
||||||
pipeline_list->pipelines = NULL;
|
pipeline_list->pipelines = NULL;
|
||||||
|
|
||||||
|
stream_priv = spcm->stream[stream].private;
|
||||||
|
kfree(stream_priv->time_info);
|
||||||
kfree(spcm->stream[stream].private);
|
kfree(spcm->stream[stream].private);
|
||||||
spcm->stream[stream].private = NULL;
|
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 snd_sof_pcm_stream_pipeline_list *pipeline_list;
|
||||||
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
|
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
|
||||||
|
struct sof_ipc4_pcm_stream_priv *stream_priv;
|
||||||
struct sof_ipc4_timestamp_info *time_info;
|
struct sof_ipc4_timestamp_info *time_info;
|
||||||
bool support_info = true;
|
bool support_info = true;
|
||||||
u32 abi_version;
|
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;
|
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)
|
if (!support_info)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -758,7 +787,7 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
spcm->stream[stream].private = time_info;
|
stream_priv->time_info = time_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -795,7 +824,7 @@ static void sof_ipc4_build_time_info(struct snd_sof_dev *sdev, struct snd_sof_pc
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_info = sps->private;
|
time_info = sof_ipc4_sps_to_time_info(sps);
|
||||||
time_info->host_copier = host_copier;
|
time_info->host_copier = host_copier;
|
||||||
time_info->dai_copier = dai_copier;
|
time_info->dai_copier = dai_copier;
|
||||||
time_info->llp_offset = offsetof(struct sof_ipc4_fw_registers,
|
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)
|
if (!spcm)
|
||||||
return -EINVAL;
|
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 */
|
/* delay calculation is not supported by current fw_reg ABI */
|
||||||
if (!time_info)
|
if (!time_info)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -928,7 +957,7 @@ static int sof_ipc4_pcm_pointer(struct snd_soc_component *component,
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
sps = &spcm->stream[substream->stream];
|
sps = &spcm->stream[substream->stream];
|
||||||
time_info = sps->private;
|
time_info = sof_ipc4_sps_to_time_info(sps);
|
||||||
if (!time_info)
|
if (!time_info)
|
||||||
return -EOPNOTSUPP;
|
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 snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
||||||
struct sof_ipc4_timestamp_info *time_info;
|
struct sof_ipc4_timestamp_info *time_info;
|
||||||
struct snd_sof_pcm_stream *sps;
|
|
||||||
struct snd_sof_pcm *spcm;
|
struct snd_sof_pcm *spcm;
|
||||||
|
|
||||||
spcm = snd_sof_find_spcm_dai(component, rtd);
|
spcm = snd_sof_find_spcm_dai(component, rtd);
|
||||||
if (!spcm)
|
if (!spcm)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sps = &spcm->stream[substream->stream];
|
time_info = sof_ipc4_sps_to_time_info(&spcm->stream[substream->stream]);
|
||||||
time_info = sps->private;
|
|
||||||
/*
|
/*
|
||||||
* Report the stored delay value calculated in the pointer callback.
|
* Report the stored delay value calculated in the pointer callback.
|
||||||
* In the unlikely event that the calculation was skipped/aborted, the
|
* In the unlikely event that the calculation was skipped/aborted, the
|
||||||
|
|
Loading…
Reference in New Issue