Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz>
0003 
0004 #include <linux/acpi.h>
0005 #include <linux/bits.h>
0006 #include <linux/dmi.h>
0007 #include <linux/module.h>
0008 #include <linux/pci.h>
0009 #include <linux/soundwire/sdw.h>
0010 #include <linux/soundwire/sdw_intel.h>
0011 #include <sound/core.h>
0012 #include <sound/intel-dsp-config.h>
0013 #include <sound/intel-nhlt.h>
0014 #include <sound/soc-acpi.h>
0015 
0016 static int dsp_driver;
0017 
0018 module_param(dsp_driver, int, 0444);
0019 MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)");
0020 
0021 #define FLAG_SST            BIT(0)
0022 #define FLAG_SOF            BIT(1)
0023 #define FLAG_SST_ONLY_IF_DMIC       BIT(15)
0024 #define FLAG_SOF_ONLY_IF_DMIC       BIT(16)
0025 #define FLAG_SOF_ONLY_IF_SOUNDWIRE  BIT(17)
0026 
0027 #define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \
0028                         FLAG_SOF_ONLY_IF_SOUNDWIRE)
0029 
0030 struct config_entry {
0031     u32 flags;
0032     u16 device;
0033     u8 acpi_hid[ACPI_ID_LEN];
0034     const struct dmi_system_id *dmi_table;
0035     const struct snd_soc_acpi_codecs *codec_hid;
0036 };
0037 
0038 static const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = {
0039     .num_codecs = 3,
0040     .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
0041 };
0042 
0043 /*
0044  * configuration table
0045  * - the order of similar PCI ID entries is important!
0046  * - the first successful match will win
0047  */
0048 static const struct config_entry config_table[] = {
0049 /* Merrifield */
0050 #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
0051     {
0052         .flags = FLAG_SOF,
0053         .device = 0x119a,
0054     },
0055 #endif
0056 /* Broxton-T */
0057 #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
0058     {
0059         .flags = FLAG_SOF,
0060         .device = 0x1a98,
0061     },
0062 #endif
0063 /*
0064  * Apollolake (Broxton-P)
0065  * the legacy HDAudio driver is used except on Up Squared (SOF) and
0066  * Chromebooks (SST), as well as devices based on the ES8336 codec
0067  */
0068 #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
0069     {
0070         .flags = FLAG_SOF,
0071         .device = 0x5a98,
0072         .dmi_table = (const struct dmi_system_id []) {
0073             {
0074                 .ident = "Up Squared",
0075                 .matches = {
0076                     DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
0077                     DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"),
0078                 }
0079             },
0080             {}
0081         }
0082     },
0083     {
0084         .flags = FLAG_SOF,
0085         .device = 0x5a98,
0086         .codec_hid =  &essx_83x6,
0087     },
0088 #endif
0089 #if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
0090     {
0091         .flags = FLAG_SST,
0092         .device = 0x5a98,
0093         .dmi_table = (const struct dmi_system_id []) {
0094             {
0095                 .ident = "Google Chromebooks",
0096                 .matches = {
0097                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0098                 }
0099             },
0100             {}
0101         }
0102     },
0103 #endif
0104 /*
0105  * Skylake and Kabylake use legacy HDAudio driver except for Google
0106  * Chromebooks (SST)
0107  */
0108 
0109 /* Sunrise Point-LP */
0110 #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)
0111     {
0112         .flags = FLAG_SST,
0113         .device = 0x9d70,
0114         .dmi_table = (const struct dmi_system_id []) {
0115             {
0116                 .ident = "Google Chromebooks",
0117                 .matches = {
0118                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0119                 }
0120             },
0121             {}
0122         }
0123     },
0124     {
0125         .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
0126         .device = 0x9d70,
0127     },
0128 #endif
0129 /* Kabylake-LP */
0130 #if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
0131     {
0132         .flags = FLAG_SST,
0133         .device = 0x9d71,
0134         .dmi_table = (const struct dmi_system_id []) {
0135             {
0136                 .ident = "Google Chromebooks",
0137                 .matches = {
0138                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0139                 }
0140             },
0141             {}
0142         }
0143     },
0144     {
0145         .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
0146         .device = 0x9d71,
0147     },
0148 #endif
0149 
0150 /*
0151  * Geminilake uses legacy HDAudio driver except for Google
0152  * Chromebooks and devices based on the ES8336 codec
0153  */
0154 /* Geminilake */
0155 #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)
0156     {
0157         .flags = FLAG_SOF,
0158         .device = 0x3198,
0159         .dmi_table = (const struct dmi_system_id []) {
0160             {
0161                 .ident = "Google Chromebooks",
0162                 .matches = {
0163                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0164                 }
0165             },
0166             {}
0167         }
0168     },
0169     {
0170         .flags = FLAG_SOF,
0171         .device = 0x3198,
0172         .codec_hid =  &essx_83x6,
0173     },
0174 #endif
0175 
0176 /*
0177  * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake use legacy
0178  * HDAudio driver except for Google Chromebooks and when DMICs are
0179  * present. Two cases are required since Coreboot does not expose NHLT
0180  * tables.
0181  *
0182  * When the Chromebook quirk is not present, it's based on information
0183  * that no such device exists. When the quirk is present, it could be
0184  * either based on product information or a placeholder.
0185  */
0186 
0187 /* Cannonlake */
0188 #if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)
0189     {
0190         .flags = FLAG_SOF,
0191         .device = 0x9dc8,
0192         .dmi_table = (const struct dmi_system_id []) {
0193             {
0194                 .ident = "Google Chromebooks",
0195                 .matches = {
0196                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0197                 }
0198             },
0199             {
0200                 .ident = "UP-WHL",
0201                 .matches = {
0202                     DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
0203                 }
0204             },
0205             {}
0206         }
0207     },
0208     {
0209         .flags = FLAG_SOF,
0210         .device = 0x09dc8,
0211         .codec_hid =  &essx_83x6,
0212     },
0213     {
0214         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0215         .device = 0x9dc8,
0216     },
0217 #endif
0218 
0219 /* Coffelake */
0220 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)
0221     {
0222         .flags = FLAG_SOF,
0223         .device = 0xa348,
0224         .dmi_table = (const struct dmi_system_id []) {
0225             {
0226                 .ident = "Google Chromebooks",
0227                 .matches = {
0228                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0229                 }
0230             },
0231             {}
0232         }
0233     },
0234     {
0235         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0236         .device = 0xa348,
0237     },
0238 #endif
0239 
0240 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE)
0241 /* Cometlake-LP */
0242     {
0243         .flags = FLAG_SOF,
0244         .device = 0x02c8,
0245         .dmi_table = (const struct dmi_system_id []) {
0246             {
0247                 .ident = "Google Chromebooks",
0248                 .matches = {
0249                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0250                 }
0251             },
0252             {
0253                 .matches = {
0254                     DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
0255                     DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
0256                 },
0257             },
0258             {
0259                 /* early version of SKU 09C6 */
0260                 .matches = {
0261                     DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
0262                     DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
0263                 },
0264             },
0265             {}
0266         }
0267     },
0268     {
0269         .flags = FLAG_SOF,
0270         .device = 0x02c8,
0271         .codec_hid =  &essx_83x6,
0272     },
0273     {
0274         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0275         .device = 0x02c8,
0276     },
0277 /* Cometlake-H */
0278     {
0279         .flags = FLAG_SOF,
0280         .device = 0x06c8,
0281         .dmi_table = (const struct dmi_system_id []) {
0282             {
0283                 .matches = {
0284                     DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
0285                     DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
0286                 },
0287             },
0288             {
0289                 .matches = {
0290                     DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
0291                     DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
0292                 },
0293             },
0294             {}
0295         }
0296     },
0297     {
0298         .flags = FLAG_SOF,
0299         .device = 0x06c8,
0300         .codec_hid =  &essx_83x6,
0301     },
0302     {
0303         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0304         .device = 0x06c8,
0305     },
0306 #endif
0307 
0308 /* Icelake */
0309 #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
0310     {
0311         .flags = FLAG_SOF,
0312         .device = 0x34c8,
0313         .dmi_table = (const struct dmi_system_id []) {
0314             {
0315                 .ident = "Google Chromebooks",
0316                 .matches = {
0317                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0318                 }
0319             },
0320             {}
0321         }
0322     },
0323     {
0324         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0325         .device = 0x34c8,
0326     },
0327 #endif
0328 
0329 /* Jasper Lake */
0330 #if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
0331     {
0332         .flags = FLAG_SOF,
0333         .device = 0x4dc8,
0334         .dmi_table = (const struct dmi_system_id []) {
0335             {
0336                 .ident = "Google Chromebooks",
0337                 .matches = {
0338                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0339                 }
0340             },
0341             {}
0342         }
0343     },
0344     {
0345         .flags = FLAG_SOF,
0346         .device = 0x4dc8,
0347         .codec_hid =  &essx_83x6,
0348     },
0349     {
0350         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
0351         .device = 0x4dc8,
0352     },
0353 #endif
0354 
0355 /* Tigerlake */
0356 #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
0357     {
0358         .flags = FLAG_SOF,
0359         .device = 0xa0c8,
0360         .dmi_table = (const struct dmi_system_id []) {
0361             {
0362                 .ident = "Google Chromebooks",
0363                 .matches = {
0364                     DMI_MATCH(DMI_SYS_VENDOR, "Google"),
0365                 }
0366             },
0367             {
0368                 .ident = "UPX-TGL",
0369                 .matches = {
0370                     DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
0371                 }
0372             },
0373             {}
0374         }
0375     },
0376     {
0377         .flags = FLAG_SOF,
0378         .device = 0xa0c8,
0379         .codec_hid =  &essx_83x6,
0380     },
0381     {
0382         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0383         .device = 0xa0c8,
0384     },
0385     {
0386         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0387         .device = 0x43c8,
0388     },
0389 #endif
0390 
0391 /* Elkhart Lake */
0392 #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
0393     {
0394         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
0395         .device = 0x4b55,
0396     },
0397     {
0398         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
0399         .device = 0x4b58,
0400     },
0401 #endif
0402 
0403 /* Alder Lake */
0404 #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE)
0405     /* Alderlake-S */
0406     {
0407         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0408         .device = 0x7ad0,
0409     },
0410     /* RaptorLake-S */
0411     {
0412         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0413         .device = 0x7a50,
0414     },
0415     /* Alderlake-P */
0416     {
0417         .flags = FLAG_SOF,
0418         .device = 0x51c8,
0419         .codec_hid =  &essx_83x6,
0420     },
0421     {
0422         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0423         .device = 0x51c8,
0424     },
0425     {
0426         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0427         .device = 0x51cd,
0428     },
0429     /* Alderlake-PS */
0430     {
0431         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0432         .device = 0x51c9,
0433     },
0434     /* Alderlake-M */
0435     {
0436         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0437         .device = 0x51cc,
0438     },
0439     /* Alderlake-N */
0440     {
0441         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0442         .device = 0x54c8,
0443     },
0444     /* RaptorLake-P */
0445     {
0446         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0447         .device = 0x51ca,
0448     },
0449     {
0450         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0451         .device = 0x51cb,
0452     },
0453     /* RaptorLake-M */
0454     {
0455         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0456         .device = 0x51ce,
0457     },
0458     /* RaptorLake-PX */
0459     {
0460         .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
0461         .device = 0x51cf,
0462     },
0463 #endif
0464 
0465 };
0466 
0467 static const struct config_entry *snd_intel_dsp_find_config
0468         (struct pci_dev *pci, const struct config_entry *table, u32 len)
0469 {
0470     u16 device;
0471 
0472     device = pci->device;
0473     for (; len > 0; len--, table++) {
0474         if (table->device != device)
0475             continue;
0476         if (table->dmi_table && !dmi_check_system(table->dmi_table))
0477             continue;
0478         if (table->codec_hid) {
0479             int i;
0480 
0481             for (i = 0; i < table->codec_hid->num_codecs; i++)
0482                 if (acpi_dev_present(table->codec_hid->codecs[i], NULL, -1))
0483                     break;
0484             if (i == table->codec_hid->num_codecs)
0485                 continue;
0486         }
0487         return table;
0488     }
0489     return NULL;
0490 }
0491 
0492 static int snd_intel_dsp_check_dmic(struct pci_dev *pci)
0493 {
0494     struct nhlt_acpi_table *nhlt;
0495     int ret = 0;
0496 
0497     nhlt = intel_nhlt_init(&pci->dev);
0498     if (nhlt) {
0499         if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_DMIC))
0500             ret = 1;
0501         intel_nhlt_free(nhlt);
0502     }
0503     return ret;
0504 }
0505 
0506 #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
0507 static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
0508 {
0509     struct sdw_intel_acpi_info info;
0510     acpi_handle handle;
0511     int ret;
0512 
0513     handle = ACPI_HANDLE(&pci->dev);
0514 
0515     ret = sdw_intel_acpi_scan(handle, &info);
0516     if (ret < 0)
0517         return ret;
0518 
0519     return info.link_mask;
0520 }
0521 #else
0522 static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
0523 {
0524     return 0;
0525 }
0526 #endif
0527 
0528 int snd_intel_dsp_driver_probe(struct pci_dev *pci)
0529 {
0530     const struct config_entry *cfg;
0531 
0532     /* Intel vendor only */
0533     if (pci->vendor != 0x8086)
0534         return SND_INTEL_DSP_DRIVER_ANY;
0535 
0536     /*
0537      * Legacy devices don't have a PCI-based DSP and use HDaudio
0538      * for HDMI/DP support, ignore kernel parameter
0539      */
0540     switch (pci->device) {
0541     case 0x160c: /* Broadwell */
0542     case 0x0a0c: /* Haswell */
0543     case 0x0c0c:
0544     case 0x0d0c:
0545     case 0x0f04: /* Baytrail */
0546     case 0x2284: /* Braswell */
0547         return SND_INTEL_DSP_DRIVER_ANY;
0548     }
0549 
0550     if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
0551         return dsp_driver;
0552 
0553     /*
0554      * detect DSP by checking class/subclass/prog-id information
0555      * class=04 subclass 03 prog-if 00: no DSP, use legacy driver
0556      * class=04 subclass 01 prog-if 00: DSP is present
0557      *  (and may be required e.g. for DMIC or SSP support)
0558      * class=04 subclass 03 prog-if 80: use DSP or legacy mode
0559      */
0560     if (pci->class == 0x040300)
0561         return SND_INTEL_DSP_DRIVER_LEGACY;
0562     if (pci->class != 0x040100 && pci->class != 0x040380) {
0563         dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class);
0564         return SND_INTEL_DSP_DRIVER_LEGACY;
0565     }
0566 
0567     dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);
0568 
0569     /* find the configuration for the specific device */
0570     cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table));
0571     if (!cfg)
0572         return SND_INTEL_DSP_DRIVER_ANY;
0573 
0574     if (cfg->flags & FLAG_SOF) {
0575         if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
0576             snd_intel_dsp_check_soundwire(pci) > 0) {
0577             dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");
0578             return SND_INTEL_DSP_DRIVER_SOF;
0579         }
0580         if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
0581             snd_intel_dsp_check_dmic(pci)) {
0582             dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
0583             return SND_INTEL_DSP_DRIVER_SOF;
0584         }
0585         if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))
0586             return SND_INTEL_DSP_DRIVER_SOF;
0587     }
0588 
0589 
0590     if (cfg->flags & FLAG_SST) {
0591         if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) {
0592             if (snd_intel_dsp_check_dmic(pci)) {
0593                 dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n");
0594                 return SND_INTEL_DSP_DRIVER_SST;
0595             }
0596         } else {
0597             return SND_INTEL_DSP_DRIVER_SST;
0598         }
0599     }
0600 
0601     return SND_INTEL_DSP_DRIVER_LEGACY;
0602 }
0603 EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
0604 
0605 /* Should we default to SOF or SST for BYT/CHT ? */
0606 #if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \
0607     !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI)
0608 #define FLAG_SST_OR_SOF_BYT FLAG_SOF
0609 #else
0610 #define FLAG_SST_OR_SOF_BYT FLAG_SST
0611 #endif
0612 
0613 /*
0614  * configuration table
0615  * - the order of similar ACPI ID entries is important!
0616  * - the first successful match will win
0617  */
0618 static const struct config_entry acpi_config_table[] = {
0619 #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
0620     IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
0621 /* BayTrail */
0622     {
0623         .flags = FLAG_SST_OR_SOF_BYT,
0624         .acpi_hid = "80860F28",
0625     },
0626 /* CherryTrail */
0627     {
0628         .flags = FLAG_SST_OR_SOF_BYT,
0629         .acpi_hid = "808622A8",
0630     },
0631 #endif
0632 /* Broadwell */
0633 #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
0634     {
0635         .flags = FLAG_SST,
0636         .acpi_hid = "INT3438"
0637     },
0638 #endif
0639 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
0640     {
0641         .flags = FLAG_SOF,
0642         .acpi_hid = "INT3438"
0643     },
0644 #endif
0645 /* Haswell - not supported by SOF but added for consistency */
0646 #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
0647     {
0648         .flags = FLAG_SST,
0649         .acpi_hid = "INT33C8"
0650     },
0651 #endif
0652 };
0653 
0654 static const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN],
0655                                  const struct config_entry *table,
0656                                  u32 len)
0657 {
0658     for (; len > 0; len--, table++) {
0659         if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN))
0660             continue;
0661         if (table->dmi_table && !dmi_check_system(table->dmi_table))
0662             continue;
0663         return table;
0664     }
0665     return NULL;
0666 }
0667 
0668 int snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN])
0669 {
0670     const struct config_entry *cfg;
0671 
0672     if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
0673         return dsp_driver;
0674 
0675     if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) {
0676         dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n",
0677              SND_INTEL_DSP_DRIVER_LEGACY);
0678     }
0679 
0680     /* find the configuration for the specific device */
0681     cfg = snd_intel_acpi_dsp_find_config(acpi_hid,  acpi_config_table,
0682                          ARRAY_SIZE(acpi_config_table));
0683     if (!cfg)
0684         return SND_INTEL_DSP_DRIVER_ANY;
0685 
0686     if (cfg->flags & FLAG_SST)
0687         return SND_INTEL_DSP_DRIVER_SST;
0688 
0689     if (cfg->flags & FLAG_SOF)
0690         return SND_INTEL_DSP_DRIVER_SOF;
0691 
0692     return SND_INTEL_DSP_DRIVER_SST;
0693 }
0694 EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe);
0695 
0696 MODULE_LICENSE("GPL v2");
0697 MODULE_DESCRIPTION("Intel DSP config driver");
0698 MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);