Skip to content

Commit 15c9b70

Browse files
ujfalusibardliao
authored andcommitted
ASoC: SOF: ipc4-topology: Update the pipeline_params of prepared modules
If the module in path has been already prepared on a branch type of topology, where the branching happens downstream: A1--> A2 ---> B1 --> B2 ... B-branch |-> C1 --> C2 ... C-branch In this case if B-branch is started then A1/A2 is prepared, but when C-branch starts we still need to refine the parameters up to C1 to arrive with a correct params to configure C1. This branching can happen with copiers process modules. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent b7338db commit 15c9b70

2 files changed

Lines changed: 92 additions & 7 deletions

File tree

sound/soc/sof/ipc4-topology.c

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,10 +2142,57 @@ static void sof_ipc4_host_config(struct snd_sof_dev *sdev, struct snd_sof_widget
21422142
}
21432143

21442144
static int
2145-
sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
2146-
struct snd_pcm_hw_params *fe_params,
2147-
struct snd_sof_platform_stream_params *platform_params,
2148-
struct snd_pcm_hw_params *pipeline_params, int dir)
2145+
sof_ipc4_copier_module_update_params(struct snd_sof_widget *swidget,
2146+
struct snd_pcm_hw_params *pipeline_params)
2147+
{
2148+
struct snd_soc_component *scomp = swidget->scomp;
2149+
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2150+
struct sof_ipc4_copier_data *copier_data;
2151+
struct sof_ipc4_copier *ipc4_copier;
2152+
2153+
switch (swidget->id) {
2154+
case snd_soc_dapm_aif_in:
2155+
case snd_soc_dapm_aif_out:
2156+
case snd_soc_dapm_buffer:
2157+
ipc4_copier = swidget->private;
2158+
copier_data = &ipc4_copier->data;
2159+
break;
2160+
case snd_soc_dapm_dai_in:
2161+
case snd_soc_dapm_dai_out:
2162+
{
2163+
struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
2164+
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
2165+
struct snd_sof_dai *dai;
2166+
2167+
if (pipeline->use_chain_dma)
2168+
return 0;
2169+
2170+
dai = swidget->private;
2171+
2172+
ipc4_copier = (struct sof_ipc4_copier *)dai->private;
2173+
copier_data = &ipc4_copier->data;
2174+
2175+
break;
2176+
}
2177+
default:
2178+
dev_err(sdev->dev, "unsupported type %d for copier %s",
2179+
swidget->id, swidget->widget->name);
2180+
return -EINVAL;
2181+
}
2182+
2183+
/* modify the input params for the next widget */
2184+
return sof_ipc4_update_hw_params(sdev, pipeline_params,
2185+
&copier_data->out_format,
2186+
BIT(SNDRV_PCM_HW_PARAM_FORMAT) |
2187+
BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
2188+
BIT(SNDRV_PCM_HW_PARAM_RATE));
2189+
}
2190+
2191+
static int
2192+
_sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
2193+
struct snd_pcm_hw_params *fe_params,
2194+
struct snd_sof_platform_stream_params *platform_params,
2195+
struct snd_pcm_hw_params *pipeline_params, int dir)
21492196
{
21502197
struct sof_ipc4_available_audio_format *available_fmt;
21512198
struct snd_soc_component *scomp = swidget->scomp;
@@ -2617,6 +2664,21 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
26172664
return 0;
26182665
}
26192666

2667+
static int
2668+
sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
2669+
struct snd_pcm_hw_params *fe_params,
2670+
struct snd_sof_platform_stream_params *platform_params,
2671+
struct snd_pcm_hw_params *pipeline_params, int dir)
2672+
{
2673+
if (swidget->prepared)
2674+
return sof_ipc4_copier_module_update_params(swidget,
2675+
pipeline_params);
2676+
2677+
return _sof_ipc4_prepare_copier_module(swidget, fe_params,
2678+
platform_params, pipeline_params,
2679+
dir);
2680+
}
2681+
26202682
static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
26212683
struct snd_pcm_hw_params *fe_params,
26222684
struct snd_sof_platform_stream_params *platform_params,
@@ -2630,6 +2692,10 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
26302692
u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
26312693
int input_fmt_index, output_fmt_index;
26322694

2695+
/* This cannot happen */
2696+
if (unlikely(swidget->prepared))
2697+
return 0;
2698+
26332699
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
26342700
&gain->data.base_config,
26352701
pipeline_params,
@@ -2675,6 +2741,10 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
26752741
u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
26762742
int input_fmt_index, output_fmt_index;
26772743

2744+
/* Already prepared, nothing to do */
2745+
if (swidget->prepared)
2746+
return 0;
2747+
26782748
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
26792749
&mixer->base_config,
26802750
pipeline_params,
@@ -2721,6 +2791,10 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
27212791
u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
27222792
int output_fmt_index, input_fmt_index;
27232793

2794+
/* This cannot happen */
2795+
if (unlikely(swidget->prepared))
2796+
return 0;
2797+
27242798
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
27252799
&src->data.base_config,
27262800
pipeline_params,
@@ -2887,6 +2961,18 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
28872961
int ret;
28882962

28892963
if (available_fmt->num_input_formats) {
2964+
if (swidget->prepared) {
2965+
if (!available_fmt->num_output_formats)
2966+
return 0;
2967+
2968+
/* modify the pipeline params with the output format */
2969+
return sof_ipc4_update_hw_params(sdev, pipeline_params,
2970+
&process->output_format,
2971+
BIT(SNDRV_PCM_HW_PARAM_FORMAT) |
2972+
BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
2973+
BIT(SNDRV_PCM_HW_PARAM_RATE));
2974+
}
2975+
28902976
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
28912977
&process->base_config,
28922978
pipeline_params,

sound/soc/sof/sof-audio.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,9 +502,8 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget
502502
!sof_widget_in_same_direction(swidget, dir))
503503
return 0;
504504

505-
/* skip widgets already prepared or aggregated DAI widgets*/
506-
if (!widget_ops[widget->id].ipc_prepare || swidget->prepared ||
507-
is_aggregated_dai(swidget))
505+
/* skip widgets aggregated DAI widgets */
506+
if (!widget_ops[widget->id].ipc_prepare || is_aggregated_dai(swidget))
508507
goto sink_prepare;
509508

510509
/* prepare the source widget */

0 commit comments

Comments
 (0)