mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
ASoC: SOF: ipc4-topology: Support for multiple src output formats
Peter Ujfalusi <peter.ujfalusi@linux.intel.com> says: SRC can only change the rate, we can still allow different bit depth and channels to be handled, the only restriction is that the input and output must have matching bit depth and channel format. In a separate patch do a sanity check for the number of formats on the input and output side as SRC/ASRC must have at least one of them. Link: https://patch.msgid.link/20260526105748.26149-1-peter.ujfalusi@linux.intel.com
This commit is contained in:
commit
2fd19f0d58
|
|
@ -1121,6 +1121,15 @@ static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (!src->available_fmt.num_input_formats ||
|
||||
!src->available_fmt.num_output_formats) {
|
||||
dev_err(scomp->dev,
|
||||
"Invalid number of formats: input: %d, output: %d\n",
|
||||
src->available_fmt.num_input_formats,
|
||||
src->available_fmt.num_output_formats);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples,
|
||||
swidget->num_tuples, sizeof(*src), 1);
|
||||
if (ret) {
|
||||
|
|
@ -1164,6 +1173,15 @@ static int sof_ipc4_widget_setup_comp_asrc(struct snd_sof_widget *swidget)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (!asrc->available_fmt.num_input_formats ||
|
||||
!asrc->available_fmt.num_output_formats) {
|
||||
dev_err(scomp->dev,
|
||||
"Invalid number of formats: input: %d, output: %d\n",
|
||||
asrc->available_fmt.num_input_formats,
|
||||
asrc->available_fmt.num_output_formats);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = sof_update_ipc_object(scomp, &asrc->data, SOF_ASRC_TOKENS, swidget->tuples,
|
||||
swidget->num_tuples, sizeof(*asrc), 1);
|
||||
if (ret) {
|
||||
|
|
@ -2631,16 +2649,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.
|
||||
|
|
@ -2650,12 +2658,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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user