Skip to content

Commit 9f533aa

Browse files
committed
ASoC: SOF: ipc4-topology: Allow the use of multiple formats for src output
The SRC module can only change the rate, it keeps the format and channels intact, but this does not mean the the num_output_formats must be 0: The SRC module can support different formats/channels, we just need to check if the output format lists the correct combination of out rate and the input format/channels. Change the logic to prioritize the sink_rate of the module as target rate, then the rate of the FE in case of capture or in case of playback check the single rate specified in the output formats. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent a3a5425 commit 9f533aa

1 file changed

Lines changed: 30 additions & 17 deletions

File tree

sound/soc/sof/ipc4-topology.c

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,16 +2629,6 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
26292629
if (input_fmt_index < 0)
26302630
return input_fmt_index;
26312631

2632-
/*
2633-
* For playback, the SRC sink rate will be configured based on the requested output
2634-
* format, which is restricted to only deal with DAI's with a single format for now.
2635-
*/
2636-
if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) {
2637-
dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n",
2638-
available_fmt->num_output_formats, swidget->widget->name);
2639-
return -EINVAL;
2640-
}
2641-
26422632
/*
26432633
* SRC does not perform format conversion, so the output channels and valid bit depth must
26442634
* be the same as that of the input.
@@ -2648,12 +2638,36 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
26482638
out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg);
26492639
out_ref_type = sof_ipc4_fmt_cfg_to_type(in_audio_fmt->fmt_cfg);
26502640

2651-
/*
2652-
* For capture, the SRC module should convert the rate to match the rate requested by the
2653-
* PCM hw_params. Set the reference params based on the fe_params unconditionally as it
2654-
* will be ignored for playback anyway.
2655-
*/
2656-
out_ref_rate = params_rate(fe_params);
2641+
if (src->data.sink_rate) {
2642+
/* Use the sink rate as reference */
2643+
out_ref_rate = src->data.sink_rate;
2644+
} else if (dir == SNDRV_PCM_STREAM_CAPTURE) {
2645+
/*
2646+
* Use the fe rate as reference for capture if the sink rate is
2647+
* not set since we need to convert to the rate the PCM device
2648+
* is openned with
2649+
*/
2650+
out_ref_rate = params_rate(fe_params);
2651+
} else {
2652+
/*
2653+
* Otherwise try to guess what the rate should be:
2654+
* The output formats must have single rate specified if the
2655+
* sink rate is not set for an SRC in playback path.
2656+
*/
2657+
int i;
2658+
2659+
out_audio_fmt = &available_fmt->output_pin_fmts[0].audio_fmt;
2660+
out_ref_rate = out_audio_fmt->sampling_frequency;
2661+
for (i = 1; i < available_fmt->num_output_formats; i++) {
2662+
out_audio_fmt = &available_fmt->output_pin_fmts[i].audio_fmt;
2663+
if (out_ref_rate != out_audio_fmt->sampling_frequency) {
2664+
dev_err(sdev->dev,
2665+
"Cannot determine the output rate for SRC: %s\n",
2666+
swidget->widget->name);
2667+
return -EINVAL;
2668+
}
2669+
}
2670+
}
26572671

26582672
output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
26592673
&src->data.base_config,
@@ -2672,7 +2686,6 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
26722686
sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config);
26732687

26742688
out_audio_fmt = &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt;
2675-
src->data.sink_rate = out_audio_fmt->sampling_frequency;
26762689

26772690
/* update pipeline_params for sink widgets */
26782691
return sof_ipc4_update_hw_params(sdev, pipeline_params, out_audio_fmt,

0 commit comments

Comments
 (0)