182d9d54aSJaroslav Kysela // SPDX-License-Identifier: GPL-2.0 282d9d54aSJaroslav Kysela // Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz> 382d9d54aSJaroslav Kysela 406508575SPierre-Louis Bossart #include <linux/acpi.h> 582d9d54aSJaroslav Kysela #include <linux/bits.h> 682d9d54aSJaroslav Kysela #include <linux/dmi.h> 782d9d54aSJaroslav Kysela #include <linux/module.h> 882d9d54aSJaroslav Kysela #include <linux/pci.h> 906508575SPierre-Louis Bossart #include <linux/soundwire/sdw.h> 1006508575SPierre-Louis Bossart #include <linux/soundwire/sdw_intel.h> 1182d9d54aSJaroslav Kysela #include <sound/core.h> 1282d9d54aSJaroslav Kysela #include <sound/intel-dsp-config.h> 1382d9d54aSJaroslav Kysela #include <sound/intel-nhlt.h> 14*de24d97fSPierre-Louis Bossart #include <sound/soc-acpi.h> 1582d9d54aSJaroslav Kysela 1682d9d54aSJaroslav Kysela static int dsp_driver; 1782d9d54aSJaroslav Kysela 1882d9d54aSJaroslav Kysela module_param(dsp_driver, int, 0444); 1982d9d54aSJaroslav Kysela MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)"); 2082d9d54aSJaroslav Kysela 2182d9d54aSJaroslav Kysela #define FLAG_SST BIT(0) 2282d9d54aSJaroslav Kysela #define FLAG_SOF BIT(1) 23df1fceacSCezary Rojewski #define FLAG_SST_ONLY_IF_DMIC BIT(15) 2482d9d54aSJaroslav Kysela #define FLAG_SOF_ONLY_IF_DMIC BIT(16) 2506508575SPierre-Louis Bossart #define FLAG_SOF_ONLY_IF_SOUNDWIRE BIT(17) 2606508575SPierre-Louis Bossart 2706508575SPierre-Louis Bossart #define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \ 2806508575SPierre-Louis Bossart FLAG_SOF_ONLY_IF_SOUNDWIRE) 2982d9d54aSJaroslav Kysela 3082d9d54aSJaroslav Kysela struct config_entry { 3182d9d54aSJaroslav Kysela u32 flags; 3282d9d54aSJaroslav Kysela u16 device; 33b5682305SPierre-Louis Bossart u8 acpi_hid[ACPI_ID_LEN]; 3482d9d54aSJaroslav Kysela const struct dmi_system_id *dmi_table; 35*de24d97fSPierre-Louis Bossart const struct snd_soc_acpi_codecs *codec_hid; 36*de24d97fSPierre-Louis Bossart }; 37*de24d97fSPierre-Louis Bossart 38*de24d97fSPierre-Louis Bossart static const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = { 39*de24d97fSPierre-Louis Bossart .num_codecs = 3, 40*de24d97fSPierre-Louis Bossart .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, 4182d9d54aSJaroslav Kysela }; 4282d9d54aSJaroslav Kysela 4382d9d54aSJaroslav Kysela /* 4482d9d54aSJaroslav Kysela * configuration table 4582d9d54aSJaroslav Kysela * - the order of similar PCI ID entries is important! 4682d9d54aSJaroslav Kysela * - the first successful match will win 4782d9d54aSJaroslav Kysela */ 4882d9d54aSJaroslav Kysela static const struct config_entry config_table[] = { 4982d9d54aSJaroslav Kysela /* Merrifield */ 5082d9d54aSJaroslav Kysela #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) 5182d9d54aSJaroslav Kysela { 5282d9d54aSJaroslav Kysela .flags = FLAG_SOF, 5382d9d54aSJaroslav Kysela .device = 0x119a, 5482d9d54aSJaroslav Kysela }, 5582d9d54aSJaroslav Kysela #endif 5682d9d54aSJaroslav Kysela /* Broxton-T */ 5782d9d54aSJaroslav Kysela #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) 5882d9d54aSJaroslav Kysela { 59cc8f81c7SPierre-Louis Bossart .flags = FLAG_SOF, 6082d9d54aSJaroslav Kysela .device = 0x1a98, 6182d9d54aSJaroslav Kysela }, 6282d9d54aSJaroslav Kysela #endif 63cc8f81c7SPierre-Louis Bossart /* 64cc8f81c7SPierre-Louis Bossart * Apollolake (Broxton-P) 65b79de57bSPierre-Louis Bossart * the legacy HDAudio driver is used except on Up Squared (SOF) and 669d36ceabSPierre-Louis Bossart * Chromebooks (SST), as well as devices based on the ES8336 codec 67cc8f81c7SPierre-Louis Bossart */ 6882d9d54aSJaroslav Kysela #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) 6982d9d54aSJaroslav Kysela { 7082d9d54aSJaroslav Kysela .flags = FLAG_SOF, 7182d9d54aSJaroslav Kysela .device = 0x5a98, 7282d9d54aSJaroslav Kysela .dmi_table = (const struct dmi_system_id []) { 7382d9d54aSJaroslav Kysela { 7482d9d54aSJaroslav Kysela .ident = "Up Squared", 7582d9d54aSJaroslav Kysela .matches = { 7682d9d54aSJaroslav Kysela DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), 7782d9d54aSJaroslav Kysela DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"), 7882d9d54aSJaroslav Kysela } 7982d9d54aSJaroslav Kysela }, 8082d9d54aSJaroslav Kysela {} 8182d9d54aSJaroslav Kysela } 8282d9d54aSJaroslav Kysela }, 839d36ceabSPierre-Louis Bossart { 849d36ceabSPierre-Louis Bossart .flags = FLAG_SOF, 859d36ceabSPierre-Louis Bossart .device = 0x5a98, 86*de24d97fSPierre-Louis Bossart .codec_hid = &essx_83x6, 879d36ceabSPierre-Louis Bossart }, 8882d9d54aSJaroslav Kysela #endif 8982d9d54aSJaroslav Kysela #if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL) 9082d9d54aSJaroslav Kysela { 9182d9d54aSJaroslav Kysela .flags = FLAG_SST, 9282d9d54aSJaroslav Kysela .device = 0x5a98, 93cc8f81c7SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 94cc8f81c7SPierre-Louis Bossart { 95cc8f81c7SPierre-Louis Bossart .ident = "Google Chromebooks", 96cc8f81c7SPierre-Louis Bossart .matches = { 97cc8f81c7SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Google"), 98cc8f81c7SPierre-Louis Bossart } 99cc8f81c7SPierre-Louis Bossart }, 100cc8f81c7SPierre-Louis Bossart {} 101cc8f81c7SPierre-Louis Bossart } 10282d9d54aSJaroslav Kysela }, 10382d9d54aSJaroslav Kysela #endif 104cc8f81c7SPierre-Louis Bossart /* 105b79de57bSPierre-Louis Bossart * Skylake and Kabylake use legacy HDAudio driver except for Google 106cc8f81c7SPierre-Louis Bossart * Chromebooks (SST) 107cc8f81c7SPierre-Louis Bossart */ 108cc8f81c7SPierre-Louis Bossart 109cc8f81c7SPierre-Louis Bossart /* Sunrise Point-LP */ 110cc8f81c7SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL) 111cc8f81c7SPierre-Louis Bossart { 112cc8f81c7SPierre-Louis Bossart .flags = FLAG_SST, 113cc8f81c7SPierre-Louis Bossart .device = 0x9d70, 114cc8f81c7SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 115cc8f81c7SPierre-Louis Bossart { 116cc8f81c7SPierre-Louis Bossart .ident = "Google Chromebooks", 117cc8f81c7SPierre-Louis Bossart .matches = { 118cc8f81c7SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Google"), 119cc8f81c7SPierre-Louis Bossart } 120cc8f81c7SPierre-Louis Bossart }, 121cc8f81c7SPierre-Louis Bossart {} 122cc8f81c7SPierre-Louis Bossart } 123cc8f81c7SPierre-Louis Bossart }, 124df1fceacSCezary Rojewski { 125df1fceacSCezary Rojewski .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, 126df1fceacSCezary Rojewski .device = 0x9d70, 127df1fceacSCezary Rojewski }, 128cc8f81c7SPierre-Louis Bossart #endif 129cc8f81c7SPierre-Louis Bossart /* Kabylake-LP */ 130cc8f81c7SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL) 131cc8f81c7SPierre-Louis Bossart { 132cc8f81c7SPierre-Louis Bossart .flags = FLAG_SST, 133cc8f81c7SPierre-Louis Bossart .device = 0x9d71, 134cc8f81c7SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 135cc8f81c7SPierre-Louis Bossart { 136cc8f81c7SPierre-Louis Bossart .ident = "Google Chromebooks", 137cc8f81c7SPierre-Louis Bossart .matches = { 138cc8f81c7SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Google"), 139cc8f81c7SPierre-Louis Bossart } 140cc8f81c7SPierre-Louis Bossart }, 141cc8f81c7SPierre-Louis Bossart {} 142cc8f81c7SPierre-Louis Bossart } 143cc8f81c7SPierre-Louis Bossart }, 144df1fceacSCezary Rojewski { 145df1fceacSCezary Rojewski .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, 146df1fceacSCezary Rojewski .device = 0x9d71, 147df1fceacSCezary Rojewski }, 148cc8f81c7SPierre-Louis Bossart #endif 149cc8f81c7SPierre-Louis Bossart 150cc8f81c7SPierre-Louis Bossart /* 151b79de57bSPierre-Louis Bossart * Geminilake uses legacy HDAudio driver except for Google 1529d36ceabSPierre-Louis Bossart * Chromebooks and devices based on the ES8336 codec 153cc8f81c7SPierre-Louis Bossart */ 154cc8f81c7SPierre-Louis Bossart /* Geminilake */ 155cc8f81c7SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE) 156cc8f81c7SPierre-Louis Bossart { 157cc8f81c7SPierre-Louis Bossart .flags = FLAG_SOF, 158cc8f81c7SPierre-Louis Bossart .device = 0x3198, 159cc8f81c7SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 160cc8f81c7SPierre-Louis Bossart { 161cc8f81c7SPierre-Louis Bossart .ident = "Google Chromebooks", 162cc8f81c7SPierre-Louis Bossart .matches = { 163cc8f81c7SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Google"), 164cc8f81c7SPierre-Louis Bossart } 165cc8f81c7SPierre-Louis Bossart }, 166cc8f81c7SPierre-Louis Bossart {} 167cc8f81c7SPierre-Louis Bossart } 168cc8f81c7SPierre-Louis Bossart }, 1699d36ceabSPierre-Louis Bossart { 1709d36ceabSPierre-Louis Bossart .flags = FLAG_SOF, 1719d36ceabSPierre-Louis Bossart .device = 0x3198, 172*de24d97fSPierre-Louis Bossart .codec_hid = &essx_83x6, 1739d36ceabSPierre-Louis Bossart }, 174cc8f81c7SPierre-Louis Bossart #endif 175cc8f81c7SPierre-Louis Bossart 176cc8f81c7SPierre-Louis Bossart /* 177cc8f81c7SPierre-Louis Bossart * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake use legacy 178b79de57bSPierre-Louis Bossart * HDAudio driver except for Google Chromebooks and when DMICs are 179cc8f81c7SPierre-Louis Bossart * present. Two cases are required since Coreboot does not expose NHLT 180cc8f81c7SPierre-Louis Bossart * tables. 181cc8f81c7SPierre-Louis Bossart * 182cc8f81c7SPierre-Louis Bossart * When the Chromebook quirk is not present, it's based on information 183cc8f81c7SPierre-Louis Bossart * that no such device exists. When the quirk is present, it could be 184cc8f81c7SPierre-Louis Bossart * either based on product information or a placeholder. 185cc8f81c7SPierre-Louis Bossart */ 186cc8f81c7SPierre-Louis Bossart 18782d9d54aSJaroslav Kysela /* Cannonlake */ 18882d9d54aSJaroslav Kysela #if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE) 18982d9d54aSJaroslav Kysela { 190cc8f81c7SPierre-Louis Bossart .flags = FLAG_SOF, 191cc8f81c7SPierre-Louis Bossart .device = 0x9dc8, 192cc8f81c7SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 193cc8f81c7SPierre-Louis Bossart { 194cc8f81c7SPierre-Louis Bossart .ident = "Google Chromebooks", 195cc8f81c7SPierre-Louis Bossart .matches = { 196cc8f81c7SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Google"), 197cc8f81c7SPierre-Louis Bossart } 198cc8f81c7SPierre-Louis Bossart }, 199cc8f81c7SPierre-Louis Bossart {} 200cc8f81c7SPierre-Louis Bossart } 201cc8f81c7SPierre-Louis Bossart }, 202cc8f81c7SPierre-Louis Bossart { 20306508575SPierre-Louis Bossart .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 20482d9d54aSJaroslav Kysela .device = 0x9dc8, 20582d9d54aSJaroslav Kysela }, 20682d9d54aSJaroslav Kysela #endif 207cc8f81c7SPierre-Louis Bossart 20882d9d54aSJaroslav Kysela /* Coffelake */ 20982d9d54aSJaroslav Kysela #if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE) 21082d9d54aSJaroslav Kysela { 211cc8f81c7SPierre-Louis Bossart .flags = FLAG_SOF, 212cc8f81c7SPierre-Louis Bossart .device = 0xa348, 213cc8f81c7SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 214cc8f81c7SPierre-Louis Bossart { 215cc8f81c7SPierre-Louis Bossart .ident = "Google Chromebooks", 216cc8f81c7SPierre-Louis Bossart .matches = { 217cc8f81c7SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Google"), 218cc8f81c7SPierre-Louis Bossart } 219cc8f81c7SPierre-Louis Bossart }, 220cc8f81c7SPierre-Louis Bossart {} 221cc8f81c7SPierre-Louis Bossart } 222cc8f81c7SPierre-Louis Bossart }, 223cc8f81c7SPierre-Louis Bossart { 22406508575SPierre-Louis Bossart .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 22582d9d54aSJaroslav Kysela .device = 0xa348, 22682d9d54aSJaroslav Kysela }, 22782d9d54aSJaroslav Kysela #endif 228cc8f81c7SPierre-Louis Bossart 2294228668eSPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE) 230cc8f81c7SPierre-Louis Bossart /* Cometlake-LP */ 231cc8f81c7SPierre-Louis Bossart { 232cc8f81c7SPierre-Louis Bossart .flags = FLAG_SOF, 233cc8f81c7SPierre-Louis Bossart .device = 0x02c8, 234cc8f81c7SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 235cc8f81c7SPierre-Louis Bossart { 236cc8f81c7SPierre-Louis Bossart .ident = "Google Chromebooks", 237cc8f81c7SPierre-Louis Bossart .matches = { 238cc8f81c7SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Google"), 239cc8f81c7SPierre-Louis Bossart } 240cc8f81c7SPierre-Louis Bossart }, 24106508575SPierre-Louis Bossart { 24206508575SPierre-Louis Bossart .matches = { 24306508575SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 24406508575SPierre-Louis Bossart DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6") 24506508575SPierre-Louis Bossart }, 24606508575SPierre-Louis Bossart }, 24706508575SPierre-Louis Bossart { 24806508575SPierre-Louis Bossart /* early version of SKU 09C6 */ 24906508575SPierre-Louis Bossart .matches = { 25006508575SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 25106508575SPierre-Louis Bossart DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983") 25206508575SPierre-Louis Bossart }, 25306508575SPierre-Louis Bossart }, 254cc8f81c7SPierre-Louis Bossart {} 255cc8f81c7SPierre-Louis Bossart } 256cc8f81c7SPierre-Louis Bossart }, 257cc8f81c7SPierre-Louis Bossart { 258ae26c08eSPierre-Louis Bossart .flags = FLAG_SOF, 259ae26c08eSPierre-Louis Bossart .device = 0x02c8, 260*de24d97fSPierre-Louis Bossart .codec_hid = &essx_83x6, 261ae26c08eSPierre-Louis Bossart }, 262081c7370SBrent Lu { 263081c7370SBrent Lu .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 264081c7370SBrent Lu .device = 0x02c8, 265081c7370SBrent Lu }, 266cc8f81c7SPierre-Louis Bossart /* Cometlake-H */ 267cc8f81c7SPierre-Louis Bossart { 26806508575SPierre-Louis Bossart .flags = FLAG_SOF, 26906508575SPierre-Louis Bossart .device = 0x06c8, 27006508575SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 27106508575SPierre-Louis Bossart { 27206508575SPierre-Louis Bossart .matches = { 27306508575SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 27406508575SPierre-Louis Bossart DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"), 27506508575SPierre-Louis Bossart }, 27606508575SPierre-Louis Bossart }, 27706508575SPierre-Louis Bossart { 27806508575SPierre-Louis Bossart .matches = { 27906508575SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 28006508575SPierre-Louis Bossart DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"), 28106508575SPierre-Louis Bossart }, 28206508575SPierre-Louis Bossart }, 28306508575SPierre-Louis Bossart {} 28406508575SPierre-Louis Bossart } 28506508575SPierre-Louis Bossart }, 28606508575SPierre-Louis Bossart { 287ae26c08eSPierre-Louis Bossart .flags = FLAG_SOF, 288ae26c08eSPierre-Louis Bossart .device = 0x06c8, 289*de24d97fSPierre-Louis Bossart .codec_hid = &essx_83x6, 290ae26c08eSPierre-Louis Bossart }, 291081c7370SBrent Lu { 292081c7370SBrent Lu .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 293081c7370SBrent Lu .device = 0x06c8, 294081c7370SBrent Lu }, 295cc8f81c7SPierre-Louis Bossart #endif 296cc8f81c7SPierre-Louis Bossart 297cc8f81c7SPierre-Louis Bossart /* Icelake */ 298cc8f81c7SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) 299cc8f81c7SPierre-Louis Bossart { 300cc8f81c7SPierre-Louis Bossart .flags = FLAG_SOF, 301cc8f81c7SPierre-Louis Bossart .device = 0x34c8, 302cc8f81c7SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 303cc8f81c7SPierre-Louis Bossart { 304cc8f81c7SPierre-Louis Bossart .ident = "Google Chromebooks", 305cc8f81c7SPierre-Louis Bossart .matches = { 306cc8f81c7SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Google"), 307cc8f81c7SPierre-Louis Bossart } 308cc8f81c7SPierre-Louis Bossart }, 309cc8f81c7SPierre-Louis Bossart {} 310cc8f81c7SPierre-Louis Bossart } 311cc8f81c7SPierre-Louis Bossart }, 312cc8f81c7SPierre-Louis Bossart { 31306508575SPierre-Louis Bossart .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 314cc8f81c7SPierre-Louis Bossart .device = 0x34c8, 315cc8f81c7SPierre-Louis Bossart }, 316cc8f81c7SPierre-Louis Bossart #endif 317cc8f81c7SPierre-Louis Bossart 318fa9730b4SPierre-Louis Bossart /* Jasper Lake */ 319fa9730b4SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE) 320fa9730b4SPierre-Louis Bossart { 321fa9730b4SPierre-Louis Bossart .flags = FLAG_SOF, 322fa9730b4SPierre-Louis Bossart .device = 0x4dc8, 32319980aa1SBrent Lu .dmi_table = (const struct dmi_system_id []) { 32419980aa1SBrent Lu { 32519980aa1SBrent Lu .ident = "Google Chromebooks", 32619980aa1SBrent Lu .matches = { 32719980aa1SBrent Lu DMI_MATCH(DMI_SYS_VENDOR, "Google"), 32819980aa1SBrent Lu } 32919980aa1SBrent Lu }, 33019980aa1SBrent Lu {} 33119980aa1SBrent Lu } 33219980aa1SBrent Lu }, 33319980aa1SBrent Lu { 33419980aa1SBrent Lu .flags = FLAG_SOF, 33519980aa1SBrent Lu .device = 0x4dc8, 336*de24d97fSPierre-Louis Bossart .codec_hid = &essx_83x6, 337fa9730b4SPierre-Louis Bossart }, 33819980aa1SBrent Lu { 33919980aa1SBrent Lu .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, 34019980aa1SBrent Lu .device = 0x4dc8, 34119980aa1SBrent Lu }, 342fa9730b4SPierre-Louis Bossart #endif 343fa9730b4SPierre-Louis Bossart 344cc8f81c7SPierre-Louis Bossart /* Tigerlake */ 345cc8f81c7SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) 346cc8f81c7SPierre-Louis Bossart { 347cc8f81c7SPierre-Louis Bossart .flags = FLAG_SOF, 348cc8f81c7SPierre-Louis Bossart .device = 0xa0c8, 349cc8f81c7SPierre-Louis Bossart .dmi_table = (const struct dmi_system_id []) { 350cc8f81c7SPierre-Louis Bossart { 351cc8f81c7SPierre-Louis Bossart .ident = "Google Chromebooks", 352cc8f81c7SPierre-Louis Bossart .matches = { 353cc8f81c7SPierre-Louis Bossart DMI_MATCH(DMI_SYS_VENDOR, "Google"), 354cc8f81c7SPierre-Louis Bossart } 355cc8f81c7SPierre-Louis Bossart }, 356cc8f81c7SPierre-Louis Bossart {} 357cc8f81c7SPierre-Louis Bossart } 358cc8f81c7SPierre-Louis Bossart }, 359cc8f81c7SPierre-Louis Bossart { 360081c7370SBrent Lu .flags = FLAG_SOF, 361081c7370SBrent Lu .device = 0xa0c8, 362*de24d97fSPierre-Louis Bossart .codec_hid = &essx_83x6, 363081c7370SBrent Lu }, 364081c7370SBrent Lu { 36506508575SPierre-Louis Bossart .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 366cc8f81c7SPierre-Louis Bossart .device = 0xa0c8, 367cc8f81c7SPierre-Louis Bossart }, 368c5b5ff60SBard Liao { 369c5b5ff60SBard Liao .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 370c5b5ff60SBard Liao .device = 0x43c8, 371c5b5ff60SBard Liao }, 372cc8f81c7SPierre-Louis Bossart #endif 373cc8f81c7SPierre-Louis Bossart 374cc8f81c7SPierre-Louis Bossart /* Elkhart Lake */ 375cc8f81c7SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE) 376cc8f81c7SPierre-Louis Bossart { 377cc8f81c7SPierre-Louis Bossart .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, 378cc8f81c7SPierre-Louis Bossart .device = 0x4b55, 379cc8f81c7SPierre-Louis Bossart }, 380114613f6SPierre-Louis Bossart { 381114613f6SPierre-Louis Bossart .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, 382114613f6SPierre-Louis Bossart .device = 0x4b58, 383114613f6SPierre-Louis Bossart }, 384cc8f81c7SPierre-Louis Bossart #endif 385cc8f81c7SPierre-Louis Bossart 386c4294d7fSKai Vehmanen /* Alder Lake */ 387c4294d7fSKai Vehmanen #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) 388c4294d7fSKai Vehmanen { 389c4294d7fSKai Vehmanen .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 390c4294d7fSKai Vehmanen .device = 0x7ad0, 391c4294d7fSKai Vehmanen }, 392c4294d7fSKai Vehmanen { 393c4294d7fSKai Vehmanen .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 394c4294d7fSKai Vehmanen .device = 0x51c8, 395c4294d7fSKai Vehmanen }, 3964ad7935dSKai Vehmanen { 3974ad7935dSKai Vehmanen .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 3984ad7935dSKai Vehmanen .device = 0x51cc, 3994ad7935dSKai Vehmanen }, 4004d5a628dSKai Vehmanen { 4014d5a628dSKai Vehmanen .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 402ca1ece24SKai Vehmanen .device = 0x51cd, 403ca1ece24SKai Vehmanen }, 404ca1ece24SKai Vehmanen { 405ca1ece24SKai Vehmanen .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 4064d5a628dSKai Vehmanen .device = 0x54c8, 4074d5a628dSKai Vehmanen }, 408c4294d7fSKai Vehmanen #endif 409c4294d7fSKai Vehmanen 41082d9d54aSJaroslav Kysela }; 41182d9d54aSJaroslav Kysela 41282d9d54aSJaroslav Kysela static const struct config_entry *snd_intel_dsp_find_config 41382d9d54aSJaroslav Kysela (struct pci_dev *pci, const struct config_entry *table, u32 len) 41482d9d54aSJaroslav Kysela { 41582d9d54aSJaroslav Kysela u16 device; 41682d9d54aSJaroslav Kysela 41782d9d54aSJaroslav Kysela device = pci->device; 41882d9d54aSJaroslav Kysela for (; len > 0; len--, table++) { 41982d9d54aSJaroslav Kysela if (table->device != device) 42082d9d54aSJaroslav Kysela continue; 42182d9d54aSJaroslav Kysela if (table->dmi_table && !dmi_check_system(table->dmi_table)) 42282d9d54aSJaroslav Kysela continue; 423*de24d97fSPierre-Louis Bossart if (table->codec_hid) { 424*de24d97fSPierre-Louis Bossart int i; 425*de24d97fSPierre-Louis Bossart 426*de24d97fSPierre-Louis Bossart for (i = 0; i < table->codec_hid->num_codecs; i++) 427*de24d97fSPierre-Louis Bossart if (acpi_dev_present(table->codec_hid->codecs[i], NULL, -1)) 428*de24d97fSPierre-Louis Bossart break; 429*de24d97fSPierre-Louis Bossart if (i == table->codec_hid->num_codecs) 4309d36ceabSPierre-Louis Bossart continue; 431*de24d97fSPierre-Louis Bossart } 43282d9d54aSJaroslav Kysela return table; 43382d9d54aSJaroslav Kysela } 43482d9d54aSJaroslav Kysela return NULL; 43582d9d54aSJaroslav Kysela } 43682d9d54aSJaroslav Kysela 43782d9d54aSJaroslav Kysela static int snd_intel_dsp_check_dmic(struct pci_dev *pci) 43882d9d54aSJaroslav Kysela { 43982d9d54aSJaroslav Kysela struct nhlt_acpi_table *nhlt; 44082d9d54aSJaroslav Kysela int ret = 0; 44182d9d54aSJaroslav Kysela 44282d9d54aSJaroslav Kysela nhlt = intel_nhlt_init(&pci->dev); 44382d9d54aSJaroslav Kysela if (nhlt) { 4448235a08bSAmadeusz Sławiński if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_DMIC)) 44582d9d54aSJaroslav Kysela ret = 1; 44682d9d54aSJaroslav Kysela intel_nhlt_free(nhlt); 44782d9d54aSJaroslav Kysela } 44882d9d54aSJaroslav Kysela return ret; 44982d9d54aSJaroslav Kysela } 45082d9d54aSJaroslav Kysela 45106508575SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) 45206508575SPierre-Louis Bossart static int snd_intel_dsp_check_soundwire(struct pci_dev *pci) 45306508575SPierre-Louis Bossart { 45406508575SPierre-Louis Bossart struct sdw_intel_acpi_info info; 45506508575SPierre-Louis Bossart acpi_handle handle; 45606508575SPierre-Louis Bossart int ret; 45706508575SPierre-Louis Bossart 45806508575SPierre-Louis Bossart handle = ACPI_HANDLE(&pci->dev); 45906508575SPierre-Louis Bossart 46006508575SPierre-Louis Bossart ret = sdw_intel_acpi_scan(handle, &info); 46106508575SPierre-Louis Bossart if (ret < 0) 46206508575SPierre-Louis Bossart return ret; 46306508575SPierre-Louis Bossart 46406508575SPierre-Louis Bossart return info.link_mask; 46506508575SPierre-Louis Bossart } 46606508575SPierre-Louis Bossart #else 46706508575SPierre-Louis Bossart static int snd_intel_dsp_check_soundwire(struct pci_dev *pci) 46806508575SPierre-Louis Bossart { 46906508575SPierre-Louis Bossart return 0; 47006508575SPierre-Louis Bossart } 47106508575SPierre-Louis Bossart #endif 47206508575SPierre-Louis Bossart 47382d9d54aSJaroslav Kysela int snd_intel_dsp_driver_probe(struct pci_dev *pci) 47482d9d54aSJaroslav Kysela { 47582d9d54aSJaroslav Kysela const struct config_entry *cfg; 47682d9d54aSJaroslav Kysela 47791636a82STakashi Iwai /* Intel vendor only */ 47891636a82STakashi Iwai if (pci->vendor != 0x8086) 47991636a82STakashi Iwai return SND_INTEL_DSP_DRIVER_ANY; 48091636a82STakashi Iwai 4810e5cc221SPierre-Louis Bossart /* 4820e5cc221SPierre-Louis Bossart * Legacy devices don't have a PCI-based DSP and use HDaudio 4830e5cc221SPierre-Louis Bossart * for HDMI/DP support, ignore kernel parameter 4840e5cc221SPierre-Louis Bossart */ 4850e5cc221SPierre-Louis Bossart switch (pci->device) { 4860e5cc221SPierre-Louis Bossart case 0x160c: /* Broadwell */ 4870e5cc221SPierre-Louis Bossart case 0x0a0c: /* Haswell */ 4880e5cc221SPierre-Louis Bossart case 0x0c0c: 4890e5cc221SPierre-Louis Bossart case 0x0d0c: 4900e5cc221SPierre-Louis Bossart case 0x0f04: /* Baytrail */ 4910e5cc221SPierre-Louis Bossart case 0x2284: /* Braswell */ 4920e5cc221SPierre-Louis Bossart return SND_INTEL_DSP_DRIVER_ANY; 4930e5cc221SPierre-Louis Bossart } 4940e5cc221SPierre-Louis Bossart 49582d9d54aSJaroslav Kysela if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) 49682d9d54aSJaroslav Kysela return dsp_driver; 49782d9d54aSJaroslav Kysela 49882d9d54aSJaroslav Kysela /* 49982d9d54aSJaroslav Kysela * detect DSP by checking class/subclass/prog-id information 50082d9d54aSJaroslav Kysela * class=04 subclass 03 prog-if 00: no DSP, use legacy driver 50182d9d54aSJaroslav Kysela * class=04 subclass 01 prog-if 00: DSP is present 50282d9d54aSJaroslav Kysela * (and may be required e.g. for DMIC or SSP support) 50382d9d54aSJaroslav Kysela * class=04 subclass 03 prog-if 80: use DSP or legacy mode 50482d9d54aSJaroslav Kysela */ 50582d9d54aSJaroslav Kysela if (pci->class == 0x040300) 50682d9d54aSJaroslav Kysela return SND_INTEL_DSP_DRIVER_LEGACY; 50782d9d54aSJaroslav Kysela if (pci->class != 0x040100 && pci->class != 0x040380) { 508b79de57bSPierre-Louis Bossart dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class); 50982d9d54aSJaroslav Kysela return SND_INTEL_DSP_DRIVER_LEGACY; 51082d9d54aSJaroslav Kysela } 51182d9d54aSJaroslav Kysela 51282d9d54aSJaroslav Kysela dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class); 51382d9d54aSJaroslav Kysela 51482d9d54aSJaroslav Kysela /* find the configuration for the specific device */ 51582d9d54aSJaroslav Kysela cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table)); 51682d9d54aSJaroslav Kysela if (!cfg) 51782d9d54aSJaroslav Kysela return SND_INTEL_DSP_DRIVER_ANY; 51882d9d54aSJaroslav Kysela 51982d9d54aSJaroslav Kysela if (cfg->flags & FLAG_SOF) { 52006508575SPierre-Louis Bossart if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE && 52106508575SPierre-Louis Bossart snd_intel_dsp_check_soundwire(pci) > 0) { 52206508575SPierre-Louis Bossart dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n"); 52306508575SPierre-Louis Bossart return SND_INTEL_DSP_DRIVER_SOF; 52406508575SPierre-Louis Bossart } 52506508575SPierre-Louis Bossart if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC && 52606508575SPierre-Louis Bossart snd_intel_dsp_check_dmic(pci)) { 52782d9d54aSJaroslav Kysela dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n"); 52882d9d54aSJaroslav Kysela return SND_INTEL_DSP_DRIVER_SOF; 52982d9d54aSJaroslav Kysela } 53006508575SPierre-Louis Bossart if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE)) 53182d9d54aSJaroslav Kysela return SND_INTEL_DSP_DRIVER_SOF; 53282d9d54aSJaroslav Kysela } 53382d9d54aSJaroslav Kysela 534df1fceacSCezary Rojewski 535df1fceacSCezary Rojewski if (cfg->flags & FLAG_SST) { 536df1fceacSCezary Rojewski if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) { 537df1fceacSCezary Rojewski if (snd_intel_dsp_check_dmic(pci)) { 538df1fceacSCezary Rojewski dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n"); 53982d9d54aSJaroslav Kysela return SND_INTEL_DSP_DRIVER_SST; 540df1fceacSCezary Rojewski } 541df1fceacSCezary Rojewski } else { 542df1fceacSCezary Rojewski return SND_INTEL_DSP_DRIVER_SST; 543df1fceacSCezary Rojewski } 544df1fceacSCezary Rojewski } 54582d9d54aSJaroslav Kysela 54682d9d54aSJaroslav Kysela return SND_INTEL_DSP_DRIVER_LEGACY; 54782d9d54aSJaroslav Kysela } 54882d9d54aSJaroslav Kysela EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe); 54982d9d54aSJaroslav Kysela 5505427c7d6SHans de Goede /* Should we default to SOF or SST for BYT/CHT ? */ 5515427c7d6SHans de Goede #if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \ 5525427c7d6SHans de Goede !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) 5535427c7d6SHans de Goede #define FLAG_SST_OR_SOF_BYT FLAG_SOF 5545427c7d6SHans de Goede #else 5555427c7d6SHans de Goede #define FLAG_SST_OR_SOF_BYT FLAG_SST 5565427c7d6SHans de Goede #endif 5575427c7d6SHans de Goede 558b5682305SPierre-Louis Bossart /* 559b5682305SPierre-Louis Bossart * configuration table 560b5682305SPierre-Louis Bossart * - the order of similar ACPI ID entries is important! 561b5682305SPierre-Louis Bossart * - the first successful match will win 562b5682305SPierre-Louis Bossart */ 563b5682305SPierre-Louis Bossart static const struct config_entry acpi_config_table[] = { 5645427c7d6SHans de Goede #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \ 5655427c7d6SHans de Goede IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) 566b5682305SPierre-Louis Bossart /* BayTrail */ 567b5682305SPierre-Louis Bossart { 5685427c7d6SHans de Goede .flags = FLAG_SST_OR_SOF_BYT, 569b5682305SPierre-Louis Bossart .acpi_hid = "80860F28", 570b5682305SPierre-Louis Bossart }, 571b5682305SPierre-Louis Bossart /* CherryTrail */ 572b5682305SPierre-Louis Bossart { 5735427c7d6SHans de Goede .flags = FLAG_SST_OR_SOF_BYT, 574b5682305SPierre-Louis Bossart .acpi_hid = "808622A8", 575b5682305SPierre-Louis Bossart }, 576b5682305SPierre-Louis Bossart #endif 577803e5913SPierre-Louis Bossart /* Broadwell */ 578803e5913SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT) 579803e5913SPierre-Louis Bossart { 580803e5913SPierre-Louis Bossart .flags = FLAG_SST, 581803e5913SPierre-Louis Bossart .acpi_hid = "INT3438" 582803e5913SPierre-Louis Bossart }, 583803e5913SPierre-Louis Bossart #endif 584803e5913SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) 585803e5913SPierre-Louis Bossart { 586803e5913SPierre-Louis Bossart .flags = FLAG_SOF, 587803e5913SPierre-Louis Bossart .acpi_hid = "INT3438" 588803e5913SPierre-Louis Bossart }, 589803e5913SPierre-Louis Bossart #endif 590803e5913SPierre-Louis Bossart /* Haswell - not supported by SOF but added for consistency */ 591803e5913SPierre-Louis Bossart #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT) 592803e5913SPierre-Louis Bossart { 593803e5913SPierre-Louis Bossart .flags = FLAG_SST, 594803e5913SPierre-Louis Bossart .acpi_hid = "INT33C8" 595803e5913SPierre-Louis Bossart }, 596803e5913SPierre-Louis Bossart #endif 597b5682305SPierre-Louis Bossart }; 598b5682305SPierre-Louis Bossart 599b5682305SPierre-Louis Bossart static const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN], 600b5682305SPierre-Louis Bossart const struct config_entry *table, 601b5682305SPierre-Louis Bossart u32 len) 602b5682305SPierre-Louis Bossart { 603b5682305SPierre-Louis Bossart for (; len > 0; len--, table++) { 604b5682305SPierre-Louis Bossart if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN)) 605b5682305SPierre-Louis Bossart continue; 606b5682305SPierre-Louis Bossart if (table->dmi_table && !dmi_check_system(table->dmi_table)) 607b5682305SPierre-Louis Bossart continue; 608b5682305SPierre-Louis Bossart return table; 609b5682305SPierre-Louis Bossart } 610b5682305SPierre-Louis Bossart return NULL; 611b5682305SPierre-Louis Bossart } 612b5682305SPierre-Louis Bossart 613b5682305SPierre-Louis Bossart int snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN]) 614b5682305SPierre-Louis Bossart { 615b5682305SPierre-Louis Bossart const struct config_entry *cfg; 616b5682305SPierre-Louis Bossart 617b5682305SPierre-Louis Bossart if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) 618b5682305SPierre-Louis Bossart return dsp_driver; 619b5682305SPierre-Louis Bossart 620b5682305SPierre-Louis Bossart if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) { 621b5682305SPierre-Louis Bossart dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n", 622b5682305SPierre-Louis Bossart SND_INTEL_DSP_DRIVER_LEGACY); 623b5682305SPierre-Louis Bossart } 624b5682305SPierre-Louis Bossart 625b5682305SPierre-Louis Bossart /* find the configuration for the specific device */ 626b5682305SPierre-Louis Bossart cfg = snd_intel_acpi_dsp_find_config(acpi_hid, acpi_config_table, 627b5682305SPierre-Louis Bossart ARRAY_SIZE(acpi_config_table)); 628b5682305SPierre-Louis Bossart if (!cfg) 629b5682305SPierre-Louis Bossart return SND_INTEL_DSP_DRIVER_ANY; 630b5682305SPierre-Louis Bossart 631b5682305SPierre-Louis Bossart if (cfg->flags & FLAG_SST) 632b5682305SPierre-Louis Bossart return SND_INTEL_DSP_DRIVER_SST; 633b5682305SPierre-Louis Bossart 634b5682305SPierre-Louis Bossart if (cfg->flags & FLAG_SOF) 635b5682305SPierre-Louis Bossart return SND_INTEL_DSP_DRIVER_SOF; 636b5682305SPierre-Louis Bossart 637b5682305SPierre-Louis Bossart return SND_INTEL_DSP_DRIVER_SST; 638b5682305SPierre-Louis Bossart } 639b5682305SPierre-Louis Bossart EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe); 640b5682305SPierre-Louis Bossart 64182d9d54aSJaroslav Kysela MODULE_LICENSE("GPL v2"); 64282d9d54aSJaroslav Kysela MODULE_DESCRIPTION("Intel DSP config driver"); 64308c2a4bcSPierre-Louis Bossart MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI); 644