18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci// Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz> 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/acpi.h> 58c2ecf20Sopenharmony_ci#include <linux/bits.h> 68c2ecf20Sopenharmony_ci#include <linux/dmi.h> 78c2ecf20Sopenharmony_ci#include <linux/module.h> 88c2ecf20Sopenharmony_ci#include <linux/pci.h> 98c2ecf20Sopenharmony_ci#include <linux/soundwire/sdw.h> 108c2ecf20Sopenharmony_ci#include <linux/soundwire/sdw_intel.h> 118c2ecf20Sopenharmony_ci#include <sound/core.h> 128c2ecf20Sopenharmony_ci#include <sound/intel-dsp-config.h> 138c2ecf20Sopenharmony_ci#include <sound/intel-nhlt.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistatic int dsp_driver; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cimodule_param(dsp_driver, int, 0444); 188c2ecf20Sopenharmony_ciMODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)"); 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define FLAG_SST BIT(0) 218c2ecf20Sopenharmony_ci#define FLAG_SOF BIT(1) 228c2ecf20Sopenharmony_ci#define FLAG_SST_ONLY_IF_DMIC BIT(15) 238c2ecf20Sopenharmony_ci#define FLAG_SOF_ONLY_IF_DMIC BIT(16) 248c2ecf20Sopenharmony_ci#define FLAG_SOF_ONLY_IF_SOUNDWIRE BIT(17) 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \ 278c2ecf20Sopenharmony_ci FLAG_SOF_ONLY_IF_SOUNDWIRE) 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistruct config_entry { 308c2ecf20Sopenharmony_ci u32 flags; 318c2ecf20Sopenharmony_ci u16 device; 328c2ecf20Sopenharmony_ci const struct dmi_system_id *dmi_table; 338c2ecf20Sopenharmony_ci u8 codec_hid[ACPI_ID_LEN]; 348c2ecf20Sopenharmony_ci}; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* 378c2ecf20Sopenharmony_ci * configuration table 388c2ecf20Sopenharmony_ci * - the order of similar PCI ID entries is important! 398c2ecf20Sopenharmony_ci * - the first successful match will win 408c2ecf20Sopenharmony_ci */ 418c2ecf20Sopenharmony_cistatic const struct config_entry config_table[] = { 428c2ecf20Sopenharmony_ci/* Merrifield */ 438c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) 448c2ecf20Sopenharmony_ci { 458c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 468c2ecf20Sopenharmony_ci .device = 0x119a, 478c2ecf20Sopenharmony_ci }, 488c2ecf20Sopenharmony_ci#endif 498c2ecf20Sopenharmony_ci/* Broxton-T */ 508c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) 518c2ecf20Sopenharmony_ci { 528c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 538c2ecf20Sopenharmony_ci .device = 0x1a98, 548c2ecf20Sopenharmony_ci }, 558c2ecf20Sopenharmony_ci#endif 568c2ecf20Sopenharmony_ci/* 578c2ecf20Sopenharmony_ci * Apollolake (Broxton-P) 588c2ecf20Sopenharmony_ci * the legacy HDAudio driver is used except on Up Squared (SOF) and 598c2ecf20Sopenharmony_ci * Chromebooks (SST), as well as devices based on the ES8336 codec 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) 628c2ecf20Sopenharmony_ci { 638c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 648c2ecf20Sopenharmony_ci .device = 0x5a98, 658c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 668c2ecf20Sopenharmony_ci { 678c2ecf20Sopenharmony_ci .ident = "Up Squared", 688c2ecf20Sopenharmony_ci .matches = { 698c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), 708c2ecf20Sopenharmony_ci DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"), 718c2ecf20Sopenharmony_ci } 728c2ecf20Sopenharmony_ci }, 738c2ecf20Sopenharmony_ci {} 748c2ecf20Sopenharmony_ci } 758c2ecf20Sopenharmony_ci }, 768c2ecf20Sopenharmony_ci { 778c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 788c2ecf20Sopenharmony_ci .device = 0x5a98, 798c2ecf20Sopenharmony_ci .codec_hid = "ESSX8336", 808c2ecf20Sopenharmony_ci }, 818c2ecf20Sopenharmony_ci#endif 828c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL) 838c2ecf20Sopenharmony_ci { 848c2ecf20Sopenharmony_ci .flags = FLAG_SST, 858c2ecf20Sopenharmony_ci .device = 0x5a98, 868c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 878c2ecf20Sopenharmony_ci { 888c2ecf20Sopenharmony_ci .ident = "Google Chromebooks", 898c2ecf20Sopenharmony_ci .matches = { 908c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Google"), 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci }, 938c2ecf20Sopenharmony_ci {} 948c2ecf20Sopenharmony_ci } 958c2ecf20Sopenharmony_ci }, 968c2ecf20Sopenharmony_ci#endif 978c2ecf20Sopenharmony_ci/* 988c2ecf20Sopenharmony_ci * Skylake and Kabylake use legacy HDAudio driver except for Google 998c2ecf20Sopenharmony_ci * Chromebooks (SST) 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci/* Sunrise Point-LP */ 1038c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL) 1048c2ecf20Sopenharmony_ci { 1058c2ecf20Sopenharmony_ci .flags = FLAG_SST, 1068c2ecf20Sopenharmony_ci .device = 0x9d70, 1078c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 1088c2ecf20Sopenharmony_ci { 1098c2ecf20Sopenharmony_ci .ident = "Google Chromebooks", 1108c2ecf20Sopenharmony_ci .matches = { 1118c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Google"), 1128c2ecf20Sopenharmony_ci } 1138c2ecf20Sopenharmony_ci }, 1148c2ecf20Sopenharmony_ci {} 1158c2ecf20Sopenharmony_ci } 1168c2ecf20Sopenharmony_ci }, 1178c2ecf20Sopenharmony_ci { 1188c2ecf20Sopenharmony_ci .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, 1198c2ecf20Sopenharmony_ci .device = 0x9d70, 1208c2ecf20Sopenharmony_ci }, 1218c2ecf20Sopenharmony_ci#endif 1228c2ecf20Sopenharmony_ci/* Kabylake-LP */ 1238c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL) 1248c2ecf20Sopenharmony_ci { 1258c2ecf20Sopenharmony_ci .flags = FLAG_SST, 1268c2ecf20Sopenharmony_ci .device = 0x9d71, 1278c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 1288c2ecf20Sopenharmony_ci { 1298c2ecf20Sopenharmony_ci .ident = "Google Chromebooks", 1308c2ecf20Sopenharmony_ci .matches = { 1318c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Google"), 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci }, 1348c2ecf20Sopenharmony_ci {} 1358c2ecf20Sopenharmony_ci } 1368c2ecf20Sopenharmony_ci }, 1378c2ecf20Sopenharmony_ci { 1388c2ecf20Sopenharmony_ci .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, 1398c2ecf20Sopenharmony_ci .device = 0x9d71, 1408c2ecf20Sopenharmony_ci }, 1418c2ecf20Sopenharmony_ci#endif 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci/* 1448c2ecf20Sopenharmony_ci * Geminilake uses legacy HDAudio driver except for Google 1458c2ecf20Sopenharmony_ci * Chromebooks and devices based on the ES8336 codec 1468c2ecf20Sopenharmony_ci */ 1478c2ecf20Sopenharmony_ci/* Geminilake */ 1488c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE) 1498c2ecf20Sopenharmony_ci { 1508c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 1518c2ecf20Sopenharmony_ci .device = 0x3198, 1528c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 1538c2ecf20Sopenharmony_ci { 1548c2ecf20Sopenharmony_ci .ident = "Google Chromebooks", 1558c2ecf20Sopenharmony_ci .matches = { 1568c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Google"), 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci }, 1598c2ecf20Sopenharmony_ci {} 1608c2ecf20Sopenharmony_ci } 1618c2ecf20Sopenharmony_ci }, 1628c2ecf20Sopenharmony_ci { 1638c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 1648c2ecf20Sopenharmony_ci .device = 0x3198, 1658c2ecf20Sopenharmony_ci .codec_hid = "ESSX8336", 1668c2ecf20Sopenharmony_ci }, 1678c2ecf20Sopenharmony_ci#endif 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci/* 1708c2ecf20Sopenharmony_ci * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake use legacy 1718c2ecf20Sopenharmony_ci * HDAudio driver except for Google Chromebooks and when DMICs are 1728c2ecf20Sopenharmony_ci * present. Two cases are required since Coreboot does not expose NHLT 1738c2ecf20Sopenharmony_ci * tables. 1748c2ecf20Sopenharmony_ci * 1758c2ecf20Sopenharmony_ci * When the Chromebook quirk is not present, it's based on information 1768c2ecf20Sopenharmony_ci * that no such device exists. When the quirk is present, it could be 1778c2ecf20Sopenharmony_ci * either based on product information or a placeholder. 1788c2ecf20Sopenharmony_ci */ 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci/* Cannonlake */ 1818c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE) 1828c2ecf20Sopenharmony_ci { 1838c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 1848c2ecf20Sopenharmony_ci .device = 0x9dc8, 1858c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 1868c2ecf20Sopenharmony_ci { 1878c2ecf20Sopenharmony_ci .ident = "Google Chromebooks", 1888c2ecf20Sopenharmony_ci .matches = { 1898c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Google"), 1908c2ecf20Sopenharmony_ci } 1918c2ecf20Sopenharmony_ci }, 1928c2ecf20Sopenharmony_ci {} 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci }, 1958c2ecf20Sopenharmony_ci { 1968c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 1978c2ecf20Sopenharmony_ci .device = 0x9dc8, 1988c2ecf20Sopenharmony_ci }, 1998c2ecf20Sopenharmony_ci#endif 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci/* Coffelake */ 2028c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE) 2038c2ecf20Sopenharmony_ci { 2048c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 2058c2ecf20Sopenharmony_ci .device = 0xa348, 2068c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 2078c2ecf20Sopenharmony_ci { 2088c2ecf20Sopenharmony_ci .ident = "Google Chromebooks", 2098c2ecf20Sopenharmony_ci .matches = { 2108c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Google"), 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci }, 2138c2ecf20Sopenharmony_ci {} 2148c2ecf20Sopenharmony_ci } 2158c2ecf20Sopenharmony_ci }, 2168c2ecf20Sopenharmony_ci { 2178c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 2188c2ecf20Sopenharmony_ci .device = 0xa348, 2198c2ecf20Sopenharmony_ci }, 2208c2ecf20Sopenharmony_ci#endif 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE) 2238c2ecf20Sopenharmony_ci/* Cometlake-LP */ 2248c2ecf20Sopenharmony_ci { 2258c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 2268c2ecf20Sopenharmony_ci .device = 0x02c8, 2278c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 2288c2ecf20Sopenharmony_ci { 2298c2ecf20Sopenharmony_ci .ident = "Google Chromebooks", 2308c2ecf20Sopenharmony_ci .matches = { 2318c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Google"), 2328c2ecf20Sopenharmony_ci } 2338c2ecf20Sopenharmony_ci }, 2348c2ecf20Sopenharmony_ci { 2358c2ecf20Sopenharmony_ci .matches = { 2368c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 2378c2ecf20Sopenharmony_ci DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6") 2388c2ecf20Sopenharmony_ci }, 2398c2ecf20Sopenharmony_ci }, 2408c2ecf20Sopenharmony_ci { 2418c2ecf20Sopenharmony_ci /* early version of SKU 09C6 */ 2428c2ecf20Sopenharmony_ci .matches = { 2438c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 2448c2ecf20Sopenharmony_ci DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983") 2458c2ecf20Sopenharmony_ci }, 2468c2ecf20Sopenharmony_ci }, 2478c2ecf20Sopenharmony_ci {} 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci }, 2508c2ecf20Sopenharmony_ci { 2518c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 2528c2ecf20Sopenharmony_ci .device = 0x02c8, 2538c2ecf20Sopenharmony_ci }, 2548c2ecf20Sopenharmony_ci { 2558c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 2568c2ecf20Sopenharmony_ci .device = 0x02c8, 2578c2ecf20Sopenharmony_ci .codec_hid = "ESSX8336", 2588c2ecf20Sopenharmony_ci }, 2598c2ecf20Sopenharmony_ci/* Cometlake-H */ 2608c2ecf20Sopenharmony_ci { 2618c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 2628c2ecf20Sopenharmony_ci .device = 0x06c8, 2638c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 2648c2ecf20Sopenharmony_ci { 2658c2ecf20Sopenharmony_ci .matches = { 2668c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 2678c2ecf20Sopenharmony_ci DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"), 2688c2ecf20Sopenharmony_ci }, 2698c2ecf20Sopenharmony_ci }, 2708c2ecf20Sopenharmony_ci { 2718c2ecf20Sopenharmony_ci .matches = { 2728c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 2738c2ecf20Sopenharmony_ci DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"), 2748c2ecf20Sopenharmony_ci }, 2758c2ecf20Sopenharmony_ci }, 2768c2ecf20Sopenharmony_ci {} 2778c2ecf20Sopenharmony_ci } 2788c2ecf20Sopenharmony_ci }, 2798c2ecf20Sopenharmony_ci { 2808c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 2818c2ecf20Sopenharmony_ci .device = 0x06c8, 2828c2ecf20Sopenharmony_ci }, 2838c2ecf20Sopenharmony_ci { 2848c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 2858c2ecf20Sopenharmony_ci .device = 0x06c8, 2868c2ecf20Sopenharmony_ci .codec_hid = "ESSX8336", 2878c2ecf20Sopenharmony_ci }, 2888c2ecf20Sopenharmony_ci#endif 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci/* Icelake */ 2918c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) 2928c2ecf20Sopenharmony_ci { 2938c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 2948c2ecf20Sopenharmony_ci .device = 0x34c8, 2958c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 2968c2ecf20Sopenharmony_ci { 2978c2ecf20Sopenharmony_ci .ident = "Google Chromebooks", 2988c2ecf20Sopenharmony_ci .matches = { 2998c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Google"), 3008c2ecf20Sopenharmony_ci } 3018c2ecf20Sopenharmony_ci }, 3028c2ecf20Sopenharmony_ci {} 3038c2ecf20Sopenharmony_ci } 3048c2ecf20Sopenharmony_ci }, 3058c2ecf20Sopenharmony_ci { 3068c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 3078c2ecf20Sopenharmony_ci .device = 0x34c8, 3088c2ecf20Sopenharmony_ci }, 3098c2ecf20Sopenharmony_ci#endif 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci/* JasperLake */ 3128c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE) 3138c2ecf20Sopenharmony_ci { 3148c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 3158c2ecf20Sopenharmony_ci .device = 0x4dc8, 3168c2ecf20Sopenharmony_ci .codec_hid = "ESSX8336", 3178c2ecf20Sopenharmony_ci }, 3188c2ecf20Sopenharmony_ci#endif 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci/* Tigerlake */ 3218c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) 3228c2ecf20Sopenharmony_ci { 3238c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 3248c2ecf20Sopenharmony_ci .device = 0xa0c8, 3258c2ecf20Sopenharmony_ci .dmi_table = (const struct dmi_system_id []) { 3268c2ecf20Sopenharmony_ci { 3278c2ecf20Sopenharmony_ci .ident = "Google Chromebooks", 3288c2ecf20Sopenharmony_ci .matches = { 3298c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Google"), 3308c2ecf20Sopenharmony_ci } 3318c2ecf20Sopenharmony_ci }, 3328c2ecf20Sopenharmony_ci { 3338c2ecf20Sopenharmony_ci .ident = "Google firmware", 3348c2ecf20Sopenharmony_ci .matches = { 3358c2ecf20Sopenharmony_ci DMI_MATCH(DMI_BIOS_VERSION, "Google"), 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci }, 3388c2ecf20Sopenharmony_ci {} 3398c2ecf20Sopenharmony_ci } 3408c2ecf20Sopenharmony_ci }, 3418c2ecf20Sopenharmony_ci { 3428c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 3438c2ecf20Sopenharmony_ci .device = 0xa0c8, 3448c2ecf20Sopenharmony_ci }, 3458c2ecf20Sopenharmony_ci { 3468c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 3478c2ecf20Sopenharmony_ci .device = 0x43c8, 3488c2ecf20Sopenharmony_ci }, 3498c2ecf20Sopenharmony_ci { 3508c2ecf20Sopenharmony_ci .flags = FLAG_SOF, 3518c2ecf20Sopenharmony_ci .device = 0xa0c8, 3528c2ecf20Sopenharmony_ci .codec_hid = "ESSX8336", 3538c2ecf20Sopenharmony_ci }, 3548c2ecf20Sopenharmony_ci#endif 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci/* Elkhart Lake */ 3578c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE) 3588c2ecf20Sopenharmony_ci { 3598c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, 3608c2ecf20Sopenharmony_ci .device = 0x4b55, 3618c2ecf20Sopenharmony_ci }, 3628c2ecf20Sopenharmony_ci { 3638c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, 3648c2ecf20Sopenharmony_ci .device = 0x4b58, 3658c2ecf20Sopenharmony_ci }, 3668c2ecf20Sopenharmony_ci#endif 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci/* Meteor Lake */ 3698c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE) 3708c2ecf20Sopenharmony_ci /* Meteorlake-P */ 3718c2ecf20Sopenharmony_ci { 3728c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 3738c2ecf20Sopenharmony_ci .device = 0x7e28, 3748c2ecf20Sopenharmony_ci }, 3758c2ecf20Sopenharmony_ci /* ArrowLake-S */ 3768c2ecf20Sopenharmony_ci { 3778c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 3788c2ecf20Sopenharmony_ci .device = PCI_DEVICE_ID_INTEL_HDA_ARL_S, 3798c2ecf20Sopenharmony_ci }, 3808c2ecf20Sopenharmony_ci /* ArrowLake */ 3818c2ecf20Sopenharmony_ci { 3828c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 3838c2ecf20Sopenharmony_ci .device = PCI_DEVICE_ID_INTEL_HDA_ARL, 3848c2ecf20Sopenharmony_ci }, 3858c2ecf20Sopenharmony_ci#endif 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci/* Lunar Lake */ 3888c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE) 3898c2ecf20Sopenharmony_ci /* Lunarlake-P */ 3908c2ecf20Sopenharmony_ci { 3918c2ecf20Sopenharmony_ci .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 3928c2ecf20Sopenharmony_ci .device = PCI_DEVICE_ID_INTEL_HDA_LNL_P, 3938c2ecf20Sopenharmony_ci }, 3948c2ecf20Sopenharmony_ci#endif 3958c2ecf20Sopenharmony_ci}; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_cistatic const struct config_entry *snd_intel_dsp_find_config 3988c2ecf20Sopenharmony_ci (struct pci_dev *pci, const struct config_entry *table, u32 len) 3998c2ecf20Sopenharmony_ci{ 4008c2ecf20Sopenharmony_ci u16 device; 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci device = pci->device; 4038c2ecf20Sopenharmony_ci for (; len > 0; len--, table++) { 4048c2ecf20Sopenharmony_ci if (table->device != device) 4058c2ecf20Sopenharmony_ci continue; 4068c2ecf20Sopenharmony_ci if (table->dmi_table && !dmi_check_system(table->dmi_table)) 4078c2ecf20Sopenharmony_ci continue; 4088c2ecf20Sopenharmony_ci if (table->codec_hid[0] && !acpi_dev_present(table->codec_hid, NULL, -1)) 4098c2ecf20Sopenharmony_ci continue; 4108c2ecf20Sopenharmony_ci return table; 4118c2ecf20Sopenharmony_ci } 4128c2ecf20Sopenharmony_ci return NULL; 4138c2ecf20Sopenharmony_ci} 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_cistatic int snd_intel_dsp_check_dmic(struct pci_dev *pci) 4168c2ecf20Sopenharmony_ci{ 4178c2ecf20Sopenharmony_ci struct nhlt_acpi_table *nhlt; 4188c2ecf20Sopenharmony_ci int ret = 0; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci nhlt = intel_nhlt_init(&pci->dev); 4218c2ecf20Sopenharmony_ci if (nhlt) { 4228c2ecf20Sopenharmony_ci if (intel_nhlt_get_dmic_geo(&pci->dev, nhlt)) 4238c2ecf20Sopenharmony_ci ret = 1; 4248c2ecf20Sopenharmony_ci intel_nhlt_free(nhlt); 4258c2ecf20Sopenharmony_ci } 4268c2ecf20Sopenharmony_ci return ret; 4278c2ecf20Sopenharmony_ci} 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) 4308c2ecf20Sopenharmony_cistatic int snd_intel_dsp_check_soundwire(struct pci_dev *pci) 4318c2ecf20Sopenharmony_ci{ 4328c2ecf20Sopenharmony_ci struct sdw_intel_acpi_info info; 4338c2ecf20Sopenharmony_ci acpi_handle handle; 4348c2ecf20Sopenharmony_ci int ret; 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci handle = ACPI_HANDLE(&pci->dev); 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci ret = sdw_intel_acpi_scan(handle, &info); 4398c2ecf20Sopenharmony_ci if (ret < 0) 4408c2ecf20Sopenharmony_ci return ret; 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci return info.link_mask; 4438c2ecf20Sopenharmony_ci} 4448c2ecf20Sopenharmony_ci#else 4458c2ecf20Sopenharmony_cistatic int snd_intel_dsp_check_soundwire(struct pci_dev *pci) 4468c2ecf20Sopenharmony_ci{ 4478c2ecf20Sopenharmony_ci return 0; 4488c2ecf20Sopenharmony_ci} 4498c2ecf20Sopenharmony_ci#endif 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ciint snd_intel_dsp_driver_probe(struct pci_dev *pci) 4528c2ecf20Sopenharmony_ci{ 4538c2ecf20Sopenharmony_ci const struct config_entry *cfg; 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci /* Intel vendor only */ 4568c2ecf20Sopenharmony_ci if (pci->vendor != 0x8086) 4578c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_ANY; 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) 4608c2ecf20Sopenharmony_ci return dsp_driver; 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ci /* 4638c2ecf20Sopenharmony_ci * detect DSP by checking class/subclass/prog-id information 4648c2ecf20Sopenharmony_ci * class=04 subclass 03 prog-if 00: no DSP, use legacy driver 4658c2ecf20Sopenharmony_ci * class=04 subclass 01 prog-if 00: DSP is present 4668c2ecf20Sopenharmony_ci * (and may be required e.g. for DMIC or SSP support) 4678c2ecf20Sopenharmony_ci * class=04 subclass 03 prog-if 80: use DSP or legacy mode 4688c2ecf20Sopenharmony_ci */ 4698c2ecf20Sopenharmony_ci if (pci->class == 0x040300) 4708c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_LEGACY; 4718c2ecf20Sopenharmony_ci if (pci->class != 0x040100 && pci->class != 0x040380) { 4728c2ecf20Sopenharmony_ci dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class); 4738c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_LEGACY; 4748c2ecf20Sopenharmony_ci } 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class); 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci /* find the configuration for the specific device */ 4798c2ecf20Sopenharmony_ci cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table)); 4808c2ecf20Sopenharmony_ci if (!cfg) 4818c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_ANY; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci if (cfg->flags & FLAG_SOF) { 4848c2ecf20Sopenharmony_ci if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE && 4858c2ecf20Sopenharmony_ci snd_intel_dsp_check_soundwire(pci) > 0) { 4868c2ecf20Sopenharmony_ci dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n"); 4878c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_SOF; 4888c2ecf20Sopenharmony_ci } 4898c2ecf20Sopenharmony_ci if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC && 4908c2ecf20Sopenharmony_ci snd_intel_dsp_check_dmic(pci)) { 4918c2ecf20Sopenharmony_ci dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n"); 4928c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_SOF; 4938c2ecf20Sopenharmony_ci } 4948c2ecf20Sopenharmony_ci if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE)) 4958c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_SOF; 4968c2ecf20Sopenharmony_ci } 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci if (cfg->flags & FLAG_SST) { 5008c2ecf20Sopenharmony_ci if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) { 5018c2ecf20Sopenharmony_ci if (snd_intel_dsp_check_dmic(pci)) { 5028c2ecf20Sopenharmony_ci dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n"); 5038c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_SST; 5048c2ecf20Sopenharmony_ci } 5058c2ecf20Sopenharmony_ci } else { 5068c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_SST; 5078c2ecf20Sopenharmony_ci } 5088c2ecf20Sopenharmony_ci } 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci return SND_INTEL_DSP_DRIVER_LEGACY; 5118c2ecf20Sopenharmony_ci} 5128c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe); 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 5158c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Intel DSP config driver"); 5168c2ecf20Sopenharmony_ciMODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT); 517