Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: SOF: ipc4-topology: Use correct queue_id for requesting input pin format

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 <kai.vehmanen@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: stable@vger.kernel.org # v6.8+
Link: https://patch.msgid.link/20240624121519.91703-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Peter Ujfalusi and committed by
Mark Brown
fe836c78 4ae814da

+15 -13
+15 -13
sound/soc/sof/ipc4-topology.c
··· 2869 2869 static int sof_ipc4_set_copier_sink_format(struct snd_sof_dev *sdev, 2870 2870 struct snd_sof_widget *src_widget, 2871 2871 struct snd_sof_widget *sink_widget, 2872 - int sink_id) 2872 + struct snd_sof_route *sroute) 2873 2873 { 2874 2874 struct sof_ipc4_copier_config_set_sink_format format; 2875 2875 const struct sof_ipc_ops *iops = sdev->ipc->ops; ··· 2877 2877 const struct sof_ipc4_audio_format *pin_fmt; 2878 2878 struct sof_ipc4_fw_module *fw_module; 2879 2879 struct sof_ipc4_msg msg = {{ 0 }}; 2880 - 2881 - dev_dbg(sdev->dev, "%s set copier sink %d format\n", 2882 - src_widget->widget->name, sink_id); 2883 2880 2884 2881 if (WIDGET_IS_DAI(src_widget->id)) { 2885 2882 struct snd_sof_dai *dai = src_widget->private; ··· 2888 2891 2889 2892 fw_module = src_widget->module_info; 2890 2893 2891 - format.sink_id = sink_id; 2894 + format.sink_id = sroute->src_queue_id; 2892 2895 memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt)); 2893 2896 2894 - pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sink_id); 2897 + pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sroute->dst_queue_id); 2895 2898 if (!pin_fmt) { 2896 - dev_err(sdev->dev, "Unable to get pin %d format for %s", 2897 - sink_id, sink_widget->widget->name); 2899 + dev_err(sdev->dev, 2900 + "Failed to get input audio format of %s:%d for output of %s:%d\n", 2901 + sink_widget->widget->name, sroute->dst_queue_id, 2902 + src_widget->widget->name, sroute->src_queue_id); 2898 2903 return -EINVAL; 2899 2904 } 2900 2905 ··· 2954 2955 sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, 2955 2956 SOF_PIN_TYPE_OUTPUT); 2956 2957 if (sroute->src_queue_id < 0) { 2957 - dev_err(sdev->dev, "failed to get queue ID for source widget: %s\n", 2958 + dev_err(sdev->dev, 2959 + "failed to get src_queue_id ID from source widget %s\n", 2958 2960 src_widget->widget->name); 2959 2961 return sroute->src_queue_id; 2960 2962 } ··· 2963 2963 sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, 2964 2964 SOF_PIN_TYPE_INPUT); 2965 2965 if (sroute->dst_queue_id < 0) { 2966 - dev_err(sdev->dev, "failed to get queue ID for sink widget: %s\n", 2966 + dev_err(sdev->dev, 2967 + "failed to get dst_queue_id ID from sink widget %s\n", 2967 2968 sink_widget->widget->name); 2968 2969 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, 2969 2970 SOF_PIN_TYPE_OUTPUT); ··· 2973 2972 2974 2973 /* Pin 0 format is already set during copier module init */ 2975 2974 if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) { 2976 - ret = sof_ipc4_set_copier_sink_format(sdev, src_widget, sink_widget, 2977 - sroute->src_queue_id); 2975 + ret = sof_ipc4_set_copier_sink_format(sdev, src_widget, 2976 + sink_widget, sroute); 2978 2977 if (ret < 0) { 2979 - dev_err(sdev->dev, "failed to set sink format for %s source queue ID %d\n", 2978 + dev_err(sdev->dev, 2979 + "failed to set sink format for source %s:%d\n", 2980 2980 src_widget->widget->name, sroute->src_queue_id); 2981 2981 goto out; 2982 2982 }