aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c1
-rw-r--r--sound/soc/codecs/adau17x1.c13
-rw-r--r--sound/soc/codecs/cs42l51.c9
-rw-r--r--sound/soc/codecs/cs53l30.c10
-rw-r--r--sound/soc/codecs/rt5659.c10
-rw-r--r--sound/soc/codecs/rt5682s.c11
-rw-r--r--sound/soc/sof/ipc4-loader.c72
-rw-r--r--sound/soc/sof/ipc4-priv.h10
-rw-r--r--sound/soc/sof/ipc4-topology.c33
-rw-r--r--sound/soc/stm/stm32_sai_sub.c9
10 files changed, 115 insertions, 63 deletions
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index baf38964b491..0405e9e49140 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -23,7 +23,6 @@
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/atmel-ssc.h>
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c
index 634d4dbca5ec..f2932713b4de 100644
--- a/sound/soc/codecs/adau17x1.c
+++ b/sound/soc/codecs/adau17x1.c
@@ -1059,13 +1059,12 @@ int adau17x1_probe(struct device *dev, struct regmap *regmap,
if (!adau)
return -ENOMEM;
- adau->mclk = devm_clk_get(dev, "mclk");
- if (IS_ERR(adau->mclk)) {
- if (PTR_ERR(adau->mclk) != -ENOENT)
- return PTR_ERR(adau->mclk);
- /* Clock is optional (for the driver) */
- adau->mclk = NULL;
- } else if (adau->mclk) {
+ /* Clock is optional (for the driver) */
+ adau->mclk = devm_clk_get_optional(dev, "mclk");
+ if (IS_ERR(adau->mclk))
+ return PTR_ERR(adau->mclk);
+
+ if (adau->mclk) {
adau->clk_src = ADAU17X1_CLK_SRC_PLL_AUTO;
/*
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index e88d9ff95cdf..a67cd3ee84e0 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -724,12 +724,9 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap)
dev_set_drvdata(dev, cs42l51);
cs42l51->regmap = regmap;
- cs42l51->mclk_handle = devm_clk_get(dev, "MCLK");
- if (IS_ERR(cs42l51->mclk_handle)) {
- if (PTR_ERR(cs42l51->mclk_handle) != -ENOENT)
- return PTR_ERR(cs42l51->mclk_handle);
- cs42l51->mclk_handle = NULL;
- }
+ cs42l51->mclk_handle = devm_clk_get_optional(dev, "MCLK");
+ if (IS_ERR(cs42l51->mclk_handle))
+ return PTR_ERR(cs42l51->mclk_handle);
for (i = 0; i < ARRAY_SIZE(cs42l51->supplies); i++)
cs42l51->supplies[i].supply = cs42l51_supply_names[i];
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c
index 51ca66e7b3ea..21962b828ab1 100644
--- a/sound/soc/codecs/cs53l30.c
+++ b/sound/soc/codecs/cs53l30.c
@@ -990,14 +990,10 @@ static int cs53l30_i2c_probe(struct i2c_client *client)
}
/* Check if MCLK provided */
- cs53l30->mclk = devm_clk_get(dev, "mclk");
+ cs53l30->mclk = devm_clk_get_optional(dev, "mclk");
if (IS_ERR(cs53l30->mclk)) {
- if (PTR_ERR(cs53l30->mclk) != -ENOENT) {
- ret = PTR_ERR(cs53l30->mclk);
- goto error;
- }
- /* Otherwise mark the mclk pointer to NULL */
- cs53l30->mclk = NULL;
+ ret = PTR_ERR(cs53l30->mclk);
+ goto error;
}
/* Fetch the MUTE control */
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
index 22bb57029bc0..df6f0d769bbd 100644
--- a/sound/soc/codecs/rt5659.c
+++ b/sound/soc/codecs/rt5659.c
@@ -4141,13 +4141,9 @@ static int rt5659_i2c_probe(struct i2c_client *i2c)
regmap_write(rt5659->regmap, RT5659_RESET, 0);
/* Check if MCLK provided */
- rt5659->mclk = devm_clk_get(&i2c->dev, "mclk");
- if (IS_ERR(rt5659->mclk)) {
- if (PTR_ERR(rt5659->mclk) != -ENOENT)
- return PTR_ERR(rt5659->mclk);
- /* Otherwise mark the mclk pointer to NULL */
- rt5659->mclk = NULL;
- }
+ rt5659->mclk = devm_clk_get_optional(&i2c->dev, "mclk");
+ if (IS_ERR(rt5659->mclk))
+ return PTR_ERR(rt5659->mclk);
rt5659_calibrate(rt5659);
diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c
index 81163b026b9e..a01de405c22c 100644
--- a/sound/soc/codecs/rt5682s.c
+++ b/sound/soc/codecs/rt5682s.c
@@ -2848,14 +2848,9 @@ static int rt5682s_dai_probe_clks(struct snd_soc_component *component)
int ret;
/* Check if MCLK provided */
- rt5682s->mclk = devm_clk_get(component->dev, "mclk");
- if (IS_ERR(rt5682s->mclk)) {
- if (PTR_ERR(rt5682s->mclk) != -ENOENT) {
- ret = PTR_ERR(rt5682s->mclk);
- return ret;
- }
- rt5682s->mclk = NULL;
- }
+ rt5682s->mclk = devm_clk_get_optional(component->dev, "mclk");
+ if (IS_ERR(rt5682s->mclk))
+ return PTR_ERR(rt5682s->mclk);
/* Register CCF DAI clock control */
ret = rt5682s_register_dai_clks(component);
diff --git a/sound/soc/sof/ipc4-loader.c b/sound/soc/sof/ipc4-loader.c
index 1321acc402fd..eaa04762eb11 100644
--- a/sound/soc/sof/ipc4-loader.c
+++ b/sound/soc/sof/ipc4-loader.c
@@ -112,16 +112,13 @@ static ssize_t sof_ipc4_fw_parse_ext_man(struct snd_sof_dev *sdev,
return -EINVAL;
}
- /* a module's config is always the same size */
- fw_module->bss_size = fm_config[fm_entry->cfg_offset].is_bytes;
+ fw_module->fw_mod_cfg = &fm_config[fm_entry->cfg_offset];
dev_dbg(sdev->dev,
"module %s: UUID %pUL cfg_count: %u, bss_size: %#x\n",
fm_entry->name, &fm_entry->uuid, fm_entry->cfg_count,
- fw_module->bss_size);
+ fm_config[fm_entry->cfg_offset].is_bytes);
} else {
- fw_module->bss_size = 0;
-
dev_dbg(sdev->dev, "module %s: UUID %pUL\n", fm_entry->name,
&fm_entry->uuid);
}
@@ -426,6 +423,71 @@ int sof_ipc4_reload_fw_libraries(struct snd_sof_dev *sdev)
return ret;
}
+/**
+ * sof_ipc4_update_cpc_from_manifest - Update the cpc in base config from manifest
+ * @sdev: SOF device
+ * @fw_module: pointer struct sof_ipc4_fw_module to parse
+ * @basecfg: Pointer to the base_config to update
+ */
+void sof_ipc4_update_cpc_from_manifest(struct snd_sof_dev *sdev,
+ struct sof_ipc4_fw_module *fw_module,
+ struct sof_ipc4_base_module_cfg *basecfg)
+{
+ const struct sof_man4_module_config *fw_mod_cfg;
+ u32 cpc_pick = 0;
+ u32 max_cpc = 0;
+ const char *msg;
+ int i;
+
+ if (!fw_module->fw_mod_cfg) {
+ msg = "No mod_cfg available for CPC lookup in the firmware file's manifest";
+ goto no_cpc;
+ }
+
+ /*
+ * Find the best matching (highest) CPC value based on the module's
+ * IBS/OBS configuration inferred from the audio format selection.
+ *
+ * The CPC value in each module config entry has been measured and
+ * recorded as a IBS/OBS/CPC triplet and stored in the firmware file's
+ * manifest
+ */
+ fw_mod_cfg = fw_module->fw_mod_cfg;
+ for (i = 0; i < fw_module->man4_module_entry.cfg_count; i++) {
+ if (basecfg->obs == fw_mod_cfg[i].obs &&
+ basecfg->ibs == fw_mod_cfg[i].ibs &&
+ cpc_pick < fw_mod_cfg[i].cpc)
+ cpc_pick = fw_mod_cfg[i].cpc;
+
+ if (max_cpc < fw_mod_cfg[i].cpc)
+ max_cpc = fw_mod_cfg[i].cpc;
+ }
+
+ basecfg->cpc = cpc_pick;
+
+ /* We have a matching configuration for CPC */
+ if (basecfg->cpc)
+ return;
+
+ /*
+ * No matching IBS/OBS found, the firmware manifest is missing
+ * information in the module's module configuration table.
+ */
+ if (!max_cpc)
+ msg = "No CPC value available in the firmware file's manifest";
+ else if (!cpc_pick)
+ msg = "No CPC match in the firmware file's manifest";
+
+no_cpc:
+ dev_warn(sdev->dev, "%s (UUID: %pUL): %s (ibs/obs: %u/%u)\n",
+ fw_module->man4_module_entry.name,
+ &fw_module->man4_module_entry.uuid, msg, basecfg->ibs,
+ basecfg->obs);
+ dev_warn_once(sdev->dev, "Please try to update the firmware.\n");
+ dev_warn_once(sdev->dev, "If the issue persists, file a bug at\n");
+ dev_warn_once(sdev->dev, "https://github.com/thesofproject/sof/issues/\n");
+}
+
const struct sof_ipc_fw_loader_ops ipc4_loader_ops = {
.validate = sof_ipc4_validate_firmware,
.parse_ext_manifest = sof_ipc4_fw_parse_basefw_ext_man,
diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h
index f461b8c70df3..a5d0b2eae464 100644
--- a/sound/soc/sof/ipc4-priv.h
+++ b/sound/soc/sof/ipc4-priv.h
@@ -28,14 +28,14 @@ enum sof_ipc4_mtrace_type {
/**
* struct sof_ipc4_fw_module - IPC4 module info
* @sof_man4_module: Module info
+ * @fw_mod_cfg: Pointer to the module config start of the module
* @m_ida: Module instance identifier
- * @bss_size: Module object size
* @private: Module private data
*/
struct sof_ipc4_fw_module {
struct sof_man4_module man4_module_entry;
+ const struct sof_man4_module_config *fw_mod_cfg;
struct ida m_ida;
- u32 bss_size;
void *private;
};
@@ -114,4 +114,10 @@ int sof_ipc4_query_fw_configuration(struct snd_sof_dev *sdev);
int sof_ipc4_reload_fw_libraries(struct snd_sof_dev *sdev);
struct sof_ipc4_fw_module *sof_ipc4_find_module_by_uuid(struct snd_sof_dev *sdev,
const guid_t *uuid);
+
+struct sof_ipc4_base_module_cfg;
+void sof_ipc4_update_cpc_from_manifest(struct snd_sof_dev *sdev,
+ struct sof_ipc4_fw_module *fw_module,
+ struct sof_ipc4_base_module_cfg *basecfg);
+
#endif
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 6b8e9edd28dd..681239dd54ee 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -39,8 +39,6 @@ static const struct sof_topology_token pipeline_tokens[] = {
};
static const struct sof_topology_token ipc4_comp_tokens[] = {
- {SOF_TKN_COMP_CPC, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
- offsetof(struct sof_ipc4_base_module_cfg, cpc)},
{SOF_TKN_COMP_IS_PAGES, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct sof_ipc4_base_module_cfg, is_pages)},
};
@@ -235,7 +233,7 @@ static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp,
"Number of input audio formats: %d. Number of output audio formats: %d\n",
available_fmt->num_input_formats, available_fmt->num_output_formats);
- /* set cpc and is_pages in the module's base_config */
+ /* set is_pages in the module's base_config */
ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples,
swidget->num_tuples, sizeof(*module_base_cfg), 1);
if (ret) {
@@ -244,8 +242,8 @@ static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp,
return ret;
}
- dev_dbg(scomp->dev, "widget %s cpc: %d is_pages: %d\n",
- swidget->widget->name, module_base_cfg->cpc, module_base_cfg->is_pages);
+ dev_dbg(scomp->dev, "widget %s: is_pages: %d\n", swidget->widget->name,
+ module_base_cfg->is_pages);
if (available_fmt->num_input_formats) {
in_format = kcalloc(available_fmt->num_input_formats,
@@ -723,9 +721,9 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
}
dev_dbg(scomp->dev,
- "pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x, cpc %d\n",
+ "pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x\n",
swidget->widget->name, gain->data.curve_type, gain->data.curve_duration_l,
- gain->data.init_val, gain->base_config.cpc);
+ gain->data.init_val);
ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg);
if (ret)
@@ -936,8 +934,8 @@ static void sof_ipc4_widget_free_comp_process(struct snd_sof_widget *swidget)
}
static void
-sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
- struct sof_ipc4_base_module_cfg *base_config)
+sof_ipc4_update_resource_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
+ struct sof_ipc4_base_module_cfg *base_config)
{
struct sof_ipc4_fw_module *fw_module = swidget->module_info;
struct snd_sof_widget *pipe_widget;
@@ -968,6 +966,13 @@ sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widg
pipe_widget = swidget->spipe->pipe_widget;
pipeline = pipe_widget->private;
pipeline->mem_usage += total;
+
+ /* Update base_config->cpc from the module manifest */
+ sof_ipc4_update_cpc_from_manifest(sdev, fw_module, base_config);
+
+ dev_dbg(sdev->dev, "%s: ibs / obs / cpc: %u / %u / %u\n",
+ swidget->widget->name, base_config->ibs, base_config->obs,
+ base_config->cpc);
}
static int sof_ipc4_widget_assign_instance_id(struct snd_sof_dev *sdev,
@@ -1711,7 +1716,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
*data, copier_data->gtw_cfg.config_length * 4);
/* update pipeline memory usage */
- sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &copier_data->base_config);
+ sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config);
return 0;
}
@@ -1748,7 +1753,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
}
/* update pipeline memory usage */
- sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &gain->base_config);
+ sof_ipc4_update_resource_usage(sdev, swidget, &gain->base_config);
return 0;
}
@@ -1785,7 +1790,7 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
}
/* update pipeline memory usage */
- sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &mixer->base_config);
+ sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config);
return 0;
}
@@ -1822,7 +1827,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
}
/* update pipeline memory usage */
- sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &src->base_config);
+ sof_ipc4_update_resource_usage(sdev, swidget, &src->base_config);
/* update pipeline_params for sink widgets */
rate = hw_param_interval(pipeline_params, SNDRV_PCM_HW_PARAM_RATE);
@@ -1959,7 +1964,7 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
}
/* update pipeline memory usage */
- sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &process->base_config);
+ sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config);
/* ipc_config_data is composed of the base_config followed by an optional extension */
memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg));
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index f6695dee353b..271ec5b3378d 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -1485,12 +1485,9 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev,
if (ret < 0)
return ret;
} else {
- sai->sai_mclk = devm_clk_get(&pdev->dev, "MCLK");
- if (IS_ERR(sai->sai_mclk)) {
- if (PTR_ERR(sai->sai_mclk) != -ENOENT)
- return PTR_ERR(sai->sai_mclk);
- sai->sai_mclk = NULL;
- }
+ sai->sai_mclk = devm_clk_get_optional(&pdev->dev, "MCLK");
+ if (IS_ERR(sai->sai_mclk))
+ return PTR_ERR(sai->sai_mclk);
}
return 0;