LCOV - code coverage report
Current view: top level - sound/hda - intel-dsp-config.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 26 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 2 0.0 %
Branches: 0 20 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : // Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz>
       3                 :            : 
       4                 :            : #include <linux/bits.h>
       5                 :            : #include <linux/dmi.h>
       6                 :            : #include <linux/module.h>
       7                 :            : #include <linux/pci.h>
       8                 :            : #include <sound/core.h>
       9                 :            : #include <sound/intel-dsp-config.h>
      10                 :            : #include <sound/intel-nhlt.h>
      11                 :            : 
      12                 :            : static int dsp_driver;
      13                 :            : 
      14                 :            : module_param(dsp_driver, int, 0444);
      15                 :            : MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)");
      16                 :            : 
      17                 :            : #define FLAG_SST                BIT(0)
      18                 :            : #define FLAG_SOF                BIT(1)
      19                 :            : #define FLAG_SOF_ONLY_IF_DMIC   BIT(16)
      20                 :            : 
      21                 :            : struct config_entry {
      22                 :            :         u32 flags;
      23                 :            :         u16 device;
      24                 :            :         const struct dmi_system_id *dmi_table;
      25                 :            : };
      26                 :            : 
      27                 :            : /*
      28                 :            :  * configuration table
      29                 :            :  * - the order of similar PCI ID entries is important!
      30                 :            :  * - the first successful match will win
      31                 :            :  */
      32                 :            : static const struct config_entry config_table[] = {
      33                 :            : /* Merrifield */
      34                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
      35                 :            :         {
      36                 :            :                 .flags = FLAG_SOF,
      37                 :            :                 .device = 0x119a,
      38                 :            :         },
      39                 :            : #endif
      40                 :            : /* Broxton-T */
      41                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
      42                 :            :         {
      43                 :            :                 .flags = FLAG_SOF,
      44                 :            :                 .device = 0x1a98,
      45                 :            :         },
      46                 :            : #endif
      47                 :            : /*
      48                 :            :  * Apollolake (Broxton-P)
      49                 :            :  * the legacy HDaudio driver is used except on Up Squared (SOF) and
      50                 :            :  * Chromebooks (SST)
      51                 :            :  */
      52                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
      53                 :            :         {
      54                 :            :                 .flags = FLAG_SOF,
      55                 :            :                 .device = 0x5a98,
      56                 :            :                 .dmi_table = (const struct dmi_system_id []) {
      57                 :            :                         {
      58                 :            :                                 .ident = "Up Squared",
      59                 :            :                                 .matches = {
      60                 :            :                                         DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
      61                 :            :                                         DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"),
      62                 :            :                                 }
      63                 :            :                         },
      64                 :            :                         {}
      65                 :            :                 }
      66                 :            :         },
      67                 :            : #endif
      68                 :            : #if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
      69                 :            :         {
      70                 :            :                 .flags = FLAG_SST,
      71                 :            :                 .device = 0x5a98,
      72                 :            :                 .dmi_table = (const struct dmi_system_id []) {
      73                 :            :                         {
      74                 :            :                                 .ident = "Google Chromebooks",
      75                 :            :                                 .matches = {
      76                 :            :                                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
      77                 :            :                                 }
      78                 :            :                         },
      79                 :            :                         {}
      80                 :            :                 }
      81                 :            :         },
      82                 :            : #endif
      83                 :            : /*
      84                 :            :  * Skylake and Kabylake use legacy HDaudio driver except for Google
      85                 :            :  * Chromebooks (SST)
      86                 :            :  */
      87                 :            : 
      88                 :            : /* Sunrise Point-LP */
      89                 :            : #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)
      90                 :            :         {
      91                 :            :                 .flags = FLAG_SST,
      92                 :            :                 .device = 0x9d70,
      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                 :            : /* Kabylake-LP */
     105                 :            : #if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
     106                 :            :         {
     107                 :            :                 .flags = FLAG_SST,
     108                 :            :                 .device = 0x9d71,
     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                 :            : #endif
     120                 :            : 
     121                 :            : /*
     122                 :            :  * Geminilake uses legacy HDaudio driver except for Google
     123                 :            :  * Chromebooks
     124                 :            :  */
     125                 :            : /* Geminilake */
     126                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)
     127                 :            :         {
     128                 :            :                 .flags = FLAG_SOF,
     129                 :            :                 .device = 0x3198,
     130                 :            :                 .dmi_table = (const struct dmi_system_id []) {
     131                 :            :                         {
     132                 :            :                                 .ident = "Google Chromebooks",
     133                 :            :                                 .matches = {
     134                 :            :                                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
     135                 :            :                                 }
     136                 :            :                         },
     137                 :            :                         {}
     138                 :            :                 }
     139                 :            :         },
     140                 :            : #endif
     141                 :            : 
     142                 :            : /*
     143                 :            :  * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake use legacy
     144                 :            :  * HDaudio driver except for Google Chromebooks and when DMICs are
     145                 :            :  * present. Two cases are required since Coreboot does not expose NHLT
     146                 :            :  * tables.
     147                 :            :  *
     148                 :            :  * When the Chromebook quirk is not present, it's based on information
     149                 :            :  * that no such device exists. When the quirk is present, it could be
     150                 :            :  * either based on product information or a placeholder.
     151                 :            :  */
     152                 :            : 
     153                 :            : /* Cannonlake */
     154                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)
     155                 :            :         {
     156                 :            :                 .flags = FLAG_SOF,
     157                 :            :                 .device = 0x9dc8,
     158                 :            :                 .dmi_table = (const struct dmi_system_id []) {
     159                 :            :                         {
     160                 :            :                                 .ident = "Google Chromebooks",
     161                 :            :                                 .matches = {
     162                 :            :                                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
     163                 :            :                                 }
     164                 :            :                         },
     165                 :            :                         {}
     166                 :            :                 }
     167                 :            :         },
     168                 :            :         {
     169                 :            :                 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
     170                 :            :                 .device = 0x9dc8,
     171                 :            :         },
     172                 :            : #endif
     173                 :            : 
     174                 :            : /* Coffelake */
     175                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)
     176                 :            :         {
     177                 :            :                 .flags = FLAG_SOF,
     178                 :            :                 .device = 0xa348,
     179                 :            :                 .dmi_table = (const struct dmi_system_id []) {
     180                 :            :                         {
     181                 :            :                                 .ident = "Google Chromebooks",
     182                 :            :                                 .matches = {
     183                 :            :                                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
     184                 :            :                                 }
     185                 :            :                         },
     186                 :            :                         {}
     187                 :            :                 }
     188                 :            :         },
     189                 :            :         {
     190                 :            :                 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
     191                 :            :                 .device = 0xa348,
     192                 :            :         },
     193                 :            : #endif
     194                 :            : 
     195                 :            : /* Cometlake-LP */
     196                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_LP)
     197                 :            :         {
     198                 :            :                 .flags = FLAG_SOF,
     199                 :            :                 .device = 0x02c8,
     200                 :            :                 .dmi_table = (const struct dmi_system_id []) {
     201                 :            :                         {
     202                 :            :                                 .ident = "Google Chromebooks",
     203                 :            :                                 .matches = {
     204                 :            :                                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
     205                 :            :                                 }
     206                 :            :                         },
     207                 :            :                         {}
     208                 :            :                 }
     209                 :            :         },
     210                 :            :         {
     211                 :            :                 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
     212                 :            :                 .device = 0x02c8,
     213                 :            :         },
     214                 :            : #endif
     215                 :            : /* Cometlake-H */
     216                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_H)
     217                 :            :         {
     218                 :            :                 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
     219                 :            :                 .device = 0x06c8,
     220                 :            :         },
     221                 :            : #endif
     222                 :            : 
     223                 :            : /* Icelake */
     224                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
     225                 :            :         {
     226                 :            :                 .flags = FLAG_SOF,
     227                 :            :                 .device = 0x34c8,
     228                 :            :                 .dmi_table = (const struct dmi_system_id []) {
     229                 :            :                         {
     230                 :            :                                 .ident = "Google Chromebooks",
     231                 :            :                                 .matches = {
     232                 :            :                                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
     233                 :            :                                 }
     234                 :            :                         },
     235                 :            :                         {}
     236                 :            :                 }
     237                 :            :         },
     238                 :            :         {
     239                 :            :                 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
     240                 :            :                 .device = 0x34c8,
     241                 :            :         },
     242                 :            : #endif
     243                 :            : 
     244                 :            : /* Tigerlake */
     245                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
     246                 :            :         {
     247                 :            :                 .flags = FLAG_SOF,
     248                 :            :                 .device = 0xa0c8,
     249                 :            :                 .dmi_table = (const struct dmi_system_id []) {
     250                 :            :                         {
     251                 :            :                                 .ident = "Google Chromebooks",
     252                 :            :                                 .matches = {
     253                 :            :                                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
     254                 :            :                                 }
     255                 :            :                         },
     256                 :            :                         {}
     257                 :            :                 }
     258                 :            :         },
     259                 :            : 
     260                 :            :         {
     261                 :            :                 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
     262                 :            :                 .device = 0xa0c8,
     263                 :            :         },
     264                 :            : #endif
     265                 :            : 
     266                 :            : /* Elkhart Lake */
     267                 :            : #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
     268                 :            :         {
     269                 :            :                 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
     270                 :            :                 .device = 0x4b55,
     271                 :            :         },
     272                 :            : #endif
     273                 :            : 
     274                 :            : };
     275                 :            : 
     276                 :            : static const struct config_entry *snd_intel_dsp_find_config
     277                 :            :                 (struct pci_dev *pci, const struct config_entry *table, u32 len)
     278                 :            : {
     279                 :            :         u16 device;
     280                 :            : 
     281                 :            :         device = pci->device;
     282                 :            :         for (; len > 0; len--, table++) {
     283                 :            :                 if (table->device != device)
     284                 :            :                         continue;
     285                 :            :                 if (table->dmi_table && !dmi_check_system(table->dmi_table))
     286                 :            :                         continue;
     287                 :            :                 return table;
     288                 :            :         }
     289                 :            :         return NULL;
     290                 :            : }
     291                 :            : 
     292                 :          0 : static int snd_intel_dsp_check_dmic(struct pci_dev *pci)
     293                 :            : {
     294                 :          0 :         struct nhlt_acpi_table *nhlt;
     295                 :          0 :         int ret = 0;
     296                 :            : 
     297                 :          0 :         nhlt = intel_nhlt_init(&pci->dev);
     298         [ #  # ]:          0 :         if (nhlt) {
     299         [ #  # ]:          0 :                 if (intel_nhlt_get_dmic_geo(&pci->dev, nhlt))
     300                 :          0 :                         ret = 1;
     301                 :          0 :                 intel_nhlt_free(nhlt);
     302                 :            :         }
     303                 :          0 :         return ret;
     304                 :            : }
     305                 :            : 
     306                 :          0 : int snd_intel_dsp_driver_probe(struct pci_dev *pci)
     307                 :            : {
     308                 :          0 :         const struct config_entry *cfg;
     309                 :            : 
     310                 :            :         /* Intel vendor only */
     311         [ #  # ]:          0 :         if (pci->vendor != 0x8086)
     312                 :            :                 return SND_INTEL_DSP_DRIVER_ANY;
     313                 :            : 
     314         [ #  # ]:          0 :         if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
     315                 :            :                 return dsp_driver;
     316                 :            : 
     317                 :            :         /*
     318                 :            :          * detect DSP by checking class/subclass/prog-id information
     319                 :            :          * class=04 subclass 03 prog-if 00: no DSP, use legacy driver
     320                 :            :          * class=04 subclass 01 prog-if 00: DSP is present
     321                 :            :          *  (and may be required e.g. for DMIC or SSP support)
     322                 :            :          * class=04 subclass 03 prog-if 80: use DSP or legacy mode
     323                 :            :          */
     324         [ #  # ]:          0 :         if (pci->class == 0x040300)
     325                 :            :                 return SND_INTEL_DSP_DRIVER_LEGACY;
     326         [ #  # ]:          0 :         if (pci->class != 0x040100 && pci->class != 0x040380) {
     327                 :          0 :                 dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDA legacy driver\n", pci->class);
     328                 :          0 :                 return SND_INTEL_DSP_DRIVER_LEGACY;
     329                 :            :         }
     330                 :            : 
     331                 :          0 :         dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);
     332                 :            : 
     333                 :            :         /* find the configuration for the specific device */
     334                 :          0 :         cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table));
     335         [ #  # ]:          0 :         if (!cfg)
     336                 :            :                 return SND_INTEL_DSP_DRIVER_ANY;
     337                 :            : 
     338         [ #  # ]:          0 :         if (cfg->flags & FLAG_SOF) {
     339         [ #  # ]:          0 :                 if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC) {
     340         [ #  # ]:          0 :                         if (snd_intel_dsp_check_dmic(pci)) {
     341                 :          0 :                                 dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
     342                 :          0 :                                 return SND_INTEL_DSP_DRIVER_SOF;
     343                 :            :                         }
     344                 :            :                 } else {
     345                 :            :                         return SND_INTEL_DSP_DRIVER_SOF;
     346                 :            :                 }
     347                 :            :         }
     348                 :            : 
     349                 :          0 :         if (cfg->flags & FLAG_SST)
     350                 :            :                 return SND_INTEL_DSP_DRIVER_SST;
     351                 :            : 
     352                 :            :         return SND_INTEL_DSP_DRIVER_LEGACY;
     353                 :            : }
     354                 :            : EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
     355                 :            : 
     356                 :            : MODULE_LICENSE("GPL v2");
     357                 :            : MODULE_DESCRIPTION("Intel DSP config driver");

Generated by: LCOV version 1.14