Linux Audio

Check our new training course

Open-source upstreaming

Need help get the support for your hardware in upstream Linux?
Loading...
Note: File does not exist in v6.9.4.
  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
 20struct 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
 27static 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
 48static 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	 * Monolithic components
 70	 *
 71	 * Only put components that can serve as both the amp and the codec below this line.
 72	 * This will ensure that if the part is used just as a codec and there is an amp as well
 73	 * then the amp will be selected properly.
 74	 */
 75	CODEC_MAP_ENTRY("RT5650", "rt5650", RT5650_ACPI_HID, CODEC_RT5650),
 76};
 77
 78enum snd_soc_acpi_intel_codec
 79snd_soc_acpi_intel_detect_codec_type(struct device *dev)
 80{
 81	int i;
 82
 83	for (i = 0; i < ARRAY_SIZE(codecs); i++) {
 84		if (!acpi_dev_present(codecs[i].acpi_hid, NULL, -1))
 85			continue;
 86
 87		dev_dbg(dev, "codec %s found\n", codecs[i].name);
 88		return codecs[i].codec_type;
 89	}
 90
 91	return CODEC_NONE;
 92}
 93EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_codec_type, "SND_SOC_ACPI_INTEL_MATCH");
 94
 95enum snd_soc_acpi_intel_codec
 96snd_soc_acpi_intel_detect_amp_type(struct device *dev)
 97{
 98	int i;
 99
100	for (i = 0; i < ARRAY_SIZE(amps); i++) {
101		if (!acpi_dev_present(amps[i].acpi_hid, NULL, -1))
102			continue;
103
104		dev_dbg(dev, "amp %s found\n", amps[i].name);
105		return amps[i].codec_type;
106	}
107
108	return CODEC_NONE;
109}
110EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_amp_type, "SND_SOC_ACPI_INTEL_MATCH");
111
112const char *
113snd_soc_acpi_intel_get_codec_name(enum snd_soc_acpi_intel_codec codec_type)
114{
115	int i;
116
117	for (i = 0; i < ARRAY_SIZE(codecs); i++) {
118		if (codecs[i].codec_type != codec_type)
119			continue;
120
121		return codecs[i].name;
122	}
123	for (i = 0; i < ARRAY_SIZE(amps); i++) {
124		if (amps[i].codec_type != codec_type)
125			continue;
126
127		return amps[i].name;
128	}
129
130	return NULL;
131}
132EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_name, "SND_SOC_ACPI_INTEL_MATCH");
133
134const char *
135snd_soc_acpi_intel_get_codec_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type)
136{
137	int i;
138
139	for (i = 0; i < ARRAY_SIZE(codecs); i++) {
140		if (codecs[i].codec_type != codec_type)
141			continue;
142
143		return codecs[i].tplg_suffix;
144	}
145
146	return NULL;
147}
148EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_tplg_suffix, "SND_SOC_ACPI_INTEL_MATCH");
149
150const char *
151snd_soc_acpi_intel_get_amp_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type)
152{
153	int i;
154
155	for (i = 0; i < ARRAY_SIZE(amps); i++) {
156		if (amps[i].codec_type != codec_type)
157			continue;
158
159		return amps[i].tplg_suffix;
160	}
161
162	return NULL;
163}
164EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_amp_tplg_suffix, "SND_SOC_ACPI_INTEL_MATCH");
165
166MODULE_DESCRIPTION("ASoC Intel SOF Common Machine Driver Helpers");
167MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
168MODULE_LICENSE("GPL");