diff options
Diffstat (limited to 'sound/hda/intel-dsp-config.c')
-rw-r--r-- | sound/hda/intel-dsp-config.c | 413 |
1 files changed, 376 insertions, 37 deletions
diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c index 1c5114dedda9..6a384b922e4f 100644 --- a/sound/hda/intel-dsp-config.c +++ b/sound/hda/intel-dsp-config.c @@ -11,6 +11,7 @@ #include <sound/core.h> #include <sound/intel-dsp-config.h> #include <sound/intel-nhlt.h> +#include <sound/soc-acpi.h> static int dsp_driver; @@ -29,7 +30,14 @@ MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=lega struct config_entry { u32 flags; u16 device; + u8 acpi_hid[ACPI_ID_LEN]; const struct dmi_system_id *dmi_table; + const struct snd_soc_acpi_codecs *codec_hid; +}; + +static const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = { + .num_codecs = 3, + .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, }; /* @@ -42,25 +50,18 @@ static const struct config_entry config_table[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) { .flags = FLAG_SOF, - .device = 0x119a, - }, -#endif -/* Broxton-T */ -#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) - { - .flags = FLAG_SOF, - .device = 0x1a98, + .device = PCI_DEVICE_ID_INTEL_SST_TNG, }, #endif /* * Apollolake (Broxton-P) * the legacy HDAudio driver is used except on Up Squared (SOF) and - * Chromebooks (SST) + * Chromebooks (SST), as well as devices based on the ES8336 codec */ #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) { .flags = FLAG_SOF, - .device = 0x5a98, + .device = PCI_DEVICE_ID_INTEL_HDA_APL, .dmi_table = (const struct dmi_system_id []) { { .ident = "Up Squared", @@ -72,11 +73,16 @@ static const struct config_entry config_table[] = { {} } }, + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_APL, + .codec_hid = &essx_83x6, + }, #endif #if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL) { .flags = FLAG_SST, - .device = 0x5a98, + .device = PCI_DEVICE_ID_INTEL_HDA_APL, .dmi_table = (const struct dmi_system_id []) { { .ident = "Google Chromebooks", @@ -97,7 +103,7 @@ static const struct config_entry config_table[] = { #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL) { .flags = FLAG_SST, - .device = 0x9d70, + .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP, .dmi_table = (const struct dmi_system_id []) { { .ident = "Google Chromebooks", @@ -110,14 +116,14 @@ static const struct config_entry config_table[] = { }, { .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, - .device = 0x9d70, + .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP, }, #endif /* Kabylake-LP */ #if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL) { .flags = FLAG_SST, - .device = 0x9d71, + .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP, .dmi_table = (const struct dmi_system_id []) { { .ident = "Google Chromebooks", @@ -130,19 +136,19 @@ static const struct config_entry config_table[] = { }, { .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, - .device = 0x9d71, + .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP, }, #endif /* * Geminilake uses legacy HDAudio driver except for Google - * Chromebooks + * Chromebooks and devices based on the ES8336 codec */ /* Geminilake */ #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE) { .flags = FLAG_SOF, - .device = 0x3198, + .device = PCI_DEVICE_ID_INTEL_HDA_GML, .dmi_table = (const struct dmi_system_id []) { { .ident = "Google Chromebooks", @@ -153,13 +159,18 @@ static const struct config_entry config_table[] = { {} } }, + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_GML, + .codec_hid = &essx_83x6, + }, #endif /* - * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake use legacy - * HDAudio driver except for Google Chromebooks and when DMICs are - * present. Two cases are required since Coreboot does not expose NHLT - * tables. + * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake, AlderLake, + * RaptorLake use legacy HDAudio driver except for Google Chromebooks + * and when DMICs are present. Two cases are required since Coreboot + * does not expose NHLT tables. * * When the Chromebook quirk is not present, it's based on information * that no such device exists. When the quirk is present, it could be @@ -170,7 +181,7 @@ static const struct config_entry config_table[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE) { .flags = FLAG_SOF, - .device = 0x9dc8, + .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP, .dmi_table = (const struct dmi_system_id []) { { .ident = "Google Chromebooks", @@ -178,12 +189,23 @@ static const struct config_entry config_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Google"), } }, + { + .ident = "UP-WHL", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), + } + }, {} } }, { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP, + .codec_hid = &essx_83x6, + }, + { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, - .device = 0x9dc8, + .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP, }, #endif @@ -191,7 +213,7 @@ static const struct config_entry config_table[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE) { .flags = FLAG_SOF, - .device = 0xa348, + .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H, .dmi_table = (const struct dmi_system_id []) { { .ident = "Google Chromebooks", @@ -204,7 +226,7 @@ static const struct config_entry config_table[] = { }, { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, - .device = 0xa348, + .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H, }, #endif @@ -212,7 +234,7 @@ static const struct config_entry config_table[] = { /* Cometlake-LP */ { .flags = FLAG_SOF, - .device = 0x02c8, + .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP, .dmi_table = (const struct dmi_system_id []) { { .ident = "Google Chromebooks", @@ -237,13 +259,18 @@ static const struct config_entry config_table[] = { } }, { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP, + .codec_hid = &essx_83x6, + }, + { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, - .device = 0x02c8, + .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP, }, /* Cometlake-H */ { .flags = FLAG_SOF, - .device = 0x06c8, + .device = PCI_DEVICE_ID_INTEL_HDA_CML_H, .dmi_table = (const struct dmi_system_id []) { { .matches = { @@ -261,8 +288,13 @@ static const struct config_entry config_table[] = { } }, { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_CML_H, + .codec_hid = &essx_83x6, + }, + { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, - .device = 0x06c8, + .device = PCI_DEVICE_ID_INTEL_HDA_CML_H, }, #endif @@ -270,7 +302,7 @@ static const struct config_entry config_table[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) { .flags = FLAG_SOF, - .device = 0x34c8, + .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP, .dmi_table = (const struct dmi_system_id []) { { .ident = "Google Chromebooks", @@ -282,8 +314,45 @@ static const struct config_entry config_table[] = { } }, { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP, + .codec_hid = &essx_83x6, + }, + { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, - .device = 0x34c8, + .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP, + }, +#endif + +/* Jasper Lake */ +#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE) + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N, + .dmi_table = (const struct dmi_system_id []) { + { + .ident = "Google Chromebooks", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + } + }, + { + .ident = "Google firmware", + .matches = { + DMI_MATCH(DMI_BIOS_VERSION, "Google"), + } + }, + {} + } + }, + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N, + .codec_hid = &essx_83x6, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, + .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N, }, #endif @@ -291,7 +360,7 @@ static const struct config_entry config_table[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) { .flags = FLAG_SOF, - .device = 0xa0c8, + .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP, .dmi_table = (const struct dmi_system_id []) { { .ident = "Google Chromebooks", @@ -299,12 +368,27 @@ static const struct config_entry config_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Google"), } }, + { + .ident = "UPX-TGL", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), + } + }, {} } }, { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP, + .codec_hid = &essx_83x6, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP, + }, + { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, - .device = 0xa0c8, + .device = PCI_DEVICE_ID_INTEL_HDA_TGL_H, }, #endif @@ -312,10 +396,151 @@ static const struct config_entry config_table[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE) { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, - .device = 0x4b55, + .device = PCI_DEVICE_ID_INTEL_HDA_EHL_0, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, + .device = PCI_DEVICE_ID_INTEL_HDA_EHL_3, + }, +#endif + +/* Alder Lake / Raptor Lake */ +#if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_S, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_RPL_S, + }, + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P, + .dmi_table = (const struct dmi_system_id []) { + { + .ident = "Google Chromebooks", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + } + }, + {} + } + }, + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P, + .codec_hid = &essx_83x6, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PX, + }, + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS, + .codec_hid = &essx_83x6, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_M, + }, + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N, + .dmi_table = (const struct dmi_system_id []) { + { + .ident = "Google Chromebooks", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + } + }, + {} + } + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N, + }, + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0, + .dmi_table = (const struct dmi_system_id []) { + { + .ident = "Google Chromebooks", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + } + }, + {} + } + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0, + }, + { + .flags = FLAG_SOF, + .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1, + .dmi_table = (const struct dmi_system_id []) { + { + .ident = "Google Chromebooks", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + } + }, + {} + } + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_RPL_M, + }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_RPL_PX, }, #endif +/* Meteor Lake */ +#if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE) + /* Meteorlake-P */ + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_MTL, + }, + /* ArrowLake-S */ + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_ARL_S, + }, + /* ArrowLake */ + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_ARL, + }, +#endif + +/* Lunar Lake */ +#if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE) + /* Lunarlake-P */ + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_LNL_P, + }, +#endif }; static const struct config_entry *snd_intel_dsp_find_config @@ -329,6 +554,15 @@ static const struct config_entry *snd_intel_dsp_find_config continue; if (table->dmi_table && !dmi_check_system(table->dmi_table)) continue; + if (table->codec_hid) { + int i; + + for (i = 0; i < table->codec_hid->num_codecs; i++) + if (acpi_dev_present(table->codec_hid->codecs[i], NULL, -1)) + break; + if (i == table->codec_hid->num_codecs) + continue; + } return table; } return NULL; @@ -341,7 +575,7 @@ static int snd_intel_dsp_check_dmic(struct pci_dev *pci) nhlt = intel_nhlt_init(&pci->dev); if (nhlt) { - if (intel_nhlt_get_dmic_geo(&pci->dev, nhlt)) + if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_DMIC)) ret = 1; intel_nhlt_free(nhlt); } @@ -375,8 +609,22 @@ int snd_intel_dsp_driver_probe(struct pci_dev *pci) const struct config_entry *cfg; /* Intel vendor only */ - if (pci->vendor != 0x8086) + if (pci->vendor != PCI_VENDOR_ID_INTEL) + return SND_INTEL_DSP_DRIVER_ANY; + + /* + * Legacy devices don't have a PCI-based DSP and use HDaudio + * for HDMI/DP support, ignore kernel parameter + */ + switch (pci->device) { + case PCI_DEVICE_ID_INTEL_HDA_BDW: + case PCI_DEVICE_ID_INTEL_HDA_HSW_0: + case PCI_DEVICE_ID_INTEL_HDA_HSW_2: + case PCI_DEVICE_ID_INTEL_HDA_HSW_3: + case PCI_DEVICE_ID_INTEL_HDA_BYT: + case PCI_DEVICE_ID_INTEL_HDA_BSW: return SND_INTEL_DSP_DRIVER_ANY; + } if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) return dsp_driver; @@ -433,6 +681,97 @@ int snd_intel_dsp_driver_probe(struct pci_dev *pci) } EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe); +/* Should we default to SOF or SST for BYT/CHT ? */ +#if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \ + !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) +#define FLAG_SST_OR_SOF_BYT FLAG_SOF +#else +#define FLAG_SST_OR_SOF_BYT FLAG_SST +#endif + +/* + * configuration table + * - the order of similar ACPI ID entries is important! + * - the first successful match will win + */ +static const struct config_entry acpi_config_table[] = { +#if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \ + IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) +/* BayTrail */ + { + .flags = FLAG_SST_OR_SOF_BYT, + .acpi_hid = "80860F28", + }, +/* CherryTrail */ + { + .flags = FLAG_SST_OR_SOF_BYT, + .acpi_hid = "808622A8", + }, +#endif +/* Broadwell */ +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT) + { + .flags = FLAG_SST, + .acpi_hid = "INT3438" + }, +#endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) + { + .flags = FLAG_SOF, + .acpi_hid = "INT3438" + }, +#endif +/* Haswell - not supported by SOF but added for consistency */ +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT) + { + .flags = FLAG_SST, + .acpi_hid = "INT33C8" + }, +#endif +}; + +static const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN], + const struct config_entry *table, + u32 len) +{ + for (; len > 0; len--, table++) { + if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN)) + continue; + if (table->dmi_table && !dmi_check_system(table->dmi_table)) + continue; + return table; + } + return NULL; +} + +int snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN]) +{ + const struct config_entry *cfg; + + if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) + return dsp_driver; + + if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) { + dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n", + SND_INTEL_DSP_DRIVER_LEGACY); + } + + /* find the configuration for the specific device */ + cfg = snd_intel_acpi_dsp_find_config(acpi_hid, acpi_config_table, + ARRAY_SIZE(acpi_config_table)); + if (!cfg) + return SND_INTEL_DSP_DRIVER_ANY; + + if (cfg->flags & FLAG_SST) + return SND_INTEL_DSP_DRIVER_SST; + + if (cfg->flags & FLAG_SOF) + return SND_INTEL_DSP_DRIVER_SOF; + + return SND_INTEL_DSP_DRIVER_SST; +} +EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe); + MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Intel DSP config driver"); -MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT); +MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI); |