From 76733db0f5560efa0c6514329620b9cbc8b1ca42 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 8 Oct 2024 14:09:29 +0300 Subject: [PATCH 1/8] ASoC: SOF: ipc4-topology: Drop the 'index' from 'Pin index' of format print Printing the word `index` does not give extra information over printing: `Pin #%d` which tells that the format line is for a specific pin. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20241008110936.22534-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 87be7f16e8c2..7967ec4c406a 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -195,7 +195,7 @@ static void sof_ipc4_dbg_audio_format(struct device *dev, struct sof_ipc4_pin_fo for (i = 0; i < num_formats; i++) { struct sof_ipc4_audio_format *fmt = &pin_fmt[i].audio_fmt; dev_dbg(dev, - "Pin index #%d: %uHz, %ubit, %luch (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x) buffer size %d\n", + "Pin #%d: %uHz, %ubit, %luch (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x) buffer size %d\n", pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth, SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg), fmt->ch_map, fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg, From 3b54c1cd69d04bbdafc5542d11c6cab685fc13bd Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 8 Oct 2024 14:09:30 +0300 Subject: [PATCH 2/8] ASoC: SOF: ipc4-topology: Use local variables in sof_ipc4_init_input_audio_fmt() We have local copies of available_fmt->input_pin_fmts and available_fmt->num_input_formats, use them in the function. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20241008110936.22534-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 7967ec4c406a..af5eea853745 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1278,13 +1278,12 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev, int sample_valid_bits; int i = 0; - if (!available_fmt->num_input_formats) { + if (!pin_fmts_size) { dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name); return -EINVAL; } - single_format = sof_ipc4_is_single_format(sdev, available_fmt->input_pin_fmts, - available_fmt->num_input_formats); + single_format = sof_ipc4_is_single_format(sdev, pin_fmts, pin_fmts_size); if (single_format) goto in_fmt; @@ -1321,15 +1320,15 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev, in_fmt: /* copy input format */ - if (available_fmt->num_input_formats && i < available_fmt->num_input_formats) { - memcpy(&base_config->audio_fmt, &available_fmt->input_pin_fmts[i].audio_fmt, + if (pin_fmts_size && i < pin_fmts_size) { + memcpy(&base_config->audio_fmt, &pin_fmts[i].audio_fmt, sizeof(struct sof_ipc4_audio_format)); /* set base_cfg ibs/obs */ - base_config->ibs = available_fmt->input_pin_fmts[i].buffer_size; + base_config->ibs = pin_fmts[i].buffer_size; dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); - sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1); + sof_ipc4_dbg_audio_format(sdev->dev, &pin_fmts[i], 1); } return i; From 2d9635b57b1bbbece2a8d30103fcd1ebfbbe0178 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 8 Oct 2024 14:09:31 +0300 Subject: [PATCH 3/8] ASoC: SOF: ipc4-topology: Remove redundant check in sof_ipc4_init_input_audio_fmt() At label in_fmt the if (pin_fmts_size && i < pin_fmts_size) is guarantied to be true all the time, drop the check completely. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20241008110936.22534-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index af5eea853745..1f10926921d5 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1320,16 +1320,14 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev, in_fmt: /* copy input format */ - if (pin_fmts_size && i < pin_fmts_size) { - memcpy(&base_config->audio_fmt, &pin_fmts[i].audio_fmt, - sizeof(struct sof_ipc4_audio_format)); + memcpy(&base_config->audio_fmt, &pin_fmts[i].audio_fmt, + sizeof(struct sof_ipc4_audio_format)); - /* set base_cfg ibs/obs */ - base_config->ibs = pin_fmts[i].buffer_size; + /* set base_cfg ibs/obs */ + base_config->ibs = pin_fmts[i].buffer_size; - dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); - sof_ipc4_dbg_audio_format(sdev->dev, &pin_fmts[i], 1); - } + dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); + sof_ipc4_dbg_audio_format(sdev->dev, &pin_fmts[i], 1); return i; } From 0126a659fd517103e8ce4d432fbe9b06f0a20510 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 8 Oct 2024 14:09:32 +0300 Subject: [PATCH 4/8] ASoC: SOF: ipc4-topology: Simplify match format print in sof_ipc4_init_input_audio_fmt() Print out the information line for the found input format once to avoid duplicated prints in case when multiple formats are available. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20241008110936.22534-5-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 1f10926921d5..31cbb7f620fd 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1305,11 +1305,8 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev, channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); if (params_rate(params) == rate && params_channels(params) == channels && - sample_valid_bits == valid_bits) { - dev_dbg(sdev->dev, "matched audio format index for %uHz, %ubit, %u channels: %d\n", - rate, valid_bits, channels, i); + sample_valid_bits == valid_bits) break; - } } if (i == pin_fmts_size) { @@ -1326,7 +1323,14 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev, /* set base_cfg ibs/obs */ base_config->ibs = pin_fmts[i].buffer_size; - dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); + if (single_format) + dev_dbg(sdev->dev, "Input audio format for %s:\n", + swidget->widget->name); + else + dev_dbg(sdev->dev, + "Input audio format (format index: %d) for %s:\n", i, + swidget->widget->name); + sof_ipc4_dbg_audio_format(sdev->dev, &pin_fmts[i], 1); return i; From 7a4c41e4778342b0ceda2e16127fefa808de3c57 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 8 Oct 2024 14:09:33 +0300 Subject: [PATCH 5/8] ASoC: SOF: ipc4-topology: Use local variables in sof_ipc4_init_output_audio_fmt() Use local variables for available_fmt->output_pin_fmts and available_fmt->num_output_formats similarly to the input format selection to make the two functions easier to understand and help with readability. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20241008110936.22534-6-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 31cbb7f620fd..45727c4d5b7e 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1210,19 +1210,19 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev, u32 out_ref_rate, u32 out_ref_channels, u32 out_ref_valid_bits) { - struct sof_ipc4_audio_format *out_fmt; + struct sof_ipc4_pin_format *pin_fmts = available_fmt->output_pin_fmts; + u32 pin_fmts_size = available_fmt->num_output_formats; bool single_format; int i; - if (!available_fmt->num_output_formats) + if (!pin_fmts_size) return -EINVAL; - single_format = sof_ipc4_is_single_format(sdev, available_fmt->output_pin_fmts, - available_fmt->num_output_formats); + single_format = sof_ipc4_is_single_format(sdev, pin_fmts, pin_fmts_size); /* pick the first format if there's only one available or if all formats are the same */ if (single_format) { - base_config->obs = available_fmt->output_pin_fmts[0].buffer_size; + base_config->obs = pin_fmts[0].buffer_size; return 0; } @@ -1230,17 +1230,18 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev, * 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++) { + for (i = 0; i < pin_fmts_size; i++) { + struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt; + u32 _out_rate, _out_channels, _out_valid_bits; - 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); + _out_rate = fmt->sampling_frequency; + _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); + _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 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; + base_config->obs = pin_fmts[i].buffer_size; return i; } } From fdaf2291524c6a220bb051ad1a8d3c99b177b6f1 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 8 Oct 2024 14:09:34 +0300 Subject: [PATCH 6/8] ASoC: SOF: ipc4-topology: Simplify code to deal with process modules without output Process modules are allowed to have zero outputs, thus zero output formats. In this case there is no need for complicated if expressions to handle such cases, we can just use a single if for the number of output formats and the rest can be simplified. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20241008110936.22534-7-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 68 +++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 45727c4d5b7e..c5f15e1bbacd 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -2357,10 +2357,7 @@ 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; ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &process->base_config, @@ -2368,36 +2365,47 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget, if (ret < 0) return 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); + /* Configure output audio format only if the module supports output */ + if (available_fmt->num_output_formats) { + u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, fmt_index; + struct sof_ipc4_audio_format *in_fmt; + struct sof_ipc4_pin_format *pin_fmt; - output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &process->base_config, - 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; - } + in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; - /* copy Pin 0 output format */ - if (available_fmt->num_output_formats && - output_fmt_index < available_fmt->num_output_formats && - !available_fmt->output_pin_fmts[output_fmt_index].pin_index) { - memcpy(&process->output_format, - &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, - sizeof(struct sof_ipc4_audio_format)); + 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); - /* modify the pipeline params with the pin 0 output format */ - ret = sof_ipc4_update_hw_params(sdev, pipeline_params, - &process->output_format, - BIT(SNDRV_PCM_HW_PARAM_FORMAT) | - BIT(SNDRV_PCM_HW_PARAM_CHANNELS) | - BIT(SNDRV_PCM_HW_PARAM_RATE)); - if (ret) - return ret; + fmt_index = sof_ipc4_init_output_audio_fmt(sdev, + &process->base_config, + available_fmt, + out_ref_rate, + out_ref_channels, + out_ref_valid_bits); + if (fmt_index < 0) { + dev_err(sdev->dev, + "Failed to initialize output format for %s", + swidget->widget->name); + return fmt_index; + } + + pin_fmt = &available_fmt->output_pin_fmts[fmt_index]; + + /* copy Pin output format for Pin 0 only */ + if (pin_fmt->pin_index == 0) { + memcpy(&process->output_format, &pin_fmt->audio_fmt, + sizeof(struct sof_ipc4_audio_format)); + + /* modify the pipeline params with the output format */ + ret = sof_ipc4_update_hw_params(sdev, pipeline_params, + &process->output_format, + BIT(SNDRV_PCM_HW_PARAM_FORMAT) | + BIT(SNDRV_PCM_HW_PARAM_CHANNELS) | + BIT(SNDRV_PCM_HW_PARAM_RATE)); + if (ret) + return ret; + } } /* update pipeline memory usage */ From 22408b8f625d85b5453fde8627aa6dd49f87c281 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 8 Oct 2024 14:09:35 +0300 Subject: [PATCH 7/8] ASoC: SOF: ipc4-topology: Concentrate prints inside of sof_ipc4_init_output_audio_fmt() Similarly to sof_ipc4_init_input_audio_fmt(), move all output format selection related prints (success or failure) inside of the sof_ipc4_init_output_audio_fmt() function. To do this, we need to pass swidget also, like with the input counterpart. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20241008110936.22534-8-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 87 ++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index c5f15e1bbacd..b00797f89595 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1205,6 +1205,7 @@ static bool sof_ipc4_is_single_format(struct snd_sof_dev *sdev, } static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev, + struct snd_sof_widget *swidget, struct sof_ipc4_base_module_cfg *base_config, struct sof_ipc4_available_audio_format *available_fmt, u32 out_ref_rate, u32 out_ref_channels, @@ -1213,18 +1214,19 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev, struct sof_ipc4_pin_format *pin_fmts = available_fmt->output_pin_fmts; u32 pin_fmts_size = available_fmt->num_output_formats; bool single_format; - int i; + int i = 0; - if (!pin_fmts_size) + if (!pin_fmts_size) { + dev_err(sdev->dev, "no output formats for %s\n", + swidget->widget->name); return -EINVAL; + } single_format = sof_ipc4_is_single_format(sdev, pin_fmts, pin_fmts_size); /* pick the first format if there's only one available or if all formats are the same */ - if (single_format) { - base_config->obs = pin_fmts[0].buffer_size; - return 0; - } + if (single_format) + goto out_fmt; /* * if there are multiple output formats, then choose the output format that matches @@ -1240,13 +1242,29 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev, _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); if (_out_rate == out_ref_rate && _out_channels == out_ref_channels && - _out_valid_bits == out_ref_valid_bits) { - base_config->obs = pin_fmts[i].buffer_size; - return i; - } + _out_valid_bits == out_ref_valid_bits) + goto out_fmt; } + dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", + __func__, out_ref_rate, out_ref_valid_bits, out_ref_channels); + return -EINVAL; + +out_fmt: + base_config->obs = pin_fmts[i].buffer_size; + + if (single_format) + dev_dbg(sdev->dev, "Output audio format for %s:\n", + swidget->widget->name); + else + dev_dbg(sdev->dev, + "Output audio format (format index: %d) for %s:\n", i, + swidget->widget->name); + + sof_ipc4_dbg_audio_format(sdev->dev, &pin_fmts[i], 1); + + return i; } static int sof_ipc4_get_valid_bits(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params) @@ -1906,17 +1924,12 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); } - dev_dbg(sdev->dev, "copier %s: reference output rate %d, channels %d valid_bits %d\n", - swidget->widget->name, out_ref_rate, out_ref_channels, out_ref_valid_bits); - - output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &copier_data->base_config, + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, + &copier_data->base_config, available_fmt, out_ref_rate, out_ref_channels, out_ref_valid_bits); - if (output_fmt_index < 0) { - dev_err(sdev->dev, "Failed to initialize output format for %s", - swidget->widget->name); + if (output_fmt_index < 0) return output_fmt_index; - } /* * Set the output format. Current topology defines pin 0 input and output formats in pairs. @@ -1928,8 +1941,6 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, memcpy(&copier_data->out_format, &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, sizeof(struct sof_ipc4_audio_format)); - dev_dbg(sdev->dev, "Output audio format for %s\n", swidget->widget->name); - sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->output_pin_fmts[output_fmt_index], 1); switch (swidget->id) { case snd_soc_dapm_dai_in: @@ -2153,13 +2164,11 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget, 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->data.base_config, available_fmt, - out_ref_rate, out_ref_channels, out_ref_valid_bits); - if (ret < 0) { - dev_err(sdev->dev, "Failed to initialize output format for %s", - swidget->widget->name); + ret = sof_ipc4_init_output_audio_fmt(sdev, swidget, &gain->data.base_config, + available_fmt, out_ref_rate, + out_ref_channels, out_ref_valid_bits); + if (ret < 0) return ret; - } /* update pipeline memory usage */ sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); @@ -2190,13 +2199,11 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget, 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, "Failed to initialize output format for %s", - swidget->widget->name); + ret = sof_ipc4_init_output_audio_fmt(sdev, swidget, &mixer->base_config, + available_fmt, out_ref_rate, + out_ref_channels, out_ref_valid_bits); + if (ret < 0) return ret; - } /* update pipeline memory usage */ sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); @@ -2248,14 +2255,12 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget, */ out_ref_rate = params_rate(fe_params); - output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->data.base_config, + output_format_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, + &src->data.base_config, available_fmt, out_ref_rate, out_ref_channels, out_ref_valid_bits); - if (output_format_index < 0) { - dev_err(sdev->dev, "Failed to initialize output format for %s", - swidget->widget->name); + if (output_format_index < 0) return output_format_index; - } /* update pipeline memory usage */ sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); @@ -2377,18 +2382,14 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget, 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); - fmt_index = sof_ipc4_init_output_audio_fmt(sdev, + fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, &process->base_config, available_fmt, out_ref_rate, out_ref_channels, out_ref_valid_bits); - if (fmt_index < 0) { - dev_err(sdev->dev, - "Failed to initialize output format for %s", - swidget->widget->name); + if (fmt_index < 0) return fmt_index; - } pin_fmt = &available_fmt->output_pin_fmts[fmt_index]; From 47701a85af0c0d655e06dd23f6b8761848147450 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 8 Oct 2024 14:09:36 +0300 Subject: [PATCH 8/8] ASoC: SOF: ipc4-topology: Add helper function to print the module's in/out audio format Introduce a helper function to print out the audio format(s) used by a module in a consistent way. The printed text depends on the module format configuration, taking into account if they have both input and output support, the format is changed by the module and the number of formats supported on input/output. For example, if a module does not change format, there is no point of printing both in and out format, it is adequate to just state the format the module is using. While the function to generate the print is fairly complex (but not too much), it will create a cleaner experience on the reader side by handling the filtering of the information and present it in a way that it - I hope - makes the developer's live a bit more easier when tracking format changes. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20241008110936.22534-9-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 262 ++++++++++++++++++++++++---------- 1 file changed, 186 insertions(+), 76 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index b00797f89595..56427d6e3679 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -203,6 +203,101 @@ static void sof_ipc4_dbg_audio_format(struct device *dev, struct sof_ipc4_pin_fo } } +static void +sof_ipc4_dbg_module_audio_format(struct device *dev, + struct snd_sof_widget *swidget, + struct sof_ipc4_available_audio_format *available_fmt, + int in_fmt_index, int out_fmt_index) +{ + struct sof_ipc4_audio_format *in_fmt, *out_fmt; + u32 out_rate, out_channels, out_valid_bits; + u32 in_rate, in_channels, in_valid_bits; + struct sof_ipc4_pin_format *pin_fmt; + + if (!available_fmt->num_input_formats && + !available_fmt->num_output_formats) + return; + + /* Only input or output is supported by the module */ + if (!available_fmt->num_input_formats) { + if (available_fmt->num_output_formats == 1) + dev_dbg(dev, "Output audio format for %s:\n", + swidget->widget->name); + else + dev_dbg(dev, + "Output audio format (format index: %d) for %s:\n", + out_fmt_index, swidget->widget->name); + + pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); + + return; + } else if (!available_fmt->num_output_formats) { + if (available_fmt->num_input_formats == 1) + dev_dbg(dev, "Input audio format for %s:\n", + swidget->widget->name); + else + dev_dbg(dev, + "Input audio format (format index: %d) for %s:\n", + out_fmt_index, swidget->widget->name); + + pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); + + return; + } + + in_fmt = &available_fmt->input_pin_fmts[in_fmt_index].audio_fmt; + out_fmt = &available_fmt->output_pin_fmts[out_fmt_index].audio_fmt; + + in_rate = in_fmt->sampling_frequency; + in_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); + in_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); + + 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); + + if (!(in_valid_bits != out_valid_bits || in_rate != out_rate || + in_channels != out_channels)) { + /* There is no change in format */ + if (available_fmt->num_input_formats == 1 && + available_fmt->num_output_formats == 1) + dev_dbg(dev, "Audio format for %s:\n", + swidget->widget->name); + else + dev_dbg(dev, + "Audio format (in/out format index: %d/%d) for %s:\n", + in_fmt_index, out_fmt_index, swidget->widget->name); + + pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); + + return; + } + + /* The format is changed by the module */ + if (available_fmt->num_input_formats == 1) + dev_dbg(dev, "Input audio format for %s:\n", + swidget->widget->name); + else + dev_dbg(dev, "Input audio format (format index: %d) for %s:\n", + in_fmt_index, swidget->widget->name); + + pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); + + if (available_fmt->num_output_formats == 1) + dev_dbg(dev, "Output audio format for %s:\n", + swidget->widget->name); + else + dev_dbg(dev, "Output audio format (format index: %d) for %s:\n", + out_fmt_index, swidget->widget->name); + + pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); +} + static const struct sof_ipc4_audio_format * sof_ipc4_get_input_pin_audio_fmt(struct snd_sof_widget *swidget, int pin_index) { @@ -1254,16 +1349,6 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev, out_fmt: base_config->obs = pin_fmts[i].buffer_size; - if (single_format) - dev_dbg(sdev->dev, "Output audio format for %s:\n", - swidget->widget->name); - else - dev_dbg(sdev->dev, - "Output audio format (format index: %d) for %s:\n", i, - swidget->widget->name); - - sof_ipc4_dbg_audio_format(sdev->dev, &pin_fmts[i], 1); - return i; } @@ -1342,16 +1427,6 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev, /* set base_cfg ibs/obs */ base_config->ibs = pin_fmts[i].buffer_size; - if (single_format) - dev_dbg(sdev->dev, "Input audio format for %s:\n", - swidget->widget->name); - else - dev_dbg(sdev->dev, - "Input audio format (format index: %d) for %s:\n", i, - swidget->widget->name); - - sof_ipc4_dbg_audio_format(sdev->dev, &pin_fmts[i], 1); - return i; } @@ -1726,6 +1801,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, struct snd_soc_component *scomp = swidget->scomp; struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct sof_ipc4_copier_data *copier_data; + int input_fmt_index, output_fmt_index; struct snd_pcm_hw_params ref_params; struct sof_ipc4_copier *ipc4_copier; struct snd_sof_dai *dai; @@ -1737,7 +1813,6 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, int ipc_size, ret, out_ref_valid_bits; u32 out_ref_rate, out_ref_channels; u32 deep_buffer_dma_ms = 0; - int output_fmt_index; bool single_output_bitdepth; int i; @@ -1869,10 +1944,11 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, } /* set input and output audio formats */ - ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &copier_data->base_config, - &ref_params, available_fmt); - if (ret < 0) - return ret; + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, + &copier_data->base_config, + &ref_params, available_fmt); + if (input_fmt_index < 0) + return input_fmt_index; /* set the reference params for output format selection */ single_output_bitdepth = sof_ipc4_copier_is_single_bitdepth(sdev, @@ -1885,7 +1961,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, { struct sof_ipc4_audio_format *in_fmt; - in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; + in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; out_ref_rate = in_fmt->sampling_frequency; out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); @@ -2117,6 +2193,9 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, *ipc_config_size = ipc_size; + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, + input_fmt_index, output_fmt_index); + /* update pipeline memory usage */ sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config); @@ -2152,23 +2231,31 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget, 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; + int input_fmt_index, output_fmt_index; - ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->data.base_config, - pipeline_params, available_fmt); - if (ret < 0) - return ret; + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, + &gain->data.base_config, + pipeline_params, + available_fmt); + if (input_fmt_index < 0) + return input_fmt_index; - in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; + in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].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, swidget, &gain->data.base_config, - available_fmt, out_ref_rate, - out_ref_channels, out_ref_valid_bits); - if (ret < 0) - return ret; + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, + &gain->data.base_config, + available_fmt, + out_ref_rate, + out_ref_channels, + out_ref_valid_bits); + if (output_fmt_index < 0) + return output_fmt_index; + + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, + input_fmt_index, output_fmt_index); /* update pipeline memory usage */ sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); @@ -2187,23 +2274,31 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget, 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; + int input_fmt_index, output_fmt_index; - ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &mixer->base_config, - pipeline_params, available_fmt); - if (ret < 0) - return ret; + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, + &mixer->base_config, + pipeline_params, + available_fmt); + if (input_fmt_index < 0) + return input_fmt_index; - in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; + in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].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, swidget, &mixer->base_config, - available_fmt, out_ref_rate, - out_ref_channels, out_ref_valid_bits); - if (ret < 0) - return ret; + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, + &mixer->base_config, + available_fmt, + out_ref_rate, + out_ref_channels, + out_ref_valid_bits); + if (output_fmt_index < 0) + return output_fmt_index; + + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, + input_fmt_index, output_fmt_index); /* update pipeline memory usage */ sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); @@ -2223,12 +2318,14 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget, struct sof_ipc4_audio_format *out_audio_fmt; struct sof_ipc4_audio_format *in_audio_fmt; u32 out_ref_rate, out_ref_channels, out_ref_valid_bits; - int output_format_index, input_format_index; + int output_fmt_index, input_fmt_index; - input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->data.base_config, - pipeline_params, available_fmt); - if (input_format_index < 0) - return input_format_index; + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, + &src->data.base_config, + pipeline_params, + available_fmt); + if (input_fmt_index < 0) + return input_fmt_index; /* * For playback, the SRC sink rate will be configured based on the requested output @@ -2244,7 +2341,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget, * SRC does not perform format conversion, so the output channels and valid bit depth must * be the same as that of the input. */ - in_audio_fmt = &available_fmt->input_pin_fmts[input_format_index].audio_fmt; + in_audio_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg); out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); @@ -2255,17 +2352,22 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget, */ out_ref_rate = params_rate(fe_params); - output_format_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, - &src->data.base_config, - available_fmt, out_ref_rate, - out_ref_channels, out_ref_valid_bits); - if (output_format_index < 0) - return output_format_index; + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, + &src->data.base_config, + available_fmt, + out_ref_rate, + out_ref_channels, + out_ref_valid_bits); + if (output_fmt_index < 0) + return output_fmt_index; + + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, + input_fmt_index, output_fmt_index); /* update pipeline memory usage */ sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); - out_audio_fmt = &available_fmt->output_pin_fmts[output_format_index].audio_fmt; + out_audio_fmt = &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt; src->data.sink_rate = out_audio_fmt->sampling_frequency; /* update pipeline_params for sink widgets */ @@ -2363,35 +2465,40 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget, struct sof_ipc4_process *process = swidget->private; struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; void *cfg = process->ipc_config_data; + int output_fmt_index = 0; + int input_fmt_index = 0; int ret; - ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &process->base_config, - pipeline_params, available_fmt); - if (ret < 0) - return ret; + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, + &process->base_config, + pipeline_params, + available_fmt); + if (input_fmt_index < 0) + return input_fmt_index; /* Configure output audio format only if the module supports output */ if (available_fmt->num_output_formats) { - u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, fmt_index; struct sof_ipc4_audio_format *in_fmt; struct sof_ipc4_pin_format *pin_fmt; + u32 out_ref_rate, out_ref_channels; + int out_ref_valid_bits; - in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; + in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].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); - fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, - &process->base_config, - available_fmt, - out_ref_rate, - out_ref_channels, - out_ref_valid_bits); - if (fmt_index < 0) - return fmt_index; + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, + &process->base_config, + available_fmt, + out_ref_rate, + out_ref_channels, + out_ref_valid_bits); + if (output_fmt_index < 0) + return output_fmt_index; - pin_fmt = &available_fmt->output_pin_fmts[fmt_index]; + pin_fmt = &available_fmt->output_pin_fmts[output_fmt_index]; /* copy Pin output format for Pin 0 only */ if (pin_fmt->pin_index == 0) { @@ -2409,6 +2516,9 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget, } } + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, + input_fmt_index, output_fmt_index); + /* update pipeline memory usage */ sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config);