diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index af93697c1ee35a..58fba63f1d85ac 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -2629,16 +2629,6 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget, if (input_fmt_index < 0) return input_fmt_index; - /* - * For playback, the SRC sink rate will be configured based on the requested output - * format, which is restricted to only deal with DAI's with a single format for now. - */ - if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) { - dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n", - available_fmt->num_output_formats, swidget->widget->name); - return -EINVAL; - } - /* * SRC does not perform format conversion, so the output channels and valid bit depth must * be the same as that of the input. @@ -2648,12 +2638,36 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget, out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); out_ref_type = sof_ipc4_fmt_cfg_to_type(in_audio_fmt->fmt_cfg); - /* - * For capture, the SRC module should convert the rate to match the rate requested by the - * PCM hw_params. Set the reference params based on the fe_params unconditionally as it - * will be ignored for playback anyway. - */ - out_ref_rate = params_rate(fe_params); + if (src->data.sink_rate) { + /* Use the sink rate as reference */ + out_ref_rate = src->data.sink_rate; + } else if (dir == SNDRV_PCM_STREAM_CAPTURE) { + /* + * Use the fe rate as reference for capture if the sink rate is + * not set since we need to convert to the rate the PCM device + * is openned with + */ + out_ref_rate = params_rate(fe_params); + } else { + /* + * Otherwise try to guess what the rate should be: + * The output formats must have single rate specified if the + * sink rate is not set for an SRC in playback path. + */ + int i; + + out_audio_fmt = &available_fmt->output_pin_fmts[0].audio_fmt; + out_ref_rate = out_audio_fmt->sampling_frequency; + for (i = 1; i < available_fmt->num_output_formats; i++) { + out_audio_fmt = &available_fmt->output_pin_fmts[i].audio_fmt; + if (out_ref_rate != out_audio_fmt->sampling_frequency) { + dev_err(sdev->dev, + "Cannot determine the output rate for SRC: %s\n", + swidget->widget->name); + return -EINVAL; + } + } + } output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, &src->data.base_config,