Commit | Line | Data |
---|---|---|
82d9d54a JK |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz> | |
3 | ||
06508575 | 4 | #include <linux/acpi.h> |
82d9d54a JK |
5 | #include <linux/bits.h> |
6 | #include <linux/dmi.h> | |
7 | #include <linux/module.h> | |
8 | #include <linux/pci.h> | |
06508575 PLB |
9 | #include <linux/soundwire/sdw.h> |
10 | #include <linux/soundwire/sdw_intel.h> | |
82d9d54a JK |
11 | #include <sound/core.h> |
12 | #include <sound/intel-dsp-config.h> | |
13 | #include <sound/intel-nhlt.h> | |
de24d97f | 14 | #include <sound/soc-acpi.h> |
82d9d54a | 15 | |
51bebf34 AS |
16 | #include <acpi/nhlt.h> |
17 | ||
82d9d54a JK |
18 | static int dsp_driver; |
19 | ||
20 | module_param(dsp_driver, int, 0444); | |
2646b439 | 21 | MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF, 4=AVS)"); |
82d9d54a | 22 | |
06508575 PLB |
23 | #define FLAG_SST BIT(0) |
24 | #define FLAG_SOF BIT(1) | |
df1fceac | 25 | #define FLAG_SST_ONLY_IF_DMIC BIT(15) |
06508575 PLB |
26 | #define FLAG_SOF_ONLY_IF_DMIC BIT(16) |
27 | #define FLAG_SOF_ONLY_IF_SOUNDWIRE BIT(17) | |
28 | ||
29 | #define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \ | |
30 | FLAG_SOF_ONLY_IF_SOUNDWIRE) | |
82d9d54a JK |
31 | |
32 | struct config_entry { | |
33 | u32 flags; | |
34 | u16 device; | |
b5682305 | 35 | u8 acpi_hid[ACPI_ID_LEN]; |
82d9d54a | 36 | const struct dmi_system_id *dmi_table; |
de24d97f PLB |
37 | const struct snd_soc_acpi_codecs *codec_hid; |
38 | }; | |
39 | ||
40 | static const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = { | |
41 | .num_codecs = 3, | |
42 | .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, | |
82d9d54a JK |
43 | }; |
44 | ||
45 | /* | |
46 | * configuration table | |
47 | * - the order of similar PCI ID entries is important! | |
48 | * - the first successful match will win | |
49 | */ | |
50 | static const struct config_entry config_table[] = { | |
cc8f81c7 PLB |
51 | /* Merrifield */ |
52 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) | |
82d9d54a | 53 | { |
cc8f81c7 | 54 | .flags = FLAG_SOF, |
0cd0a7c2 | 55 | .device = PCI_DEVICE_ID_INTEL_SST_TNG, |
82d9d54a | 56 | }, |
cc8f81c7 | 57 | #endif |
cc8f81c7 | 58 | /* |
ec7bccd7 | 59 | * Skylake, Kabylake, Apollolake |
b79de57b | 60 | * the legacy HDAudio driver is used except on Up Squared (SOF) and |
9d36ceab | 61 | * Chromebooks (SST), as well as devices based on the ES8336 codec |
cc8f81c7 | 62 | */ |
ec7bccd7 | 63 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_AVS) |
82d9d54a | 64 | { |
ec7bccd7 CR |
65 | .flags = FLAG_SST, |
66 | .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP, | |
cc8f81c7 PLB |
67 | .dmi_table = (const struct dmi_system_id []) { |
68 | { | |
ec7bccd7 | 69 | .ident = "Google Chromebooks", |
cc8f81c7 | 70 | .matches = { |
ec7bccd7 | 71 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), |
cc8f81c7 PLB |
72 | } |
73 | }, | |
74 | {} | |
75 | } | |
82d9d54a | 76 | }, |
9d36ceab | 77 | { |
ec7bccd7 CR |
78 | .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, |
79 | .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP, | |
9d36ceab | 80 | }, |
82d9d54a | 81 | { |
cc8f81c7 | 82 | .flags = FLAG_SST, |
ec7bccd7 | 83 | .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP, |
cc8f81c7 PLB |
84 | .dmi_table = (const struct dmi_system_id []) { |
85 | { | |
86 | .ident = "Google Chromebooks", | |
87 | .matches = { | |
88 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
89 | } | |
90 | }, | |
91 | {} | |
92 | } | |
82d9d54a | 93 | }, |
ec7bccd7 CR |
94 | { |
95 | .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, | |
96 | .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP, | |
97 | }, | |
82d9d54a | 98 | { |
cc8f81c7 | 99 | .flags = FLAG_SST, |
ec7bccd7 | 100 | .device = PCI_DEVICE_ID_INTEL_HDA_APL, |
cc8f81c7 PLB |
101 | .dmi_table = (const struct dmi_system_id []) { |
102 | { | |
103 | .ident = "Google Chromebooks", | |
104 | .matches = { | |
105 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
106 | } | |
107 | }, | |
108 | {} | |
109 | } | |
82d9d54a | 110 | }, |
856366dc CR |
111 | { |
112 | .flags = FLAG_SST, | |
113 | .device = PCI_DEVICE_ID_INTEL_HDA_RPL_M, | |
114 | }, | |
387ddbc7 CR |
115 | { |
116 | .flags = FLAG_SST, | |
117 | .device = PCI_DEVICE_ID_INTEL_HDA_FCL, | |
118 | }, | |
82d9d54a | 119 | #endif |
ec7bccd7 | 120 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) |
82d9d54a | 121 | { |
ec7bccd7 CR |
122 | .flags = FLAG_SOF, |
123 | .device = PCI_DEVICE_ID_INTEL_HDA_APL, | |
cc8f81c7 PLB |
124 | .dmi_table = (const struct dmi_system_id []) { |
125 | { | |
ec7bccd7 | 126 | .ident = "Up Squared", |
cc8f81c7 | 127 | .matches = { |
ec7bccd7 CR |
128 | DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), |
129 | DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"), | |
cc8f81c7 PLB |
130 | } |
131 | }, | |
132 | {} | |
133 | } | |
82d9d54a | 134 | }, |
df1fceac | 135 | { |
ec7bccd7 CR |
136 | .flags = FLAG_SOF, |
137 | .device = PCI_DEVICE_ID_INTEL_HDA_APL, | |
138 | .codec_hid = &essx_83x6, | |
df1fceac | 139 | }, |
82d9d54a | 140 | #endif |
cc8f81c7 PLB |
141 | |
142 | /* | |
b79de57b | 143 | * Geminilake uses legacy HDAudio driver except for Google |
9d36ceab | 144 | * Chromebooks and devices based on the ES8336 codec |
cc8f81c7 | 145 | */ |
82d9d54a JK |
146 | /* Geminilake */ |
147 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE) | |
148 | { | |
149 | .flags = FLAG_SOF, | |
0cd0a7c2 | 150 | .device = PCI_DEVICE_ID_INTEL_HDA_GML, |
82d9d54a JK |
151 | .dmi_table = (const struct dmi_system_id []) { |
152 | { | |
153 | .ident = "Google Chromebooks", | |
154 | .matches = { | |
155 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
156 | } | |
157 | }, | |
158 | {} | |
159 | } | |
160 | }, | |
9d36ceab PLB |
161 | { |
162 | .flags = FLAG_SOF, | |
0cd0a7c2 | 163 | .device = PCI_DEVICE_ID_INTEL_HDA_GML, |
de24d97f | 164 | .codec_hid = &essx_83x6, |
9d36ceab | 165 | }, |
82d9d54a | 166 | #endif |
cc8f81c7 PLB |
167 | |
168 | /* | |
905240d1 BN |
169 | * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake, AlderLake, |
170 | * RaptorLake use legacy HDAudio driver except for Google Chromebooks | |
171 | * and when DMICs are present. Two cases are required since Coreboot | |
172 | * does not expose NHLT tables. | |
cc8f81c7 PLB |
173 | * |
174 | * When the Chromebook quirk is not present, it's based on information | |
175 | * that no such device exists. When the quirk is present, it could be | |
176 | * either based on product information or a placeholder. | |
177 | */ | |
178 | ||
179 | /* Cannonlake */ | |
180 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE) | |
82d9d54a | 181 | { |
cc8f81c7 | 182 | .flags = FLAG_SOF, |
0cd0a7c2 | 183 | .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP, |
cc8f81c7 PLB |
184 | .dmi_table = (const struct dmi_system_id []) { |
185 | { | |
186 | .ident = "Google Chromebooks", | |
187 | .matches = { | |
188 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
189 | } | |
190 | }, | |
33fa35db PLB |
191 | { |
192 | .ident = "UP-WHL", | |
193 | .matches = { | |
194 | DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), | |
195 | } | |
196 | }, | |
cc8f81c7 PLB |
197 | {} |
198 | } | |
82d9d54a | 199 | }, |
cded07a2 PLB |
200 | { |
201 | .flags = FLAG_SOF, | |
0cd0a7c2 | 202 | .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP, |
cded07a2 PLB |
203 | .codec_hid = &essx_83x6, |
204 | }, | |
82d9d54a | 205 | { |
06508575 | 206 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
0cd0a7c2 | 207 | .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP, |
82d9d54a JK |
208 | }, |
209 | #endif | |
cc8f81c7 PLB |
210 | |
211 | /* Coffelake */ | |
212 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE) | |
213 | { | |
214 | .flags = FLAG_SOF, | |
0cd0a7c2 | 215 | .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H, |
cc8f81c7 PLB |
216 | .dmi_table = (const struct dmi_system_id []) { |
217 | { | |
218 | .ident = "Google Chromebooks", | |
219 | .matches = { | |
220 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
221 | } | |
222 | }, | |
223 | {} | |
224 | } | |
225 | }, | |
82d9d54a | 226 | { |
06508575 | 227 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
0cd0a7c2 | 228 | .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H, |
82d9d54a JK |
229 | }, |
230 | #endif | |
cc8f81c7 | 231 | |
4228668e | 232 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE) |
cc8f81c7 | 233 | /* Cometlake-LP */ |
82d9d54a JK |
234 | { |
235 | .flags = FLAG_SOF, | |
0cd0a7c2 | 236 | .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP, |
82d9d54a JK |
237 | .dmi_table = (const struct dmi_system_id []) { |
238 | { | |
cc8f81c7 | 239 | .ident = "Google Chromebooks", |
82d9d54a | 240 | .matches = { |
cc8f81c7 | 241 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), |
82d9d54a JK |
242 | } |
243 | }, | |
06508575 PLB |
244 | { |
245 | .matches = { | |
246 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
247 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6") | |
248 | }, | |
249 | }, | |
250 | { | |
251 | /* early version of SKU 09C6 */ | |
252 | .matches = { | |
253 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
254 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983") | |
255 | }, | |
256 | }, | |
82d9d54a JK |
257 | {} |
258 | } | |
259 | }, | |
82d9d54a | 260 | { |
081c7370 | 261 | .flags = FLAG_SOF, |
0cd0a7c2 | 262 | .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP, |
de24d97f | 263 | .codec_hid = &essx_83x6, |
82d9d54a | 264 | }, |
ae26c08e | 265 | { |
081c7370 | 266 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
0cd0a7c2 | 267 | .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP, |
ae26c08e | 268 | }, |
cc8f81c7 | 269 | /* Cometlake-H */ |
82d9d54a | 270 | { |
06508575 | 271 | .flags = FLAG_SOF, |
0cd0a7c2 | 272 | .device = PCI_DEVICE_ID_INTEL_HDA_CML_H, |
06508575 PLB |
273 | .dmi_table = (const struct dmi_system_id []) { |
274 | { | |
275 | .matches = { | |
276 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
277 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"), | |
278 | }, | |
279 | }, | |
280 | { | |
281 | .matches = { | |
282 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
283 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"), | |
284 | }, | |
285 | }, | |
286 | {} | |
287 | } | |
288 | }, | |
289 | { | |
ae26c08e | 290 | .flags = FLAG_SOF, |
0cd0a7c2 | 291 | .device = PCI_DEVICE_ID_INTEL_HDA_CML_H, |
de24d97f | 292 | .codec_hid = &essx_83x6, |
ae26c08e | 293 | }, |
081c7370 BL |
294 | { |
295 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 296 | .device = PCI_DEVICE_ID_INTEL_HDA_CML_H, |
081c7370 | 297 | }, |
82d9d54a | 298 | #endif |
cc8f81c7 PLB |
299 | |
300 | /* Icelake */ | |
301 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) | |
82d9d54a | 302 | { |
cc8f81c7 | 303 | .flags = FLAG_SOF, |
0cd0a7c2 | 304 | .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP, |
cc8f81c7 PLB |
305 | .dmi_table = (const struct dmi_system_id []) { |
306 | { | |
307 | .ident = "Google Chromebooks", | |
308 | .matches = { | |
309 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
310 | } | |
311 | }, | |
312 | {} | |
313 | } | |
82d9d54a | 314 | }, |
5d73263f PLB |
315 | { |
316 | .flags = FLAG_SOF, | |
0cd0a7c2 | 317 | .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP, |
5d73263f PLB |
318 | .codec_hid = &essx_83x6, |
319 | }, | |
82d9d54a | 320 | { |
06508575 | 321 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
0cd0a7c2 | 322 | .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP, |
82d9d54a JK |
323 | }, |
324 | #endif | |
cc8f81c7 | 325 | |
19980aa1 | 326 | /* Jasper Lake */ |
fa9730b4 | 327 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE) |
19980aa1 BL |
328 | { |
329 | .flags = FLAG_SOF, | |
0cd0a7c2 | 330 | .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N, |
19980aa1 BL |
331 | .dmi_table = (const struct dmi_system_id []) { |
332 | { | |
333 | .ident = "Google Chromebooks", | |
334 | .matches = { | |
335 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
336 | } | |
337 | }, | |
7c05b44e MH |
338 | { |
339 | .ident = "Google firmware", | |
340 | .matches = { | |
341 | DMI_MATCH(DMI_BIOS_VERSION, "Google"), | |
342 | } | |
343 | }, | |
19980aa1 BL |
344 | {} |
345 | } | |
346 | }, | |
fa9730b4 PLB |
347 | { |
348 | .flags = FLAG_SOF, | |
0cd0a7c2 | 349 | .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N, |
de24d97f | 350 | .codec_hid = &essx_83x6, |
fa9730b4 | 351 | }, |
19980aa1 BL |
352 | { |
353 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, | |
0cd0a7c2 | 354 | .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N, |
19980aa1 | 355 | }, |
fa9730b4 PLB |
356 | #endif |
357 | ||
82d9d54a JK |
358 | /* Tigerlake */ |
359 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) | |
cc8f81c7 PLB |
360 | { |
361 | .flags = FLAG_SOF, | |
0cd0a7c2 | 362 | .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP, |
cc8f81c7 PLB |
363 | .dmi_table = (const struct dmi_system_id []) { |
364 | { | |
365 | .ident = "Google Chromebooks", | |
366 | .matches = { | |
367 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
368 | } | |
369 | }, | |
33fa35db PLB |
370 | { |
371 | .ident = "UPX-TGL", | |
372 | .matches = { | |
373 | DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), | |
374 | } | |
375 | }, | |
cc8f81c7 PLB |
376 | {} |
377 | } | |
378 | }, | |
82d9d54a | 379 | { |
081c7370 | 380 | .flags = FLAG_SOF, |
0cd0a7c2 | 381 | .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP, |
de24d97f | 382 | .codec_hid = &essx_83x6, |
82d9d54a | 383 | }, |
c5b5ff60 BL |
384 | { |
385 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 386 | .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP, |
c5b5ff60 | 387 | }, |
9d36ceab | 388 | { |
081c7370 | 389 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
0cd0a7c2 | 390 | .device = PCI_DEVICE_ID_INTEL_HDA_TGL_H, |
9d36ceab | 391 | }, |
82d9d54a | 392 | #endif |
cc8f81c7 PLB |
393 | |
394 | /* Elkhart Lake */ | |
395 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE) | |
82d9d54a JK |
396 | { |
397 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, | |
0cd0a7c2 | 398 | .device = PCI_DEVICE_ID_INTEL_HDA_EHL_0, |
82d9d54a | 399 | }, |
114613f6 PLB |
400 | { |
401 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, | |
0cd0a7c2 | 402 | .device = PCI_DEVICE_ID_INTEL_HDA_EHL_3, |
114613f6 | 403 | }, |
82d9d54a | 404 | #endif |
cc8f81c7 | 405 | |
0cd0a7c2 | 406 | /* Alder Lake / Raptor Lake */ |
c4294d7f KV |
407 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) |
408 | { | |
409 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 410 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_S, |
c4294d7f KV |
411 | }, |
412 | { | |
413 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 414 | .device = PCI_DEVICE_ID_INTEL_HDA_RPL_S, |
c4294d7f | 415 | }, |
905240d1 BN |
416 | { |
417 | .flags = FLAG_SOF, | |
418 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P, | |
419 | .dmi_table = (const struct dmi_system_id []) { | |
420 | { | |
421 | .ident = "Google Chromebooks", | |
422 | .matches = { | |
423 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
424 | } | |
425 | }, | |
426 | {} | |
427 | } | |
428 | }, | |
2ec8b081 MR |
429 | { |
430 | .flags = FLAG_SOF, | |
0cd0a7c2 | 431 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P, |
2ec8b081 MR |
432 | .codec_hid = &essx_83x6, |
433 | }, | |
4ad7935d KV |
434 | { |
435 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 436 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P, |
4ad7935d | 437 | }, |
ca1ece24 KV |
438 | { |
439 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 440 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PX, |
ca1ece24 | 441 | }, |
9db1c9fa MR |
442 | { |
443 | .flags = FLAG_SOF, | |
0cd0a7c2 | 444 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS, |
9db1c9fa MR |
445 | .codec_hid = &essx_83x6, |
446 | }, | |
d52eee98 PLB |
447 | { |
448 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 449 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS, |
d52eee98 | 450 | }, |
d52eee98 PLB |
451 | { |
452 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 453 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_M, |
d52eee98 | 454 | }, |
905240d1 BN |
455 | { |
456 | .flags = FLAG_SOF, | |
457 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N, | |
458 | .dmi_table = (const struct dmi_system_id []) { | |
459 | { | |
460 | .ident = "Google Chromebooks", | |
461 | .matches = { | |
462 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
463 | } | |
464 | }, | |
465 | {} | |
466 | } | |
467 | }, | |
4d5a628d KV |
468 | { |
469 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 470 | .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N, |
4d5a628d | 471 | }, |
905240d1 BN |
472 | { |
473 | .flags = FLAG_SOF, | |
474 | .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0, | |
475 | .dmi_table = (const struct dmi_system_id []) { | |
476 | { | |
477 | .ident = "Google Chromebooks", | |
478 | .matches = { | |
479 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
480 | } | |
481 | }, | |
482 | {} | |
483 | } | |
484 | }, | |
b07908ab GS |
485 | { |
486 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 487 | .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0, |
b07908ab | 488 | }, |
905240d1 BN |
489 | { |
490 | .flags = FLAG_SOF, | |
491 | .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1, | |
492 | .dmi_table = (const struct dmi_system_id []) { | |
493 | { | |
494 | .ident = "Google Chromebooks", | |
495 | .matches = { | |
496 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
497 | } | |
498 | }, | |
499 | {} | |
500 | } | |
501 | }, | |
b07908ab GS |
502 | { |
503 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 504 | .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1, |
b07908ab | 505 | }, |
c35fbea4 PLB |
506 | { |
507 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 508 | .device = PCI_DEVICE_ID_INTEL_HDA_RPL_M, |
c35fbea4 | 509 | }, |
c35fbea4 PLB |
510 | { |
511 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
0cd0a7c2 | 512 | .device = PCI_DEVICE_ID_INTEL_HDA_RPL_PX, |
c35fbea4 | 513 | }, |
c4294d7f KV |
514 | #endif |
515 | ||
bbdf904b BL |
516 | /* Meteor Lake */ |
517 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE) | |
518 | /* Meteorlake-P */ | |
519 | { | |
520 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
73e6ebf6 | 521 | .device = PCI_DEVICE_ID_INTEL_HDA_MTL, |
bbdf904b | 522 | }, |
7a9d6bbe PLB |
523 | /* ArrowLake-S */ |
524 | { | |
525 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
526 | .device = PCI_DEVICE_ID_INTEL_HDA_ARL_S, | |
527 | }, | |
528 | /* ArrowLake */ | |
529 | { | |
530 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
531 | .device = PCI_DEVICE_ID_INTEL_HDA_ARL, | |
532 | }, | |
bbdf904b BL |
533 | #endif |
534 | ||
d2852b8c PLB |
535 | /* Lunar Lake */ |
536 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE) | |
537 | /* Lunarlake-P */ | |
538 | { | |
539 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
540 | .device = PCI_DEVICE_ID_INTEL_HDA_LNL_P, | |
541 | }, | |
542 | #endif | |
19765dbe | 543 | |
3d1a2707 | 544 | /* Panther Lake, Wildcat Lake */ |
19765dbe PLB |
545 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_PANTHERLAKE) |
546 | { | |
547 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
548 | .device = PCI_DEVICE_ID_INTEL_HDA_PTL, | |
549 | }, | |
214e6be2 PLB |
550 | { |
551 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
552 | .device = PCI_DEVICE_ID_INTEL_HDA_PTL_H, | |
553 | }, | |
3d1a2707 PU |
554 | { |
555 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
556 | .device = PCI_DEVICE_ID_INTEL_HDA_WCL, | |
557 | }, | |
214e6be2 | 558 | |
19765dbe PLB |
559 | #endif |
560 | ||
82d9d54a JK |
561 | }; |
562 | ||
563 | static const struct config_entry *snd_intel_dsp_find_config | |
564 | (struct pci_dev *pci, const struct config_entry *table, u32 len) | |
565 | { | |
566 | u16 device; | |
567 | ||
568 | device = pci->device; | |
569 | for (; len > 0; len--, table++) { | |
570 | if (table->device != device) | |
571 | continue; | |
572 | if (table->dmi_table && !dmi_check_system(table->dmi_table)) | |
573 | continue; | |
de24d97f PLB |
574 | if (table->codec_hid) { |
575 | int i; | |
576 | ||
79ac4c14 PLB |
577 | for (i = 0; i < table->codec_hid->num_codecs; i++) { |
578 | struct nhlt_acpi_table *nhlt; | |
579 | bool ssp_found = false; | |
580 | ||
581 | if (!acpi_dev_present(table->codec_hid->codecs[i], NULL, -1)) | |
582 | continue; | |
583 | ||
584 | nhlt = intel_nhlt_init(&pci->dev); | |
585 | if (!nhlt) { | |
586 | dev_warn(&pci->dev, "%s: NHLT table not found, skipped HID %s\n", | |
587 | __func__, table->codec_hid->codecs[i]); | |
588 | continue; | |
589 | } | |
590 | ||
591 | if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_SSP) && | |
592 | intel_nhlt_ssp_endpoint_mask(nhlt, NHLT_DEVICE_I2S)) | |
593 | ssp_found = true; | |
594 | ||
595 | intel_nhlt_free(nhlt); | |
596 | ||
597 | if (ssp_found) | |
de24d97f | 598 | break; |
79ac4c14 PLB |
599 | |
600 | dev_warn(&pci->dev, "%s: no valid SSP found for HID %s, skipped\n", | |
601 | __func__, table->codec_hid->codecs[i]); | |
602 | } | |
de24d97f PLB |
603 | if (i == table->codec_hid->num_codecs) |
604 | continue; | |
605 | } | |
82d9d54a JK |
606 | return table; |
607 | } | |
608 | return NULL; | |
609 | } | |
610 | ||
611 | static int snd_intel_dsp_check_dmic(struct pci_dev *pci) | |
612 | { | |
82d9d54a JK |
613 | int ret = 0; |
614 | ||
51bebf34 AS |
615 | acpi_nhlt_get_gbl_table(); |
616 | ||
617 | if (acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) | |
618 | ret = 1; | |
619 | ||
620 | acpi_nhlt_put_gbl_table(); | |
621 | ||
82d9d54a JK |
622 | return ret; |
623 | } | |
624 | ||
06508575 PLB |
625 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) |
626 | static int snd_intel_dsp_check_soundwire(struct pci_dev *pci) | |
627 | { | |
628 | struct sdw_intel_acpi_info info; | |
629 | acpi_handle handle; | |
630 | int ret; | |
631 | ||
632 | handle = ACPI_HANDLE(&pci->dev); | |
633 | ||
634 | ret = sdw_intel_acpi_scan(handle, &info); | |
635 | if (ret < 0) | |
636 | return ret; | |
637 | ||
638 | return info.link_mask; | |
639 | } | |
640 | #else | |
641 | static int snd_intel_dsp_check_soundwire(struct pci_dev *pci) | |
642 | { | |
643 | return 0; | |
644 | } | |
645 | #endif | |
646 | ||
82d9d54a JK |
647 | int snd_intel_dsp_driver_probe(struct pci_dev *pci) |
648 | { | |
649 | const struct config_entry *cfg; | |
650 | ||
82d9d54a | 651 | /* Intel vendor only */ |
0cd0a7c2 | 652 | if (pci->vendor != PCI_VENDOR_ID_INTEL) |
82d9d54a JK |
653 | return SND_INTEL_DSP_DRIVER_ANY; |
654 | ||
0e5cc221 PLB |
655 | /* |
656 | * Legacy devices don't have a PCI-based DSP and use HDaudio | |
657 | * for HDMI/DP support, ignore kernel parameter | |
658 | */ | |
659 | switch (pci->device) { | |
0cd0a7c2 AS |
660 | case PCI_DEVICE_ID_INTEL_HDA_BDW: |
661 | case PCI_DEVICE_ID_INTEL_HDA_HSW_0: | |
662 | case PCI_DEVICE_ID_INTEL_HDA_HSW_2: | |
663 | case PCI_DEVICE_ID_INTEL_HDA_HSW_3: | |
664 | case PCI_DEVICE_ID_INTEL_HDA_BYT: | |
665 | case PCI_DEVICE_ID_INTEL_HDA_BSW: | |
0e5cc221 PLB |
666 | return SND_INTEL_DSP_DRIVER_ANY; |
667 | } | |
668 | ||
91636a82 TI |
669 | if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) |
670 | return dsp_driver; | |
671 | ||
82d9d54a JK |
672 | /* |
673 | * detect DSP by checking class/subclass/prog-id information | |
674 | * class=04 subclass 03 prog-if 00: no DSP, use legacy driver | |
675 | * class=04 subclass 01 prog-if 00: DSP is present | |
676 | * (and may be required e.g. for DMIC or SSP support) | |
677 | * class=04 subclass 03 prog-if 80: use DSP or legacy mode | |
678 | */ | |
679 | if (pci->class == 0x040300) | |
680 | return SND_INTEL_DSP_DRIVER_LEGACY; | |
681 | if (pci->class != 0x040100 && pci->class != 0x040380) { | |
b79de57b | 682 | dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class); |
82d9d54a JK |
683 | return SND_INTEL_DSP_DRIVER_LEGACY; |
684 | } | |
685 | ||
e662c90a | 686 | dev_dbg(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class); |
82d9d54a JK |
687 | |
688 | /* find the configuration for the specific device */ | |
689 | cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table)); | |
690 | if (!cfg) | |
691 | return SND_INTEL_DSP_DRIVER_ANY; | |
692 | ||
693 | if (cfg->flags & FLAG_SOF) { | |
06508575 PLB |
694 | if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE && |
695 | snd_intel_dsp_check_soundwire(pci) > 0) { | |
e662c90a | 696 | dev_info_once(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n"); |
06508575 PLB |
697 | return SND_INTEL_DSP_DRIVER_SOF; |
698 | } | |
699 | if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC && | |
700 | snd_intel_dsp_check_dmic(pci)) { | |
e662c90a | 701 | dev_info_once(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n"); |
82d9d54a JK |
702 | return SND_INTEL_DSP_DRIVER_SOF; |
703 | } | |
06508575 PLB |
704 | if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE)) |
705 | return SND_INTEL_DSP_DRIVER_SOF; | |
82d9d54a JK |
706 | } |
707 | ||
df1fceac CR |
708 | |
709 | if (cfg->flags & FLAG_SST) { | |
710 | if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) { | |
711 | if (snd_intel_dsp_check_dmic(pci)) { | |
e662c90a | 712 | dev_info_once(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n"); |
df1fceac CR |
713 | return SND_INTEL_DSP_DRIVER_SST; |
714 | } | |
715 | } else { | |
716 | return SND_INTEL_DSP_DRIVER_SST; | |
717 | } | |
718 | } | |
82d9d54a JK |
719 | |
720 | return SND_INTEL_DSP_DRIVER_LEGACY; | |
721 | } | |
722 | EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe); | |
723 | ||
5427c7d6 HG |
724 | /* Should we default to SOF or SST for BYT/CHT ? */ |
725 | #if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \ | |
726 | !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) | |
727 | #define FLAG_SST_OR_SOF_BYT FLAG_SOF | |
728 | #else | |
729 | #define FLAG_SST_OR_SOF_BYT FLAG_SST | |
730 | #endif | |
731 | ||
b5682305 PLB |
732 | /* |
733 | * configuration table | |
734 | * - the order of similar ACPI ID entries is important! | |
735 | * - the first successful match will win | |
736 | */ | |
737 | static const struct config_entry acpi_config_table[] = { | |
5427c7d6 HG |
738 | #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \ |
739 | IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) | |
b5682305 | 740 | /* BayTrail */ |
6668610b HG |
741 | { |
742 | .flags = FLAG_SST_OR_SOF_BYT, | |
743 | .acpi_hid = "LPE0F28", | |
744 | }, | |
b5682305 | 745 | { |
5427c7d6 | 746 | .flags = FLAG_SST_OR_SOF_BYT, |
b5682305 PLB |
747 | .acpi_hid = "80860F28", |
748 | }, | |
b5682305 | 749 | /* CherryTrail */ |
b5682305 | 750 | { |
5427c7d6 | 751 | .flags = FLAG_SST_OR_SOF_BYT, |
b5682305 PLB |
752 | .acpi_hid = "808622A8", |
753 | }, | |
754 | #endif | |
803e5913 PLB |
755 | /* Broadwell */ |
756 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT) | |
757 | { | |
758 | .flags = FLAG_SST, | |
759 | .acpi_hid = "INT3438" | |
760 | }, | |
761 | #endif | |
762 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) | |
763 | { | |
764 | .flags = FLAG_SOF, | |
765 | .acpi_hid = "INT3438" | |
766 | }, | |
767 | #endif | |
768 | /* Haswell - not supported by SOF but added for consistency */ | |
769 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT) | |
770 | { | |
771 | .flags = FLAG_SST, | |
772 | .acpi_hid = "INT33C8" | |
773 | }, | |
774 | #endif | |
b5682305 PLB |
775 | }; |
776 | ||
777 | static const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN], | |
778 | const struct config_entry *table, | |
779 | u32 len) | |
780 | { | |
781 | for (; len > 0; len--, table++) { | |
782 | if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN)) | |
783 | continue; | |
784 | if (table->dmi_table && !dmi_check_system(table->dmi_table)) | |
785 | continue; | |
786 | return table; | |
787 | } | |
788 | return NULL; | |
789 | } | |
790 | ||
791 | int snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN]) | |
792 | { | |
793 | const struct config_entry *cfg; | |
794 | ||
795 | if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) | |
796 | return dsp_driver; | |
797 | ||
798 | if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) { | |
799 | dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n", | |
800 | SND_INTEL_DSP_DRIVER_LEGACY); | |
801 | } | |
802 | ||
803 | /* find the configuration for the specific device */ | |
804 | cfg = snd_intel_acpi_dsp_find_config(acpi_hid, acpi_config_table, | |
805 | ARRAY_SIZE(acpi_config_table)); | |
806 | if (!cfg) | |
807 | return SND_INTEL_DSP_DRIVER_ANY; | |
808 | ||
809 | if (cfg->flags & FLAG_SST) | |
810 | return SND_INTEL_DSP_DRIVER_SST; | |
811 | ||
812 | if (cfg->flags & FLAG_SOF) | |
813 | return SND_INTEL_DSP_DRIVER_SOF; | |
814 | ||
815 | return SND_INTEL_DSP_DRIVER_SST; | |
816 | } | |
817 | EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe); | |
818 | ||
82d9d54a JK |
819 | MODULE_LICENSE("GPL v2"); |
820 | MODULE_DESCRIPTION("Intel DSP config driver"); | |
cdd30ebb | 821 | MODULE_IMPORT_NS("SND_INTEL_SOUNDWIRE_ACPI"); |