Skip to content

Commit bafc0a2

Browse files
committed
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 d075847 commit bafc0a2

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
@@ -2096,10 +2096,57 @@ static void sof_ipc4_host_config(struct snd_sof_dev *sdev, struct snd_sof_widget
20962096
}
20972097

20982098
static int
2099-
sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
2100-
struct snd_pcm_hw_params *fe_params,
2101-
struct snd_sof_platform_stream_params *platform_params,
2102-
struct snd_pcm_hw_params *pipeline_params, int dir)
2099+
sof_ipc4_copier_module_update_params(struct snd_sof_widget *swidget,
2100+
struct snd_pcm_hw_params *pipeline_params)
2101+
{
2102+
struct snd_soc_component *scomp = swidget->scomp;
2103+
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2104+
struct sof_ipc4_copier_data *copier_data;
2105+
struct sof_ipc4_copier *ipc4_copier;
2106+
2107+
switch (swidget->id) {
2108+
case snd_soc_dapm_aif_in:
2109+
case snd_soc_dapm_aif_out:
2110+
case snd_soc_dapm_buffer:
2111+
ipc4_copier = swidget->private;
2112+
copier_data = &ipc4_copier->data;
2113+
break;
2114+
case snd_soc_dapm_dai_in:
2115+
case snd_soc_dapm_dai_out:
2116+
{
2117+
struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
2118+
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
2119+
struct snd_sof_dai *dai;
2120+
2121+
if (pipeline->use_chain_dma)
2122+
return 0;
2123+
2124+
dai = swidget->private;
2125+
2126+
ipc4_copier = (struct sof_ipc4_copier *)dai->private;
2127+
copier_data = &ipc4_copier->data;
2128+
2129+
break;
2130+
}
2131+
default:
2132+
dev_err(sdev->dev, "unsupported type %d for copier %s",
2133+
swidget->id, swidget->widget->name);
2134+
return -EINVAL;
2135+
}
2136+
2137+
/* modify the input params for the next widget */
2138+
return sof_ipc4_update_hw_params(sdev, pipeline_params,
2139+
&copier_data->out_format,
2140+
BIT(SNDRV_PCM_HW_PARAM_FORMAT) |
2141+
BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
2142+
BIT(SNDRV_PCM_HW_PARAM_RATE));
2143+
}
2144+
2145+
static int
2146+
_sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
2147+
struct snd_pcm_hw_params *fe_params,
2148+
struct snd_sof_platform_stream_params *platform_params,
2149+
struct snd_pcm_hw_params *pipeline_params, int dir)
21032150
{
21042151
struct sof_ipc4_available_audio_format *available_fmt;
21052152
struct snd_soc_component *scomp = swidget->scomp;
@@ -2571,6 +2618,21 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
25712618
return 0;
25722619
}
25732620

2621+
static int
2622+
sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
2623+
struct snd_pcm_hw_params *fe_params,
2624+
struct snd_sof_platform_stream_params *platform_params,
2625+
struct snd_pcm_hw_params *pipeline_params, int dir)
2626+
{
2627+
if (swidget->prepared)
2628+
return sof_ipc4_copier_module_update_params(swidget,
2629+
pipeline_params);
2630+
2631+
return _sof_ipc4_prepare_copier_module(swidget, fe_params,
2632+
platform_params, pipeline_params,
2633+
dir);
2634+
}
2635+
25742636
static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
25752637
struct snd_pcm_hw_params *fe_params,
25762638
struct snd_sof_platform_stream_params *platform_params,
@@ -2584,6 +2646,10 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
25842646
u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
25852647
int input_fmt_index, output_fmt_index;
25862648

2649+
/* This cannot happen */
2650+
if (unlikely(swidget->prepared))
2651+
return 0;
2652+
25872653
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
25882654
&gain->data.base_config,
25892655
pipeline_params,
@@ -2629,6 +2695,10 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
26292695
u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
26302696
int input_fmt_index, output_fmt_index;
26312697

2698+
/* Already prepared, nothing to do */
2699+
if (swidget->prepared)
2700+
return 0;
2701+
26322702
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
26332703
&mixer->base_config,
26342704
pipeline_params,
@@ -2675,6 +2745,10 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
26752745
u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
26762746
int output_fmt_index, input_fmt_index;
26772747

2748+
/* This cannot happen */
2749+
if (unlikely(swidget->prepared))
2750+
return 0;
2751+
26782752
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
26792753
&src->data.base_config,
26802754
pipeline_params,
@@ -2841,6 +2915,18 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
28412915
int ret;
28422916

28432917
if (available_fmt->num_input_formats) {
2918+
if (swidget->prepared) {
2919+
if (!available_fmt->num_output_formats)
2920+
return 0;
2921+
2922+
/* modify the pipeline params with the output format */
2923+
return sof_ipc4_update_hw_params(sdev, pipeline_params,
2924+
&process->output_format,
2925+
BIT(SNDRV_PCM_HW_PARAM_FORMAT) |
2926+
BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
2927+
BIT(SNDRV_PCM_HW_PARAM_RATE));
2928+
}
2929+
28442930
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
28452931
&process->base_config,
28462932
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)