Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/intel/common/sof-function-topology-lib.c
49628 views
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
#include <linux/device.h>
10
#include <linux/errno.h>
11
#include <linux/firmware.h>
12
#include <sound/soc.h>
13
#include <sound/soc-acpi.h>
14
#include "sof-function-topology-lib.h"
15
16
enum tplg_device_id {
17
TPLG_DEVICE_SDCA_JACK,
18
TPLG_DEVICE_SDCA_AMP,
19
TPLG_DEVICE_SDCA_MIC,
20
TPLG_DEVICE_INTEL_PCH_DMIC,
21
TPLG_DEVICE_HDMI,
22
TPLG_DEVICE_MAX
23
};
24
25
#define SDCA_DEVICE_MASK (BIT(TPLG_DEVICE_SDCA_JACK) | BIT(TPLG_DEVICE_SDCA_AMP) | \
26
BIT(TPLG_DEVICE_SDCA_MIC))
27
28
#define SOF_INTEL_PLATFORM_NAME_MAX 4
29
30
int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach,
31
const char *prefix, const char ***tplg_files, bool best_effort)
32
{
33
struct snd_soc_acpi_mach_params mach_params = mach->mach_params;
34
struct snd_soc_dai_link *dai_link;
35
const struct firmware *fw;
36
char platform[SOF_INTEL_PLATFORM_NAME_MAX];
37
unsigned long tplg_mask = 0;
38
int tplg_num = 0;
39
int tplg_dev;
40
int ret;
41
int i;
42
43
ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform);
44
if (ret != 1) {
45
dev_err(card->dev, "Invalid platform name %s of tplg %s\n",
46
platform, mach->sof_tplg_filename);
47
return -EINVAL;
48
}
49
50
for_each_card_prelinks(card, i, dai_link) {
51
char *tplg_dev_name;
52
53
dev_dbg(card->dev, "dai_link %s id %d\n", dai_link->name, dai_link->id);
54
if (strstr(dai_link->name, "SimpleJack")) {
55
tplg_dev = TPLG_DEVICE_SDCA_JACK;
56
tplg_dev_name = "sdca-jack";
57
} else if (strstr(dai_link->name, "SmartAmp")) {
58
tplg_dev = TPLG_DEVICE_SDCA_AMP;
59
tplg_dev_name = devm_kasprintf(card->dev, GFP_KERNEL,
60
"sdca-%damp", dai_link->num_cpus);
61
if (!tplg_dev_name)
62
return -ENOMEM;
63
} else if (strstr(dai_link->name, "SmartMic")) {
64
tplg_dev = TPLG_DEVICE_SDCA_MIC;
65
tplg_dev_name = "sdca-mic";
66
} else if (strstr(dai_link->name, "dmic")) {
67
switch (mach_params.dmic_num) {
68
case 2:
69
tplg_dev_name = "dmic-2ch";
70
break;
71
case 4:
72
tplg_dev_name = "dmic-4ch";
73
break;
74
default:
75
dev_warn(card->dev,
76
"unsupported number of dmics: %d\n",
77
mach_params.dmic_num);
78
continue;
79
}
80
tplg_dev = TPLG_DEVICE_INTEL_PCH_DMIC;
81
} else if (strstr(dai_link->name, "iDisp")) {
82
tplg_dev = TPLG_DEVICE_HDMI;
83
tplg_dev_name = "hdmi-pcm5";
84
85
} else {
86
/* The dai link is not supported by separated tplg yet */
87
dev_dbg(card->dev,
88
"dai_link %s is not supported by separated tplg yet\n",
89
dai_link->name);
90
if (best_effort)
91
continue;
92
93
return 0;
94
}
95
if (tplg_mask & BIT(tplg_dev))
96
continue;
97
98
tplg_mask |= BIT(tplg_dev);
99
100
/*
101
* The tplg file naming rule is sof-<platform>-<function>-id<BE id number>.tplg
102
* where <platform> is only required for the DMIC function as the nhlt blob
103
* is platform dependent.
104
*/
105
switch (tplg_dev) {
106
case TPLG_DEVICE_INTEL_PCH_DMIC:
107
(*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
108
"%s/sof-%s-%s-id%d.tplg",
109
prefix, platform,
110
tplg_dev_name, dai_link->id);
111
break;
112
default:
113
(*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
114
"%s/sof-%s-id%d.tplg",
115
prefix, tplg_dev_name,
116
dai_link->id);
117
break;
118
}
119
if (!(*tplg_files)[tplg_num])
120
return -ENOMEM;
121
tplg_num++;
122
}
123
124
dev_dbg(card->dev, "tplg_mask %#lx tplg_num %d\n", tplg_mask, tplg_num);
125
126
/* Check presence of sub-topologies */
127
for (i = 0; i < tplg_num; i++) {
128
ret = firmware_request_nowarn(&fw, (*tplg_files)[i], card->dev);
129
if (!ret) {
130
release_firmware(fw);
131
} else {
132
dev_warn(card->dev,
133
"Failed to open topology file: %s, you might need to\n",
134
(*tplg_files)[i]);
135
dev_warn(card->dev,
136
"download it from https://github.com/thesofproject/sof-bin/\n");
137
return 0;
138
}
139
}
140
141
return tplg_num;
142
}
143
EXPORT_SYMBOL_GPL(sof_sdw_get_tplg_files);
144
145