Skip to content

Commit 7eb5975

Browse files
committed
WIP: ASoC: SOF: topology: test load multi-topologies
Get device information from dai links. load topology for each device. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
1 parent c152730 commit 7eb5975

File tree

1 file changed

+108
-3
lines changed

1 file changed

+108
-3
lines changed

sound/soc/sof/topology.c

Lines changed: 108 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ static int sof_copy_tuples(struct snd_sof_dev *sdev, struct snd_soc_tplg_vendor_
567567
continue;
568568

569569
tuples[*num_copied_tuples].token = tokens[j].token;
570-
tuples[*num_copied_tuples].value.s = elem->string;
570+
tuples[*num_copied_tuples].value.s = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s", elem->string);
571571
} else {
572572
struct snd_soc_tplg_vendor_value_elem *elem;
573573

@@ -2280,7 +2280,7 @@ static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = {
22802280
{SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_bytes_ext_volatile_get},
22812281
};
22822282

2283-
static const struct snd_soc_tplg_ops sof_tplg_ops = {
2283+
static struct snd_soc_tplg_ops sof_tplg_ops = {
22842284
/* external kcontrol init - used for any driver specific init */
22852285
.control_load = sof_control_load,
22862286
.control_unload = sof_control_unload,
@@ -2303,7 +2303,7 @@ static const struct snd_soc_tplg_ops sof_tplg_ops = {
23032303
.link_unload = sof_link_unload,
23042304

23052305
/* completion - called at completion of firmware loading */
2306-
.complete = sof_complete,
2306+
/* complete will be added in the last tplg ops */
23072307

23082308
/* manifest - optional to inform component of manifest */
23092309
.manifest = sof_manifest,
@@ -2456,14 +2456,117 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
24562456
.bytes_ext_ops_count = ARRAY_SIZE(sof_dspless_bytes_ext_ops),
24572457
};
24582458

2459+
#define MAX_TPLG_NUM 5
2460+
2461+
enum tplg_device_id {
2462+
TPLG_DEVICE_SDW_JACK,
2463+
TPLG_DEVICE_SDW_AMP,
2464+
TPLG_DEVICE_SDW_MIC,
2465+
TPLG_DEVICE_HOST_DMIC,
2466+
TPLG_DEVICE_HDMI,
2467+
};
2468+
2469+
struct topology_file {
2470+
char *platform;
2471+
char *device;
2472+
char *file;
2473+
int be_id;
2474+
};
2475+
24592476
int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24602477
{
24612478
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2479+
struct snd_sof_pdata *sof_pdata = sdev->pdata;
2480+
struct topology_file tplg_files[MAX_TPLG_NUM];
2481+
struct snd_soc_dai_link *dai_link;
2482+
char platform[4];
2483+
bool load_default_tplg = false;
2484+
unsigned long tplg_mask = 0;
24622485
const struct firmware *fw;
2486+
int tplg_num = 0;
24632487
int ret;
2488+
int i;
24642489

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

2492+
sscanf(sof_pdata->tplg_filename, "sof-%3s-*.tplg", platform);
2493+
2494+
if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3)
2495+
goto legacy_tplg;
2496+
2497+
for_each_card_prelinks(scomp->card, i, dai_link) {
2498+
dev_dbg(scomp->dev, "dai_link %s id %d\n", dai_link->name, dai_link->id);
2499+
if (strstr(dai_link->name, "SimpleJack")) {
2500+
if (tplg_mask & BIT(TPLG_DEVICE_SDW_JACK))
2501+
continue;
2502+
tplg_mask |= BIT(TPLG_DEVICE_SDW_JACK);
2503+
tplg_files[tplg_num].device = "sdca-jack";
2504+
} else if (strstr(dai_link->name, "SmartAmp")) {
2505+
if (tplg_mask & BIT(TPLG_DEVICE_SDW_AMP))
2506+
continue;
2507+
tplg_mask |= BIT(TPLG_DEVICE_SDW_AMP);
2508+
tplg_files[tplg_num].device = "sdca-amp";
2509+
} else if (strstr(dai_link->name, "SmartMic")) {
2510+
if (tplg_mask & BIT(TPLG_DEVICE_SDW_MIC))
2511+
continue;
2512+
tplg_mask |= BIT(TPLG_DEVICE_SDW_MIC);
2513+
tplg_files[tplg_num].device = "sdca-mic";
2514+
} else if (strstr(dai_link->name, "DMIC")) {
2515+
if (tplg_mask & BIT(TPLG_DEVICE_HOST_DMIC))
2516+
continue;
2517+
tplg_mask |= BIT(TPLG_DEVICE_HOST_DMIC);
2518+
tplg_files[tplg_num].device = "host-dmic";
2519+
} else if (strstr(dai_link->name, "iDisp")) {
2520+
if (tplg_mask & BIT(TPLG_DEVICE_HDMI))
2521+
continue;
2522+
tplg_mask |= BIT(TPLG_DEVICE_HDMI);
2523+
tplg_files[tplg_num].device = "hdmi";
2524+
} else {
2525+
/* The dai link is not supported by sperated tplg yet */
2526+
load_default_tplg = true;
2527+
continue;
2528+
}
2529+
tplg_files[tplg_num].be_id = dai_link->id;
2530+
tplg_num++;
2531+
}
2532+
dev_dbg(scomp->dev, "tplg_mask %#lx tplg_num %d\n", tplg_mask, tplg_num);
2533+
2534+
for (i = 0; i < tplg_num; i++) {
2535+
tplg_files[i].file = devm_kasprintf(sdev->dev, GFP_KERNEL,
2536+
"%s/sof-%s-%s-id%d.tplg",
2537+
sof_pdata->tplg_filename_prefix, platform,
2538+
tplg_files[i].device,
2539+
tplg_files[i].be_id);
2540+
ret = request_firmware(&fw, tplg_files[i].file, scomp->dev);
2541+
dev_dbg(scomp->dev, "Requesting %d %s\n", i, tplg_files[i].file);
2542+
if (ret < 0) {
2543+
dev_warn(scomp->dev, "error: tplg request firmware %s failed err: %d\n",
2544+
tplg_files[i].file, ret);
2545+
dev_warn(scomp->dev,"Fail back to the default topology\n");
2546+
goto legacy_tplg;
2547+
}
2548+
/* set complete = sof_complete if it is the last topology */
2549+
if (!load_default_tplg && i == tplg_num - 1)
2550+
sof_tplg_ops.complete = sof_complete;
2551+
if (sdev->dspless_mode_selected)
2552+
ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
2553+
else
2554+
ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
2555+
2556+
if (ret < 0) {
2557+
dev_err(scomp->dev, "error: tplg component load failed %d\n",
2558+
ret);
2559+
release_firmware(fw);
2560+
return -EINVAL;
2561+
}
2562+
2563+
release_firmware(fw);
2564+
}
2565+
/* Load topology successfully, goto out */
2566+
if (!load_default_tplg)
2567+
goto out;
2568+
2569+
legacy_tplg:
24672570
ret = request_firmware(&fw, file, scomp->dev);
24682571
if (ret < 0) {
24692572
dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n",
@@ -2473,6 +2576,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24732576
return ret;
24742577
}
24752578

2579+
sof_tplg_ops.complete = sof_complete;
24762580
if (sdev->dspless_mode_selected)
24772581
ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
24782582
else
@@ -2486,6 +2590,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24862590

24872591
release_firmware(fw);
24882592

2593+
out:
24892594
if (ret >= 0 && sdev->led_present)
24902595
ret = snd_ctl_led_request();
24912596

0 commit comments

Comments
 (0)