Skip to content

Commit 1dfef99

Browse files
committed
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 d120514 commit 1dfef99

1 file changed

Lines changed: 61 additions & 18 deletions

File tree

sound/soc/sof/topology.c

Lines changed: 61 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,
@@ -2477,34 +2479,75 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
24772479
int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24782480
{
24792481
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2482+
struct snd_sof_pdata *sof_pdata = sdev->pdata;
2483+
const char *tplg_filename_prefix = sof_pdata->tplg_filename_prefix;
24802484
const struct firmware *fw;
2485+
const char **tplg_files;
2486+
int tplg_cnt = 0;
24812487
int ret;
2488+
int i;
24822489

2483-
dev_dbg(scomp->dev, "loading topology:%s\n", file);
2490+
tplg_files = kcalloc(scomp->card->num_links, sizeof(char *), GFP_KERNEL);
2491+
if (!tplg_files)
2492+
return -ENOMEM;
24842493

2485-
ret = request_firmware(&fw, file, scomp->dev);
2486-
if (ret < 0) {
2487-
dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n",
2488-
file, ret);
2489-
dev_err(scomp->dev,
2490-
"you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n");
2491-
return ret;
2494+
if (sof_pdata->machine->get_function_tplg_files) {
2495+
tplg_cnt = sof_pdata->machine->get_function_tplg_files(scomp->card,
2496+
sof_pdata->machine,
2497+
tplg_filename_prefix,
2498+
&tplg_files);
2499+
if (tplg_cnt < 0) {
2500+
kfree(tplg_files);
2501+
return tplg_cnt;
2502+
}
24922503
}
24932504

2494-
if (sdev->dspless_mode_selected)
2495-
ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
2496-
else
2497-
ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
2505+
/*
2506+
* The monolithic topology will be used if there is no get_sub_tplg_files
2507+
* callback or the callback returns 0.
2508+
*/
2509+
if (!tplg_cnt) {
2510+
tplg_files[0] = file;
2511+
tplg_cnt = 1;
2512+
}
24982513

2499-
if (ret < 0)
2500-
dev_err(scomp->dev, "error: tplg component load failed %d\n",
2501-
ret);
2514+
for (i = 0; i < tplg_cnt; i++) {
2515+
dev_info(scomp->dev, "loading topology %d: %s\n", i, tplg_files[i]);
2516+
ret = request_firmware(&fw, tplg_files[i], scomp->dev);
2517+
if (ret < 0) {
2518+
/*
2519+
* snd_soc_tplg_component_remove(scomp) will be called
2520+
* if snd_soc_tplg_component_load(scomp) failed and all
2521+
* objects in the scomp will be removed. No need to call
2522+
* snd_soc_tplg_component_remove(scomp) here.
2523+
*/
2524+
dev_err(scomp->dev, "tplg request firmware %s failed err: %d\n",
2525+
tplg_files[i], ret);
2526+
goto out;
2527+
}
2528+
2529+
if (sdev->dspless_mode_selected)
2530+
ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
2531+
else
2532+
ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
2533+
2534+
release_firmware(fw);
25022535

2503-
release_firmware(fw);
2536+
if (ret < 0) {
2537+
dev_err(scomp->dev, "tplg %s component load failed %d\n", tplg_files[i], ret);
2538+
goto out;
2539+
}
2540+
}
25042541

2542+
/* call sof_complete when topologies are loaded successfully */
2543+
ret = sof_complete(scomp);
2544+
2545+
out:
25052546
if (ret >= 0 && sdev->led_present)
25062547
ret = snd_ctl_led_request();
25072548

2549+
kfree(tplg_files);
2550+
25082551
return ret;
25092552
}
25102553
EXPORT_SYMBOL(snd_sof_load_topology);

0 commit comments

Comments
 (0)