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 * 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 78 enum snd_soc_acpi_intel_codec 79 snd_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 } 93 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_codec_type, SND_SOC_ACPI_INTEL_MATCH); 94 95 enum snd_soc_acpi_intel_codec 96 snd_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 } 110 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_amp_type, SND_SOC_ACPI_INTEL_MATCH); 111 112 const char * 113 snd_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 } 132 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_name, SND_SOC_ACPI_INTEL_MATCH); 133 134 const char * 135 snd_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 } 148 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_tplg_suffix, SND_SOC_ACPI_INTEL_MATCH); 149 150 const char * 151 snd_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 } 164 EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_amp_tplg_suffix, SND_SOC_ACPI_INTEL_MATCH); 165 166 MODULE_DESCRIPTION("ASoC Intel SOF Common Machine Driver Helpers"); 167 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); 168 MODULE_LICENSE("GPL"); 169