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