xref: /linux/sound/soc/intel/common/soc-acpi-intel-ssp-common.c (revision 001821b0e79716c4e17c71d8e053a23599a7a508)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2023 Intel Corporation
4 
5 #include <linux/device.h>
6 #include <sound/soc-acpi.h>
7 #include <sound/soc-acpi-intel-ssp-common.h>
8 
9 /*
10  * Codec probe function
11  */
12 #define CODEC_MAP_ENTRY(n, s, h, t)	\
13 	{				\
14 		.name = n,		\
15 		.tplg_suffix = s,	\
16 		.acpi_hid = h,		\
17 		.codec_type = t,	\
18 	}
19 
20 struct codec_map {
21 	const char *name;
22 	const char *tplg_suffix;
23 	const char *acpi_hid;
24 	enum snd_soc_acpi_intel_codec codec_type;
25 };
26 
27 static const struct codec_map codecs[] = {
28 	/* Cirrus Logic */
29 	CODEC_MAP_ENTRY("CS42L42", "cs42l42", CS42L42_ACPI_HID, CODEC_CS42L42),
30 
31 	/* Dialog */
32 	CODEC_MAP_ENTRY("DA7219", "da7219", DA7219_ACPI_HID, CODEC_DA7219),
33 
34 	/* Everest */
35 	CODEC_MAP_ENTRY("ES8316", "es8336", ES8316_ACPI_HID, CODEC_ES8316),
36 	CODEC_MAP_ENTRY("ES8326", "es8336", ES8326_ACPI_HID, CODEC_ES8326),
37 	CODEC_MAP_ENTRY("ES8336", "es8336", ES8336_ACPI_HID, CODEC_ES8336),
38 
39 	/* Nuvoton */
40 	CODEC_MAP_ENTRY("NAU8825", "nau8825", NAU8825_ACPI_HID, CODEC_NAU8825),
41 
42 	/* Realtek */
43 	CODEC_MAP_ENTRY("RT5650", "rt5650", RT5650_ACPI_HID, CODEC_RT5650),
44 	CODEC_MAP_ENTRY("RT5682", "rt5682", RT5682_ACPI_HID, CODEC_RT5682),
45 	CODEC_MAP_ENTRY("RT5682S", "rt5682", RT5682S_ACPI_HID, CODEC_RT5682S),
46 };
47 
48 static const struct codec_map amps[] = {
49 	/* Cirrus Logic */
50 	CODEC_MAP_ENTRY("CS35L41", "cs35l41", CS35L41_ACPI_HID, CODEC_CS35L41),
51 
52 	/* Maxim */
53 	CODEC_MAP_ENTRY("MAX98357A", "max98357a", MAX_98357A_ACPI_HID, CODEC_MAX98357A),
54 	CODEC_MAP_ENTRY("MAX98360A", "max98360a", MAX_98360A_ACPI_HID, CODEC_MAX98360A),
55 	CODEC_MAP_ENTRY("MAX98373", "max98373", MAX_98373_ACPI_HID, CODEC_MAX98373),
56 	CODEC_MAP_ENTRY("MAX98390", "max98390", MAX_98390_ACPI_HID, CODEC_MAX98390),
57 
58 	/* Nuvoton */
59 	CODEC_MAP_ENTRY("NAU8318", "nau8318", NAU8318_ACPI_HID, CODEC_NAU8318),
60 
61 	/* Realtek */
62 	CODEC_MAP_ENTRY("RT1011", "rt1011", RT1011_ACPI_HID, CODEC_RT1011),
63 	CODEC_MAP_ENTRY("RT1015", "rt1015", RT1015_ACPI_HID, CODEC_RT1015),
64 	CODEC_MAP_ENTRY("RT1015P", "rt1015", RT1015P_ACPI_HID, CODEC_RT1015P),
65 	CODEC_MAP_ENTRY("RT1019P", "rt1019", RT1019P_ACPI_HID, CODEC_RT1019P),
66 	CODEC_MAP_ENTRY("RT1308", "rt1308", RT1308_ACPI_HID, CODEC_RT1308),
67 };
68 
69 enum snd_soc_acpi_intel_codec
70 snd_soc_acpi_intel_detect_codec_type(struct device *dev)
71 {
72 	int i;
73 
74 	for (i = 0; i < ARRAY_SIZE(codecs); i++) {
75 		if (!acpi_dev_present(codecs[i].acpi_hid, NULL, -1))
76 			continue;
77 
78 		dev_dbg(dev, "codec %s found\n", codecs[i].name);
79 		return codecs[i].codec_type;
80 	}
81 
82 	return CODEC_NONE;
83 }
84 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_codec_type, SND_SOC_ACPI_INTEL_MATCH);
85 
86 enum snd_soc_acpi_intel_codec
87 snd_soc_acpi_intel_detect_amp_type(struct device *dev)
88 {
89 	int i;
90 
91 	for (i = 0; i < ARRAY_SIZE(amps); i++) {
92 		if (!acpi_dev_present(amps[i].acpi_hid, NULL, -1))
93 			continue;
94 
95 		dev_dbg(dev, "amp %s found\n", amps[i].name);
96 		return amps[i].codec_type;
97 	}
98 
99 	return CODEC_NONE;
100 }
101 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_amp_type, SND_SOC_ACPI_INTEL_MATCH);
102 
103 const char *
104 snd_soc_acpi_intel_get_codec_name(enum snd_soc_acpi_intel_codec codec_type)
105 {
106 	int i;
107 
108 	for (i = 0; i < ARRAY_SIZE(codecs); i++) {
109 		if (codecs[i].codec_type != codec_type)
110 			continue;
111 
112 		return codecs[i].name;
113 	}
114 	for (i = 0; i < ARRAY_SIZE(amps); i++) {
115 		if (amps[i].codec_type != codec_type)
116 			continue;
117 
118 		return amps[i].name;
119 	}
120 
121 	return NULL;
122 }
123 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_name, SND_SOC_ACPI_INTEL_MATCH);
124 
125 const char *
126 snd_soc_acpi_intel_get_codec_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type)
127 {
128 	int i;
129 
130 	for (i = 0; i < ARRAY_SIZE(codecs); i++) {
131 		if (codecs[i].codec_type != codec_type)
132 			continue;
133 
134 		return codecs[i].tplg_suffix;
135 	}
136 
137 	return NULL;
138 }
139 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_tplg_suffix, SND_SOC_ACPI_INTEL_MATCH);
140 
141 const char *
142 snd_soc_acpi_intel_get_amp_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type)
143 {
144 	int i;
145 
146 	for (i = 0; i < ARRAY_SIZE(amps); i++) {
147 		if (amps[i].codec_type != codec_type)
148 			continue;
149 
150 		return amps[i].tplg_suffix;
151 	}
152 
153 	return NULL;
154 }
155 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_amp_tplg_suffix, SND_SOC_ACPI_INTEL_MATCH);
156 
157 MODULE_DESCRIPTION("ASoC Intel SOF Common Machine Driver Helpers");
158 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
159 MODULE_LICENSE("GPL");
160