1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2023 Intel Corporation. All rights reserved.
4 
5 #include <linux/device.h>
6 #include <sound/soc-acpi.h>
7 #include "sof_ssp_common.h"
8 
9 /*
10  * Codec probe function
11  */
12 #define CODEC_MAP_ENTRY(n, h, t)	\
13 	{				\
14 		.name = n,		\
15 		.acpi_hid = h,		\
16 		.codec_type = t,	\
17 	}
18 
19 struct codec_map {
20 	const char *name;
21 	const char *acpi_hid;
22 	enum sof_ssp_codec codec_type;
23 };
24 
25 static const struct codec_map codecs[] = {
26 	/* Cirrus Logic */
27 	CODEC_MAP_ENTRY("CS42L42", CS42L42_ACPI_HID, CODEC_CS42L42),
28 
29 	/* Dialog */
30 	CODEC_MAP_ENTRY("DA7219", DA7219_ACPI_HID, CODEC_DA7219),
31 
32 	/* Everest */
33 	CODEC_MAP_ENTRY("ES8316", ES8316_ACPI_HID, CODEC_ES8316),
34 	CODEC_MAP_ENTRY("ES8326", ES8326_ACPI_HID, CODEC_ES8326),
35 	CODEC_MAP_ENTRY("ES8336", ES8336_ACPI_HID, CODEC_ES8336),
36 
37 	/* Nuvoton */
38 	CODEC_MAP_ENTRY("NAU8825", NAU8825_ACPI_HID, CODEC_NAU8825),
39 
40 	/* Realtek */
41 	CODEC_MAP_ENTRY("RT5650", RT5650_ACPI_HID, CODEC_RT5650),
42 	CODEC_MAP_ENTRY("RT5682", RT5682_ACPI_HID, CODEC_RT5682),
43 	CODEC_MAP_ENTRY("RT5682S", RT5682S_ACPI_HID, CODEC_RT5682S),
44 };
45 
46 static const struct codec_map amps[] = {
47 	/* Cirrus Logic */
48 	CODEC_MAP_ENTRY("CS35L41", CS35L41_ACPI_HID, CODEC_CS35L41),
49 
50 	/* Maxim */
51 	CODEC_MAP_ENTRY("MAX98357A", MAX_98357A_ACPI_HID, CODEC_MAX98357A),
52 	CODEC_MAP_ENTRY("MAX98360A", MAX_98360A_ACPI_HID, CODEC_MAX98360A),
53 	CODEC_MAP_ENTRY("MAX98373", MAX_98373_ACPI_HID, CODEC_MAX98373),
54 	CODEC_MAP_ENTRY("MAX98390", MAX_98390_ACPI_HID, CODEC_MAX98390),
55 
56 	/* Nuvoton */
57 	CODEC_MAP_ENTRY("NAU8318", NAU8318_ACPI_HID, CODEC_NAU8318),
58 
59 	/* Realtek */
60 	CODEC_MAP_ENTRY("RT1011", RT1011_ACPI_HID, CODEC_RT1011),
61 	CODEC_MAP_ENTRY("RT1015", RT1015_ACPI_HID, CODEC_RT1015),
62 	CODEC_MAP_ENTRY("RT1015P", RT1015P_ACPI_HID, CODEC_RT1015P),
63 	CODEC_MAP_ENTRY("RT1019P", RT1019P_ACPI_HID, CODEC_RT1019P),
64 	CODEC_MAP_ENTRY("RT1308", RT1308_ACPI_HID, CODEC_RT1308),
65 };
66 
sof_ssp_detect_codec_type(struct device * dev)67 enum sof_ssp_codec sof_ssp_detect_codec_type(struct device *dev)
68 {
69 	int i;
70 
71 	for (i = 0; i < ARRAY_SIZE(codecs); i++) {
72 		if (!acpi_dev_present(codecs[i].acpi_hid, NULL, -1))
73 			continue;
74 
75 		dev_dbg(dev, "codec %s found\n", codecs[i].name);
76 		return codecs[i].codec_type;
77 	}
78 
79 	return CODEC_NONE;
80 }
81 EXPORT_SYMBOL_NS(sof_ssp_detect_codec_type, SND_SOC_INTEL_SOF_SSP_COMMON);
82 
sof_ssp_detect_amp_type(struct device * dev)83 enum sof_ssp_codec sof_ssp_detect_amp_type(struct device *dev)
84 {
85 	int i;
86 
87 	for (i = 0; i < ARRAY_SIZE(amps); i++) {
88 		if (!acpi_dev_present(amps[i].acpi_hid, NULL, -1))
89 			continue;
90 
91 		dev_dbg(dev, "amp %s found\n", amps[i].name);
92 		return amps[i].codec_type;
93 	}
94 
95 	return CODEC_NONE;
96 }
97 EXPORT_SYMBOL_NS(sof_ssp_detect_amp_type, SND_SOC_INTEL_SOF_SSP_COMMON);
98 
sof_ssp_get_codec_name(enum sof_ssp_codec codec_type)99 const char *sof_ssp_get_codec_name(enum sof_ssp_codec codec_type)
100 {
101 	int i;
102 
103 	for (i = 0; i < ARRAY_SIZE(codecs); i++) {
104 		if (codecs[i].codec_type != codec_type)
105 			continue;
106 
107 		return codecs[i].name;
108 	}
109 	for (i = 0; i < ARRAY_SIZE(amps); i++) {
110 		if (amps[i].codec_type != codec_type)
111 			continue;
112 
113 		return amps[i].name;
114 	}
115 
116 	return NULL;
117 }
118 EXPORT_SYMBOL_NS(sof_ssp_get_codec_name, SND_SOC_INTEL_SOF_SSP_COMMON);
119 
120 MODULE_DESCRIPTION("ASoC Intel SOF Common Machine Driver Helpers");
121 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
122 MODULE_LICENSE("GPL");
123