ASoC: SOF: topology: allow user to add topologies

Currently, the function topology provides the basic audio function. The
commit allow the users add their topologies to the topology list. So
they can add their own features.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20260421091351.4056377-3-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Bard Liao 2026-04-21 17:13:51 +08:00 committed by Mark Brown
parent 0d0e98603f
commit d82bf6af62
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -23,6 +23,13 @@ static bool disable_function_topology;
module_param(disable_function_topology, bool, 0444);
MODULE_PARM_DESC(disable_function_topology, "Disable function topology loading");
#define MAX_FEATURE_TPLG_COUNT 16
static char *feature_topologies[MAX_FEATURE_TPLG_COUNT];
static int feature_tplg_cnt;
module_param_array(feature_topologies, charp, &feature_tplg_cnt, 0444);
MODULE_PARM_DESC(feature_topologies, "Topology list for virtual loop DAI link");
#define COMP_ID_UNASSIGNED 0xffffffff
/*
* Constants used in the computation of linear volume gain
@ -2575,6 +2582,54 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
}
}
/* Loading user defined topologies */
for (i = 0; i < feature_tplg_cnt; i++) {
const char *feature_topology = devm_kasprintf(scomp->dev, GFP_KERNEL, "%s/%s",
tplg_filename_prefix,
feature_topologies[i]);
if (!feature_topology) {
ret = -ENOMEM;
goto out;
}
dev_info(scomp->dev, "loading feature topology %d: %s\n", i, feature_topology);
ret = request_firmware(&fw, feature_topology, scomp->dev);
if (ret < 0) {
/*
* snd_soc_tplg_component_remove(scomp) will be called
* if snd_soc_tplg_component_load(scomp) failed and all
* objects in the scomp will be removed. No need to call
* snd_soc_tplg_component_remove(scomp) here.
*/
dev_warn(scomp->dev, "feature tplg request firmware %s failed err: %d\n",
feature_topologies[i], ret);
/*
* We don't return error here because we can still have the basic
* audio feature when the function topology load complete. No need
* to convert the error code because we will get new 'ret' out of the
* loop.
*/
continue;
}
if (sdev->dspless_mode_selected)
ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
else
ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
release_firmware(fw);
if (ret < 0) {
dev_err(scomp->dev, "feature tplg %s component load failed %d\n",
feature_topologies[i], ret);
/*
* We need to return error here because it may lead to kernel NULL pointer
* dereference if we continue the remaining tasks.
*/
goto out;
}
}
/* call sof_complete when topologies are loaded successfully */
ret = sof_complete(scomp);