cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intel-dsp-config.c (15042B)


      1// SPDX-License-Identifier: GPL-2.0
      2// 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
     16static int dsp_driver;
     17
     18module_param(dsp_driver, int, 0444);
     19MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)");
     20
     21#define FLAG_SST			BIT(0)
     22#define FLAG_SOF			BIT(1)
     23#define FLAG_SST_ONLY_IF_DMIC		BIT(15)
     24#define FLAG_SOF_ONLY_IF_DMIC		BIT(16)
     25#define FLAG_SOF_ONLY_IF_SOUNDWIRE	BIT(17)
     26
     27#define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \
     28					    FLAG_SOF_ONLY_IF_SOUNDWIRE)
     29
     30struct config_entry {
     31	u32 flags;
     32	u16 device;
     33	u8 acpi_hid[ACPI_ID_LEN];
     34	const struct dmi_system_id *dmi_table;
     35	const struct snd_soc_acpi_codecs *codec_hid;
     36};
     37
     38static const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = {
     39	.num_codecs = 3,
     40	.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
     41};
     42
     43/*
     44 * configuration table
     45 * - the order of similar PCI ID entries is important!
     46 * - the first successful match will win
     47 */
     48static const struct config_entry config_table[] = {
     49/* Merrifield */
     50#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
     51	{
     52		.flags = FLAG_SOF,
     53		.device = 0x119a,
     54	},
     55#endif
     56/* Broxton-T */
     57#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
     58	{
     59		.flags = FLAG_SOF,
     60		.device = 0x1a98,
     61	},
     62#endif
     63/*
     64 * Apollolake (Broxton-P)
     65 * the legacy HDAudio driver is used except on Up Squared (SOF) and
     66 * Chromebooks (SST), as well as devices based on the ES8336 codec
     67 */
     68#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
     69	{
     70		.flags = FLAG_SOF,
     71		.device = 0x5a98,
     72		.dmi_table = (const struct dmi_system_id []) {
     73			{
     74				.ident = "Up Squared",
     75				.matches = {
     76					DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
     77					DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"),
     78				}
     79			},
     80			{}
     81		}
     82	},
     83	{
     84		.flags = FLAG_SOF,
     85		.device = 0x5a98,
     86		.codec_hid =  &essx_83x6,
     87	},
     88#endif
     89#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
     90	{
     91		.flags = FLAG_SST,
     92		.device = 0x5a98,
     93		.dmi_table = (const struct dmi_system_id []) {
     94			{
     95				.ident = "Google Chromebooks",
     96				.matches = {
     97					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
     98				}
     99			},
    100			{}
    101		}
    102	},
    103#endif
    104/*
    105 * Skylake and Kabylake use legacy HDAudio driver except for Google
    106 * Chromebooks (SST)
    107 */
    108
    109/* Sunrise Point-LP */
    110#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)
    111	{
    112		.flags = FLAG_SST,
    113		.device = 0x9d70,
    114		.dmi_table = (const struct dmi_system_id []) {
    115			{
    116				.ident = "Google Chromebooks",
    117				.matches = {
    118					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
    119				}
    120			},
    121			{}
    122		}
    123	},
    124	{
    125		.flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
    126		.device = 0x9d70,
    127	},
    128#endif
    129/* Kabylake-LP */
    130#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
    131	{
    132		.flags = FLAG_SST,
    133		.device = 0x9d71,
    134		.dmi_table = (const struct dmi_system_id []) {
    135			{
    136				.ident = "Google Chromebooks",
    137				.matches = {
    138					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
    139				}
    140			},
    141			{}
    142		}
    143	},
    144	{
    145		.flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
    146		.device = 0x9d71,
    147	},
    148#endif
    149
    150/*
    151 * Geminilake uses legacy HDAudio driver except for Google
    152 * Chromebooks and devices based on the ES8336 codec
    153 */
    154/* Geminilake */
    155#if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)
    156	{
    157		.flags = FLAG_SOF,
    158		.device = 0x3198,
    159		.dmi_table = (const struct dmi_system_id []) {
    160			{
    161				.ident = "Google Chromebooks",
    162				.matches = {
    163					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
    164				}
    165			},
    166			{}
    167		}
    168	},
    169	{
    170		.flags = FLAG_SOF,
    171		.device = 0x3198,
    172		.codec_hid =  &essx_83x6,
    173	},
    174#endif
    175
    176/*
    177 * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake use legacy
    178 * HDAudio driver except for Google Chromebooks and when DMICs are
    179 * present. Two cases are required since Coreboot does not expose NHLT
    180 * tables.
    181 *
    182 * When the Chromebook quirk is not present, it's based on information
    183 * that no such device exists. When the quirk is present, it could be
    184 * either based on product information or a placeholder.
    185 */
    186
    187/* Cannonlake */
    188#if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)
    189	{
    190		.flags = FLAG_SOF,
    191		.device = 0x9dc8,
    192		.dmi_table = (const struct dmi_system_id []) {
    193			{
    194				.ident = "Google Chromebooks",
    195				.matches = {
    196					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
    197				}
    198			},
    199			{
    200				.ident = "UP-WHL",
    201				.matches = {
    202					DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
    203				}
    204			},
    205			{}
    206		}
    207	},
    208	{
    209		.flags = FLAG_SOF,
    210		.device = 0x09dc8,
    211		.codec_hid =  &essx_83x6,
    212	},
    213	{
    214		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    215		.device = 0x9dc8,
    216	},
    217#endif
    218
    219/* Coffelake */
    220#if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)
    221	{
    222		.flags = FLAG_SOF,
    223		.device = 0xa348,
    224		.dmi_table = (const struct dmi_system_id []) {
    225			{
    226				.ident = "Google Chromebooks",
    227				.matches = {
    228					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
    229				}
    230			},
    231			{}
    232		}
    233	},
    234	{
    235		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    236		.device = 0xa348,
    237	},
    238#endif
    239
    240#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE)
    241/* Cometlake-LP */
    242	{
    243		.flags = FLAG_SOF,
    244		.device = 0x02c8,
    245		.dmi_table = (const struct dmi_system_id []) {
    246			{
    247				.ident = "Google Chromebooks",
    248				.matches = {
    249					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
    250				}
    251			},
    252			{
    253				.matches = {
    254					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
    255					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
    256				},
    257			},
    258			{
    259				/* early version of SKU 09C6 */
    260				.matches = {
    261					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
    262					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
    263				},
    264			},
    265			{}
    266		}
    267	},
    268	{
    269		.flags = FLAG_SOF,
    270		.device = 0x02c8,
    271		.codec_hid =  &essx_83x6,
    272	},
    273	{
    274		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    275		.device = 0x02c8,
    276	},
    277/* Cometlake-H */
    278	{
    279		.flags = FLAG_SOF,
    280		.device = 0x06c8,
    281		.dmi_table = (const struct dmi_system_id []) {
    282			{
    283				.matches = {
    284					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
    285					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
    286				},
    287			},
    288			{
    289				.matches = {
    290					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
    291					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
    292				},
    293			},
    294			{}
    295		}
    296	},
    297	{
    298		.flags = FLAG_SOF,
    299		.device = 0x06c8,
    300		.codec_hid =  &essx_83x6,
    301	},
    302	{
    303		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    304		.device = 0x06c8,
    305	},
    306#endif
    307
    308/* Icelake */
    309#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
    310	{
    311		.flags = FLAG_SOF,
    312		.device = 0x34c8,
    313		.dmi_table = (const struct dmi_system_id []) {
    314			{
    315				.ident = "Google Chromebooks",
    316				.matches = {
    317					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
    318				}
    319			},
    320			{}
    321		}
    322	},
    323	{
    324		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    325		.device = 0x34c8,
    326	},
    327#endif
    328
    329/* Jasper Lake */
    330#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
    331	{
    332		.flags = FLAG_SOF,
    333		.device = 0x4dc8,
    334		.dmi_table = (const struct dmi_system_id []) {
    335			{
    336				.ident = "Google Chromebooks",
    337				.matches = {
    338					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
    339				}
    340			},
    341			{}
    342		}
    343	},
    344	{
    345		.flags = FLAG_SOF,
    346		.device = 0x4dc8,
    347		.codec_hid =  &essx_83x6,
    348	},
    349	{
    350		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
    351		.device = 0x4dc8,
    352	},
    353#endif
    354
    355/* Tigerlake */
    356#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
    357	{
    358		.flags = FLAG_SOF,
    359		.device = 0xa0c8,
    360		.dmi_table = (const struct dmi_system_id []) {
    361			{
    362				.ident = "Google Chromebooks",
    363				.matches = {
    364					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
    365				}
    366			},
    367			{
    368				.ident = "UPX-TGL",
    369				.matches = {
    370					DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
    371				}
    372			},
    373			{}
    374		}
    375	},
    376	{
    377		.flags = FLAG_SOF,
    378		.device = 0xa0c8,
    379		.codec_hid =  &essx_83x6,
    380	},
    381	{
    382		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    383		.device = 0xa0c8,
    384	},
    385	{
    386		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    387		.device = 0x43c8,
    388	},
    389#endif
    390
    391/* Elkhart Lake */
    392#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
    393	{
    394		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
    395		.device = 0x4b55,
    396	},
    397	{
    398		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
    399		.device = 0x4b58,
    400	},
    401#endif
    402
    403/* Alder Lake */
    404#if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE)
    405	/* Alderlake-S */
    406	{
    407		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    408		.device = 0x7ad0,
    409	},
    410	/* RaptorLake-S */
    411	{
    412		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    413		.device = 0x7a50,
    414	},
    415	/* Alderlake-P */
    416	{
    417		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    418		.device = 0x51c8,
    419	},
    420	{
    421		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    422		.device = 0x51cd,
    423	},
    424	/* Alderlake-PS */
    425	{
    426		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    427		.device = 0x51c9,
    428	},
    429	/* Alderlake-M */
    430	{
    431		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    432		.device = 0x51cc,
    433	},
    434	/* Alderlake-N */
    435	{
    436		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    437		.device = 0x54c8,
    438	},
    439	/* RaptorLake-P */
    440	{
    441		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    442		.device = 0x51ca,
    443	},
    444	{
    445		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
    446		.device = 0x51cb,
    447	},
    448#endif
    449
    450};
    451
    452static const struct config_entry *snd_intel_dsp_find_config
    453		(struct pci_dev *pci, const struct config_entry *table, u32 len)
    454{
    455	u16 device;
    456
    457	device = pci->device;
    458	for (; len > 0; len--, table++) {
    459		if (table->device != device)
    460			continue;
    461		if (table->dmi_table && !dmi_check_system(table->dmi_table))
    462			continue;
    463		if (table->codec_hid) {
    464			int i;
    465
    466			for (i = 0; i < table->codec_hid->num_codecs; i++)
    467				if (acpi_dev_present(table->codec_hid->codecs[i], NULL, -1))
    468					break;
    469			if (i == table->codec_hid->num_codecs)
    470				continue;
    471		}
    472		return table;
    473	}
    474	return NULL;
    475}
    476
    477static int snd_intel_dsp_check_dmic(struct pci_dev *pci)
    478{
    479	struct nhlt_acpi_table *nhlt;
    480	int ret = 0;
    481
    482	nhlt = intel_nhlt_init(&pci->dev);
    483	if (nhlt) {
    484		if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_DMIC))
    485			ret = 1;
    486		intel_nhlt_free(nhlt);
    487	}
    488	return ret;
    489}
    490
    491#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
    492static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
    493{
    494	struct sdw_intel_acpi_info info;
    495	acpi_handle handle;
    496	int ret;
    497
    498	handle = ACPI_HANDLE(&pci->dev);
    499
    500	ret = sdw_intel_acpi_scan(handle, &info);
    501	if (ret < 0)
    502		return ret;
    503
    504	return info.link_mask;
    505}
    506#else
    507static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
    508{
    509	return 0;
    510}
    511#endif
    512
    513int snd_intel_dsp_driver_probe(struct pci_dev *pci)
    514{
    515	const struct config_entry *cfg;
    516
    517	/* Intel vendor only */
    518	if (pci->vendor != 0x8086)
    519		return SND_INTEL_DSP_DRIVER_ANY;
    520
    521	/*
    522	 * Legacy devices don't have a PCI-based DSP and use HDaudio
    523	 * for HDMI/DP support, ignore kernel parameter
    524	 */
    525	switch (pci->device) {
    526	case 0x160c: /* Broadwell */
    527	case 0x0a0c: /* Haswell */
    528	case 0x0c0c:
    529	case 0x0d0c:
    530	case 0x0f04: /* Baytrail */
    531	case 0x2284: /* Braswell */
    532		return SND_INTEL_DSP_DRIVER_ANY;
    533	}
    534
    535	if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
    536		return dsp_driver;
    537
    538	/*
    539	 * detect DSP by checking class/subclass/prog-id information
    540	 * class=04 subclass 03 prog-if 00: no DSP, use legacy driver
    541	 * class=04 subclass 01 prog-if 00: DSP is present
    542	 *  (and may be required e.g. for DMIC or SSP support)
    543	 * class=04 subclass 03 prog-if 80: use DSP or legacy mode
    544	 */
    545	if (pci->class == 0x040300)
    546		return SND_INTEL_DSP_DRIVER_LEGACY;
    547	if (pci->class != 0x040100 && pci->class != 0x040380) {
    548		dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class);
    549		return SND_INTEL_DSP_DRIVER_LEGACY;
    550	}
    551
    552	dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);
    553
    554	/* find the configuration for the specific device */
    555	cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table));
    556	if (!cfg)
    557		return SND_INTEL_DSP_DRIVER_ANY;
    558
    559	if (cfg->flags & FLAG_SOF) {
    560		if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
    561		    snd_intel_dsp_check_soundwire(pci) > 0) {
    562			dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");
    563			return SND_INTEL_DSP_DRIVER_SOF;
    564		}
    565		if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
    566		    snd_intel_dsp_check_dmic(pci)) {
    567			dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
    568			return SND_INTEL_DSP_DRIVER_SOF;
    569		}
    570		if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))
    571			return SND_INTEL_DSP_DRIVER_SOF;
    572	}
    573
    574
    575	if (cfg->flags & FLAG_SST) {
    576		if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) {
    577			if (snd_intel_dsp_check_dmic(pci)) {
    578				dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n");
    579				return SND_INTEL_DSP_DRIVER_SST;
    580			}
    581		} else {
    582			return SND_INTEL_DSP_DRIVER_SST;
    583		}
    584	}
    585
    586	return SND_INTEL_DSP_DRIVER_LEGACY;
    587}
    588EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
    589
    590/* Should we default to SOF or SST for BYT/CHT ? */
    591#if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \
    592    !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI)
    593#define FLAG_SST_OR_SOF_BYT	FLAG_SOF
    594#else
    595#define FLAG_SST_OR_SOF_BYT	FLAG_SST
    596#endif
    597
    598/*
    599 * configuration table
    600 * - the order of similar ACPI ID entries is important!
    601 * - the first successful match will win
    602 */
    603static const struct config_entry acpi_config_table[] = {
    604#if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
    605    IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
    606/* BayTrail */
    607	{
    608		.flags = FLAG_SST_OR_SOF_BYT,
    609		.acpi_hid = "80860F28",
    610	},
    611/* CherryTrail */
    612	{
    613		.flags = FLAG_SST_OR_SOF_BYT,
    614		.acpi_hid = "808622A8",
    615	},
    616#endif
    617/* Broadwell */
    618#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
    619	{
    620		.flags = FLAG_SST,
    621		.acpi_hid = "INT3438"
    622	},
    623#endif
    624#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
    625	{
    626		.flags = FLAG_SOF,
    627		.acpi_hid = "INT3438"
    628	},
    629#endif
    630/* Haswell - not supported by SOF but added for consistency */
    631#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
    632	{
    633		.flags = FLAG_SST,
    634		.acpi_hid = "INT33C8"
    635	},
    636#endif
    637};
    638
    639static const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN],
    640								 const struct config_entry *table,
    641								 u32 len)
    642{
    643	for (; len > 0; len--, table++) {
    644		if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN))
    645			continue;
    646		if (table->dmi_table && !dmi_check_system(table->dmi_table))
    647			continue;
    648		return table;
    649	}
    650	return NULL;
    651}
    652
    653int snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN])
    654{
    655	const struct config_entry *cfg;
    656
    657	if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
    658		return dsp_driver;
    659
    660	if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) {
    661		dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n",
    662			 SND_INTEL_DSP_DRIVER_LEGACY);
    663	}
    664
    665	/* find the configuration for the specific device */
    666	cfg = snd_intel_acpi_dsp_find_config(acpi_hid,  acpi_config_table,
    667					     ARRAY_SIZE(acpi_config_table));
    668	if (!cfg)
    669		return SND_INTEL_DSP_DRIVER_ANY;
    670
    671	if (cfg->flags & FLAG_SST)
    672		return SND_INTEL_DSP_DRIVER_SST;
    673
    674	if (cfg->flags & FLAG_SOF)
    675		return SND_INTEL_DSP_DRIVER_SOF;
    676
    677	return SND_INTEL_DSP_DRIVER_SST;
    678}
    679EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe);
    680
    681MODULE_LICENSE("GPL v2");
    682MODULE_DESCRIPTION("Intel DSP config driver");
    683MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);