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