Skip to content

Commit bfa96a4

Browse files
committed
ASoC: SOF: topology: load multiple topologies
A topology can be split into several sub-topologies. The sub-topologies can be used across cards. In other words, we can create multiple mini topologies and let driver select what it needs. However, the topology depends on the cards. Add a get_tplg_files ops allow cards have their own sub-topology file names. The commit add an empty ops first. Will add the first ops in the follow up commit. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
1 parent d1b73da commit bfa96a4

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

sound/soc/sof/topology.c

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
#include <linux/workqueue.h>
1616
#include <sound/tlv.h>
1717
#include <uapi/sound/sof/tokens.h>
18+
#include "ops.h"
1819
#include "sof-priv.h"
1920
#include "sof-audio.h"
20-
#include "ops.h"
21+
#include "topology.h"
2122

2223
#define COMP_ID_UNASSIGNED 0xffffffff
2324
/*
@@ -2298,7 +2299,7 @@ static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = {
22982299
{SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_bytes_ext_volatile_get},
22992300
};
23002301

2301-
static const struct snd_soc_tplg_ops sof_tplg_ops = {
2302+
static struct snd_soc_tplg_ops sof_tplg_ops = {
23022303
/* external kcontrol init - used for any driver specific init */
23032304
.control_load = sof_control_load,
23042305
.control_unload = sof_control_unload,
@@ -2321,7 +2322,7 @@ static const struct snd_soc_tplg_ops sof_tplg_ops = {
23212322
.link_unload = sof_link_unload,
23222323

23232324
/* completion - called at completion of firmware loading */
2324-
.complete = sof_complete,
2325+
/* complete will be added in the last tplg ops */
23252326

23262327
/* manifest - optional to inform component of manifest */
23272328
.manifest = sof_manifest,
@@ -2474,14 +2475,71 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
24742475
.bytes_ext_ops_count = ARRAY_SIZE(sof_dspless_bytes_ext_ops),
24752476
};
24762477

2478+
static const struct card_tplg_ops card_ops[] = {
2479+
{}
2480+
};
2481+
24772482
int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24782483
{
24792484
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2485+
char **tplg_files;
24802486
const struct firmware *fw;
2487+
int tplg_num = 0;
24812488
int ret;
2489+
int i;
24822490

24832491
dev_dbg(scomp->dev, "loading topology:%s\n", file);
24842492

2493+
for (i = 0; card_ops[i].card_name; i++) {
2494+
if (!strcmp(scomp->card->name, card_ops[i].card_name)) {
2495+
ret = card_ops[i].get_tplg_files(scomp, file, &tplg_files);
2496+
if (ret < 0)
2497+
return ret;
2498+
tplg_num = ret;
2499+
break;
2500+
}
2501+
}
2502+
if (!tplg_num)
2503+
goto legacy_tplg;
2504+
2505+
for (i = 0; i < tplg_num; i++) {
2506+
dev_dbg(scomp->dev, "Requesting %d %s\n", i, tplg_files[i]);
2507+
ret = firmware_request_nowarn(&fw, tplg_files[i], scomp->dev);
2508+
if (ret < 0) {
2509+
if (i == 0) {
2510+
dev_dbg(scomp->dev, "Fail back to %s\n", file);
2511+
kfree(tplg_files[i]);
2512+
goto legacy_tplg;
2513+
}
2514+
2515+
dev_err(scomp->dev, "tplg request firmware %s failed err: %d\n",
2516+
tplg_files[i], ret);
2517+
kfree(tplg_files[i]);
2518+
goto out;
2519+
}
2520+
kfree(tplg_files[i]);
2521+
2522+
/* set complete = sof_complete if it is the last topology */
2523+
if (i == tplg_num - 1)
2524+
sof_tplg_ops.complete = sof_complete;
2525+
2526+
if (sdev->dspless_mode_selected)
2527+
ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
2528+
else
2529+
ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
2530+
2531+
release_firmware(fw);
2532+
2533+
if (ret < 0) {
2534+
dev_err(scomp->dev, "tplg component load failed %d\n",
2535+
ret);
2536+
return ret;
2537+
}
2538+
}
2539+
/* Load topology successfully, goto out */
2540+
goto out;
2541+
2542+
legacy_tplg:
24852543
ret = request_firmware(&fw, file, scomp->dev);
24862544
if (ret < 0) {
24872545
dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n",
@@ -2491,6 +2549,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24912549
return ret;
24922550
}
24932551

2552+
sof_tplg_ops.complete = sof_complete;
24942553
if (sdev->dspless_mode_selected)
24952554
ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
24962555
else
@@ -2502,6 +2561,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
25022561

25032562
release_firmware(fw);
25042563

2564+
out:
25052565
if (ret >= 0 && sdev->led_present)
25062566
ret = snd_ctl_led_request();
25072567

sound/soc/sof/topology.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2+
/*
3+
* This file is provided under a dual BSD/GPLv2 license. When using or
4+
* redistributing this file, you may do so under either license.
5+
*
6+
* Copyright(c) 2025 Intel Corporation
7+
*/
8+
9+
#ifndef __SOUND_SOC_SOF_TOPOLOGY_H
10+
#define __SOUND_SOC_SOF_TOPOLOGY_H
11+
12+
struct card_tplg_ops {
13+
const char *card_name;
14+
int (*get_tplg_files)(struct snd_soc_component *scomp, const char *file,
15+
char ***tplg_files);
16+
};
17+
18+
#endif

0 commit comments

Comments
 (0)