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