18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
28c2ecf20Sopenharmony_ci//
38c2ecf20Sopenharmony_ci// This file is provided under a dual BSD/GPLv2 license.  When using or
48c2ecf20Sopenharmony_ci// redistributing this file, you may do so under either license.
58c2ecf20Sopenharmony_ci//
68c2ecf20Sopenharmony_ci// Copyright(c) 2018 Intel Corporation. All rights reserved.
78c2ecf20Sopenharmony_ci//
88c2ecf20Sopenharmony_ci// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
98c2ecf20Sopenharmony_ci//
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/firmware.h>
128c2ecf20Sopenharmony_ci#include <linux/dmi.h>
138c2ecf20Sopenharmony_ci#include <linux/module.h>
148c2ecf20Sopenharmony_ci#include <linux/pci.h>
158c2ecf20Sopenharmony_ci#include <linux/platform_data/x86/soc.h>
168c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h>
178c2ecf20Sopenharmony_ci#include <sound/intel-dsp-config.h>
188c2ecf20Sopenharmony_ci#include <sound/soc-acpi.h>
198c2ecf20Sopenharmony_ci#include <sound/soc-acpi-intel-match.h>
208c2ecf20Sopenharmony_ci#include <sound/sof.h>
218c2ecf20Sopenharmony_ci#include "ops.h"
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/* platform specific devices */
248c2ecf20Sopenharmony_ci#include "intel/shim.h"
258c2ecf20Sopenharmony_ci#include "intel/hda.h"
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_cistatic char *fw_path;
288c2ecf20Sopenharmony_cimodule_param(fw_path, charp, 0444);
298c2ecf20Sopenharmony_ciMODULE_PARM_DESC(fw_path, "alternate path for SOF firmware.");
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic char *tplg_path;
328c2ecf20Sopenharmony_cimodule_param(tplg_path, charp, 0444);
338c2ecf20Sopenharmony_ciMODULE_PARM_DESC(tplg_path, "alternate path for SOF topology.");
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic char *tplg_filename;
368c2ecf20Sopenharmony_cimodule_param(tplg_filename, charp, 0444);
378c2ecf20Sopenharmony_ciMODULE_PARM_DESC(tplg_filename, "alternate filename for SOF topology.");
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic int sof_pci_debug;
408c2ecf20Sopenharmony_cimodule_param_named(sof_pci_debug, sof_pci_debug, int, 0444);
418c2ecf20Sopenharmony_ciMODULE_PARM_DESC(sof_pci_debug, "SOF PCI debug options (0x0 all off)");
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cistatic const char *sof_dmi_override_tplg_name;
448c2ecf20Sopenharmony_cistatic bool sof_dmi_use_community_key;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#define SOF_PCI_DISABLE_PM_RUNTIME BIT(0)
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistatic int sof_tplg_cb(const struct dmi_system_id *id)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	sof_dmi_override_tplg_name = id->driver_data;
518c2ecf20Sopenharmony_ci	return 1;
528c2ecf20Sopenharmony_ci}
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistatic const struct dmi_system_id sof_tplg_table[] = {
558c2ecf20Sopenharmony_ci	{
568c2ecf20Sopenharmony_ci		.callback = sof_tplg_cb,
578c2ecf20Sopenharmony_ci		.matches = {
588c2ecf20Sopenharmony_ci			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"),
598c2ecf20Sopenharmony_ci			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"),
608c2ecf20Sopenharmony_ci		},
618c2ecf20Sopenharmony_ci		.driver_data = "sof-tgl-rt5682-ssp0-max98373-ssp2.tplg",
628c2ecf20Sopenharmony_ci	},
638c2ecf20Sopenharmony_ci	{}
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci/* all Up boards use the community key */
678c2ecf20Sopenharmony_cistatic int up_use_community_key(const struct dmi_system_id *id)
688c2ecf20Sopenharmony_ci{
698c2ecf20Sopenharmony_ci	sof_dmi_use_community_key = true;
708c2ecf20Sopenharmony_ci	return 1;
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/*
748c2ecf20Sopenharmony_ci * For ApolloLake Chromebooks we want to force the use of the Intel production key.
758c2ecf20Sopenharmony_ci * All newer platforms use the community key
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_cistatic int chromebook_use_community_key(const struct dmi_system_id *id)
788c2ecf20Sopenharmony_ci{
798c2ecf20Sopenharmony_ci	if (!soc_intel_is_apl())
808c2ecf20Sopenharmony_ci		sof_dmi_use_community_key = true;
818c2ecf20Sopenharmony_ci	return 1;
828c2ecf20Sopenharmony_ci}
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistatic const struct dmi_system_id community_key_platforms[] = {
858c2ecf20Sopenharmony_ci	{
868c2ecf20Sopenharmony_ci		.ident = "Up boards",
878c2ecf20Sopenharmony_ci		.callback = up_use_community_key,
888c2ecf20Sopenharmony_ci		.matches = {
898c2ecf20Sopenharmony_ci			DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
908c2ecf20Sopenharmony_ci		}
918c2ecf20Sopenharmony_ci	},
928c2ecf20Sopenharmony_ci	{
938c2ecf20Sopenharmony_ci		.ident = "Google Chromebooks",
948c2ecf20Sopenharmony_ci		.callback = chromebook_use_community_key,
958c2ecf20Sopenharmony_ci		.matches = {
968c2ecf20Sopenharmony_ci			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google"),
978c2ecf20Sopenharmony_ci		}
988c2ecf20Sopenharmony_ci	},
998c2ecf20Sopenharmony_ci	{
1008c2ecf20Sopenharmony_ci		.ident = "Google firmware",
1018c2ecf20Sopenharmony_ci		.callback = chromebook_use_community_key,
1028c2ecf20Sopenharmony_ci		.matches = {
1038c2ecf20Sopenharmony_ci			DMI_MATCH(DMI_BIOS_VERSION, "Google"),
1048c2ecf20Sopenharmony_ci		}
1058c2ecf20Sopenharmony_ci	},
1068c2ecf20Sopenharmony_ci	{},
1078c2ecf20Sopenharmony_ci};
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
1108c2ecf20Sopenharmony_cistatic const struct sof_dev_desc bxt_desc = {
1118c2ecf20Sopenharmony_ci	.machines		= snd_soc_acpi_intel_bxt_machines,
1128c2ecf20Sopenharmony_ci	.use_acpi_target_states	= true,
1138c2ecf20Sopenharmony_ci	.resindex_lpe_base	= 0,
1148c2ecf20Sopenharmony_ci	.resindex_pcicfg_base	= -1,
1158c2ecf20Sopenharmony_ci	.resindex_imr_base	= -1,
1168c2ecf20Sopenharmony_ci	.irqindex_host_ipc	= -1,
1178c2ecf20Sopenharmony_ci	.resindex_dma_base	= -1,
1188c2ecf20Sopenharmony_ci	.chip_info = &apl_chip_info,
1198c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
1208c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
1218c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-apl.ri",
1228c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-apl-nocodec.tplg",
1238c2ecf20Sopenharmony_ci	.ops = &sof_apl_ops,
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci#endif
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)
1288c2ecf20Sopenharmony_cistatic const struct sof_dev_desc glk_desc = {
1298c2ecf20Sopenharmony_ci	.machines		= snd_soc_acpi_intel_glk_machines,
1308c2ecf20Sopenharmony_ci	.use_acpi_target_states	= true,
1318c2ecf20Sopenharmony_ci	.resindex_lpe_base	= 0,
1328c2ecf20Sopenharmony_ci	.resindex_pcicfg_base	= -1,
1338c2ecf20Sopenharmony_ci	.resindex_imr_base	= -1,
1348c2ecf20Sopenharmony_ci	.irqindex_host_ipc	= -1,
1358c2ecf20Sopenharmony_ci	.resindex_dma_base	= -1,
1368c2ecf20Sopenharmony_ci	.chip_info = &apl_chip_info,
1378c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
1388c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
1398c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-glk.ri",
1408c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-glk-nocodec.tplg",
1418c2ecf20Sopenharmony_ci	.ops = &sof_apl_ops,
1428c2ecf20Sopenharmony_ci};
1438c2ecf20Sopenharmony_ci#endif
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
1468c2ecf20Sopenharmony_cistatic struct snd_soc_acpi_mach sof_tng_machines[] = {
1478c2ecf20Sopenharmony_ci	{
1488c2ecf20Sopenharmony_ci		.id = "INT343A",
1498c2ecf20Sopenharmony_ci		.drv_name = "edison",
1508c2ecf20Sopenharmony_ci		.sof_fw_filename = "sof-byt.ri",
1518c2ecf20Sopenharmony_ci		.sof_tplg_filename = "sof-byt.tplg",
1528c2ecf20Sopenharmony_ci	},
1538c2ecf20Sopenharmony_ci	{}
1548c2ecf20Sopenharmony_ci};
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_cistatic const struct sof_dev_desc tng_desc = {
1578c2ecf20Sopenharmony_ci	.machines		= sof_tng_machines,
1588c2ecf20Sopenharmony_ci	.resindex_lpe_base	= 3,	/* IRAM, but subtract IRAM offset */
1598c2ecf20Sopenharmony_ci	.resindex_pcicfg_base	= -1,
1608c2ecf20Sopenharmony_ci	.resindex_imr_base	= 0,
1618c2ecf20Sopenharmony_ci	.irqindex_host_ipc	= -1,
1628c2ecf20Sopenharmony_ci	.resindex_dma_base	= -1,
1638c2ecf20Sopenharmony_ci	.chip_info = &tng_chip_info,
1648c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
1658c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
1668c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-byt.ri",
1678c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-byt.tplg",
1688c2ecf20Sopenharmony_ci	.ops = &sof_tng_ops,
1698c2ecf20Sopenharmony_ci};
1708c2ecf20Sopenharmony_ci#endif
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)
1738c2ecf20Sopenharmony_cistatic const struct sof_dev_desc cnl_desc = {
1748c2ecf20Sopenharmony_ci	.machines		= snd_soc_acpi_intel_cnl_machines,
1758c2ecf20Sopenharmony_ci	.alt_machines		= snd_soc_acpi_intel_cnl_sdw_machines,
1768c2ecf20Sopenharmony_ci	.use_acpi_target_states	= true,
1778c2ecf20Sopenharmony_ci	.resindex_lpe_base	= 0,
1788c2ecf20Sopenharmony_ci	.resindex_pcicfg_base	= -1,
1798c2ecf20Sopenharmony_ci	.resindex_imr_base	= -1,
1808c2ecf20Sopenharmony_ci	.irqindex_host_ipc	= -1,
1818c2ecf20Sopenharmony_ci	.resindex_dma_base	= -1,
1828c2ecf20Sopenharmony_ci	.chip_info = &cnl_chip_info,
1838c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
1848c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
1858c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-cnl.ri",
1868c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-cnl-nocodec.tplg",
1878c2ecf20Sopenharmony_ci	.ops = &sof_cnl_ops,
1888c2ecf20Sopenharmony_ci};
1898c2ecf20Sopenharmony_ci#endif
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)
1928c2ecf20Sopenharmony_cistatic const struct sof_dev_desc cfl_desc = {
1938c2ecf20Sopenharmony_ci	.machines		= snd_soc_acpi_intel_cfl_machines,
1948c2ecf20Sopenharmony_ci	.alt_machines		= snd_soc_acpi_intel_cfl_sdw_machines,
1958c2ecf20Sopenharmony_ci	.use_acpi_target_states	= true,
1968c2ecf20Sopenharmony_ci	.resindex_lpe_base	= 0,
1978c2ecf20Sopenharmony_ci	.resindex_pcicfg_base	= -1,
1988c2ecf20Sopenharmony_ci	.resindex_imr_base	= -1,
1998c2ecf20Sopenharmony_ci	.irqindex_host_ipc	= -1,
2008c2ecf20Sopenharmony_ci	.resindex_dma_base	= -1,
2018c2ecf20Sopenharmony_ci	.chip_info = &cnl_chip_info,
2028c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
2038c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
2048c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-cfl.ri",
2058c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-cnl-nocodec.tplg",
2068c2ecf20Sopenharmony_ci	.ops = &sof_cnl_ops,
2078c2ecf20Sopenharmony_ci};
2088c2ecf20Sopenharmony_ci#endif
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE)
2118c2ecf20Sopenharmony_cistatic const struct sof_dev_desc cml_desc = {
2128c2ecf20Sopenharmony_ci	.machines		= snd_soc_acpi_intel_cml_machines,
2138c2ecf20Sopenharmony_ci	.alt_machines		= snd_soc_acpi_intel_cml_sdw_machines,
2148c2ecf20Sopenharmony_ci	.use_acpi_target_states	= true,
2158c2ecf20Sopenharmony_ci	.resindex_lpe_base	= 0,
2168c2ecf20Sopenharmony_ci	.resindex_pcicfg_base	= -1,
2178c2ecf20Sopenharmony_ci	.resindex_imr_base	= -1,
2188c2ecf20Sopenharmony_ci	.irqindex_host_ipc	= -1,
2198c2ecf20Sopenharmony_ci	.resindex_dma_base	= -1,
2208c2ecf20Sopenharmony_ci	.chip_info = &cnl_chip_info,
2218c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
2228c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
2238c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-cml.ri",
2248c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-cnl-nocodec.tplg",
2258c2ecf20Sopenharmony_ci	.ops = &sof_cnl_ops,
2268c2ecf20Sopenharmony_ci};
2278c2ecf20Sopenharmony_ci#endif
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
2308c2ecf20Sopenharmony_cistatic const struct sof_dev_desc icl_desc = {
2318c2ecf20Sopenharmony_ci	.machines               = snd_soc_acpi_intel_icl_machines,
2328c2ecf20Sopenharmony_ci	.alt_machines		= snd_soc_acpi_intel_icl_sdw_machines,
2338c2ecf20Sopenharmony_ci	.use_acpi_target_states	= true,
2348c2ecf20Sopenharmony_ci	.resindex_lpe_base      = 0,
2358c2ecf20Sopenharmony_ci	.resindex_pcicfg_base   = -1,
2368c2ecf20Sopenharmony_ci	.resindex_imr_base      = -1,
2378c2ecf20Sopenharmony_ci	.irqindex_host_ipc      = -1,
2388c2ecf20Sopenharmony_ci	.resindex_dma_base      = -1,
2398c2ecf20Sopenharmony_ci	.chip_info = &icl_chip_info,
2408c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
2418c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
2428c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-icl.ri",
2438c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-icl-nocodec.tplg",
2448c2ecf20Sopenharmony_ci	.ops = &sof_cnl_ops,
2458c2ecf20Sopenharmony_ci};
2468c2ecf20Sopenharmony_ci#endif
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
2498c2ecf20Sopenharmony_cistatic const struct sof_dev_desc tgl_desc = {
2508c2ecf20Sopenharmony_ci	.machines               = snd_soc_acpi_intel_tgl_machines,
2518c2ecf20Sopenharmony_ci	.alt_machines		= snd_soc_acpi_intel_tgl_sdw_machines,
2528c2ecf20Sopenharmony_ci	.use_acpi_target_states	= true,
2538c2ecf20Sopenharmony_ci	.resindex_lpe_base      = 0,
2548c2ecf20Sopenharmony_ci	.resindex_pcicfg_base   = -1,
2558c2ecf20Sopenharmony_ci	.resindex_imr_base      = -1,
2568c2ecf20Sopenharmony_ci	.irqindex_host_ipc      = -1,
2578c2ecf20Sopenharmony_ci	.resindex_dma_base      = -1,
2588c2ecf20Sopenharmony_ci	.chip_info = &tgl_chip_info,
2598c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
2608c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
2618c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-tgl.ri",
2628c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-tgl-nocodec.tplg",
2638c2ecf20Sopenharmony_ci	.ops = &sof_tgl_ops,
2648c2ecf20Sopenharmony_ci};
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_cistatic const struct sof_dev_desc tglh_desc = {
2678c2ecf20Sopenharmony_ci	.machines               = snd_soc_acpi_intel_tgl_machines,
2688c2ecf20Sopenharmony_ci	.alt_machines		= snd_soc_acpi_intel_tgl_sdw_machines,
2698c2ecf20Sopenharmony_ci	.resindex_lpe_base      = 0,
2708c2ecf20Sopenharmony_ci	.resindex_pcicfg_base   = -1,
2718c2ecf20Sopenharmony_ci	.resindex_imr_base      = -1,
2728c2ecf20Sopenharmony_ci	.irqindex_host_ipc      = -1,
2738c2ecf20Sopenharmony_ci	.resindex_dma_base      = -1,
2748c2ecf20Sopenharmony_ci	.chip_info = &tglh_chip_info,
2758c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
2768c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
2778c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-tgl-h.ri",
2788c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-tgl-nocodec.tplg",
2798c2ecf20Sopenharmony_ci	.ops = &sof_tgl_ops,
2808c2ecf20Sopenharmony_ci};
2818c2ecf20Sopenharmony_ci#endif
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
2848c2ecf20Sopenharmony_cistatic const struct sof_dev_desc ehl_desc = {
2858c2ecf20Sopenharmony_ci	.machines               = snd_soc_acpi_intel_ehl_machines,
2868c2ecf20Sopenharmony_ci	.use_acpi_target_states	= true,
2878c2ecf20Sopenharmony_ci	.resindex_lpe_base      = 0,
2888c2ecf20Sopenharmony_ci	.resindex_pcicfg_base   = -1,
2898c2ecf20Sopenharmony_ci	.resindex_imr_base      = -1,
2908c2ecf20Sopenharmony_ci	.irqindex_host_ipc      = -1,
2918c2ecf20Sopenharmony_ci	.resindex_dma_base      = -1,
2928c2ecf20Sopenharmony_ci	.chip_info = &ehl_chip_info,
2938c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
2948c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
2958c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-ehl.ri",
2968c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-ehl-nocodec.tplg",
2978c2ecf20Sopenharmony_ci	.ops = &sof_cnl_ops,
2988c2ecf20Sopenharmony_ci};
2998c2ecf20Sopenharmony_ci#endif
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
3028c2ecf20Sopenharmony_cistatic const struct sof_dev_desc jsl_desc = {
3038c2ecf20Sopenharmony_ci	.machines               = snd_soc_acpi_intel_jsl_machines,
3048c2ecf20Sopenharmony_ci	.use_acpi_target_states	= true,
3058c2ecf20Sopenharmony_ci	.resindex_lpe_base      = 0,
3068c2ecf20Sopenharmony_ci	.resindex_pcicfg_base   = -1,
3078c2ecf20Sopenharmony_ci	.resindex_imr_base      = -1,
3088c2ecf20Sopenharmony_ci	.irqindex_host_ipc      = -1,
3098c2ecf20Sopenharmony_ci	.resindex_dma_base      = -1,
3108c2ecf20Sopenharmony_ci	.chip_info = &jsl_chip_info,
3118c2ecf20Sopenharmony_ci	.default_fw_path = "intel/sof",
3128c2ecf20Sopenharmony_ci	.default_tplg_path = "intel/sof-tplg",
3138c2ecf20Sopenharmony_ci	.default_fw_filename = "sof-jsl.ri",
3148c2ecf20Sopenharmony_ci	.nocodec_tplg_filename = "sof-jsl-nocodec.tplg",
3158c2ecf20Sopenharmony_ci	.ops = &sof_cnl_ops,
3168c2ecf20Sopenharmony_ci};
3178c2ecf20Sopenharmony_ci#endif
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_cistatic const struct dev_pm_ops sof_pci_pm = {
3208c2ecf20Sopenharmony_ci	.prepare = snd_sof_prepare,
3218c2ecf20Sopenharmony_ci	.complete = snd_sof_complete,
3228c2ecf20Sopenharmony_ci	SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume)
3238c2ecf20Sopenharmony_ci	SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume,
3248c2ecf20Sopenharmony_ci			   snd_sof_runtime_idle)
3258c2ecf20Sopenharmony_ci};
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_cistatic void sof_pci_probe_complete(struct device *dev)
3288c2ecf20Sopenharmony_ci{
3298c2ecf20Sopenharmony_ci	dev_dbg(dev, "Completing SOF PCI probe");
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	if (sof_pci_debug & SOF_PCI_DISABLE_PM_RUNTIME)
3328c2ecf20Sopenharmony_ci		return;
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	/* allow runtime_pm */
3358c2ecf20Sopenharmony_ci	pm_runtime_set_autosuspend_delay(dev, SND_SOF_SUSPEND_DELAY_MS);
3368c2ecf20Sopenharmony_ci	pm_runtime_use_autosuspend(dev);
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	/*
3398c2ecf20Sopenharmony_ci	 * runtime pm for pci device is "forbidden" by default.
3408c2ecf20Sopenharmony_ci	 * so call pm_runtime_allow() to enable it.
3418c2ecf20Sopenharmony_ci	 */
3428c2ecf20Sopenharmony_ci	pm_runtime_allow(dev);
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci	/* mark last_busy for pm_runtime to make sure not suspend immediately */
3458c2ecf20Sopenharmony_ci	pm_runtime_mark_last_busy(dev);
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	/* follow recommendation in pci-driver.c to decrement usage counter */
3488c2ecf20Sopenharmony_ci	pm_runtime_put_noidle(dev);
3498c2ecf20Sopenharmony_ci}
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_cistatic int sof_pci_probe(struct pci_dev *pci,
3528c2ecf20Sopenharmony_ci			 const struct pci_device_id *pci_id)
3538c2ecf20Sopenharmony_ci{
3548c2ecf20Sopenharmony_ci	struct device *dev = &pci->dev;
3558c2ecf20Sopenharmony_ci	const struct sof_dev_desc *desc =
3568c2ecf20Sopenharmony_ci		(const struct sof_dev_desc *)pci_id->driver_data;
3578c2ecf20Sopenharmony_ci	struct snd_sof_pdata *sof_pdata;
3588c2ecf20Sopenharmony_ci	const struct snd_sof_dsp_ops *ops;
3598c2ecf20Sopenharmony_ci	int ret;
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci	ret = snd_intel_dsp_driver_probe(pci);
3628c2ecf20Sopenharmony_ci	if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
3638c2ecf20Sopenharmony_ci		dev_dbg(&pci->dev, "SOF PCI driver not selected, aborting probe\n");
3648c2ecf20Sopenharmony_ci		return -ENODEV;
3658c2ecf20Sopenharmony_ci	}
3668c2ecf20Sopenharmony_ci	dev_dbg(&pci->dev, "PCI DSP detected");
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_ci	/* get ops for platform */
3698c2ecf20Sopenharmony_ci	ops = desc->ops;
3708c2ecf20Sopenharmony_ci	if (!ops) {
3718c2ecf20Sopenharmony_ci		dev_err(dev, "error: no matching PCI descriptor ops\n");
3728c2ecf20Sopenharmony_ci		return -ENODEV;
3738c2ecf20Sopenharmony_ci	}
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci	sof_pdata = devm_kzalloc(dev, sizeof(*sof_pdata), GFP_KERNEL);
3768c2ecf20Sopenharmony_ci	if (!sof_pdata)
3778c2ecf20Sopenharmony_ci		return -ENOMEM;
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_ci	ret = pcim_enable_device(pci);
3808c2ecf20Sopenharmony_ci	if (ret < 0)
3818c2ecf20Sopenharmony_ci		return ret;
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci	ret = pci_request_regions(pci, "Audio DSP");
3848c2ecf20Sopenharmony_ci	if (ret < 0)
3858c2ecf20Sopenharmony_ci		return ret;
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci	sof_pdata->name = pci_name(pci);
3888c2ecf20Sopenharmony_ci	sof_pdata->desc = (struct sof_dev_desc *)pci_id->driver_data;
3898c2ecf20Sopenharmony_ci	sof_pdata->dev = dev;
3908c2ecf20Sopenharmony_ci	sof_pdata->fw_filename = desc->default_fw_filename;
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	/*
3938c2ecf20Sopenharmony_ci	 * for platforms using the SOF community key, change the
3948c2ecf20Sopenharmony_ci	 * default path automatically to pick the right files from the
3958c2ecf20Sopenharmony_ci	 * linux-firmware tree. This can be overridden with the
3968c2ecf20Sopenharmony_ci	 * fw_path kernel parameter, e.g. for developers.
3978c2ecf20Sopenharmony_ci	 */
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci	/* alternate fw and tplg filenames ? */
4008c2ecf20Sopenharmony_ci	if (fw_path) {
4018c2ecf20Sopenharmony_ci		sof_pdata->fw_filename_prefix = fw_path;
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci		dev_dbg(dev,
4048c2ecf20Sopenharmony_ci			"Module parameter used, changed fw path to %s\n",
4058c2ecf20Sopenharmony_ci			sof_pdata->fw_filename_prefix);
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_ci	} else if (dmi_check_system(community_key_platforms) && sof_dmi_use_community_key) {
4088c2ecf20Sopenharmony_ci		sof_pdata->fw_filename_prefix =
4098c2ecf20Sopenharmony_ci			devm_kasprintf(dev, GFP_KERNEL, "%s/%s",
4108c2ecf20Sopenharmony_ci				       sof_pdata->desc->default_fw_path,
4118c2ecf20Sopenharmony_ci				       "community");
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci		dev_dbg(dev,
4148c2ecf20Sopenharmony_ci			"Platform uses community key, changed fw path to %s\n",
4158c2ecf20Sopenharmony_ci			sof_pdata->fw_filename_prefix);
4168c2ecf20Sopenharmony_ci	} else {
4178c2ecf20Sopenharmony_ci		sof_pdata->fw_filename_prefix =
4188c2ecf20Sopenharmony_ci			sof_pdata->desc->default_fw_path;
4198c2ecf20Sopenharmony_ci	}
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_ci	if (tplg_path)
4228c2ecf20Sopenharmony_ci		sof_pdata->tplg_filename_prefix = tplg_path;
4238c2ecf20Sopenharmony_ci	else
4248c2ecf20Sopenharmony_ci		sof_pdata->tplg_filename_prefix =
4258c2ecf20Sopenharmony_ci			sof_pdata->desc->default_tplg_path;
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	/*
4288c2ecf20Sopenharmony_ci	 * the topology filename will be provided in the machine descriptor, unless
4298c2ecf20Sopenharmony_ci	 * it is overridden by a module parameter or DMI quirk.
4308c2ecf20Sopenharmony_ci	 */
4318c2ecf20Sopenharmony_ci	if (tplg_filename) {
4328c2ecf20Sopenharmony_ci		sof_pdata->tplg_filename = tplg_filename;
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci		dev_dbg(dev, "Module parameter used, changed tplg filename to %s\n",
4358c2ecf20Sopenharmony_ci			sof_pdata->tplg_filename);
4368c2ecf20Sopenharmony_ci	} else {
4378c2ecf20Sopenharmony_ci		dmi_check_system(sof_tplg_table);
4388c2ecf20Sopenharmony_ci		if (sof_dmi_override_tplg_name)
4398c2ecf20Sopenharmony_ci			sof_pdata->tplg_filename = sof_dmi_override_tplg_name;
4408c2ecf20Sopenharmony_ci	}
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
4438c2ecf20Sopenharmony_ci	/* set callback to enable runtime_pm */
4448c2ecf20Sopenharmony_ci	sof_pdata->sof_probe_complete = sof_pci_probe_complete;
4458c2ecf20Sopenharmony_ci#endif
4468c2ecf20Sopenharmony_ci	/* call sof helper for DSP hardware probe */
4478c2ecf20Sopenharmony_ci	ret = snd_sof_device_probe(dev, sof_pdata);
4488c2ecf20Sopenharmony_ci	if (ret) {
4498c2ecf20Sopenharmony_ci		dev_err(dev, "error: failed to probe DSP hardware!\n");
4508c2ecf20Sopenharmony_ci		goto release_regions;
4518c2ecf20Sopenharmony_ci	}
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_ci#if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
4548c2ecf20Sopenharmony_ci	sof_pci_probe_complete(dev);
4558c2ecf20Sopenharmony_ci#endif
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_ci	return ret;
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_cirelease_regions:
4608c2ecf20Sopenharmony_ci	pci_release_regions(pci);
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	return ret;
4638c2ecf20Sopenharmony_ci}
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_cistatic void sof_pci_remove(struct pci_dev *pci)
4668c2ecf20Sopenharmony_ci{
4678c2ecf20Sopenharmony_ci	/* call sof helper for DSP hardware remove */
4688c2ecf20Sopenharmony_ci	snd_sof_device_remove(&pci->dev);
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	/* follow recommendation in pci-driver.c to increment usage counter */
4718c2ecf20Sopenharmony_ci	if (!(sof_pci_debug & SOF_PCI_DISABLE_PM_RUNTIME))
4728c2ecf20Sopenharmony_ci		pm_runtime_get_noresume(&pci->dev);
4738c2ecf20Sopenharmony_ci
4748c2ecf20Sopenharmony_ci	/* release pci regions and disable device */
4758c2ecf20Sopenharmony_ci	pci_release_regions(pci);
4768c2ecf20Sopenharmony_ci}
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci/* PCI IDs */
4798c2ecf20Sopenharmony_cistatic const struct pci_device_id sof_pci_ids[] = {
4808c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
4818c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x119a),
4828c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&tng_desc},
4838c2ecf20Sopenharmony_ci#endif
4848c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
4858c2ecf20Sopenharmony_ci	/* BXT-P & Apollolake */
4868c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x5a98),
4878c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&bxt_desc},
4888c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x1a98),
4898c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&bxt_desc},
4908c2ecf20Sopenharmony_ci#endif
4918c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)
4928c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x3198),
4938c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&glk_desc},
4948c2ecf20Sopenharmony_ci#endif
4958c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)
4968c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x9dc8),
4978c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&cnl_desc},
4988c2ecf20Sopenharmony_ci#endif
4998c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)
5008c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0xa348),
5018c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&cfl_desc},
5028c2ecf20Sopenharmony_ci#endif
5038c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
5048c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x34C8), /* ICL-LP */
5058c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&icl_desc},
5068c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x3dc8), /* ICL-H */
5078c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&icl_desc},
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ci#endif
5108c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
5118c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x38c8),
5128c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&jsl_desc},
5138c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x4dc8),
5148c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&jsl_desc},
5158c2ecf20Sopenharmony_ci#endif
5168c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE)
5178c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x02c8), /* CML-LP */
5188c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&cml_desc},
5198c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x06c8), /* CML-H */
5208c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&cml_desc},
5218c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0xa3f0), /* CML-S */
5228c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&cml_desc},
5238c2ecf20Sopenharmony_ci#endif
5248c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
5258c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0xa0c8), /* TGL-LP */
5268c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&tgl_desc},
5278c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x43c8), /* TGL-H */
5288c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&tglh_desc},
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci#endif
5318c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
5328c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x4b55),
5338c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&ehl_desc},
5348c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x8086, 0x4b58),
5358c2ecf20Sopenharmony_ci		.driver_data = (unsigned long)&ehl_desc},
5368c2ecf20Sopenharmony_ci#endif
5378c2ecf20Sopenharmony_ci	{ 0, }
5388c2ecf20Sopenharmony_ci};
5398c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(pci, sof_pci_ids);
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci/* pci_driver definition */
5428c2ecf20Sopenharmony_cistatic struct pci_driver snd_sof_pci_driver = {
5438c2ecf20Sopenharmony_ci	.name = "sof-audio-pci",
5448c2ecf20Sopenharmony_ci	.id_table = sof_pci_ids,
5458c2ecf20Sopenharmony_ci	.probe = sof_pci_probe,
5468c2ecf20Sopenharmony_ci	.remove = sof_pci_remove,
5478c2ecf20Sopenharmony_ci	.driver = {
5488c2ecf20Sopenharmony_ci		.pm = &sof_pci_pm,
5498c2ecf20Sopenharmony_ci	},
5508c2ecf20Sopenharmony_ci};
5518c2ecf20Sopenharmony_cimodule_pci_driver(snd_sof_pci_driver);
5528c2ecf20Sopenharmony_ci
5538c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL");
5548c2ecf20Sopenharmony_ciMODULE_IMPORT_NS(SND_SOC_SOF_MERRIFIELD);
5558c2ecf20Sopenharmony_ciMODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON);
556