~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/hda/intel-dsp-config.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php