mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-21 06:50:25 +00:00
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> Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://patch.msgid.link/20250414063239.85200-5-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
d1e70eed0b
commit
6d5997c412
1 changed files with 68 additions and 18 deletions
|
@ -2310,8 +2310,10 @@ static const struct snd_soc_tplg_ops sof_tplg_ops = {
|
||||||
.link_load = sof_link_load,
|
.link_load = sof_link_load,
|
||||||
.link_unload = sof_link_unload,
|
.link_unload = sof_link_unload,
|
||||||
|
|
||||||
/* completion - called at completion of firmware loading */
|
/*
|
||||||
.complete = sof_complete,
|
* No need to set the complete callback. sof_complete will be called explicitly after
|
||||||
|
* topology loading is complete.
|
||||||
|
*/
|
||||||
|
|
||||||
/* manifest - optional to inform component of manifest */
|
/* manifest - optional to inform component of manifest */
|
||||||
.manifest = sof_manifest,
|
.manifest = sof_manifest,
|
||||||
|
@ -2467,18 +2469,57 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
|
||||||
int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
|
int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
|
||||||
{
|
{
|
||||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
|
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
|
||||||
|
struct snd_sof_pdata *sof_pdata = sdev->pdata;
|
||||||
|
const char *tplg_filename_prefix = sof_pdata->tplg_filename_prefix;
|
||||||
const struct firmware *fw;
|
const struct firmware *fw;
|
||||||
|
const char **tplg_files;
|
||||||
|
int tplg_cnt = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tplg_files = kcalloc(scomp->card->num_links, sizeof(char *), GFP_KERNEL);
|
||||||
|
if (!tplg_files)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (sof_pdata->machine->get_function_tplg_files) {
|
||||||
|
tplg_cnt = sof_pdata->machine->get_function_tplg_files(scomp->card,
|
||||||
|
sof_pdata->machine,
|
||||||
|
tplg_filename_prefix,
|
||||||
|
&tplg_files);
|
||||||
|
if (tplg_cnt < 0) {
|
||||||
|
kfree(tplg_files);
|
||||||
|
return tplg_cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The monolithic topology will be used if there is no get_function_tplg_files
|
||||||
|
* callback or the callback returns 0.
|
||||||
|
*/
|
||||||
|
if (!tplg_cnt) {
|
||||||
|
tplg_files[0] = file;
|
||||||
|
tplg_cnt = 1;
|
||||||
dev_dbg(scomp->dev, "loading topology: %s\n", file);
|
dev_dbg(scomp->dev, "loading topology: %s\n", file);
|
||||||
|
} else {
|
||||||
|
dev_info(scomp->dev, "Using function topologies instead %s\n", file);
|
||||||
|
}
|
||||||
|
|
||||||
ret = request_firmware(&fw, file, scomp->dev);
|
for (i = 0; i < tplg_cnt; i++) {
|
||||||
|
/* Only print the file names if the function topologies are used */
|
||||||
|
if (tplg_files[0] != file)
|
||||||
|
dev_info(scomp->dev, "loading topology %d: %s\n", i, tplg_files[i]);
|
||||||
|
|
||||||
|
ret = request_firmware(&fw, tplg_files[i], scomp->dev);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n",
|
/*
|
||||||
file, ret);
|
* snd_soc_tplg_component_remove(scomp) will be called
|
||||||
dev_err(scomp->dev,
|
* if snd_soc_tplg_component_load(scomp) failed and all
|
||||||
"you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n");
|
* objects in the scomp will be removed. No need to call
|
||||||
return ret;
|
* 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)
|
if (sdev->dspless_mode_selected)
|
||||||
|
@ -2486,15 +2527,24 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
|
||||||
else
|
else
|
||||||
ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
|
ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
dev_err(scomp->dev, "error: tplg component load failed %d\n",
|
|
||||||
ret);
|
|
||||||
|
|
||||||
release_firmware(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);
|
||||||
|
|
||||||
|
out:
|
||||||
if (ret >= 0 && sdev->led_present)
|
if (ret >= 0 && sdev->led_present)
|
||||||
ret = snd_ctl_led_request();
|
ret = snd_ctl_led_request();
|
||||||
|
|
||||||
|
kfree(tplg_files);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(snd_sof_load_topology);
|
EXPORT_SYMBOL(snd_sof_load_topology);
|
||||||
|
|
Loading…
Add table
Reference in a new issue