@@ -166,6 +166,37 @@ static void sof_ipc4_dbg_audio_format(struct device *dev, struct sof_ipc4_pin_fo
}
}
+static const struct sof_ipc4_audio_format *
+sof_ipc4_get_input_pin_audio_fmt(struct snd_sof_widget *swidget, int pin_index)
+{
+ struct sof_ipc4_base_module_cfg_ext *base_cfg_ext;
+ struct sof_ipc4_process *process;
+ int i;
+
+ if (swidget->id != snd_soc_dapm_effect) {
+ struct sof_ipc4_base_module_cfg *base = swidget->private;
+
+ /* For non-process modules, base module config format is used for all input pins */
+ return &base->audio_fmt;
+ }
+
+ process = swidget->private;
+ base_cfg_ext = process->base_config_ext;
+
+ /*
+ * If there are multiple input formats available for a pin, the first available format
+ * is chosen.
+ */
+ for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) {
+ struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i];
+
+ if (pin_format->pin_index == pin_index)
+ return &pin_format->audio_fmt;
+ }
+
+ return NULL;
+}
+
/**
* sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
* @scomp: pointer to pointer to SOC component
@@ -2049,9 +2080,9 @@ static int sof_ipc4_set_copier_sink_format(struct snd_sof_dev *sdev,
struct snd_sof_widget *sink_widget,
int sink_id)
{
- struct sof_ipc4_base_module_cfg *sink_config = sink_widget->private;
- struct sof_ipc4_base_module_cfg *src_config;
struct sof_ipc4_copier_config_set_sink_format format;
+ struct sof_ipc4_base_module_cfg *src_config;
+ const struct sof_ipc4_audio_format *pin_fmt;
struct sof_ipc4_fw_module *fw_module;
struct sof_ipc4_msg msg = {{ 0 }};
u32 header, extension;
@@ -2071,7 +2102,16 @@ static int sof_ipc4_set_copier_sink_format(struct snd_sof_dev *sdev,
format.sink_id = sink_id;
memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt));
- memcpy(&format.sink_fmt, &sink_config->audio_fmt, sizeof(format.sink_fmt));
+
+ pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sink_id);
+ if (!pin_fmt) {
+ dev_err(sdev->dev, "Unable to get pin %d format for %s",
+ sink_id, sink_widget->widget->name);
+ return -EINVAL;
+ }
+
+ memcpy(&format.sink_fmt, pin_fmt, sizeof(format.sink_fmt));
+
msg.data_size = sizeof(format);
msg.data_ptr = &format;