Merge tag 'pci-v6.16-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
[linux-block.git] / sound / hda / intel-dsp-config.c
CommitLineData
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
18static int dsp_driver;
19
20module_param(dsp_driver, int, 0444);
2646b439 21MODULE_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
32struct 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
40static 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 */
50static 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
563static 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
611static 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)
626static 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
641static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
642{
643 return 0;
644}
645#endif
646
82d9d54a
JK
647int 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}
722EXPORT_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 */
737static 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
777static 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
791int 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}
817EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe);
818
82d9d54a
JK
819MODULE_LICENSE("GPL v2");
820MODULE_DESCRIPTION("Intel DSP config driver");
cdd30ebb 821MODULE_IMPORT_NS("SND_INTEL_SOUNDWIRE_ACPI");