805 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz>3 4#include <linux/acpi.h>5#include <linux/bits.h>6#include <linux/dmi.h>7#include <linux/module.h>8#include <linux/pci.h>9#include <linux/soundwire/sdw.h>10#include <linux/soundwire/sdw_intel.h>11#include <sound/core.h>12#include <sound/intel-dsp-config.h>13#include <sound/intel-nhlt.h>14#include <sound/soc-acpi.h>15 16#include <acpi/nhlt.h>17 18static int dsp_driver;19 20module_param(dsp_driver, int, 0444);21MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF, 4=AVS)");22 23#define FLAG_SST BIT(0)24#define FLAG_SOF BIT(1)25#define FLAG_SST_ONLY_IF_DMIC BIT(15)26#define FLAG_SOF_ONLY_IF_DMIC BIT(16)27#define FLAG_SOF_ONLY_IF_SOUNDWIRE BIT(17)28 29#define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \30 FLAG_SOF_ONLY_IF_SOUNDWIRE)31 32struct config_entry {33 u32 flags;34 u16 device;35 u8 acpi_hid[ACPI_ID_LEN];36 const struct dmi_system_id *dmi_table;37 const struct snd_soc_acpi_codecs *codec_hid;38};39 40static const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = {41 .num_codecs = 3,42 .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},43};44 45/*46 * configuration table47 * - the order of similar PCI ID entries is important!48 * - the first successful match will win49 */50static const struct config_entry config_table[] = {51/* Merrifield */52#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)53 {54 .flags = FLAG_SOF,55 .device = PCI_DEVICE_ID_INTEL_SST_TNG,56 },57#endif58/*59 * Skylake, Kabylake, Apollolake60 * the legacy HDAudio driver is used except on Up Squared (SOF) and61 * Chromebooks (SST), as well as devices based on the ES8336 codec62 */63#if IS_ENABLED(CONFIG_SND_SOC_INTEL_AVS)64 {65 .flags = FLAG_SST,66 .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,67 .dmi_table = (const struct dmi_system_id []) {68 {69 .ident = "Google Chromebooks",70 .matches = {71 DMI_MATCH(DMI_SYS_VENDOR, "Google"),72 }73 },74 {}75 }76 },77 {78 .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,79 .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,80 },81 {82 .flags = FLAG_SST,83 .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,84 .dmi_table = (const struct dmi_system_id []) {85 {86 .ident = "Google Chromebooks",87 .matches = {88 DMI_MATCH(DMI_SYS_VENDOR, "Google"),89 }90 },91 {}92 }93 },94 {95 .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,96 .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,97 },98 {99 .flags = FLAG_SST,100 .device = PCI_DEVICE_ID_INTEL_HDA_APL,101 .dmi_table = (const struct dmi_system_id []) {102 {103 .ident = "Google Chromebooks",104 .matches = {105 DMI_MATCH(DMI_SYS_VENDOR, "Google"),106 }107 },108 {}109 }110 },111#endif112#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)113 {114 .flags = FLAG_SOF,115 .device = PCI_DEVICE_ID_INTEL_HDA_APL,116 .dmi_table = (const struct dmi_system_id []) {117 {118 .ident = "Up Squared",119 .matches = {120 DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),121 DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"),122 }123 },124 {}125 }126 },127 {128 .flags = FLAG_SOF,129 .device = PCI_DEVICE_ID_INTEL_HDA_APL,130 .codec_hid = &essx_83x6,131 },132#endif133 134/*135 * Geminilake uses legacy HDAudio driver except for Google136 * Chromebooks and devices based on the ES8336 codec137 */138/* Geminilake */139#if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)140 {141 .flags = FLAG_SOF,142 .device = PCI_DEVICE_ID_INTEL_HDA_GML,143 .dmi_table = (const struct dmi_system_id []) {144 {145 .ident = "Google Chromebooks",146 .matches = {147 DMI_MATCH(DMI_SYS_VENDOR, "Google"),148 }149 },150 {}151 }152 },153 {154 .flags = FLAG_SOF,155 .device = PCI_DEVICE_ID_INTEL_HDA_GML,156 .codec_hid = &essx_83x6,157 },158#endif159 160/*161 * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake, AlderLake,162 * RaptorLake use legacy HDAudio driver except for Google Chromebooks163 * and when DMICs are present. Two cases are required since Coreboot164 * does not expose NHLT tables.165 *166 * When the Chromebook quirk is not present, it's based on information167 * that no such device exists. When the quirk is present, it could be168 * either based on product information or a placeholder.169 */170 171/* Cannonlake */172#if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)173 {174 .flags = FLAG_SOF,175 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,176 .dmi_table = (const struct dmi_system_id []) {177 {178 .ident = "Google Chromebooks",179 .matches = {180 DMI_MATCH(DMI_SYS_VENDOR, "Google"),181 }182 },183 {184 .ident = "UP-WHL",185 .matches = {186 DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),187 }188 },189 {}190 }191 },192 {193 .flags = FLAG_SOF,194 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,195 .codec_hid = &essx_83x6,196 },197 {198 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,199 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,200 },201#endif202 203/* Coffelake */204#if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)205 {206 .flags = FLAG_SOF,207 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H,208 .dmi_table = (const struct dmi_system_id []) {209 {210 .ident = "Google Chromebooks",211 .matches = {212 DMI_MATCH(DMI_SYS_VENDOR, "Google"),213 }214 },215 {}216 }217 },218 {219 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,220 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H,221 },222#endif223 224#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE)225/* Cometlake-LP */226 {227 .flags = FLAG_SOF,228 .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,229 .dmi_table = (const struct dmi_system_id []) {230 {231 .ident = "Google Chromebooks",232 .matches = {233 DMI_MATCH(DMI_SYS_VENDOR, "Google"),234 }235 },236 {237 .matches = {238 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),239 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")240 },241 },242 {243 /* early version of SKU 09C6 */244 .matches = {245 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),246 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")247 },248 },249 {}250 }251 },252 {253 .flags = FLAG_SOF,254 .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,255 .codec_hid = &essx_83x6,256 },257 {258 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,259 .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,260 },261/* Cometlake-H */262 {263 .flags = FLAG_SOF,264 .device = PCI_DEVICE_ID_INTEL_HDA_CML_H,265 .dmi_table = (const struct dmi_system_id []) {266 {267 .matches = {268 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),269 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),270 },271 },272 {273 .matches = {274 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),275 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),276 },277 },278 {}279 }280 },281 {282 .flags = FLAG_SOF,283 .device = PCI_DEVICE_ID_INTEL_HDA_CML_H,284 .codec_hid = &essx_83x6,285 },286 {287 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,288 .device = PCI_DEVICE_ID_INTEL_HDA_CML_H,289 },290#endif291 292/* Icelake */293#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)294 {295 .flags = FLAG_SOF,296 .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,297 .dmi_table = (const struct dmi_system_id []) {298 {299 .ident = "Google Chromebooks",300 .matches = {301 DMI_MATCH(DMI_SYS_VENDOR, "Google"),302 }303 },304 {}305 }306 },307 {308 .flags = FLAG_SOF,309 .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,310 .codec_hid = &essx_83x6,311 },312 {313 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,314 .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,315 },316#endif317 318/* Jasper Lake */319#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)320 {321 .flags = FLAG_SOF,322 .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,323 .dmi_table = (const struct dmi_system_id []) {324 {325 .ident = "Google Chromebooks",326 .matches = {327 DMI_MATCH(DMI_SYS_VENDOR, "Google"),328 }329 },330 {331 .ident = "Google firmware",332 .matches = {333 DMI_MATCH(DMI_BIOS_VERSION, "Google"),334 }335 },336 {}337 }338 },339 {340 .flags = FLAG_SOF,341 .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,342 .codec_hid = &essx_83x6,343 },344 {345 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,346 .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,347 },348#endif349 350/* Tigerlake */351#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)352 {353 .flags = FLAG_SOF,354 .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,355 .dmi_table = (const struct dmi_system_id []) {356 {357 .ident = "Google Chromebooks",358 .matches = {359 DMI_MATCH(DMI_SYS_VENDOR, "Google"),360 }361 },362 {363 .ident = "UPX-TGL",364 .matches = {365 DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),366 }367 },368 {}369 }370 },371 {372 .flags = FLAG_SOF,373 .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,374 .codec_hid = &essx_83x6,375 },376 {377 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,378 .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,379 },380 {381 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,382 .device = PCI_DEVICE_ID_INTEL_HDA_TGL_H,383 },384#endif385 386/* Elkhart Lake */387#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)388 {389 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,390 .device = PCI_DEVICE_ID_INTEL_HDA_EHL_0,391 },392 {393 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,394 .device = PCI_DEVICE_ID_INTEL_HDA_EHL_3,395 },396#endif397 398/* Alder Lake / Raptor Lake */399#if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE)400 {401 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,402 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_S,403 },404 {405 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,406 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_S,407 },408 {409 .flags = FLAG_SOF,410 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,411 .dmi_table = (const struct dmi_system_id []) {412 {413 .ident = "Google Chromebooks",414 .matches = {415 DMI_MATCH(DMI_SYS_VENDOR, "Google"),416 }417 },418 {}419 }420 },421 {422 .flags = FLAG_SOF,423 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,424 .codec_hid = &essx_83x6,425 },426 {427 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,428 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,429 },430 {431 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,432 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PX,433 },434 {435 .flags = FLAG_SOF,436 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS,437 .codec_hid = &essx_83x6,438 },439 {440 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,441 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS,442 },443 {444 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,445 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_M,446 },447 {448 .flags = FLAG_SOF,449 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N,450 .dmi_table = (const struct dmi_system_id []) {451 {452 .ident = "Google Chromebooks",453 .matches = {454 DMI_MATCH(DMI_SYS_VENDOR, "Google"),455 }456 },457 {}458 }459 },460 {461 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,462 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N,463 },464 {465 .flags = FLAG_SOF,466 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0,467 .dmi_table = (const struct dmi_system_id []) {468 {469 .ident = "Google Chromebooks",470 .matches = {471 DMI_MATCH(DMI_SYS_VENDOR, "Google"),472 }473 },474 {}475 }476 },477 {478 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,479 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0,480 },481 {482 .flags = FLAG_SOF,483 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1,484 .dmi_table = (const struct dmi_system_id []) {485 {486 .ident = "Google Chromebooks",487 .matches = {488 DMI_MATCH(DMI_SYS_VENDOR, "Google"),489 }490 },491 {}492 }493 },494 {495 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,496 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1,497 },498 {499 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,500 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_M,501 },502 {503 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,504 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_PX,505 },506#endif507 508/* Meteor Lake */509#if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE)510 /* Meteorlake-P */511 {512 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,513 .device = PCI_DEVICE_ID_INTEL_HDA_MTL,514 },515 /* ArrowLake-S */516 {517 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,518 .device = PCI_DEVICE_ID_INTEL_HDA_ARL_S,519 },520 /* ArrowLake */521 {522 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,523 .device = PCI_DEVICE_ID_INTEL_HDA_ARL,524 },525#endif526 527/* Lunar Lake */528#if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE)529 /* Lunarlake-P */530 {531 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,532 .device = PCI_DEVICE_ID_INTEL_HDA_LNL_P,533 },534#endif535 536 /* Panther Lake */537#if IS_ENABLED(CONFIG_SND_SOC_SOF_PANTHERLAKE)538 {539 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,540 .device = PCI_DEVICE_ID_INTEL_HDA_PTL,541 },542#endif543 544};545 546static const struct config_entry *snd_intel_dsp_find_config547 (struct pci_dev *pci, const struct config_entry *table, u32 len)548{549 u16 device;550 551 device = pci->device;552 for (; len > 0; len--, table++) {553 if (table->device != device)554 continue;555 if (table->dmi_table && !dmi_check_system(table->dmi_table))556 continue;557 if (table->codec_hid) {558 int i;559 560 for (i = 0; i < table->codec_hid->num_codecs; i++) {561 struct nhlt_acpi_table *nhlt;562 bool ssp_found = false;563 564 if (!acpi_dev_present(table->codec_hid->codecs[i], NULL, -1))565 continue;566 567 nhlt = intel_nhlt_init(&pci->dev);568 if (!nhlt) {569 dev_warn(&pci->dev, "%s: NHLT table not found, skipped HID %s\n",570 __func__, table->codec_hid->codecs[i]);571 continue;572 }573 574 if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_SSP) &&575 intel_nhlt_ssp_endpoint_mask(nhlt, NHLT_DEVICE_I2S))576 ssp_found = true;577 578 intel_nhlt_free(nhlt);579 580 if (ssp_found)581 break;582 583 dev_warn(&pci->dev, "%s: no valid SSP found for HID %s, skipped\n",584 __func__, table->codec_hid->codecs[i]);585 }586 if (i == table->codec_hid->num_codecs)587 continue;588 }589 return table;590 }591 return NULL;592}593 594static int snd_intel_dsp_check_dmic(struct pci_dev *pci)595{596 int ret = 0;597 598 acpi_nhlt_get_gbl_table();599 600 if (acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1))601 ret = 1;602 603 acpi_nhlt_put_gbl_table();604 605 return ret;606}607 608#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)609static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)610{611 struct sdw_intel_acpi_info info;612 acpi_handle handle;613 int ret;614 615 handle = ACPI_HANDLE(&pci->dev);616 617 ret = sdw_intel_acpi_scan(handle, &info);618 if (ret < 0)619 return ret;620 621 return info.link_mask;622}623#else624static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)625{626 return 0;627}628#endif629 630int snd_intel_dsp_driver_probe(struct pci_dev *pci)631{632 const struct config_entry *cfg;633 634 /* Intel vendor only */635 if (pci->vendor != PCI_VENDOR_ID_INTEL)636 return SND_INTEL_DSP_DRIVER_ANY;637 638 /*639 * Legacy devices don't have a PCI-based DSP and use HDaudio640 * for HDMI/DP support, ignore kernel parameter641 */642 switch (pci->device) {643 case PCI_DEVICE_ID_INTEL_HDA_BDW:644 case PCI_DEVICE_ID_INTEL_HDA_HSW_0:645 case PCI_DEVICE_ID_INTEL_HDA_HSW_2:646 case PCI_DEVICE_ID_INTEL_HDA_HSW_3:647 case PCI_DEVICE_ID_INTEL_HDA_BYT:648 case PCI_DEVICE_ID_INTEL_HDA_BSW:649 return SND_INTEL_DSP_DRIVER_ANY;650 }651 652 if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)653 return dsp_driver;654 655 /*656 * detect DSP by checking class/subclass/prog-id information657 * class=04 subclass 03 prog-if 00: no DSP, use legacy driver658 * class=04 subclass 01 prog-if 00: DSP is present659 * (and may be required e.g. for DMIC or SSP support)660 * class=04 subclass 03 prog-if 80: use DSP or legacy mode661 */662 if (pci->class == 0x040300)663 return SND_INTEL_DSP_DRIVER_LEGACY;664 if (pci->class != 0x040100 && pci->class != 0x040380) {665 dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class);666 return SND_INTEL_DSP_DRIVER_LEGACY;667 }668 669 dev_dbg(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);670 671 /* find the configuration for the specific device */672 cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table));673 if (!cfg)674 return SND_INTEL_DSP_DRIVER_ANY;675 676 if (cfg->flags & FLAG_SOF) {677 if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&678 snd_intel_dsp_check_soundwire(pci) > 0) {679 dev_info_once(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");680 return SND_INTEL_DSP_DRIVER_SOF;681 }682 if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&683 snd_intel_dsp_check_dmic(pci)) {684 dev_info_once(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");685 return SND_INTEL_DSP_DRIVER_SOF;686 }687 if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))688 return SND_INTEL_DSP_DRIVER_SOF;689 }690 691 692 if (cfg->flags & FLAG_SST) {693 if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) {694 if (snd_intel_dsp_check_dmic(pci)) {695 dev_info_once(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n");696 return SND_INTEL_DSP_DRIVER_SST;697 }698 } else {699 return SND_INTEL_DSP_DRIVER_SST;700 }701 }702 703 return SND_INTEL_DSP_DRIVER_LEGACY;704}705EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);706 707/* Should we default to SOF or SST for BYT/CHT ? */708#if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \709 !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI)710#define FLAG_SST_OR_SOF_BYT FLAG_SOF711#else712#define FLAG_SST_OR_SOF_BYT FLAG_SST713#endif714 715/*716 * configuration table717 * - the order of similar ACPI ID entries is important!718 * - the first successful match will win719 */720static const struct config_entry acpi_config_table[] = {721#if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \722 IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)723/* BayTrail */724 {725 .flags = FLAG_SST_OR_SOF_BYT,726 .acpi_hid = "LPE0F28",727 },728 {729 .flags = FLAG_SST_OR_SOF_BYT,730 .acpi_hid = "80860F28",731 },732/* CherryTrail */733 {734 .flags = FLAG_SST_OR_SOF_BYT,735 .acpi_hid = "808622A8",736 },737#endif738/* Broadwell */739#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)740 {741 .flags = FLAG_SST,742 .acpi_hid = "INT3438"743 },744#endif745#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)746 {747 .flags = FLAG_SOF,748 .acpi_hid = "INT3438"749 },750#endif751/* Haswell - not supported by SOF but added for consistency */752#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)753 {754 .flags = FLAG_SST,755 .acpi_hid = "INT33C8"756 },757#endif758};759 760static const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN],761 const struct config_entry *table,762 u32 len)763{764 for (; len > 0; len--, table++) {765 if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN))766 continue;767 if (table->dmi_table && !dmi_check_system(table->dmi_table))768 continue;769 return table;770 }771 return NULL;772}773 774int snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN])775{776 const struct config_entry *cfg;777 778 if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)779 return dsp_driver;780 781 if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) {782 dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n",783 SND_INTEL_DSP_DRIVER_LEGACY);784 }785 786 /* find the configuration for the specific device */787 cfg = snd_intel_acpi_dsp_find_config(acpi_hid, acpi_config_table,788 ARRAY_SIZE(acpi_config_table));789 if (!cfg)790 return SND_INTEL_DSP_DRIVER_ANY;791 792 if (cfg->flags & FLAG_SST)793 return SND_INTEL_DSP_DRIVER_SST;794 795 if (cfg->flags & FLAG_SOF)796 return SND_INTEL_DSP_DRIVER_SOF;797 798 return SND_INTEL_DSP_DRIVER_SST;799}800EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe);801 802MODULE_LICENSE("GPL v2");803MODULE_DESCRIPTION("Intel DSP config driver");804MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);805