diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 2903e784a5dd..7f5400612bf8 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1031,7 +1031,8 @@ static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw
 static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
 					  struct sof_ipc4_base_module_cfg *base_config,
 					  struct sof_ipc4_available_audio_format *available_fmt,
-					  int input_audio_format_index)
+					  u32 out_ref_rate, u32 out_ref_channels,
+					  u32 out_ref_valid_bits)
 {
 	struct sof_ipc4_audio_format *out_fmt;
 	u32 out_rate, out_channels, out_valid_bits;
@@ -1063,16 +1064,31 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
 	}
 
 	/* pick the first format if there's only one available or if all formats are the same */
-	if (single_format)
-		i = 0;
-	else
-		i = input_audio_format_index;
+	if (single_format) {
+		base_config->obs = available_fmt->output_pin_fmts[0].buffer_size;
+		return 0;
+	}
+
+	/*
+	 * if there are multiple output formats, then choose the output format that matches
+	 * the reference params
+	 */
+	for (i = 0; i < available_fmt->num_output_formats; i++) {
+		u32 _out_rate, _out_channels, _out_valid_bits;
 
-	if (available_fmt->num_output_formats && i < available_fmt->num_output_formats)
-		base_config->obs = available_fmt->output_pin_fmts[i].buffer_size;
+		out_fmt = &available_fmt->output_pin_fmts[i].audio_fmt;
+		_out_rate = out_fmt->sampling_frequency;
+		_out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg);
+		_out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg);
 
-	/* Return the index of the chosen output format */
-	return i;
+		if (_out_rate == out_ref_rate && _out_channels == out_ref_channels &&
+		    _out_valid_bits == out_ref_valid_bits) {
+			base_config->obs = available_fmt->output_pin_fmts[i].buffer_size;
+			return i;
+		}
+	}
+
+	return -EINVAL;
 }
 
 static int sof_ipc4_get_valid_bits(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params)
@@ -1404,6 +1420,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
 	int *ipc_config_size;
 	u32 **data;
 	int ipc_size, ret;
+	u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
 	u32 deep_buffer_dma_ms = 0;
 	u32 format_list_count;
 	int output_fmt_index;
@@ -1551,10 +1568,42 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
 	if (ret < 0)
 		return ret;
 
+	/* set the reference params for output format selection */
+	switch (swidget->id) {
+	case snd_soc_dapm_aif_in:
+	case snd_soc_dapm_dai_out:
+	case snd_soc_dapm_buffer:
+	{
+		struct sof_ipc4_audio_format *in_fmt;
+
+		in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt;
+		out_ref_rate = in_fmt->sampling_frequency;
+		out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
+		out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
+		break;
+	}
+	case snd_soc_dapm_aif_out:
+	case snd_soc_dapm_dai_in:
+		out_ref_valid_bits = sof_ipc4_get_valid_bits(sdev, fe_params);
+		if (out_ref_valid_bits < 0)
+			return out_ref_valid_bits;
+
+		out_ref_rate = params_rate(fe_params);
+		out_ref_channels = params_channels(fe_params);
+		break;
+	default:
+		/*
+		 * Unsupported type should be caught by the former switch default
+		 * case, this should never happen in reality.
+		 */
+		return -EINVAL;
+	}
+
 	output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &copier_data->base_config,
-							  available_fmt, ret);
+							  available_fmt, out_ref_rate,
+							  out_ref_channels, out_ref_valid_bits);
 	if (output_fmt_index < 0) {
-		dev_err(sdev->dev, "No output formats in topology for copier %s",
+		dev_err(sdev->dev, "Failed to initialize output format for %s",
 			swidget->widget->name);
 		return output_fmt_index;
 	}
@@ -1727,6 +1776,8 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
 	struct sof_ipc4_gain *gain = swidget->private;
 	struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt;
+	struct sof_ipc4_audio_format *in_fmt;
+	u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
 	int ret;
 
 	ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->base_config,
@@ -1736,9 +1787,16 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
 	if (ret < 0)
 		return ret;
 
-	ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->base_config, available_fmt, ret);
+	in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt;
+	out_ref_rate = in_fmt->sampling_frequency;
+	out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
+	out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
+
+	ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->base_config, available_fmt,
+					     out_ref_rate, out_ref_channels, out_ref_valid_bits);
 	if (ret < 0) {
-		dev_err(sdev->dev, "No output formats for %s", swidget->widget->name);
+		dev_err(sdev->dev, "Failed to initialize output format for %s",
+			swidget->widget->name);
 		return ret;
 	}
 
@@ -1757,6 +1815,8 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
 	struct sof_ipc4_mixer *mixer = swidget->private;
 	struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt;
+	struct sof_ipc4_audio_format *in_fmt;
+	u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
 	int ret;
 
 	ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &mixer->base_config,
@@ -1766,9 +1826,16 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
 	if (ret < 0)
 		return ret;
 
-	ret = sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt, ret);
+	in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt;
+	out_ref_rate = in_fmt->sampling_frequency;
+	out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
+	out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
+
+	ret = sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt,
+					     out_ref_rate, out_ref_channels, out_ref_valid_bits);
 	if (ret < 0) {
-		dev_err(sdev->dev, "No output formats for %s", swidget->widget->name);
+		dev_err(sdev->dev, "Failed to initialize output format for %s",
+			swidget->widget->name);
 		return ret;
 	}
 
@@ -1787,6 +1854,8 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
 	struct sof_ipc4_src *src = swidget->private;
 	struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt;
+	struct sof_ipc4_audio_format *in_fmt;
+	u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
 	struct snd_interval *rate;
 	int ret;
 
@@ -1797,10 +1866,16 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
 	if (ret < 0)
 		return ret;
 
-	ret = sof_ipc4_init_output_audio_fmt(sdev, &src->base_config, available_fmt, ret);
+	in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt;
+	out_ref_rate = in_fmt->sampling_frequency;
+	out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
+	out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
+
+	ret = sof_ipc4_init_output_audio_fmt(sdev, &src->base_config, available_fmt,
+					     out_ref_rate, out_ref_channels, out_ref_valid_bits);
 	if (ret < 0) {
-		dev_err(sdev->dev, "No output formats for %s", swidget->widget->name);
-		return ret;
+		dev_err(sdev->dev, "Failed to initialize output format for %s",
+			swidget->widget->name);
 	}
 
 	/* update pipeline memory usage */
@@ -1901,6 +1976,8 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
 	struct sof_ipc4_process *process = swidget->private;
 	struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt;
+	struct sof_ipc4_audio_format *in_fmt;
+	u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
 	void *cfg = process->ipc_config_data;
 	int output_fmt_index;
 	int ret;
@@ -1912,9 +1989,19 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
 	if (ret < 0)
 		return ret;
 
-	/* No need to check the return value. Some processing modules do not have output pins */
+	in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt;
+	out_ref_rate = in_fmt->sampling_frequency;
+	out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
+	out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
+
 	output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &process->base_config,
-							  available_fmt, ret);
+							  available_fmt, out_ref_rate,
+							  out_ref_channels, out_ref_valid_bits);
+	if (output_fmt_index < 0 && available_fmt->num_output_formats) {
+		dev_err(sdev->dev, "Failed to initialize output format for %s",
+			swidget->widget->name);
+		return output_fmt_index;
+	}
 
 	/* copy Pin 0 output format */
 	if (available_fmt->num_output_formats &&
