Skip to content

Commit

Permalink
ASoC: SOF: ipc4-topology: Use correct queue_id for requesting input p…
Browse files Browse the repository at this point in the history
…in format

commit fe836c7 upstream.

It is incorrect to request the input pin format of the destination widget
using the output pin index of the source module as the indexes are not
necessarily matching.
moduleA.out_pin1 can be connected to moduleB.in_pin0 for example.

Use the dst_queue_id to request the input format of the destination module.

This bug remained unnoticed likely because in nocodec topologies we don't
have process modules after a module copier, thus the pin/queue index is
ignored.
For the process module case, the code was likely have been tested in a
controlled way where all the pin/queue/format properties were present to
work.

Update the debug prints to have better information.

Reviewed-by: Kai Vehmanen <[email protected]>
Reviewed-by: Ranjani Sridharan <[email protected]>
Reviewed-by: Bard Liao <[email protected]>
Signed-off-by: Peter Ujfalusi <[email protected]>
Signed-off-by: Pierre-Louis Bossart <[email protected]>
Cc: [email protected] # v6.8+
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
ujfalusi authored and gregkh committed Jul 31, 2024
1 parent 4f5f1bf commit 21bd5c7
Showing 1 changed file with 15 additions and 13 deletions.
28 changes: 15 additions & 13 deletions sound/soc/sof/ipc4-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -2875,7 +2875,7 @@ static void sof_ipc4_put_queue_id(struct snd_sof_widget *swidget, int queue_id,
static int sof_ipc4_set_copier_sink_format(struct snd_sof_dev *sdev,
struct snd_sof_widget *src_widget,
struct snd_sof_widget *sink_widget,
int sink_id)
struct snd_sof_route *sroute)
{
struct sof_ipc4_copier_config_set_sink_format format;
const struct sof_ipc_ops *iops = sdev->ipc->ops;
Expand All @@ -2884,9 +2884,6 @@ static int sof_ipc4_set_copier_sink_format(struct snd_sof_dev *sdev,
struct sof_ipc4_fw_module *fw_module;
struct sof_ipc4_msg msg = {{ 0 }};

dev_dbg(sdev->dev, "%s set copier sink %d format\n",
src_widget->widget->name, sink_id);

if (WIDGET_IS_DAI(src_widget->id)) {
struct snd_sof_dai *dai = src_widget->private;

Expand All @@ -2897,13 +2894,15 @@ static int sof_ipc4_set_copier_sink_format(struct snd_sof_dev *sdev,

fw_module = src_widget->module_info;

format.sink_id = sink_id;
format.sink_id = sroute->src_queue_id;
memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt));

pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sink_id);
pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sroute->dst_queue_id);
if (!pin_fmt) {
dev_err(sdev->dev, "Unable to get pin %d format for %s",
sink_id, sink_widget->widget->name);
dev_err(sdev->dev,
"Failed to get input audio format of %s:%d for output of %s:%d\n",
sink_widget->widget->name, sroute->dst_queue_id,
src_widget->widget->name, sroute->src_queue_id);
return -EINVAL;
}

Expand Down Expand Up @@ -2961,15 +2960,17 @@ static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *
sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
SOF_PIN_TYPE_OUTPUT);
if (sroute->src_queue_id < 0) {
dev_err(sdev->dev, "failed to get queue ID for source widget: %s\n",
dev_err(sdev->dev,
"failed to get src_queue_id ID from source widget %s\n",
src_widget->widget->name);
return sroute->src_queue_id;
}

sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
SOF_PIN_TYPE_INPUT);
if (sroute->dst_queue_id < 0) {
dev_err(sdev->dev, "failed to get queue ID for sink widget: %s\n",
dev_err(sdev->dev,
"failed to get dst_queue_id ID from sink widget %s\n",
sink_widget->widget->name);
sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id,
SOF_PIN_TYPE_OUTPUT);
Expand All @@ -2978,10 +2979,11 @@ static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *

/* Pin 0 format is already set during copier module init */
if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) {
ret = sof_ipc4_set_copier_sink_format(sdev, src_widget, sink_widget,
sroute->src_queue_id);
ret = sof_ipc4_set_copier_sink_format(sdev, src_widget,
sink_widget, sroute);
if (ret < 0) {
dev_err(sdev->dev, "failed to set sink format for %s source queue ID %d\n",
dev_err(sdev->dev,
"failed to set sink format for source %s:%d\n",
src_widget->widget->name, sroute->src_queue_id);
goto out;
}
Expand Down

0 comments on commit 21bd5c7

Please sign in to comment.