ALSA: hda: Add AlderLake-N PCI ID
[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>
14
15static int dsp_driver;
16
17module_param(dsp_driver, int, 0444);
18MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)");
19
06508575
PLB
20#define FLAG_SST BIT(0)
21#define FLAG_SOF BIT(1)
df1fceac 22#define FLAG_SST_ONLY_IF_DMIC BIT(15)
06508575
PLB
23#define FLAG_SOF_ONLY_IF_DMIC BIT(16)
24#define FLAG_SOF_ONLY_IF_SOUNDWIRE BIT(17)
25
26#define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \
27 FLAG_SOF_ONLY_IF_SOUNDWIRE)
82d9d54a
JK
28
29struct config_entry {
30 u32 flags;
31 u16 device;
b5682305 32 u8 acpi_hid[ACPI_ID_LEN];
82d9d54a 33 const struct dmi_system_id *dmi_table;
9d36ceab 34 u8 codec_hid[ACPI_ID_LEN];
82d9d54a
JK
35};
36
37/*
38 * configuration table
39 * - the order of similar PCI ID entries is important!
40 * - the first successful match will win
41 */
42static const struct config_entry config_table[] = {
cc8f81c7
PLB
43/* Merrifield */
44#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
82d9d54a 45 {
cc8f81c7
PLB
46 .flags = FLAG_SOF,
47 .device = 0x119a,
82d9d54a 48 },
cc8f81c7
PLB
49#endif
50/* Broxton-T */
51#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
82d9d54a
JK
52 {
53 .flags = FLAG_SOF,
cc8f81c7 54 .device = 0x1a98,
82d9d54a
JK
55 },
56#endif
cc8f81c7
PLB
57/*
58 * Apollolake (Broxton-P)
b79de57b 59 * the legacy HDAudio driver is used except on Up Squared (SOF) and
9d36ceab 60 * Chromebooks (SST), as well as devices based on the ES8336 codec
cc8f81c7
PLB
61 */
62#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
82d9d54a 63 {
cc8f81c7
PLB
64 .flags = FLAG_SOF,
65 .device = 0x5a98,
66 .dmi_table = (const struct dmi_system_id []) {
67 {
68 .ident = "Up Squared",
69 .matches = {
70 DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
71 DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"),
72 }
73 },
74 {}
75 }
82d9d54a 76 },
9d36ceab
PLB
77 {
78 .flags = FLAG_SOF,
79 .device = 0x5a98,
80 .codec_hid = "ESSX8336",
81 },
cc8f81c7
PLB
82#endif
83#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
82d9d54a 84 {
cc8f81c7
PLB
85 .flags = FLAG_SST,
86 .device = 0x5a98,
87 .dmi_table = (const struct dmi_system_id []) {
88 {
89 .ident = "Google Chromebooks",
90 .matches = {
91 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
92 }
93 },
94 {}
95 }
82d9d54a
JK
96 },
97#endif
cc8f81c7 98/*
b79de57b 99 * Skylake and Kabylake use legacy HDAudio driver except for Google
cc8f81c7
PLB
100 * Chromebooks (SST)
101 */
102
103/* Sunrise Point-LP */
104#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)
82d9d54a 105 {
cc8f81c7
PLB
106 .flags = FLAG_SST,
107 .device = 0x9d70,
108 .dmi_table = (const struct dmi_system_id []) {
109 {
110 .ident = "Google Chromebooks",
111 .matches = {
112 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
113 }
114 },
115 {}
116 }
82d9d54a 117 },
df1fceac
CR
118 {
119 .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
120 .device = 0x9d70,
121 },
82d9d54a 122#endif
cc8f81c7
PLB
123/* Kabylake-LP */
124#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
82d9d54a 125 {
cc8f81c7
PLB
126 .flags = FLAG_SST,
127 .device = 0x9d71,
128 .dmi_table = (const struct dmi_system_id []) {
129 {
130 .ident = "Google Chromebooks",
131 .matches = {
132 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
133 }
134 },
135 {}
136 }
82d9d54a 137 },
df1fceac
CR
138 {
139 .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
140 .device = 0x9d71,
141 },
82d9d54a 142#endif
cc8f81c7
PLB
143
144/*
b79de57b 145 * Geminilake uses legacy HDAudio driver except for Google
9d36ceab 146 * Chromebooks and devices based on the ES8336 codec
cc8f81c7 147 */
82d9d54a
JK
148/* Geminilake */
149#if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)
150 {
151 .flags = FLAG_SOF,
152 .device = 0x3198,
153 .dmi_table = (const struct dmi_system_id []) {
154 {
155 .ident = "Google Chromebooks",
156 .matches = {
157 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
158 }
159 },
160 {}
161 }
162 },
9d36ceab
PLB
163 {
164 .flags = FLAG_SOF,
165 .device = 0x3198,
166 .codec_hid = "ESSX8336",
167 },
82d9d54a 168#endif
cc8f81c7
PLB
169
170/*
171 * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake use legacy
b79de57b 172 * HDAudio driver except for Google Chromebooks and when DMICs are
cc8f81c7
PLB
173 * present. Two cases are required since Coreboot does not expose NHLT
174 * tables.
175 *
176 * When the Chromebook quirk is not present, it's based on information
177 * that no such device exists. When the quirk is present, it could be
178 * either based on product information or a placeholder.
179 */
180
181/* Cannonlake */
182#if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)
82d9d54a 183 {
cc8f81c7
PLB
184 .flags = FLAG_SOF,
185 .device = 0x9dc8,
186 .dmi_table = (const struct dmi_system_id []) {
187 {
188 .ident = "Google Chromebooks",
189 .matches = {
190 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
191 }
192 },
193 {}
194 }
82d9d54a 195 },
82d9d54a 196 {
06508575 197 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
cc8f81c7 198 .device = 0x9dc8,
82d9d54a
JK
199 },
200#endif
cc8f81c7
PLB
201
202/* Coffelake */
203#if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)
204 {
205 .flags = FLAG_SOF,
206 .device = 0xa348,
207 .dmi_table = (const struct dmi_system_id []) {
208 {
209 .ident = "Google Chromebooks",
210 .matches = {
211 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
212 }
213 },
214 {}
215 }
216 },
82d9d54a 217 {
06508575 218 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
cc8f81c7 219 .device = 0xa348,
82d9d54a
JK
220 },
221#endif
cc8f81c7 222
4228668e 223#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE)
cc8f81c7 224/* Cometlake-LP */
82d9d54a
JK
225 {
226 .flags = FLAG_SOF,
cc8f81c7 227 .device = 0x02c8,
82d9d54a
JK
228 .dmi_table = (const struct dmi_system_id []) {
229 {
cc8f81c7 230 .ident = "Google Chromebooks",
82d9d54a 231 .matches = {
cc8f81c7 232 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
82d9d54a
JK
233 }
234 },
06508575
PLB
235 {
236 .matches = {
237 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
238 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
239 },
240 },
241 {
242 /* early version of SKU 09C6 */
243 .matches = {
244 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
245 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
246 },
247 },
82d9d54a
JK
248 {}
249 }
250 },
82d9d54a 251 {
06508575 252 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
cc8f81c7 253 .device = 0x02c8,
82d9d54a 254 },
cc8f81c7 255/* Cometlake-H */
82d9d54a 256 {
06508575
PLB
257 .flags = FLAG_SOF,
258 .device = 0x06c8,
259 .dmi_table = (const struct dmi_system_id []) {
260 {
261 .matches = {
262 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
263 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
264 },
265 },
266 {
267 .matches = {
268 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
269 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
270 },
271 },
272 {}
273 }
274 },
275 {
276 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
cc8f81c7 277 .device = 0x06c8,
82d9d54a
JK
278 },
279#endif
cc8f81c7
PLB
280
281/* Icelake */
282#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
82d9d54a 283 {
cc8f81c7
PLB
284 .flags = FLAG_SOF,
285 .device = 0x34c8,
286 .dmi_table = (const struct dmi_system_id []) {
287 {
288 .ident = "Google Chromebooks",
289 .matches = {
290 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
291 }
292 },
293 {}
294 }
82d9d54a 295 },
82d9d54a 296 {
06508575 297 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
cc8f81c7 298 .device = 0x34c8,
82d9d54a
JK
299 },
300#endif
cc8f81c7 301
82d9d54a
JK
302/* Tigerlake */
303#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
cc8f81c7
PLB
304 {
305 .flags = FLAG_SOF,
306 .device = 0xa0c8,
307 .dmi_table = (const struct dmi_system_id []) {
308 {
309 .ident = "Google Chromebooks",
310 .matches = {
311 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
312 }
313 },
314 {}
315 }
316 },
82d9d54a 317 {
06508575 318 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
82d9d54a
JK
319 .device = 0xa0c8,
320 },
c5b5ff60
BL
321 {
322 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
323 .device = 0x43c8,
324 },
9d36ceab
PLB
325 {
326 .flags = FLAG_SOF,
327 .device = 0xa0c8,
328 .codec_hid = "ESSX8336",
329 },
82d9d54a 330#endif
cc8f81c7
PLB
331
332/* Elkhart Lake */
333#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
82d9d54a
JK
334 {
335 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
cc8f81c7 336 .device = 0x4b55,
82d9d54a 337 },
114613f6
PLB
338 {
339 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
340 .device = 0x4b58,
341 },
82d9d54a 342#endif
cc8f81c7 343
c4294d7f
KV
344/* Alder Lake */
345#if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE)
346 {
347 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
348 .device = 0x7ad0,
349 },
350 {
351 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
352 .device = 0x51c8,
353 },
4ad7935d
KV
354 {
355 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
356 .device = 0x51cc,
357 },
4d5a628d
KV
358 {
359 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
360 .device = 0x54c8,
361 },
c4294d7f
KV
362#endif
363
82d9d54a
JK
364};
365
366static const struct config_entry *snd_intel_dsp_find_config
367 (struct pci_dev *pci, const struct config_entry *table, u32 len)
368{
369 u16 device;
370
371 device = pci->device;
372 for (; len > 0; len--, table++) {
373 if (table->device != device)
374 continue;
375 if (table->dmi_table && !dmi_check_system(table->dmi_table))
376 continue;
9d36ceab
PLB
377 if (table->codec_hid[0] && !acpi_dev_present(table->codec_hid, NULL, -1))
378 continue;
82d9d54a
JK
379 return table;
380 }
381 return NULL;
382}
383
384static int snd_intel_dsp_check_dmic(struct pci_dev *pci)
385{
386 struct nhlt_acpi_table *nhlt;
387 int ret = 0;
388
389 nhlt = intel_nhlt_init(&pci->dev);
390 if (nhlt) {
8235a08b 391 if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_DMIC))
82d9d54a
JK
392 ret = 1;
393 intel_nhlt_free(nhlt);
394 }
395 return ret;
396}
397
06508575
PLB
398#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
399static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
400{
401 struct sdw_intel_acpi_info info;
402 acpi_handle handle;
403 int ret;
404
405 handle = ACPI_HANDLE(&pci->dev);
406
407 ret = sdw_intel_acpi_scan(handle, &info);
408 if (ret < 0)
409 return ret;
410
411 return info.link_mask;
412}
413#else
414static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
415{
416 return 0;
417}
418#endif
419
82d9d54a
JK
420int snd_intel_dsp_driver_probe(struct pci_dev *pci)
421{
422 const struct config_entry *cfg;
423
82d9d54a 424 /* Intel vendor only */
91636a82 425 if (pci->vendor != 0x8086)
82d9d54a
JK
426 return SND_INTEL_DSP_DRIVER_ANY;
427
0e5cc221
PLB
428 /*
429 * Legacy devices don't have a PCI-based DSP and use HDaudio
430 * for HDMI/DP support, ignore kernel parameter
431 */
432 switch (pci->device) {
433 case 0x160c: /* Broadwell */
434 case 0x0a0c: /* Haswell */
435 case 0x0c0c:
436 case 0x0d0c:
437 case 0x0f04: /* Baytrail */
438 case 0x2284: /* Braswell */
439 return SND_INTEL_DSP_DRIVER_ANY;
440 }
441
91636a82
TI
442 if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
443 return dsp_driver;
444
82d9d54a
JK
445 /*
446 * detect DSP by checking class/subclass/prog-id information
447 * class=04 subclass 03 prog-if 00: no DSP, use legacy driver
448 * class=04 subclass 01 prog-if 00: DSP is present
449 * (and may be required e.g. for DMIC or SSP support)
450 * class=04 subclass 03 prog-if 80: use DSP or legacy mode
451 */
452 if (pci->class == 0x040300)
453 return SND_INTEL_DSP_DRIVER_LEGACY;
454 if (pci->class != 0x040100 && pci->class != 0x040380) {
b79de57b 455 dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class);
82d9d54a
JK
456 return SND_INTEL_DSP_DRIVER_LEGACY;
457 }
458
459 dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);
460
461 /* find the configuration for the specific device */
462 cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table));
463 if (!cfg)
464 return SND_INTEL_DSP_DRIVER_ANY;
465
466 if (cfg->flags & FLAG_SOF) {
06508575
PLB
467 if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
468 snd_intel_dsp_check_soundwire(pci) > 0) {
469 dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");
470 return SND_INTEL_DSP_DRIVER_SOF;
471 }
472 if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
473 snd_intel_dsp_check_dmic(pci)) {
474 dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
82d9d54a
JK
475 return SND_INTEL_DSP_DRIVER_SOF;
476 }
06508575
PLB
477 if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))
478 return SND_INTEL_DSP_DRIVER_SOF;
82d9d54a
JK
479 }
480
df1fceac
CR
481
482 if (cfg->flags & FLAG_SST) {
483 if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) {
484 if (snd_intel_dsp_check_dmic(pci)) {
485 dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n");
486 return SND_INTEL_DSP_DRIVER_SST;
487 }
488 } else {
489 return SND_INTEL_DSP_DRIVER_SST;
490 }
491 }
82d9d54a
JK
492
493 return SND_INTEL_DSP_DRIVER_LEGACY;
494}
495EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
496
5427c7d6
HG
497/* Should we default to SOF or SST for BYT/CHT ? */
498#if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \
499 !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI)
500#define FLAG_SST_OR_SOF_BYT FLAG_SOF
501#else
502#define FLAG_SST_OR_SOF_BYT FLAG_SST
503#endif
504
b5682305
PLB
505/*
506 * configuration table
507 * - the order of similar ACPI ID entries is important!
508 * - the first successful match will win
509 */
510static const struct config_entry acpi_config_table[] = {
5427c7d6
HG
511#if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
512 IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
b5682305 513/* BayTrail */
b5682305 514 {
5427c7d6 515 .flags = FLAG_SST_OR_SOF_BYT,
b5682305
PLB
516 .acpi_hid = "80860F28",
517 },
b5682305 518/* CherryTrail */
b5682305 519 {
5427c7d6 520 .flags = FLAG_SST_OR_SOF_BYT,
b5682305
PLB
521 .acpi_hid = "808622A8",
522 },
523#endif
803e5913
PLB
524/* Broadwell */
525#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
526 {
527 .flags = FLAG_SST,
528 .acpi_hid = "INT3438"
529 },
530#endif
531#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
532 {
533 .flags = FLAG_SOF,
534 .acpi_hid = "INT3438"
535 },
536#endif
537/* Haswell - not supported by SOF but added for consistency */
538#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
539 {
540 .flags = FLAG_SST,
541 .acpi_hid = "INT33C8"
542 },
543#endif
b5682305
PLB
544};
545
546static const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN],
547 const struct config_entry *table,
548 u32 len)
549{
550 for (; len > 0; len--, table++) {
551 if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN))
552 continue;
553 if (table->dmi_table && !dmi_check_system(table->dmi_table))
554 continue;
555 return table;
556 }
557 return NULL;
558}
559
560int snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN])
561{
562 const struct config_entry *cfg;
563
564 if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
565 return dsp_driver;
566
567 if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) {
568 dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n",
569 SND_INTEL_DSP_DRIVER_LEGACY);
570 }
571
572 /* find the configuration for the specific device */
573 cfg = snd_intel_acpi_dsp_find_config(acpi_hid, acpi_config_table,
574 ARRAY_SIZE(acpi_config_table));
575 if (!cfg)
576 return SND_INTEL_DSP_DRIVER_ANY;
577
578 if (cfg->flags & FLAG_SST)
579 return SND_INTEL_DSP_DRIVER_SST;
580
581 if (cfg->flags & FLAG_SOF)
582 return SND_INTEL_DSP_DRIVER_SOF;
583
584 return SND_INTEL_DSP_DRIVER_SST;
585}
586EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe);
587
82d9d54a
JK
588MODULE_LICENSE("GPL v2");
589MODULE_DESCRIPTION("Intel DSP config driver");
08c2a4bc 590MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);