162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci// Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz>
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include <linux/acpi.h>
562306a36Sopenharmony_ci#include <linux/bits.h>
662306a36Sopenharmony_ci#include <linux/dmi.h>
762306a36Sopenharmony_ci#include <linux/module.h>
862306a36Sopenharmony_ci#include <linux/pci.h>
962306a36Sopenharmony_ci#include <linux/soundwire/sdw.h>
1062306a36Sopenharmony_ci#include <linux/soundwire/sdw_intel.h>
1162306a36Sopenharmony_ci#include <sound/core.h>
1262306a36Sopenharmony_ci#include <sound/intel-dsp-config.h>
1362306a36Sopenharmony_ci#include <sound/intel-nhlt.h>
1462306a36Sopenharmony_ci#include <sound/soc-acpi.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistatic int dsp_driver;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cimodule_param(dsp_driver, int, 0444);
1962306a36Sopenharmony_ciMODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)");
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define FLAG_SST			BIT(0)
2262306a36Sopenharmony_ci#define FLAG_SOF			BIT(1)
2362306a36Sopenharmony_ci#define FLAG_SST_ONLY_IF_DMIC		BIT(15)
2462306a36Sopenharmony_ci#define FLAG_SOF_ONLY_IF_DMIC		BIT(16)
2562306a36Sopenharmony_ci#define FLAG_SOF_ONLY_IF_SOUNDWIRE	BIT(17)
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \
2862306a36Sopenharmony_ci					    FLAG_SOF_ONLY_IF_SOUNDWIRE)
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistruct config_entry {
3162306a36Sopenharmony_ci	u32 flags;
3262306a36Sopenharmony_ci	u16 device;
3362306a36Sopenharmony_ci	u8 acpi_hid[ACPI_ID_LEN];
3462306a36Sopenharmony_ci	const struct dmi_system_id *dmi_table;
3562306a36Sopenharmony_ci	const struct snd_soc_acpi_codecs *codec_hid;
3662306a36Sopenharmony_ci};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = {
3962306a36Sopenharmony_ci	.num_codecs = 3,
4062306a36Sopenharmony_ci	.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
4162306a36Sopenharmony_ci};
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci/*
4462306a36Sopenharmony_ci * configuration table
4562306a36Sopenharmony_ci * - the order of similar PCI ID entries is important!
4662306a36Sopenharmony_ci * - the first successful match will win
4762306a36Sopenharmony_ci */
4862306a36Sopenharmony_cistatic const struct config_entry config_table[] = {
4962306a36Sopenharmony_ci/* Merrifield */
5062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
5162306a36Sopenharmony_ci	{
5262306a36Sopenharmony_ci		.flags = FLAG_SOF,
5362306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_SST_TNG,
5462306a36Sopenharmony_ci	},
5562306a36Sopenharmony_ci#endif
5662306a36Sopenharmony_ci/*
5762306a36Sopenharmony_ci * Apollolake (Broxton-P)
5862306a36Sopenharmony_ci * the legacy HDAudio driver is used except on Up Squared (SOF) and
5962306a36Sopenharmony_ci * Chromebooks (SST), as well as devices based on the ES8336 codec
6062306a36Sopenharmony_ci */
6162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
6262306a36Sopenharmony_ci	{
6362306a36Sopenharmony_ci		.flags = FLAG_SOF,
6462306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_APL,
6562306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
6662306a36Sopenharmony_ci			{
6762306a36Sopenharmony_ci				.ident = "Up Squared",
6862306a36Sopenharmony_ci				.matches = {
6962306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
7062306a36Sopenharmony_ci					DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"),
7162306a36Sopenharmony_ci				}
7262306a36Sopenharmony_ci			},
7362306a36Sopenharmony_ci			{}
7462306a36Sopenharmony_ci		}
7562306a36Sopenharmony_ci	},
7662306a36Sopenharmony_ci	{
7762306a36Sopenharmony_ci		.flags = FLAG_SOF,
7862306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_APL,
7962306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
8062306a36Sopenharmony_ci	},
8162306a36Sopenharmony_ci#endif
8262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
8362306a36Sopenharmony_ci	{
8462306a36Sopenharmony_ci		.flags = FLAG_SST,
8562306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_APL,
8662306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
8762306a36Sopenharmony_ci			{
8862306a36Sopenharmony_ci				.ident = "Google Chromebooks",
8962306a36Sopenharmony_ci				.matches = {
9062306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
9162306a36Sopenharmony_ci				}
9262306a36Sopenharmony_ci			},
9362306a36Sopenharmony_ci			{}
9462306a36Sopenharmony_ci		}
9562306a36Sopenharmony_ci	},
9662306a36Sopenharmony_ci#endif
9762306a36Sopenharmony_ci/*
9862306a36Sopenharmony_ci * Skylake and Kabylake use legacy HDAudio driver except for Google
9962306a36Sopenharmony_ci * Chromebooks (SST)
10062306a36Sopenharmony_ci */
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Sunrise Point-LP */
10362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)
10462306a36Sopenharmony_ci	{
10562306a36Sopenharmony_ci		.flags = FLAG_SST,
10662306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
10762306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
10862306a36Sopenharmony_ci			{
10962306a36Sopenharmony_ci				.ident = "Google Chromebooks",
11062306a36Sopenharmony_ci				.matches = {
11162306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
11262306a36Sopenharmony_ci				}
11362306a36Sopenharmony_ci			},
11462306a36Sopenharmony_ci			{}
11562306a36Sopenharmony_ci		}
11662306a36Sopenharmony_ci	},
11762306a36Sopenharmony_ci	{
11862306a36Sopenharmony_ci		.flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
11962306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
12062306a36Sopenharmony_ci	},
12162306a36Sopenharmony_ci#endif
12262306a36Sopenharmony_ci/* Kabylake-LP */
12362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
12462306a36Sopenharmony_ci	{
12562306a36Sopenharmony_ci		.flags = FLAG_SST,
12662306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
12762306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
12862306a36Sopenharmony_ci			{
12962306a36Sopenharmony_ci				.ident = "Google Chromebooks",
13062306a36Sopenharmony_ci				.matches = {
13162306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
13262306a36Sopenharmony_ci				}
13362306a36Sopenharmony_ci			},
13462306a36Sopenharmony_ci			{}
13562306a36Sopenharmony_ci		}
13662306a36Sopenharmony_ci	},
13762306a36Sopenharmony_ci	{
13862306a36Sopenharmony_ci		.flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
13962306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
14062306a36Sopenharmony_ci	},
14162306a36Sopenharmony_ci#endif
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci/*
14462306a36Sopenharmony_ci * Geminilake uses legacy HDAudio driver except for Google
14562306a36Sopenharmony_ci * Chromebooks and devices based on the ES8336 codec
14662306a36Sopenharmony_ci */
14762306a36Sopenharmony_ci/* Geminilake */
14862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)
14962306a36Sopenharmony_ci	{
15062306a36Sopenharmony_ci		.flags = FLAG_SOF,
15162306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_GML,
15262306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
15362306a36Sopenharmony_ci			{
15462306a36Sopenharmony_ci				.ident = "Google Chromebooks",
15562306a36Sopenharmony_ci				.matches = {
15662306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
15762306a36Sopenharmony_ci				}
15862306a36Sopenharmony_ci			},
15962306a36Sopenharmony_ci			{}
16062306a36Sopenharmony_ci		}
16162306a36Sopenharmony_ci	},
16262306a36Sopenharmony_ci	{
16362306a36Sopenharmony_ci		.flags = FLAG_SOF,
16462306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_GML,
16562306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
16662306a36Sopenharmony_ci	},
16762306a36Sopenharmony_ci#endif
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/*
17062306a36Sopenharmony_ci * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake, AlderLake,
17162306a36Sopenharmony_ci * RaptorLake use legacy HDAudio driver except for Google Chromebooks
17262306a36Sopenharmony_ci * and when DMICs are present. Two cases are required since Coreboot
17362306a36Sopenharmony_ci * does not expose NHLT tables.
17462306a36Sopenharmony_ci *
17562306a36Sopenharmony_ci * When the Chromebook quirk is not present, it's based on information
17662306a36Sopenharmony_ci * that no such device exists. When the quirk is present, it could be
17762306a36Sopenharmony_ci * either based on product information or a placeholder.
17862306a36Sopenharmony_ci */
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci/* Cannonlake */
18162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)
18262306a36Sopenharmony_ci	{
18362306a36Sopenharmony_ci		.flags = FLAG_SOF,
18462306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
18562306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
18662306a36Sopenharmony_ci			{
18762306a36Sopenharmony_ci				.ident = "Google Chromebooks",
18862306a36Sopenharmony_ci				.matches = {
18962306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
19062306a36Sopenharmony_ci				}
19162306a36Sopenharmony_ci			},
19262306a36Sopenharmony_ci			{
19362306a36Sopenharmony_ci				.ident = "UP-WHL",
19462306a36Sopenharmony_ci				.matches = {
19562306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
19662306a36Sopenharmony_ci				}
19762306a36Sopenharmony_ci			},
19862306a36Sopenharmony_ci			{}
19962306a36Sopenharmony_ci		}
20062306a36Sopenharmony_ci	},
20162306a36Sopenharmony_ci	{
20262306a36Sopenharmony_ci		.flags = FLAG_SOF,
20362306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
20462306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
20562306a36Sopenharmony_ci	},
20662306a36Sopenharmony_ci	{
20762306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
20862306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
20962306a36Sopenharmony_ci	},
21062306a36Sopenharmony_ci#endif
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci/* Coffelake */
21362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)
21462306a36Sopenharmony_ci	{
21562306a36Sopenharmony_ci		.flags = FLAG_SOF,
21662306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CNL_H,
21762306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
21862306a36Sopenharmony_ci			{
21962306a36Sopenharmony_ci				.ident = "Google Chromebooks",
22062306a36Sopenharmony_ci				.matches = {
22162306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
22262306a36Sopenharmony_ci				}
22362306a36Sopenharmony_ci			},
22462306a36Sopenharmony_ci			{}
22562306a36Sopenharmony_ci		}
22662306a36Sopenharmony_ci	},
22762306a36Sopenharmony_ci	{
22862306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
22962306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CNL_H,
23062306a36Sopenharmony_ci	},
23162306a36Sopenharmony_ci#endif
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE)
23462306a36Sopenharmony_ci/* Cometlake-LP */
23562306a36Sopenharmony_ci	{
23662306a36Sopenharmony_ci		.flags = FLAG_SOF,
23762306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
23862306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
23962306a36Sopenharmony_ci			{
24062306a36Sopenharmony_ci				.ident = "Google Chromebooks",
24162306a36Sopenharmony_ci				.matches = {
24262306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
24362306a36Sopenharmony_ci				}
24462306a36Sopenharmony_ci			},
24562306a36Sopenharmony_ci			{
24662306a36Sopenharmony_ci				.matches = {
24762306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
24862306a36Sopenharmony_ci					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
24962306a36Sopenharmony_ci				},
25062306a36Sopenharmony_ci			},
25162306a36Sopenharmony_ci			{
25262306a36Sopenharmony_ci				/* early version of SKU 09C6 */
25362306a36Sopenharmony_ci				.matches = {
25462306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
25562306a36Sopenharmony_ci					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
25662306a36Sopenharmony_ci				},
25762306a36Sopenharmony_ci			},
25862306a36Sopenharmony_ci			{}
25962306a36Sopenharmony_ci		}
26062306a36Sopenharmony_ci	},
26162306a36Sopenharmony_ci	{
26262306a36Sopenharmony_ci		.flags = FLAG_SOF,
26362306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
26462306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
26562306a36Sopenharmony_ci	},
26662306a36Sopenharmony_ci	{
26762306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
26862306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
26962306a36Sopenharmony_ci	},
27062306a36Sopenharmony_ci/* Cometlake-H */
27162306a36Sopenharmony_ci	{
27262306a36Sopenharmony_ci		.flags = FLAG_SOF,
27362306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CML_H,
27462306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
27562306a36Sopenharmony_ci			{
27662306a36Sopenharmony_ci				.matches = {
27762306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
27862306a36Sopenharmony_ci					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
27962306a36Sopenharmony_ci				},
28062306a36Sopenharmony_ci			},
28162306a36Sopenharmony_ci			{
28262306a36Sopenharmony_ci				.matches = {
28362306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
28462306a36Sopenharmony_ci					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
28562306a36Sopenharmony_ci				},
28662306a36Sopenharmony_ci			},
28762306a36Sopenharmony_ci			{}
28862306a36Sopenharmony_ci		}
28962306a36Sopenharmony_ci	},
29062306a36Sopenharmony_ci	{
29162306a36Sopenharmony_ci		.flags = FLAG_SOF,
29262306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CML_H,
29362306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
29462306a36Sopenharmony_ci	},
29562306a36Sopenharmony_ci	{
29662306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
29762306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_CML_H,
29862306a36Sopenharmony_ci	},
29962306a36Sopenharmony_ci#endif
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci/* Icelake */
30262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
30362306a36Sopenharmony_ci	{
30462306a36Sopenharmony_ci		.flags = FLAG_SOF,
30562306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,
30662306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
30762306a36Sopenharmony_ci			{
30862306a36Sopenharmony_ci				.ident = "Google Chromebooks",
30962306a36Sopenharmony_ci				.matches = {
31062306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
31162306a36Sopenharmony_ci				}
31262306a36Sopenharmony_ci			},
31362306a36Sopenharmony_ci			{}
31462306a36Sopenharmony_ci		}
31562306a36Sopenharmony_ci	},
31662306a36Sopenharmony_ci	{
31762306a36Sopenharmony_ci		.flags = FLAG_SOF,
31862306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,
31962306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
32062306a36Sopenharmony_ci	},
32162306a36Sopenharmony_ci	{
32262306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
32362306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,
32462306a36Sopenharmony_ci	},
32562306a36Sopenharmony_ci#endif
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci/* Jasper Lake */
32862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
32962306a36Sopenharmony_ci	{
33062306a36Sopenharmony_ci		.flags = FLAG_SOF,
33162306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,
33262306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
33362306a36Sopenharmony_ci			{
33462306a36Sopenharmony_ci				.ident = "Google Chromebooks",
33562306a36Sopenharmony_ci				.matches = {
33662306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
33762306a36Sopenharmony_ci				}
33862306a36Sopenharmony_ci			},
33962306a36Sopenharmony_ci			{
34062306a36Sopenharmony_ci				.ident = "Google firmware",
34162306a36Sopenharmony_ci				.matches = {
34262306a36Sopenharmony_ci					DMI_MATCH(DMI_BIOS_VERSION, "Google"),
34362306a36Sopenharmony_ci				}
34462306a36Sopenharmony_ci			},
34562306a36Sopenharmony_ci			{}
34662306a36Sopenharmony_ci		}
34762306a36Sopenharmony_ci	},
34862306a36Sopenharmony_ci	{
34962306a36Sopenharmony_ci		.flags = FLAG_SOF,
35062306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,
35162306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
35262306a36Sopenharmony_ci	},
35362306a36Sopenharmony_ci	{
35462306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
35562306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,
35662306a36Sopenharmony_ci	},
35762306a36Sopenharmony_ci#endif
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci/* Tigerlake */
36062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
36162306a36Sopenharmony_ci	{
36262306a36Sopenharmony_ci		.flags = FLAG_SOF,
36362306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,
36462306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
36562306a36Sopenharmony_ci			{
36662306a36Sopenharmony_ci				.ident = "Google Chromebooks",
36762306a36Sopenharmony_ci				.matches = {
36862306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
36962306a36Sopenharmony_ci				}
37062306a36Sopenharmony_ci			},
37162306a36Sopenharmony_ci			{
37262306a36Sopenharmony_ci				.ident = "UPX-TGL",
37362306a36Sopenharmony_ci				.matches = {
37462306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
37562306a36Sopenharmony_ci				}
37662306a36Sopenharmony_ci			},
37762306a36Sopenharmony_ci			{}
37862306a36Sopenharmony_ci		}
37962306a36Sopenharmony_ci	},
38062306a36Sopenharmony_ci	{
38162306a36Sopenharmony_ci		.flags = FLAG_SOF,
38262306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,
38362306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
38462306a36Sopenharmony_ci	},
38562306a36Sopenharmony_ci	{
38662306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
38762306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,
38862306a36Sopenharmony_ci	},
38962306a36Sopenharmony_ci	{
39062306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
39162306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_TGL_H,
39262306a36Sopenharmony_ci	},
39362306a36Sopenharmony_ci#endif
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci/* Elkhart Lake */
39662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
39762306a36Sopenharmony_ci	{
39862306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
39962306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_EHL_0,
40062306a36Sopenharmony_ci	},
40162306a36Sopenharmony_ci	{
40262306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
40362306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_EHL_3,
40462306a36Sopenharmony_ci	},
40562306a36Sopenharmony_ci#endif
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci/* Alder Lake / Raptor Lake */
40862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE)
40962306a36Sopenharmony_ci	{
41062306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
41162306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_S,
41262306a36Sopenharmony_ci	},
41362306a36Sopenharmony_ci	{
41462306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
41562306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_RPL_S,
41662306a36Sopenharmony_ci	},
41762306a36Sopenharmony_ci	{
41862306a36Sopenharmony_ci		.flags = FLAG_SOF,
41962306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,
42062306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
42162306a36Sopenharmony_ci			{
42262306a36Sopenharmony_ci				.ident = "Google Chromebooks",
42362306a36Sopenharmony_ci				.matches = {
42462306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
42562306a36Sopenharmony_ci				}
42662306a36Sopenharmony_ci			},
42762306a36Sopenharmony_ci			{}
42862306a36Sopenharmony_ci		}
42962306a36Sopenharmony_ci	},
43062306a36Sopenharmony_ci	{
43162306a36Sopenharmony_ci		.flags = FLAG_SOF,
43262306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,
43362306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
43462306a36Sopenharmony_ci	},
43562306a36Sopenharmony_ci	{
43662306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
43762306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,
43862306a36Sopenharmony_ci	},
43962306a36Sopenharmony_ci	{
44062306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
44162306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_PX,
44262306a36Sopenharmony_ci	},
44362306a36Sopenharmony_ci	{
44462306a36Sopenharmony_ci		.flags = FLAG_SOF,
44562306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS,
44662306a36Sopenharmony_ci		.codec_hid =  &essx_83x6,
44762306a36Sopenharmony_ci	},
44862306a36Sopenharmony_ci	{
44962306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
45062306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS,
45162306a36Sopenharmony_ci	},
45262306a36Sopenharmony_ci	{
45362306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
45462306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_M,
45562306a36Sopenharmony_ci	},
45662306a36Sopenharmony_ci	{
45762306a36Sopenharmony_ci		.flags = FLAG_SOF,
45862306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_N,
45962306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
46062306a36Sopenharmony_ci			{
46162306a36Sopenharmony_ci				.ident = "Google Chromebooks",
46262306a36Sopenharmony_ci				.matches = {
46362306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
46462306a36Sopenharmony_ci				}
46562306a36Sopenharmony_ci			},
46662306a36Sopenharmony_ci			{}
46762306a36Sopenharmony_ci		}
46862306a36Sopenharmony_ci	},
46962306a36Sopenharmony_ci	{
47062306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
47162306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ADL_N,
47262306a36Sopenharmony_ci	},
47362306a36Sopenharmony_ci	{
47462306a36Sopenharmony_ci		.flags = FLAG_SOF,
47562306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0,
47662306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
47762306a36Sopenharmony_ci			{
47862306a36Sopenharmony_ci				.ident = "Google Chromebooks",
47962306a36Sopenharmony_ci				.matches = {
48062306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
48162306a36Sopenharmony_ci				}
48262306a36Sopenharmony_ci			},
48362306a36Sopenharmony_ci			{}
48462306a36Sopenharmony_ci		}
48562306a36Sopenharmony_ci	},
48662306a36Sopenharmony_ci	{
48762306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
48862306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0,
48962306a36Sopenharmony_ci	},
49062306a36Sopenharmony_ci	{
49162306a36Sopenharmony_ci		.flags = FLAG_SOF,
49262306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1,
49362306a36Sopenharmony_ci		.dmi_table = (const struct dmi_system_id []) {
49462306a36Sopenharmony_ci			{
49562306a36Sopenharmony_ci				.ident = "Google Chromebooks",
49662306a36Sopenharmony_ci				.matches = {
49762306a36Sopenharmony_ci					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
49862306a36Sopenharmony_ci				}
49962306a36Sopenharmony_ci			},
50062306a36Sopenharmony_ci			{}
50162306a36Sopenharmony_ci		}
50262306a36Sopenharmony_ci	},
50362306a36Sopenharmony_ci	{
50462306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
50562306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1,
50662306a36Sopenharmony_ci	},
50762306a36Sopenharmony_ci	{
50862306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
50962306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_RPL_M,
51062306a36Sopenharmony_ci	},
51162306a36Sopenharmony_ci	{
51262306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
51362306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_RPL_PX,
51462306a36Sopenharmony_ci	},
51562306a36Sopenharmony_ci#endif
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci/* Meteor Lake */
51862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE)
51962306a36Sopenharmony_ci	/* Meteorlake-P */
52062306a36Sopenharmony_ci	{
52162306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
52262306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_MTL,
52362306a36Sopenharmony_ci	},
52462306a36Sopenharmony_ci	/* ArrowLake-S */
52562306a36Sopenharmony_ci	{
52662306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
52762306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ARL_S,
52862306a36Sopenharmony_ci	},
52962306a36Sopenharmony_ci	/* ArrowLake */
53062306a36Sopenharmony_ci	{
53162306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
53262306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_ARL,
53362306a36Sopenharmony_ci	},
53462306a36Sopenharmony_ci#endif
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci/* Lunar Lake */
53762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE)
53862306a36Sopenharmony_ci	/* Lunarlake-P */
53962306a36Sopenharmony_ci	{
54062306a36Sopenharmony_ci		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
54162306a36Sopenharmony_ci		.device = PCI_DEVICE_ID_INTEL_HDA_LNL_P,
54262306a36Sopenharmony_ci	},
54362306a36Sopenharmony_ci#endif
54462306a36Sopenharmony_ci};
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_cistatic const struct config_entry *snd_intel_dsp_find_config
54762306a36Sopenharmony_ci		(struct pci_dev *pci, const struct config_entry *table, u32 len)
54862306a36Sopenharmony_ci{
54962306a36Sopenharmony_ci	u16 device;
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	device = pci->device;
55262306a36Sopenharmony_ci	for (; len > 0; len--, table++) {
55362306a36Sopenharmony_ci		if (table->device != device)
55462306a36Sopenharmony_ci			continue;
55562306a36Sopenharmony_ci		if (table->dmi_table && !dmi_check_system(table->dmi_table))
55662306a36Sopenharmony_ci			continue;
55762306a36Sopenharmony_ci		if (table->codec_hid) {
55862306a36Sopenharmony_ci			int i;
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci			for (i = 0; i < table->codec_hid->num_codecs; i++)
56162306a36Sopenharmony_ci				if (acpi_dev_present(table->codec_hid->codecs[i], NULL, -1))
56262306a36Sopenharmony_ci					break;
56362306a36Sopenharmony_ci			if (i == table->codec_hid->num_codecs)
56462306a36Sopenharmony_ci				continue;
56562306a36Sopenharmony_ci		}
56662306a36Sopenharmony_ci		return table;
56762306a36Sopenharmony_ci	}
56862306a36Sopenharmony_ci	return NULL;
56962306a36Sopenharmony_ci}
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_cistatic int snd_intel_dsp_check_dmic(struct pci_dev *pci)
57262306a36Sopenharmony_ci{
57362306a36Sopenharmony_ci	struct nhlt_acpi_table *nhlt;
57462306a36Sopenharmony_ci	int ret = 0;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	nhlt = intel_nhlt_init(&pci->dev);
57762306a36Sopenharmony_ci	if (nhlt) {
57862306a36Sopenharmony_ci		if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_DMIC))
57962306a36Sopenharmony_ci			ret = 1;
58062306a36Sopenharmony_ci		intel_nhlt_free(nhlt);
58162306a36Sopenharmony_ci	}
58262306a36Sopenharmony_ci	return ret;
58362306a36Sopenharmony_ci}
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
58662306a36Sopenharmony_cistatic int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
58762306a36Sopenharmony_ci{
58862306a36Sopenharmony_ci	struct sdw_intel_acpi_info info;
58962306a36Sopenharmony_ci	acpi_handle handle;
59062306a36Sopenharmony_ci	int ret;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	handle = ACPI_HANDLE(&pci->dev);
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci	ret = sdw_intel_acpi_scan(handle, &info);
59562306a36Sopenharmony_ci	if (ret < 0)
59662306a36Sopenharmony_ci		return ret;
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci	return info.link_mask;
59962306a36Sopenharmony_ci}
60062306a36Sopenharmony_ci#else
60162306a36Sopenharmony_cistatic int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
60262306a36Sopenharmony_ci{
60362306a36Sopenharmony_ci	return 0;
60462306a36Sopenharmony_ci}
60562306a36Sopenharmony_ci#endif
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ciint snd_intel_dsp_driver_probe(struct pci_dev *pci)
60862306a36Sopenharmony_ci{
60962306a36Sopenharmony_ci	const struct config_entry *cfg;
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci	/* Intel vendor only */
61262306a36Sopenharmony_ci	if (pci->vendor != PCI_VENDOR_ID_INTEL)
61362306a36Sopenharmony_ci		return SND_INTEL_DSP_DRIVER_ANY;
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci	/*
61662306a36Sopenharmony_ci	 * Legacy devices don't have a PCI-based DSP and use HDaudio
61762306a36Sopenharmony_ci	 * for HDMI/DP support, ignore kernel parameter
61862306a36Sopenharmony_ci	 */
61962306a36Sopenharmony_ci	switch (pci->device) {
62062306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_HDA_BDW:
62162306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_HDA_HSW_0:
62262306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_HDA_HSW_2:
62362306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_HDA_HSW_3:
62462306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_HDA_BYT:
62562306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_HDA_BSW:
62662306a36Sopenharmony_ci		return SND_INTEL_DSP_DRIVER_ANY;
62762306a36Sopenharmony_ci	}
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci	if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
63062306a36Sopenharmony_ci		return dsp_driver;
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	/*
63362306a36Sopenharmony_ci	 * detect DSP by checking class/subclass/prog-id information
63462306a36Sopenharmony_ci	 * class=04 subclass 03 prog-if 00: no DSP, use legacy driver
63562306a36Sopenharmony_ci	 * class=04 subclass 01 prog-if 00: DSP is present
63662306a36Sopenharmony_ci	 *  (and may be required e.g. for DMIC or SSP support)
63762306a36Sopenharmony_ci	 * class=04 subclass 03 prog-if 80: use DSP or legacy mode
63862306a36Sopenharmony_ci	 */
63962306a36Sopenharmony_ci	if (pci->class == 0x040300)
64062306a36Sopenharmony_ci		return SND_INTEL_DSP_DRIVER_LEGACY;
64162306a36Sopenharmony_ci	if (pci->class != 0x040100 && pci->class != 0x040380) {
64262306a36Sopenharmony_ci		dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class);
64362306a36Sopenharmony_ci		return SND_INTEL_DSP_DRIVER_LEGACY;
64462306a36Sopenharmony_ci	}
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci	dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	/* find the configuration for the specific device */
64962306a36Sopenharmony_ci	cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table));
65062306a36Sopenharmony_ci	if (!cfg)
65162306a36Sopenharmony_ci		return SND_INTEL_DSP_DRIVER_ANY;
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci	if (cfg->flags & FLAG_SOF) {
65462306a36Sopenharmony_ci		if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
65562306a36Sopenharmony_ci		    snd_intel_dsp_check_soundwire(pci) > 0) {
65662306a36Sopenharmony_ci			dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");
65762306a36Sopenharmony_ci			return SND_INTEL_DSP_DRIVER_SOF;
65862306a36Sopenharmony_ci		}
65962306a36Sopenharmony_ci		if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
66062306a36Sopenharmony_ci		    snd_intel_dsp_check_dmic(pci)) {
66162306a36Sopenharmony_ci			dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
66262306a36Sopenharmony_ci			return SND_INTEL_DSP_DRIVER_SOF;
66362306a36Sopenharmony_ci		}
66462306a36Sopenharmony_ci		if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))
66562306a36Sopenharmony_ci			return SND_INTEL_DSP_DRIVER_SOF;
66662306a36Sopenharmony_ci	}
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	if (cfg->flags & FLAG_SST) {
67062306a36Sopenharmony_ci		if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) {
67162306a36Sopenharmony_ci			if (snd_intel_dsp_check_dmic(pci)) {
67262306a36Sopenharmony_ci				dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n");
67362306a36Sopenharmony_ci				return SND_INTEL_DSP_DRIVER_SST;
67462306a36Sopenharmony_ci			}
67562306a36Sopenharmony_ci		} else {
67662306a36Sopenharmony_ci			return SND_INTEL_DSP_DRIVER_SST;
67762306a36Sopenharmony_ci		}
67862306a36Sopenharmony_ci	}
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	return SND_INTEL_DSP_DRIVER_LEGACY;
68162306a36Sopenharmony_ci}
68262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci/* Should we default to SOF or SST for BYT/CHT ? */
68562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \
68662306a36Sopenharmony_ci    !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI)
68762306a36Sopenharmony_ci#define FLAG_SST_OR_SOF_BYT	FLAG_SOF
68862306a36Sopenharmony_ci#else
68962306a36Sopenharmony_ci#define FLAG_SST_OR_SOF_BYT	FLAG_SST
69062306a36Sopenharmony_ci#endif
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci/*
69362306a36Sopenharmony_ci * configuration table
69462306a36Sopenharmony_ci * - the order of similar ACPI ID entries is important!
69562306a36Sopenharmony_ci * - the first successful match will win
69662306a36Sopenharmony_ci */
69762306a36Sopenharmony_cistatic const struct config_entry acpi_config_table[] = {
69862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
69962306a36Sopenharmony_ci    IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
70062306a36Sopenharmony_ci/* BayTrail */
70162306a36Sopenharmony_ci	{
70262306a36Sopenharmony_ci		.flags = FLAG_SST_OR_SOF_BYT,
70362306a36Sopenharmony_ci		.acpi_hid = "80860F28",
70462306a36Sopenharmony_ci	},
70562306a36Sopenharmony_ci/* CherryTrail */
70662306a36Sopenharmony_ci	{
70762306a36Sopenharmony_ci		.flags = FLAG_SST_OR_SOF_BYT,
70862306a36Sopenharmony_ci		.acpi_hid = "808622A8",
70962306a36Sopenharmony_ci	},
71062306a36Sopenharmony_ci#endif
71162306a36Sopenharmony_ci/* Broadwell */
71262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
71362306a36Sopenharmony_ci	{
71462306a36Sopenharmony_ci		.flags = FLAG_SST,
71562306a36Sopenharmony_ci		.acpi_hid = "INT3438"
71662306a36Sopenharmony_ci	},
71762306a36Sopenharmony_ci#endif
71862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
71962306a36Sopenharmony_ci	{
72062306a36Sopenharmony_ci		.flags = FLAG_SOF,
72162306a36Sopenharmony_ci		.acpi_hid = "INT3438"
72262306a36Sopenharmony_ci	},
72362306a36Sopenharmony_ci#endif
72462306a36Sopenharmony_ci/* Haswell - not supported by SOF but added for consistency */
72562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
72662306a36Sopenharmony_ci	{
72762306a36Sopenharmony_ci		.flags = FLAG_SST,
72862306a36Sopenharmony_ci		.acpi_hid = "INT33C8"
72962306a36Sopenharmony_ci	},
73062306a36Sopenharmony_ci#endif
73162306a36Sopenharmony_ci};
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_cistatic const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN],
73462306a36Sopenharmony_ci								 const struct config_entry *table,
73562306a36Sopenharmony_ci								 u32 len)
73662306a36Sopenharmony_ci{
73762306a36Sopenharmony_ci	for (; len > 0; len--, table++) {
73862306a36Sopenharmony_ci		if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN))
73962306a36Sopenharmony_ci			continue;
74062306a36Sopenharmony_ci		if (table->dmi_table && !dmi_check_system(table->dmi_table))
74162306a36Sopenharmony_ci			continue;
74262306a36Sopenharmony_ci		return table;
74362306a36Sopenharmony_ci	}
74462306a36Sopenharmony_ci	return NULL;
74562306a36Sopenharmony_ci}
74662306a36Sopenharmony_ci
74762306a36Sopenharmony_ciint snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN])
74862306a36Sopenharmony_ci{
74962306a36Sopenharmony_ci	const struct config_entry *cfg;
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
75262306a36Sopenharmony_ci		return dsp_driver;
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci	if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) {
75562306a36Sopenharmony_ci		dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n",
75662306a36Sopenharmony_ci			 SND_INTEL_DSP_DRIVER_LEGACY);
75762306a36Sopenharmony_ci	}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	/* find the configuration for the specific device */
76062306a36Sopenharmony_ci	cfg = snd_intel_acpi_dsp_find_config(acpi_hid,  acpi_config_table,
76162306a36Sopenharmony_ci					     ARRAY_SIZE(acpi_config_table));
76262306a36Sopenharmony_ci	if (!cfg)
76362306a36Sopenharmony_ci		return SND_INTEL_DSP_DRIVER_ANY;
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci	if (cfg->flags & FLAG_SST)
76662306a36Sopenharmony_ci		return SND_INTEL_DSP_DRIVER_SST;
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_ci	if (cfg->flags & FLAG_SOF)
76962306a36Sopenharmony_ci		return SND_INTEL_DSP_DRIVER_SOF;
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci	return SND_INTEL_DSP_DRIVER_SST;
77262306a36Sopenharmony_ci}
77362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe);
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
77662306a36Sopenharmony_ciMODULE_DESCRIPTION("Intel DSP config driver");
77762306a36Sopenharmony_ciMODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);
778