Skip to content

Commit f5034ec

Browse files
bardliaoujfalusi
authored andcommitted
ASoC: SOF: topology: load multiple topologies
Currently, we always use single topology file to describe the widgets. However, with SDCA, we want to be able to load sub-topologies based on the supported device functions. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
1 parent 677d531 commit f5034ec

1 file changed

Lines changed: 68 additions & 18 deletions

File tree

sound/soc/sof/topology.c

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2320,8 +2320,10 @@ static const struct snd_soc_tplg_ops sof_tplg_ops = {
23202320
.link_load = sof_link_load,
23212321
.link_unload = sof_link_unload,
23222322

2323-
/* completion - called at completion of firmware loading */
2324-
.complete = sof_complete,
2323+
/*
2324+
* No need to set the complete callback. sof_complete will be called explicitly after
2325+
* topology loading is complete.
2326+
*/
23252327

23262328
/* manifest - optional to inform component of manifest */
23272329
.manifest = sof_manifest,
@@ -2488,34 +2490,82 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
24882490
int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24892491
{
24902492
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2493+
struct snd_sof_pdata *sof_pdata = sdev->pdata;
2494+
const char *tplg_filename_prefix = sof_pdata->tplg_filename_prefix;
24912495
const struct firmware *fw;
2496+
const char **tplg_files;
2497+
int tplg_cnt = 0;
24922498
int ret;
2499+
int i;
24932500

2494-
dev_dbg(scomp->dev, "loading topology:%s\n", file);
2501+
tplg_files = kcalloc(scomp->card->num_links, sizeof(char *), GFP_KERNEL);
2502+
if (!tplg_files)
2503+
return -ENOMEM;
24952504

2496-
ret = request_firmware(&fw, file, scomp->dev);
2497-
if (ret < 0) {
2498-
dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n",
2499-
file, ret);
2500-
dev_err(scomp->dev,
2501-
"you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n");
2502-
return ret;
2505+
if (sof_pdata->machine->get_function_tplg_files) {
2506+
tplg_cnt = sof_pdata->machine->get_function_tplg_files(scomp->card,
2507+
sof_pdata->machine,
2508+
tplg_filename_prefix,
2509+
&tplg_files);
2510+
if (tplg_cnt < 0) {
2511+
kfree(tplg_files);
2512+
return tplg_cnt;
2513+
}
25032514
}
25042515

2505-
if (sdev->dspless_mode_selected)
2506-
ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
2507-
else
2508-
ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
2516+
/*
2517+
* The monolithic topology will be used if there is no get_function_tplg_files
2518+
* callback or the callback returns 0.
2519+
*/
2520+
if (!tplg_cnt) {
2521+
tplg_files[0] = file;
2522+
tplg_cnt = 1;
2523+
dev_dbg(scomp->dev, "loading topology: %s\n", file);
2524+
} else {
2525+
dev_info(scomp->dev, "Using function topologies instead %s\n", file);
2526+
}
25092527

2510-
if (ret < 0)
2511-
dev_err(scomp->dev, "error: tplg component load failed %d\n",
2512-
ret);
2528+
for (i = 0; i < tplg_cnt; i++) {
2529+
/* Only print the file names if the function topologies are used */
2530+
if (tplg_files[0] != file)
2531+
dev_info(scomp->dev, "loading topology %d: %s\n", i, tplg_files[i]);
25132532

2514-
release_firmware(fw);
2533+
ret = request_firmware(&fw, tplg_files[i], scomp->dev);
2534+
if (ret < 0) {
2535+
/*
2536+
* snd_soc_tplg_component_remove(scomp) will be called
2537+
* if snd_soc_tplg_component_load(scomp) failed and all
2538+
* objects in the scomp will be removed. No need to call
2539+
* snd_soc_tplg_component_remove(scomp) here.
2540+
*/
2541+
dev_err(scomp->dev, "tplg request firmware %s failed err: %d\n",
2542+
tplg_files[i], ret);
2543+
goto out;
2544+
}
25152545

2546+
if (sdev->dspless_mode_selected)
2547+
ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
2548+
else
2549+
ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
2550+
2551+
release_firmware(fw);
2552+
2553+
if (ret < 0) {
2554+
dev_err(scomp->dev, "tplg %s component load failed %d\n",
2555+
tplg_files[i], ret);
2556+
goto out;
2557+
}
2558+
}
2559+
2560+
/* call sof_complete when topologies are loaded successfully */
2561+
ret = sof_complete(scomp);
2562+
2563+
out:
25162564
if (ret >= 0 && sdev->led_present)
25172565
ret = snd_ctl_led_request();
25182566

2567+
kfree(tplg_files);
2568+
25192569
return ret;
25202570
}
25212571
EXPORT_SYMBOL(snd_sof_load_topology);

0 commit comments

Comments
 (0)