* [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic
@ 2023-05-15 10:33 Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 1/9] ASoC: SOF: ipc4-topology: Handle input/output audio format special case Peter Ujfalusi
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
Hi,
Improve the logic to account for the current restrictions in topology while
making it extensible for future topology modifications.
The current topology definitions assume that input/output formats come in pairs.
For example even if there's only 1 output format for a module, we add 3 output
formats to match that of the input format count with the same parameters.
This is unnecessary but we have to deal with it until the topologies are
modified.
Additionally, choosing the input/output audio format should depend only on the
pipeline params or the runtime FE hw_params depending on where the module is in
the pipeline.
This PR modifies the logic for selection based on this and removes unnecessary
dependencies between the input and output formats.
Regards,
Peter
---
Ranjani Sridharan (9):
ASoC: SOF: ipc4-topology: Handle input/output audio format special
case
ASoC: SOF: ipc4-topology: Add a helper function for output format
selection
ASoC: SOF: ipc4-topology: Move the call to init output format
ASoC: SOF: ipc4-topology: Rename sof_ipc4_init_audio_fmt()
ASoC: SOF: ipc4-topology: Handle output format special case
ASoC: SOF: ipc4-topology: Add a new helper function to get the valid
bits
ASoC: SOF: ipc4-topology: Modify the output format selection logic
ASoC: SOF: ipc4-topology: New helper to check if all output formats
are the same
ASoC: SOF: ipc4-topology: Modify input audio format selection logic
sound/soc/sof/ipc4-topology.c | 358 ++++++++++++++++++++++------------
1 file changed, 237 insertions(+), 121 deletions(-)
--
2.40.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/9] ASoC: SOF: ipc4-topology: Handle input/output audio format special case
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
@ 2023-05-15 10:33 ` Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 2/9] ASoC: SOF: ipc4-topology: Add a helper function for output format selection Peter Ujfalusi
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
When there is only one input/output format specified in topology, there
is no need to search for a matching format, simply pick the available
one. This is in preparation to modify and split the selection logic for
the input and output audio formats.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
sound/soc/sof/ipc4-topology.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 059eebf0a687..3e59551b2367 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1039,7 +1039,7 @@ static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
u32 channels;
u32 rate;
int sample_valid_bits;
- int i;
+ int i = 0;
if (!pin_fmts) {
dev_err(sdev->dev, "no reference formats for %s\n", swidget->widget->name);
@@ -1066,6 +1066,10 @@ static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
return -EINVAL;
}
+ /* pick the only available input format */
+ if (available_fmt->num_input_formats == 1)
+ goto in_fmt;
+
/*
* Search supported audio formats with pin index 0 to match rate, channels ,and
* sample_valid_bytes from runtime params
@@ -1093,6 +1097,7 @@ static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
return -EINVAL;
}
+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,
@@ -1105,6 +1110,10 @@ static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1);
}
+ /* pick the only available output format */
+ if (available_fmt->num_output_formats == 1)
+ i = 0;
+
if (available_fmt->num_output_formats && i < available_fmt->num_output_formats)
base_config->obs = available_fmt->output_pin_fmts[i].buffer_size;
--
2.40.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/9] ASoC: SOF: ipc4-topology: Add a helper function for output format selection
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 1/9] ASoC: SOF: ipc4-topology: Handle input/output audio format special case Peter Ujfalusi
@ 2023-05-15 10:33 ` Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 3/9] ASoC: SOF: ipc4-topology: Move the call to init output format Peter Ujfalusi
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Add a helper function to select the output format.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
sound/soc/sof/ipc4-topology.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 3e59551b2367..7c448342ff92 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1028,6 +1028,26 @@ static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw
return 0;
}
+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)
+{
+ int i;
+
+ /* pick the only available output format */
+ if (available_fmt->num_output_formats == 1)
+ i = 0;
+ else
+ i = input_audio_format_index;
+
+ if (available_fmt->num_output_formats && i < available_fmt->num_output_formats)
+ base_config->obs = available_fmt->output_pin_fmts[i].buffer_size;
+
+ /* Return the index of the chosen output format */
+ return i;
+}
+
static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
struct snd_sof_widget *swidget,
struct sof_ipc4_base_module_cfg *base_config,
@@ -1110,15 +1130,7 @@ static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1);
}
- /* pick the only available output format */
- if (available_fmt->num_output_formats == 1)
- i = 0;
-
- if (available_fmt->num_output_formats && i < available_fmt->num_output_formats)
- base_config->obs = available_fmt->output_pin_fmts[i].buffer_size;
-
- /* Return the index of the matched format */
- return i;
+ return sof_ipc4_init_output_audio_fmt(sdev, base_config, available_fmt, i);
}
static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
--
2.40.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/9] ASoC: SOF: ipc4-topology: Move the call to init output format
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 1/9] ASoC: SOF: ipc4-topology: Handle input/output audio format special case Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 2/9] ASoC: SOF: ipc4-topology: Add a helper function for output format selection Peter Ujfalusi
@ 2023-05-15 10:33 ` Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 4/9] ASoC: SOF: ipc4-topology: Rename sof_ipc4_init_audio_fmt() Peter Ujfalusi
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
In preparation for changing the logic for input/output format selection,
move the call to sof_ipc4_init_output_audio_fmt() into the individual
widget prepare ops.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
sound/soc/sof/ipc4-topology.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 7c448342ff92..87ab415b27da 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1130,7 +1130,7 @@ static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1);
}
- return sof_ipc4_init_output_audio_fmt(sdev, base_config, available_fmt, i);
+ return i;
}
static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
@@ -1375,6 +1375,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
int ipc_size, ret;
u32 deep_buffer_dma_ms = 0;
u32 format_list_count;
+ int output_fmt_index;
dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id);
@@ -1518,6 +1519,9 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
if (ret < 0)
return ret;
+ output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &copier_data->base_config,
+ available_fmt, ret);
+
/*
* Set the output format. Current topology defines pin 0 input and output formats in pairs.
* This assumes that the pin 0 formats are defined before all other pins.
@@ -1525,10 +1529,11 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
* input format. This logic will need to be updated when the format definitions
* in topology change.
*/
- memcpy(&copier_data->out_format, &available_fmt->output_pin_fmts[ret].audio_fmt,
+ 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[ret], 1);
+ 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:
@@ -1694,6 +1699,8 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
if (ret < 0)
return ret;
+ sof_ipc4_init_output_audio_fmt(sdev, &gain->base_config, available_fmt, ret);
+
/* update pipeline memory usage */
sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &gain->base_config);
@@ -1718,6 +1725,8 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
if (ret < 0)
return ret;
+ sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt, ret);
+
/* update pipeline memory usage */
sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &mixer->base_config);
@@ -1743,6 +1752,8 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
if (ret < 0)
return ret;
+ sof_ipc4_init_output_audio_fmt(sdev, &src->base_config, available_fmt, ret);
+
/* update pipeline memory usage */
sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &src->base_config);
@@ -1842,6 +1853,7 @@ 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;
int ret;
ret = sof_ipc4_init_audio_fmt(sdev, swidget, &process->base_config,
@@ -1851,10 +1863,15 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
if (ret < 0)
return ret;
+ output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &process->base_config,
+ available_fmt, ret);
+
/* copy Pin 0 output format */
- if (available_fmt->num_output_formats && ret < available_fmt->num_output_formats &&
- !available_fmt->output_pin_fmts[ret].pin_index) {
- memcpy(&process->output_format, &available_fmt->output_pin_fmts[ret].audio_fmt,
+ 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));
/* modify the pipeline params with the pin 0 output format */
--
2.40.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/9] ASoC: SOF: ipc4-topology: Rename sof_ipc4_init_audio_fmt()
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
` (2 preceding siblings ...)
2023-05-15 10:33 ` [PATCH 3/9] ASoC: SOF: ipc4-topology: Move the call to init output format Peter Ujfalusi
@ 2023-05-15 10:33 ` Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 5/9] ASoC: SOF: ipc4-topology: Handle output format special case Peter Ujfalusi
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Rename it to sof_ipc4_init_input_audio_fmt() as it only does input
format selection now.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
sound/soc/sof/ipc4-topology.c | 51 ++++++++++++++++++-----------------
1 file changed, 26 insertions(+), 25 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 87ab415b27da..a079dd8eb7e1 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1048,12 +1048,12 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
return i;
}
-static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
- struct snd_sof_widget *swidget,
- struct sof_ipc4_base_module_cfg *base_config,
- struct snd_pcm_hw_params *params,
- struct sof_ipc4_available_audio_format *available_fmt,
- struct sof_ipc4_pin_format *pin_fmts, u32 pin_fmts_size)
+static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
+ struct snd_sof_widget *swidget,
+ struct sof_ipc4_base_module_cfg *base_config,
+ struct snd_pcm_hw_params *params,
+ struct sof_ipc4_available_audio_format *available_fmt,
+ struct sof_ipc4_pin_format *pin_fmts, u32 pin_fmts_size)
{
u32 valid_bits;
u32 channels;
@@ -1514,8 +1514,9 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
}
/* set input and output audio formats */
- ret = sof_ipc4_init_audio_fmt(sdev, swidget, &copier_data->base_config, ref_params,
- available_fmt, format_list_to_search, format_list_count);
+ ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &copier_data->base_config, ref_params,
+ available_fmt, format_list_to_search,
+ format_list_count);
if (ret < 0)
return ret;
@@ -1541,7 +1542,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
{
/*
* Only SOF_DAI_INTEL_ALH needs copier_data to set blob.
- * That's why only ALH dai's blob is set after sof_ipc4_init_audio_fmt
+ * That's why only ALH dai's blob is set after sof_ipc4_init_input_audio_fmt
*/
if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
struct sof_ipc4_alh_configuration_blob *blob;
@@ -1692,10 +1693,10 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt;
int ret;
- ret = sof_ipc4_init_audio_fmt(sdev, swidget, &gain->base_config,
- pipeline_params, available_fmt,
- available_fmt->input_pin_fmts,
- available_fmt->num_input_formats);
+ ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->base_config,
+ pipeline_params, available_fmt,
+ available_fmt->input_pin_fmts,
+ available_fmt->num_input_formats);
if (ret < 0)
return ret;
@@ -1718,10 +1719,10 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt;
int ret;
- ret = sof_ipc4_init_audio_fmt(sdev, swidget, &mixer->base_config,
- pipeline_params, available_fmt,
- available_fmt->input_pin_fmts,
- available_fmt->num_input_formats);
+ ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &mixer->base_config,
+ pipeline_params, available_fmt,
+ available_fmt->input_pin_fmts,
+ available_fmt->num_input_formats);
if (ret < 0)
return ret;
@@ -1745,10 +1746,10 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
struct snd_interval *rate;
int ret;
- ret = sof_ipc4_init_audio_fmt(sdev, swidget, &src->base_config,
- pipeline_params, available_fmt,
- available_fmt->input_pin_fmts,
- available_fmt->num_input_formats);
+ ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->base_config,
+ pipeline_params, available_fmt,
+ available_fmt->input_pin_fmts,
+ available_fmt->num_input_formats);
if (ret < 0)
return ret;
@@ -1856,10 +1857,10 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
int output_fmt_index;
int ret;
- ret = sof_ipc4_init_audio_fmt(sdev, swidget, &process->base_config,
- pipeline_params, available_fmt,
- available_fmt->input_pin_fmts,
- available_fmt->num_input_formats);
+ ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &process->base_config,
+ pipeline_params, available_fmt,
+ available_fmt->input_pin_fmts,
+ available_fmt->num_input_formats);
if (ret < 0)
return ret;
--
2.40.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/9] ASoC: SOF: ipc4-topology: Handle output format special case
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
` (3 preceding siblings ...)
2023-05-15 10:33 ` [PATCH 4/9] ASoC: SOF: ipc4-topology: Rename sof_ipc4_init_audio_fmt() Peter Ujfalusi
@ 2023-05-15 10:33 ` Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 6/9] ASoC: SOF: ipc4-topology: Add a new helper function to get the valid bits Peter Ujfalusi
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
The current topologies have input/output formats in pairs and even
though there are multiple output formats, they are all the same. Handle
this case as if there were only one format in topology. Also, add a check
for the number of output formats and reports errors where applicable.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
sound/soc/sof/ipc4-topology.c | 55 +++++++++++++++++++++++++++++++----
1 file changed, 50 insertions(+), 5 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index a079dd8eb7e1..f3a6e739e800 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1033,10 +1033,37 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
struct sof_ipc4_available_audio_format *available_fmt,
int input_audio_format_index)
{
+ struct sof_ipc4_audio_format *out_fmt;
+ u32 out_rate, out_channels, out_valid_bits;
+ bool single_format = true;
int i;
- /* pick the only available output format */
- if (available_fmt->num_output_formats == 1)
+ if (!available_fmt->num_output_formats)
+ return -EINVAL;
+
+ out_fmt = &available_fmt->output_pin_fmts[0].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);
+
+ /* check if all output formats in topology are the same */
+ for (i = 1; i < available_fmt->num_output_formats; i++) {
+ 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);
+
+ if (_out_rate != out_rate || _out_channels != out_channels ||
+ _out_valid_bits != out_valid_bits) {
+ single_format = false;
+ break;
+ }
+ }
+
+ /* 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;
@@ -1522,6 +1549,11 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &copier_data->base_config,
available_fmt, ret);
+ if (output_fmt_index < 0) {
+ dev_err(sdev->dev, "No output formats in topology for copier %s",
+ swidget->widget->name);
+ return output_fmt_index;
+ }
/*
* Set the output format. Current topology defines pin 0 input and output formats in pairs.
@@ -1700,7 +1732,11 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
if (ret < 0)
return ret;
- sof_ipc4_init_output_audio_fmt(sdev, &gain->base_config, available_fmt, ret);
+ ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->base_config, available_fmt, ret);
+ if (ret < 0) {
+ dev_err(sdev->dev, "No output formats for %s", swidget->widget->name);
+ return ret;
+ }
/* update pipeline memory usage */
sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &gain->base_config);
@@ -1726,7 +1762,11 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
if (ret < 0)
return ret;
- sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt, ret);
+ ret = sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt, ret);
+ if (ret < 0) {
+ dev_err(sdev->dev, "No output formats for %s", swidget->widget->name);
+ return ret;
+ }
/* update pipeline memory usage */
sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &mixer->base_config);
@@ -1753,7 +1793,11 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
if (ret < 0)
return ret;
- sof_ipc4_init_output_audio_fmt(sdev, &src->base_config, available_fmt, ret);
+ ret = sof_ipc4_init_output_audio_fmt(sdev, &src->base_config, available_fmt, ret);
+ if (ret < 0) {
+ dev_err(sdev->dev, "No output formats for %s", swidget->widget->name);
+ return ret;
+ }
/* update pipeline memory usage */
sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &src->base_config);
@@ -1864,6 +1908,7 @@ 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 */
output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &process->base_config,
available_fmt, ret);
--
2.40.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/9] ASoC: SOF: ipc4-topology: Add a new helper function to get the valid bits
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
` (4 preceding siblings ...)
2023-05-15 10:33 ` [PATCH 5/9] ASoC: SOF: ipc4-topology: Handle output format special case Peter Ujfalusi
@ 2023-05-15 10:33 ` Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 7/9] ASoC: SOF: ipc4-topology: Modify the output format selection logic Peter Ujfalusi
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Add a new helper function sof_ipc4_get_valid_bits() to get the valid
bits in the PCM params.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
sound/soc/sof/ipc4-topology.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index f3a6e739e800..2903e784a5dd 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1075,6 +1075,21 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
return i;
}
+static int sof_ipc4_get_valid_bits(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params)
+{
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ return 16;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ return 24;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ return 32;
+ default:
+ dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params));
+ return -EINVAL;
+ }
+}
+
static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
struct snd_sof_widget *swidget,
struct sof_ipc4_base_module_cfg *base_config,
@@ -1093,20 +1108,9 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
return -EINVAL;
}
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- sample_valid_bits = 16;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- sample_valid_bits = 24;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- sample_valid_bits = 32;
- break;
- default:
- dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params));
- return -EINVAL;
- }
+ sample_valid_bits = sof_ipc4_get_valid_bits(sdev, params);
+ if (sample_valid_bits < 0)
+ return sample_valid_bits;
if (!pin_fmts_size) {
dev_err(sdev->dev, "no formats available for %s\n", swidget->widget->name);
--
2.40.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 7/9] ASoC: SOF: ipc4-topology: Modify the output format selection logic
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
` (5 preceding siblings ...)
2023-05-15 10:33 ` [PATCH 6/9] ASoC: SOF: ipc4-topology: Add a new helper function to get the valid bits Peter Ujfalusi
@ 2023-05-15 10:33 ` Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 8/9] ASoC: SOF: ipc4-topology: New helper to check if all output formats are the same Peter Ujfalusi
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Modify the output format selection when there are multiple output
formats available to choose the one that matches the reference params.
The reference params depend on the type of module. In the case of
processing modules, the reference params are based on the selected input
audio format. This would be the case when a processing module does not
perform any format conversion during processing.
The only special case is the copier module. The copier module is capable
of format conversion but it is only used in the case when the output
is fixed to a single format. In the case of a module copier, when there are
multiple formats, the reference params is based on the selected input
params and the output format must match that of the selected input
format. In the case of host copier, the reference params should be
based on the input audio format for playback and the FE hw_params for
capture. In the case DAI copier, the reference params should be based on
the input audio format for capture and the FE hw_params for playback
when there is no format conversion in the pipeline from the host to the
DAI.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
sound/soc/sof/ipc4-topology.c | 127 ++++++++++++++++++++++++++++------
1 file changed, 107 insertions(+), 20 deletions(-)
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 &&
--
2.40.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 8/9] ASoC: SOF: ipc4-topology: New helper to check if all output formats are the same
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
` (6 preceding siblings ...)
2023-05-15 10:33 ` [PATCH 7/9] ASoC: SOF: ipc4-topology: Modify the output format selection logic Peter Ujfalusi
@ 2023-05-15 10:33 ` Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 9/9] ASoC: SOF: ipc4-topology: Modify input audio format selection logic Peter Ujfalusi
2023-05-15 15:31 ` [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the " Mark Brown
9 siblings, 0 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Add a helper function to check if all formats are identical.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
sound/soc/sof/ipc4-topology.c | 53 ++++++++++++++++++++---------------
1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 7f5400612bf8..723e72d2d325 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1028,6 +1028,34 @@ static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw
return 0;
}
+static bool sof_ipc4_is_single_format(struct snd_sof_dev *sdev,
+ struct sof_ipc4_pin_format *pin_fmts, u32 pin_fmts_size)
+{
+ struct sof_ipc4_audio_format *fmt;
+ u32 rate, channels, valid_bits;
+ int i;
+
+ fmt = &pin_fmts[0].audio_fmt;
+ rate = fmt->sampling_frequency;
+ channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
+ valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
+
+ /* check if all output formats in topology are the same */
+ for (i = 1; i < pin_fmts_size; i++) {
+ u32 _rate, _channels, _valid_bits;
+
+ fmt = &pin_fmts[i].audio_fmt;
+ _rate = fmt->sampling_frequency;
+ _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 (_rate != rate || _channels != channels || _valid_bits != valid_bits)
+ return false;
+ }
+
+ return true;
+}
+
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,
@@ -1035,33 +1063,14 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
u32 out_ref_valid_bits)
{
struct sof_ipc4_audio_format *out_fmt;
- u32 out_rate, out_channels, out_valid_bits;
- bool single_format = true;
+ bool single_format;
int i;
if (!available_fmt->num_output_formats)
return -EINVAL;
- out_fmt = &available_fmt->output_pin_fmts[0].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);
-
- /* check if all output formats in topology are the same */
- for (i = 1; i < available_fmt->num_output_formats; i++) {
- 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);
-
- if (_out_rate != out_rate || _out_channels != out_channels ||
- _out_valid_bits != out_valid_bits) {
- single_format = false;
- break;
- }
- }
+ single_format = sof_ipc4_is_single_format(sdev, available_fmt->output_pin_fmts,
+ available_fmt->num_output_formats);
/* pick the first format if there's only one available or if all formats are the same */
if (single_format) {
--
2.40.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 9/9] ASoC: SOF: ipc4-topology: Modify input audio format selection logic
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
` (7 preceding siblings ...)
2023-05-15 10:33 ` [PATCH 8/9] ASoC: SOF: ipc4-topology: New helper to check if all output formats are the same Peter Ujfalusi
@ 2023-05-15 10:33 ` Peter Ujfalusi
2023-05-15 15:31 ` [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the " Mark Brown
9 siblings, 0 replies; 11+ messages in thread
From: Peter Ujfalusi @ 2023-05-15 10:33 UTC (permalink / raw)
To: lgirdwood, broonie
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
The current selection logic assumes that input and output formats always
come in pairs in topology. Handle this special case by checking if all
input formats are the same. And for the case where there are multiple
supported input audio formats, modify the selection logic to pick the
audio formats based on the reference params which is either the FE
hw_params or the pipeline params based on the type of module.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
sound/soc/sof/ipc4-topology.c | 132 +++++++++-------------------------
1 file changed, 32 insertions(+), 100 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 723e72d2d325..f2c5e3c61f90 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1119,36 +1119,34 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
struct snd_sof_widget *swidget,
struct sof_ipc4_base_module_cfg *base_config,
struct snd_pcm_hw_params *params,
- struct sof_ipc4_available_audio_format *available_fmt,
- struct sof_ipc4_pin_format *pin_fmts, u32 pin_fmts_size)
+ struct sof_ipc4_available_audio_format *available_fmt)
{
+ struct sof_ipc4_pin_format *pin_fmts = available_fmt->input_pin_fmts;
+ u32 pin_fmts_size = available_fmt->num_input_formats;
u32 valid_bits;
u32 channels;
u32 rate;
+ bool single_format;
int sample_valid_bits;
int i = 0;
- if (!pin_fmts) {
- dev_err(sdev->dev, "no reference formats for %s\n", swidget->widget->name);
+ if (!available_fmt->num_input_formats) {
+ 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);
+ if (single_format)
+ goto in_fmt;
+
sample_valid_bits = sof_ipc4_get_valid_bits(sdev, params);
if (sample_valid_bits < 0)
return sample_valid_bits;
- if (!pin_fmts_size) {
- dev_err(sdev->dev, "no formats available for %s\n", swidget->widget->name);
- return -EINVAL;
- }
-
- /* pick the only available input format */
- if (available_fmt->num_input_formats == 1)
- goto in_fmt;
-
/*
- * Search supported audio formats with pin index 0 to match rate, channels ,and
- * sample_valid_bytes from runtime params
+ * Search supported input audio formats with pin index 0 to match rate, channels and
+ * sample_valid_bits from reference params
*/
for (i = 0; i < pin_fmts_size; i++) {
struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt;
@@ -1365,50 +1363,6 @@ static int ipc4_set_fmt_mask(struct snd_mask *fmt, unsigned int bit_depth)
return 0;
}
-static int ipc4_copier_set_capture_fmt(struct snd_sof_dev *sdev,
- struct snd_pcm_hw_params *pipeline_params,
- struct snd_pcm_hw_params *fe_params,
- struct sof_ipc4_available_audio_format *available_fmt)
-{
- struct sof_ipc4_audio_format *audio_fmt;
- unsigned int sample_valid_bits;
- bool multiple_formats = false;
- bool fe_format_match = false;
- struct snd_mask *fmt;
- int i;
-
- for (i = 0; i < available_fmt->num_output_formats; i++) {
- unsigned int val;
-
- audio_fmt = &available_fmt->output_pin_fmts[i].audio_fmt;
- val = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(audio_fmt->fmt_cfg);
-
- if (i == 0)
- sample_valid_bits = val;
- else if (sample_valid_bits != val)
- multiple_formats = true;
-
- if (snd_pcm_format_width(params_format(fe_params)) == val)
- fe_format_match = true;
- }
-
- fmt = hw_param_mask(pipeline_params, SNDRV_PCM_HW_PARAM_FORMAT);
- snd_mask_none(fmt);
-
- if (multiple_formats) {
- if (fe_format_match) {
- /* multiple formats defined and one matches FE */
- snd_mask_set_format(fmt, params_format(fe_params));
- return 0;
- }
-
- dev_err(sdev->dev, "Multiple audio formats for single dai_out not supported\n");
- return -EINVAL;
- }
-
- return ipc4_set_fmt_mask(fmt, sample_valid_bits);
-}
-
static int
sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
struct snd_pcm_hw_params *fe_params,
@@ -1418,7 +1372,6 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
struct sof_ipc4_available_audio_format *available_fmt;
struct snd_soc_component *scomp = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- struct sof_ipc4_pin_format *format_list_to_search;
struct sof_ipc4_copier_data *copier_data;
struct snd_pcm_hw_params *ref_params;
struct sof_ipc4_copier *ipc4_copier;
@@ -1431,7 +1384,6 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
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;
dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id);
@@ -1496,13 +1448,10 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
* Use the input_pin_fmts to match pcm params for playback and the output_pin_fmts
* for capture.
*/
- if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
- format_list_to_search = available_fmt->input_pin_fmts;
- format_list_count = available_fmt->num_input_formats;
- } else {
- format_list_to_search = available_fmt->output_pin_fmts;
- format_list_count = available_fmt->num_output_formats;
- }
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK)
+ ref_params = fe_params;
+ else
+ ref_params = pipeline_params;
copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
copier_data->gtw_cfg.node_id |=
@@ -1510,7 +1459,6 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
/* set gateway attributes */
gtw_attr->lp_buffer_alloc = pipeline->lp_mode;
- ref_params = fe_params;
break;
}
case snd_soc_dapm_dai_in:
@@ -1527,20 +1475,17 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
ipc4_copier = (struct sof_ipc4_copier *)dai->private;
copier_data = &ipc4_copier->data;
available_fmt = &ipc4_copier->available_fmt;
- if (dir == SNDRV_PCM_STREAM_CAPTURE) {
- format_list_to_search = available_fmt->output_pin_fmts;
- format_list_count = available_fmt->num_output_formats;
-
- ret = ipc4_copier_set_capture_fmt(sdev, pipeline_params, fe_params,
- available_fmt);
- if (ret < 0)
- return ret;
- } else {
- format_list_to_search = available_fmt->input_pin_fmts;
- format_list_count = available_fmt->num_input_formats;
- }
- ref_params = pipeline_params;
+ /*
+ * When there is format conversion within a pipeline, the number of supported
+ * output formats is typically limited to just 1 for the DAI copiers. But when there
+ * is no format conversion, the DAI copiers input format must match that of the
+ * FE hw_params for capture and the pipeline params for playback.
+ */
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK)
+ ref_params = pipeline_params;
+ else
+ ref_params = fe_params;
ret = snd_sof_get_nhlt_endpoint_data(sdev, dai, fe_params, ipc4_copier->dai_index,
ipc4_copier->dai_type, dir,
@@ -1556,10 +1501,6 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
ipc4_copier = (struct sof_ipc4_copier *)swidget->private;
copier_data = &ipc4_copier->data;
available_fmt = &ipc4_copier->available_fmt;
-
- /* Use the input formats to match pcm params */
- format_list_to_search = available_fmt->input_pin_fmts;
- format_list_count = available_fmt->num_input_formats;
ref_params = pipeline_params;
break;
@@ -1572,8 +1513,7 @@ 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, format_list_to_search,
- format_list_count);
+ available_fmt);
if (ret < 0)
return ret;
@@ -1790,9 +1730,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
int ret;
ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->base_config,
- pipeline_params, available_fmt,
- available_fmt->input_pin_fmts,
- available_fmt->num_input_formats);
+ pipeline_params, available_fmt);
if (ret < 0)
return ret;
@@ -1829,9 +1767,7 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
int ret;
ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &mixer->base_config,
- pipeline_params, available_fmt,
- available_fmt->input_pin_fmts,
- available_fmt->num_input_formats);
+ pipeline_params, available_fmt);
if (ret < 0)
return ret;
@@ -1869,9 +1805,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
int ret;
ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->base_config,
- pipeline_params, available_fmt,
- available_fmt->input_pin_fmts,
- available_fmt->num_input_formats);
+ pipeline_params, available_fmt);
if (ret < 0)
return ret;
@@ -1992,9 +1926,7 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
int ret;
ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &process->base_config,
- pipeline_params, available_fmt,
- available_fmt->input_pin_fmts,
- available_fmt->num_input_formats);
+ pipeline_params, available_fmt);
if (ret < 0)
return ret;
--
2.40.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
` (8 preceding siblings ...)
2023-05-15 10:33 ` [PATCH 9/9] ASoC: SOF: ipc4-topology: Modify input audio format selection logic Peter Ujfalusi
@ 2023-05-15 15:31 ` Mark Brown
9 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2023-05-15 15:31 UTC (permalink / raw)
To: lgirdwood, Peter Ujfalusi
Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan, kai.vehmanen,
yung-chuan.liao
On Mon, 15 May 2023 13:33:27 +0300, Peter Ujfalusi wrote:
> Improve the logic to account for the current restrictions in topology while
> making it extensible for future topology modifications.
>
> The current topology definitions assume that input/output formats come in pairs.
> For example even if there's only 1 output format for a module, we add 3 output
> formats to match that of the input format count with the same parameters.
> This is unnecessary but we have to deal with it until the topologies are
> modified.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/9] ASoC: SOF: ipc4-topology: Handle input/output audio format special case
commit: 4c7873d60958ed1895b6552fb1e15fa2bbf06cad
[2/9] ASoC: SOF: ipc4-topology: Add a helper function for output format selection
commit: 523042f63febca24cbf9cf83729044c3dbaa9706
[3/9] ASoC: SOF: ipc4-topology: Move the call to init output format
commit: a2e07c3319f79f7305641b98d32765dc5b607873
[4/9] ASoC: SOF: ipc4-topology: Rename sof_ipc4_init_audio_fmt()
commit: ae45aebe45600a85c410280badec6b209979cf7c
[5/9] ASoC: SOF: ipc4-topology: Handle output format special case
commit: f1ceebdbe8d8915edb64045853ab23db8ddade60
[6/9] ASoC: SOF: ipc4-topology: Add a new helper function to get the valid bits
commit: 35171c1a907cb1226ba190685c38f62ef02bbed8
[7/9] ASoC: SOF: ipc4-topology: Modify the output format selection logic
commit: 1af13f221ac331e2d493896df5315fb8b211b4aa
[8/9] ASoC: SOF: ipc4-topology: New helper to check if all output formats are the same
commit: f37b702cb6f76963013af951737e49e61bf35771
[9/9] ASoC: SOF: ipc4-topology: Modify input audio format selection logic
commit: 5a56c5335d36decbdcb80900c665360fbbd1042a
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2023-05-15 15:33 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-15 10:33 [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the audio format selection logic Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 1/9] ASoC: SOF: ipc4-topology: Handle input/output audio format special case Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 2/9] ASoC: SOF: ipc4-topology: Add a helper function for output format selection Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 3/9] ASoC: SOF: ipc4-topology: Move the call to init output format Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 4/9] ASoC: SOF: ipc4-topology: Rename sof_ipc4_init_audio_fmt() Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 5/9] ASoC: SOF: ipc4-topology: Handle output format special case Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 6/9] ASoC: SOF: ipc4-topology: Add a new helper function to get the valid bits Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 7/9] ASoC: SOF: ipc4-topology: Modify the output format selection logic Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 8/9] ASoC: SOF: ipc4-topology: New helper to check if all output formats are the same Peter Ujfalusi
2023-05-15 10:33 ` [PATCH 9/9] ASoC: SOF: ipc4-topology: Modify input audio format selection logic Peter Ujfalusi
2023-05-15 15:31 ` [PATCH 0/9] ASoC: SOF: ipc4-topology: Improve the " Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox