From: Bard Liao Date: Tue, 21 Apr 2026 09:13:51 +0000 (+0800) Subject: ASoC: SOF: topology: allow user to add topologies X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d82bf6af621301971ac01b0f2919e87137c59774;p=thirdparty%2Flinux.git 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 Reviewed-by: Péter Ujfalusi Link: https://patch.msgid.link/20260421091351.4056377-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 63d582c658915..87b539916b4a7 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -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);