From 64d5a1199f08fb0f38c5f96a94d08e448f44c55b Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 5 Mar 2026 09:17:23 +0800 Subject: [PATCH 1/2] ASoC: sof-function-topology-lib: add virtual loop dai support The virtual loop dai link is created by the machine driver and no topology is needed for the dai link. Handle it to avoid the dai_link is not supported error. Signed-off-by: Bard Liao --- sound/soc/intel/common/sof-function-topology-lib.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/common/sof-function-topology-lib.c b/sound/soc/intel/common/sof-function-topology-lib.c index 0daa7d83808be6..2f2c902ef90ce9 100644 --- a/sound/soc/intel/common/sof-function-topology-lib.c +++ b/sound/soc/intel/common/sof-function-topology-lib.c @@ -19,6 +19,7 @@ enum tplg_device_id { TPLG_DEVICE_SDCA_MIC, TPLG_DEVICE_INTEL_PCH_DMIC, TPLG_DEVICE_HDMI, + TPLG_DEVICE_LOOPBACK_VIRTUAL, TPLG_DEVICE_MAX }; @@ -81,7 +82,15 @@ int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_ } else if (strstr(dai_link->name, "iDisp")) { tplg_dev = TPLG_DEVICE_HDMI; tplg_dev_name = "hdmi-pcm5"; - + } else if (strstr(dai_link->name, "Loopback_Virtual")) { + tplg_dev = TPLG_DEVICE_LOOPBACK_VIRTUAL; + /* + * Mark the LOOPBACK_VIRTUAL device but no need to create the + * LOOPBACK_VIRTUAL topology. Just to avoid the dai_link is not supported + * error. + */ + tplg_mask |= BIT(tplg_dev); + continue; } else { /* The dai link is not supported by separated tplg yet */ dev_dbg(card->dev, From c3616a94ec06d0b8468c84f3e6c324b5b784a912 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 5 Mar 2026 21:06:07 +0800 Subject: [PATCH 2/2] 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 --- sound/soc/sof/topology.c | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 17d00f868d411f..773aa2399b5439 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_USER_TPLG_COUNT 5 + +static char *user_topologies[MAX_USER_TPLG_COUNT]; +static int user_tplg_cnt; +module_param_array(user_topologies, charp, &user_tplg_cnt, 0444); +MODULE_PARM_DESC(index, "Topology list for virtual loop DAI link"); + #define COMP_ID_UNASSIGNED 0xffffffff /* * Constants used in the computation of linear volume gain @@ -2590,6 +2597,40 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) } } + /* Loading user defined topologies */ + for (i = 0; i < user_tplg_cnt; i++) { + const char *user_topology = devm_kasprintf(scomp->dev, GFP_KERNEL, "%s/%s", + tplg_filename_prefix, + user_topologies[i]); + + dev_info(scomp->dev, "loading user topology %d: %s\n", i, user_topology); + ret = request_firmware(&fw, user_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_err(scomp->dev, "tplg request firmware %s failed err: %d\n", + tplg_files[i], ret); + goto out; + } + + 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, "tplg %s component load failed %d\n", + tplg_files[i], ret); + goto out; + } + } + /* call sof_complete when topologies are loaded successfully */ ret = sof_complete(scomp);