summaryrefslogtreecommitdiffstats
path: root/sound/soc/amd
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:27:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:27:49 +0000
commitace9429bb58fd418f0c81d4c2835699bddf6bde6 (patch)
treeb2d64bc10158fdd5497876388cd68142ca374ed3 /sound/soc/amd
parentInitial commit. (diff)
downloadlinux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.tar.xz
linux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.zip
Adding upstream version 6.6.15.upstream/6.6.15
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sound/soc/amd')
-rw-r--r--sound/soc/amd/Kconfig156
-rw-r--r--sound/soc/amd/Makefile21
-rw-r--r--sound/soc/amd/acp-config.c196
-rw-r--r--sound/soc/amd/acp-da7219-max98357a.c811
-rw-r--r--sound/soc/amd/acp-es8336.c320
-rw-r--r--sound/soc/amd/acp-pcm-dma.c1442
-rw-r--r--sound/soc/amd/acp-rt5645.c218
-rw-r--r--sound/soc/amd/acp.h223
-rw-r--r--sound/soc/amd/acp/Kconfig89
-rw-r--r--sound/soc/amd/acp/Makefile34
-rw-r--r--sound/soc/amd/acp/acp-i2s.c575
-rw-r--r--sound/soc/amd/acp/acp-legacy-common.c347
-rw-r--r--sound/soc/amd/acp/acp-legacy-mach.c158
-rw-r--r--sound/soc/amd/acp/acp-mach-common.c1688
-rw-r--r--sound/soc/amd/acp/acp-mach.h72
-rw-r--r--sound/soc/amd/acp/acp-pci.c235
-rw-r--r--sound/soc/amd/acp/acp-pdm.c182
-rw-r--r--sound/soc/amd/acp/acp-platform.c323
-rw-r--r--sound/soc/amd/acp/acp-rembrandt.c300
-rw-r--r--sound/soc/amd/acp/acp-renoir.c217
-rw-r--r--sound/soc/amd/acp/acp-sof-mach.c187
-rw-r--r--sound/soc/amd/acp/amd.h303
-rw-r--r--sound/soc/amd/acp/chip_offset_byte.h132
-rw-r--r--sound/soc/amd/acp3x-rt5682-max9836.c558
-rw-r--r--sound/soc/amd/include/acp_2_2_d.h609
-rw-r--r--sound/soc/amd/include/acp_2_2_enum.h1068
-rw-r--r--sound/soc/amd/include/acp_2_2_sh_mask.h2292
-rw-r--r--sound/soc/amd/mach-config.h31
-rw-r--r--sound/soc/amd/ps/Makefile11
-rw-r--r--sound/soc/amd/ps/acp63.h290
-rw-r--r--sound/soc/amd/ps/pci-ps.c742
-rw-r--r--sound/soc/amd/ps/ps-mach.c79
-rw-r--r--sound/soc/amd/ps/ps-pdm-dma.c463
-rw-r--r--sound/soc/amd/ps/ps-sdw-dma.c566
-rw-r--r--sound/soc/amd/raven/Makefile8
-rw-r--r--sound/soc/amd/raven/acp3x-i2s.c330
-rw-r--r--sound/soc/amd/raven/acp3x-pcm-dma.c526
-rw-r--r--sound/soc/amd/raven/acp3x.h162
-rw-r--r--sound/soc/amd/raven/chip_offset_byte.h639
-rw-r--r--sound/soc/amd/raven/pci-acp3x.c347
-rw-r--r--sound/soc/amd/renoir/Makefile8
-rw-r--r--sound/soc/amd/renoir/acp3x-pdm-dma.c504
-rw-r--r--sound/soc/amd/renoir/acp3x-rn.c76
-rw-r--r--sound/soc/amd/renoir/rn-pci-acp3x.c434
-rw-r--r--sound/soc/amd/renoir/rn_acp3x.h93
-rw-r--r--sound/soc/amd/renoir/rn_chip_offset_byte.h349
-rw-r--r--sound/soc/amd/rpl/Makefile5
-rw-r--r--sound/soc/amd/rpl/rpl-pci-acp6x.c227
-rw-r--r--sound/soc/amd/rpl/rpl_acp6x.h36
-rw-r--r--sound/soc/amd/rpl/rpl_acp6x_chip_offset_byte.h30
-rw-r--r--sound/soc/amd/vangogh/Makefile11
-rw-r--r--sound/soc/amd/vangogh/acp5x-i2s.c416
-rw-r--r--sound/soc/amd/vangogh/acp5x-mach.c496
-rw-r--r--sound/soc/amd/vangogh/acp5x-pcm-dma.c514
-rw-r--r--sound/soc/amd/vangogh/acp5x.h224
-rw-r--r--sound/soc/amd/vangogh/pci-acp5x.c338
-rw-r--r--sound/soc/amd/vangogh/vg_chip_offset_byte.h337
-rw-r--r--sound/soc/amd/yc/Makefile9
-rw-r--r--sound/soc/amd/yc/acp6x-mach.c459
-rw-r--r--sound/soc/amd/yc/acp6x-pdm-dma.c455
-rw-r--r--sound/soc/amd/yc/acp6x.h110
-rw-r--r--sound/soc/amd/yc/acp6x_chip_offset_byte.h444
-rw-r--r--sound/soc/amd/yc/pci-acp6x.c350
63 files changed, 22875 insertions, 0 deletions
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
new file mode 100644
index 0000000000..273688c053
--- /dev/null
+++ b/sound/soc/amd/Kconfig
@@ -0,0 +1,156 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config SND_SOC_AMD_ACP
+ tristate "AMD Audio Coprocessor support"
+ help
+ This option enables ACP DMA support on AMD platform.
+
+config SND_SOC_AMD_CZ_DA7219MX98357_MACH
+ tristate "AMD CZ support for DA7219, RT5682 and MAX9835"
+ select CLK_FIXED_FCH
+ select SND_SOC_DA7219
+ select SND_SOC_RT5682_I2C
+ select SND_SOC_MAX98357A
+ select SND_SOC_ADAU7002
+ select REGULATOR
+ depends on SND_SOC_AMD_ACP && I2C && GPIOLIB && ACPI
+ help
+ This option enables machine driver for DA7219, RT5682 and MAX9835.
+
+config SND_SOC_AMD_CZ_RT5645_MACH
+ tristate "AMD CZ support for RT5645"
+ select SND_SOC_RT5645
+ depends on SND_SOC_AMD_ACP && I2C
+ help
+ This option enables machine driver for rt5645.
+
+config SND_SOC_AMD_ST_ES8336_MACH
+ tristate "AMD ST support for ES8336"
+ select SND_SOC_ACPI if ACPI
+ select SND_SOC_ES8316
+ depends on SND_SOC_AMD_ACP && ACPI
+ depends on I2C
+ help
+ This option enables machine driver for Jadeite platform
+ using es8336 codec.
+ Say m if you have such a device.
+ If unsure select "N".
+
+config SND_SOC_AMD_ACP3x
+ tristate "AMD Audio Coprocessor-v3.x support"
+ depends on X86 && PCI
+ help
+ This option enables ACP v3.x I2S support on AMD platform
+
+config SND_SOC_AMD_RV_RT5682_MACH
+ tristate "AMD RV support for RT5682"
+ select CLK_FIXED_FCH
+ select SND_SOC_RT5682_I2C
+ select SND_SOC_MAX98357A
+ select SND_SOC_CROS_EC_CODEC
+ select I2C_CROS_EC_TUNNEL
+ select SND_SOC_RT1015
+ select SND_SOC_RT1015P
+ depends on SND_SOC_AMD_ACP3x && I2C && CROS_EC && GPIOLIB
+ help
+ This option enables machine driver for RT5682 and MAX9835.
+
+config SND_SOC_AMD_RENOIR
+ tristate "AMD Audio Coprocessor - Renoir support"
+ select SND_AMD_ACP_CONFIG
+ depends on X86 && PCI
+ help
+ This option enables ACP support for Renoir platform
+
+config SND_SOC_AMD_RENOIR_MACH
+ tristate "AMD Renoir support for DMIC"
+ select SND_SOC_DMIC
+ depends on SND_SOC_AMD_RENOIR && GPIOLIB
+ help
+ This option enables machine driver for DMIC
+
+config SND_SOC_AMD_ACP5x
+ tristate "AMD Audio Coprocessor-v5.x I2S support"
+ depends on X86 && PCI
+ select SND_AMD_ACP_CONFIG
+ help
+ This option enables ACP v5.x support on AMD platform
+
+ By enabling this flag build will trigger for ACP PCI driver,
+ ACP DMA driver, CPU DAI driver.
+
+config SND_SOC_AMD_VANGOGH_MACH
+ tristate "AMD Vangogh support for NAU8821/CS35L41/MAX98388"
+ select SND_SOC_NAU8821
+ select SND_SOC_CS35L41_SPI
+ select SND_SOC_MAX98388
+ select SND_AMD_ACP_CONFIG
+ depends on SND_SOC_AMD_ACP5x && I2C && SPI_MASTER
+ help
+ This option enables machine driver for Vangogh platform
+ using NAU8821 and either CS35L41 or MAX98388 codecs.
+ Say m if you have such a device.
+ If unsure select "N".
+
+config SND_SOC_AMD_ACP6x
+ tristate "AMD Audio Coprocessor-v6.x Yellow Carp support"
+ select SND_AMD_ACP_CONFIG
+ depends on X86 && PCI
+ help
+ This option enables Audio Coprocessor i.e ACP v6.x support on
+ AMD Yellow Carp platform. By enabling this flag build will be
+ triggered for ACP PCI driver, ACP PDM DMA driver.
+ Say m if you have such a device.
+ If unsure select "N".
+
+config SND_SOC_AMD_YC_MACH
+ tristate "AMD YC support for DMIC"
+ select SND_SOC_DMIC
+ depends on SND_SOC_AMD_ACP6x
+ help
+ This option enables machine driver for Yellow Carp platform
+ using dmic. ACP IP has PDM Decoder block with DMA controller.
+ DMIC can be connected directly to ACP IP.
+ Say m if you have such a device.
+ If unsure select "N".
+
+config SND_AMD_ACP_CONFIG
+ tristate "AMD ACP configuration selection"
+ select SND_SOC_ACPI if ACPI
+ help
+ This option adds an auto detection to determine which ACP
+ driver modules to use
+
+source "sound/soc/amd/acp/Kconfig"
+
+config SND_SOC_AMD_RPL_ACP6x
+ tristate "AMD Audio Coprocessor-v6.2 RPL support"
+ depends on X86 && PCI
+ help
+ This option enables Audio Coprocessor i.e. ACP v6.2 support on
+ AMD RPL platform. By enabling this flag build will be
+ triggered for ACP PCI driver.
+ Say m if you have such a device.
+ If unsure select "N".
+
+config SND_SOC_AMD_PS
+ tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support"
+ select SND_AMD_ACP_CONFIG
+ depends on X86 && PCI && ACPI
+ help
+ This option enables Audio Coprocessor i.e ACP v6.3 support on
+ AMD Pink sardine platform. By enabling this flag build will be
+ triggered for ACP PCI driver, ACP PDM DMA driver, ACP SoundWire
+ DMA driver.
+ Say m if you have such a device.
+ If unsure select "N".
+
+config SND_SOC_AMD_PS_MACH
+ tristate "AMD PINK SARDINE support for DMIC"
+ select SND_SOC_DMIC
+ depends on SND_SOC_AMD_PS
+ help
+ This option enables machine driver for Pink Sardine platform
+ using dmic. ACP IP has PDM Decoder block with DMA controller.
+ DMIC can be connected directly to ACP IP.
+ Say m if you have such a device.
+ If unsure select "N".
diff --git a/sound/soc/amd/Makefile b/sound/soc/amd/Makefile
new file mode 100644
index 0000000000..82e1cf864a
--- /dev/null
+++ b/sound/soc/amd/Makefile
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-only
+acp_audio_dma-objs := acp-pcm-dma.o
+snd-soc-acp-da7219mx98357-mach-objs := acp-da7219-max98357a.o
+snd-soc-acp-rt5645-mach-objs := acp-rt5645.o
+snd-soc-acp-es8336-mach-objs := acp-es8336.o
+snd-soc-acp-rt5682-mach-objs := acp3x-rt5682-max9836.o
+snd-acp-config-objs := acp-config.o
+
+obj-$(CONFIG_SND_SOC_AMD_ACP) += acp_audio_dma.o
+obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mach.o
+obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o
+obj-$(CONFIG_SND_SOC_AMD_ST_ES8336_MACH) += snd-soc-acp-es8336-mach.o
+obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/
+obj-$(CONFIG_SND_SOC_AMD_RV_RT5682_MACH) += snd-soc-acp-rt5682-mach.o
+obj-$(CONFIG_SND_SOC_AMD_RENOIR) += renoir/
+obj-$(CONFIG_SND_SOC_AMD_ACP5x) += vangogh/
+obj-$(CONFIG_SND_SOC_AMD_ACP6x) += yc/
+obj-$(CONFIG_SND_SOC_AMD_ACP_COMMON) += acp/
+obj-$(CONFIG_SND_AMD_ACP_CONFIG) += snd-acp-config.o
+obj-$(CONFIG_SND_SOC_AMD_RPL_ACP6x) += rpl/
+obj-$(CONFIG_SND_SOC_AMD_PS) += ps/
diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c
new file mode 100644
index 0000000000..f27c275800
--- /dev/null
+++ b/sound/soc/amd/acp-config.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2021 Advanced Micro Devices, Inc.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+//
+
+/* ACP machine configuration module */
+
+#include <linux/acpi.h>
+#include <linux/bits.h>
+#include <linux/dmi.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "../sof/amd/acp.h"
+#include "mach-config.h"
+
+static int acp_quirk_data;
+
+static const struct config_entry config_table[] = {
+ {
+ .flags = FLAG_AMD_SOF,
+ .device = ACP_PCI_DEV_ID,
+ .dmi_table = (const struct dmi_system_id []) {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "AMD"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Majolica-CZN"),
+ },
+ },
+ {}
+ },
+ },
+ {
+ .flags = FLAG_AMD_SOF,
+ .device = ACP_PCI_DEV_ID,
+ .dmi_table = (const struct dmi_system_id []) {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Google"),
+ },
+ },
+ {}
+ },
+ },
+ {
+ .flags = FLAG_AMD_SOF,
+ .device = ACP_PCI_DEV_ID,
+ .dmi_table = (const struct dmi_system_id []) {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Valve"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Galileo"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Sephiroth"),
+ },
+ },
+ {}
+ },
+ },
+};
+
+int snd_amd_acp_find_config(struct pci_dev *pci)
+{
+ const struct config_entry *table = config_table;
+ u16 device = pci->device;
+ int i;
+
+ /* Do not enable FLAGS on older platforms with Rev id zero */
+ if (!pci->revision)
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(config_table); i++, table++) {
+ if (table->device != device)
+ continue;
+ if (table->dmi_table && !dmi_check_system(table->dmi_table))
+ continue;
+ acp_quirk_data = table->flags;
+ return table->flags;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(snd_amd_acp_find_config);
+
+static struct snd_soc_acpi_codecs amp_rt1019 = {
+ .num_codecs = 1,
+ .codecs = {"10EC1019"}
+};
+
+static struct snd_soc_acpi_codecs amp_max = {
+ .num_codecs = 1,
+ .codecs = {"MX98360A"}
+};
+
+static struct snd_soc_acpi_codecs amp_max98388 = {
+ .num_codecs = 1,
+ .codecs = {"ADS8388"}
+};
+
+struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[] = {
+ {
+ .id = "10EC5682",
+ .drv_name = "rt5682-rt1019",
+ .pdata = (void *)&acp_quirk_data,
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_rt1019,
+ .fw_filename = "sof-rn.ri",
+ .sof_tplg_filename = "sof-rn-rt5682-rt1019.tplg",
+ },
+ {
+ .id = "10EC5682",
+ .drv_name = "rt5682-max",
+ .pdata = (void *)&acp_quirk_data,
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_max,
+ .fw_filename = "sof-rn.ri",
+ .sof_tplg_filename = "sof-rn-rt5682-max98360.tplg",
+ },
+ {
+ .id = "RTL5682",
+ .drv_name = "rt5682s-max",
+ .pdata = (void *)&acp_quirk_data,
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_max,
+ .fw_filename = "sof-rn.ri",
+ .sof_tplg_filename = "sof-rn-rt5682-max98360.tplg",
+ },
+ {
+ .id = "RTL5682",
+ .drv_name = "rt5682s-rt1019",
+ .pdata = (void *)&acp_quirk_data,
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_rt1019,
+ .fw_filename = "sof-rn.ri",
+ .sof_tplg_filename = "sof-rn-rt5682-rt1019.tplg",
+ },
+ {
+ .id = "AMDI1019",
+ .drv_name = "renoir-dsp",
+ .pdata = (void *)&acp_quirk_data,
+ .fw_filename = "sof-rn.ri",
+ .sof_tplg_filename = "sof-acp.tplg",
+ },
+ {},
+};
+EXPORT_SYMBOL(snd_soc_acpi_amd_sof_machines);
+
+struct snd_soc_acpi_mach snd_soc_acpi_amd_vangogh_sof_machines[] = {
+ {
+ .id = "NVTN2020",
+ .drv_name = "nau8821-max",
+ .pdata = &acp_quirk_data,
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_max98388,
+ .fw_filename = "sof-vangogh.ri",
+ .sof_tplg_filename = "sof-vangogh-nau8821-max.tplg",
+ },
+ {},
+};
+EXPORT_SYMBOL(snd_soc_acpi_amd_vangogh_sof_machines);
+
+struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[] = {
+ {
+ .id = "AMDI1019",
+ .drv_name = "rmb-dsp",
+ .pdata = &acp_quirk_data,
+ .fw_filename = "sof-rmb.ri",
+ .sof_tplg_filename = "sof-acp-rmb.tplg",
+ },
+ {
+ .id = "10508825",
+ .drv_name = "nau8825-max",
+ .pdata = &acp_quirk_data,
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_max,
+ .fw_filename = "sof-rmb.ri",
+ .sof_tplg_filename = "sof-rmb-nau8825-max98360.tplg",
+ },
+ {
+ .id = "RTL5682",
+ .drv_name = "rt5682s-hs-rt1019",
+ .pdata = &acp_quirk_data,
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_rt1019,
+ .fw_filename = "sof-rmb.ri",
+ .sof_tplg_filename = "sof-rmb-rt5682s-rt1019.tplg",
+ },
+ {},
+};
+EXPORT_SYMBOL(snd_soc_acpi_amd_rmb_sof_machines);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c
new file mode 100644
index 0000000000..9e3133bec2
--- /dev/null
+++ b/sound/soc/amd/acp-da7219-max98357a.c
@@ -0,0 +1,811 @@
+// SPDX-License-Identifier: MIT
+//
+// Machine driver for AMD ACP Audio engine using DA7219, RT5682 & MAX98357 codec
+//
+//Copyright 2017-2021 Advanced Micro Devices, Inc.
+
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/acpi.h>
+
+#include "acp.h"
+#include "../codecs/da7219.h"
+#include "../codecs/rt5682.h"
+
+#define CZ_PLAT_CLK 48000000
+#define DUAL_CHANNEL 2
+#define RT5682_PLL_FREQ (48000 * 512)
+
+static struct snd_soc_jack cz_jack;
+static struct snd_soc_jack_pin cz_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+ {
+ .pin = "Line Out",
+ .mask = SND_JACK_LINEOUT,
+ },
+};
+
+static struct clk *da7219_dai_wclk;
+static struct clk *da7219_dai_bclk;
+static struct clk *rt5682_dai_wclk;
+static struct clk *rt5682_dai_bclk;
+
+void *acp_soc_is_rltk_max(struct device *dev);
+
+static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret;
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_component *component = codec_dai->component;
+
+ dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK,
+ CZ_PLAT_CLK, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL,
+ CZ_PLAT_CLK, DA7219_PLL_FREQ_OUT_98304);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
+ return ret;
+ }
+
+ da7219_dai_wclk = devm_clk_get(component->dev, "da7219-dai-wclk");
+ if (IS_ERR(da7219_dai_wclk))
+ return PTR_ERR(da7219_dai_wclk);
+
+ da7219_dai_bclk = devm_clk_get(component->dev, "da7219-dai-bclk");
+ if (IS_ERR(da7219_dai_bclk))
+ return PTR_ERR(da7219_dai_bclk);
+
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
+ SND_JACK_HEADSET | SND_JACK_LINEOUT |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &cz_jack,
+ cz_jack_pins,
+ ARRAY_SIZE(cz_jack_pins));
+ if (ret) {
+ dev_err(card->dev, "HP jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
+ snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
+ snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
+
+ snd_soc_component_set_jack(component, &cz_jack, NULL);
+
+ return 0;
+}
+
+static int da7219_clk_enable(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+ /*
+ * Set wclk to 48000 because the rate constraint of this driver is
+ * 48000. ADAU7002 spec: "The ADAU7002 requires a BCLK rate that is
+ * minimum of 64x the LRCLK sample rate." DA7219 is the only clk
+ * source so for all codecs we have to limit bclk to 64X lrclk.
+ */
+ clk_set_rate(da7219_dai_wclk, 48000);
+ clk_set_rate(da7219_dai_bclk, 48000 * 64);
+ ret = clk_prepare_enable(da7219_dai_bclk);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't enable master clock %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static void da7219_clk_disable(void)
+{
+ clk_disable_unprepare(da7219_dai_bclk);
+}
+
+static int cz_rt5682_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret;
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_component *component = codec_dai->component;
+
+ dev_info(codec_dai->dev, "codec dai name = %s\n", codec_dai->name);
+
+ /* Set codec sysclk */
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
+ RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(codec_dai->dev,
+ "Failed to set rt5682 SYSCLK: %d\n", ret);
+ return ret;
+ }
+ /* set codec PLL */
+ ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
+ CZ_PLAT_CLK, RT5682_PLL_FREQ);
+ if (ret < 0) {
+ dev_err(codec_dai->dev, "can't set rt5682 PLL: %d\n", ret);
+ return ret;
+ }
+
+ rt5682_dai_wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
+ if (IS_ERR(rt5682_dai_wclk))
+ return PTR_ERR(rt5682_dai_wclk);
+
+ rt5682_dai_bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
+ if (IS_ERR(rt5682_dai_bclk))
+ return PTR_ERR(rt5682_dai_bclk);
+
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
+ SND_JACK_HEADSET | SND_JACK_LINEOUT |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &cz_jack,
+ cz_jack_pins,
+ ARRAY_SIZE(cz_jack_pins));
+ if (ret) {
+ dev_err(card->dev, "HP jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
+ snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
+ snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
+
+ ret = snd_soc_component_set_jack(component, &cz_jack, NULL);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int rt5682_clk_enable(struct snd_pcm_substream *substream)
+{
+ int ret;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+ /*
+ * Set wclk to 48000 because the rate constraint of this driver is
+ * 48000. ADAU7002 spec: "The ADAU7002 requires a BCLK rate that is
+ * minimum of 64x the LRCLK sample rate." RT5682 is the only clk
+ * source so for all codecs we have to limit bclk to 64X lrclk.
+ */
+ ret = clk_set_rate(rt5682_dai_wclk, 48000);
+ if (ret) {
+ dev_err(rtd->dev, "Error setting wclk rate: %d\n", ret);
+ return ret;
+ }
+ ret = clk_set_rate(rt5682_dai_bclk, 48000 * 64);
+ if (ret) {
+ dev_err(rtd->dev, "Error setting bclk rate: %d\n", ret);
+ return ret;
+ }
+ ret = clk_prepare_enable(rt5682_dai_wclk);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't enable wclk %d\n", ret);
+ return ret;
+ }
+ return ret;
+}
+
+static void rt5682_clk_disable(void)
+{
+ clk_disable_unprepare(rt5682_dai_wclk);
+}
+
+static const unsigned int channels[] = {
+ DUAL_CHANNEL,
+};
+
+static const unsigned int rates[] = {
+ 48000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
+ .count = ARRAY_SIZE(channels),
+ .list = channels,
+ .mask = 0,
+};
+
+static int cz_da7219_play_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->play_i2s_instance = I2S_SP_INSTANCE;
+ return da7219_clk_enable(substream);
+}
+
+static int cz_da7219_cap_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->cap_i2s_instance = I2S_SP_INSTANCE;
+ machine->capture_channel = CAP_CHANNEL1;
+ return da7219_clk_enable(substream);
+}
+
+static int cz_max_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->play_i2s_instance = I2S_BT_INSTANCE;
+ return da7219_clk_enable(substream);
+}
+
+static int cz_dmic0_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->cap_i2s_instance = I2S_BT_INSTANCE;
+ return da7219_clk_enable(substream);
+}
+
+static int cz_dmic1_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->cap_i2s_instance = I2S_SP_INSTANCE;
+ machine->capture_channel = CAP_CHANNEL0;
+ return da7219_clk_enable(substream);
+}
+
+static void cz_da7219_shutdown(struct snd_pcm_substream *substream)
+{
+ da7219_clk_disable();
+}
+
+static int cz_rt5682_play_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->play_i2s_instance = I2S_SP_INSTANCE;
+ return rt5682_clk_enable(substream);
+}
+
+static int cz_rt5682_cap_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->cap_i2s_instance = I2S_SP_INSTANCE;
+ machine->capture_channel = CAP_CHANNEL1;
+ return rt5682_clk_enable(substream);
+}
+
+static int cz_rt5682_max_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->play_i2s_instance = I2S_BT_INSTANCE;
+ return rt5682_clk_enable(substream);
+}
+
+static int cz_rt5682_dmic0_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->cap_i2s_instance = I2S_BT_INSTANCE;
+ return rt5682_clk_enable(substream);
+}
+
+static int cz_rt5682_dmic1_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ /*
+ * On this platform for PCM device we support stereo
+ */
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ machine->cap_i2s_instance = I2S_SP_INSTANCE;
+ machine->capture_channel = CAP_CHANNEL0;
+ return rt5682_clk_enable(substream);
+}
+
+static void cz_rt5682_shutdown(struct snd_pcm_substream *substream)
+{
+ rt5682_clk_disable();
+}
+
+static const struct snd_soc_ops cz_da7219_play_ops = {
+ .startup = cz_da7219_play_startup,
+ .shutdown = cz_da7219_shutdown,
+};
+
+static const struct snd_soc_ops cz_da7219_cap_ops = {
+ .startup = cz_da7219_cap_startup,
+ .shutdown = cz_da7219_shutdown,
+};
+
+static const struct snd_soc_ops cz_max_play_ops = {
+ .startup = cz_max_startup,
+ .shutdown = cz_da7219_shutdown,
+};
+
+static const struct snd_soc_ops cz_dmic0_cap_ops = {
+ .startup = cz_dmic0_startup,
+ .shutdown = cz_da7219_shutdown,
+};
+
+static const struct snd_soc_ops cz_dmic1_cap_ops = {
+ .startup = cz_dmic1_startup,
+ .shutdown = cz_da7219_shutdown,
+};
+
+static const struct snd_soc_ops cz_rt5682_play_ops = {
+ .startup = cz_rt5682_play_startup,
+ .shutdown = cz_rt5682_shutdown,
+};
+
+static const struct snd_soc_ops cz_rt5682_cap_ops = {
+ .startup = cz_rt5682_cap_startup,
+ .shutdown = cz_rt5682_shutdown,
+};
+
+static const struct snd_soc_ops cz_rt5682_max_play_ops = {
+ .startup = cz_rt5682_max_startup,
+ .shutdown = cz_rt5682_shutdown,
+};
+
+static const struct snd_soc_ops cz_rt5682_dmic0_cap_ops = {
+ .startup = cz_rt5682_dmic0_startup,
+ .shutdown = cz_rt5682_shutdown,
+};
+
+static const struct snd_soc_ops cz_rt5682_dmic1_cap_ops = {
+ .startup = cz_rt5682_dmic1_startup,
+ .shutdown = cz_rt5682_shutdown,
+};
+
+SND_SOC_DAILINK_DEF(designware1,
+ DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.1.auto")));
+SND_SOC_DAILINK_DEF(designware2,
+ DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto")));
+SND_SOC_DAILINK_DEF(designware3,
+ DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.3.auto")));
+
+SND_SOC_DAILINK_DEF(dlgs,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", "da7219-hifi")));
+SND_SOC_DAILINK_DEF(rt5682,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
+SND_SOC_DAILINK_DEF(mx,
+ DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", "HiFi")));
+SND_SOC_DAILINK_DEF(adau,
+ DAILINK_COMP_ARRAY(COMP_CODEC("ADAU7002:00", "adau7002-hifi")));
+
+SND_SOC_DAILINK_DEF(platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.0.auto")));
+
+static struct snd_soc_dai_link cz_dai_7219_98357[] = {
+ {
+ .name = "amd-da7219-play",
+ .stream_name = "Playback",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .init = cz_da7219_init,
+ .dpcm_playback = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_da7219_play_ops,
+ SND_SOC_DAILINK_REG(designware1, dlgs, platform),
+ },
+ {
+ .name = "amd-da7219-cap",
+ .stream_name = "Capture",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_capture = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_da7219_cap_ops,
+ SND_SOC_DAILINK_REG(designware2, dlgs, platform),
+ },
+ {
+ .name = "amd-max98357-play",
+ .stream_name = "HiFi Playback",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_playback = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_max_play_ops,
+ SND_SOC_DAILINK_REG(designware3, mx, platform),
+ },
+ {
+ /* C panel DMIC */
+ .name = "dmic0",
+ .stream_name = "DMIC0 Capture",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_capture = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_dmic0_cap_ops,
+ SND_SOC_DAILINK_REG(designware3, adau, platform),
+ },
+ {
+ /* A/B panel DMIC */
+ .name = "dmic1",
+ .stream_name = "DMIC1 Capture",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_capture = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_dmic1_cap_ops,
+ SND_SOC_DAILINK_REG(designware2, adau, platform),
+ },
+};
+
+static struct snd_soc_dai_link cz_dai_5682_98357[] = {
+ {
+ .name = "amd-rt5682-play",
+ .stream_name = "Playback",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .init = cz_rt5682_init,
+ .dpcm_playback = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_rt5682_play_ops,
+ SND_SOC_DAILINK_REG(designware1, rt5682, platform),
+ },
+ {
+ .name = "amd-rt5682-cap",
+ .stream_name = "Capture",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_capture = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_rt5682_cap_ops,
+ SND_SOC_DAILINK_REG(designware2, rt5682, platform),
+ },
+ {
+ .name = "amd-max98357-play",
+ .stream_name = "HiFi Playback",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_playback = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_rt5682_max_play_ops,
+ SND_SOC_DAILINK_REG(designware3, mx, platform),
+ },
+ {
+ /* C panel DMIC */
+ .name = "dmic0",
+ .stream_name = "DMIC0 Capture",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_capture = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_rt5682_dmic0_cap_ops,
+ SND_SOC_DAILINK_REG(designware3, adau, platform),
+ },
+ {
+ /* A/B panel DMIC */
+ .name = "dmic1",
+ .stream_name = "DMIC1 Capture",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_capture = 1,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .ops = &cz_rt5682_dmic1_cap_ops,
+ SND_SOC_DAILINK_REG(designware2, adau, platform),
+ },
+};
+
+static const struct snd_soc_dapm_widget cz_widgets[] = {
+ SND_SOC_DAPM_HP("Headphones", NULL),
+ SND_SOC_DAPM_SPK("Speakers", NULL),
+ SND_SOC_DAPM_LINE("Line Out", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Int Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route cz_audio_route[] = {
+ {"Headphones", NULL, "HPL"},
+ {"Headphones", NULL, "HPR"},
+ {"MIC", NULL, "Headset Mic"},
+ {"Speakers", NULL, "Speaker"},
+ {"PDM_DAT", NULL, "Int Mic"},
+};
+
+static const struct snd_soc_dapm_route cz_rt5682_audio_route[] = {
+ {"Headphones", NULL, "HPOL"},
+ {"Headphones", NULL, "HPOR"},
+ {"IN1P", NULL, "Headset Mic"},
+ {"Speakers", NULL, "Speaker"},
+ {"PDM_DAT", NULL, "Int Mic"},
+};
+
+static const struct snd_kcontrol_new cz_mc_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphones"),
+ SOC_DAPM_PIN_SWITCH("Speakers"),
+ SOC_DAPM_PIN_SWITCH("Line Out"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Int Mic"),
+};
+
+static struct snd_soc_card cz_card = {
+ .name = "acpd7219m98357",
+ .owner = THIS_MODULE,
+ .dai_link = cz_dai_7219_98357,
+ .num_links = ARRAY_SIZE(cz_dai_7219_98357),
+ .dapm_widgets = cz_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cz_widgets),
+ .dapm_routes = cz_audio_route,
+ .num_dapm_routes = ARRAY_SIZE(cz_audio_route),
+ .controls = cz_mc_controls,
+ .num_controls = ARRAY_SIZE(cz_mc_controls),
+};
+
+static struct snd_soc_card cz_rt5682_card = {
+ .name = "acpr5682m98357",
+ .owner = THIS_MODULE,
+ .dai_link = cz_dai_5682_98357,
+ .num_links = ARRAY_SIZE(cz_dai_5682_98357),
+ .dapm_widgets = cz_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cz_widgets),
+ .dapm_routes = cz_rt5682_audio_route,
+ .controls = cz_mc_controls,
+ .num_controls = ARRAY_SIZE(cz_mc_controls),
+};
+
+void *acp_soc_is_rltk_max(struct device *dev)
+{
+ const struct acpi_device_id *match;
+
+ match = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!match)
+ return NULL;
+ return (void *)match->driver_data;
+}
+
+static struct regulator_consumer_supply acp_da7219_supplies[] = {
+ REGULATOR_SUPPLY("VDD", "i2c-DLGS7219:00"),
+ REGULATOR_SUPPLY("VDDMIC", "i2c-DLGS7219:00"),
+ REGULATOR_SUPPLY("VDDIO", "i2c-DLGS7219:00"),
+ REGULATOR_SUPPLY("IOVDD", "ADAU7002:00"),
+};
+
+static struct regulator_init_data acp_da7219_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(acp_da7219_supplies),
+ .consumer_supplies = acp_da7219_supplies,
+};
+
+static struct regulator_config acp_da7219_cfg = {
+ .init_data = &acp_da7219_data,
+};
+
+static struct regulator_ops acp_da7219_ops = {
+};
+
+static const struct regulator_desc acp_da7219_desc = {
+ .name = "reg-fixed-1.8V",
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .ops = &acp_da7219_ops,
+ .fixed_uV = 1800000, /* 1.8V */
+ .n_voltages = 1,
+};
+
+static int cz_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct snd_soc_card *card;
+ struct acp_platform_info *machine;
+ struct regulator_dev *rdev;
+ struct device *dev = &pdev->dev;
+
+ card = (struct snd_soc_card *)acp_soc_is_rltk_max(dev);
+ if (!card)
+ return -ENODEV;
+ if (!strcmp(card->name, "acpd7219m98357")) {
+ acp_da7219_cfg.dev = &pdev->dev;
+ rdev = devm_regulator_register(&pdev->dev, &acp_da7219_desc,
+ &acp_da7219_cfg);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "Failed to register regulator: %d\n",
+ (int)PTR_ERR(rdev));
+ return -EINVAL;
+ }
+ }
+
+ machine = devm_kzalloc(&pdev->dev, sizeof(struct acp_platform_info),
+ GFP_KERNEL);
+ if (!machine)
+ return -ENOMEM;
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, machine);
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret) {
+ return dev_err_probe(&pdev->dev, ret,
+ "devm_snd_soc_register_card(%s) failed\n",
+ card->name);
+ }
+ acp_bt_uart_enable = !device_property_read_bool(&pdev->dev,
+ "bt-pad-enable");
+ return 0;
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id cz_audio_acpi_match[] = {
+ { "AMD7219", (unsigned long)&cz_card },
+ { "AMDI5682", (unsigned long)&cz_rt5682_card},
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match);
+#endif
+
+static struct platform_driver cz_pcm_driver = {
+ .driver = {
+ .name = "cz-da7219-max98357a",
+ .acpi_match_table = ACPI_PTR(cz_audio_acpi_match),
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = cz_probe,
+};
+
+module_platform_driver(cz_pcm_driver);
+
+MODULE_AUTHOR("akshu.agrawal@amd.com");
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("DA7219, RT5682 & MAX98357A audio support");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c
new file mode 100644
index 0000000000..5e56d3a53b
--- /dev/null
+++ b/sound/soc/amd/acp-es8336.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Machine driver for AMD Stoney platform using ES8336 Codec
+ *
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ */
+
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/dmi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
+
+#include "acp.h"
+
+#define DUAL_CHANNEL 2
+#define DRV_NAME "acp2x_mach"
+#define ST_JADEITE 1
+#define ES8336_PLL_FREQ (48000 * 256)
+
+static unsigned long acp2x_machine_id;
+static struct snd_soc_jack st_jack;
+static struct device *codec_dev;
+static struct gpio_desc *gpio_pa;
+
+static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ if (SND_SOC_DAPM_EVENT_ON(event))
+ gpiod_set_value_cansleep(gpio_pa, true);
+ else
+ gpiod_set_value_cansleep(gpio_pa, false);
+
+ return 0;
+}
+
+static struct snd_soc_jack_pin st_es8316_jack_pins[] = {
+ {
+ .pin = "Headphone",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+static int st_es8336_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret;
+ struct snd_soc_card *card;
+ struct snd_soc_component *codec;
+
+ codec = asoc_rtd_to_codec(rtd, 0)->component;
+ card = rtd->card;
+
+ ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0,
+ &st_jack, st_es8316_jack_pins,
+ ARRAY_SIZE(st_es8316_jack_pins));
+ if (ret) {
+ dev_err(card->dev, "HP jack creation failed %d\n", ret);
+ return ret;
+ }
+ snd_jack_set_key(st_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ ret = snd_soc_component_set_jack(codec, &st_jack, NULL);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static const unsigned int st_channels[] = {
+ DUAL_CHANNEL,
+};
+
+static const unsigned int st_rates[] = {
+ 48000,
+};
+
+static const struct snd_pcm_hw_constraint_list st_constraints_rates = {
+ .count = ARRAY_SIZE(st_rates),
+ .list = st_rates,
+ .mask = 0,
+};
+
+static const struct snd_pcm_hw_constraint_list st_constraints_channels = {
+ .count = ARRAY_SIZE(st_channels),
+ .list = st_channels,
+ .mask = 0,
+};
+
+static int st_es8336_codec_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime;
+ struct snd_soc_pcm_runtime *rtd;
+ struct snd_soc_card *card;
+ struct acp_platform_info *machine;
+ struct snd_soc_dai *codec_dai;
+ int ret;
+
+ runtime = substream->runtime;
+ rtd = asoc_substream_to_rtd(substream);
+ card = rtd->card;
+ machine = snd_soc_card_get_drvdata(card);
+ codec_dai = asoc_rtd_to_codec(rtd, 0);
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, ES8336_PLL_FREQ, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
+ return ret;
+ }
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &st_constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &st_constraints_rates);
+
+ machine->play_i2s_instance = I2S_MICSP_INSTANCE;
+ machine->cap_i2s_instance = I2S_MICSP_INSTANCE;
+ machine->capture_channel = CAP_CHANNEL0;
+ return 0;
+}
+
+static const struct snd_soc_ops st_es8336_ops = {
+ .startup = st_es8336_codec_startup,
+};
+
+SND_SOC_DAILINK_DEF(designware1,
+ DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto")));
+SND_SOC_DAILINK_DEF(codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ESSX8336:00", "ES8316 HiFi")));
+SND_SOC_DAILINK_DEF(platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.1.auto")));
+
+static struct snd_soc_dai_link st_dai_es8336[] = {
+ {
+ .name = "amdes8336",
+ .stream_name = "ES8336 HiFi Play",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .init = st_es8336_init,
+ .ops = &st_es8336_ops,
+ SND_SOC_DAILINK_REG(designware1, codec, platform),
+ },
+};
+
+static const struct snd_soc_dapm_widget st_widgets[] = {
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Internal Mic", NULL),
+
+ SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
+ sof_es8316_speaker_power_event,
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+};
+
+static const struct snd_soc_dapm_route st_audio_route[] = {
+ {"Speaker", NULL, "HPOL"},
+ {"Speaker", NULL, "HPOR"},
+ {"Headphone", NULL, "HPOL"},
+ {"Headphone", NULL, "HPOR"},
+ {"MIC1", NULL, "Headset Mic"},
+ {"MIC2", NULL, "Internal Mic"},
+ {"Speaker", NULL, "Speaker Power"},
+};
+
+static const struct snd_kcontrol_new st_mc_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Speaker"),
+ SOC_DAPM_PIN_SWITCH("Headphone"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Internal Mic"),
+};
+
+static const struct acpi_gpio_params pa_enable_gpio = { 0, 0, false };
+static const struct acpi_gpio_mapping acpi_es8336_gpios[] = {
+ { "pa-enable-gpios", &pa_enable_gpio, 1 },
+ { }
+};
+
+static int st_es8336_late_probe(struct snd_soc_card *card)
+{
+ struct acpi_device *adev;
+ int ret;
+
+ adev = acpi_dev_get_first_match_dev("ESSX8336", NULL, -1);
+ if (!adev)
+ return -ENODEV;
+
+ codec_dev = acpi_get_first_physical_node(adev);
+ acpi_dev_put(adev);
+ if (!codec_dev)
+ dev_err(card->dev, "can not find codec dev\n");
+
+ ret = devm_acpi_dev_add_driver_gpios(codec_dev, acpi_es8336_gpios);
+ if (ret)
+ dev_warn(card->dev, "Failed to add driver gpios\n");
+
+ gpio_pa = gpiod_get_optional(codec_dev, "pa-enable", GPIOD_OUT_LOW);
+ if (IS_ERR(gpio_pa)) {
+ ret = dev_err_probe(card->dev, PTR_ERR(gpio_pa),
+ "could not get pa-enable GPIO\n");
+ put_device(codec_dev);
+ return ret;
+ }
+ return 0;
+}
+
+static struct snd_soc_card st_card = {
+ .name = "acpes8336",
+ .owner = THIS_MODULE,
+ .dai_link = st_dai_es8336,
+ .num_links = ARRAY_SIZE(st_dai_es8336),
+ .dapm_widgets = st_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(st_widgets),
+ .dapm_routes = st_audio_route,
+ .num_dapm_routes = ARRAY_SIZE(st_audio_route),
+ .controls = st_mc_controls,
+ .num_controls = ARRAY_SIZE(st_mc_controls),
+ .late_probe = st_es8336_late_probe,
+};
+
+static int st_es8336_quirk_cb(const struct dmi_system_id *id)
+{
+ acp2x_machine_id = ST_JADEITE;
+ return 1;
+}
+
+static const struct dmi_system_id st_es8336_quirk_table[] = {
+ {
+ .callback = st_es8336_quirk_cb,
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMD"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jadeite"),
+ },
+ },
+ {
+ .callback = st_es8336_quirk_cb,
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "IP3 Technology CO.,Ltd."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN1D"),
+ },
+ },
+ {
+ .callback = st_es8336_quirk_cb,
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Standard"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN10"),
+ },
+ },
+ {}
+};
+
+static int st_es8336_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct snd_soc_card *card;
+ struct acp_platform_info *machine;
+
+ machine = devm_kzalloc(&pdev->dev, sizeof(struct acp_platform_info), GFP_KERNEL);
+ if (!machine)
+ return -ENOMEM;
+
+ dmi_check_system(st_es8336_quirk_table);
+ switch (acp2x_machine_id) {
+ case ST_JADEITE:
+ card = &st_card;
+ st_card.dev = &pdev->dev;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, machine);
+ ret = devm_snd_soc_register_card(&pdev->dev, &st_card);
+ if (ret) {
+ return dev_err_probe(&pdev->dev, ret,
+ "devm_snd_soc_register_card(%s) failed\n",
+ card->name);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id st_audio_acpi_match[] = {
+ {"AMDI8336", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, st_audio_acpi_match);
+#endif
+
+static struct platform_driver st_mach_driver = {
+ .driver = {
+ .name = "st-es8316",
+ .acpi_match_table = ACPI_PTR(st_audio_acpi_match),
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = st_es8336_probe,
+};
+
+module_platform_driver(st_mach_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("st-es8316 audio support");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
new file mode 100644
index 0000000000..d41df316da
--- /dev/null
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -0,0 +1,1442 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AMD ALSA SoC PCM Driver for ACP 2.x
+ *
+ * Copyright 2014-2015 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/sizes.h>
+#include <linux/pm_runtime.h>
+
+#include <sound/soc.h>
+#include <drm/amd_asic_type.h>
+#include "acp.h"
+
+#define DRV_NAME "acp_audio_dma"
+
+#define PLAYBACK_MIN_NUM_PERIODS 2
+#define PLAYBACK_MAX_NUM_PERIODS 2
+#define PLAYBACK_MAX_PERIOD_SIZE 16384
+#define PLAYBACK_MIN_PERIOD_SIZE 1024
+#define CAPTURE_MIN_NUM_PERIODS 2
+#define CAPTURE_MAX_NUM_PERIODS 2
+#define CAPTURE_MAX_PERIOD_SIZE 16384
+#define CAPTURE_MIN_PERIOD_SIZE 1024
+
+#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
+#define MIN_BUFFER MAX_BUFFER
+
+#define ST_PLAYBACK_MAX_PERIOD_SIZE 4096
+#define ST_CAPTURE_MAX_PERIOD_SIZE ST_PLAYBACK_MAX_PERIOD_SIZE
+#define ST_MAX_BUFFER (ST_PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
+#define ST_MIN_BUFFER ST_MAX_BUFFER
+
+#define DRV_NAME "acp_audio_dma"
+bool acp_bt_uart_enable = true;
+EXPORT_SYMBOL(acp_bt_uart_enable);
+
+static const struct snd_pcm_hardware acp_pcm_hardware_playback = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
+ .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
+ .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
+ .periods_min = PLAYBACK_MIN_NUM_PERIODS,
+ .periods_max = PLAYBACK_MAX_NUM_PERIODS,
+};
+
+static const struct snd_pcm_hardware acp_pcm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
+static const struct snd_pcm_hardware acp_st_pcm_hardware_playback = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .buffer_bytes_max = ST_MAX_BUFFER,
+ .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
+ .period_bytes_max = ST_PLAYBACK_MAX_PERIOD_SIZE,
+ .periods_min = PLAYBACK_MIN_NUM_PERIODS,
+ .periods_max = PLAYBACK_MAX_NUM_PERIODS,
+};
+
+static const struct snd_pcm_hardware acp_st_pcm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .buffer_bytes_max = ST_MAX_BUFFER,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = ST_CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
+static u32 acp_reg_read(void __iomem *acp_mmio, u32 reg)
+{
+ return readl(acp_mmio + (reg * 4));
+}
+
+static void acp_reg_write(u32 val, void __iomem *acp_mmio, u32 reg)
+{
+ writel(val, acp_mmio + (reg * 4));
+}
+
+/*
+ * Configure a given dma channel parameters - enable/disable,
+ * number of descriptors, priority
+ */
+static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num,
+ u16 dscr_strt_idx, u16 num_dscrs,
+ enum acp_dma_priority_level priority_level)
+{
+ u32 dma_ctrl;
+
+ /* disable the channel run field */
+ dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+ dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRun_MASK;
+ acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+
+ /* program a DMA channel with first descriptor to be processed. */
+ acp_reg_write((ACP_DMA_DSCR_STRT_IDX_0__DMAChDscrStrtIdx_MASK
+ & dscr_strt_idx),
+ acp_mmio, mmACP_DMA_DSCR_STRT_IDX_0 + ch_num);
+
+ /*
+ * program a DMA channel with the number of descriptors to be
+ * processed in the transfer
+ */
+ acp_reg_write(ACP_DMA_DSCR_CNT_0__DMAChDscrCnt_MASK & num_dscrs,
+ acp_mmio, mmACP_DMA_DSCR_CNT_0 + ch_num);
+
+ /* set DMA channel priority */
+ acp_reg_write(priority_level, acp_mmio, mmACP_DMA_PRIO_0 + ch_num);
+}
+
+/* Initialize a dma descriptor in SRAM based on descriptor information passed */
+static void config_dma_descriptor_in_sram(void __iomem *acp_mmio,
+ u16 descr_idx,
+ acp_dma_dscr_transfer_t *descr_info)
+{
+ u32 sram_offset;
+
+ sram_offset = (descr_idx * sizeof(acp_dma_dscr_transfer_t));
+
+ /* program the source base address. */
+ acp_reg_write(sram_offset, acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
+ acp_reg_write(descr_info->src, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
+ /* program the destination base address. */
+ acp_reg_write(sram_offset + 4, acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
+ acp_reg_write(descr_info->dest, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
+
+ /* program the number of bytes to be transferred for this descriptor. */
+ acp_reg_write(sram_offset + 8, acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
+ acp_reg_write(descr_info->xfer_val, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
+}
+
+static void pre_config_reset(void __iomem *acp_mmio, u16 ch_num)
+{
+ u32 dma_ctrl;
+ int ret;
+
+ /* clear the reset bit */
+ dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+ dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRst_MASK;
+ acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+ /* check the reset bit before programming configuration registers */
+ ret = readl_poll_timeout(acp_mmio + ((mmACP_DMA_CNTL_0 + ch_num) * 4),
+ dma_ctrl,
+ !(dma_ctrl & ACP_DMA_CNTL_0__DMAChRst_MASK),
+ 100, ACP_DMA_RESET_TIME);
+ if (ret < 0)
+ pr_err("Failed to clear reset of channel : %d\n", ch_num);
+}
+
+/*
+ * Initialize the DMA descriptor information for transfer between
+ * system memory <-> ACP SRAM
+ */
+static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
+ u32 size, int direction,
+ u32 pte_offset, u16 ch,
+ u32 sram_bank, u16 dma_dscr_idx,
+ u32 asic_type)
+{
+ u16 i;
+ acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
+
+ for (i = 0; i < NUM_DSCRS_PER_CHANNEL; i++) {
+ dmadscr[i].xfer_val = 0;
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ dma_dscr_idx = dma_dscr_idx + i;
+ dmadscr[i].dest = sram_bank + (i * (size / 2));
+ dmadscr[i].src = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS
+ + (pte_offset * SZ_4K) + (i * (size / 2));
+ switch (asic_type) {
+ case CHIP_STONEY:
+ dmadscr[i].xfer_val |=
+ (ACP_DMA_ATTR_DAGB_GARLIC_TO_SHAREDMEM << 16) |
+ (size / 2);
+ break;
+ default:
+ dmadscr[i].xfer_val |=
+ (ACP_DMA_ATTR_DAGB_ONION_TO_SHAREDMEM << 16) |
+ (size / 2);
+ }
+ } else {
+ dma_dscr_idx = dma_dscr_idx + i;
+ dmadscr[i].src = sram_bank + (i * (size / 2));
+ dmadscr[i].dest =
+ ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
+ (pte_offset * SZ_4K) + (i * (size / 2));
+ switch (asic_type) {
+ case CHIP_STONEY:
+ dmadscr[i].xfer_val |=
+ (ACP_DMA_ATTR_SHARED_MEM_TO_DAGB_GARLIC << 16) |
+ (size / 2);
+ break;
+ default:
+ dmadscr[i].xfer_val |=
+ (ACP_DMA_ATTR_SHAREDMEM_TO_DAGB_ONION << 16) |
+ (size / 2);
+ }
+ }
+ config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
+ &dmadscr[i]);
+ }
+ pre_config_reset(acp_mmio, ch);
+ config_acp_dma_channel(acp_mmio, ch,
+ dma_dscr_idx - 1,
+ NUM_DSCRS_PER_CHANNEL,
+ ACP_DMA_PRIORITY_LEVEL_NORMAL);
+}
+
+/*
+ * Initialize the DMA descriptor information for transfer between
+ * ACP SRAM <-> I2S
+ */
+static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
+ int direction, u32 sram_bank,
+ u16 destination, u16 ch,
+ u16 dma_dscr_idx, u32 asic_type)
+{
+ u16 i;
+ acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
+
+ for (i = 0; i < NUM_DSCRS_PER_CHANNEL; i++) {
+ dmadscr[i].xfer_val = 0;
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ dma_dscr_idx = dma_dscr_idx + i;
+ dmadscr[i].src = sram_bank + (i * (size / 2));
+ /* dmadscr[i].dest is unused by hardware. */
+ dmadscr[i].dest = 0;
+ dmadscr[i].xfer_val |= BIT(22) | (destination << 16) |
+ (size / 2);
+ } else {
+ dma_dscr_idx = dma_dscr_idx + i;
+ /* dmadscr[i].src is unused by hardware. */
+ dmadscr[i].src = 0;
+ dmadscr[i].dest =
+ sram_bank + (i * (size / 2));
+ dmadscr[i].xfer_val |= BIT(22) |
+ (destination << 16) | (size / 2);
+ }
+ config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
+ &dmadscr[i]);
+ }
+ pre_config_reset(acp_mmio, ch);
+ /* Configure the DMA channel with the above descriptor */
+ config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1,
+ NUM_DSCRS_PER_CHANNEL,
+ ACP_DMA_PRIORITY_LEVEL_NORMAL);
+}
+
+/* Create page table entries in ACP SRAM for the allocated memory */
+static void acp_pte_config(void __iomem *acp_mmio, dma_addr_t addr,
+ u16 num_of_pages, u32 pte_offset)
+{
+ u16 page_idx;
+ u32 low;
+ u32 high;
+ u32 offset;
+
+ offset = ACP_DAGB_GRP_SRBM_SRAM_BASE_OFFSET + (pte_offset * 8);
+ for (page_idx = 0; page_idx < (num_of_pages); page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ acp_reg_write((offset + (page_idx * 8)),
+ acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
+
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+
+ acp_reg_write(low, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
+
+ /* Load the High address of page int ACP SRAM through SRBM */
+ acp_reg_write((offset + (page_idx * 8) + 4),
+ acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
+
+ /* page enable in ACP */
+ high |= BIT(31);
+ acp_reg_write(high, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
+
+ /* Move to next physically contiguous page */
+ addr += PAGE_SIZE;
+ }
+}
+
+static void config_acp_dma(void __iomem *acp_mmio,
+ struct audio_substream_data *rtd,
+ u32 asic_type)
+{
+ u16 ch_acp_sysmem, ch_acp_i2s;
+
+ acp_pte_config(acp_mmio, rtd->dma_addr, rtd->num_of_pages,
+ rtd->pte_offset);
+
+ if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ ch_acp_sysmem = rtd->ch1;
+ ch_acp_i2s = rtd->ch2;
+ } else {
+ ch_acp_i2s = rtd->ch1;
+ ch_acp_sysmem = rtd->ch2;
+ }
+ /* Configure System memory <-> ACP SRAM DMA descriptors */
+ set_acp_sysmem_dma_descriptors(acp_mmio, rtd->size,
+ rtd->direction, rtd->pte_offset,
+ ch_acp_sysmem, rtd->sram_bank,
+ rtd->dma_dscr_idx_1, asic_type);
+ /* Configure ACP SRAM <-> I2S DMA descriptors */
+ set_acp_to_i2s_dma_descriptors(acp_mmio, rtd->size,
+ rtd->direction, rtd->sram_bank,
+ rtd->destination, ch_acp_i2s,
+ rtd->dma_dscr_idx_2, asic_type);
+}
+
+static void acp_dma_cap_channel_enable(void __iomem *acp_mmio,
+ u16 cap_channel)
+{
+ u32 val, ch_reg, imr_reg, res_reg;
+
+ switch (cap_channel) {
+ case CAP_CHANNEL1:
+ ch_reg = mmACP_I2SMICSP_RER1;
+ res_reg = mmACP_I2SMICSP_RCR1;
+ imr_reg = mmACP_I2SMICSP_IMR1;
+ break;
+ case CAP_CHANNEL0:
+ default:
+ ch_reg = mmACP_I2SMICSP_RER0;
+ res_reg = mmACP_I2SMICSP_RCR0;
+ imr_reg = mmACP_I2SMICSP_IMR0;
+ break;
+ }
+ val = acp_reg_read(acp_mmio,
+ mmACP_I2S_16BIT_RESOLUTION_EN);
+ if (val & ACP_I2S_MIC_16BIT_RESOLUTION_EN) {
+ acp_reg_write(0x0, acp_mmio, ch_reg);
+ /* Set 16bit resolution on capture */
+ acp_reg_write(0x2, acp_mmio, res_reg);
+ }
+ val = acp_reg_read(acp_mmio, imr_reg);
+ val &= ~ACP_I2SMICSP_IMR1__I2SMICSP_RXDAM_MASK;
+ val &= ~ACP_I2SMICSP_IMR1__I2SMICSP_RXFOM_MASK;
+ acp_reg_write(val, acp_mmio, imr_reg);
+ acp_reg_write(0x1, acp_mmio, ch_reg);
+}
+
+static void acp_dma_cap_channel_disable(void __iomem *acp_mmio,
+ u16 cap_channel)
+{
+ u32 val, ch_reg, imr_reg;
+
+ switch (cap_channel) {
+ case CAP_CHANNEL1:
+ imr_reg = mmACP_I2SMICSP_IMR1;
+ ch_reg = mmACP_I2SMICSP_RER1;
+ break;
+ case CAP_CHANNEL0:
+ default:
+ imr_reg = mmACP_I2SMICSP_IMR0;
+ ch_reg = mmACP_I2SMICSP_RER0;
+ break;
+ }
+ val = acp_reg_read(acp_mmio, imr_reg);
+ val |= ACP_I2SMICSP_IMR1__I2SMICSP_RXDAM_MASK;
+ val |= ACP_I2SMICSP_IMR1__I2SMICSP_RXFOM_MASK;
+ acp_reg_write(val, acp_mmio, imr_reg);
+ acp_reg_write(0x0, acp_mmio, ch_reg);
+}
+
+/* Start a given DMA channel transfer */
+static void acp_dma_start(void __iomem *acp_mmio, u16 ch_num, bool is_circular)
+{
+ u32 dma_ctrl;
+
+ /* read the dma control register and disable the channel run field */
+ dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+
+ /* Invalidating the DAGB cache */
+ acp_reg_write(1, acp_mmio, mmACP_DAGB_ATU_CTRL);
+
+ /*
+ * configure the DMA channel and start the DMA transfer
+ * set dmachrun bit to start the transfer and enable the
+ * interrupt on completion of the dma transfer
+ */
+ dma_ctrl |= ACP_DMA_CNTL_0__DMAChRun_MASK;
+
+ switch (ch_num) {
+ case ACP_TO_I2S_DMA_CH_NUM:
+ case I2S_TO_ACP_DMA_CH_NUM:
+ case ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM:
+ case I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM:
+ case ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM:
+ dma_ctrl |= ACP_DMA_CNTL_0__DMAChIOCEn_MASK;
+ break;
+ default:
+ dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChIOCEn_MASK;
+ break;
+ }
+
+ /* enable for ACP to SRAM DMA channel */
+ if (is_circular == true)
+ dma_ctrl |= ACP_DMA_CNTL_0__Circular_DMA_En_MASK;
+ else
+ dma_ctrl &= ~ACP_DMA_CNTL_0__Circular_DMA_En_MASK;
+
+ acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+}
+
+/* Stop a given DMA channel transfer */
+static int acp_dma_stop(void __iomem *acp_mmio, u8 ch_num)
+{
+ u32 dma_ctrl;
+ u32 dma_ch_sts;
+ u32 count = ACP_DMA_RESET_TIME;
+
+ dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+
+ /*
+ * clear the dma control register fields before writing zero
+ * in reset bit
+ */
+ dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRun_MASK;
+ dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChIOCEn_MASK;
+
+ acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+ dma_ch_sts = acp_reg_read(acp_mmio, mmACP_DMA_CH_STS);
+
+ if (dma_ch_sts & BIT(ch_num)) {
+ /*
+ * set the reset bit for this channel to stop the dma
+ * transfer
+ */
+ dma_ctrl |= ACP_DMA_CNTL_0__DMAChRst_MASK;
+ acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+ }
+
+ /* check the channel status bit for some time and return the status */
+ while (true) {
+ dma_ch_sts = acp_reg_read(acp_mmio, mmACP_DMA_CH_STS);
+ if (!(dma_ch_sts & BIT(ch_num))) {
+ /*
+ * clear the reset flag after successfully stopping
+ * the dma transfer and break from the loop
+ */
+ dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRst_MASK;
+
+ acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0
+ + ch_num);
+ break;
+ }
+ if (--count == 0) {
+ pr_err("Failed to stop ACP DMA channel : %d\n", ch_num);
+ return -ETIMEDOUT;
+ }
+ udelay(100);
+ }
+ return 0;
+}
+
+static void acp_set_sram_bank_state(void __iomem *acp_mmio, u16 bank,
+ bool power_on)
+{
+ u32 val, req_reg, sts_reg, sts_reg_mask;
+ u32 loops = 1000;
+
+ if (bank < 32) {
+ req_reg = mmACP_MEM_SHUT_DOWN_REQ_LO;
+ sts_reg = mmACP_MEM_SHUT_DOWN_STS_LO;
+ sts_reg_mask = 0xFFFFFFFF;
+
+ } else {
+ bank -= 32;
+ req_reg = mmACP_MEM_SHUT_DOWN_REQ_HI;
+ sts_reg = mmACP_MEM_SHUT_DOWN_STS_HI;
+ sts_reg_mask = 0x0000FFFF;
+ }
+
+ val = acp_reg_read(acp_mmio, req_reg);
+ if (val & (1 << bank)) {
+ /* bank is in off state */
+ if (power_on == true)
+ /* request to on */
+ val &= ~(1 << bank);
+ else
+ /* request to off */
+ return;
+ } else {
+ /* bank is in on state */
+ if (power_on == false)
+ /* request to off */
+ val |= 1 << bank;
+ else
+ /* request to on */
+ return;
+ }
+ acp_reg_write(val, acp_mmio, req_reg);
+
+ while (acp_reg_read(acp_mmio, sts_reg) != sts_reg_mask) {
+ if (!loops--) {
+ pr_err("ACP SRAM bank %d state change failed\n", bank);
+ break;
+ }
+ cpu_relax();
+ }
+}
+
+/* Initialize and bring ACP hardware to default state. */
+static int acp_init(void __iomem *acp_mmio, u32 asic_type)
+{
+ u16 bank;
+ u32 val, count, sram_pte_offset;
+
+ /* Assert Soft reset of ACP */
+ val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
+
+ val |= ACP_SOFT_RESET__SoftResetAud_MASK;
+ acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET);
+
+ count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;
+ while (true) {
+ val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
+ if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==
+ (val & ACP_SOFT_RESET__SoftResetAudDone_MASK))
+ break;
+ if (--count == 0) {
+ pr_err("Failed to reset ACP\n");
+ return -ETIMEDOUT;
+ }
+ udelay(100);
+ }
+
+ /* Enable clock to ACP and wait until the clock is enabled */
+ val = acp_reg_read(acp_mmio, mmACP_CONTROL);
+ val = val | ACP_CONTROL__ClkEn_MASK;
+ acp_reg_write(val, acp_mmio, mmACP_CONTROL);
+
+ count = ACP_CLOCK_EN_TIME_OUT_VALUE;
+
+ while (true) {
+ val = acp_reg_read(acp_mmio, mmACP_STATUS);
+ if (val & (u32)0x1)
+ break;
+ if (--count == 0) {
+ pr_err("Failed to reset ACP\n");
+ return -ETIMEDOUT;
+ }
+ udelay(100);
+ }
+
+ /* Deassert the SOFT RESET flags */
+ val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
+ val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
+ acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET);
+
+ /* For BT instance change pins from UART to BT */
+ if (!acp_bt_uart_enable) {
+ val = acp_reg_read(acp_mmio, mmACP_BT_UART_PAD_SEL);
+ val |= ACP_BT_UART_PAD_SELECT_MASK;
+ acp_reg_write(val, acp_mmio, mmACP_BT_UART_PAD_SEL);
+ }
+
+ /* initialize Onion control DAGB register */
+ acp_reg_write(ACP_ONION_CNTL_DEFAULT, acp_mmio,
+ mmACP_AXI2DAGB_ONION_CNTL);
+
+ /* initialize Garlic control DAGB registers */
+ acp_reg_write(ACP_GARLIC_CNTL_DEFAULT, acp_mmio,
+ mmACP_AXI2DAGB_GARLIC_CNTL);
+
+ sram_pte_offset = ACP_DAGB_GRP_SRAM_BASE_ADDRESS |
+ ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBSnoopSel_MASK |
+ ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBTargetMemSel_MASK |
+ ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBGrpEnable_MASK;
+ acp_reg_write(sram_pte_offset, acp_mmio, mmACP_DAGB_BASE_ADDR_GRP_1);
+ acp_reg_write(ACP_PAGE_SIZE_4K_ENABLE, acp_mmio,
+ mmACP_DAGB_PAGE_SIZE_GRP_1);
+
+ acp_reg_write(ACP_SRAM_BASE_ADDRESS, acp_mmio,
+ mmACP_DMA_DESC_BASE_ADDR);
+
+ /* Num of descriptors in SRAM 0x4, means 256 descriptors;(64 * 4) */
+ acp_reg_write(0x4, acp_mmio, mmACP_DMA_DESC_MAX_NUM_DSCR);
+ acp_reg_write(ACP_EXTERNAL_INTR_CNTL__DMAIOCMask_MASK,
+ acp_mmio, mmACP_EXTERNAL_INTR_CNTL);
+
+ /*
+ * When ACP_TILE_P1 is turned on, all SRAM banks get turned on.
+ * Now, turn off all of them. This can't be done in 'poweron' of
+ * ACP pm domain, as this requires ACP to be initialized.
+ * For Stoney, Memory gating is disabled,i.e SRAM Banks
+ * won't be turned off. The default state for SRAM banks is ON.
+ * Setting SRAM bank state code skipped for STONEY platform.
+ */
+ if (asic_type != CHIP_STONEY) {
+ for (bank = 1; bank < 48; bank++)
+ acp_set_sram_bank_state(acp_mmio, bank, false);
+ }
+ return 0;
+}
+
+/* Deinitialize ACP */
+static int acp_deinit(void __iomem *acp_mmio)
+{
+ u32 val;
+ u32 count;
+
+ /* Assert Soft reset of ACP */
+ val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
+
+ val |= ACP_SOFT_RESET__SoftResetAud_MASK;
+ acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET);
+
+ count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;
+ while (true) {
+ val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
+ if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==
+ (val & ACP_SOFT_RESET__SoftResetAudDone_MASK))
+ break;
+ if (--count == 0) {
+ pr_err("Failed to reset ACP\n");
+ return -ETIMEDOUT;
+ }
+ udelay(100);
+ }
+ /* Disable ACP clock */
+ val = acp_reg_read(acp_mmio, mmACP_CONTROL);
+ val &= ~ACP_CONTROL__ClkEn_MASK;
+ acp_reg_write(val, acp_mmio, mmACP_CONTROL);
+
+ count = ACP_CLOCK_EN_TIME_OUT_VALUE;
+
+ while (true) {
+ val = acp_reg_read(acp_mmio, mmACP_STATUS);
+ if (!(val & (u32)0x1))
+ break;
+ if (--count == 0) {
+ pr_err("Failed to reset ACP\n");
+ return -ETIMEDOUT;
+ }
+ udelay(100);
+ }
+ return 0;
+}
+
+/* ACP DMA irq handler routine for playback, capture usecases */
+static irqreturn_t dma_irq_handler(int irq, void *arg)
+{
+ u16 dscr_idx;
+ u32 intr_flag, ext_intr_status;
+ struct audio_drv_data *irq_data;
+ void __iomem *acp_mmio;
+ struct device *dev = arg;
+ bool valid_irq = false;
+
+ irq_data = dev_get_drvdata(dev);
+ acp_mmio = irq_data->acp_mmio;
+
+ ext_intr_status = acp_reg_read(acp_mmio, mmACP_EXTERNAL_INTR_STAT);
+ intr_flag = (((ext_intr_status &
+ ACP_EXTERNAL_INTR_STAT__DMAIOCStat_MASK) >>
+ ACP_EXTERNAL_INTR_STAT__DMAIOCStat__SHIFT));
+
+ if ((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) != 0) {
+ valid_irq = true;
+ snd_pcm_period_elapsed(irq_data->play_i2ssp_stream);
+ acp_reg_write((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) << 16,
+ acp_mmio, mmACP_EXTERNAL_INTR_STAT);
+ }
+
+ if ((intr_flag & BIT(ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM)) != 0) {
+ valid_irq = true;
+ snd_pcm_period_elapsed(irq_data->play_i2s_micsp_stream);
+ acp_reg_write((intr_flag & BIT(ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM)) << 16,
+ acp_mmio, mmACP_EXTERNAL_INTR_STAT);
+ }
+
+ if ((intr_flag & BIT(ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM)) != 0) {
+ valid_irq = true;
+ snd_pcm_period_elapsed(irq_data->play_i2sbt_stream);
+ acp_reg_write((intr_flag &
+ BIT(ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM)) << 16,
+ acp_mmio, mmACP_EXTERNAL_INTR_STAT);
+ }
+
+ if ((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) != 0) {
+ valid_irq = true;
+ if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_14) ==
+ CAPTURE_START_DMA_DESCR_CH15)
+ dscr_idx = CAPTURE_END_DMA_DESCR_CH14;
+ else
+ dscr_idx = CAPTURE_START_DMA_DESCR_CH14;
+ config_acp_dma_channel(acp_mmio, ACP_TO_SYSRAM_CH_NUM, dscr_idx,
+ 1, 0);
+ acp_dma_start(acp_mmio, ACP_TO_SYSRAM_CH_NUM, false);
+
+ snd_pcm_period_elapsed(irq_data->capture_i2ssp_stream);
+ acp_reg_write((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) << 16,
+ acp_mmio, mmACP_EXTERNAL_INTR_STAT);
+ }
+
+ if ((intr_flag & BIT(I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM)) != 0) {
+ valid_irq = true;
+ if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_10) ==
+ CAPTURE_START_DMA_DESCR_CH11)
+ dscr_idx = CAPTURE_END_DMA_DESCR_CH10;
+ else
+ dscr_idx = CAPTURE_START_DMA_DESCR_CH10;
+ config_acp_dma_channel(acp_mmio,
+ ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM,
+ dscr_idx, 1, 0);
+ acp_dma_start(acp_mmio, ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM,
+ false);
+
+ snd_pcm_period_elapsed(irq_data->capture_i2sbt_stream);
+ acp_reg_write((intr_flag &
+ BIT(I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM)) << 16,
+ acp_mmio, mmACP_EXTERNAL_INTR_STAT);
+ }
+
+ if (valid_irq)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static int acp_dma_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ u16 bank;
+ int ret = 0;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct audio_drv_data *intr_data = dev_get_drvdata(component->dev);
+ struct audio_substream_data *adata =
+ kzalloc(sizeof(struct audio_substream_data), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (intr_data->asic_type) {
+ case CHIP_STONEY:
+ runtime->hw = acp_st_pcm_hardware_playback;
+ break;
+ default:
+ runtime->hw = acp_pcm_hardware_playback;
+ }
+ } else {
+ switch (intr_data->asic_type) {
+ case CHIP_STONEY:
+ runtime->hw = acp_st_pcm_hardware_capture;
+ break;
+ default:
+ runtime->hw = acp_pcm_hardware_capture;
+ }
+ }
+
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(adata);
+ return ret;
+ }
+
+ adata->acp_mmio = intr_data->acp_mmio;
+ runtime->private_data = adata;
+
+ /*
+ * Enable ACP irq, when neither playback or capture streams are
+ * active by the time when a new stream is being opened.
+ * This enablement is not required for another stream, if current
+ * stream is not closed
+ */
+ if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream &&
+ !intr_data->play_i2sbt_stream && !intr_data->capture_i2sbt_stream &&
+ !intr_data->play_i2s_micsp_stream)
+ acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ /*
+ * For Stoney, Memory gating is disabled,i.e SRAM Banks
+ * won't be turned off. The default state for SRAM banks is ON.
+ * Setting SRAM bank state code skipped for STONEY platform.
+ */
+ if (intr_data->asic_type != CHIP_STONEY) {
+ for (bank = 1; bank <= 4; bank++)
+ acp_set_sram_bank_state(intr_data->acp_mmio,
+ bank, true);
+ }
+ } else {
+ if (intr_data->asic_type != CHIP_STONEY) {
+ for (bank = 5; bank <= 8; bank++)
+ acp_set_sram_bank_state(intr_data->acp_mmio,
+ bank, true);
+ }
+ }
+
+ return 0;
+}
+
+static int acp_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ uint64_t size;
+ u32 val = 0;
+ struct snd_pcm_runtime *runtime;
+ struct audio_substream_data *rtd;
+ struct snd_soc_pcm_runtime *prtd = asoc_substream_to_rtd(substream);
+ struct audio_drv_data *adata = dev_get_drvdata(component->dev);
+ struct snd_soc_card *card = prtd->card;
+ struct acp_platform_info *pinfo = snd_soc_card_get_drvdata(card);
+
+ runtime = substream->runtime;
+ rtd = runtime->private_data;
+
+ if (WARN_ON(!rtd))
+ return -EINVAL;
+
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ } else {
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ rtd->capture_channel = pinfo->capture_channel;
+ }
+ }
+ if (adata->asic_type == CHIP_STONEY) {
+ val = acp_reg_read(adata->acp_mmio,
+ mmACP_I2S_16BIT_RESOLUTION_EN);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ val |= ACP_I2S_BT_16BIT_RESOLUTION_EN;
+ break;
+ case I2S_MICSP_INSTANCE:
+ val |= ACP_I2S_MICSP_16BIT_RESOLUTION_EN;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ val |= ACP_I2S_SP_16BIT_RESOLUTION_EN;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ val |= ACP_I2S_BT_16BIT_RESOLUTION_EN;
+ break;
+ case I2S_MICSP_INSTANCE:
+ case I2S_SP_INSTANCE:
+ default:
+ val |= ACP_I2S_MIC_16BIT_RESOLUTION_EN;
+ }
+ }
+ acp_reg_write(val, adata->acp_mmio,
+ mmACP_I2S_16BIT_RESOLUTION_EN);
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ rtd->pte_offset = ACP_ST_BT_PLAYBACK_PTE_OFFSET;
+ rtd->ch1 = SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM;
+ rtd->ch2 = ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM;
+ rtd->sram_bank = ACP_SRAM_BANK_3_ADDRESS;
+ rtd->destination = TO_BLUETOOTH;
+ rtd->dma_dscr_idx_1 = PLAYBACK_START_DMA_DESCR_CH8;
+ rtd->dma_dscr_idx_2 = PLAYBACK_START_DMA_DESCR_CH9;
+ rtd->byte_cnt_high_reg_offset =
+ mmACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH;
+ rtd->byte_cnt_low_reg_offset =
+ mmACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW;
+ adata->play_i2sbt_stream = substream;
+ break;
+ case I2S_MICSP_INSTANCE:
+ switch (adata->asic_type) {
+ case CHIP_STONEY:
+ rtd->pte_offset = ACP_ST_PLAYBACK_PTE_OFFSET;
+ break;
+ default:
+ rtd->pte_offset = ACP_PLAYBACK_PTE_OFFSET;
+ }
+ rtd->ch1 = SYSRAM_TO_ACP_MICSP_INSTANCE_CH_NUM;
+ rtd->ch2 = ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM;
+ rtd->sram_bank = ACP_SRAM_BANK_1_ADDRESS;
+ rtd->destination = TO_ACP_I2S_2;
+ rtd->dma_dscr_idx_1 = PLAYBACK_START_DMA_DESCR_CH4;
+ rtd->dma_dscr_idx_2 = PLAYBACK_START_DMA_DESCR_CH5;
+ rtd->byte_cnt_high_reg_offset =
+ mmACP_I2S_MICSP_TRANSMIT_BYTE_CNT_HIGH;
+ rtd->byte_cnt_low_reg_offset =
+ mmACP_I2S_MICSP_TRANSMIT_BYTE_CNT_LOW;
+
+ adata->play_i2s_micsp_stream = substream;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ switch (adata->asic_type) {
+ case CHIP_STONEY:
+ rtd->pte_offset = ACP_ST_PLAYBACK_PTE_OFFSET;
+ break;
+ default:
+ rtd->pte_offset = ACP_PLAYBACK_PTE_OFFSET;
+ }
+ rtd->ch1 = SYSRAM_TO_ACP_CH_NUM;
+ rtd->ch2 = ACP_TO_I2S_DMA_CH_NUM;
+ rtd->sram_bank = ACP_SRAM_BANK_1_ADDRESS;
+ rtd->destination = TO_ACP_I2S_1;
+ rtd->dma_dscr_idx_1 = PLAYBACK_START_DMA_DESCR_CH12;
+ rtd->dma_dscr_idx_2 = PLAYBACK_START_DMA_DESCR_CH13;
+ rtd->byte_cnt_high_reg_offset =
+ mmACP_I2S_TRANSMIT_BYTE_CNT_HIGH;
+ rtd->byte_cnt_low_reg_offset =
+ mmACP_I2S_TRANSMIT_BYTE_CNT_LOW;
+ adata->play_i2ssp_stream = substream;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ rtd->pte_offset = ACP_ST_BT_CAPTURE_PTE_OFFSET;
+ rtd->ch1 = I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM;
+ rtd->ch2 = ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM;
+ rtd->sram_bank = ACP_SRAM_BANK_4_ADDRESS;
+ rtd->destination = FROM_BLUETOOTH;
+ rtd->dma_dscr_idx_1 = CAPTURE_START_DMA_DESCR_CH10;
+ rtd->dma_dscr_idx_2 = CAPTURE_START_DMA_DESCR_CH11;
+ rtd->byte_cnt_high_reg_offset =
+ mmACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH;
+ rtd->byte_cnt_low_reg_offset =
+ mmACP_I2S_BT_RECEIVE_BYTE_CNT_LOW;
+ rtd->dma_curr_dscr = mmACP_DMA_CUR_DSCR_11;
+ adata->capture_i2sbt_stream = substream;
+ break;
+ case I2S_MICSP_INSTANCE:
+ case I2S_SP_INSTANCE:
+ default:
+ rtd->pte_offset = ACP_CAPTURE_PTE_OFFSET;
+ rtd->ch1 = I2S_TO_ACP_DMA_CH_NUM;
+ rtd->ch2 = ACP_TO_SYSRAM_CH_NUM;
+ switch (adata->asic_type) {
+ case CHIP_STONEY:
+ rtd->pte_offset = ACP_ST_CAPTURE_PTE_OFFSET;
+ rtd->sram_bank = ACP_SRAM_BANK_2_ADDRESS;
+ break;
+ default:
+ rtd->pte_offset = ACP_CAPTURE_PTE_OFFSET;
+ rtd->sram_bank = ACP_SRAM_BANK_5_ADDRESS;
+ }
+ rtd->destination = FROM_ACP_I2S_1;
+ rtd->dma_dscr_idx_1 = CAPTURE_START_DMA_DESCR_CH14;
+ rtd->dma_dscr_idx_2 = CAPTURE_START_DMA_DESCR_CH15;
+ rtd->byte_cnt_high_reg_offset =
+ mmACP_I2S_RECEIVED_BYTE_CNT_HIGH;
+ rtd->byte_cnt_low_reg_offset =
+ mmACP_I2S_RECEIVED_BYTE_CNT_LOW;
+ rtd->dma_curr_dscr = mmACP_DMA_CUR_DSCR_15;
+ adata->capture_i2ssp_stream = substream;
+ }
+ }
+
+ size = params_buffer_bytes(params);
+
+ acp_set_sram_bank_state(rtd->acp_mmio, 0, true);
+ /* Save for runtime private data */
+ rtd->dma_addr = runtime->dma_addr;
+ rtd->order = get_order(size);
+
+ /* Fill the page table entries in ACP SRAM */
+ rtd->size = size;
+ rtd->num_of_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ rtd->direction = substream->stream;
+
+ config_acp_dma(rtd->acp_mmio, rtd, adata->asic_type);
+ return 0;
+}
+
+static u64 acp_get_byte_count(struct audio_substream_data *rtd)
+{
+ union acp_dma_count byte_count;
+
+ byte_count.bcount.high = acp_reg_read(rtd->acp_mmio,
+ rtd->byte_cnt_high_reg_offset);
+ byte_count.bcount.low = acp_reg_read(rtd->acp_mmio,
+ rtd->byte_cnt_low_reg_offset);
+ return byte_count.bytescount;
+}
+
+static snd_pcm_uframes_t acp_dma_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ u32 buffersize;
+ u32 pos = 0;
+ u64 bytescount = 0;
+ u16 dscr;
+ u32 period_bytes, delay;
+
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct audio_substream_data *rtd = runtime->private_data;
+ struct audio_drv_data *adata = dev_get_drvdata(component->dev);
+
+ if (!rtd)
+ return -EINVAL;
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ period_bytes = frames_to_bytes(runtime, runtime->period_size);
+ bytescount = acp_get_byte_count(rtd);
+ if (bytescount >= rtd->bytescount)
+ bytescount -= rtd->bytescount;
+ if (bytescount < period_bytes) {
+ pos = 0;
+ } else {
+ dscr = acp_reg_read(rtd->acp_mmio, rtd->dma_curr_dscr);
+ if (dscr == rtd->dma_dscr_idx_1)
+ pos = period_bytes;
+ else
+ pos = 0;
+ }
+ if (bytescount > 0) {
+ delay = do_div(bytescount, period_bytes);
+ adata->delay += bytes_to_frames(runtime, delay);
+ }
+ } else {
+ buffersize = frames_to_bytes(runtime, runtime->buffer_size);
+ bytescount = acp_get_byte_count(rtd);
+ if (bytescount > rtd->bytescount)
+ bytescount -= rtd->bytescount;
+ pos = do_div(bytescount, buffersize);
+ }
+ return bytes_to_frames(runtime, pos);
+}
+
+static snd_pcm_sframes_t acp_dma_delay(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct audio_drv_data *adata = dev_get_drvdata(component->dev);
+ snd_pcm_sframes_t delay = adata->delay;
+
+ adata->delay = 0;
+
+ return delay;
+}
+
+static int acp_dma_prepare(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct audio_substream_data *rtd = runtime->private_data;
+ u16 ch_acp_sysmem, ch_acp_i2s;
+
+ if (!rtd)
+ return -EINVAL;
+
+ if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ ch_acp_sysmem = rtd->ch1;
+ ch_acp_i2s = rtd->ch2;
+ } else {
+ ch_acp_i2s = rtd->ch1;
+ ch_acp_sysmem = rtd->ch2;
+ }
+ config_acp_dma_channel(rtd->acp_mmio,
+ ch_acp_sysmem,
+ rtd->dma_dscr_idx_1,
+ NUM_DSCRS_PER_CHANNEL, 0);
+ config_acp_dma_channel(rtd->acp_mmio,
+ ch_acp_i2s,
+ rtd->dma_dscr_idx_2,
+ NUM_DSCRS_PER_CHANNEL, 0);
+ return 0;
+}
+
+static int acp_dma_trigger(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, int cmd)
+{
+ int ret;
+
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct audio_substream_data *rtd = runtime->private_data;
+
+ if (!rtd)
+ return -EINVAL;
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ rtd->bytescount = acp_get_byte_count(rtd);
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ if (rtd->capture_channel == CAP_CHANNEL0) {
+ acp_dma_cap_channel_disable(rtd->acp_mmio,
+ CAP_CHANNEL1);
+ acp_dma_cap_channel_enable(rtd->acp_mmio,
+ CAP_CHANNEL0);
+ }
+ if (rtd->capture_channel == CAP_CHANNEL1) {
+ acp_dma_cap_channel_disable(rtd->acp_mmio,
+ CAP_CHANNEL0);
+ acp_dma_cap_channel_enable(rtd->acp_mmio,
+ CAP_CHANNEL1);
+ }
+ acp_dma_start(rtd->acp_mmio, rtd->ch1, true);
+ } else {
+ acp_dma_start(rtd->acp_mmio, rtd->ch1, true);
+ acp_dma_start(rtd->acp_mmio, rtd->ch2, true);
+ }
+ ret = 0;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ acp_dma_stop(rtd->acp_mmio, rtd->ch2);
+ ret = acp_dma_stop(rtd->acp_mmio, rtd->ch1);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static int acp_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct audio_drv_data *adata = dev_get_drvdata(component->dev);
+ struct device *parent = component->dev->parent;
+
+ switch (adata->asic_type) {
+ case CHIP_STONEY:
+ snd_pcm_set_managed_buffer_all(rtd->pcm,
+ SNDRV_DMA_TYPE_DEV,
+ parent,
+ ST_MIN_BUFFER,
+ ST_MAX_BUFFER);
+ break;
+ default:
+ snd_pcm_set_managed_buffer_all(rtd->pcm,
+ SNDRV_DMA_TYPE_DEV,
+ parent,
+ MIN_BUFFER,
+ MAX_BUFFER);
+ break;
+ }
+ return 0;
+}
+
+static int acp_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ u16 bank;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct audio_substream_data *rtd = runtime->private_data;
+ struct audio_drv_data *adata = dev_get_drvdata(component->dev);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ adata->play_i2sbt_stream = NULL;
+ break;
+ case I2S_MICSP_INSTANCE:
+ adata->play_i2s_micsp_stream = NULL;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->play_i2ssp_stream = NULL;
+ /*
+ * For Stoney, Memory gating is disabled,i.e SRAM Banks
+ * won't be turned off. The default state for SRAM banks
+ * is ON.Setting SRAM bank state code skipped for STONEY
+ * platform. Added condition checks for Carrizo platform
+ * only.
+ */
+ if (adata->asic_type != CHIP_STONEY) {
+ for (bank = 1; bank <= 4; bank++)
+ acp_set_sram_bank_state(adata->acp_mmio,
+ bank, false);
+ }
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ adata->capture_i2sbt_stream = NULL;
+ break;
+ case I2S_MICSP_INSTANCE:
+ case I2S_SP_INSTANCE:
+ default:
+ adata->capture_i2ssp_stream = NULL;
+ if (adata->asic_type != CHIP_STONEY) {
+ for (bank = 5; bank <= 8; bank++)
+ acp_set_sram_bank_state(adata->acp_mmio,
+ bank, false);
+ }
+ }
+ }
+
+ /*
+ * Disable ACP irq, when the current stream is being closed and
+ * another stream is also not active.
+ */
+ if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream &&
+ !adata->play_i2sbt_stream && !adata->capture_i2sbt_stream &&
+ !adata->play_i2s_micsp_stream)
+ acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
+ kfree(rtd);
+ return 0;
+}
+
+static const struct snd_soc_component_driver acp_asoc_platform = {
+ .name = DRV_NAME,
+ .open = acp_dma_open,
+ .close = acp_dma_close,
+ .hw_params = acp_dma_hw_params,
+ .trigger = acp_dma_trigger,
+ .pointer = acp_dma_pointer,
+ .delay = acp_dma_delay,
+ .prepare = acp_dma_prepare,
+ .pcm_construct = acp_dma_new,
+};
+
+static int acp_audio_probe(struct platform_device *pdev)
+{
+ int status, irq;
+ struct audio_drv_data *audio_drv_data;
+ const u32 *pdata = pdev->dev.platform_data;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "Missing platform data\n");
+ return -ENODEV;
+ }
+
+ audio_drv_data = devm_kzalloc(&pdev->dev, sizeof(struct audio_drv_data),
+ GFP_KERNEL);
+ if (!audio_drv_data)
+ return -ENOMEM;
+
+ audio_drv_data->acp_mmio = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(audio_drv_data->acp_mmio))
+ return PTR_ERR(audio_drv_data->acp_mmio);
+
+ /*
+ * The following members gets populated in device 'open'
+ * function. Till then interrupts are disabled in 'acp_init'
+ * and device doesn't generate any interrupts.
+ */
+
+ audio_drv_data->play_i2ssp_stream = NULL;
+ audio_drv_data->capture_i2ssp_stream = NULL;
+ audio_drv_data->play_i2sbt_stream = NULL;
+ audio_drv_data->capture_i2sbt_stream = NULL;
+ audio_drv_data->play_i2s_micsp_stream = NULL;
+
+ audio_drv_data->asic_type = *pdata;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return -ENODEV;
+
+ status = devm_request_irq(&pdev->dev, irq, dma_irq_handler,
+ 0, "ACP_IRQ", &pdev->dev);
+ if (status) {
+ dev_err(&pdev->dev, "ACP IRQ request failed\n");
+ return status;
+ }
+
+ dev_set_drvdata(&pdev->dev, audio_drv_data);
+
+ /* Initialize the ACP */
+ status = acp_init(audio_drv_data->acp_mmio, audio_drv_data->asic_type);
+ if (status) {
+ dev_err(&pdev->dev, "ACP Init failed status:%d\n", status);
+ return status;
+ }
+
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp_asoc_platform, NULL, 0);
+ if (status != 0) {
+ dev_err(&pdev->dev, "Fail to register ALSA platform device\n");
+ return status;
+ }
+
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 10000);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+ return status;
+}
+
+static void acp_audio_remove(struct platform_device *pdev)
+{
+ int status;
+ struct audio_drv_data *adata = dev_get_drvdata(&pdev->dev);
+
+ status = acp_deinit(adata->acp_mmio);
+ if (status)
+ dev_err(&pdev->dev, "ACP Deinit failed status:%d\n", status);
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int acp_pcm_resume(struct device *dev)
+{
+ u16 bank;
+ int status;
+ struct audio_substream_data *rtd;
+ struct audio_drv_data *adata = dev_get_drvdata(dev);
+
+ status = acp_init(adata->acp_mmio, adata->asic_type);
+ if (status) {
+ dev_err(dev, "ACP Init failed status:%d\n", status);
+ return status;
+ }
+
+ if (adata->play_i2ssp_stream && adata->play_i2ssp_stream->runtime) {
+ /*
+ * For Stoney, Memory gating is disabled,i.e SRAM Banks
+ * won't be turned off. The default state for SRAM banks is ON.
+ * Setting SRAM bank state code skipped for STONEY platform.
+ */
+ if (adata->asic_type != CHIP_STONEY) {
+ for (bank = 1; bank <= 4; bank++)
+ acp_set_sram_bank_state(adata->acp_mmio, bank,
+ true);
+ }
+ rtd = adata->play_i2ssp_stream->runtime->private_data;
+ config_acp_dma(adata->acp_mmio, rtd, adata->asic_type);
+ }
+ if (adata->capture_i2ssp_stream &&
+ adata->capture_i2ssp_stream->runtime) {
+ if (adata->asic_type != CHIP_STONEY) {
+ for (bank = 5; bank <= 8; bank++)
+ acp_set_sram_bank_state(adata->acp_mmio, bank,
+ true);
+ }
+ rtd = adata->capture_i2ssp_stream->runtime->private_data;
+ config_acp_dma(adata->acp_mmio, rtd, adata->asic_type);
+ }
+ if (adata->asic_type != CHIP_CARRIZO) {
+ if (adata->play_i2s_micsp_stream &&
+ adata->play_i2s_micsp_stream->runtime) {
+ rtd = adata->play_i2s_micsp_stream->runtime->private_data;
+ config_acp_dma(adata->acp_mmio, rtd, adata->asic_type);
+ }
+ if (adata->play_i2sbt_stream &&
+ adata->play_i2sbt_stream->runtime) {
+ rtd = adata->play_i2sbt_stream->runtime->private_data;
+ config_acp_dma(adata->acp_mmio, rtd, adata->asic_type);
+ }
+ if (adata->capture_i2sbt_stream &&
+ adata->capture_i2sbt_stream->runtime) {
+ rtd = adata->capture_i2sbt_stream->runtime->private_data;
+ config_acp_dma(adata->acp_mmio, rtd, adata->asic_type);
+ }
+ }
+ acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static int acp_pcm_runtime_suspend(struct device *dev)
+{
+ int status;
+ struct audio_drv_data *adata = dev_get_drvdata(dev);
+
+ status = acp_deinit(adata->acp_mmio);
+ if (status)
+ dev_err(dev, "ACP Deinit failed status:%d\n", status);
+ acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static int acp_pcm_runtime_resume(struct device *dev)
+{
+ int status;
+ struct audio_drv_data *adata = dev_get_drvdata(dev);
+
+ status = acp_init(adata->acp_mmio, adata->asic_type);
+ if (status) {
+ dev_err(dev, "ACP Init failed status:%d\n", status);
+ return status;
+ }
+ acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static const struct dev_pm_ops acp_pm_ops = {
+ .resume = acp_pcm_resume,
+ .runtime_suspend = acp_pcm_runtime_suspend,
+ .runtime_resume = acp_pcm_runtime_resume,
+};
+
+static struct platform_driver acp_dma_driver = {
+ .probe = acp_audio_probe,
+ .remove_new = acp_audio_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .pm = &acp_pm_ops,
+ },
+};
+
+module_platform_driver(acp_dma_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
+MODULE_DESCRIPTION("AMD ACP PCM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:"DRV_NAME);
diff --git a/sound/soc/amd/acp-rt5645.c b/sound/soc/amd/acp-rt5645.c
new file mode 100644
index 0000000000..c8ed1e0b1c
--- /dev/null
+++ b/sound/soc/amd/acp-rt5645.c
@@ -0,0 +1,218 @@
+/*
+ * Machine driver for AMD ACP Audio engine using Realtek RT5645 codec
+ *
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * This file is modified from rt288 machine driver
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+
+#include "../codecs/rt5645.h"
+
+#define CZ_PLAT_CLK 24000000
+
+static struct snd_soc_jack cz_jack;
+static struct snd_soc_jack_pin cz_jack_pins[] = {
+ {
+ .pin = "Headphones",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+static int cz_aif1_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT5645_PLL1_S_MCLK,
+ CZ_PLAT_CLK, params_rate(params) * 512);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_PLL1,
+ params_rate(params) * 512, SND_SOC_CLOCK_OUT);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int cz_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret;
+ struct snd_soc_card *card;
+ struct snd_soc_component *codec;
+
+ codec = asoc_rtd_to_codec(rtd, 0)->component;
+ card = rtd->card;
+
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
+ SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &cz_jack,
+ cz_jack_pins,
+ ARRAY_SIZE(cz_jack_pins));
+ if (ret) {
+ dev_err(card->dev, "HP jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ rt5645_set_jack_detect(codec, &cz_jack, &cz_jack, &cz_jack);
+
+ return 0;
+}
+
+static const struct snd_soc_ops cz_aif1_ops = {
+ .hw_params = cz_aif1_hw_params,
+};
+
+SND_SOC_DAILINK_DEF(designware1,
+ DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.1.auto")));
+SND_SOC_DAILINK_DEF(designware2,
+ DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto")));
+
+SND_SOC_DAILINK_DEF(codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5650:00", "rt5645-aif1")));
+
+SND_SOC_DAILINK_DEF(platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.0.auto")));
+
+static struct snd_soc_dai_link cz_dai_rt5650[] = {
+ {
+ .name = "amd-rt5645-play",
+ .stream_name = "RT5645_AIF1",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .init = cz_init,
+ .ops = &cz_aif1_ops,
+ SND_SOC_DAILINK_REG(designware1, codec, platform),
+ },
+ {
+ .name = "amd-rt5645-cap",
+ .stream_name = "RT5645_AIF1",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .ops = &cz_aif1_ops,
+ SND_SOC_DAILINK_REG(designware2, codec, platform),
+ },
+};
+
+static const struct snd_soc_dapm_widget cz_widgets[] = {
+ SND_SOC_DAPM_HP("Headphones", NULL),
+ SND_SOC_DAPM_SPK("Speakers", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Int Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route cz_audio_route[] = {
+ {"Headphones", NULL, "HPOL"},
+ {"Headphones", NULL, "HPOR"},
+ {"RECMIXL", NULL, "Headset Mic"},
+ {"RECMIXR", NULL, "Headset Mic"},
+ {"Speakers", NULL, "SPOL"},
+ {"Speakers", NULL, "SPOR"},
+ {"DMIC L2", NULL, "Int Mic"},
+ {"DMIC R2", NULL, "Int Mic"},
+};
+
+static const struct snd_kcontrol_new cz_mc_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphones"),
+ SOC_DAPM_PIN_SWITCH("Speakers"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Int Mic"),
+};
+
+static struct snd_soc_card cz_card = {
+ .name = "acprt5650",
+ .owner = THIS_MODULE,
+ .dai_link = cz_dai_rt5650,
+ .num_links = ARRAY_SIZE(cz_dai_rt5650),
+ .dapm_widgets = cz_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cz_widgets),
+ .dapm_routes = cz_audio_route,
+ .num_dapm_routes = ARRAY_SIZE(cz_audio_route),
+ .controls = cz_mc_controls,
+ .num_controls = ARRAY_SIZE(cz_mc_controls),
+};
+
+static int cz_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct snd_soc_card *card;
+
+ card = &cz_card;
+ cz_card.dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ ret = devm_snd_soc_register_card(&pdev->dev, &cz_card);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "devm_snd_soc_register_card(%s) failed: %d\n",
+ cz_card.name, ret);
+ return ret;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id cz_audio_acpi_match[] = {
+ { "AMDI1002", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match);
+#endif
+
+static struct platform_driver cz_pcm_driver = {
+ .driver = {
+ .name = "cz-rt5645",
+ .acpi_match_table = ACPI_PTR(cz_audio_acpi_match),
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = cz_probe,
+};
+
+module_platform_driver(cz_pcm_driver);
+
+MODULE_AUTHOR("akshu.agrawal@amd.com");
+MODULE_DESCRIPTION("cz-rt5645 audio support");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h
new file mode 100644
index 0000000000..b29bef90f8
--- /dev/null
+++ b/sound/soc/amd/acp.h
@@ -0,0 +1,223 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ACP_HW_H
+#define __ACP_HW_H
+
+#include "include/acp_2_2_d.h"
+#include "include/acp_2_2_sh_mask.h"
+
+#define ACP_PAGE_SIZE_4K_ENABLE 0x02
+
+#define ACP_PLAYBACK_PTE_OFFSET 10
+#define ACP_CAPTURE_PTE_OFFSET 0
+
+/* Playback and Capture Offset for Stoney */
+#define ACP_ST_PLAYBACK_PTE_OFFSET 0x04
+#define ACP_ST_CAPTURE_PTE_OFFSET 0x00
+#define ACP_ST_BT_PLAYBACK_PTE_OFFSET 0x08
+#define ACP_ST_BT_CAPTURE_PTE_OFFSET 0x0c
+
+#define ACP_GARLIC_CNTL_DEFAULT 0x00000FB4
+#define ACP_ONION_CNTL_DEFAULT 0x00000FB4
+
+#define ACP_PHYSICAL_BASE 0x14000
+
+/*
+ * In case of I2S SP controller instance, Stoney uses SRAM bank 1 for
+ * playback and SRAM Bank 2 for capture where as in case of BT I2S
+ * Instance, Stoney uses SRAM Bank 3 for playback & SRAM Bank 4 will
+ * be used for capture. Carrizo uses I2S SP controller instance. SRAM Banks
+ * 1, 2, 3, 4 will be used for playback & SRAM Banks 5, 6, 7, 8 will be used
+ * for capture scenario.
+ */
+#define ACP_SRAM_BANK_1_ADDRESS 0x4002000
+#define ACP_SRAM_BANK_2_ADDRESS 0x4004000
+#define ACP_SRAM_BANK_3_ADDRESS 0x4006000
+#define ACP_SRAM_BANK_4_ADDRESS 0x4008000
+#define ACP_SRAM_BANK_5_ADDRESS 0x400A000
+
+#define ACP_DMA_RESET_TIME 10000
+#define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF
+#define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF
+#define ACP_DMA_COMPLETE_TIME_OUT_VALUE 0x000000FF
+
+#define ACP_SRAM_BASE_ADDRESS 0x4000000
+#define ACP_DAGB_GRP_SRAM_BASE_ADDRESS 0x4001000
+#define ACP_DAGB_GRP_SRBM_SRAM_BASE_OFFSET 0x1000
+#define ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS 0x00000000
+#define ACP_INTERNAL_APERTURE_WINDOW_4_ADDRESS 0x01800000
+
+#define TO_ACP_I2S_1 0x2
+#define TO_ACP_I2S_2 0x4
+#define TO_BLUETOOTH 0x3
+#define FROM_ACP_I2S_1 0xa
+#define FROM_ACP_I2S_2 0xb
+#define FROM_BLUETOOTH 0xb
+
+#define I2S_SP_INSTANCE 0x01
+#define I2S_BT_INSTANCE 0x02
+#define I2S_MICSP_INSTANCE 0x03
+#define CAP_CHANNEL0 0x00
+#define CAP_CHANNEL1 0x01
+
+#define ACP_TILE_ON_MASK 0x03
+#define ACP_TILE_OFF_MASK 0x02
+#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f
+#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20
+
+#define ACP_TILE_P1_MASK 0x3e
+#define ACP_TILE_P2_MASK 0x3d
+#define ACP_TILE_DSP0_MASK 0x3b
+#define ACP_TILE_DSP1_MASK 0x37
+
+#define ACP_TILE_DSP2_MASK 0x2f
+/* Playback DMA channels */
+#define SYSRAM_TO_ACP_CH_NUM 12
+#define ACP_TO_I2S_DMA_CH_NUM 13
+
+/* Capture DMA channels */
+#define I2S_TO_ACP_DMA_CH_NUM 14
+#define ACP_TO_SYSRAM_CH_NUM 15
+
+/* Playback DMA Channels for I2S BT instance */
+#define SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM 8
+#define ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM 9
+
+/* Capture DMA Channels for I2S BT Instance */
+#define I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM 10
+#define ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM 11
+
+/* Playback DMA channels for I2S MICSP instance */
+#define SYSRAM_TO_ACP_MICSP_INSTANCE_CH_NUM 4
+#define ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM 5
+
+#define NUM_DSCRS_PER_CHANNEL 2
+
+#define PLAYBACK_START_DMA_DESCR_CH12 0
+#define PLAYBACK_END_DMA_DESCR_CH12 1
+#define PLAYBACK_START_DMA_DESCR_CH13 2
+#define PLAYBACK_END_DMA_DESCR_CH13 3
+
+#define CAPTURE_START_DMA_DESCR_CH14 4
+#define CAPTURE_END_DMA_DESCR_CH14 5
+#define CAPTURE_START_DMA_DESCR_CH15 6
+#define CAPTURE_END_DMA_DESCR_CH15 7
+
+/* I2S BT Instance DMA Descriptors */
+#define PLAYBACK_START_DMA_DESCR_CH8 8
+#define PLAYBACK_END_DMA_DESCR_CH8 9
+#define PLAYBACK_START_DMA_DESCR_CH9 10
+#define PLAYBACK_END_DMA_DESCR_CH9 11
+
+#define CAPTURE_START_DMA_DESCR_CH10 12
+#define CAPTURE_END_DMA_DESCR_CH10 13
+#define CAPTURE_START_DMA_DESCR_CH11 14
+#define CAPTURE_END_DMA_DESCR_CH11 15
+
+/* I2S MICSP Instance DMA Descriptors */
+#define PLAYBACK_START_DMA_DESCR_CH4 0
+#define PLAYBACK_END_DMA_DESCR_CH4 1
+#define PLAYBACK_START_DMA_DESCR_CH5 2
+#define PLAYBACK_END_DMA_DESCR_CH5 3
+
+#define mmACP_I2S_16BIT_RESOLUTION_EN 0x5209
+#define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01
+#define ACP_I2S_MICSP_16BIT_RESOLUTION_EN 0x01
+#define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02
+#define ACP_I2S_BT_16BIT_RESOLUTION_EN 0x04
+#define ACP_BT_UART_PAD_SELECT_MASK 0x1
+
+enum acp_dma_priority_level {
+ /* 0x0 Specifies the DMA channel is given normal priority */
+ ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0,
+ /* 0x1 Specifies the DMA channel is given high priority */
+ ACP_DMA_PRIORITY_LEVEL_HIGH = 0x1,
+ ACP_DMA_PRIORITY_LEVEL_FORCESIZE = 0xFF
+};
+
+struct audio_substream_data {
+ dma_addr_t dma_addr;
+ unsigned int order;
+ u16 num_of_pages;
+ u16 i2s_instance;
+ u16 capture_channel;
+ u16 direction;
+ u16 ch1;
+ u16 ch2;
+ u16 destination;
+ u16 dma_dscr_idx_1;
+ u16 dma_dscr_idx_2;
+ u32 pte_offset;
+ u32 sram_bank;
+ u32 byte_cnt_high_reg_offset;
+ u32 byte_cnt_low_reg_offset;
+ u32 dma_curr_dscr;
+ uint64_t size;
+ u64 bytescount;
+ void __iomem *acp_mmio;
+};
+
+struct audio_drv_data {
+ struct snd_pcm_substream *play_i2ssp_stream;
+ struct snd_pcm_substream *capture_i2ssp_stream;
+ struct snd_pcm_substream *play_i2sbt_stream;
+ struct snd_pcm_substream *capture_i2sbt_stream;
+ struct snd_pcm_substream *play_i2s_micsp_stream;
+ void __iomem *acp_mmio;
+ u32 asic_type;
+ snd_pcm_sframes_t delay;
+};
+
+/*
+ * this structure used for platform data transfer between machine driver
+ * and dma driver
+ */
+struct acp_platform_info {
+ u16 play_i2s_instance;
+ u16 cap_i2s_instance;
+ u16 capture_channel;
+};
+
+union acp_dma_count {
+ struct {
+ u32 low;
+ u32 high;
+ } bcount;
+ u64 bytescount;
+};
+
+enum {
+ ACP_TILE_P1 = 0,
+ ACP_TILE_P2,
+ ACP_TILE_DSP0,
+ ACP_TILE_DSP1,
+ ACP_TILE_DSP2,
+};
+
+enum {
+ ACP_DMA_ATTR_SHAREDMEM_TO_DAGB_ONION = 0x0,
+ ACP_DMA_ATTR_SHARED_MEM_TO_DAGB_GARLIC = 0x1,
+ ACP_DMA_ATTR_DAGB_ONION_TO_SHAREDMEM = 0x8,
+ ACP_DMA_ATTR_DAGB_GARLIC_TO_SHAREDMEM = 0x9,
+ ACP_DMA_ATTR_FORCE_SIZE = 0xF
+};
+
+typedef struct acp_dma_dscr_transfer {
+ /* Specifies the source memory location for the DMA data transfer. */
+ u32 src;
+ /*
+ * Specifies the destination memory location to where the data will
+ * be transferred.
+ */
+ u32 dest;
+ /*
+ * Specifies the number of bytes need to be transferred
+ * from source to destination memory.Transfer direction & IOC enable
+ */
+ u32 xfer_val;
+ /* Reserved for future use */
+ u32 reserved;
+} acp_dma_dscr_transfer_t;
+
+extern bool acp_bt_uart_enable;
+
+#endif /*__ACP_HW_H */
diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig
new file mode 100644
index 0000000000..631cdf96d6
--- /dev/null
+++ b/sound/soc/amd/acp/Kconfig
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+# This file is provided under a dual BSD/GPLv2 license. When using or
+# redistributing this file, you may do so under either license.
+#
+# Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
+#
+
+config SND_SOC_AMD_ACP_COMMON
+ tristate "AMD Audio ACP Common support"
+ select SND_AMD_ACP_CONFIG
+ depends on X86 && PCI
+ help
+ This option enables common modules for Audio-Coprocessor i.e. ACP
+ IP block on AMD platforms.
+
+if SND_SOC_AMD_ACP_COMMON
+
+config SND_SOC_AMD_ACP_PDM
+ tristate
+
+config SND_SOC_AMD_ACP_LEGACY_COMMON
+ tristate
+
+config SND_SOC_AMD_ACP_I2S
+ tristate
+
+config SND_SOC_AMD_ACP_PCM
+ tristate
+ select SND_SOC_ACPI if ACPI
+
+config SND_SOC_AMD_ACP_PCI
+ tristate "AMD ACP PCI Driver Support"
+ select SND_SOC_AMD_ACP_LEGACY_COMMON
+ depends on X86 && PCI
+ help
+ This options enables generic PCI driver for ACP device.
+
+config SND_AMD_ASOC_RENOIR
+ tristate "AMD ACP ASOC Renoir Support"
+ select SND_SOC_AMD_ACP_PCM
+ select SND_SOC_AMD_ACP_I2S
+ select SND_SOC_AMD_ACP_PDM
+ select SND_SOC_AMD_ACP_LEGACY_COMMON
+ depends on X86 && PCI
+ help
+ This option enables Renoir I2S support on AMD platform.
+
+config SND_AMD_ASOC_REMBRANDT
+ tristate "AMD ACP ASOC Rembrandt Support"
+ select SND_SOC_AMD_ACP_PCM
+ select SND_SOC_AMD_ACP_I2S
+ select SND_SOC_AMD_ACP_PDM
+ select SND_SOC_AMD_ACP_LEGACY_COMMON
+ depends on X86 && PCI
+ help
+ This option enables Rembrandt I2S support on AMD platform.
+ Say Y if you want to enable AUDIO on Rembrandt
+ If unsure select "N".
+
+config SND_SOC_AMD_MACH_COMMON
+ tristate
+ depends on X86 && PCI && I2C
+ select CLK_FIXED_FCH
+ select SND_SOC_RT5682_I2C
+ select SND_SOC_DMIC
+ select SND_SOC_RT1019
+ select SND_SOC_MAX98357A
+ select SND_SOC_RT5682S
+ select SND_SOC_NAU8825
+ select SND_SOC_NAU8821
+ select SND_SOC_MAX98388
+ help
+ This option enables common Machine driver module for ACP.
+
+config SND_SOC_AMD_LEGACY_MACH
+ tristate "AMD Legacy Machine Driver Support"
+ depends on X86 && PCI && I2C
+ select SND_SOC_AMD_MACH_COMMON
+ help
+ This option enables legacy sound card support for ACP audio.
+
+config SND_SOC_AMD_SOF_MACH
+ tristate "AMD SOF Machine Driver Support"
+ depends on X86 && PCI && I2C
+ select SND_SOC_AMD_MACH_COMMON
+ help
+ This option enables SOF sound card support for ACP audio.
+
+endif # SND_SOC_AMD_ACP_COMMON
diff --git a/sound/soc/amd/acp/Makefile b/sound/soc/amd/acp/Makefile
new file mode 100644
index 0000000000..4e65fdbc8d
--- /dev/null
+++ b/sound/soc/amd/acp/Makefile
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+# This file is provided under a dual BSD/GPLv2 license. When using or
+# redistributing this file, you may do so under either license.
+#
+# Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
+
+#common acp driver
+snd-acp-pcm-objs := acp-platform.o
+snd-acp-i2s-objs := acp-i2s.o
+snd-acp-pdm-objs := acp-pdm.o
+snd-acp-legacy-common-objs := acp-legacy-common.o
+snd-acp-pci-objs := acp-pci.o
+
+#platform specific driver
+snd-acp-renoir-objs := acp-renoir.o
+snd-acp-rembrandt-objs := acp-rembrandt.o
+
+#machine specific driver
+snd-acp-mach-objs := acp-mach-common.o
+snd-acp-legacy-mach-objs := acp-legacy-mach.o
+snd-acp-sof-mach-objs := acp-sof-mach.o
+
+obj-$(CONFIG_SND_SOC_AMD_ACP_PCM) += snd-acp-pcm.o
+obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o
+obj-$(CONFIG_SND_SOC_AMD_ACP_PDM) += snd-acp-pdm.o
+obj-$(CONFIG_SND_SOC_AMD_ACP_LEGACY_COMMON) += snd-acp-legacy-common.o
+obj-$(CONFIG_SND_SOC_AMD_ACP_PCI) += snd-acp-pci.o
+
+obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o
+obj-$(CONFIG_SND_AMD_ASOC_REMBRANDT) += snd-acp-rembrandt.o
+
+obj-$(CONFIG_SND_SOC_AMD_MACH_COMMON) += snd-acp-mach.o
+obj-$(CONFIG_SND_SOC_AMD_LEGACY_MACH) += snd-acp-legacy-mach.o
+obj-$(CONFIG_SND_SOC_AMD_SOF_MACH) += snd-acp-sof-mach.o
diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c
new file mode 100644
index 0000000000..df35001496
--- /dev/null
+++ b/sound/soc/amd/acp/acp-i2s.c
@@ -0,0 +1,575 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2021 Advanced Micro Devices, Inc.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+//
+
+/*
+ * Generic Hardware interface for ACP Audio I2S controller
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/dma-mapping.h>
+
+#include "amd.h"
+
+#define DRV_NAME "acp_i2s_playcap"
+
+static int acp_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
+ unsigned int fmt)
+{
+ struct acp_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai);
+ int mode;
+
+ mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+ switch (mode) {
+ case SND_SOC_DAIFMT_I2S:
+ adata->tdm_mode = TDM_DISABLE;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ adata->tdm_mode = TDM_ENABLE;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mask,
+ int slots, int slot_width)
+{
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = snd_soc_dai_get_drvdata(dai);
+ struct acp_stream *stream;
+ int slot_len, no_of_slots;
+
+ switch (slot_width) {
+ case SLOT_WIDTH_8:
+ slot_len = 8;
+ break;
+ case SLOT_WIDTH_16:
+ slot_len = 16;
+ break;
+ case SLOT_WIDTH_24:
+ slot_len = 24;
+ break;
+ case SLOT_WIDTH_32:
+ slot_len = 0;
+ break;
+ default:
+ dev_err(dev, "Unsupported bitdepth %d\n", slot_width);
+ return -EINVAL;
+ }
+
+ switch (slots) {
+ case 1 ... 7:
+ no_of_slots = slots;
+ break;
+ case 8:
+ no_of_slots = 0;
+ break;
+ default:
+ dev_err(dev, "Unsupported slots %d\n", slots);
+ return -EINVAL;
+ }
+
+ slots = no_of_slots;
+
+ spin_lock_irq(&adata->acp_lock);
+ list_for_each_entry(stream, &adata->stream_list, list) {
+ if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
+ adata->tdm_tx_fmt[stream->dai_id - 1] =
+ FRM_LEN | (slots << 15) | (slot_len << 18);
+ else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE)
+ adata->tdm_rx_fmt[stream->dai_id - 1] =
+ FRM_LEN | (slots << 15) | (slot_len << 18);
+ }
+ spin_unlock_irq(&adata->acp_lock);
+ return 0;
+}
+
+static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata;
+ struct acp_resource *rsrc;
+ u32 val;
+ u32 xfer_resolution;
+ u32 reg_val, fmt_reg, tdm_fmt;
+ u32 lrclk_div_val, bclk_div_val;
+
+ adata = snd_soc_dai_get_drvdata(dai);
+ rsrc = adata->rsrc;
+
+ /* These values are as per Hardware Spec */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_S8:
+ xfer_resolution = 0x0;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ xfer_resolution = 0x02;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ xfer_resolution = 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ xfer_resolution = 0x05;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (dai->driver->id) {
+ case I2S_BT_INSTANCE:
+ reg_val = ACP_BTTDM_ITER;
+ fmt_reg = ACP_BTTDM_TXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ reg_val = ACP_I2STDM_ITER;
+ fmt_reg = ACP_I2STDM_TXFRMT;
+ break;
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_ITER;
+ fmt_reg = ACP_HSTDM_TXFRMT;
+ break;
+ default:
+ dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
+ return -EINVAL;
+ }
+ adata->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution;
+ } else {
+ switch (dai->driver->id) {
+ case I2S_BT_INSTANCE:
+ reg_val = ACP_BTTDM_IRER;
+ fmt_reg = ACP_BTTDM_RXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ reg_val = ACP_I2STDM_IRER;
+ fmt_reg = ACP_I2STDM_RXFRMT;
+ break;
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_IRER;
+ fmt_reg = ACP_HSTDM_RXFRMT;
+ break;
+ default:
+ dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
+ return -EINVAL;
+ }
+ adata->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution;
+ }
+
+ val = readl(adata->acp_base + reg_val);
+ val &= ~ACP3x_ITER_IRER_SAMP_LEN_MASK;
+ val = val | (xfer_resolution << 3);
+ writel(val, adata->acp_base + reg_val);
+
+ if (adata->tdm_mode) {
+ val = readl(adata->acp_base + reg_val);
+ writel(val | BIT(1), adata->acp_base + reg_val);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ tdm_fmt = adata->tdm_tx_fmt[dai->driver->id - 1];
+ else
+ tdm_fmt = adata->tdm_rx_fmt[dai->driver->id - 1];
+ writel(tdm_fmt, adata->acp_base + fmt_reg);
+ }
+
+ if (rsrc->soc_mclk) {
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ switch (params_rate(params)) {
+ case 8000:
+ bclk_div_val = 768;
+ break;
+ case 16000:
+ bclk_div_val = 384;
+ break;
+ case 24000:
+ bclk_div_val = 256;
+ break;
+ case 32000:
+ bclk_div_val = 192;
+ break;
+ case 44100:
+ case 48000:
+ bclk_div_val = 128;
+ break;
+ case 88200:
+ case 96000:
+ bclk_div_val = 64;
+ break;
+ case 192000:
+ bclk_div_val = 32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ lrclk_div_val = 32;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ switch (params_rate(params)) {
+ case 8000:
+ bclk_div_val = 384;
+ break;
+ case 16000:
+ bclk_div_val = 192;
+ break;
+ case 24000:
+ bclk_div_val = 128;
+ break;
+ case 32000:
+ bclk_div_val = 96;
+ break;
+ case 44100:
+ case 48000:
+ bclk_div_val = 64;
+ break;
+ case 88200:
+ case 96000:
+ bclk_div_val = 32;
+ break;
+ case 192000:
+ bclk_div_val = 16;
+ break;
+ default:
+ return -EINVAL;
+ }
+ lrclk_div_val = 64;
+ break;
+ default:
+ return -EINVAL;
+ }
+ adata->lrclk_div = lrclk_div_val;
+ adata->bclk_div = bclk_div_val;
+ }
+ return 0;
+}
+
+static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
+{
+ struct acp_stream *stream = substream->runtime->private_data;
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct acp_resource *rsrc = adata->rsrc;
+ u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg;
+
+ period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size);
+ buf_size = frames_to_bytes(substream->runtime, substream->runtime->buffer_size);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ stream->bytescount = acp_get_byte_count(adata, stream->dai_id, substream->stream);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (dai->driver->id) {
+ case I2S_BT_INSTANCE:
+ water_val = ACP_BT_TX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_BTTDM_ITER;
+ ier_val = ACP_BTTDM_IER;
+ buf_reg = ACP_BT_TX_RINGBUFSIZE;
+ break;
+ case I2S_SP_INSTANCE:
+ water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_I2STDM_ITER;
+ ier_val = ACP_I2STDM_IER;
+ buf_reg = ACP_I2S_TX_RINGBUFSIZE;
+ break;
+ case I2S_HS_INSTANCE:
+ water_val = ACP_HS_TX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_HSTDM_ITER;
+ ier_val = ACP_HSTDM_IER;
+ buf_reg = ACP_HS_TX_RINGBUFSIZE;
+ break;
+ default:
+ dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
+ return -EINVAL;
+ }
+ } else {
+ switch (dai->driver->id) {
+ case I2S_BT_INSTANCE:
+ water_val = ACP_BT_RX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_BTTDM_IRER;
+ ier_val = ACP_BTTDM_IER;
+ buf_reg = ACP_BT_RX_RINGBUFSIZE;
+ break;
+ case I2S_SP_INSTANCE:
+ water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_I2STDM_IRER;
+ ier_val = ACP_I2STDM_IER;
+ buf_reg = ACP_I2S_RX_RINGBUFSIZE;
+ break;
+ case I2S_HS_INSTANCE:
+ water_val = ACP_HS_RX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_HSTDM_IRER;
+ ier_val = ACP_HSTDM_IER;
+ buf_reg = ACP_HS_RX_RINGBUFSIZE;
+ break;
+ default:
+ dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
+ return -EINVAL;
+ }
+ }
+ writel(period_bytes, adata->acp_base + water_val);
+ writel(buf_size, adata->acp_base + buf_reg);
+ val = readl(adata->acp_base + reg_val);
+ val = val | BIT(0);
+ writel(val, adata->acp_base + reg_val);
+ writel(1, adata->acp_base + ier_val);
+ if (rsrc->soc_mclk)
+ acp_set_i2s_clk(adata, dai->driver->id);
+ return 0;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (dai->driver->id) {
+ case I2S_BT_INSTANCE:
+ reg_val = ACP_BTTDM_ITER;
+ break;
+ case I2S_SP_INSTANCE:
+ reg_val = ACP_I2STDM_ITER;
+ break;
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_ITER;
+ break;
+ default:
+ dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
+ return -EINVAL;
+ }
+
+ } else {
+ switch (dai->driver->id) {
+ case I2S_BT_INSTANCE:
+ reg_val = ACP_BTTDM_IRER;
+ break;
+ case I2S_SP_INSTANCE:
+ reg_val = ACP_I2STDM_IRER;
+ break;
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_IRER;
+ break;
+ default:
+ dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
+ return -EINVAL;
+ }
+ }
+ val = readl(adata->acp_base + reg_val);
+ val = val & ~BIT(0);
+ writel(val, adata->acp_base + reg_val);
+
+ if (!(readl(adata->acp_base + ACP_BTTDM_ITER) & BIT(0)) &&
+ !(readl(adata->acp_base + ACP_BTTDM_IRER) & BIT(0)))
+ writel(0, adata->acp_base + ACP_BTTDM_IER);
+ if (!(readl(adata->acp_base + ACP_I2STDM_ITER) & BIT(0)) &&
+ !(readl(adata->acp_base + ACP_I2STDM_IRER) & BIT(0)))
+ writel(0, adata->acp_base + ACP_I2STDM_IER);
+ if (!(readl(adata->acp_base + ACP_HSTDM_ITER) & BIT(0)) &&
+ !(readl(adata->acp_base + ACP_HSTDM_IRER) & BIT(0)))
+ writel(0, adata->acp_base + ACP_HSTDM_IER);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct acp_resource *rsrc = adata->rsrc;
+ struct acp_stream *stream = substream->runtime->private_data;
+ u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0;
+ u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl;
+ unsigned int dir = substream->stream;
+
+ switch (dai->driver->id) {
+ case I2S_SP_INSTANCE:
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ reg_dma_size = ACP_I2S_TX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ SP_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_I2S_TX_FIFOADDR;
+ reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
+
+ phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR);
+ } else {
+ reg_dma_size = ACP_I2S_RX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ SP_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
+ reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
+ phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR);
+ }
+ break;
+ case I2S_BT_INSTANCE:
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ reg_dma_size = ACP_BT_TX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ BT_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_BT_TX_FIFOADDR;
+ reg_fifo_size = ACP_BT_TX_FIFOSIZE;
+
+ phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR);
+ } else {
+ reg_dma_size = ACP_BT_RX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ BT_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_BT_RX_FIFOADDR;
+ reg_fifo_size = ACP_BT_RX_FIFOSIZE;
+
+ phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR);
+ }
+ break;
+ case I2S_HS_INSTANCE:
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ reg_dma_size = ACP_HS_TX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ HS_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_HS_TX_FIFOADDR;
+ reg_fifo_size = ACP_HS_TX_FIFOSIZE;
+
+ phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR);
+ } else {
+ reg_dma_size = ACP_HS_RX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ HS_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_HS_RX_FIFOADDR;
+ reg_fifo_size = ACP_HS_RX_FIFOSIZE;
+
+ phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR);
+ }
+ break;
+ default:
+ dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
+ return -EINVAL;
+ }
+
+ writel(DMA_SIZE, adata->acp_base + reg_dma_size);
+ writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
+ writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);
+
+ ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+ ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
+ BIT(BT_RX_THRESHOLD(rsrc->offset)) |
+ BIT(I2S_TX_THRESHOLD(rsrc->offset)) |
+ BIT(BT_TX_THRESHOLD(rsrc->offset)) |
+ BIT(HS_RX_THRESHOLD(rsrc->offset)) |
+ BIT(HS_TX_THRESHOLD(rsrc->offset));
+
+ writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+
+ return 0;
+}
+
+static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct acp_stream *stream = substream->runtime->private_data;
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct acp_resource *rsrc = adata->rsrc;
+ unsigned int dir = substream->stream;
+ unsigned int irq_bit = 0;
+
+ switch (dai->driver->id) {
+ case I2S_SP_INSTANCE:
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ irq_bit = BIT(I2S_TX_THRESHOLD(rsrc->offset));
+ stream->pte_offset = ACP_SRAM_SP_PB_PTE_OFFSET;
+ stream->fifo_offset = SP_PB_FIFO_ADDR_OFFSET;
+ } else {
+ irq_bit = BIT(I2S_RX_THRESHOLD(rsrc->offset));
+ stream->pte_offset = ACP_SRAM_SP_CP_PTE_OFFSET;
+ stream->fifo_offset = SP_CAPT_FIFO_ADDR_OFFSET;
+ }
+ break;
+ case I2S_BT_INSTANCE:
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ irq_bit = BIT(BT_TX_THRESHOLD(rsrc->offset));
+ stream->pte_offset = ACP_SRAM_BT_PB_PTE_OFFSET;
+ stream->fifo_offset = BT_PB_FIFO_ADDR_OFFSET;
+ } else {
+ irq_bit = BIT(BT_RX_THRESHOLD(rsrc->offset));
+ stream->pte_offset = ACP_SRAM_BT_CP_PTE_OFFSET;
+ stream->fifo_offset = BT_CAPT_FIFO_ADDR_OFFSET;
+ }
+ break;
+ case I2S_HS_INSTANCE:
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ irq_bit = BIT(HS_TX_THRESHOLD(rsrc->offset));
+ stream->pte_offset = ACP_SRAM_HS_PB_PTE_OFFSET;
+ stream->fifo_offset = HS_PB_FIFO_ADDR_OFFSET;
+ } else {
+ irq_bit = BIT(HS_RX_THRESHOLD(rsrc->offset));
+ stream->pte_offset = ACP_SRAM_HS_CP_PTE_OFFSET;
+ stream->fifo_offset = HS_CAPT_FIFO_ADDR_OFFSET;
+ }
+ break;
+ default:
+ dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
+ return -EINVAL;
+ }
+
+ /* Save runtime dai configuration in stream */
+ stream->id = dai->driver->id + dir;
+ stream->dai_id = dai->driver->id;
+ stream->irq_bit = irq_bit;
+ stream->dir = substream->stream;
+
+ return 0;
+}
+
+static int acp_i2s_probe(struct snd_soc_dai *dai)
+{
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct acp_resource *rsrc = adata->rsrc;
+ unsigned int val;
+
+ if (!adata->acp_base) {
+ dev_err(dev, "I2S base is NULL\n");
+ return -EINVAL;
+ }
+
+ val = readl(adata->acp_base + rsrc->i2s_pin_cfg_offset);
+ if (val != rsrc->i2s_mode) {
+ dev_err(dev, "I2S Mode not supported val %x\n", val);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops = {
+ .probe = acp_i2s_probe,
+ .startup = acp_i2s_startup,
+ .hw_params = acp_i2s_hwparams,
+ .prepare = acp_i2s_prepare,
+ .trigger = acp_i2s_trigger,
+ .set_fmt = acp_i2s_set_fmt,
+ .set_tdm_slot = acp_i2s_set_tdm_slot,
+};
+EXPORT_SYMBOL_NS_GPL(asoc_acp_cpu_dai_ops, SND_SOC_ACP_COMMON);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS(DRV_NAME);
diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c
new file mode 100644
index 0000000000..ba58165cc6
--- /dev/null
+++ b/sound/soc/amd/acp/acp-legacy-common.c
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2023 Advanced Micro Devices, Inc.
+//
+// Authors: Syed Saba Kareem <Syed.SabaKareem@amd.com>
+//
+
+/*
+ * Common file to be used by amd platforms
+ */
+
+#include "amd.h"
+#include <linux/pci.h>
+#include <linux/export.h>
+
+void acp_enable_interrupts(struct acp_dev_data *adata)
+{
+ struct acp_resource *rsrc = adata->rsrc;
+ u32 ext_intr_ctrl;
+
+ writel(0x01, ACP_EXTERNAL_INTR_ENB(adata));
+ ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+ ext_intr_ctrl |= ACP_ERROR_MASK;
+ writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+}
+EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, SND_SOC_ACP_COMMON);
+
+void acp_disable_interrupts(struct acp_dev_data *adata)
+{
+ struct acp_resource *rsrc = adata->rsrc;
+
+ writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
+ writel(0x00, ACP_EXTERNAL_INTR_ENB(adata));
+}
+EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, SND_SOC_ACP_COMMON);
+
+static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct acp_stream *stream = runtime->private_data;
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+
+ u32 physical_addr, pdm_size, period_bytes;
+
+ period_bytes = frames_to_bytes(runtime, runtime->period_size);
+ pdm_size = frames_to_bytes(runtime, runtime->buffer_size);
+ physical_addr = stream->reg_offset + MEM_WINDOW_START;
+
+ /* Init ACP PDM Ring buffer */
+ writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR);
+ writel(pdm_size, adata->acp_base + ACP_WOV_RX_RINGBUFSIZE);
+ writel(period_bytes, adata->acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
+ writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
+}
+
+static void set_acp_pdm_clk(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ unsigned int pdm_ctrl;
+
+ /* Enable default ACP PDM clk */
+ writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL);
+ pdm_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL);
+ pdm_ctrl |= PDM_MISC_CTRL_MASK;
+ writel(pdm_ctrl, adata->acp_base + ACP_WOV_MISC_CTRL);
+ set_acp_pdm_ring_buffer(substream, dai);
+}
+
+void restore_acp_pdm_params(struct snd_pcm_substream *substream,
+ struct acp_dev_data *adata)
+{
+ struct snd_soc_dai *dai;
+ struct snd_soc_pcm_runtime *soc_runtime;
+ u32 ext_int_ctrl;
+
+ soc_runtime = asoc_substream_to_rtd(substream);
+ dai = asoc_rtd_to_cpu(soc_runtime, 0);
+ /* Programming channel mask and sampling rate */
+ writel(adata->ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
+ writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR);
+
+ /* Enabling ACP Pdm interuppts */
+ ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
+ ext_int_ctrl |= PDM_DMA_INTR_MASK;
+ writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
+ set_acp_pdm_clk(substream, dai);
+}
+EXPORT_SYMBOL_NS_GPL(restore_acp_pdm_params, SND_SOC_ACP_COMMON);
+
+static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct acp_resource *rsrc = adata->rsrc;
+ struct acp_stream *stream = substream->runtime->private_data;
+ u32 reg_dma_size, reg_fifo_size, reg_fifo_addr;
+ u32 phy_addr, acp_fifo_addr, ext_int_ctrl;
+ unsigned int dir = substream->stream;
+
+ switch (dai->driver->id) {
+ case I2S_SP_INSTANCE:
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ reg_dma_size = ACP_I2S_TX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ SP_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_I2S_TX_FIFOADDR;
+ reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
+ phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR);
+ } else {
+ reg_dma_size = ACP_I2S_RX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ SP_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
+ reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
+ phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR);
+ }
+ break;
+ case I2S_BT_INSTANCE:
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ reg_dma_size = ACP_BT_TX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ BT_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_BT_TX_FIFOADDR;
+ reg_fifo_size = ACP_BT_TX_FIFOSIZE;
+ phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR);
+ } else {
+ reg_dma_size = ACP_BT_RX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ BT_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_BT_RX_FIFOADDR;
+ reg_fifo_size = ACP_BT_RX_FIFOSIZE;
+ phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR);
+ }
+ break;
+ case I2S_HS_INSTANCE:
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ reg_dma_size = ACP_HS_TX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ HS_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_HS_TX_FIFOADDR;
+ reg_fifo_size = ACP_HS_TX_FIFOSIZE;
+ phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR);
+ } else {
+ reg_dma_size = ACP_HS_RX_DMA_SIZE;
+ acp_fifo_addr = rsrc->sram_pte_offset +
+ HS_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_HS_RX_FIFOADDR;
+ reg_fifo_size = ACP_HS_RX_FIFOSIZE;
+ phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset;
+ writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR);
+ }
+ break;
+ default:
+ dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
+ return -EINVAL;
+ }
+
+ writel(DMA_SIZE, adata->acp_base + reg_dma_size);
+ writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
+ writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);
+
+ ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+ ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
+ BIT(BT_RX_THRESHOLD(rsrc->offset)) |
+ BIT(I2S_TX_THRESHOLD(rsrc->offset)) |
+ BIT(BT_TX_THRESHOLD(rsrc->offset)) |
+ BIT(HS_RX_THRESHOLD(rsrc->offset)) |
+ BIT(HS_TX_THRESHOLD(rsrc->offset));
+
+ writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+ return 0;
+}
+
+int restore_acp_i2s_params(struct snd_pcm_substream *substream,
+ struct acp_dev_data *adata,
+ struct acp_stream *stream)
+{
+ struct snd_soc_dai *dai;
+ struct snd_soc_pcm_runtime *soc_runtime;
+ u32 tdm_fmt, reg_val, fmt_reg, val;
+
+ soc_runtime = asoc_substream_to_rtd(substream);
+ dai = asoc_rtd_to_cpu(soc_runtime, 0);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ tdm_fmt = adata->tdm_tx_fmt[stream->dai_id - 1];
+ switch (stream->dai_id) {
+ case I2S_BT_INSTANCE:
+ reg_val = ACP_BTTDM_ITER;
+ fmt_reg = ACP_BTTDM_TXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ reg_val = ACP_I2STDM_ITER;
+ fmt_reg = ACP_I2STDM_TXFRMT;
+ break;
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_ITER;
+ fmt_reg = ACP_HSTDM_TXFRMT;
+ break;
+ default:
+ pr_err("Invalid dai id %x\n", stream->dai_id);
+ return -EINVAL;
+ }
+ val = adata->xfer_tx_resolution[stream->dai_id - 1] << 3;
+ } else {
+ tdm_fmt = adata->tdm_rx_fmt[stream->dai_id - 1];
+ switch (stream->dai_id) {
+ case I2S_BT_INSTANCE:
+ reg_val = ACP_BTTDM_IRER;
+ fmt_reg = ACP_BTTDM_RXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ reg_val = ACP_I2STDM_IRER;
+ fmt_reg = ACP_I2STDM_RXFRMT;
+ break;
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_IRER;
+ fmt_reg = ACP_HSTDM_RXFRMT;
+ break;
+ default:
+ pr_err("Invalid dai id %x\n", stream->dai_id);
+ return -EINVAL;
+ }
+ val = adata->xfer_rx_resolution[stream->dai_id - 1] << 3;
+ }
+ writel(val, adata->acp_base + reg_val);
+ if (adata->tdm_mode == TDM_ENABLE) {
+ writel(tdm_fmt, adata->acp_base + fmt_reg);
+ val = readl(adata->acp_base + reg_val);
+ writel(val | 0x2, adata->acp_base + reg_val);
+ }
+ return set_acp_i2s_dma_fifo(substream, dai);
+}
+EXPORT_SYMBOL_NS_GPL(restore_acp_i2s_params, SND_SOC_ACP_COMMON);
+
+static int acp_power_on(struct acp_chip_info *chip)
+{
+ u32 val, acp_pgfsm_stat_reg, acp_pgfsm_ctrl_reg;
+ void __iomem *base;
+
+ base = chip->base;
+ switch (chip->acp_rev) {
+ case ACP3X_DEV:
+ acp_pgfsm_stat_reg = ACP_PGFSM_STATUS;
+ acp_pgfsm_ctrl_reg = ACP_PGFSM_CONTROL;
+ break;
+ case ACP6X_DEV:
+ acp_pgfsm_stat_reg = ACP6X_PGFSM_STATUS;
+ acp_pgfsm_ctrl_reg = ACP6X_PGFSM_CONTROL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val = readl(base + acp_pgfsm_stat_reg);
+ if (val == ACP_POWERED_ON)
+ return 0;
+
+ if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS)
+ writel(ACP_PGFSM_CNTL_POWER_ON_MASK, base + acp_pgfsm_ctrl_reg);
+
+ return readl_poll_timeout(base + acp_pgfsm_stat_reg, val,
+ !val, DELAY_US, ACP_TIMEOUT);
+}
+
+static int acp_reset(void __iomem *base)
+{
+ u32 val;
+ int ret;
+
+ writel(1, base + ACP_SOFT_RESET);
+ ret = readl_poll_timeout(base + ACP_SOFT_RESET, val, val & ACP_SOFT_RST_DONE_MASK,
+ DELAY_US, ACP_TIMEOUT);
+ if (ret)
+ return ret;
+
+ writel(0, base + ACP_SOFT_RESET);
+ return readl_poll_timeout(base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT);
+}
+
+int acp_init(struct acp_chip_info *chip)
+{
+ int ret;
+
+ /* power on */
+ ret = acp_power_on(chip);
+ if (ret) {
+ pr_err("ACP power on failed\n");
+ return ret;
+ }
+ writel(0x01, chip->base + ACP_CONTROL);
+
+ /* Reset */
+ ret = acp_reset(chip->base);
+ if (ret) {
+ pr_err("ACP reset failed\n");
+ return ret;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(acp_init, SND_SOC_ACP_COMMON);
+
+int acp_deinit(void __iomem *base)
+{
+ int ret;
+
+ /* Reset */
+ ret = acp_reset(base);
+ if (ret)
+ return ret;
+
+ writel(0, base + ACP_CONTROL);
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(acp_deinit, SND_SOC_ACP_COMMON);
+
+int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data)
+{
+ pci_write_config_dword(dev, 0x60, smn_addr);
+ pci_write_config_dword(dev, 0x64, data);
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(smn_write, SND_SOC_ACP_COMMON);
+
+int smn_read(struct pci_dev *dev, u32 smn_addr)
+{
+ u32 data;
+
+ pci_write_config_dword(dev, 0x60, smn_addr);
+ pci_read_config_dword(dev, 0x64, &data);
+ return data;
+}
+EXPORT_SYMBOL_NS_GPL(smn_read, SND_SOC_ACP_COMMON);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/amd/acp/acp-legacy-mach.c b/sound/soc/amd/acp/acp-legacy-mach.c
new file mode 100644
index 0000000000..6d57d17ddf
--- /dev/null
+++ b/sound/soc/amd/acp/acp-legacy-mach.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2021 Advanced Micro Devices, Inc.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+//
+
+/*
+ * Machine Driver Legacy Support for ACP HW block
+ */
+
+#include <sound/core.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-dapm.h>
+#include <linux/dmi.h>
+#include <linux/module.h>
+
+#include "acp-mach.h"
+
+static struct acp_card_drvdata rt5682_rt1019_data = {
+ .hs_cpu_id = I2S_SP,
+ .amp_cpu_id = I2S_SP,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = RT5682,
+ .amp_codec_id = RT1019,
+ .dmic_codec_id = DMIC,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata rt5682s_max_data = {
+ .hs_cpu_id = I2S_SP,
+ .amp_cpu_id = I2S_SP,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = RT5682S,
+ .amp_codec_id = MAX98360A,
+ .dmic_codec_id = DMIC,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata rt5682s_rt1019_data = {
+ .hs_cpu_id = I2S_SP,
+ .amp_cpu_id = I2S_SP,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = RT5682S,
+ .amp_codec_id = RT1019,
+ .dmic_codec_id = DMIC,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata max_nau8825_data = {
+ .hs_cpu_id = I2S_HS,
+ .amp_cpu_id = I2S_HS,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = NAU8825,
+ .amp_codec_id = MAX98360A,
+ .dmic_codec_id = DMIC,
+ .soc_mclk = true,
+ .platform = REMBRANDT,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata rt5682s_rt1019_rmb_data = {
+ .hs_cpu_id = I2S_HS,
+ .amp_cpu_id = I2S_HS,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = RT5682S,
+ .amp_codec_id = RT1019,
+ .dmic_codec_id = DMIC,
+ .soc_mclk = true,
+ .platform = REMBRANDT,
+ .tdm_mode = false,
+};
+
+static int acp_asoc_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = NULL;
+ struct device *dev = &pdev->dev;
+ const struct dmi_system_id *dmi_id;
+ struct acp_card_drvdata *acp_card_drvdata;
+ int ret;
+
+ if (!pdev->id_entry)
+ return -EINVAL;
+
+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+
+ card->dev = dev;
+ card->owner = THIS_MODULE;
+ card->name = pdev->id_entry->name;
+ card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
+ /* Widgets and controls added per-codec in acp-mach-common.c */
+
+ acp_card_drvdata = card->drvdata;
+ dmi_id = dmi_first_match(acp_quirk_table);
+ if (dmi_id && dmi_id->driver_data)
+ acp_card_drvdata->tdm_mode = dmi_id->driver_data;
+
+ acp_legacy_dai_links_create(card);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "devm_snd_soc_register_card(%s) failed: %d\n",
+ card->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id board_ids[] = {
+ {
+ .name = "acp3xalc56821019",
+ .driver_data = (kernel_ulong_t)&rt5682_rt1019_data,
+ },
+ {
+ .name = "acp3xalc5682sm98360",
+ .driver_data = (kernel_ulong_t)&rt5682s_max_data,
+ },
+ {
+ .name = "acp3xalc5682s1019",
+ .driver_data = (kernel_ulong_t)&rt5682s_rt1019_data,
+ },
+ {
+ .name = "rmb-nau8825-max",
+ .driver_data = (kernel_ulong_t)&max_nau8825_data,
+ },
+ {
+ .name = "rmb-rt5682s-rt1019",
+ .driver_data = (kernel_ulong_t)&rt5682s_rt1019_rmb_data,
+ },
+ { }
+};
+static struct platform_driver acp_asoc_audio = {
+ .driver = {
+ .pm = &snd_soc_pm_ops,
+ .name = "acp_mach",
+ },
+ .probe = acp_asoc_probe,
+ .id_table = board_ids,
+};
+
+module_platform_driver(acp_asoc_audio);
+
+MODULE_IMPORT_NS(SND_SOC_AMD_MACH);
+MODULE_DESCRIPTION("ACP chrome audio support");
+MODULE_ALIAS("platform:acp3xalc56821019");
+MODULE_ALIAS("platform:acp3xalc5682sm98360");
+MODULE_ALIAS("platform:acp3xalc5682s1019");
+MODULE_ALIAS("platform:rmb-nau8825-max");
+MODULE_ALIAS("platform:rmb-rt5682s-rt1019");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c
new file mode 100644
index 0000000000..a06af82b80
--- /dev/null
+++ b/sound/soc/amd/acp/acp-mach-common.c
@@ -0,0 +1,1688 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2021 Advanced Micro Devices, Inc.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+// Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+//
+
+/*
+ * Machine Driver Interface for ACP HW block
+ */
+
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <sound/soc.h>
+#include <linux/input.h>
+#include <linux/module.h>
+
+#include "../../codecs/rt5682.h"
+#include "../../codecs/rt1019.h"
+#include "../../codecs/rt5682s.h"
+#include "../../codecs/nau8825.h"
+#include "../../codecs/nau8821.h"
+#include "acp-mach.h"
+
+#define PCO_PLAT_CLK 48000000
+#define RT5682_PLL_FREQ (48000 * 512)
+#define DUAL_CHANNEL 2
+#define FOUR_CHANNEL 4
+#define NAU8821_CODEC_DAI "nau8821-hifi"
+#define NAU8821_BCLK 1536000
+#define NAU8821_FREQ_OUT 12288000
+#define MAX98388_CODEC_DAI "max98388-aif1"
+
+#define TDM_MODE_ENABLE 1
+
+const struct dmi_system_id acp_quirk_table[] = {
+ {
+ /* Google skyrim proto-0 */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_PRODUCT_FAMILY, "Google_Skyrim"),
+ },
+ .driver_data = (void *)TDM_MODE_ENABLE,
+ },
+ {}
+};
+EXPORT_SYMBOL_GPL(acp_quirk_table);
+
+static const unsigned int channels[] = {
+ DUAL_CHANNEL,
+};
+
+static const unsigned int rates[] = {
+ 48000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
+ .count = ARRAY_SIZE(channels),
+ .list = channels,
+ .mask = 0,
+};
+
+static int acp_clk_enable(struct acp_card_drvdata *drvdata,
+ unsigned int srate, unsigned int bclk_ratio)
+{
+ clk_set_rate(drvdata->wclk, srate);
+ clk_set_rate(drvdata->bclk, srate * bclk_ratio);
+
+ return clk_prepare_enable(drvdata->wclk);
+}
+
+/* Declare RT5682 codec components */
+SND_SOC_DAILINK_DEF(rt5682,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
+
+static struct snd_soc_jack rt5682_jack;
+static struct snd_soc_jack_pin rt5682_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+static const struct snd_kcontrol_new rt5682_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static const struct snd_soc_dapm_widget rt5682_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route rt5682_map[] = {
+ { "Headphone Jack", NULL, "HPOL" },
+ { "Headphone Jack", NULL, "HPOR" },
+ { "IN1P", NULL, "Headset Mic" },
+};
+
+/* Define card ops for RT5682 CODEC */
+static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_component *component = codec_dai->component;
+ int ret;
+
+ dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+
+ if (drvdata->hs_codec_id != RT5682)
+ return -EINVAL;
+
+ drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
+ drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, rt5682_widgets,
+ ARRAY_SIZE(rt5682_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, rt5682_controls,
+ ARRAY_SIZE(rt5682_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
+ SND_JACK_HEADSET | SND_JACK_LINEOUT |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &rt5682_jack,
+ rt5682_jack_pins,
+ ARRAY_SIZE(rt5682_jack_pins));
+ if (ret) {
+ dev_err(card->dev, "HP jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+ snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+ snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+ ret = snd_soc_component_set_jack(component, &rt5682_jack, NULL);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
+ return ret;
+ }
+
+ return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682_map, ARRAY_SIZE(rt5682_map));
+}
+
+static int acp_card_hs_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ int ret;
+ unsigned int fmt;
+
+ if (drvdata->tdm_mode)
+ fmt = SND_SOC_DAIFMT_DSP_A;
+ else
+ fmt = SND_SOC_DAIFMT_I2S;
+
+ if (drvdata->soc_mclk)
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
+ else
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0) {
+ dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ return ret;
+}
+
+static void acp_card_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+
+ if (!drvdata->soc_mclk)
+ clk_disable_unprepare(drvdata->wclk);
+}
+
+static int acp_card_rt5682_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ int ret;
+ unsigned int fmt, srate, ch, format;
+
+ srate = params_rate(params);
+ ch = params_channels(params);
+ format = params_physical_width(params);
+
+ if (drvdata->tdm_mode)
+ fmt = SND_SOC_DAIFMT_DSP_A;
+ else
+ fmt = SND_SOC_DAIFMT_I2S;
+
+ if (drvdata->soc_mclk)
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
+ else
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0) {
+ dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ if (drvdata->tdm_mode) {
+ /**
+ * As codec supports slot 0 and slot 1 for playback and capture.
+ */
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);
+ if (ret < 0) {
+ dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
+ PCO_PLAT_CLK, RT5682_PLL_FREQ);
+ if (ret < 0) {
+ dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
+ RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
+ return ret;
+ }
+
+ /* Set tdm/i2s1 master bclk ratio */
+ ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
+ if (ret < 0) {
+ dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
+ return ret;
+ }
+
+ if (!drvdata->soc_mclk) {
+ ret = acp_clk_enable(drvdata, srate, ch * format);
+ if (ret < 0) {
+ dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_ops acp_card_rt5682_ops = {
+ .startup = acp_card_hs_startup,
+ .shutdown = acp_card_shutdown,
+ .hw_params = acp_card_rt5682_hw_params,
+};
+
+/* Define RT5682S CODEC component*/
+SND_SOC_DAILINK_DEF(rt5682s,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1")));
+
+static struct snd_soc_jack rt5682s_jack;
+static struct snd_soc_jack_pin rt5682s_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+static const struct snd_kcontrol_new rt5682s_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static const struct snd_soc_dapm_widget rt5682s_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route rt5682s_map[] = {
+ { "Headphone Jack", NULL, "HPOL" },
+ { "Headphone Jack", NULL, "HPOR" },
+ { "IN1P", NULL, "Headset Mic" },
+};
+
+static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_component *component = codec_dai->component;
+ int ret;
+
+ dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+
+ if (drvdata->hs_codec_id != RT5682S)
+ return -EINVAL;
+
+ if (!drvdata->soc_mclk) {
+ drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
+ drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
+ }
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, rt5682s_widgets,
+ ARRAY_SIZE(rt5682s_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, rt5682s_controls,
+ ARRAY_SIZE(rt5682s_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
+ SND_JACK_HEADSET | SND_JACK_LINEOUT |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &rt5682s_jack,
+ rt5682s_jack_pins,
+ ARRAY_SIZE(rt5682s_jack_pins));
+ if (ret) {
+ dev_err(card->dev, "HP jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+ snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+ snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+ ret = snd_soc_component_set_jack(component, &rt5682s_jack, NULL);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
+ return ret;
+ }
+
+ return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map));
+}
+
+static int acp_card_rt5682s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ int ret;
+ unsigned int fmt, srate, ch, format;
+
+ srate = params_rate(params);
+ ch = params_channels(params);
+ format = params_physical_width(params);
+
+ if (drvdata->tdm_mode)
+ fmt = SND_SOC_DAIFMT_DSP_A;
+ else
+ fmt = SND_SOC_DAIFMT_I2S;
+
+ if (drvdata->soc_mclk)
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
+ else
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0) {
+ dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ if (drvdata->tdm_mode) {
+ /**
+ * As codec supports slot 0 and slot 1 for playback and capture.
+ */
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);
+ if (ret < 0) {
+ dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
+ PCO_PLAT_CLK, RT5682_PLL_FREQ);
+ if (ret < 0) {
+ dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
+ RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
+ return ret;
+ }
+
+ /* Set tdm/i2s1 master bclk ratio */
+ ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
+ if (ret < 0) {
+ dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
+ return ret;
+ }
+
+ clk_set_rate(drvdata->wclk, srate);
+ clk_set_rate(drvdata->bclk, srate * ch * format);
+
+ return 0;
+}
+
+static const struct snd_soc_ops acp_card_rt5682s_ops = {
+ .startup = acp_card_hs_startup,
+ .hw_params = acp_card_rt5682s_hw_params,
+};
+
+static const unsigned int dmic_channels[] = {
+ DUAL_CHANNEL, FOUR_CHANNEL,
+};
+
+static const struct snd_pcm_hw_constraint_list dmic_constraints_channels = {
+ .count = ARRAY_SIZE(dmic_channels),
+ .list = dmic_channels,
+ .mask = 0,
+};
+
+static int acp_card_dmic_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &dmic_constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ return 0;
+}
+
+static const struct snd_soc_ops acp_card_dmic_ops = {
+ .startup = acp_card_dmic_startup,
+};
+
+/* Declare RT1019 codec components */
+SND_SOC_DAILINK_DEF(rt1019,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
+ COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));
+
+static const struct snd_kcontrol_new rt1019_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
+static const struct snd_soc_dapm_widget rt1019_widgets[] = {
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route rt1019_map_lr[] = {
+ { "Left Spk", NULL, "Left SPO" },
+ { "Right Spk", NULL, "Right SPO" },
+};
+
+static struct snd_soc_codec_conf rt1019_conf[] = {
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
+ .name_prefix = "Left",
+ },
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1019:00"),
+ .name_prefix = "Right",
+ },
+};
+
+static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ int ret;
+
+ if (drvdata->amp_codec_id != RT1019)
+ return -EINVAL;
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, rt1019_widgets,
+ ARRAY_SIZE(rt1019_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, rt1019_controls,
+ ARRAY_SIZE(rt1019_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
+ return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr,
+ ARRAY_SIZE(rt1019_map_lr));
+}
+
+static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *codec_dai;
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ int i, ret = 0;
+ unsigned int fmt, srate, ch, format;
+
+ srate = params_rate(params);
+ ch = params_channels(params);
+ format = params_physical_width(params);
+
+ if (drvdata->amp_codec_id != RT1019)
+ return -EINVAL;
+
+ if (drvdata->tdm_mode)
+ fmt = SND_SOC_DAIFMT_DSP_A;
+ else
+ fmt = SND_SOC_DAIFMT_I2S;
+
+ if (drvdata->soc_mclk)
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
+ else
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ if (drvdata->tdm_mode) {
+ /**
+ * As codec supports slot 2 and slot 3 for playback.
+ */
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
+ return ret;
+ }
+ }
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+ if (strcmp(codec_dai->name, "rt1019-aif"))
+ continue;
+
+ if (drvdata->tdm_mode)
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
+ TDM_CHANNELS * format * srate, 256 * srate);
+ else
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
+ ch * format * srate, 256 * srate);
+
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT1019_SCLK_S_PLL,
+ 256 * srate, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ return ret;
+
+ if (drvdata->tdm_mode) {
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A
+ | SND_SOC_DAIFMT_NB_NF);
+ if (ret < 0) {
+ dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ /**
+ * As codec supports slot 2 for left channel playback.
+ */
+ if (!strcmp(codec_dai->component->name, "i2c-10EC1019:00")) {
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x4, 8, 16);
+ if (ret < 0)
+ break;
+ }
+
+ /**
+ * As codec supports slot 3 for right channel playback.
+ */
+ if (!strcmp(codec_dai->component->name, "i2c-10EC1019:01")) {
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x8, 8, 16);
+ if (ret < 0)
+ break;
+ }
+ }
+ }
+
+ if (!drvdata->soc_mclk) {
+ ret = acp_clk_enable(drvdata, srate, ch * format);
+ if (ret < 0) {
+ dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int acp_card_amp_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ return 0;
+}
+
+static const struct snd_soc_ops acp_card_rt1019_ops = {
+ .startup = acp_card_amp_startup,
+ .shutdown = acp_card_shutdown,
+ .hw_params = acp_card_rt1019_hw_params,
+};
+
+/* Declare Maxim codec components */
+SND_SOC_DAILINK_DEF(max98360a,
+ DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi")));
+
+static const struct snd_kcontrol_new max98360a_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Spk"),
+};
+
+static const struct snd_soc_dapm_widget max98360a_widgets[] = {
+ SND_SOC_DAPM_SPK("Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route max98360a_map[] = {
+ {"Spk", NULL, "Speaker"},
+};
+
+static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ int ret;
+
+ if (drvdata->amp_codec_id != MAX98360A)
+ return -EINVAL;
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, max98360a_widgets,
+ ARRAY_SIZE(max98360a_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, max98360a_controls,
+ ARRAY_SIZE(max98360a_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
+ return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map,
+ ARRAY_SIZE(max98360a_map));
+}
+
+static int acp_card_maxim_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ unsigned int fmt, srate, ch, format;
+ int ret;
+
+ srate = params_rate(params);
+ ch = params_channels(params);
+ format = params_physical_width(params);
+
+ if (drvdata->tdm_mode)
+ fmt = SND_SOC_DAIFMT_DSP_A;
+ else
+ fmt = SND_SOC_DAIFMT_I2S;
+
+ if (drvdata->soc_mclk)
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
+ else
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ if (drvdata->tdm_mode) {
+ /**
+ * As codec supports slot 2 and slot 3 for playback.
+ */
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
+ return ret;
+ }
+ }
+
+ if (!drvdata->soc_mclk) {
+ ret = acp_clk_enable(drvdata, srate, ch * format);
+ if (ret < 0) {
+ dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static const struct snd_soc_ops acp_card_maxim_ops = {
+ .startup = acp_card_amp_startup,
+ .shutdown = acp_card_shutdown,
+ .hw_params = acp_card_maxim_hw_params,
+};
+
+SND_SOC_DAILINK_DEF(max98388,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", "max98388-aif1"),
+ COMP_CODEC("i2c-ADS8388:01", "max98388-aif1")));
+
+static const struct snd_kcontrol_new max98388_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
+static const struct snd_soc_dapm_widget max98388_widgets[] = {
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route max98388_map[] = {
+ { "Left Spk", NULL, "Left BE_OUT" },
+ { "Right Spk", NULL, "Right BE_OUT" },
+};
+
+static struct snd_soc_codec_conf max98388_conf[] = {
+ {
+ .dlc = COMP_CODEC_CONF("i2c-ADS8388:00"),
+ .name_prefix = "Left",
+ },
+ {
+ .dlc = COMP_CODEC_CONF("i2c-ADS8388:01"),
+ .name_prefix = "Right",
+ },
+};
+
+static const unsigned int max98388_format[] = {16};
+
+static struct snd_pcm_hw_constraint_list constraints_sample_bits_max = {
+ .list = max98388_format,
+ .count = ARRAY_SIZE(max98388_format),
+};
+
+static int acp_card_max98388_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ &constraints_sample_bits_max);
+
+ return 0;
+}
+
+static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ int ret;
+
+ if (drvdata->amp_codec_id != MAX98388)
+ return -EINVAL;
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, max98388_widgets,
+ ARRAY_SIZE(max98388_widgets));
+
+ if (ret) {
+ dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
+ /* Don't need to add routes if widget addition failed */
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, max98388_controls,
+ ARRAY_SIZE(max98388_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
+ return snd_soc_dapm_add_routes(&rtd->card->dapm, max98388_map,
+ ARRAY_SIZE(max98388_map));
+}
+
+static int acp_max98388_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *codec_dai =
+ snd_soc_card_get_codec_dai(card,
+ MAX98388_CODEC_DAI);
+ int ret;
+
+ ret = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
+static const struct snd_soc_ops acp_max98388_ops = {
+ .startup = acp_card_max98388_startup,
+ .hw_params = acp_max98388_hw_params,
+};
+
+/* Declare nau8825 codec components */
+SND_SOC_DAILINK_DEF(nau8825,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi")));
+
+static struct snd_soc_jack nau8825_jack;
+static struct snd_soc_jack_pin nau8825_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+static const struct snd_kcontrol_new nau8825_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static const struct snd_soc_dapm_widget nau8825_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route nau8825_map[] = {
+ { "Headphone Jack", NULL, "HPOL" },
+ { "Headphone Jack", NULL, "HPOR" },
+};
+
+static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_component *component = codec_dai->component;
+ int ret;
+
+ dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+
+ if (drvdata->hs_codec_id != NAU8825)
+ return -EINVAL;
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, nau8825_widgets,
+ ARRAY_SIZE(nau8825_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, nau8825_controls,
+ ARRAY_SIZE(nau8825_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
+ SND_JACK_HEADSET | SND_JACK_LINEOUT |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &nau8825_jack,
+ nau8825_jack_pins,
+ ARRAY_SIZE(nau8825_jack_pins));
+ if (ret) {
+ dev_err(card->dev, "HP jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+ snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+ snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+ ret = snd_soc_component_set_jack(component, &nau8825_jack, NULL);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
+ return ret;
+ }
+
+ return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8825_map, ARRAY_SIZE(nau8825_map));
+}
+
+static int acp_nau8825_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ int ret;
+ unsigned int fmt;
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS,
+ (48000 * 256), SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
+
+ ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params),
+ params_rate(params) * 256);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set FLL: %d\n", ret);
+ return ret;
+ }
+
+ if (drvdata->tdm_mode)
+ fmt = SND_SOC_DAIFMT_DSP_A;
+ else
+ fmt = SND_SOC_DAIFMT_I2S;
+
+ if (drvdata->soc_mclk)
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
+ else
+ fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0) {
+ dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ if (drvdata->tdm_mode) {
+ /**
+ * As codec supports slot 4 and slot 5 for playback and slot 6 for capture.
+ */
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x30, 0xC0, 8, 16);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x40, 0x30, 8, 16);
+ if (ret < 0) {
+ dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static int acp_nau8825_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ runtime->hw.channels_max = 2;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+
+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
+ snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
+ return 0;
+}
+
+static const struct snd_soc_ops acp_card_nau8825_ops = {
+ .startup = acp_nau8825_startup,
+ .hw_params = acp_nau8825_hw_params,
+};
+
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_dapm_context *dapm = w->dapm;
+ struct snd_soc_card *card = dapm->card;
+ struct snd_soc_dai *codec_dai;
+ int ret = 0;
+
+ codec_dai = snd_soc_card_get_codec_dai(card, NAU8821_CODEC_DAI);
+ if (!codec_dai) {
+ dev_err(card->dev, "Codec dai not found\n");
+ return -EIO;
+ }
+
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_INTERNAL,
+ 0, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(card->dev, "set sysclk err = %d\n", ret);
+ return -EIO;
+ }
+ } else {
+ ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ dev_err(codec_dai->dev, "can't set FS clock %d\n", ret);
+ ret = snd_soc_dai_set_pll(codec_dai, 0, 0, NAU8821_BCLK,
+ NAU8821_FREQ_OUT);
+ if (ret < 0)
+ dev_err(codec_dai->dev, "can't set FLL: %d\n", ret);
+ }
+ return ret;
+}
+
+static struct snd_soc_jack nau8821_jack;
+static struct snd_soc_jack_pin nau8821_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+static const struct snd_kcontrol_new nau8821_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static const struct snd_soc_dapm_widget nau8821_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Int Mic", NULL),
+ SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+ platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route nau8821_audio_route[] = {
+ /* HP jack connectors - unknown if we have jack detection */
+ { "Headphone Jack", NULL, "HPOL" },
+ { "Headphone Jack", NULL, "HPOR" },
+ { "MICL", NULL, "Headset Mic" },
+ { "MICR", NULL, "Headset Mic" },
+ { "DMIC", NULL, "Int Mic" },
+ { "Headphone Jack", NULL, "Platform Clock" },
+ { "Headset Mic", NULL, "Platform Clock" },
+ { "Int Mic", NULL, "Platform Clock" },
+};
+
+static const unsigned int nau8821_format[] = {16};
+
+static struct snd_pcm_hw_constraint_list constraints_sample_bits = {
+ .list = nau8821_format,
+ .count = ARRAY_SIZE(nau8821_format),
+};
+
+static int acp_8821_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_component *component = codec_dai->component;
+ int ret;
+
+ dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, nau8821_widgets,
+ ARRAY_SIZE(nau8821_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
+ // Don't need to add routes if widget addition failed
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, nau8821_controls,
+ ARRAY_SIZE(nau8821_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
+ SND_JACK_HEADSET | SND_JACK_LINEOUT |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &nau8821_jack,
+ nau8821_jack_pins,
+ ARRAY_SIZE(nau8821_jack_pins));
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+ snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+ snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+ nau8821_enable_jack_detect(component, &nau8821_jack);
+
+ return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8821_audio_route,
+ ARRAY_SIZE(nau8821_audio_route));
+}
+
+static int acp_8821_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ &constraints_sample_bits);
+ return 0;
+}
+
+static int acp_nau8821_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ int ret;
+ unsigned int fmt;
+
+ if (drvdata->soc_mclk)
+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
+ else
+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0) {
+ dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ dev_err(card->dev, "can't set FS clock %d\n", ret);
+ ret = snd_soc_dai_set_pll(codec_dai, 0, 0, snd_soc_params_to_bclk(params),
+ params_rate(params) * 256);
+ if (ret < 0)
+ dev_err(card->dev, "can't set FLL: %d\n", ret);
+
+ return ret;
+}
+
+static const struct snd_soc_ops acp_8821_ops = {
+ .startup = acp_8821_startup,
+ .hw_params = acp_nau8821_hw_params,
+};
+
+SND_SOC_DAILINK_DEF(nau8821,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00",
+ "nau8821-hifi")));
+
+/* Declare DMIC codec components */
+SND_SOC_DAILINK_DEF(dmic_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
+
+/* Declare ACP CPU components */
+static struct snd_soc_dai_link_component platform_component[] = {
+ {
+ .name = "acp_asoc_renoir.0",
+ }
+};
+
+static struct snd_soc_dai_link_component platform_rmb_component[] = {
+ {
+ .name = "acp_asoc_rembrandt.0",
+ }
+};
+
+static struct snd_soc_dai_link_component sof_component[] = {
+ {
+ .name = "0000:04:00.5",
+ }
+};
+
+SND_SOC_DAILINK_DEF(i2s_sp,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp")));
+SND_SOC_DAILINK_DEF(i2s_hs,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs")));
+SND_SOC_DAILINK_DEF(sof_sp,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp")));
+SND_SOC_DAILINK_DEF(sof_sp_virtual,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp-virtual")));
+SND_SOC_DAILINK_DEF(sof_hs,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs")));
+SND_SOC_DAILINK_DEF(sof_hs_virtual,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs-virtual")));
+SND_SOC_DAILINK_DEF(sof_dmic,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic")));
+SND_SOC_DAILINK_DEF(pdm_dmic,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp-pdm-dmic")));
+
+static int acp_rtk_set_bias_level(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct snd_soc_component *component = dapm->component;
+ struct acp_card_drvdata *drvdata = card->drvdata;
+ int ret = 0;
+
+ if (!component)
+ return 0;
+
+ if (strncmp(component->name, "i2c-RTL5682", 11) &&
+ strncmp(component->name, "i2c-10EC1019", 12))
+ return 0;
+
+ /*
+ * For Realtek's codec and amplifier components,
+ * the lrck and bclk must be enabled brfore their all dapms be powered on,
+ * and must be disabled after their all dapms be powered down
+ * to avoid any pop.
+ */
+ switch (level) {
+ case SND_SOC_BIAS_STANDBY:
+ if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
+
+ /* Increase bclk's enable_count */
+ ret = clk_prepare_enable(drvdata->bclk);
+ if (ret < 0)
+ dev_err(component->dev, "Failed to enable bclk %d\n", ret);
+ } else {
+ /*
+ * Decrease bclk's enable_count.
+ * While the enable_count is 0, the bclk would be closed.
+ */
+ clk_disable_unprepare(drvdata->bclk);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
+{
+ struct snd_soc_dai_link *links;
+ struct device *dev = card->dev;
+ struct acp_card_drvdata *drv_data = card->drvdata;
+ int i = 0, num_links = 0;
+
+ if (drv_data->hs_cpu_id)
+ num_links++;
+ if (drv_data->amp_cpu_id)
+ num_links++;
+ if (drv_data->dmic_cpu_id)
+ num_links++;
+
+ links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);
+ if (!links)
+ return -ENOMEM;
+
+ if (drv_data->hs_cpu_id == I2S_SP) {
+ links[i].name = "acp-headset-codec";
+ links[i].id = HEADSET_BE_ID;
+ links[i].cpus = sof_sp;
+ links[i].num_cpus = ARRAY_SIZE(sof_sp);
+ links[i].platforms = sof_component;
+ links[i].num_platforms = ARRAY_SIZE(sof_component);
+ links[i].dpcm_playback = 1;
+ links[i].dpcm_capture = 1;
+ links[i].nonatomic = true;
+ links[i].no_pcm = 1;
+ if (!drv_data->hs_codec_id) {
+ /* Use dummy codec if codec id not specified */
+ links[i].codecs = &asoc_dummy_dlc;
+ links[i].num_codecs = 1;
+ }
+ if (drv_data->hs_codec_id == RT5682) {
+ links[i].codecs = rt5682;
+ links[i].num_codecs = ARRAY_SIZE(rt5682);
+ links[i].init = acp_card_rt5682_init;
+ links[i].ops = &acp_card_rt5682_ops;
+ }
+ if (drv_data->hs_codec_id == RT5682S) {
+ links[i].codecs = rt5682s;
+ links[i].num_codecs = ARRAY_SIZE(rt5682s);
+ links[i].init = acp_card_rt5682s_init;
+ links[i].ops = &acp_card_rt5682s_ops;
+ }
+ if (drv_data->hs_codec_id == NAU8821) {
+ links[i].codecs = nau8821;
+ links[i].num_codecs = ARRAY_SIZE(nau8821);
+ links[i].init = acp_8821_init;
+ links[i].ops = &acp_8821_ops;
+ }
+ i++;
+ }
+
+ if (drv_data->hs_cpu_id == I2S_HS) {
+ links[i].name = "acp-headset-codec";
+ links[i].id = HEADSET_BE_ID;
+ links[i].cpus = sof_hs;
+ links[i].num_cpus = ARRAY_SIZE(sof_hs);
+ links[i].platforms = sof_component;
+ links[i].num_platforms = ARRAY_SIZE(sof_component);
+ links[i].dpcm_playback = 1;
+ links[i].dpcm_capture = 1;
+ links[i].nonatomic = true;
+ links[i].no_pcm = 1;
+ if (!drv_data->hs_codec_id) {
+ /* Use dummy codec if codec id not specified */
+ links[i].codecs = &asoc_dummy_dlc;
+ links[i].num_codecs = 1;
+ }
+ if (drv_data->hs_codec_id == NAU8825) {
+ links[i].codecs = nau8825;
+ links[i].num_codecs = ARRAY_SIZE(nau8825);
+ links[i].init = acp_card_nau8825_init;
+ links[i].ops = &acp_card_nau8825_ops;
+ }
+ if (drv_data->hs_codec_id == RT5682S) {
+ links[i].codecs = rt5682s;
+ links[i].num_codecs = ARRAY_SIZE(rt5682s);
+ links[i].init = acp_card_rt5682s_init;
+ links[i].ops = &acp_card_rt5682s_ops;
+ }
+ i++;
+ }
+
+ if (drv_data->amp_cpu_id == I2S_SP) {
+ links[i].name = "acp-amp-codec";
+ links[i].id = AMP_BE_ID;
+ links[i].cpus = sof_sp_virtual;
+ links[i].num_cpus = ARRAY_SIZE(sof_sp_virtual);
+ links[i].platforms = sof_component;
+ links[i].num_platforms = ARRAY_SIZE(sof_component);
+ links[i].dpcm_playback = 1;
+ links[i].nonatomic = true;
+ links[i].no_pcm = 1;
+ if (!drv_data->amp_codec_id) {
+ /* Use dummy codec if codec id not specified */
+ links[i].codecs = &asoc_dummy_dlc;
+ links[i].num_codecs = 1;
+ }
+ if (drv_data->amp_codec_id == RT1019) {
+ links[i].codecs = rt1019;
+ links[i].num_codecs = ARRAY_SIZE(rt1019);
+ links[i].ops = &acp_card_rt1019_ops;
+ links[i].init = acp_card_rt1019_init;
+ card->codec_conf = rt1019_conf;
+ card->num_configs = ARRAY_SIZE(rt1019_conf);
+ }
+ if (drv_data->amp_codec_id == MAX98360A) {
+ links[i].codecs = max98360a;
+ links[i].num_codecs = ARRAY_SIZE(max98360a);
+ links[i].ops = &acp_card_maxim_ops;
+ links[i].init = acp_card_maxim_init;
+ }
+ i++;
+ }
+
+ if (drv_data->amp_cpu_id == I2S_HS) {
+ links[i].name = "acp-amp-codec";
+ links[i].id = AMP_BE_ID;
+ links[i].cpus = sof_hs_virtual;
+ links[i].num_cpus = ARRAY_SIZE(sof_hs_virtual);
+ links[i].platforms = sof_component;
+ links[i].num_platforms = ARRAY_SIZE(sof_component);
+ links[i].dpcm_playback = 1;
+ links[i].nonatomic = true;
+ links[i].no_pcm = 1;
+ if (!drv_data->amp_codec_id) {
+ /* Use dummy codec if codec id not specified */
+ links[i].codecs = &asoc_dummy_dlc;
+ links[i].num_codecs = 1;
+ }
+ if (drv_data->amp_codec_id == MAX98360A) {
+ links[i].codecs = max98360a;
+ links[i].num_codecs = ARRAY_SIZE(max98360a);
+ links[i].ops = &acp_card_maxim_ops;
+ links[i].init = acp_card_maxim_init;
+ }
+ if (drv_data->amp_codec_id == MAX98388) {
+ links[i].codecs = max98388;
+ links[i].num_codecs = ARRAY_SIZE(max98388);
+ links[i].ops = &acp_max98388_ops;
+ links[i].init = acp_card_max98388_init;
+ card->codec_conf = max98388_conf;
+ card->num_configs = ARRAY_SIZE(max98388_conf);
+ }
+ if (drv_data->amp_codec_id == RT1019) {
+ links[i].codecs = rt1019;
+ links[i].num_codecs = ARRAY_SIZE(rt1019);
+ links[i].ops = &acp_card_rt1019_ops;
+ links[i].init = acp_card_rt1019_init;
+ card->codec_conf = rt1019_conf;
+ card->num_configs = ARRAY_SIZE(rt1019_conf);
+ }
+ i++;
+ }
+
+ if (drv_data->dmic_cpu_id == DMIC) {
+ links[i].name = "acp-dmic-codec";
+ links[i].id = DMIC_BE_ID;
+ links[i].codecs = dmic_codec;
+ links[i].num_codecs = ARRAY_SIZE(dmic_codec);
+ links[i].cpus = sof_dmic;
+ links[i].num_cpus = ARRAY_SIZE(sof_dmic);
+ links[i].platforms = sof_component;
+ links[i].num_platforms = ARRAY_SIZE(sof_component);
+ links[i].dpcm_capture = 1;
+ links[i].nonatomic = true;
+ links[i].no_pcm = 1;
+ }
+
+ card->dai_link = links;
+ card->num_links = num_links;
+ card->set_bias_level = acp_rtk_set_bias_level;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, SND_SOC_AMD_MACH);
+
+int acp_legacy_dai_links_create(struct snd_soc_card *card)
+{
+ struct snd_soc_dai_link *links;
+ struct device *dev = card->dev;
+ struct acp_card_drvdata *drv_data = card->drvdata;
+ int i = 0, num_links = 0;
+
+ if (drv_data->hs_cpu_id)
+ num_links++;
+ if (drv_data->amp_cpu_id)
+ num_links++;
+ if (drv_data->dmic_cpu_id)
+ num_links++;
+
+ links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);
+ if (!links)
+ return -ENOMEM;
+
+ if (drv_data->hs_cpu_id == I2S_SP) {
+ links[i].name = "acp-headset-codec";
+ links[i].id = HEADSET_BE_ID;
+ links[i].cpus = i2s_sp;
+ links[i].num_cpus = ARRAY_SIZE(i2s_sp);
+ links[i].platforms = platform_component;
+ links[i].num_platforms = ARRAY_SIZE(platform_component);
+ links[i].dpcm_playback = 1;
+ links[i].dpcm_capture = 1;
+ if (!drv_data->hs_codec_id) {
+ /* Use dummy codec if codec id not specified */
+ links[i].codecs = &asoc_dummy_dlc;
+ links[i].num_codecs = 1;
+ }
+ if (drv_data->hs_codec_id == RT5682) {
+ links[i].codecs = rt5682;
+ links[i].num_codecs = ARRAY_SIZE(rt5682);
+ links[i].init = acp_card_rt5682_init;
+ links[i].ops = &acp_card_rt5682_ops;
+ }
+ if (drv_data->hs_codec_id == RT5682S) {
+ links[i].codecs = rt5682s;
+ links[i].num_codecs = ARRAY_SIZE(rt5682s);
+ links[i].init = acp_card_rt5682s_init;
+ links[i].ops = &acp_card_rt5682s_ops;
+ }
+ i++;
+ }
+
+ if (drv_data->hs_cpu_id == I2S_HS) {
+ links[i].name = "acp-headset-codec";
+ links[i].id = HEADSET_BE_ID;
+ links[i].cpus = i2s_hs;
+ links[i].num_cpus = ARRAY_SIZE(i2s_hs);
+ if (drv_data->platform == REMBRANDT) {
+ links[i].platforms = platform_rmb_component;
+ links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
+ } else {
+ links[i].platforms = platform_component;
+ links[i].num_platforms = ARRAY_SIZE(platform_component);
+ }
+ links[i].dpcm_playback = 1;
+ links[i].dpcm_capture = 1;
+ if (!drv_data->hs_codec_id) {
+ /* Use dummy codec if codec id not specified */
+ links[i].codecs = &asoc_dummy_dlc;
+ links[i].num_codecs = 1;
+ }
+ if (drv_data->hs_codec_id == NAU8825) {
+ links[i].codecs = nau8825;
+ links[i].num_codecs = ARRAY_SIZE(nau8825);
+ links[i].init = acp_card_nau8825_init;
+ links[i].ops = &acp_card_nau8825_ops;
+ }
+ if (drv_data->hs_codec_id == RT5682S) {
+ links[i].codecs = rt5682s;
+ links[i].num_codecs = ARRAY_SIZE(rt5682s);
+ links[i].init = acp_card_rt5682s_init;
+ links[i].ops = &acp_card_rt5682s_ops;
+ }
+ i++;
+ }
+
+ if (drv_data->amp_cpu_id == I2S_SP) {
+ links[i].name = "acp-amp-codec";
+ links[i].id = AMP_BE_ID;
+ links[i].cpus = i2s_sp;
+ links[i].num_cpus = ARRAY_SIZE(i2s_sp);
+ links[i].platforms = platform_component;
+ links[i].num_platforms = ARRAY_SIZE(platform_component);
+ links[i].dpcm_playback = 1;
+ if (!drv_data->amp_codec_id) {
+ /* Use dummy codec if codec id not specified */
+ links[i].codecs = &asoc_dummy_dlc;
+ links[i].num_codecs = 1;
+ }
+ if (drv_data->amp_codec_id == RT1019) {
+ links[i].codecs = rt1019;
+ links[i].num_codecs = ARRAY_SIZE(rt1019);
+ links[i].ops = &acp_card_rt1019_ops;
+ links[i].init = acp_card_rt1019_init;
+ card->codec_conf = rt1019_conf;
+ card->num_configs = ARRAY_SIZE(rt1019_conf);
+ }
+ if (drv_data->amp_codec_id == MAX98360A) {
+ links[i].codecs = max98360a;
+ links[i].num_codecs = ARRAY_SIZE(max98360a);
+ links[i].ops = &acp_card_maxim_ops;
+ links[i].init = acp_card_maxim_init;
+ }
+ i++;
+ }
+
+ if (drv_data->amp_cpu_id == I2S_HS) {
+ links[i].name = "acp-amp-codec";
+ links[i].id = AMP_BE_ID;
+ links[i].cpus = i2s_hs;
+ links[i].num_cpus = ARRAY_SIZE(i2s_hs);
+ if (drv_data->platform == REMBRANDT) {
+ links[i].platforms = platform_rmb_component;
+ links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
+ } else {
+ links[i].platforms = platform_component;
+ links[i].num_platforms = ARRAY_SIZE(platform_component);
+ }
+ links[i].dpcm_playback = 1;
+ if (!drv_data->amp_codec_id) {
+ /* Use dummy codec if codec id not specified */
+ links[i].codecs = &asoc_dummy_dlc;
+ links[i].num_codecs = 1;
+ }
+ if (drv_data->amp_codec_id == MAX98360A) {
+ links[i].codecs = max98360a;
+ links[i].num_codecs = ARRAY_SIZE(max98360a);
+ links[i].ops = &acp_card_maxim_ops;
+ links[i].init = acp_card_maxim_init;
+ }
+ if (drv_data->amp_codec_id == RT1019) {
+ links[i].codecs = rt1019;
+ links[i].num_codecs = ARRAY_SIZE(rt1019);
+ links[i].ops = &acp_card_rt1019_ops;
+ links[i].init = acp_card_rt1019_init;
+ card->codec_conf = rt1019_conf;
+ card->num_configs = ARRAY_SIZE(rt1019_conf);
+ }
+ i++;
+ }
+
+ if (drv_data->dmic_cpu_id == DMIC) {
+ links[i].name = "acp-dmic-codec";
+ links[i].id = DMIC_BE_ID;
+ if (drv_data->dmic_codec_id == DMIC) {
+ links[i].codecs = dmic_codec;
+ links[i].num_codecs = ARRAY_SIZE(dmic_codec);
+ } else {
+ /* Use dummy codec if codec id not specified */
+ links[i].codecs = &asoc_dummy_dlc;
+ links[i].num_codecs = 1;
+ }
+ links[i].cpus = pdm_dmic;
+ links[i].num_cpus = ARRAY_SIZE(pdm_dmic);
+ if (drv_data->platform == REMBRANDT) {
+ links[i].platforms = platform_rmb_component;
+ links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
+ } else {
+ links[i].platforms = platform_component;
+ links[i].num_platforms = ARRAY_SIZE(platform_component);
+ }
+ links[i].ops = &acp_card_dmic_ops;
+ links[i].dpcm_capture = 1;
+ }
+
+ card->dai_link = links;
+ card->num_links = num_links;
+ card->set_bias_level = acp_rtk_set_bias_level;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, SND_SOC_AMD_MACH);
+
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/acp/acp-mach.h b/sound/soc/amd/acp/acp-mach.h
new file mode 100644
index 0000000000..2b3ec65940
--- /dev/null
+++ b/sound/soc/amd/acp/acp-mach.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Author: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+ */
+#ifndef __ACP_MACH_H
+#define __ACP_MACH_H
+
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+
+#define TDM_CHANNELS 8
+
+enum be_id {
+ HEADSET_BE_ID = 0,
+ AMP_BE_ID,
+ DMIC_BE_ID,
+};
+
+enum cpu_endpoints {
+ NONE = 0,
+ I2S_HS,
+ I2S_SP,
+ I2S_BT,
+ DMIC,
+};
+
+enum codec_endpoints {
+ DUMMY = 0,
+ RT5682,
+ RT1019,
+ MAX98360A,
+ RT5682S,
+ NAU8825,
+ NAU8821,
+ MAX98388,
+};
+
+enum platform_end_point {
+ RENOIR = 0,
+ REMBRANDT,
+};
+
+struct acp_card_drvdata {
+ unsigned int hs_cpu_id;
+ unsigned int amp_cpu_id;
+ unsigned int dmic_cpu_id;
+ unsigned int hs_codec_id;
+ unsigned int amp_codec_id;
+ unsigned int dmic_codec_id;
+ unsigned int dai_fmt;
+ unsigned int platform;
+ struct clk *wclk;
+ struct clk *bclk;
+ bool soc_mclk;
+ bool tdm_mode;
+};
+
+int acp_sofdsp_dai_links_create(struct snd_soc_card *card);
+int acp_legacy_dai_links_create(struct snd_soc_card *card);
+extern const struct dmi_system_id acp_quirk_table[];
+
+#endif
diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c
new file mode 100644
index 0000000000..a32c14a109
--- /dev/null
+++ b/sound/soc/amd/acp/acp-pci.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2022 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+
+/*
+ * Generic PCI interface for ACP device
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+
+#include "amd.h"
+#include "../mach-config.h"
+
+#define DRV_NAME "acp_pci"
+
+#define ACP3x_REG_START 0x1240000
+#define ACP3x_REG_END 0x125C000
+
+static struct platform_device *dmic_dev;
+static struct platform_device *pdev;
+
+static const struct resource acp_res[] = {
+ {
+ .start = 0,
+ .end = ACP3x_REG_END - ACP3x_REG_START,
+ .name = "acp_mem",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0,
+ .end = 0,
+ .name = "acp_dai_irq",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+{
+ struct platform_device_info pdevinfo;
+ struct device *dev = &pci->dev;
+ const struct resource *res_acp;
+ struct acp_chip_info *chip;
+ struct resource *res;
+ unsigned int flag, addr, num_res, i;
+ int ret;
+
+ flag = snd_amd_acp_find_config(pci);
+ if (flag != FLAG_AMD_LEGACY)
+ return -ENODEV;
+
+ chip = devm_kzalloc(&pci->dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ if (pci_enable_device(pci))
+ return dev_err_probe(&pci->dev, -ENODEV,
+ "pci_enable_device failed\n");
+
+ ret = pci_request_regions(pci, "AMD ACP3x audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ ret = -ENOMEM;
+ goto disable_pci;
+ }
+
+ pci_set_master(pci);
+
+ res_acp = acp_res;
+ num_res = ARRAY_SIZE(acp_res);
+
+ switch (pci->revision) {
+ case 0x01:
+ chip->name = "acp_asoc_renoir";
+ chip->acp_rev = ACP3X_DEV;
+ break;
+ case 0x6f:
+ chip->name = "acp_asoc_rembrandt";
+ chip->acp_rev = ACP6X_DEV;
+ break;
+ default:
+ dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision);
+ ret = -EINVAL;
+ goto release_regions;
+ }
+
+ dmic_dev = platform_device_register_data(dev, "dmic-codec", PLATFORM_DEVID_NONE, NULL, 0);
+ if (IS_ERR(dmic_dev)) {
+ dev_err(dev, "failed to create DMIC device\n");
+ ret = PTR_ERR(dmic_dev);
+ goto release_regions;
+ }
+
+ addr = pci_resource_start(pci, 0);
+ chip->base = devm_ioremap(&pci->dev, addr, pci_resource_len(pci, 0));
+ if (!chip->base) {
+ ret = -ENOMEM;
+ goto unregister_dmic_dev;
+ }
+
+ acp_init(chip);
+ res = devm_kcalloc(&pci->dev, num_res, sizeof(struct resource), GFP_KERNEL);
+ if (!res) {
+ ret = -ENOMEM;
+ goto unregister_dmic_dev;
+ }
+
+ for (i = 0; i < num_res; i++, res_acp++) {
+ res[i].name = res_acp->name;
+ res[i].flags = res_acp->flags;
+ res[i].start = addr + res_acp->start;
+ res[i].end = addr + res_acp->end;
+ if (res_acp->flags == IORESOURCE_IRQ) {
+ res[i].start = pci->irq;
+ res[i].end = res[i].start;
+ }
+ }
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+
+ pdevinfo.name = chip->name;
+ pdevinfo.id = 0;
+ pdevinfo.parent = &pci->dev;
+ pdevinfo.num_res = num_res;
+ pdevinfo.res = &res[0];
+ pdevinfo.data = chip;
+ pdevinfo.size_data = sizeof(*chip);
+
+ pdev = platform_device_register_full(&pdevinfo);
+ if (IS_ERR(pdev)) {
+ dev_err(&pci->dev, "cannot register %s device\n", pdevinfo.name);
+ ret = PTR_ERR(pdev);
+ goto unregister_dmic_dev;
+ }
+ chip->chip_pdev = pdev;
+ dev_set_drvdata(&pci->dev, chip);
+ pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_put_noidle(&pci->dev);
+ pm_runtime_allow(&pci->dev);
+ return ret;
+
+unregister_dmic_dev:
+ platform_device_unregister(dmic_dev);
+release_regions:
+ pci_release_regions(pci);
+disable_pci:
+ pci_disable_device(pci);
+
+ return ret;
+};
+
+static int __maybe_unused snd_acp_suspend(struct device *dev)
+{
+ struct acp_chip_info *chip;
+ int ret;
+
+ chip = dev_get_drvdata(dev);
+ ret = acp_deinit(chip->base);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+ return ret;
+}
+
+static int __maybe_unused snd_acp_resume(struct device *dev)
+{
+ struct acp_chip_info *chip;
+ struct acp_dev_data *adata;
+ struct device child;
+ int ret;
+
+ chip = dev_get_drvdata(dev);
+ ret = acp_init(chip);
+ if (ret)
+ dev_err(dev, "ACP init failed\n");
+ child = chip->chip_pdev->dev;
+ adata = dev_get_drvdata(&child);
+ if (adata)
+ acp_enable_interrupts(adata);
+ return ret;
+}
+
+static const struct dev_pm_ops acp_pm_ops = {
+ SET_RUNTIME_PM_OPS(snd_acp_suspend, snd_acp_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(snd_acp_suspend, snd_acp_resume)
+};
+
+static void acp_pci_remove(struct pci_dev *pci)
+{
+ struct acp_chip_info *chip;
+ int ret;
+
+ chip = pci_get_drvdata(pci);
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_get_noresume(&pci->dev);
+ if (dmic_dev)
+ platform_device_unregister(dmic_dev);
+ if (pdev)
+ platform_device_unregister(pdev);
+ ret = acp_deinit(chip->base);
+ if (ret)
+ dev_err(&pci->dev, "ACP de-init failed\n");
+}
+
+/* PCI IDs */
+static const struct pci_device_id acp_pci_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_PCI_DEV_ID)},
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, acp_pci_ids);
+
+/* pci_driver definition */
+static struct pci_driver snd_amd_acp_pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = acp_pci_ids,
+ .probe = acp_pci_probe,
+ .remove = acp_pci_remove,
+ .driver = {
+ .pm = &acp_pm_ops,
+ },
+};
+module_pci_driver(snd_amd_acp_pci_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_IMPORT_NS(SND_SOC_ACP_COMMON);
+MODULE_ALIAS(DRV_NAME);
diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c
new file mode 100644
index 0000000000..f754bf79b5
--- /dev/null
+++ b/sound/soc/amd/acp/acp-pdm.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2022 Advanced Micro Devices, Inc.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+// Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+//
+
+/*
+ * Generic Hardware interface for ACP Audio PDM controller
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+#include "amd.h"
+
+#define DRV_NAME "acp-pdm"
+
+static int acp_dmic_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct acp_stream *stream = substream->runtime->private_data;
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ u32 physical_addr, size_dmic, period_bytes;
+ unsigned int dmic_ctrl;
+
+ /* Enable default DMIC clk */
+ writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL);
+ dmic_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL);
+ dmic_ctrl |= PDM_MISC_CTRL_MASK;
+ writel(dmic_ctrl, adata->acp_base + ACP_WOV_MISC_CTRL);
+
+ period_bytes = frames_to_bytes(substream->runtime,
+ substream->runtime->period_size);
+ size_dmic = frames_to_bytes(substream->runtime,
+ substream->runtime->buffer_size);
+
+ physical_addr = stream->reg_offset + MEM_WINDOW_START;
+
+ /* Init DMIC Ring buffer */
+ writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR);
+ writel(size_dmic, adata->acp_base + ACP_WOV_RX_RINGBUFSIZE);
+ writel(period_bytes, adata->acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
+ writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
+
+ return 0;
+}
+
+static int acp_dmic_dai_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ unsigned int dma_enable;
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ dma_enable = readl(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if (!(dma_enable & DMA_EN_MASK)) {
+ writel(PDM_ENABLE, adata->acp_base + ACP_WOV_PDM_ENABLE);
+ writel(PDM_ENABLE, adata->acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ }
+
+ ret = readl_poll_timeout_atomic(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE,
+ dma_enable, (dma_enable & DMA_EN_MASK),
+ DELAY_US, PDM_TIMEOUT);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ dma_enable = readl(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((dma_enable & DMA_EN_MASK)) {
+ writel(PDM_DISABLE, adata->acp_base + ACP_WOV_PDM_ENABLE);
+ writel(PDM_DISABLE, adata->acp_base + ACP_WOV_PDM_DMA_ENABLE);
+
+ }
+
+ ret = readl_poll_timeout_atomic(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE,
+ dma_enable, !(dma_enable & DMA_EN_MASK),
+ DELAY_US, PDM_TIMEOUT);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int acp_dmic_hwparams(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hwparams, struct snd_soc_dai *dai)
+{
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ unsigned int channels, ch_mask;
+
+ channels = params_channels(hwparams);
+ switch (channels) {
+ case 2:
+ ch_mask = 0;
+ break;
+ case 4:
+ ch_mask = 1;
+ break;
+ case 6:
+ ch_mask = 2;
+ break;
+ default:
+ dev_err(dev, "Invalid channels %d\n", channels);
+ return -EINVAL;
+ }
+
+ adata->ch_mask = ch_mask;
+ if (params_format(hwparams) != SNDRV_PCM_FORMAT_S32_LE) {
+ dev_err(dai->dev, "Invalid format:%d\n", params_format(hwparams));
+ return -EINVAL;
+ }
+
+ writel(ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
+ writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR);
+
+ return 0;
+}
+
+static int acp_dmic_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct acp_stream *stream = substream->runtime->private_data;
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ u32 ext_int_ctrl;
+
+ stream->dai_id = DMIC_INSTANCE;
+ stream->irq_bit = BIT(PDM_DMA_STAT);
+ stream->pte_offset = ACP_SRAM_PDM_PTE_OFFSET;
+ stream->reg_offset = ACP_REGION2_OFFSET;
+
+ /* Enable DMIC Interrupts */
+ ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
+ ext_int_ctrl |= PDM_DMA_INTR_MASK;
+ writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
+
+ return 0;
+}
+
+static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct device *dev = dai->component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ u32 ext_int_ctrl;
+
+ /* Disable DMIC interrupts */
+ ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
+ ext_int_ctrl &= ~PDM_DMA_INTR_MASK;
+ writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
+}
+
+const struct snd_soc_dai_ops acp_dmic_dai_ops = {
+ .prepare = acp_dmic_prepare,
+ .hw_params = acp_dmic_hwparams,
+ .trigger = acp_dmic_dai_trigger,
+ .startup = acp_dmic_dai_startup,
+ .shutdown = acp_dmic_dai_shutdown,
+};
+EXPORT_SYMBOL_NS_GPL(acp_dmic_dai_ops, SND_SOC_ACP_COMMON);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS(DRV_NAME);
diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c
new file mode 100644
index 0000000000..f516daf6fe
--- /dev/null
+++ b/sound/soc/amd/acp/acp-platform.c
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2021 Advanced Micro Devices, Inc.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+
+/*
+ * Generic interface for ACP audio blck PCM component
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/dma-mapping.h>
+
+#include "amd.h"
+
+#define DRV_NAME "acp_i2s_dma"
+
+static const struct snd_pcm_hardware acp_pcm_hardware_playback = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
+ .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
+ .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
+ .periods_min = PLAYBACK_MIN_NUM_PERIODS,
+ .periods_max = PLAYBACK_MAX_NUM_PERIODS,
+};
+
+static const struct snd_pcm_hardware acp_pcm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
+int acp_machine_select(struct acp_dev_data *adata)
+{
+ struct snd_soc_acpi_mach *mach;
+ int size;
+
+ size = sizeof(*adata->machines);
+ mach = snd_soc_acpi_find_machine(adata->machines);
+ if (!mach) {
+ dev_err(adata->dev, "warning: No matching ASoC machine driver found\n");
+ return -EINVAL;
+ }
+
+ adata->mach_dev = platform_device_register_data(adata->dev, mach->drv_name,
+ PLATFORM_DEVID_NONE, mach, size);
+ if (IS_ERR(adata->mach_dev))
+ dev_warn(adata->dev, "Unable to register Machine device\n");
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(acp_machine_select, SND_SOC_ACP_COMMON);
+
+static irqreturn_t i2s_irq_handler(int irq, void *data)
+{
+ struct acp_dev_data *adata = data;
+ struct acp_resource *rsrc = adata->rsrc;
+ struct acp_stream *stream;
+ u16 i2s_flag = 0;
+ u32 ext_intr_stat, ext_intr_stat1;
+
+ if (!adata)
+ return IRQ_NONE;
+
+ if (adata->rsrc->no_of_ctrls == 2)
+ ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(adata, (rsrc->irqp_used - 1)));
+
+ ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
+
+ spin_lock(&adata->acp_lock);
+ list_for_each_entry(stream, &adata->stream_list, list) {
+ if (ext_intr_stat & stream->irq_bit) {
+ writel(stream->irq_bit,
+ ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
+ snd_pcm_period_elapsed(stream->substream);
+ i2s_flag = 1;
+ }
+ if (adata->rsrc->no_of_ctrls == 2) {
+ if (ext_intr_stat1 & stream->irq_bit) {
+ writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(adata,
+ (rsrc->irqp_used - 1)));
+ snd_pcm_period_elapsed(stream->substream);
+ i2s_flag = 1;
+ }
+ }
+ }
+ spin_unlock(&adata->acp_lock);
+ if (i2s_flag)
+ return IRQ_HANDLED;
+
+ return IRQ_NONE;
+}
+
+void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream)
+{
+ struct acp_resource *rsrc = adata->rsrc;
+ u32 pte_reg, pte_size, reg_val;
+
+ /* Use ATU base Group5 */
+ pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_5;
+ pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5;
+ stream->reg_offset = 0x02000000;
+
+ /* Group Enable */
+ reg_val = rsrc->sram_pte_offset;
+ writel(reg_val | BIT(31), adata->acp_base + pte_reg);
+ writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + pte_size);
+ writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
+}
+EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, SND_SOC_ACP_COMMON);
+
+void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size)
+{
+ struct snd_pcm_substream *substream = stream->substream;
+ struct acp_resource *rsrc = adata->rsrc;
+ dma_addr_t addr = substream->dma_buffer.addr;
+ int num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+ u32 low, high, val;
+ u16 page_idx;
+
+ val = stream->pte_offset;
+
+ for (page_idx = 0; page_idx < num_pages; page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+ writel(low, adata->acp_base + rsrc->scratch_reg_offset + val);
+ high |= BIT(31);
+ writel(high, adata->acp_base + rsrc->scratch_reg_offset + val + 4);
+
+ /* Move to next physically contiguous page */
+ val += 8;
+ addr += PAGE_SIZE;
+ }
+}
+EXPORT_SYMBOL_NS_GPL(config_acp_dma, SND_SOC_ACP_COMMON);
+
+static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct device *dev = component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct acp_stream *stream;
+ int ret;
+
+ stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+ if (!stream)
+ return -ENOMEM;
+
+ stream->substream = substream;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ runtime->hw = acp_pcm_hardware_playback;
+ else
+ runtime->hw = acp_pcm_hardware_capture;
+
+ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(stream);
+ return ret;
+ }
+ runtime->private_data = stream;
+
+ writel(1, ACP_EXTERNAL_INTR_ENB(adata));
+
+ spin_lock_irq(&adata->acp_lock);
+ list_add_tail(&stream->list, &adata->stream_list);
+ spin_unlock_irq(&adata->acp_lock);
+
+ return ret;
+}
+
+static int acp_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct acp_dev_data *adata = snd_soc_component_get_drvdata(component);
+ struct acp_stream *stream = substream->runtime->private_data;
+ u64 size = params_buffer_bytes(params);
+
+ /* Configure ACP DMA block with params */
+ config_pte_for_stream(adata, stream);
+ config_acp_dma(adata, stream, size);
+
+ return 0;
+}
+
+static snd_pcm_uframes_t acp_dma_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct device *dev = component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct acp_stream *stream = substream->runtime->private_data;
+ u32 pos, buffersize;
+ u64 bytescount;
+
+ buffersize = frames_to_bytes(substream->runtime,
+ substream->runtime->buffer_size);
+
+ bytescount = acp_get_byte_count(adata, stream->dai_id, substream->stream);
+
+ if (bytescount > stream->bytescount)
+ bytescount -= stream->bytescount;
+
+ pos = do_div(bytescount, buffersize);
+
+ return bytes_to_frames(substream->runtime, pos);
+}
+
+static int acp_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct device *parent = component->dev->parent;
+
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ parent, MIN_BUFFER, MAX_BUFFER);
+ return 0;
+}
+
+static int acp_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct device *dev = component->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct acp_stream *stream = substream->runtime->private_data;
+
+ /* Remove entry from list */
+ spin_lock_irq(&adata->acp_lock);
+ list_del(&stream->list);
+ spin_unlock_irq(&adata->acp_lock);
+ kfree(stream);
+
+ return 0;
+}
+
+static const struct snd_soc_component_driver acp_pcm_component = {
+ .name = DRV_NAME,
+ .open = acp_dma_open,
+ .close = acp_dma_close,
+ .hw_params = acp_dma_hw_params,
+ .pointer = acp_dma_pointer,
+ .pcm_construct = acp_dma_new,
+ .legacy_dai_naming = 1,
+};
+
+int acp_platform_register(struct device *dev)
+{
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct snd_soc_dai_driver;
+ unsigned int status;
+
+ status = devm_request_irq(dev, adata->i2s_irq, i2s_irq_handler,
+ IRQF_SHARED, "ACP_I2S_IRQ", adata);
+ if (status) {
+ dev_err(dev, "ACP I2S IRQ request failed\n");
+ return status;
+ }
+
+ status = devm_snd_soc_register_component(dev, &acp_pcm_component,
+ adata->dai_driver,
+ adata->num_dai);
+ if (status) {
+ dev_err(dev, "Fail to register acp i2s component\n");
+ return status;
+ }
+
+ INIT_LIST_HEAD(&adata->stream_list);
+ spin_lock_init(&adata->acp_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(acp_platform_register, SND_SOC_ACP_COMMON);
+
+int acp_platform_unregister(struct device *dev)
+{
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+
+ if (adata->mach_dev)
+ platform_device_unregister(adata->mach_dev);
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(acp_platform_unregister, SND_SOC_ACP_COMMON);
+
+MODULE_DESCRIPTION("AMD ACP PCM Driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS(DRV_NAME);
diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c
new file mode 100644
index 0000000000..1bf7b2e68a
--- /dev/null
+++ b/sound/soc/amd/acp/acp-rembrandt.c
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2022 Advanced Micro Devices, Inc.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+// V sujith kumar Reddy <Vsujithkumar.Reddy@amd.com>
+/*
+ * Hardware interface for Renoir ACP block
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+
+#include "amd.h"
+
+#define DRV_NAME "acp_asoc_rembrandt"
+
+#define MP1_C2PMSG_69 0x3B10A14
+#define MP1_C2PMSG_85 0x3B10A54
+#define MP1_C2PMSG_93 0x3B10A74
+#define HOST_BRIDGE_ID 0x14B5
+
+static struct acp_resource rsrc = {
+ .offset = 0,
+ .no_of_ctrls = 2,
+ .irqp_used = 1,
+ .soc_mclk = true,
+ .irq_reg_offset = 0x1a00,
+ .i2s_pin_cfg_offset = 0x1440,
+ .i2s_mode = 0x0a,
+ .scratch_reg_offset = 0x12800,
+ .sram_pte_offset = 0x03802800,
+};
+
+static struct snd_soc_acpi_codecs amp_rt1019 = {
+ .num_codecs = 1,
+ .codecs = {"10EC1019"}
+};
+
+static struct snd_soc_acpi_codecs amp_max = {
+ .num_codecs = 1,
+ .codecs = {"MX98360A"}
+};
+
+static struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines[] = {
+ {
+ .id = "10508825",
+ .drv_name = "rmb-nau8825-max",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_max,
+ },
+ {
+ .id = "AMDI0007",
+ .drv_name = "rembrandt-acp",
+ },
+ {
+ .id = "RTL5682",
+ .drv_name = "rmb-rt5682s-rt1019",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_rt1019,
+ },
+ {},
+};
+
+static struct snd_soc_dai_driver acp_rmb_dai[] = {
+{
+ .name = "acp-i2s-sp",
+ .id = I2S_SP_INSTANCE,
+ .playback = {
+ .stream_name = "I2S SP Playback",
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .stream_name = "I2S SP Capture",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &asoc_acp_cpu_dai_ops,
+},
+{
+ .name = "acp-i2s-bt",
+ .id = I2S_BT_INSTANCE,
+ .playback = {
+ .stream_name = "I2S BT Playback",
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .stream_name = "I2S BT Capture",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &asoc_acp_cpu_dai_ops,
+},
+{
+ .name = "acp-i2s-hs",
+ .id = I2S_HS_INSTANCE,
+ .playback = {
+ .stream_name = "I2S HS Playback",
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .stream_name = "I2S HS Capture",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &asoc_acp_cpu_dai_ops,
+},
+{
+ .name = "acp-pdm-dmic",
+ .id = DMIC_INSTANCE,
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &acp_dmic_dai_ops,
+},
+};
+
+static int acp6x_master_clock_generate(struct device *dev)
+{
+ int data = 0;
+ struct pci_dev *smn_dev;
+
+ smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, HOST_BRIDGE_ID, NULL);
+ if (!smn_dev) {
+ dev_err(dev, "Failed to get host bridge device\n");
+ return -ENODEV;
+ }
+
+ smn_write(smn_dev, MP1_C2PMSG_93, 0);
+ smn_write(smn_dev, MP1_C2PMSG_85, 0xC4);
+ smn_write(smn_dev, MP1_C2PMSG_69, 0x4);
+ read_poll_timeout(smn_read, data, data, DELAY_US,
+ ACP_TIMEOUT, false, smn_dev, MP1_C2PMSG_93);
+ return 0;
+}
+
+static int rembrandt_audio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct acp_chip_info *chip;
+ struct acp_dev_data *adata;
+ struct resource *res;
+
+ chip = dev_get_platdata(&pdev->dev);
+ if (!chip || !chip->base) {
+ dev_err(&pdev->dev, "ACP chip data is NULL\n");
+ return -ENODEV;
+ }
+
+ if (chip->acp_rev != ACP6X_DEV) {
+ dev_err(&pdev->dev, "Un-supported ACP Revision %d\n", chip->acp_rev);
+ return -ENODEV;
+ }
+
+ adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem");
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!adata->acp_base)
+ return -ENOMEM;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq");
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
+ return -ENODEV;
+ }
+
+ adata->i2s_irq = res->start;
+ adata->dev = dev;
+ adata->dai_driver = acp_rmb_dai;
+ adata->num_dai = ARRAY_SIZE(acp_rmb_dai);
+ adata->rsrc = &rsrc;
+
+ adata->machines = snd_soc_acpi_amd_rmb_acp_machines;
+ acp_machine_select(adata);
+
+ dev_set_drvdata(dev, adata);
+ acp6x_master_clock_generate(dev);
+ acp_enable_interrupts(adata);
+ acp_platform_register(dev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ return 0;
+}
+
+static void rembrandt_audio_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+
+ acp_disable_interrupts(adata);
+ acp_platform_unregister(dev);
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int __maybe_unused rmb_pcm_resume(struct device *dev)
+{
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+ struct acp_stream *stream;
+ struct snd_pcm_substream *substream;
+ snd_pcm_uframes_t buf_in_frames;
+ u64 buf_size;
+
+ acp6x_master_clock_generate(dev);
+ spin_lock(&adata->acp_lock);
+ list_for_each_entry(stream, &adata->stream_list, list) {
+ substream = stream->substream;
+ if (substream && substream->runtime) {
+ buf_in_frames = (substream->runtime->buffer_size);
+ buf_size = frames_to_bytes(substream->runtime, buf_in_frames);
+ config_pte_for_stream(adata, stream);
+ config_acp_dma(adata, stream, buf_size);
+ if (stream->dai_id)
+ restore_acp_i2s_params(substream, adata, stream);
+ else
+ restore_acp_pdm_params(substream, adata);
+ }
+ }
+ spin_unlock(&adata->acp_lock);
+ return 0;
+}
+
+static const struct dev_pm_ops rmb_dma_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(NULL, rmb_pcm_resume)
+};
+
+static struct platform_driver rembrandt_driver = {
+ .probe = rembrandt_audio_probe,
+ .remove_new = rembrandt_audio_remove,
+ .driver = {
+ .name = "acp_asoc_rembrandt",
+ .pm = &rmb_dma_pm_ops,
+ },
+};
+
+module_platform_driver(rembrandt_driver);
+
+MODULE_DESCRIPTION("AMD ACP Rembrandt Driver");
+MODULE_IMPORT_NS(SND_SOC_ACP_COMMON);
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c
new file mode 100644
index 0000000000..54235cad9c
--- /dev/null
+++ b/sound/soc/amd/acp/acp-renoir.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2021 Advanced Micro Devices, Inc.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+//
+
+/*
+ * Hardware interface for Renoir ACP block
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/dma-mapping.h>
+
+#include "amd.h"
+
+#define DRV_NAME "acp_asoc_renoir"
+
+static struct acp_resource rsrc = {
+ .offset = 20,
+ .no_of_ctrls = 1,
+ .irqp_used = 0,
+ .irq_reg_offset = 0x1800,
+ .i2s_pin_cfg_offset = 0x1400,
+ .i2s_mode = 0x04,
+ .scratch_reg_offset = 0x12800,
+ .sram_pte_offset = 0x02052800,
+};
+
+static struct snd_soc_acpi_codecs amp_rt1019 = {
+ .num_codecs = 1,
+ .codecs = {"10EC1019"}
+};
+
+static struct snd_soc_acpi_codecs amp_max = {
+ .num_codecs = 1,
+ .codecs = {"MX98360A"}
+};
+
+static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = {
+ {
+ .id = "10EC5682",
+ .drv_name = "acp3xalc56821019",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_rt1019,
+ },
+ {
+ .id = "RTL5682",
+ .drv_name = "acp3xalc5682sm98360",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_max,
+ },
+ {
+ .id = "RTL5682",
+ .drv_name = "acp3xalc5682s1019",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &amp_rt1019,
+ },
+ {
+ .id = "AMDI1019",
+ .drv_name = "renoir-acp",
+ },
+ {},
+};
+
+static struct snd_soc_dai_driver acp_renoir_dai[] = {
+{
+ .name = "acp-i2s-sp",
+ .id = I2S_SP_INSTANCE,
+ .playback = {
+ .stream_name = "I2S SP Playback",
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .stream_name = "I2S SP Capture",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &asoc_acp_cpu_dai_ops,
+},
+{
+ .name = "acp-i2s-bt",
+ .id = I2S_BT_INSTANCE,
+ .playback = {
+ .stream_name = "I2S BT Playback",
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .stream_name = "I2S BT Capture",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &asoc_acp_cpu_dai_ops,
+},
+{
+ .name = "acp-pdm-dmic",
+ .id = DMIC_INSTANCE,
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &acp_dmic_dai_ops,
+},
+};
+
+
+static int renoir_audio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct acp_chip_info *chip;
+ struct acp_dev_data *adata;
+ struct resource *res;
+ int ret;
+
+ chip = dev_get_platdata(&pdev->dev);
+ if (!chip || !chip->base) {
+ dev_err(&pdev->dev, "ACP chip data is NULL\n");
+ return -ENODEV;
+ }
+
+ if (chip->acp_rev != ACP3X_DEV) {
+ dev_err(&pdev->dev, "Un-supported ACP Revision %d\n", chip->acp_rev);
+ return -ENODEV;
+ }
+
+ adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem");
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!adata->acp_base)
+ return -ENOMEM;
+
+ ret = platform_get_irq_byname(pdev, "acp_dai_irq");
+ if (ret < 0)
+ return ret;
+ adata->i2s_irq = ret;
+
+ adata->dev = dev;
+ adata->dai_driver = acp_renoir_dai;
+ adata->num_dai = ARRAY_SIZE(acp_renoir_dai);
+ adata->rsrc = &rsrc;
+
+ adata->machines = snd_soc_acpi_amd_acp_machines;
+ acp_machine_select(adata);
+
+ dev_set_drvdata(dev, adata);
+ acp_enable_interrupts(adata);
+ acp_platform_register(dev);
+
+ return 0;
+}
+
+static void renoir_audio_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct acp_dev_data *adata = dev_get_drvdata(dev);
+
+ acp_disable_interrupts(adata);
+ acp_platform_unregister(dev);
+}
+
+static struct platform_driver renoir_driver = {
+ .probe = renoir_audio_probe,
+ .remove_new = renoir_audio_remove,
+ .driver = {
+ .name = "acp_asoc_renoir",
+ },
+};
+
+module_platform_driver(renoir_driver);
+
+MODULE_DESCRIPTION("AMD ACP Renoir Driver");
+MODULE_IMPORT_NS(SND_SOC_ACP_COMMON);
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/acp/acp-sof-mach.c b/sound/soc/amd/acp/acp-sof-mach.c
new file mode 100644
index 0000000000..5223033a12
--- /dev/null
+++ b/sound/soc/amd/acp/acp-sof-mach.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2021 Advanced Micro Devices, Inc.
+//
+// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+//
+
+/*
+ * SOF Machine Driver Support for ACP HW block
+ */
+
+#include <sound/core.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-dapm.h>
+#include <linux/dmi.h>
+#include <linux/module.h>
+
+#include "acp-mach.h"
+
+static struct acp_card_drvdata sof_rt5682_rt1019_data = {
+ .hs_cpu_id = I2S_SP,
+ .amp_cpu_id = I2S_SP,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = RT5682,
+ .amp_codec_id = RT1019,
+ .dmic_codec_id = DMIC,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata sof_rt5682_max_data = {
+ .hs_cpu_id = I2S_SP,
+ .amp_cpu_id = I2S_SP,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = RT5682,
+ .amp_codec_id = MAX98360A,
+ .dmic_codec_id = DMIC,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata sof_rt5682s_rt1019_data = {
+ .hs_cpu_id = I2S_SP,
+ .amp_cpu_id = I2S_SP,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = RT5682S,
+ .amp_codec_id = RT1019,
+ .dmic_codec_id = DMIC,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata sof_rt5682s_max_data = {
+ .hs_cpu_id = I2S_SP,
+ .amp_cpu_id = I2S_SP,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = RT5682S,
+ .amp_codec_id = MAX98360A,
+ .dmic_codec_id = DMIC,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata sof_nau8825_data = {
+ .hs_cpu_id = I2S_HS,
+ .amp_cpu_id = I2S_HS,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = NAU8825,
+ .amp_codec_id = MAX98360A,
+ .dmic_codec_id = DMIC,
+ .soc_mclk = true,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = {
+ .hs_cpu_id = I2S_HS,
+ .amp_cpu_id = I2S_HS,
+ .dmic_cpu_id = DMIC,
+ .hs_codec_id = RT5682S,
+ .amp_codec_id = RT1019,
+ .dmic_codec_id = DMIC,
+ .soc_mclk = true,
+ .tdm_mode = false,
+};
+
+static struct acp_card_drvdata sof_nau8821_max98388_data = {
+ .hs_cpu_id = I2S_SP,
+ .amp_cpu_id = I2S_HS,
+ .dmic_cpu_id = NONE,
+ .hs_codec_id = NAU8821,
+ .amp_codec_id = MAX98388,
+ .dmic_codec_id = NONE,
+ .soc_mclk = true,
+ .tdm_mode = false,
+};
+
+static int acp_sof_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = NULL;
+ struct device *dev = &pdev->dev;
+ const struct dmi_system_id *dmi_id;
+ struct acp_card_drvdata *acp_card_drvdata;
+ int ret;
+
+ if (!pdev->id_entry)
+ return -EINVAL;
+
+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+
+ card->dev = dev;
+ card->owner = THIS_MODULE;
+ card->name = pdev->id_entry->name;
+ card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
+ /* Widgets and controls added per-codec in acp-mach-common.c */
+
+ acp_card_drvdata = card->drvdata;
+ dmi_id = dmi_first_match(acp_quirk_table);
+ if (dmi_id && dmi_id->driver_data)
+ acp_card_drvdata->tdm_mode = dmi_id->driver_data;
+
+ acp_sofdsp_dai_links_create(card);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "devm_snd_soc_register_card(%s) failed: %d\n",
+ card->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id board_ids[] = {
+ {
+ .name = "rt5682-rt1019",
+ .driver_data = (kernel_ulong_t)&sof_rt5682_rt1019_data
+ },
+ {
+ .name = "rt5682-max",
+ .driver_data = (kernel_ulong_t)&sof_rt5682_max_data
+ },
+ {
+ .name = "rt5682s-max",
+ .driver_data = (kernel_ulong_t)&sof_rt5682s_max_data
+ },
+ {
+ .name = "rt5682s-rt1019",
+ .driver_data = (kernel_ulong_t)&sof_rt5682s_rt1019_data
+ },
+ {
+ .name = "nau8825-max",
+ .driver_data = (kernel_ulong_t)&sof_nau8825_data
+ },
+ {
+ .name = "rt5682s-hs-rt1019",
+ .driver_data = (kernel_ulong_t)&sof_rt5682s_hs_rt1019_data
+ },
+ {
+ .name = "nau8821-max",
+ .driver_data = (kernel_ulong_t)&sof_nau8821_max98388_data
+ },
+ { }
+};
+static struct platform_driver acp_asoc_audio = {
+ .driver = {
+ .name = "sof_mach",
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = acp_sof_probe,
+ .id_table = board_ids,
+};
+
+module_platform_driver(acp_asoc_audio);
+
+MODULE_IMPORT_NS(SND_SOC_AMD_MACH);
+MODULE_DESCRIPTION("ACP chrome SOF audio support");
+MODULE_ALIAS("platform:rt5682-rt1019");
+MODULE_ALIAS("platform:rt5682-max");
+MODULE_ALIAS("platform:rt5682s-max");
+MODULE_ALIAS("platform:rt5682s-rt1019");
+MODULE_ALIAS("platform:nau8825-max");
+MODULE_ALIAS("platform:rt5682s-hs-rt1019");
+MODULE_ALIAS("platform:nau8821-max");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h
new file mode 100644
index 0000000000..d6cfae6ec5
--- /dev/null
+++ b/sound/soc/amd/acp/amd.h
@@ -0,0 +1,303 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Author: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+ */
+
+#ifndef __AMD_ACP_H
+#define __AMD_ACP_H
+
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-dai.h>
+
+#include "chip_offset_byte.h"
+
+#define ACP3X_DEV 3
+#define ACP6X_DEV 6
+
+#define DMIC_INSTANCE 0x00
+#define I2S_SP_INSTANCE 0x01
+#define I2S_BT_INSTANCE 0x02
+#define I2S_HS_INSTANCE 0x03
+
+#define MEM_WINDOW_START 0x4080000
+
+#define ACP_I2S_REG_START 0x1242400
+#define ACP_I2S_REG_END 0x1242810
+#define ACP3x_I2STDM_REG_START 0x1242400
+#define ACP3x_I2STDM_REG_END 0x1242410
+#define ACP3x_BT_TDM_REG_START 0x1242800
+#define ACP3x_BT_TDM_REG_END 0x1242810
+
+#define THRESHOLD(bit, base) ((bit) + (base))
+#define I2S_RX_THRESHOLD(base) THRESHOLD(7, base)
+#define I2S_TX_THRESHOLD(base) THRESHOLD(8, base)
+#define BT_TX_THRESHOLD(base) THRESHOLD(6, base)
+#define BT_RX_THRESHOLD(base) THRESHOLD(5, base)
+#define HS_TX_THRESHOLD(base) THRESHOLD(4, base)
+#define HS_RX_THRESHOLD(base) THRESHOLD(3, base)
+
+#define ACP_SRAM_SP_PB_PTE_OFFSET 0x0
+#define ACP_SRAM_SP_CP_PTE_OFFSET 0x100
+#define ACP_SRAM_BT_PB_PTE_OFFSET 0x200
+#define ACP_SRAM_BT_CP_PTE_OFFSET 0x300
+#define ACP_SRAM_PDM_PTE_OFFSET 0x400
+#define ACP_SRAM_HS_PB_PTE_OFFSET 0x500
+#define ACP_SRAM_HS_CP_PTE_OFFSET 0x600
+#define PAGE_SIZE_4K_ENABLE 0x2
+
+#define I2S_SP_TX_MEM_WINDOW_START 0x4000000
+#define I2S_SP_RX_MEM_WINDOW_START 0x4020000
+#define I2S_BT_TX_MEM_WINDOW_START 0x4040000
+#define I2S_BT_RX_MEM_WINDOW_START 0x4060000
+#define I2S_HS_TX_MEM_WINDOW_START 0x40A0000
+#define I2S_HS_RX_MEM_WINDOW_START 0x40C0000
+
+#define SP_PB_FIFO_ADDR_OFFSET 0x500
+#define SP_CAPT_FIFO_ADDR_OFFSET 0x700
+#define BT_PB_FIFO_ADDR_OFFSET 0x900
+#define BT_CAPT_FIFO_ADDR_OFFSET 0xB00
+#define HS_PB_FIFO_ADDR_OFFSET 0xD00
+#define HS_CAPT_FIFO_ADDR_OFFSET 0xF00
+#define PLAYBACK_MIN_NUM_PERIODS 2
+#define PLAYBACK_MAX_NUM_PERIODS 8
+#define PLAYBACK_MAX_PERIOD_SIZE 8192
+#define PLAYBACK_MIN_PERIOD_SIZE 1024
+#define CAPTURE_MIN_NUM_PERIODS 2
+#define CAPTURE_MAX_NUM_PERIODS 8
+#define CAPTURE_MAX_PERIOD_SIZE 8192
+#define CAPTURE_MIN_PERIOD_SIZE 1024
+
+#define MAX_BUFFER 65536
+#define MIN_BUFFER MAX_BUFFER
+#define FIFO_SIZE 0x100
+#define DMA_SIZE 0x40
+#define FRM_LEN 0x100
+
+#define ACP3x_ITER_IRER_SAMP_LEN_MASK 0x38
+
+#define ACP_MAX_STREAM 8
+
+#define TDM_ENABLE 1
+#define TDM_DISABLE 0
+
+#define SLOT_WIDTH_8 0x8
+#define SLOT_WIDTH_16 0x10
+#define SLOT_WIDTH_24 0x18
+#define SLOT_WIDTH_32 0x20
+
+#define ACP6X_PGFSM_CONTROL 0x1024
+#define ACP6X_PGFSM_STATUS 0x1028
+
+#define ACP_SOFT_RST_DONE_MASK 0x00010001
+
+#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00
+#define ACP_PGFSM_STATUS_MASK 0x03
+#define ACP_POWERED_ON 0x00
+#define ACP_POWER_ON_IN_PROGRESS 0x01
+#define ACP_POWERED_OFF 0x02
+#define ACP_POWER_OFF_IN_PROGRESS 0x03
+
+#define ACP_ERROR_MASK 0x20000000
+#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xffffffff
+
+#define ACP_TIMEOUT 500
+#define DELAY_US 5
+#define ACP_SUSPEND_DELAY_MS 2000
+
+#define PDM_DMA_STAT 0x10
+#define PDM_DMA_INTR_MASK 0x10000
+#define PDM_DEC_64 0x2
+#define PDM_CLK_FREQ_MASK 0x07
+#define PDM_MISC_CTRL_MASK 0x10
+#define PDM_ENABLE 0x01
+#define PDM_DISABLE 0x00
+#define DMA_EN_MASK 0x02
+#define DELAY_US 5
+#define PDM_TIMEOUT 1000
+#define ACP_REGION2_OFFSET 0x02000000
+
+struct acp_chip_info {
+ char *name; /* Platform name */
+ unsigned int acp_rev; /* ACP Revision id */
+ void __iomem *base; /* ACP memory PCI base */
+ struct platform_device *chip_pdev;
+};
+
+struct acp_stream {
+ struct list_head list;
+ struct snd_pcm_substream *substream;
+ int irq_bit;
+ int dai_id;
+ int id;
+ int dir;
+ u64 bytescount;
+ u32 reg_offset;
+ u32 pte_offset;
+ u32 fifo_offset;
+};
+
+struct acp_resource {
+ int offset;
+ int no_of_ctrls;
+ int irqp_used;
+ bool soc_mclk;
+ u32 irq_reg_offset;
+ u32 i2s_pin_cfg_offset;
+ int i2s_mode;
+ u64 scratch_reg_offset;
+ u64 sram_pte_offset;
+};
+
+struct acp_dev_data {
+ char *name;
+ struct device *dev;
+ void __iomem *acp_base;
+ unsigned int i2s_irq;
+
+ bool tdm_mode;
+ /* SOC specific dais */
+ struct snd_soc_dai_driver *dai_driver;
+ int num_dai;
+
+ struct list_head stream_list;
+ spinlock_t acp_lock;
+
+ struct snd_soc_acpi_mach *machines;
+ struct platform_device *mach_dev;
+
+ u32 bclk_div;
+ u32 lrclk_div;
+
+ struct acp_resource *rsrc;
+ u32 ch_mask;
+ u32 tdm_tx_fmt[3];
+ u32 tdm_rx_fmt[3];
+ u32 xfer_tx_resolution[3];
+ u32 xfer_rx_resolution[3];
+};
+
+union acp_i2stdm_mstrclkgen {
+ struct {
+ u32 i2stdm_master_mode : 1;
+ u32 i2stdm_format_mode : 1;
+ u32 i2stdm_lrclk_div_val : 9;
+ u32 i2stdm_bclk_div_val : 11;
+ u32:10;
+ } bitfields, bits;
+ u32 u32_all;
+};
+
+extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops;
+extern const struct snd_soc_dai_ops acp_dmic_dai_ops;
+
+int acp_platform_register(struct device *dev);
+int acp_platform_unregister(struct device *dev);
+
+int acp_machine_select(struct acp_dev_data *adata);
+
+int smn_read(struct pci_dev *dev, u32 smn_addr);
+int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data);
+
+int acp_init(struct acp_chip_info *chip);
+int acp_deinit(void __iomem *base);
+void acp_enable_interrupts(struct acp_dev_data *adata);
+void acp_disable_interrupts(struct acp_dev_data *adata);
+/* Machine configuration */
+int snd_amd_acp_find_config(struct pci_dev *pci);
+
+void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream);
+void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size);
+void restore_acp_pdm_params(struct snd_pcm_substream *substream,
+ struct acp_dev_data *adata);
+
+int restore_acp_i2s_params(struct snd_pcm_substream *substream,
+ struct acp_dev_data *adata, struct acp_stream *stream);
+
+static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction)
+{
+ u64 byte_count = 0, low = 0, high = 0;
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (dai_id) {
+ case I2S_BT_INSTANCE:
+ high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
+ low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH);
+ low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW);
+ break;
+ case I2S_HS_INSTANCE:
+ high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH);
+ low = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_LOW);
+ break;
+ default:
+ dev_err(adata->dev, "Invalid dai id %x\n", dai_id);
+ goto POINTER_RETURN_BYTES;
+ }
+ } else {
+ switch (dai_id) {
+ case I2S_BT_INSTANCE:
+ high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
+ low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH);
+ low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW);
+ break;
+ case I2S_HS_INSTANCE:
+ high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH);
+ low = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_LOW);
+ break;
+ case DMIC_INSTANCE:
+ high = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);
+ low = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);
+ break;
+ default:
+ dev_err(adata->dev, "Invalid dai id %x\n", dai_id);
+ goto POINTER_RETURN_BYTES;
+ }
+ }
+ /* Get 64 bit value from two 32 bit registers */
+ byte_count = (high << 32) | low;
+
+POINTER_RETURN_BYTES:
+ return byte_count;
+}
+
+static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id)
+{
+ union acp_i2stdm_mstrclkgen mclkgen;
+ u32 master_reg;
+
+ switch (dai_id) {
+ case I2S_SP_INSTANCE:
+ master_reg = ACP_I2STDM0_MSTRCLKGEN;
+ break;
+ case I2S_BT_INSTANCE:
+ master_reg = ACP_I2STDM1_MSTRCLKGEN;
+ break;
+ case I2S_HS_INSTANCE:
+ master_reg = ACP_I2STDM2_MSTRCLKGEN;
+ break;
+ default:
+ master_reg = ACP_I2STDM0_MSTRCLKGEN;
+ break;
+ }
+
+ mclkgen.bits.i2stdm_master_mode = 0x1;
+ mclkgen.bits.i2stdm_format_mode = 0x00;
+
+ mclkgen.bits.i2stdm_bclk_div_val = adata->bclk_div;
+ mclkgen.bits.i2stdm_lrclk_div_val = adata->lrclk_div;
+ writel(mclkgen.u32_all, adata->acp_base + master_reg);
+}
+#endif
diff --git a/sound/soc/amd/acp/chip_offset_byte.h b/sound/soc/amd/acp/chip_offset_byte.h
new file mode 100644
index 0000000000..ce3948e067
--- /dev/null
+++ b/sound/soc/amd/acp/chip_offset_byte.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Author: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+ */
+
+#ifndef _ACP_IP_OFFSET_HEADER
+#define _ACP_IP_OFFSET_HEADER
+
+#define ACPAXI2AXI_ATU_CTRL 0xC40
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0xC20
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0xC24
+
+#define ACP_PGFSM_CONTROL 0x141C
+#define ACP_PGFSM_STATUS 0x1420
+#define ACP_SOFT_RESET 0x1000
+#define ACP_CONTROL 0x1004
+
+#define ACP_EXTERNAL_INTR_REG_ADDR(adata, offset, ctrl) \
+ (adata->acp_base + adata->rsrc->irq_reg_offset + offset + (ctrl * 0x04))
+
+#define ACP_EXTERNAL_INTR_ENB(adata) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x0, 0x0)
+#define ACP_EXTERNAL_INTR_CNTL(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x4, ctrl)
+#define ACP_EXTERNAL_INTR_STAT(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, \
+ (0x4 + (adata->rsrc->no_of_ctrls * 0x04)), ctrl)
+
+/* Registers from ACP_AUDIO_BUFFERS block */
+
+#define ACP_I2S_RX_RINGBUFADDR 0x2000
+#define ACP_I2S_RX_RINGBUFSIZE 0x2004
+#define ACP_I2S_RX_LINKPOSITIONCNTR 0x2008
+#define ACP_I2S_RX_FIFOADDR 0x200C
+#define ACP_I2S_RX_FIFOSIZE 0x2010
+#define ACP_I2S_RX_DMA_SIZE 0x2014
+#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x2018
+#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x201C
+#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x2020
+#define ACP_I2S_TX_RINGBUFADDR 0x2024
+#define ACP_I2S_TX_RINGBUFSIZE 0x2028
+#define ACP_I2S_TX_LINKPOSITIONCNTR 0x202C
+#define ACP_I2S_TX_FIFOADDR 0x2030
+#define ACP_I2S_TX_FIFOSIZE 0x2034
+#define ACP_I2S_TX_DMA_SIZE 0x2038
+#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x203C
+#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x2040
+#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x2044
+#define ACP_BT_RX_RINGBUFADDR 0x2048
+#define ACP_BT_RX_RINGBUFSIZE 0x204C
+#define ACP_BT_RX_LINKPOSITIONCNTR 0x2050
+#define ACP_BT_RX_FIFOADDR 0x2054
+#define ACP_BT_RX_FIFOSIZE 0x2058
+#define ACP_BT_RX_DMA_SIZE 0x205C
+#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x2060
+#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x2064
+#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x2068
+#define ACP_BT_TX_RINGBUFADDR 0x206C
+#define ACP_BT_TX_RINGBUFSIZE 0x2070
+#define ACP_BT_TX_LINKPOSITIONCNTR 0x2074
+#define ACP_BT_TX_FIFOADDR 0x2078
+#define ACP_BT_TX_FIFOSIZE 0x207C
+#define ACP_BT_TX_DMA_SIZE 0x2080
+#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x2084
+#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x2088
+#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x208C
+#define ACP_HS_RX_RINGBUFADDR 0x3A90
+#define ACP_HS_RX_RINGBUFSIZE 0x3A94
+#define ACP_HS_RX_LINKPOSITIONCNTR 0x3A98
+#define ACP_HS_RX_FIFOADDR 0x3A9C
+#define ACP_HS_RX_FIFOSIZE 0x3AA0
+#define ACP_HS_RX_DMA_SIZE 0x3AA4
+#define ACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x3AA8
+#define ACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x3AAC
+#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x3AB0
+#define ACP_HS_TX_RINGBUFADDR 0x3AB4
+#define ACP_HS_TX_RINGBUFSIZE 0x3AB8
+#define ACP_HS_TX_LINKPOSITIONCNTR 0x3ABC
+#define ACP_HS_TX_FIFOADDR 0x3AC0
+#define ACP_HS_TX_FIFOSIZE 0x3AC4
+#define ACP_HS_TX_DMA_SIZE 0x3AC8
+#define ACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x3ACC
+#define ACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x3AD0
+#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x3AD4
+
+#define ACP_I2STDM_IER 0x2400
+#define ACP_I2STDM_IRER 0x2404
+#define ACP_I2STDM_RXFRMT 0x2408
+#define ACP_I2STDM_ITER 0x240C
+#define ACP_I2STDM_TXFRMT 0x2410
+
+/* Registers from ACP_BT_TDM block */
+
+#define ACP_BTTDM_IER 0x2800
+#define ACP_BTTDM_IRER 0x2804
+#define ACP_BTTDM_RXFRMT 0x2808
+#define ACP_BTTDM_ITER 0x280C
+#define ACP_BTTDM_TXFRMT 0x2810
+
+/* Registers from ACP_HS_TDM block */
+#define ACP_HSTDM_IER 0x2814
+#define ACP_HSTDM_IRER 0x2818
+#define ACP_HSTDM_RXFRMT 0x281C
+#define ACP_HSTDM_ITER 0x2820
+#define ACP_HSTDM_TXFRMT 0x2824
+
+/* Registers from ACP_WOV_PDM block */
+
+#define ACP_WOV_PDM_ENABLE 0x2C04
+#define ACP_WOV_PDM_DMA_ENABLE 0x2C08
+#define ACP_WOV_RX_RINGBUFADDR 0x2C0C
+#define ACP_WOV_RX_RINGBUFSIZE 0x2C10
+#define ACP_WOV_RX_LINKPOSITIONCNTR 0x2C14
+#define ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH 0x2C18
+#define ACP_WOV_RX_LINEARPOSITIONCNTR_LOW 0x2C1C
+#define ACP_WOV_RX_INTR_WATERMARK_SIZE 0x2C20
+#define ACP_WOV_PDM_FIFO_FLUSH 0x2C24
+#define ACP_WOV_PDM_NO_OF_CHANNELS 0x2C28
+#define ACP_WOV_PDM_DECIMATION_FACTOR 0x2C2C
+#define ACP_WOV_PDM_VAD_CTRL 0x2C30
+#define ACP_WOV_BUFFER_STATUS 0x2C58
+#define ACP_WOV_MISC_CTRL 0x2C5C
+#define ACP_WOV_CLK_CTRL 0x2C60
+#define ACP_PDM_VAD_DYNAMIC_CLK_GATING_EN 0x2C64
+#define ACP_WOV_ERROR_STATUS_REGISTER 0x2C68
+
+#define ACP_I2STDM0_MSTRCLKGEN 0x2414
+#define ACP_I2STDM1_MSTRCLKGEN 0x2418
+#define ACP_I2STDM2_MSTRCLKGEN 0x241C
+#endif
diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c
new file mode 100644
index 0000000000..28ad5f5b9a
--- /dev/null
+++ b/sound/soc/amd/acp3x-rt5682-max9836.c
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Machine driver for AMD ACP Audio engine using DA7219 & MAX98357 codec.
+//
+//Copyright 2016 Advanced Micro Devices, Inc.
+
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/acpi.h>
+
+#include "raven/acp3x.h"
+#include "../codecs/rt5682.h"
+#include "../codecs/rt1015.h"
+
+#define PCO_PLAT_CLK 48000000
+#define RT5682_PLL_FREQ (48000 * 512)
+#define DUAL_CHANNEL 2
+
+static struct snd_soc_jack pco_jack;
+static struct snd_soc_jack_pin pco_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+static struct clk *rt5682_dai_wclk;
+static struct clk *rt5682_dai_bclk;
+static struct gpio_desc *dmic_sel;
+void *soc_is_rltk_max(struct device *dev);
+
+enum {
+ RT5682 = 0,
+ MAX,
+ EC,
+};
+
+static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret;
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_component *component = codec_dai->component;
+
+ dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+
+ /* set rt5682 dai fmt */
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP);
+ if (ret < 0) {
+ dev_err(rtd->card->dev,
+ "Failed to set rt5682 dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ /* set codec PLL */
+ ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
+ PCO_PLAT_CLK, RT5682_PLL_FREQ);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set rt5682 PLL: %d\n", ret);
+ return ret;
+ }
+
+ /* Set codec sysclk */
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
+ RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(rtd->dev,
+ "Failed to set rt5682 SYSCLK: %d\n", ret);
+ return ret;
+ }
+
+ /* Set tdm/i2s1 master bclk ratio */
+ ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
+ if (ret < 0) {
+ dev_err(rtd->dev,
+ "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
+ return ret;
+ }
+
+ rt5682_dai_wclk = clk_get(component->dev, "rt5682-dai-wclk");
+ rt5682_dai_bclk = clk_get(component->dev, "rt5682-dai-bclk");
+
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
+ SND_JACK_HEADSET |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &pco_jack,
+ pco_jack_pins,
+ ARRAY_SIZE(pco_jack_pins));
+ if (ret) {
+ dev_err(card->dev, "HP jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+ snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+ snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+ ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int rt5682_clk_enable(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+ /* RT5682 will support only 48K output with 48M mclk */
+ clk_set_rate(rt5682_dai_wclk, 48000);
+ clk_set_rate(rt5682_dai_bclk, 48000 * 64);
+ ret = clk_prepare_enable(rt5682_dai_wclk);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't enable wclk %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int acp3x_1015_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai;
+ int srate, i, ret;
+
+ ret = 0;
+ srate = params_rate(params);
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+ if (strcmp(codec_dai->name, "rt1015-aif"))
+ continue;
+
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
+ 64 * srate, 256 * srate);
+ if (ret < 0)
+ return ret;
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
+ 256 * srate, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ return ret;
+ }
+ return ret;
+}
+
+static void rt5682_clk_disable(void)
+{
+ clk_disable_unprepare(rt5682_dai_wclk);
+}
+
+static const unsigned int channels[] = {
+ DUAL_CHANNEL,
+};
+
+static const unsigned int rates[] = {
+ 48000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
+ .count = ARRAY_SIZE(channels),
+ .list = channels,
+ .mask = 0,
+};
+
+static int acp3x_5682_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ machine->play_i2s_instance = I2S_SP_INSTANCE;
+ machine->cap_i2s_instance = I2S_SP_INSTANCE;
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+ return rt5682_clk_enable(substream);
+}
+
+static int acp3x_max_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ machine->play_i2s_instance = I2S_BT_INSTANCE;
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+ return rt5682_clk_enable(substream);
+}
+
+static int acp3x_ec_dmic0_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+ machine->cap_i2s_instance = I2S_BT_INSTANCE;
+ snd_soc_dai_set_bclk_ratio(codec_dai, 64);
+
+ return rt5682_clk_enable(substream);
+}
+
+static int dmic_switch;
+
+static int dmic_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = dmic_switch;
+ return 0;
+}
+
+static int dmic_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ if (dmic_sel) {
+ dmic_switch = ucontrol->value.integer.value[0];
+ gpiod_set_value(dmic_sel, dmic_switch);
+ }
+ return 0;
+}
+
+static void rt5682_shutdown(struct snd_pcm_substream *substream)
+{
+ rt5682_clk_disable();
+}
+
+static const struct snd_soc_ops acp3x_5682_ops = {
+ .startup = acp3x_5682_startup,
+ .shutdown = rt5682_shutdown,
+};
+
+static const struct snd_soc_ops acp3x_max_play_ops = {
+ .startup = acp3x_max_startup,
+ .shutdown = rt5682_shutdown,
+ .hw_params = acp3x_1015_hw_params,
+};
+
+static const struct snd_soc_ops acp3x_ec_cap0_ops = {
+ .startup = acp3x_ec_dmic0_startup,
+ .shutdown = rt5682_shutdown,
+};
+
+SND_SOC_DAILINK_DEF(acp3x_i2s,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.0")));
+SND_SOC_DAILINK_DEF(acp3x_bt,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.2")));
+
+SND_SOC_DAILINK_DEF(rt5682,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
+SND_SOC_DAILINK_DEF(max,
+ DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", "HiFi")));
+SND_SOC_DAILINK_DEF(rt1015p,
+ DAILINK_COMP_ARRAY(COMP_CODEC("RTL1015:00", "HiFi")));
+SND_SOC_DAILINK_DEF(rt1015,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1015:00", "rt1015-aif"),
+ COMP_CODEC("i2c-10EC1015:01", "rt1015-aif")));
+SND_SOC_DAILINK_DEF(cros_ec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("GOOG0013:00", "EC Codec I2S RX")));
+
+SND_SOC_DAILINK_DEF(platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("acp3x_rv_i2s_dma.0")));
+
+static struct snd_soc_codec_conf rt1015_conf[] = {
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1015:00"),
+ .name_prefix = "Left",
+ },
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1015:01"),
+ .name_prefix = "Right",
+ },
+};
+
+static struct snd_soc_dai_link acp3x_dai[] = {
+ [RT5682] = {
+ .name = "acp3x-5682-play",
+ .stream_name = "Playback",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBP_CFP,
+ .init = acp3x_5682_init,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .ops = &acp3x_5682_ops,
+ SND_SOC_DAILINK_REG(acp3x_i2s, rt5682, platform),
+ },
+ [MAX] = {
+ .name = "acp3x-max98357-play",
+ .stream_name = "HiFi Playback",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_playback = 1,
+ .ops = &acp3x_max_play_ops,
+ .cpus = acp3x_bt,
+ .num_cpus = ARRAY_SIZE(acp3x_bt),
+ .platforms = platform,
+ .num_platforms = ARRAY_SIZE(platform),
+ },
+ [EC] = {
+ .name = "acp3x-ec-dmic0-capture",
+ .stream_name = "Capture DMIC0",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_capture = 1,
+ .ops = &acp3x_ec_cap0_ops,
+ SND_SOC_DAILINK_REG(acp3x_bt, cros_ec, platform),
+ },
+};
+
+static const char * const dmic_mux_text[] = {
+ "Front Mic",
+ "Rear Mic",
+};
+
+static SOC_ENUM_SINGLE_DECL(
+ acp3x_dmic_enum, SND_SOC_NOPM, 0, dmic_mux_text);
+
+static const struct snd_kcontrol_new acp3x_dmic_mux_control =
+ SOC_DAPM_ENUM_EXT("DMIC Select Mux", acp3x_dmic_enum,
+ dmic_get, dmic_set);
+
+static const struct snd_soc_dapm_widget acp3x_5682_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_SPK("Spk", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0,
+ &acp3x_dmic_mux_control),
+};
+
+static const struct snd_soc_dapm_route acp3x_5682_audio_route[] = {
+ {"Headphone Jack", NULL, "HPOL"},
+ {"Headphone Jack", NULL, "HPOR"},
+ {"IN1P", NULL, "Headset Mic"},
+ {"Spk", NULL, "Speaker"},
+ {"Dmic Mux", "Front Mic", "DMIC"},
+ {"Dmic Mux", "Rear Mic", "DMIC"},
+};
+
+static const struct snd_kcontrol_new acp3x_5682_mc_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Spk"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static struct snd_soc_card acp3x_5682 = {
+ .name = "acp3xalc5682m98357",
+ .owner = THIS_MODULE,
+ .dai_link = acp3x_dai,
+ .num_links = ARRAY_SIZE(acp3x_dai),
+ .dapm_widgets = acp3x_5682_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(acp3x_5682_widgets),
+ .dapm_routes = acp3x_5682_audio_route,
+ .num_dapm_routes = ARRAY_SIZE(acp3x_5682_audio_route),
+ .controls = acp3x_5682_mc_controls,
+ .num_controls = ARRAY_SIZE(acp3x_5682_mc_controls),
+};
+
+static const struct snd_soc_dapm_widget acp3x_1015_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0,
+ &acp3x_dmic_mux_control),
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route acp3x_1015_route[] = {
+ {"Headphone Jack", NULL, "HPOL"},
+ {"Headphone Jack", NULL, "HPOR"},
+ {"IN1P", NULL, "Headset Mic"},
+ {"Dmic Mux", "Front Mic", "DMIC"},
+ {"Dmic Mux", "Rear Mic", "DMIC"},
+ {"Left Spk", NULL, "Left SPO"},
+ {"Right Spk", NULL, "Right SPO"},
+};
+
+static const struct snd_kcontrol_new acp3x_mc_1015_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
+static struct snd_soc_card acp3x_1015 = {
+ .name = "acp3xalc56821015",
+ .owner = THIS_MODULE,
+ .dai_link = acp3x_dai,
+ .num_links = ARRAY_SIZE(acp3x_dai),
+ .dapm_widgets = acp3x_1015_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(acp3x_1015_widgets),
+ .dapm_routes = acp3x_1015_route,
+ .num_dapm_routes = ARRAY_SIZE(acp3x_1015_route),
+ .codec_conf = rt1015_conf,
+ .num_configs = ARRAY_SIZE(rt1015_conf),
+ .controls = acp3x_mc_1015_controls,
+ .num_controls = ARRAY_SIZE(acp3x_mc_1015_controls),
+};
+
+static const struct snd_soc_dapm_widget acp3x_1015p_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0,
+ &acp3x_dmic_mux_control),
+ SND_SOC_DAPM_SPK("Speakers", NULL),
+};
+
+static const struct snd_soc_dapm_route acp3x_1015p_route[] = {
+ {"Headphone Jack", NULL, "HPOL"},
+ {"Headphone Jack", NULL, "HPOR"},
+ {"IN1P", NULL, "Headset Mic"},
+ {"Dmic Mux", "Front Mic", "DMIC"},
+ {"Dmic Mux", "Rear Mic", "DMIC"},
+ /* speaker */
+ { "Speakers", NULL, "Speaker" },
+};
+
+static const struct snd_kcontrol_new acp3x_mc_1015p_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Speakers"),
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static struct snd_soc_card acp3x_1015p = {
+ .name = "acp3xalc56821015p",
+ .owner = THIS_MODULE,
+ .dai_link = acp3x_dai,
+ .num_links = ARRAY_SIZE(acp3x_dai),
+ .dapm_widgets = acp3x_1015p_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(acp3x_1015p_widgets),
+ .dapm_routes = acp3x_1015p_route,
+ .num_dapm_routes = ARRAY_SIZE(acp3x_1015p_route),
+ .controls = acp3x_mc_1015p_controls,
+ .num_controls = ARRAY_SIZE(acp3x_mc_1015p_controls),
+};
+
+void *soc_is_rltk_max(struct device *dev)
+{
+ const struct acpi_device_id *match;
+
+ match = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!match)
+ return NULL;
+ return (void *)match->driver_data;
+}
+
+static void card_spk_dai_link_present(struct snd_soc_dai_link *links,
+ const char *card_name)
+{
+ if (!strcmp(card_name, "acp3xalc56821015")) {
+ links[1].codecs = rt1015;
+ links[1].num_codecs = ARRAY_SIZE(rt1015);
+ } else if (!strcmp(card_name, "acp3xalc56821015p")) {
+ links[1].codecs = rt1015p;
+ links[1].num_codecs = ARRAY_SIZE(rt1015p);
+ } else {
+ links[1].codecs = max;
+ links[1].num_codecs = ARRAY_SIZE(max);
+ }
+}
+
+static int acp3x_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct snd_soc_card *card;
+ struct acp3x_platform_info *machine;
+ struct device *dev = &pdev->dev;
+
+ card = (struct snd_soc_card *)soc_is_rltk_max(dev);
+ if (!card)
+ return -ENODEV;
+
+ machine = devm_kzalloc(&pdev->dev, sizeof(*machine), GFP_KERNEL);
+ if (!machine)
+ return -ENOMEM;
+
+ card_spk_dai_link_present(card->dai_link, card->name);
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, machine);
+
+ dmic_sel = devm_gpiod_get(&pdev->dev, "dmic", GPIOD_OUT_LOW);
+ if (IS_ERR(dmic_sel)) {
+ dev_err(&pdev->dev, "DMIC gpio failed err=%ld\n",
+ PTR_ERR(dmic_sel));
+ return PTR_ERR(dmic_sel);
+ }
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret) {
+ return dev_err_probe(&pdev->dev, ret,
+ "devm_snd_soc_register_card(%s) failed\n",
+ card->name);
+ }
+ return 0;
+}
+
+static const struct acpi_device_id acp3x_audio_acpi_match[] = {
+ { "AMDI5682", (unsigned long)&acp3x_5682},
+ { "AMDI1015", (unsigned long)&acp3x_1015},
+ { "10021015", (unsigned long)&acp3x_1015p},
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, acp3x_audio_acpi_match);
+
+static struct platform_driver acp3x_audio = {
+ .driver = {
+ .name = "acp3x-alc5682-max98357",
+ .acpi_match_table = ACPI_PTR(acp3x_audio_acpi_match),
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = acp3x_probe,
+};
+
+module_platform_driver(acp3x_audio);
+
+MODULE_AUTHOR("akshu.agrawal@amd.com");
+MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("ALC5682 ALC1015, ALC1015P & MAX98357 audio support");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/include/acp_2_2_d.h b/sound/soc/amd/include/acp_2_2_d.h
new file mode 100644
index 0000000000..0118fe9e6a
--- /dev/null
+++ b/sound/soc/amd/include/acp_2_2_d.h
@@ -0,0 +1,609 @@
+/*
+ * ACP_2_2 Register documentation
+ *
+ * Copyright (C) 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef ACP_2_2_D_H
+#define ACP_2_2_D_H
+
+#define mmACP_DMA_CNTL_0 0x5000
+#define mmACP_DMA_CNTL_1 0x5001
+#define mmACP_DMA_CNTL_2 0x5002
+#define mmACP_DMA_CNTL_3 0x5003
+#define mmACP_DMA_CNTL_4 0x5004
+#define mmACP_DMA_CNTL_5 0x5005
+#define mmACP_DMA_CNTL_6 0x5006
+#define mmACP_DMA_CNTL_7 0x5007
+#define mmACP_DMA_CNTL_8 0x5008
+#define mmACP_DMA_CNTL_9 0x5009
+#define mmACP_DMA_CNTL_10 0x500a
+#define mmACP_DMA_CNTL_11 0x500b
+#define mmACP_DMA_CNTL_12 0x500c
+#define mmACP_DMA_CNTL_13 0x500d
+#define mmACP_DMA_CNTL_14 0x500e
+#define mmACP_DMA_CNTL_15 0x500f
+#define mmACP_DMA_DSCR_STRT_IDX_0 0x5010
+#define mmACP_DMA_DSCR_STRT_IDX_1 0x5011
+#define mmACP_DMA_DSCR_STRT_IDX_2 0x5012
+#define mmACP_DMA_DSCR_STRT_IDX_3 0x5013
+#define mmACP_DMA_DSCR_STRT_IDX_4 0x5014
+#define mmACP_DMA_DSCR_STRT_IDX_5 0x5015
+#define mmACP_DMA_DSCR_STRT_IDX_6 0x5016
+#define mmACP_DMA_DSCR_STRT_IDX_7 0x5017
+#define mmACP_DMA_DSCR_STRT_IDX_8 0x5018
+#define mmACP_DMA_DSCR_STRT_IDX_9 0x5019
+#define mmACP_DMA_DSCR_STRT_IDX_10 0x501a
+#define mmACP_DMA_DSCR_STRT_IDX_11 0x501b
+#define mmACP_DMA_DSCR_STRT_IDX_12 0x501c
+#define mmACP_DMA_DSCR_STRT_IDX_13 0x501d
+#define mmACP_DMA_DSCR_STRT_IDX_14 0x501e
+#define mmACP_DMA_DSCR_STRT_IDX_15 0x501f
+#define mmACP_DMA_DSCR_CNT_0 0x5020
+#define mmACP_DMA_DSCR_CNT_1 0x5021
+#define mmACP_DMA_DSCR_CNT_2 0x5022
+#define mmACP_DMA_DSCR_CNT_3 0x5023
+#define mmACP_DMA_DSCR_CNT_4 0x5024
+#define mmACP_DMA_DSCR_CNT_5 0x5025
+#define mmACP_DMA_DSCR_CNT_6 0x5026
+#define mmACP_DMA_DSCR_CNT_7 0x5027
+#define mmACP_DMA_DSCR_CNT_8 0x5028
+#define mmACP_DMA_DSCR_CNT_9 0x5029
+#define mmACP_DMA_DSCR_CNT_10 0x502a
+#define mmACP_DMA_DSCR_CNT_11 0x502b
+#define mmACP_DMA_DSCR_CNT_12 0x502c
+#define mmACP_DMA_DSCR_CNT_13 0x502d
+#define mmACP_DMA_DSCR_CNT_14 0x502e
+#define mmACP_DMA_DSCR_CNT_15 0x502f
+#define mmACP_DMA_PRIO_0 0x5030
+#define mmACP_DMA_PRIO_1 0x5031
+#define mmACP_DMA_PRIO_2 0x5032
+#define mmACP_DMA_PRIO_3 0x5033
+#define mmACP_DMA_PRIO_4 0x5034
+#define mmACP_DMA_PRIO_5 0x5035
+#define mmACP_DMA_PRIO_6 0x5036
+#define mmACP_DMA_PRIO_7 0x5037
+#define mmACP_DMA_PRIO_8 0x5038
+#define mmACP_DMA_PRIO_9 0x5039
+#define mmACP_DMA_PRIO_10 0x503a
+#define mmACP_DMA_PRIO_11 0x503b
+#define mmACP_DMA_PRIO_12 0x503c
+#define mmACP_DMA_PRIO_13 0x503d
+#define mmACP_DMA_PRIO_14 0x503e
+#define mmACP_DMA_PRIO_15 0x503f
+#define mmACP_DMA_CUR_DSCR_0 0x5040
+#define mmACP_DMA_CUR_DSCR_1 0x5041
+#define mmACP_DMA_CUR_DSCR_2 0x5042
+#define mmACP_DMA_CUR_DSCR_3 0x5043
+#define mmACP_DMA_CUR_DSCR_4 0x5044
+#define mmACP_DMA_CUR_DSCR_5 0x5045
+#define mmACP_DMA_CUR_DSCR_6 0x5046
+#define mmACP_DMA_CUR_DSCR_7 0x5047
+#define mmACP_DMA_CUR_DSCR_8 0x5048
+#define mmACP_DMA_CUR_DSCR_9 0x5049
+#define mmACP_DMA_CUR_DSCR_10 0x504a
+#define mmACP_DMA_CUR_DSCR_11 0x504b
+#define mmACP_DMA_CUR_DSCR_12 0x504c
+#define mmACP_DMA_CUR_DSCR_13 0x504d
+#define mmACP_DMA_CUR_DSCR_14 0x504e
+#define mmACP_DMA_CUR_DSCR_15 0x504f
+#define mmACP_DMA_CUR_TRANS_CNT_0 0x5050
+#define mmACP_DMA_CUR_TRANS_CNT_1 0x5051
+#define mmACP_DMA_CUR_TRANS_CNT_2 0x5052
+#define mmACP_DMA_CUR_TRANS_CNT_3 0x5053
+#define mmACP_DMA_CUR_TRANS_CNT_4 0x5054
+#define mmACP_DMA_CUR_TRANS_CNT_5 0x5055
+#define mmACP_DMA_CUR_TRANS_CNT_6 0x5056
+#define mmACP_DMA_CUR_TRANS_CNT_7 0x5057
+#define mmACP_DMA_CUR_TRANS_CNT_8 0x5058
+#define mmACP_DMA_CUR_TRANS_CNT_9 0x5059
+#define mmACP_DMA_CUR_TRANS_CNT_10 0x505a
+#define mmACP_DMA_CUR_TRANS_CNT_11 0x505b
+#define mmACP_DMA_CUR_TRANS_CNT_12 0x505c
+#define mmACP_DMA_CUR_TRANS_CNT_13 0x505d
+#define mmACP_DMA_CUR_TRANS_CNT_14 0x505e
+#define mmACP_DMA_CUR_TRANS_CNT_15 0x505f
+#define mmACP_DMA_ERR_STS_0 0x5060
+#define mmACP_DMA_ERR_STS_1 0x5061
+#define mmACP_DMA_ERR_STS_2 0x5062
+#define mmACP_DMA_ERR_STS_3 0x5063
+#define mmACP_DMA_ERR_STS_4 0x5064
+#define mmACP_DMA_ERR_STS_5 0x5065
+#define mmACP_DMA_ERR_STS_6 0x5066
+#define mmACP_DMA_ERR_STS_7 0x5067
+#define mmACP_DMA_ERR_STS_8 0x5068
+#define mmACP_DMA_ERR_STS_9 0x5069
+#define mmACP_DMA_ERR_STS_10 0x506a
+#define mmACP_DMA_ERR_STS_11 0x506b
+#define mmACP_DMA_ERR_STS_12 0x506c
+#define mmACP_DMA_ERR_STS_13 0x506d
+#define mmACP_DMA_ERR_STS_14 0x506e
+#define mmACP_DMA_ERR_STS_15 0x506f
+#define mmACP_DMA_DESC_BASE_ADDR 0x5070
+#define mmACP_DMA_DESC_MAX_NUM_DSCR 0x5071
+#define mmACP_DMA_CH_STS 0x5072
+#define mmACP_DMA_CH_GROUP 0x5073
+#define mmACP_DSP0_CACHE_OFFSET0 0x5078
+#define mmACP_DSP0_CACHE_SIZE0 0x5079
+#define mmACP_DSP0_CACHE_OFFSET1 0x507a
+#define mmACP_DSP0_CACHE_SIZE1 0x507b
+#define mmACP_DSP0_CACHE_OFFSET2 0x507c
+#define mmACP_DSP0_CACHE_SIZE2 0x507d
+#define mmACP_DSP0_CACHE_OFFSET3 0x507e
+#define mmACP_DSP0_CACHE_SIZE3 0x507f
+#define mmACP_DSP0_CACHE_OFFSET4 0x5080
+#define mmACP_DSP0_CACHE_SIZE4 0x5081
+#define mmACP_DSP0_CACHE_OFFSET5 0x5082
+#define mmACP_DSP0_CACHE_SIZE5 0x5083
+#define mmACP_DSP0_CACHE_OFFSET6 0x5084
+#define mmACP_DSP0_CACHE_SIZE6 0x5085
+#define mmACP_DSP0_CACHE_OFFSET7 0x5086
+#define mmACP_DSP0_CACHE_SIZE7 0x5087
+#define mmACP_DSP0_CACHE_OFFSET8 0x5088
+#define mmACP_DSP0_CACHE_SIZE8 0x5089
+#define mmACP_DSP0_NONCACHE_OFFSET0 0x508a
+#define mmACP_DSP0_NONCACHE_SIZE0 0x508b
+#define mmACP_DSP0_NONCACHE_OFFSET1 0x508c
+#define mmACP_DSP0_NONCACHE_SIZE1 0x508d
+#define mmACP_DSP0_DEBUG_PC 0x508e
+#define mmACP_DSP0_NMI_SEL 0x508f
+#define mmACP_DSP0_CLKRST_CNTL 0x5090
+#define mmACP_DSP0_RUNSTALL 0x5091
+#define mmACP_DSP0_OCD_HALT_ON_RST 0x5092
+#define mmACP_DSP0_WAIT_MODE 0x5093
+#define mmACP_DSP0_VECT_SEL 0x5094
+#define mmACP_DSP0_DEBUG_REG1 0x5095
+#define mmACP_DSP0_DEBUG_REG2 0x5096
+#define mmACP_DSP0_DEBUG_REG3 0x5097
+#define mmACP_DSP1_CACHE_OFFSET0 0x509d
+#define mmACP_DSP1_CACHE_SIZE0 0x509e
+#define mmACP_DSP1_CACHE_OFFSET1 0x509f
+#define mmACP_DSP1_CACHE_SIZE1 0x50a0
+#define mmACP_DSP1_CACHE_OFFSET2 0x50a1
+#define mmACP_DSP1_CACHE_SIZE2 0x50a2
+#define mmACP_DSP1_CACHE_OFFSET3 0x50a3
+#define mmACP_DSP1_CACHE_SIZE3 0x50a4
+#define mmACP_DSP1_CACHE_OFFSET4 0x50a5
+#define mmACP_DSP1_CACHE_SIZE4 0x50a6
+#define mmACP_DSP1_CACHE_OFFSET5 0x50a7
+#define mmACP_DSP1_CACHE_SIZE5 0x50a8
+#define mmACP_DSP1_CACHE_OFFSET6 0x50a9
+#define mmACP_DSP1_CACHE_SIZE6 0x50aa
+#define mmACP_DSP1_CACHE_OFFSET7 0x50ab
+#define mmACP_DSP1_CACHE_SIZE7 0x50ac
+#define mmACP_DSP1_CACHE_OFFSET8 0x50ad
+#define mmACP_DSP1_CACHE_SIZE8 0x50ae
+#define mmACP_DSP1_NONCACHE_OFFSET0 0x50af
+#define mmACP_DSP1_NONCACHE_SIZE0 0x50b0
+#define mmACP_DSP1_NONCACHE_OFFSET1 0x50b1
+#define mmACP_DSP1_NONCACHE_SIZE1 0x50b2
+#define mmACP_DSP1_DEBUG_PC 0x50b3
+#define mmACP_DSP1_NMI_SEL 0x50b4
+#define mmACP_DSP1_CLKRST_CNTL 0x50b5
+#define mmACP_DSP1_RUNSTALL 0x50b6
+#define mmACP_DSP1_OCD_HALT_ON_RST 0x50b7
+#define mmACP_DSP1_WAIT_MODE 0x50b8
+#define mmACP_DSP1_VECT_SEL 0x50b9
+#define mmACP_DSP1_DEBUG_REG1 0x50ba
+#define mmACP_DSP1_DEBUG_REG2 0x50bb
+#define mmACP_DSP1_DEBUG_REG3 0x50bc
+#define mmACP_DSP2_CACHE_OFFSET0 0x50c2
+#define mmACP_DSP2_CACHE_SIZE0 0x50c3
+#define mmACP_DSP2_CACHE_OFFSET1 0x50c4
+#define mmACP_DSP2_CACHE_SIZE1 0x50c5
+#define mmACP_DSP2_CACHE_OFFSET2 0x50c6
+#define mmACP_DSP2_CACHE_SIZE2 0x50c7
+#define mmACP_DSP2_CACHE_OFFSET3 0x50c8
+#define mmACP_DSP2_CACHE_SIZE3 0x50c9
+#define mmACP_DSP2_CACHE_OFFSET4 0x50ca
+#define mmACP_DSP2_CACHE_SIZE4 0x50cb
+#define mmACP_DSP2_CACHE_OFFSET5 0x50cc
+#define mmACP_DSP2_CACHE_SIZE5 0x50cd
+#define mmACP_DSP2_CACHE_OFFSET6 0x50ce
+#define mmACP_DSP2_CACHE_SIZE6 0x50cf
+#define mmACP_DSP2_CACHE_OFFSET7 0x50d0
+#define mmACP_DSP2_CACHE_SIZE7 0x50d1
+#define mmACP_DSP2_CACHE_OFFSET8 0x50d2
+#define mmACP_DSP2_CACHE_SIZE8 0x50d3
+#define mmACP_DSP2_NONCACHE_OFFSET0 0x50d4
+#define mmACP_DSP2_NONCACHE_SIZE0 0x50d5
+#define mmACP_DSP2_NONCACHE_OFFSET1 0x50d6
+#define mmACP_DSP2_NONCACHE_SIZE1 0x50d7
+#define mmACP_DSP2_DEBUG_PC 0x50d8
+#define mmACP_DSP2_NMI_SEL 0x50d9
+#define mmACP_DSP2_CLKRST_CNTL 0x50da
+#define mmACP_DSP2_RUNSTALL 0x50db
+#define mmACP_DSP2_OCD_HALT_ON_RST 0x50dc
+#define mmACP_DSP2_WAIT_MODE 0x50dd
+#define mmACP_DSP2_VECT_SEL 0x50de
+#define mmACP_DSP2_DEBUG_REG1 0x50df
+#define mmACP_DSP2_DEBUG_REG2 0x50e0
+#define mmACP_DSP2_DEBUG_REG3 0x50e1
+#define mmACP_AXI2DAGB_ONION_CNTL 0x50e7
+#define mmACP_AXI2DAGB_ONION_ERR_STATUS_WR 0x50e8
+#define mmACP_AXI2DAGB_ONION_ERR_STATUS_RD 0x50e9
+#define mmACP_DAGB_Onion_TransPerf_Counter_Control 0x50ea
+#define mmACP_DAGB_Onion_Wr_TransPerf_Counter_Current 0x50eb
+#define mmACP_DAGB_Onion_Wr_TransPerf_Counter_Peak 0x50ec
+#define mmACP_DAGB_Onion_Rd_TransPerf_Counter_Current 0x50ed
+#define mmACP_DAGB_Onion_Rd_TransPerf_Counter_Peak 0x50ee
+#define mmACP_AXI2DAGB_GARLIC_CNTL 0x50f3
+#define mmACP_AXI2DAGB_GARLIC_ERR_STATUS_WR 0x50f4
+#define mmACP_AXI2DAGB_GARLIC_ERR_STATUS_RD 0x50f5
+#define mmACP_DAGB_Garlic_TransPerf_Counter_Control 0x50f6
+#define mmACP_DAGB_Garlic_Wr_TransPerf_Counter_Current 0x50f7
+#define mmACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak 0x50f8
+#define mmACP_DAGB_Garlic_Rd_TransPerf_Counter_Current 0x50f9
+#define mmACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak 0x50fa
+#define mmACP_DAGB_PAGE_SIZE_GRP_1 0x50ff
+#define mmACP_DAGB_BASE_ADDR_GRP_1 0x5100
+#define mmACP_DAGB_PAGE_SIZE_GRP_2 0x5101
+#define mmACP_DAGB_BASE_ADDR_GRP_2 0x5102
+#define mmACP_DAGB_PAGE_SIZE_GRP_3 0x5103
+#define mmACP_DAGB_BASE_ADDR_GRP_3 0x5104
+#define mmACP_DAGB_PAGE_SIZE_GRP_4 0x5105
+#define mmACP_DAGB_BASE_ADDR_GRP_4 0x5106
+#define mmACP_DAGB_PAGE_SIZE_GRP_5 0x5107
+#define mmACP_DAGB_BASE_ADDR_GRP_5 0x5108
+#define mmACP_DAGB_PAGE_SIZE_GRP_6 0x5109
+#define mmACP_DAGB_BASE_ADDR_GRP_6 0x510a
+#define mmACP_DAGB_PAGE_SIZE_GRP_7 0x510b
+#define mmACP_DAGB_BASE_ADDR_GRP_7 0x510c
+#define mmACP_DAGB_PAGE_SIZE_GRP_8 0x510d
+#define mmACP_DAGB_BASE_ADDR_GRP_8 0x510e
+#define mmACP_DAGB_ATU_CTRL 0x510f
+#define mmACP_CONTROL 0x5131
+#define mmACP_STATUS 0x5133
+#define mmACP_SOFT_RESET 0x5134
+#define mmACP_PwrMgmt_CNTL 0x5135
+#define mmACP_CAC_INDICATOR_CONTROL 0x5136
+#define mmACP_SMU_MAILBOX 0x5137
+#define mmACP_FUTURE_REG_SCLK_0 0x5138
+#define mmACP_FUTURE_REG_SCLK_1 0x5139
+#define mmACP_FUTURE_REG_SCLK_2 0x513a
+#define mmACP_FUTURE_REG_SCLK_3 0x513b
+#define mmACP_FUTURE_REG_SCLK_4 0x513c
+#define mmACP_DAGB_DEBUG_CNT_ENABLE 0x513d
+#define mmACP_DAGBG_WR_ASK_CNT 0x513e
+#define mmACP_DAGBG_WR_GO_CNT 0x513f
+#define mmACP_DAGBG_WR_EXP_RESP_CNT 0x5140
+#define mmACP_DAGBG_WR_ACTUAL_RESP_CNT 0x5141
+#define mmACP_DAGBG_RD_ASK_CNT 0x5142
+#define mmACP_DAGBG_RD_GO_CNT 0x5143
+#define mmACP_DAGBG_RD_EXP_RESP_CNT 0x5144
+#define mmACP_DAGBG_RD_ACTUAL_RESP_CNT 0x5145
+#define mmACP_DAGBO_WR_ASK_CNT 0x5146
+#define mmACP_DAGBO_WR_GO_CNT 0x5147
+#define mmACP_DAGBO_WR_EXP_RESP_CNT 0x5148
+#define mmACP_DAGBO_WR_ACTUAL_RESP_CNT 0x5149
+#define mmACP_DAGBO_RD_ASK_CNT 0x514a
+#define mmACP_DAGBO_RD_GO_CNT 0x514b
+#define mmACP_DAGBO_RD_EXP_RESP_CNT 0x514c
+#define mmACP_DAGBO_RD_ACTUAL_RESP_CNT 0x514d
+#define mmACP_BRB_CONTROL 0x5156
+#define mmACP_EXTERNAL_INTR_ENB 0x5157
+#define mmACP_EXTERNAL_INTR_CNTL 0x5158
+#define mmACP_ERROR_SOURCE_STS 0x5159
+#define mmACP_DSP_SW_INTR_TRIG 0x515a
+#define mmACP_DSP_SW_INTR_CNTL 0x515b
+#define mmACP_DAGBG_TIMEOUT_CNTL 0x515c
+#define mmACP_DAGBO_TIMEOUT_CNTL 0x515d
+#define mmACP_EXTERNAL_INTR_STAT 0x515e
+#define mmACP_DSP_SW_INTR_STAT 0x515f
+#define mmACP_DSP0_INTR_CNTL 0x5160
+#define mmACP_DSP0_INTR_STAT 0x5161
+#define mmACP_DSP0_TIMEOUT_CNTL 0x5162
+#define mmACP_DSP1_INTR_CNTL 0x5163
+#define mmACP_DSP1_INTR_STAT 0x5164
+#define mmACP_DSP1_TIMEOUT_CNTL 0x5165
+#define mmACP_DSP2_INTR_CNTL 0x5166
+#define mmACP_DSP2_INTR_STAT 0x5167
+#define mmACP_DSP2_TIMEOUT_CNTL 0x5168
+#define mmACP_DSP0_EXT_TIMER_CNTL 0x5169
+#define mmACP_DSP1_EXT_TIMER_CNTL 0x516a
+#define mmACP_DSP2_EXT_TIMER_CNTL 0x516b
+#define mmACP_AXI2DAGB_SEM_0 0x516c
+#define mmACP_AXI2DAGB_SEM_1 0x516d
+#define mmACP_AXI2DAGB_SEM_2 0x516e
+#define mmACP_AXI2DAGB_SEM_3 0x516f
+#define mmACP_AXI2DAGB_SEM_4 0x5170
+#define mmACP_AXI2DAGB_SEM_5 0x5171
+#define mmACP_AXI2DAGB_SEM_6 0x5172
+#define mmACP_AXI2DAGB_SEM_7 0x5173
+#define mmACP_AXI2DAGB_SEM_8 0x5174
+#define mmACP_AXI2DAGB_SEM_9 0x5175
+#define mmACP_AXI2DAGB_SEM_10 0x5176
+#define mmACP_AXI2DAGB_SEM_11 0x5177
+#define mmACP_AXI2DAGB_SEM_12 0x5178
+#define mmACP_AXI2DAGB_SEM_13 0x5179
+#define mmACP_AXI2DAGB_SEM_14 0x517a
+#define mmACP_AXI2DAGB_SEM_15 0x517b
+#define mmACP_AXI2DAGB_SEM_16 0x517c
+#define mmACP_AXI2DAGB_SEM_17 0x517d
+#define mmACP_AXI2DAGB_SEM_18 0x517e
+#define mmACP_AXI2DAGB_SEM_19 0x517f
+#define mmACP_AXI2DAGB_SEM_20 0x5180
+#define mmACP_AXI2DAGB_SEM_21 0x5181
+#define mmACP_AXI2DAGB_SEM_22 0x5182
+#define mmACP_AXI2DAGB_SEM_23 0x5183
+#define mmACP_AXI2DAGB_SEM_24 0x5184
+#define mmACP_AXI2DAGB_SEM_25 0x5185
+#define mmACP_AXI2DAGB_SEM_26 0x5186
+#define mmACP_AXI2DAGB_SEM_27 0x5187
+#define mmACP_AXI2DAGB_SEM_28 0x5188
+#define mmACP_AXI2DAGB_SEM_29 0x5189
+#define mmACP_AXI2DAGB_SEM_30 0x518a
+#define mmACP_AXI2DAGB_SEM_31 0x518b
+#define mmACP_AXI2DAGB_SEM_32 0x518c
+#define mmACP_AXI2DAGB_SEM_33 0x518d
+#define mmACP_AXI2DAGB_SEM_34 0x518e
+#define mmACP_AXI2DAGB_SEM_35 0x518f
+#define mmACP_AXI2DAGB_SEM_36 0x5190
+#define mmACP_AXI2DAGB_SEM_37 0x5191
+#define mmACP_AXI2DAGB_SEM_38 0x5192
+#define mmACP_AXI2DAGB_SEM_39 0x5193
+#define mmACP_AXI2DAGB_SEM_40 0x5194
+#define mmACP_AXI2DAGB_SEM_41 0x5195
+#define mmACP_AXI2DAGB_SEM_42 0x5196
+#define mmACP_AXI2DAGB_SEM_43 0x5197
+#define mmACP_AXI2DAGB_SEM_44 0x5198
+#define mmACP_AXI2DAGB_SEM_45 0x5199
+#define mmACP_AXI2DAGB_SEM_46 0x519a
+#define mmACP_AXI2DAGB_SEM_47 0x519b
+#define mmACP_SRBM_Client_Base_Addr 0x519c
+#define mmACP_SRBM_Client_RDDATA 0x519d
+#define mmACP_SRBM_Cycle_Sts 0x519e
+#define mmACP_SRBM_Targ_Idx_Addr 0x519f
+#define mmACP_SRBM_Targ_Idx_Data 0x51a0
+#define mmACP_SEMA_ADDR_LOW 0x51a1
+#define mmACP_SEMA_ADDR_HIGH 0x51a2
+#define mmACP_SEMA_CMD 0x51a3
+#define mmACP_SEMA_STS 0x51a4
+#define mmACP_SEMA_REQ 0x51a5
+#define mmACP_FW_STATUS 0x51a6
+#define mmACP_FUTURE_REG_ACLK_0 0x51a7
+#define mmACP_FUTURE_REG_ACLK_1 0x51a8
+#define mmACP_FUTURE_REG_ACLK_2 0x51a9
+#define mmACP_FUTURE_REG_ACLK_3 0x51aa
+#define mmACP_FUTURE_REG_ACLK_4 0x51ab
+#define mmACP_TIMER 0x51ac
+#define mmACP_TIMER_CNTL 0x51ad
+#define mmACP_DSP0_TIMER 0x51ae
+#define mmACP_DSP1_TIMER 0x51af
+#define mmACP_DSP2_TIMER 0x51b0
+#define mmACP_I2S_TRANSMIT_BYTE_CNT_HIGH 0x51b1
+#define mmACP_I2S_TRANSMIT_BYTE_CNT_LOW 0x51b2
+#define mmACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH 0x51b3
+#define mmACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW 0x51b4
+#define mmACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH 0x51b5
+#define mmACP_I2S_BT_RECEIVE_BYTE_CNT_LOW 0x51b6
+#define mmACP_DSP0_CS_STATE 0x51b7
+#define mmACP_DSP1_CS_STATE 0x51b8
+#define mmACP_DSP2_CS_STATE 0x51b9
+#define mmACP_SCRATCH_REG_BASE_ADDR 0x51ba
+#define mmCC_ACP_EFUSE 0x51c8
+#define mmACP_PGFSM_RETAIN_REG 0x51c9
+#define mmACP_PGFSM_CONFIG_REG 0x51ca
+#define mmACP_PGFSM_WRITE_REG 0x51cb
+#define mmACP_PGFSM_READ_REG_0 0x51cc
+#define mmACP_PGFSM_READ_REG_1 0x51cd
+#define mmACP_PGFSM_READ_REG_2 0x51ce
+#define mmACP_PGFSM_READ_REG_3 0x51cf
+#define mmACP_PGFSM_READ_REG_4 0x51d0
+#define mmACP_PGFSM_READ_REG_5 0x51d1
+#define mmACP_IP_PGFSM_ENABLE 0x51d2
+#define mmACP_I2S_PIN_CONFIG 0x51d3
+#define mmACP_AZALIA_I2S_SELECT 0x51d4
+#define mmACP_CHIP_PKG_FOR_PAD_ISOLATION 0x51d5
+#define mmACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL 0x51d6
+#define mmACP_BT_UART_PAD_SEL 0x51d7
+#define mmACP_SCRATCH_REG_0 0x52c0
+#define mmACP_SCRATCH_REG_1 0x52c1
+#define mmACP_SCRATCH_REG_2 0x52c2
+#define mmACP_SCRATCH_REG_3 0x52c3
+#define mmACP_SCRATCH_REG_4 0x52c4
+#define mmACP_SCRATCH_REG_5 0x52c5
+#define mmACP_SCRATCH_REG_6 0x52c6
+#define mmACP_SCRATCH_REG_7 0x52c7
+#define mmACP_SCRATCH_REG_8 0x52c8
+#define mmACP_SCRATCH_REG_9 0x52c9
+#define mmACP_SCRATCH_REG_10 0x52ca
+#define mmACP_SCRATCH_REG_11 0x52cb
+#define mmACP_SCRATCH_REG_12 0x52cc
+#define mmACP_SCRATCH_REG_13 0x52cd
+#define mmACP_SCRATCH_REG_14 0x52ce
+#define mmACP_SCRATCH_REG_15 0x52cf
+#define mmACP_SCRATCH_REG_16 0x52d0
+#define mmACP_SCRATCH_REG_17 0x52d1
+#define mmACP_SCRATCH_REG_18 0x52d2
+#define mmACP_SCRATCH_REG_19 0x52d3
+#define mmACP_SCRATCH_REG_20 0x52d4
+#define mmACP_SCRATCH_REG_21 0x52d5
+#define mmACP_SCRATCH_REG_22 0x52d6
+#define mmACP_SCRATCH_REG_23 0x52d7
+#define mmACP_SCRATCH_REG_24 0x52d8
+#define mmACP_SCRATCH_REG_25 0x52d9
+#define mmACP_SCRATCH_REG_26 0x52da
+#define mmACP_SCRATCH_REG_27 0x52db
+#define mmACP_SCRATCH_REG_28 0x52dc
+#define mmACP_SCRATCH_REG_29 0x52dd
+#define mmACP_SCRATCH_REG_30 0x52de
+#define mmACP_SCRATCH_REG_31 0x52df
+#define mmACP_SCRATCH_REG_32 0x52e0
+#define mmACP_SCRATCH_REG_33 0x52e1
+#define mmACP_SCRATCH_REG_34 0x52e2
+#define mmACP_SCRATCH_REG_35 0x52e3
+#define mmACP_SCRATCH_REG_36 0x52e4
+#define mmACP_SCRATCH_REG_37 0x52e5
+#define mmACP_SCRATCH_REG_38 0x52e6
+#define mmACP_SCRATCH_REG_39 0x52e7
+#define mmACP_SCRATCH_REG_40 0x52e8
+#define mmACP_SCRATCH_REG_41 0x52e9
+#define mmACP_SCRATCH_REG_42 0x52ea
+#define mmACP_SCRATCH_REG_43 0x52eb
+#define mmACP_SCRATCH_REG_44 0x52ec
+#define mmACP_SCRATCH_REG_45 0x52ed
+#define mmACP_SCRATCH_REG_46 0x52ee
+#define mmACP_SCRATCH_REG_47 0x52ef
+#define mmACP_VOICE_WAKEUP_ENABLE 0x51e8
+#define mmACP_VOICE_WAKEUP_STATUS 0x51e9
+#define mmI2S_VOICE_WAKEUP_LOWER_THRESHOLD 0x51ea
+#define mmI2S_VOICE_WAKEUP_HIGHER_THRESHOLD 0x51eb
+#define mmI2S_VOICE_WAKEUP_NO_OF_SAMPLES 0x51ec
+#define mmI2S_VOICE_WAKEUP_NO_OF_PEAKS 0x51ed
+#define mmI2S_VOICE_WAKEUP_DURATION_OF_N_PEAKS 0x51ee
+#define mmI2S_VOICE_WAKEUP_BITCLK_TOGGLE_DETECTION 0x51ef
+#define mmI2S_VOICE_WAKEUP_DATA_PATH_SWITCH 0x51f0
+#define mmI2S_VOICE_WAKEUP_DATA_POINTER 0x51f1
+#define mmI2S_VOICE_WAKEUP_AUTH_MATCH 0x51f2
+#define mmI2S_VOICE_WAKEUP_8KB_WRAP 0x51f3
+#define mmACP_I2S_RECEIVED_BYTE_CNT_HIGH 0x51f4
+#define mmACP_I2S_RECEIVED_BYTE_CNT_LOW 0x51f5
+#define mmACP_I2S_MICSP_TRANSMIT_BYTE_CNT_HIGH 0x51f6
+#define mmACP_I2S_MICSP_TRANSMIT_BYTE_CNT_LOW 0x51f7
+#define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8
+#define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9
+#define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa
+#define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb
+#define mmACP_MEM_DEEP_SLEEP_REQ_LO 0x51fc
+#define mmACP_MEM_DEEP_SLEEP_REQ_HI 0x51fd
+#define mmACP_MEM_DEEP_SLEEP_STS_LO 0x51fe
+#define mmACP_MEM_DEEP_SLEEP_STS_HI 0x51ff
+#define mmACP_MEM_WAKEUP_FROM_SHUT_DOWN_LO 0x5200
+#define mmACP_MEM_WAKEUP_FROM_SHUT_DOWN_HI 0x5201
+#define mmACP_MEM_WAKEUP_FROM_SLEEP_LO 0x5202
+#define mmACP_MEM_WAKEUP_FROM_SLEEP_HI 0x5203
+#define mmACP_I2SSP_IER 0x5210
+#define mmACP_I2SSP_IRER 0x5211
+#define mmACP_I2SSP_ITER 0x5212
+#define mmACP_I2SSP_CER 0x5213
+#define mmACP_I2SSP_CCR 0x5214
+#define mmACP_I2SSP_RXFFR 0x5215
+#define mmACP_I2SSP_TXFFR 0x5216
+#define mmACP_I2SSP_LRBR0 0x5218
+#define mmACP_I2SSP_RRBR0 0x5219
+#define mmACP_I2SSP_RER0 0x521a
+#define mmACP_I2SSP_TER0 0x521b
+#define mmACP_I2SSP_RCR0 0x521c
+#define mmACP_I2SSP_TCR0 0x521d
+#define mmACP_I2SSP_ISR0 0x521e
+#define mmACP_I2SSP_IMR0 0x521f
+#define mmACP_I2SSP_ROR0 0x5220
+#define mmACP_I2SSP_TOR0 0x5221
+#define mmACP_I2SSP_RFCR0 0x5222
+#define mmACP_I2SSP_TFCR0 0x5223
+#define mmACP_I2SSP_RFF0 0x5224
+#define mmACP_I2SSP_TFF0 0x5225
+#define mmACP_I2SSP_RXDMA 0x5226
+#define mmACP_I2SSP_RRXDMA 0x5227
+#define mmACP_I2SSP_TXDMA 0x5228
+#define mmACP_I2SSP_RTXDMA 0x5229
+#define mmACP_I2SSP_COMP_PARAM_2 0x522a
+#define mmACP_I2SSP_COMP_PARAM_1 0x522b
+#define mmACP_I2SSP_COMP_VERSION 0x522c
+#define mmACP_I2SSP_COMP_TYPE 0x522d
+#define mmACP_I2SMICSP_IER 0x522e
+#define mmACP_I2SMICSP_IRER 0x522f
+#define mmACP_I2SMICSP_ITER 0x5230
+#define mmACP_I2SMICSP_CER 0x5231
+#define mmACP_I2SMICSP_CCR 0x5232
+#define mmACP_I2SMICSP_RXFFR 0x5233
+#define mmACP_I2SMICSP_TXFFR 0x5234
+#define mmACP_I2SMICSP_LRBR0 0x5236
+#define mmACP_I2SMICSP_RRBR0 0x5237
+#define mmACP_I2SMICSP_RER0 0x5238
+#define mmACP_I2SMICSP_TER0 0x5239
+#define mmACP_I2SMICSP_RCR0 0x523a
+#define mmACP_I2SMICSP_TCR0 0x523b
+#define mmACP_I2SMICSP_ISR0 0x523c
+#define mmACP_I2SMICSP_IMR0 0x523d
+#define mmACP_I2SMICSP_ROR0 0x523e
+#define mmACP_I2SMICSP_TOR0 0x523f
+#define mmACP_I2SMICSP_RFCR0 0x5240
+#define mmACP_I2SMICSP_TFCR0 0x5241
+#define mmACP_I2SMICSP_RFF0 0x5242
+#define mmACP_I2SMICSP_TFF0 0x5243
+#define mmACP_I2SMICSP_LRBR1 0x5246
+#define mmACP_I2SMICSP_RRBR1 0x5247
+#define mmACP_I2SMICSP_RER1 0x5248
+#define mmACP_I2SMICSP_TER1 0x5249
+#define mmACP_I2SMICSP_RCR1 0x524a
+#define mmACP_I2SMICSP_TCR1 0x524b
+#define mmACP_I2SMICSP_ISR1 0x524c
+#define mmACP_I2SMICSP_IMR1 0x524d
+#define mmACP_I2SMICSP_ROR1 0x524e
+#define mmACP_I2SMICSP_TOR1 0x524f
+#define mmACP_I2SMICSP_RFCR1 0x5250
+#define mmACP_I2SMICSP_TFCR1 0x5251
+#define mmACP_I2SMICSP_RFF1 0x5252
+#define mmACP_I2SMICSP_TFF1 0x5253
+#define mmACP_I2SMICSP_RXDMA 0x5254
+#define mmACP_I2SMICSP_RRXDMA 0x5255
+#define mmACP_I2SMICSP_TXDMA 0x5256
+#define mmACP_I2SMICSP_RTXDMA 0x5257
+#define mmACP_I2SMICSP_COMP_PARAM_2 0x5258
+#define mmACP_I2SMICSP_COMP_PARAM_1 0x5259
+#define mmACP_I2SMICSP_COMP_VERSION 0x525a
+#define mmACP_I2SMICSP_COMP_TYPE 0x525b
+#define mmACP_I2SBT_IER 0x525c
+#define mmACP_I2SBT_IRER 0x525d
+#define mmACP_I2SBT_ITER 0x525e
+#define mmACP_I2SBT_CER 0x525f
+#define mmACP_I2SBT_CCR 0x5260
+#define mmACP_I2SBT_RXFFR 0x5261
+#define mmACP_I2SBT_TXFFR 0x5262
+#define mmACP_I2SBT_LRBR0 0x5264
+#define mmACP_I2SBT_RRBR0 0x5265
+#define mmACP_I2SBT_RER0 0x5266
+#define mmACP_I2SBT_TER0 0x5267
+#define mmACP_I2SBT_RCR0 0x5268
+#define mmACP_I2SBT_TCR0 0x5269
+#define mmACP_I2SBT_ISR0 0x526a
+#define mmACP_I2SBT_IMR0 0x526b
+#define mmACP_I2SBT_ROR0 0x526c
+#define mmACP_I2SBT_TOR0 0x526d
+#define mmACP_I2SBT_RFCR0 0x526e
+#define mmACP_I2SBT_TFCR0 0x526f
+#define mmACP_I2SBT_RFF0 0x5270
+#define mmACP_I2SBT_TFF0 0x5271
+#define mmACP_I2SBT_LRBR1 0x5274
+#define mmACP_I2SBT_RRBR1 0x5275
+#define mmACP_I2SBT_RER1 0x5276
+#define mmACP_I2SBT_TER1 0x5277
+#define mmACP_I2SBT_RCR1 0x5278
+#define mmACP_I2SBT_TCR1 0x5279
+#define mmACP_I2SBT_ISR1 0x527a
+#define mmACP_I2SBT_IMR1 0x527b
+#define mmACP_I2SBT_ROR1 0x527c
+#define mmACP_I2SBT_TOR1 0x527d
+#define mmACP_I2SBT_RFCR1 0x527e
+#define mmACP_I2SBT_TFCR1 0x527f
+#define mmACP_I2SBT_RFF1 0x5280
+#define mmACP_I2SBT_TFF1 0x5281
+#define mmACP_I2SBT_RXDMA 0x5282
+#define mmACP_I2SBT_RRXDMA 0x5283
+#define mmACP_I2SBT_TXDMA 0x5284
+#define mmACP_I2SBT_RTXDMA 0x5285
+#define mmACP_I2SBT_COMP_PARAM_2 0x5286
+#define mmACP_I2SBT_COMP_PARAM_1 0x5287
+#define mmACP_I2SBT_COMP_VERSION 0x5288
+#define mmACP_I2SBT_COMP_TYPE 0x5289
+
+#endif /* ACP_2_2_D_H */
diff --git a/sound/soc/amd/include/acp_2_2_enum.h b/sound/soc/amd/include/acp_2_2_enum.h
new file mode 100644
index 0000000000..f3577c8510
--- /dev/null
+++ b/sound/soc/amd/include/acp_2_2_enum.h
@@ -0,0 +1,1068 @@
+/*
+ * ACP_2_2 Register documentation
+ *
+ * Copyright (C) 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef ACP_2_2_ENUM_H
+#define ACP_2_2_ENUM_H
+
+typedef enum DebugBlockId {
+ DBG_BLOCK_ID_RESERVED = 0x0,
+ DBG_BLOCK_ID_DBG = 0x1,
+ DBG_BLOCK_ID_VMC = 0x2,
+ DBG_BLOCK_ID_PDMA = 0x3,
+ DBG_BLOCK_ID_CG = 0x4,
+ DBG_BLOCK_ID_SRBM = 0x5,
+ DBG_BLOCK_ID_GRBM = 0x6,
+ DBG_BLOCK_ID_RLC = 0x7,
+ DBG_BLOCK_ID_CSC = 0x8,
+ DBG_BLOCK_ID_SEM = 0x9,
+ DBG_BLOCK_ID_IH = 0xa,
+ DBG_BLOCK_ID_SC = 0xb,
+ DBG_BLOCK_ID_SQ = 0xc,
+ DBG_BLOCK_ID_UVDU = 0xd,
+ DBG_BLOCK_ID_SQA = 0xe,
+ DBG_BLOCK_ID_SDMA0 = 0xf,
+ DBG_BLOCK_ID_SDMA1 = 0x10,
+ DBG_BLOCK_ID_SPIM = 0x11,
+ DBG_BLOCK_ID_GDS = 0x12,
+ DBG_BLOCK_ID_VC0 = 0x13,
+ DBG_BLOCK_ID_VC1 = 0x14,
+ DBG_BLOCK_ID_PA0 = 0x15,
+ DBG_BLOCK_ID_PA1 = 0x16,
+ DBG_BLOCK_ID_CP0 = 0x17,
+ DBG_BLOCK_ID_CP1 = 0x18,
+ DBG_BLOCK_ID_CP2 = 0x19,
+ DBG_BLOCK_ID_XBR = 0x1a,
+ DBG_BLOCK_ID_UVDM = 0x1b,
+ DBG_BLOCK_ID_VGT0 = 0x1c,
+ DBG_BLOCK_ID_VGT1 = 0x1d,
+ DBG_BLOCK_ID_IA = 0x1e,
+ DBG_BLOCK_ID_SXM0 = 0x1f,
+ DBG_BLOCK_ID_SXM1 = 0x20,
+ DBG_BLOCK_ID_SCT0 = 0x21,
+ DBG_BLOCK_ID_SCT1 = 0x22,
+ DBG_BLOCK_ID_SPM0 = 0x23,
+ DBG_BLOCK_ID_SPM1 = 0x24,
+ DBG_BLOCK_ID_UNUSED0 = 0x25,
+ DBG_BLOCK_ID_UNUSED1 = 0x26,
+ DBG_BLOCK_ID_TCAA = 0x27,
+ DBG_BLOCK_ID_TCAB = 0x28,
+ DBG_BLOCK_ID_TCCA = 0x29,
+ DBG_BLOCK_ID_TCCB = 0x2a,
+ DBG_BLOCK_ID_MCC0 = 0x2b,
+ DBG_BLOCK_ID_MCC1 = 0x2c,
+ DBG_BLOCK_ID_MCC2 = 0x2d,
+ DBG_BLOCK_ID_MCC3 = 0x2e,
+ DBG_BLOCK_ID_SXS0 = 0x2f,
+ DBG_BLOCK_ID_SXS1 = 0x30,
+ DBG_BLOCK_ID_SXS2 = 0x31,
+ DBG_BLOCK_ID_SXS3 = 0x32,
+ DBG_BLOCK_ID_SXS4 = 0x33,
+ DBG_BLOCK_ID_SXS5 = 0x34,
+ DBG_BLOCK_ID_SXS6 = 0x35,
+ DBG_BLOCK_ID_SXS7 = 0x36,
+ DBG_BLOCK_ID_SXS8 = 0x37,
+ DBG_BLOCK_ID_SXS9 = 0x38,
+ DBG_BLOCK_ID_BCI0 = 0x39,
+ DBG_BLOCK_ID_BCI1 = 0x3a,
+ DBG_BLOCK_ID_BCI2 = 0x3b,
+ DBG_BLOCK_ID_BCI3 = 0x3c,
+ DBG_BLOCK_ID_MCB = 0x3d,
+ DBG_BLOCK_ID_UNUSED6 = 0x3e,
+ DBG_BLOCK_ID_SQA00 = 0x3f,
+ DBG_BLOCK_ID_SQA01 = 0x40,
+ DBG_BLOCK_ID_SQA02 = 0x41,
+ DBG_BLOCK_ID_SQA10 = 0x42,
+ DBG_BLOCK_ID_SQA11 = 0x43,
+ DBG_BLOCK_ID_SQA12 = 0x44,
+ DBG_BLOCK_ID_UNUSED7 = 0x45,
+ DBG_BLOCK_ID_UNUSED8 = 0x46,
+ DBG_BLOCK_ID_SQB00 = 0x47,
+ DBG_BLOCK_ID_SQB01 = 0x48,
+ DBG_BLOCK_ID_SQB10 = 0x49,
+ DBG_BLOCK_ID_SQB11 = 0x4a,
+ DBG_BLOCK_ID_SQ00 = 0x4b,
+ DBG_BLOCK_ID_SQ01 = 0x4c,
+ DBG_BLOCK_ID_SQ10 = 0x4d,
+ DBG_BLOCK_ID_SQ11 = 0x4e,
+ DBG_BLOCK_ID_CB00 = 0x4f,
+ DBG_BLOCK_ID_CB01 = 0x50,
+ DBG_BLOCK_ID_CB02 = 0x51,
+ DBG_BLOCK_ID_CB03 = 0x52,
+ DBG_BLOCK_ID_CB04 = 0x53,
+ DBG_BLOCK_ID_UNUSED9 = 0x54,
+ DBG_BLOCK_ID_UNUSED10 = 0x55,
+ DBG_BLOCK_ID_UNUSED11 = 0x56,
+ DBG_BLOCK_ID_CB10 = 0x57,
+ DBG_BLOCK_ID_CB11 = 0x58,
+ DBG_BLOCK_ID_CB12 = 0x59,
+ DBG_BLOCK_ID_CB13 = 0x5a,
+ DBG_BLOCK_ID_CB14 = 0x5b,
+ DBG_BLOCK_ID_UNUSED12 = 0x5c,
+ DBG_BLOCK_ID_UNUSED13 = 0x5d,
+ DBG_BLOCK_ID_UNUSED14 = 0x5e,
+ DBG_BLOCK_ID_TCP0 = 0x5f,
+ DBG_BLOCK_ID_TCP1 = 0x60,
+ DBG_BLOCK_ID_TCP2 = 0x61,
+ DBG_BLOCK_ID_TCP3 = 0x62,
+ DBG_BLOCK_ID_TCP4 = 0x63,
+ DBG_BLOCK_ID_TCP5 = 0x64,
+ DBG_BLOCK_ID_TCP6 = 0x65,
+ DBG_BLOCK_ID_TCP7 = 0x66,
+ DBG_BLOCK_ID_TCP8 = 0x67,
+ DBG_BLOCK_ID_TCP9 = 0x68,
+ DBG_BLOCK_ID_TCP10 = 0x69,
+ DBG_BLOCK_ID_TCP11 = 0x6a,
+ DBG_BLOCK_ID_TCP12 = 0x6b,
+ DBG_BLOCK_ID_TCP13 = 0x6c,
+ DBG_BLOCK_ID_TCP14 = 0x6d,
+ DBG_BLOCK_ID_TCP15 = 0x6e,
+ DBG_BLOCK_ID_TCP16 = 0x6f,
+ DBG_BLOCK_ID_TCP17 = 0x70,
+ DBG_BLOCK_ID_TCP18 = 0x71,
+ DBG_BLOCK_ID_TCP19 = 0x72,
+ DBG_BLOCK_ID_TCP20 = 0x73,
+ DBG_BLOCK_ID_TCP21 = 0x74,
+ DBG_BLOCK_ID_TCP22 = 0x75,
+ DBG_BLOCK_ID_TCP23 = 0x76,
+ DBG_BLOCK_ID_TCP_RESERVED0 = 0x77,
+ DBG_BLOCK_ID_TCP_RESERVED1 = 0x78,
+ DBG_BLOCK_ID_TCP_RESERVED2 = 0x79,
+ DBG_BLOCK_ID_TCP_RESERVED3 = 0x7a,
+ DBG_BLOCK_ID_TCP_RESERVED4 = 0x7b,
+ DBG_BLOCK_ID_TCP_RESERVED5 = 0x7c,
+ DBG_BLOCK_ID_TCP_RESERVED6 = 0x7d,
+ DBG_BLOCK_ID_TCP_RESERVED7 = 0x7e,
+ DBG_BLOCK_ID_DB00 = 0x7f,
+ DBG_BLOCK_ID_DB01 = 0x80,
+ DBG_BLOCK_ID_DB02 = 0x81,
+ DBG_BLOCK_ID_DB03 = 0x82,
+ DBG_BLOCK_ID_DB04 = 0x83,
+ DBG_BLOCK_ID_UNUSED15 = 0x84,
+ DBG_BLOCK_ID_UNUSED16 = 0x85,
+ DBG_BLOCK_ID_UNUSED17 = 0x86,
+ DBG_BLOCK_ID_DB10 = 0x87,
+ DBG_BLOCK_ID_DB11 = 0x88,
+ DBG_BLOCK_ID_DB12 = 0x89,
+ DBG_BLOCK_ID_DB13 = 0x8a,
+ DBG_BLOCK_ID_DB14 = 0x8b,
+ DBG_BLOCK_ID_UNUSED18 = 0x8c,
+ DBG_BLOCK_ID_UNUSED19 = 0x8d,
+ DBG_BLOCK_ID_UNUSED20 = 0x8e,
+ DBG_BLOCK_ID_TCC0 = 0x8f,
+ DBG_BLOCK_ID_TCC1 = 0x90,
+ DBG_BLOCK_ID_TCC2 = 0x91,
+ DBG_BLOCK_ID_TCC3 = 0x92,
+ DBG_BLOCK_ID_TCC4 = 0x93,
+ DBG_BLOCK_ID_TCC5 = 0x94,
+ DBG_BLOCK_ID_TCC6 = 0x95,
+ DBG_BLOCK_ID_TCC7 = 0x96,
+ DBG_BLOCK_ID_SPS00 = 0x97,
+ DBG_BLOCK_ID_SPS01 = 0x98,
+ DBG_BLOCK_ID_SPS02 = 0x99,
+ DBG_BLOCK_ID_SPS10 = 0x9a,
+ DBG_BLOCK_ID_SPS11 = 0x9b,
+ DBG_BLOCK_ID_SPS12 = 0x9c,
+ DBG_BLOCK_ID_UNUSED21 = 0x9d,
+ DBG_BLOCK_ID_UNUSED22 = 0x9e,
+ DBG_BLOCK_ID_TA00 = 0x9f,
+ DBG_BLOCK_ID_TA01 = 0xa0,
+ DBG_BLOCK_ID_TA02 = 0xa1,
+ DBG_BLOCK_ID_TA03 = 0xa2,
+ DBG_BLOCK_ID_TA04 = 0xa3,
+ DBG_BLOCK_ID_TA05 = 0xa4,
+ DBG_BLOCK_ID_TA06 = 0xa5,
+ DBG_BLOCK_ID_TA07 = 0xa6,
+ DBG_BLOCK_ID_TA08 = 0xa7,
+ DBG_BLOCK_ID_TA09 = 0xa8,
+ DBG_BLOCK_ID_TA0A = 0xa9,
+ DBG_BLOCK_ID_TA0B = 0xaa,
+ DBG_BLOCK_ID_UNUSED23 = 0xab,
+ DBG_BLOCK_ID_UNUSED24 = 0xac,
+ DBG_BLOCK_ID_UNUSED25 = 0xad,
+ DBG_BLOCK_ID_UNUSED26 = 0xae,
+ DBG_BLOCK_ID_TA10 = 0xaf,
+ DBG_BLOCK_ID_TA11 = 0xb0,
+ DBG_BLOCK_ID_TA12 = 0xb1,
+ DBG_BLOCK_ID_TA13 = 0xb2,
+ DBG_BLOCK_ID_TA14 = 0xb3,
+ DBG_BLOCK_ID_TA15 = 0xb4,
+ DBG_BLOCK_ID_TA16 = 0xb5,
+ DBG_BLOCK_ID_TA17 = 0xb6,
+ DBG_BLOCK_ID_TA18 = 0xb7,
+ DBG_BLOCK_ID_TA19 = 0xb8,
+ DBG_BLOCK_ID_TA1A = 0xb9,
+ DBG_BLOCK_ID_TA1B = 0xba,
+ DBG_BLOCK_ID_UNUSED27 = 0xbb,
+ DBG_BLOCK_ID_UNUSED28 = 0xbc,
+ DBG_BLOCK_ID_UNUSED29 = 0xbd,
+ DBG_BLOCK_ID_UNUSED30 = 0xbe,
+ DBG_BLOCK_ID_TD00 = 0xbf,
+ DBG_BLOCK_ID_TD01 = 0xc0,
+ DBG_BLOCK_ID_TD02 = 0xc1,
+ DBG_BLOCK_ID_TD03 = 0xc2,
+ DBG_BLOCK_ID_TD04 = 0xc3,
+ DBG_BLOCK_ID_TD05 = 0xc4,
+ DBG_BLOCK_ID_TD06 = 0xc5,
+ DBG_BLOCK_ID_TD07 = 0xc6,
+ DBG_BLOCK_ID_TD08 = 0xc7,
+ DBG_BLOCK_ID_TD09 = 0xc8,
+ DBG_BLOCK_ID_TD0A = 0xc9,
+ DBG_BLOCK_ID_TD0B = 0xca,
+ DBG_BLOCK_ID_UNUSED31 = 0xcb,
+ DBG_BLOCK_ID_UNUSED32 = 0xcc,
+ DBG_BLOCK_ID_UNUSED33 = 0xcd,
+ DBG_BLOCK_ID_UNUSED34 = 0xce,
+ DBG_BLOCK_ID_TD10 = 0xcf,
+ DBG_BLOCK_ID_TD11 = 0xd0,
+ DBG_BLOCK_ID_TD12 = 0xd1,
+ DBG_BLOCK_ID_TD13 = 0xd2,
+ DBG_BLOCK_ID_TD14 = 0xd3,
+ DBG_BLOCK_ID_TD15 = 0xd4,
+ DBG_BLOCK_ID_TD16 = 0xd5,
+ DBG_BLOCK_ID_TD17 = 0xd6,
+ DBG_BLOCK_ID_TD18 = 0xd7,
+ DBG_BLOCK_ID_TD19 = 0xd8,
+ DBG_BLOCK_ID_TD1A = 0xd9,
+ DBG_BLOCK_ID_TD1B = 0xda,
+ DBG_BLOCK_ID_UNUSED35 = 0xdb,
+ DBG_BLOCK_ID_UNUSED36 = 0xdc,
+ DBG_BLOCK_ID_UNUSED37 = 0xdd,
+ DBG_BLOCK_ID_UNUSED38 = 0xde,
+ DBG_BLOCK_ID_LDS00 = 0xdf,
+ DBG_BLOCK_ID_LDS01 = 0xe0,
+ DBG_BLOCK_ID_LDS02 = 0xe1,
+ DBG_BLOCK_ID_LDS03 = 0xe2,
+ DBG_BLOCK_ID_LDS04 = 0xe3,
+ DBG_BLOCK_ID_LDS05 = 0xe4,
+ DBG_BLOCK_ID_LDS06 = 0xe5,
+ DBG_BLOCK_ID_LDS07 = 0xe6,
+ DBG_BLOCK_ID_LDS08 = 0xe7,
+ DBG_BLOCK_ID_LDS09 = 0xe8,
+ DBG_BLOCK_ID_LDS0A = 0xe9,
+ DBG_BLOCK_ID_LDS0B = 0xea,
+ DBG_BLOCK_ID_UNUSED39 = 0xeb,
+ DBG_BLOCK_ID_UNUSED40 = 0xec,
+ DBG_BLOCK_ID_UNUSED41 = 0xed,
+ DBG_BLOCK_ID_UNUSED42 = 0xee,
+ DBG_BLOCK_ID_LDS10 = 0xef,
+ DBG_BLOCK_ID_LDS11 = 0xf0,
+ DBG_BLOCK_ID_LDS12 = 0xf1,
+ DBG_BLOCK_ID_LDS13 = 0xf2,
+ DBG_BLOCK_ID_LDS14 = 0xf3,
+ DBG_BLOCK_ID_LDS15 = 0xf4,
+ DBG_BLOCK_ID_LDS16 = 0xf5,
+ DBG_BLOCK_ID_LDS17 = 0xf6,
+ DBG_BLOCK_ID_LDS18 = 0xf7,
+ DBG_BLOCK_ID_LDS19 = 0xf8,
+ DBG_BLOCK_ID_LDS1A = 0xf9,
+ DBG_BLOCK_ID_LDS1B = 0xfa,
+ DBG_BLOCK_ID_UNUSED43 = 0xfb,
+ DBG_BLOCK_ID_UNUSED44 = 0xfc,
+ DBG_BLOCK_ID_UNUSED45 = 0xfd,
+ DBG_BLOCK_ID_UNUSED46 = 0xfe,
+} DebugBlockId;
+typedef enum DebugBlockId_BY2 {
+ DBG_BLOCK_ID_RESERVED_BY2 = 0x0,
+ DBG_BLOCK_ID_VMC_BY2 = 0x1,
+ DBG_BLOCK_ID_UNUSED0_BY2 = 0x2,
+ DBG_BLOCK_ID_GRBM_BY2 = 0x3,
+ DBG_BLOCK_ID_CSC_BY2 = 0x4,
+ DBG_BLOCK_ID_IH_BY2 = 0x5,
+ DBG_BLOCK_ID_SQ_BY2 = 0x6,
+ DBG_BLOCK_ID_UVD_BY2 = 0x7,
+ DBG_BLOCK_ID_SDMA0_BY2 = 0x8,
+ DBG_BLOCK_ID_SPIM_BY2 = 0x9,
+ DBG_BLOCK_ID_VC0_BY2 = 0xa,
+ DBG_BLOCK_ID_PA_BY2 = 0xb,
+ DBG_BLOCK_ID_CP0_BY2 = 0xc,
+ DBG_BLOCK_ID_CP2_BY2 = 0xd,
+ DBG_BLOCK_ID_PC0_BY2 = 0xe,
+ DBG_BLOCK_ID_BCI0_BY2 = 0xf,
+ DBG_BLOCK_ID_SXM0_BY2 = 0x10,
+ DBG_BLOCK_ID_SCT0_BY2 = 0x11,
+ DBG_BLOCK_ID_SPM0_BY2 = 0x12,
+ DBG_BLOCK_ID_BCI2_BY2 = 0x13,
+ DBG_BLOCK_ID_TCA_BY2 = 0x14,
+ DBG_BLOCK_ID_TCCA_BY2 = 0x15,
+ DBG_BLOCK_ID_MCC_BY2 = 0x16,
+ DBG_BLOCK_ID_MCC2_BY2 = 0x17,
+ DBG_BLOCK_ID_MCD_BY2 = 0x18,
+ DBG_BLOCK_ID_MCD2_BY2 = 0x19,
+ DBG_BLOCK_ID_MCD4_BY2 = 0x1a,
+ DBG_BLOCK_ID_MCB_BY2 = 0x1b,
+ DBG_BLOCK_ID_SQA_BY2 = 0x1c,
+ DBG_BLOCK_ID_SQA02_BY2 = 0x1d,
+ DBG_BLOCK_ID_SQA11_BY2 = 0x1e,
+ DBG_BLOCK_ID_UNUSED8_BY2 = 0x1f,
+ DBG_BLOCK_ID_SQB_BY2 = 0x20,
+ DBG_BLOCK_ID_SQB10_BY2 = 0x21,
+ DBG_BLOCK_ID_UNUSED10_BY2 = 0x22,
+ DBG_BLOCK_ID_UNUSED12_BY2 = 0x23,
+ DBG_BLOCK_ID_CB_BY2 = 0x24,
+ DBG_BLOCK_ID_CB02_BY2 = 0x25,
+ DBG_BLOCK_ID_CB10_BY2 = 0x26,
+ DBG_BLOCK_ID_CB12_BY2 = 0x27,
+ DBG_BLOCK_ID_SXS_BY2 = 0x28,
+ DBG_BLOCK_ID_SXS2_BY2 = 0x29,
+ DBG_BLOCK_ID_SXS4_BY2 = 0x2a,
+ DBG_BLOCK_ID_SXS6_BY2 = 0x2b,
+ DBG_BLOCK_ID_DB_BY2 = 0x2c,
+ DBG_BLOCK_ID_DB02_BY2 = 0x2d,
+ DBG_BLOCK_ID_DB10_BY2 = 0x2e,
+ DBG_BLOCK_ID_DB12_BY2 = 0x2f,
+ DBG_BLOCK_ID_TCP_BY2 = 0x30,
+ DBG_BLOCK_ID_TCP2_BY2 = 0x31,
+ DBG_BLOCK_ID_TCP4_BY2 = 0x32,
+ DBG_BLOCK_ID_TCP6_BY2 = 0x33,
+ DBG_BLOCK_ID_TCP8_BY2 = 0x34,
+ DBG_BLOCK_ID_TCP10_BY2 = 0x35,
+ DBG_BLOCK_ID_TCP12_BY2 = 0x36,
+ DBG_BLOCK_ID_TCP14_BY2 = 0x37,
+ DBG_BLOCK_ID_TCP16_BY2 = 0x38,
+ DBG_BLOCK_ID_TCP18_BY2 = 0x39,
+ DBG_BLOCK_ID_TCP20_BY2 = 0x3a,
+ DBG_BLOCK_ID_TCP22_BY2 = 0x3b,
+ DBG_BLOCK_ID_TCP_RESERVED0_BY2 = 0x3c,
+ DBG_BLOCK_ID_TCP_RESERVED2_BY2 = 0x3d,
+ DBG_BLOCK_ID_TCP_RESERVED4_BY2 = 0x3e,
+ DBG_BLOCK_ID_TCP_RESERVED6_BY2 = 0x3f,
+ DBG_BLOCK_ID_TCC_BY2 = 0x40,
+ DBG_BLOCK_ID_TCC2_BY2 = 0x41,
+ DBG_BLOCK_ID_TCC4_BY2 = 0x42,
+ DBG_BLOCK_ID_TCC6_BY2 = 0x43,
+ DBG_BLOCK_ID_SPS_BY2 = 0x44,
+ DBG_BLOCK_ID_SPS02_BY2 = 0x45,
+ DBG_BLOCK_ID_SPS11_BY2 = 0x46,
+ DBG_BLOCK_ID_UNUSED14_BY2 = 0x47,
+ DBG_BLOCK_ID_TA_BY2 = 0x48,
+ DBG_BLOCK_ID_TA02_BY2 = 0x49,
+ DBG_BLOCK_ID_TA04_BY2 = 0x4a,
+ DBG_BLOCK_ID_TA06_BY2 = 0x4b,
+ DBG_BLOCK_ID_TA08_BY2 = 0x4c,
+ DBG_BLOCK_ID_TA0A_BY2 = 0x4d,
+ DBG_BLOCK_ID_UNUSED20_BY2 = 0x4e,
+ DBG_BLOCK_ID_UNUSED22_BY2 = 0x4f,
+ DBG_BLOCK_ID_TA10_BY2 = 0x50,
+ DBG_BLOCK_ID_TA12_BY2 = 0x51,
+ DBG_BLOCK_ID_TA14_BY2 = 0x52,
+ DBG_BLOCK_ID_TA16_BY2 = 0x53,
+ DBG_BLOCK_ID_TA18_BY2 = 0x54,
+ DBG_BLOCK_ID_TA1A_BY2 = 0x55,
+ DBG_BLOCK_ID_UNUSED24_BY2 = 0x56,
+ DBG_BLOCK_ID_UNUSED26_BY2 = 0x57,
+ DBG_BLOCK_ID_TD_BY2 = 0x58,
+ DBG_BLOCK_ID_TD02_BY2 = 0x59,
+ DBG_BLOCK_ID_TD04_BY2 = 0x5a,
+ DBG_BLOCK_ID_TD06_BY2 = 0x5b,
+ DBG_BLOCK_ID_TD08_BY2 = 0x5c,
+ DBG_BLOCK_ID_TD0A_BY2 = 0x5d,
+ DBG_BLOCK_ID_UNUSED28_BY2 = 0x5e,
+ DBG_BLOCK_ID_UNUSED30_BY2 = 0x5f,
+ DBG_BLOCK_ID_TD10_BY2 = 0x60,
+ DBG_BLOCK_ID_TD12_BY2 = 0x61,
+ DBG_BLOCK_ID_TD14_BY2 = 0x62,
+ DBG_BLOCK_ID_TD16_BY2 = 0x63,
+ DBG_BLOCK_ID_TD18_BY2 = 0x64,
+ DBG_BLOCK_ID_TD1A_BY2 = 0x65,
+ DBG_BLOCK_ID_UNUSED32_BY2 = 0x66,
+ DBG_BLOCK_ID_UNUSED34_BY2 = 0x67,
+ DBG_BLOCK_ID_LDS_BY2 = 0x68,
+ DBG_BLOCK_ID_LDS02_BY2 = 0x69,
+ DBG_BLOCK_ID_LDS04_BY2 = 0x6a,
+ DBG_BLOCK_ID_LDS06_BY2 = 0x6b,
+ DBG_BLOCK_ID_LDS08_BY2 = 0x6c,
+ DBG_BLOCK_ID_LDS0A_BY2 = 0x6d,
+ DBG_BLOCK_ID_UNUSED36_BY2 = 0x6e,
+ DBG_BLOCK_ID_UNUSED38_BY2 = 0x6f,
+ DBG_BLOCK_ID_LDS10_BY2 = 0x70,
+ DBG_BLOCK_ID_LDS12_BY2 = 0x71,
+ DBG_BLOCK_ID_LDS14_BY2 = 0x72,
+ DBG_BLOCK_ID_LDS16_BY2 = 0x73,
+ DBG_BLOCK_ID_LDS18_BY2 = 0x74,
+ DBG_BLOCK_ID_LDS1A_BY2 = 0x75,
+ DBG_BLOCK_ID_UNUSED40_BY2 = 0x76,
+ DBG_BLOCK_ID_UNUSED42_BY2 = 0x77,
+} DebugBlockId_BY2;
+typedef enum DebugBlockId_BY4 {
+ DBG_BLOCK_ID_RESERVED_BY4 = 0x0,
+ DBG_BLOCK_ID_UNUSED0_BY4 = 0x1,
+ DBG_BLOCK_ID_CSC_BY4 = 0x2,
+ DBG_BLOCK_ID_SQ_BY4 = 0x3,
+ DBG_BLOCK_ID_SDMA0_BY4 = 0x4,
+ DBG_BLOCK_ID_VC0_BY4 = 0x5,
+ DBG_BLOCK_ID_CP0_BY4 = 0x6,
+ DBG_BLOCK_ID_UNUSED1_BY4 = 0x7,
+ DBG_BLOCK_ID_SXM0_BY4 = 0x8,
+ DBG_BLOCK_ID_SPM0_BY4 = 0x9,
+ DBG_BLOCK_ID_TCAA_BY4 = 0xa,
+ DBG_BLOCK_ID_MCC_BY4 = 0xb,
+ DBG_BLOCK_ID_MCD_BY4 = 0xc,
+ DBG_BLOCK_ID_MCD4_BY4 = 0xd,
+ DBG_BLOCK_ID_SQA_BY4 = 0xe,
+ DBG_BLOCK_ID_SQA11_BY4 = 0xf,
+ DBG_BLOCK_ID_SQB_BY4 = 0x10,
+ DBG_BLOCK_ID_UNUSED10_BY4 = 0x11,
+ DBG_BLOCK_ID_CB_BY4 = 0x12,
+ DBG_BLOCK_ID_CB10_BY4 = 0x13,
+ DBG_BLOCK_ID_SXS_BY4 = 0x14,
+ DBG_BLOCK_ID_SXS4_BY4 = 0x15,
+ DBG_BLOCK_ID_DB_BY4 = 0x16,
+ DBG_BLOCK_ID_DB10_BY4 = 0x17,
+ DBG_BLOCK_ID_TCP_BY4 = 0x18,
+ DBG_BLOCK_ID_TCP4_BY4 = 0x19,
+ DBG_BLOCK_ID_TCP8_BY4 = 0x1a,
+ DBG_BLOCK_ID_TCP12_BY4 = 0x1b,
+ DBG_BLOCK_ID_TCP16_BY4 = 0x1c,
+ DBG_BLOCK_ID_TCP20_BY4 = 0x1d,
+ DBG_BLOCK_ID_TCP_RESERVED0_BY4 = 0x1e,
+ DBG_BLOCK_ID_TCP_RESERVED4_BY4 = 0x1f,
+ DBG_BLOCK_ID_TCC_BY4 = 0x20,
+ DBG_BLOCK_ID_TCC4_BY4 = 0x21,
+ DBG_BLOCK_ID_SPS_BY4 = 0x22,
+ DBG_BLOCK_ID_SPS11_BY4 = 0x23,
+ DBG_BLOCK_ID_TA_BY4 = 0x24,
+ DBG_BLOCK_ID_TA04_BY4 = 0x25,
+ DBG_BLOCK_ID_TA08_BY4 = 0x26,
+ DBG_BLOCK_ID_UNUSED20_BY4 = 0x27,
+ DBG_BLOCK_ID_TA10_BY4 = 0x28,
+ DBG_BLOCK_ID_TA14_BY4 = 0x29,
+ DBG_BLOCK_ID_TA18_BY4 = 0x2a,
+ DBG_BLOCK_ID_UNUSED24_BY4 = 0x2b,
+ DBG_BLOCK_ID_TD_BY4 = 0x2c,
+ DBG_BLOCK_ID_TD04_BY4 = 0x2d,
+ DBG_BLOCK_ID_TD08_BY4 = 0x2e,
+ DBG_BLOCK_ID_UNUSED28_BY4 = 0x2f,
+ DBG_BLOCK_ID_TD10_BY4 = 0x30,
+ DBG_BLOCK_ID_TD14_BY4 = 0x31,
+ DBG_BLOCK_ID_TD18_BY4 = 0x32,
+ DBG_BLOCK_ID_UNUSED32_BY4 = 0x33,
+ DBG_BLOCK_ID_LDS_BY4 = 0x34,
+ DBG_BLOCK_ID_LDS04_BY4 = 0x35,
+ DBG_BLOCK_ID_LDS08_BY4 = 0x36,
+ DBG_BLOCK_ID_UNUSED36_BY4 = 0x37,
+ DBG_BLOCK_ID_LDS10_BY4 = 0x38,
+ DBG_BLOCK_ID_LDS14_BY4 = 0x39,
+ DBG_BLOCK_ID_LDS18_BY4 = 0x3a,
+ DBG_BLOCK_ID_UNUSED40_BY4 = 0x3b,
+} DebugBlockId_BY4;
+typedef enum DebugBlockId_BY8 {
+ DBG_BLOCK_ID_RESERVED_BY8 = 0x0,
+ DBG_BLOCK_ID_CSC_BY8 = 0x1,
+ DBG_BLOCK_ID_SDMA0_BY8 = 0x2,
+ DBG_BLOCK_ID_CP0_BY8 = 0x3,
+ DBG_BLOCK_ID_SXM0_BY8 = 0x4,
+ DBG_BLOCK_ID_TCA_BY8 = 0x5,
+ DBG_BLOCK_ID_MCD_BY8 = 0x6,
+ DBG_BLOCK_ID_SQA_BY8 = 0x7,
+ DBG_BLOCK_ID_SQB_BY8 = 0x8,
+ DBG_BLOCK_ID_CB_BY8 = 0x9,
+ DBG_BLOCK_ID_SXS_BY8 = 0xa,
+ DBG_BLOCK_ID_DB_BY8 = 0xb,
+ DBG_BLOCK_ID_TCP_BY8 = 0xc,
+ DBG_BLOCK_ID_TCP8_BY8 = 0xd,
+ DBG_BLOCK_ID_TCP16_BY8 = 0xe,
+ DBG_BLOCK_ID_TCP_RESERVED0_BY8 = 0xf,
+ DBG_BLOCK_ID_TCC_BY8 = 0x10,
+ DBG_BLOCK_ID_SPS_BY8 = 0x11,
+ DBG_BLOCK_ID_TA_BY8 = 0x12,
+ DBG_BLOCK_ID_TA08_BY8 = 0x13,
+ DBG_BLOCK_ID_TA10_BY8 = 0x14,
+ DBG_BLOCK_ID_TA18_BY8 = 0x15,
+ DBG_BLOCK_ID_TD_BY8 = 0x16,
+ DBG_BLOCK_ID_TD08_BY8 = 0x17,
+ DBG_BLOCK_ID_TD10_BY8 = 0x18,
+ DBG_BLOCK_ID_TD18_BY8 = 0x19,
+ DBG_BLOCK_ID_LDS_BY8 = 0x1a,
+ DBG_BLOCK_ID_LDS08_BY8 = 0x1b,
+ DBG_BLOCK_ID_LDS10_BY8 = 0x1c,
+ DBG_BLOCK_ID_LDS18_BY8 = 0x1d,
+} DebugBlockId_BY8;
+typedef enum DebugBlockId_BY16 {
+ DBG_BLOCK_ID_RESERVED_BY16 = 0x0,
+ DBG_BLOCK_ID_SDMA0_BY16 = 0x1,
+ DBG_BLOCK_ID_SXM_BY16 = 0x2,
+ DBG_BLOCK_ID_MCD_BY16 = 0x3,
+ DBG_BLOCK_ID_SQB_BY16 = 0x4,
+ DBG_BLOCK_ID_SXS_BY16 = 0x5,
+ DBG_BLOCK_ID_TCP_BY16 = 0x6,
+ DBG_BLOCK_ID_TCP16_BY16 = 0x7,
+ DBG_BLOCK_ID_TCC_BY16 = 0x8,
+ DBG_BLOCK_ID_TA_BY16 = 0x9,
+ DBG_BLOCK_ID_TA10_BY16 = 0xa,
+ DBG_BLOCK_ID_TD_BY16 = 0xb,
+ DBG_BLOCK_ID_TD10_BY16 = 0xc,
+ DBG_BLOCK_ID_LDS_BY16 = 0xd,
+ DBG_BLOCK_ID_LDS10_BY16 = 0xe,
+} DebugBlockId_BY16;
+typedef enum SurfaceEndian {
+ ENDIAN_NONE = 0x0,
+ ENDIAN_8IN16 = 0x1,
+ ENDIAN_8IN32 = 0x2,
+ ENDIAN_8IN64 = 0x3,
+} SurfaceEndian;
+typedef enum ArrayMode {
+ ARRAY_LINEAR_GENERAL = 0x0,
+ ARRAY_LINEAR_ALIGNED = 0x1,
+ ARRAY_1D_TILED_THIN1 = 0x2,
+ ARRAY_1D_TILED_THICK = 0x3,
+ ARRAY_2D_TILED_THIN1 = 0x4,
+ ARRAY_PRT_TILED_THIN1 = 0x5,
+ ARRAY_PRT_2D_TILED_THIN1 = 0x6,
+ ARRAY_2D_TILED_THICK = 0x7,
+ ARRAY_2D_TILED_XTHICK = 0x8,
+ ARRAY_PRT_TILED_THICK = 0x9,
+ ARRAY_PRT_2D_TILED_THICK = 0xa,
+ ARRAY_PRT_3D_TILED_THIN1 = 0xb,
+ ARRAY_3D_TILED_THIN1 = 0xc,
+ ARRAY_3D_TILED_THICK = 0xd,
+ ARRAY_3D_TILED_XTHICK = 0xe,
+ ARRAY_PRT_3D_TILED_THICK = 0xf,
+} ArrayMode;
+typedef enum PipeTiling {
+ CONFIG_1_PIPE = 0x0,
+ CONFIG_2_PIPE = 0x1,
+ CONFIG_4_PIPE = 0x2,
+ CONFIG_8_PIPE = 0x3,
+} PipeTiling;
+typedef enum BankTiling {
+ CONFIG_4_BANK = 0x0,
+ CONFIG_8_BANK = 0x1,
+} BankTiling;
+typedef enum GroupInterleave {
+ CONFIG_256B_GROUP = 0x0,
+ CONFIG_512B_GROUP = 0x1,
+} GroupInterleave;
+typedef enum RowTiling {
+ CONFIG_1KB_ROW = 0x0,
+ CONFIG_2KB_ROW = 0x1,
+ CONFIG_4KB_ROW = 0x2,
+ CONFIG_8KB_ROW = 0x3,
+ CONFIG_1KB_ROW_OPT = 0x4,
+ CONFIG_2KB_ROW_OPT = 0x5,
+ CONFIG_4KB_ROW_OPT = 0x6,
+ CONFIG_8KB_ROW_OPT = 0x7,
+} RowTiling;
+typedef enum BankSwapBytes {
+ CONFIG_128B_SWAPS = 0x0,
+ CONFIG_256B_SWAPS = 0x1,
+ CONFIG_512B_SWAPS = 0x2,
+ CONFIG_1KB_SWAPS = 0x3,
+} BankSwapBytes;
+typedef enum SampleSplitBytes {
+ CONFIG_1KB_SPLIT = 0x0,
+ CONFIG_2KB_SPLIT = 0x1,
+ CONFIG_4KB_SPLIT = 0x2,
+ CONFIG_8KB_SPLIT = 0x3,
+} SampleSplitBytes;
+typedef enum NumPipes {
+ ADDR_CONFIG_1_PIPE = 0x0,
+ ADDR_CONFIG_2_PIPE = 0x1,
+ ADDR_CONFIG_4_PIPE = 0x2,
+ ADDR_CONFIG_8_PIPE = 0x3,
+} NumPipes;
+typedef enum PipeInterleaveSize {
+ ADDR_CONFIG_PIPE_INTERLEAVE_256B = 0x0,
+ ADDR_CONFIG_PIPE_INTERLEAVE_512B = 0x1,
+} PipeInterleaveSize;
+typedef enum BankInterleaveSize {
+ ADDR_CONFIG_BANK_INTERLEAVE_1 = 0x0,
+ ADDR_CONFIG_BANK_INTERLEAVE_2 = 0x1,
+ ADDR_CONFIG_BANK_INTERLEAVE_4 = 0x2,
+ ADDR_CONFIG_BANK_INTERLEAVE_8 = 0x3,
+} BankInterleaveSize;
+typedef enum NumShaderEngines {
+ ADDR_CONFIG_1_SHADER_ENGINE = 0x0,
+ ADDR_CONFIG_2_SHADER_ENGINE = 0x1,
+} NumShaderEngines;
+typedef enum ShaderEngineTileSize {
+ ADDR_CONFIG_SE_TILE_16 = 0x0,
+ ADDR_CONFIG_SE_TILE_32 = 0x1,
+} ShaderEngineTileSize;
+typedef enum NumGPUs {
+ ADDR_CONFIG_1_GPU = 0x0,
+ ADDR_CONFIG_2_GPU = 0x1,
+ ADDR_CONFIG_4_GPU = 0x2,
+} NumGPUs;
+typedef enum MultiGPUTileSize {
+ ADDR_CONFIG_GPU_TILE_16 = 0x0,
+ ADDR_CONFIG_GPU_TILE_32 = 0x1,
+ ADDR_CONFIG_GPU_TILE_64 = 0x2,
+ ADDR_CONFIG_GPU_TILE_128 = 0x3,
+} MultiGPUTileSize;
+typedef enum RowSize {
+ ADDR_CONFIG_1KB_ROW = 0x0,
+ ADDR_CONFIG_2KB_ROW = 0x1,
+ ADDR_CONFIG_4KB_ROW = 0x2,
+} RowSize;
+typedef enum NumLowerPipes {
+ ADDR_CONFIG_1_LOWER_PIPES = 0x0,
+ ADDR_CONFIG_2_LOWER_PIPES = 0x1,
+} NumLowerPipes;
+typedef enum ColorTransform {
+ DCC_CT_AUTO = 0x0,
+ DCC_CT_NONE = 0x1,
+ ABGR_TO_A_BG_G_RB = 0x2,
+ BGRA_TO_BG_G_RB_A = 0x3,
+} ColorTransform;
+typedef enum CompareRef {
+ REF_NEVER = 0x0,
+ REF_LESS = 0x1,
+ REF_EQUAL = 0x2,
+ REF_LEQUAL = 0x3,
+ REF_GREATER = 0x4,
+ REF_NOTEQUAL = 0x5,
+ REF_GEQUAL = 0x6,
+ REF_ALWAYS = 0x7,
+} CompareRef;
+typedef enum ReadSize {
+ READ_256_BITS = 0x0,
+ READ_512_BITS = 0x1,
+} ReadSize;
+typedef enum DepthFormat {
+ DEPTH_INVALID = 0x0,
+ DEPTH_16 = 0x1,
+ DEPTH_X8_24 = 0x2,
+ DEPTH_8_24 = 0x3,
+ DEPTH_X8_24_FLOAT = 0x4,
+ DEPTH_8_24_FLOAT = 0x5,
+ DEPTH_32_FLOAT = 0x6,
+ DEPTH_X24_8_32_FLOAT = 0x7,
+} DepthFormat;
+typedef enum ZFormat {
+ Z_INVALID = 0x0,
+ Z_16 = 0x1,
+ Z_24 = 0x2,
+ Z_32_FLOAT = 0x3,
+} ZFormat;
+typedef enum StencilFormat {
+ STENCIL_INVALID = 0x0,
+ STENCIL_8 = 0x1,
+} StencilFormat;
+typedef enum CmaskMode {
+ CMASK_CLEAR_NONE = 0x0,
+ CMASK_CLEAR_ONE = 0x1,
+ CMASK_CLEAR_ALL = 0x2,
+ CMASK_ANY_EXPANDED = 0x3,
+ CMASK_ALPHA0_FRAG1 = 0x4,
+ CMASK_ALPHA0_FRAG2 = 0x5,
+ CMASK_ALPHA0_FRAG4 = 0x6,
+ CMASK_ALPHA0_FRAGS = 0x7,
+ CMASK_ALPHA1_FRAG1 = 0x8,
+ CMASK_ALPHA1_FRAG2 = 0x9,
+ CMASK_ALPHA1_FRAG4 = 0xa,
+ CMASK_ALPHA1_FRAGS = 0xb,
+ CMASK_ALPHAX_FRAG1 = 0xc,
+ CMASK_ALPHAX_FRAG2 = 0xd,
+ CMASK_ALPHAX_FRAG4 = 0xe,
+ CMASK_ALPHAX_FRAGS = 0xf,
+} CmaskMode;
+typedef enum QuadExportFormat {
+ EXPORT_UNUSED = 0x0,
+ EXPORT_32_R = 0x1,
+ EXPORT_32_GR = 0x2,
+ EXPORT_32_AR = 0x3,
+ EXPORT_FP16_ABGR = 0x4,
+ EXPORT_UNSIGNED16_ABGR = 0x5,
+ EXPORT_SIGNED16_ABGR = 0x6,
+ EXPORT_32_ABGR = 0x7,
+} QuadExportFormat;
+typedef enum QuadExportFormatOld {
+ EXPORT_4P_32BPC_ABGR = 0x0,
+ EXPORT_4P_16BPC_ABGR = 0x1,
+ EXPORT_4P_32BPC_GR = 0x2,
+ EXPORT_4P_32BPC_AR = 0x3,
+ EXPORT_2P_32BPC_ABGR = 0x4,
+ EXPORT_8P_32BPC_R = 0x5,
+} QuadExportFormatOld;
+typedef enum ColorFormat {
+ COLOR_INVALID = 0x0,
+ COLOR_8 = 0x1,
+ COLOR_16 = 0x2,
+ COLOR_8_8 = 0x3,
+ COLOR_32 = 0x4,
+ COLOR_16_16 = 0x5,
+ COLOR_10_11_11 = 0x6,
+ COLOR_11_11_10 = 0x7,
+ COLOR_10_10_10_2 = 0x8,
+ COLOR_2_10_10_10 = 0x9,
+ COLOR_8_8_8_8 = 0xa,
+ COLOR_32_32 = 0xb,
+ COLOR_16_16_16_16 = 0xc,
+ COLOR_RESERVED_13 = 0xd,
+ COLOR_32_32_32_32 = 0xe,
+ COLOR_RESERVED_15 = 0xf,
+ COLOR_5_6_5 = 0x10,
+ COLOR_1_5_5_5 = 0x11,
+ COLOR_5_5_5_1 = 0x12,
+ COLOR_4_4_4_4 = 0x13,
+ COLOR_8_24 = 0x14,
+ COLOR_24_8 = 0x15,
+ COLOR_X24_8_32_FLOAT = 0x16,
+ COLOR_RESERVED_23 = 0x17,
+} ColorFormat;
+typedef enum SurfaceFormat {
+ FMT_INVALID = 0x0,
+ FMT_8 = 0x1,
+ FMT_16 = 0x2,
+ FMT_8_8 = 0x3,
+ FMT_32 = 0x4,
+ FMT_16_16 = 0x5,
+ FMT_10_11_11 = 0x6,
+ FMT_11_11_10 = 0x7,
+ FMT_10_10_10_2 = 0x8,
+ FMT_2_10_10_10 = 0x9,
+ FMT_8_8_8_8 = 0xa,
+ FMT_32_32 = 0xb,
+ FMT_16_16_16_16 = 0xc,
+ FMT_32_32_32 = 0xd,
+ FMT_32_32_32_32 = 0xe,
+ FMT_RESERVED_4 = 0xf,
+ FMT_5_6_5 = 0x10,
+ FMT_1_5_5_5 = 0x11,
+ FMT_5_5_5_1 = 0x12,
+ FMT_4_4_4_4 = 0x13,
+ FMT_8_24 = 0x14,
+ FMT_24_8 = 0x15,
+ FMT_X24_8_32_FLOAT = 0x16,
+ FMT_RESERVED_33 = 0x17,
+ FMT_11_11_10_FLOAT = 0x18,
+ FMT_16_FLOAT = 0x19,
+ FMT_32_FLOAT = 0x1a,
+ FMT_16_16_FLOAT = 0x1b,
+ FMT_8_24_FLOAT = 0x1c,
+ FMT_24_8_FLOAT = 0x1d,
+ FMT_32_32_FLOAT = 0x1e,
+ FMT_10_11_11_FLOAT = 0x1f,
+ FMT_16_16_16_16_FLOAT = 0x20,
+ FMT_3_3_2 = 0x21,
+ FMT_6_5_5 = 0x22,
+ FMT_32_32_32_32_FLOAT = 0x23,
+ FMT_RESERVED_36 = 0x24,
+ FMT_1 = 0x25,
+ FMT_1_REVERSED = 0x26,
+ FMT_GB_GR = 0x27,
+ FMT_BG_RG = 0x28,
+ FMT_32_AS_8 = 0x29,
+ FMT_32_AS_8_8 = 0x2a,
+ FMT_5_9_9_9_SHAREDEXP = 0x2b,
+ FMT_8_8_8 = 0x2c,
+ FMT_16_16_16 = 0x2d,
+ FMT_16_16_16_FLOAT = 0x2e,
+ FMT_4_4 = 0x2f,
+ FMT_32_32_32_FLOAT = 0x30,
+ FMT_BC1 = 0x31,
+ FMT_BC2 = 0x32,
+ FMT_BC3 = 0x33,
+ FMT_BC4 = 0x34,
+ FMT_BC5 = 0x35,
+ FMT_BC6 = 0x36,
+ FMT_BC7 = 0x37,
+ FMT_32_AS_32_32_32_32 = 0x38,
+ FMT_APC3 = 0x39,
+ FMT_APC4 = 0x3a,
+ FMT_APC5 = 0x3b,
+ FMT_APC6 = 0x3c,
+ FMT_APC7 = 0x3d,
+ FMT_CTX1 = 0x3e,
+ FMT_RESERVED_63 = 0x3f,
+} SurfaceFormat;
+typedef enum BUF_DATA_FORMAT {
+ BUF_DATA_FORMAT_INVALID = 0x0,
+ BUF_DATA_FORMAT_8 = 0x1,
+ BUF_DATA_FORMAT_16 = 0x2,
+ BUF_DATA_FORMAT_8_8 = 0x3,
+ BUF_DATA_FORMAT_32 = 0x4,
+ BUF_DATA_FORMAT_16_16 = 0x5,
+ BUF_DATA_FORMAT_10_11_11 = 0x6,
+ BUF_DATA_FORMAT_11_11_10 = 0x7,
+ BUF_DATA_FORMAT_10_10_10_2 = 0x8,
+ BUF_DATA_FORMAT_2_10_10_10 = 0x9,
+ BUF_DATA_FORMAT_8_8_8_8 = 0xa,
+ BUF_DATA_FORMAT_32_32 = 0xb,
+ BUF_DATA_FORMAT_16_16_16_16 = 0xc,
+ BUF_DATA_FORMAT_32_32_32 = 0xd,
+ BUF_DATA_FORMAT_32_32_32_32 = 0xe,
+ BUF_DATA_FORMAT_RESERVED_15 = 0xf,
+} BUF_DATA_FORMAT;
+typedef enum IMG_DATA_FORMAT {
+ IMG_DATA_FORMAT_INVALID = 0x0,
+ IMG_DATA_FORMAT_8 = 0x1,
+ IMG_DATA_FORMAT_16 = 0x2,
+ IMG_DATA_FORMAT_8_8 = 0x3,
+ IMG_DATA_FORMAT_32 = 0x4,
+ IMG_DATA_FORMAT_16_16 = 0x5,
+ IMG_DATA_FORMAT_10_11_11 = 0x6,
+ IMG_DATA_FORMAT_11_11_10 = 0x7,
+ IMG_DATA_FORMAT_10_10_10_2 = 0x8,
+ IMG_DATA_FORMAT_2_10_10_10 = 0x9,
+ IMG_DATA_FORMAT_8_8_8_8 = 0xa,
+ IMG_DATA_FORMAT_32_32 = 0xb,
+ IMG_DATA_FORMAT_16_16_16_16 = 0xc,
+ IMG_DATA_FORMAT_32_32_32 = 0xd,
+ IMG_DATA_FORMAT_32_32_32_32 = 0xe,
+ IMG_DATA_FORMAT_RESERVED_15 = 0xf,
+ IMG_DATA_FORMAT_5_6_5 = 0x10,
+ IMG_DATA_FORMAT_1_5_5_5 = 0x11,
+ IMG_DATA_FORMAT_5_5_5_1 = 0x12,
+ IMG_DATA_FORMAT_4_4_4_4 = 0x13,
+ IMG_DATA_FORMAT_8_24 = 0x14,
+ IMG_DATA_FORMAT_24_8 = 0x15,
+ IMG_DATA_FORMAT_X24_8_32 = 0x16,
+ IMG_DATA_FORMAT_RESERVED_23 = 0x17,
+ IMG_DATA_FORMAT_RESERVED_24 = 0x18,
+ IMG_DATA_FORMAT_RESERVED_25 = 0x19,
+ IMG_DATA_FORMAT_RESERVED_26 = 0x1a,
+ IMG_DATA_FORMAT_RESERVED_27 = 0x1b,
+ IMG_DATA_FORMAT_RESERVED_28 = 0x1c,
+ IMG_DATA_FORMAT_RESERVED_29 = 0x1d,
+ IMG_DATA_FORMAT_RESERVED_30 = 0x1e,
+ IMG_DATA_FORMAT_RESERVED_31 = 0x1f,
+ IMG_DATA_FORMAT_GB_GR = 0x20,
+ IMG_DATA_FORMAT_BG_RG = 0x21,
+ IMG_DATA_FORMAT_5_9_9_9 = 0x22,
+ IMG_DATA_FORMAT_BC1 = 0x23,
+ IMG_DATA_FORMAT_BC2 = 0x24,
+ IMG_DATA_FORMAT_BC3 = 0x25,
+ IMG_DATA_FORMAT_BC4 = 0x26,
+ IMG_DATA_FORMAT_BC5 = 0x27,
+ IMG_DATA_FORMAT_BC6 = 0x28,
+ IMG_DATA_FORMAT_BC7 = 0x29,
+ IMG_DATA_FORMAT_RESERVED_42 = 0x2a,
+ IMG_DATA_FORMAT_RESERVED_43 = 0x2b,
+ IMG_DATA_FORMAT_FMASK8_S2_F1 = 0x2c,
+ IMG_DATA_FORMAT_FMASK8_S4_F1 = 0x2d,
+ IMG_DATA_FORMAT_FMASK8_S8_F1 = 0x2e,
+ IMG_DATA_FORMAT_FMASK8_S2_F2 = 0x2f,
+ IMG_DATA_FORMAT_FMASK8_S4_F2 = 0x30,
+ IMG_DATA_FORMAT_FMASK8_S4_F4 = 0x31,
+ IMG_DATA_FORMAT_FMASK16_S16_F1 = 0x32,
+ IMG_DATA_FORMAT_FMASK16_S8_F2 = 0x33,
+ IMG_DATA_FORMAT_FMASK32_S16_F2 = 0x34,
+ IMG_DATA_FORMAT_FMASK32_S8_F4 = 0x35,
+ IMG_DATA_FORMAT_FMASK32_S8_F8 = 0x36,
+ IMG_DATA_FORMAT_FMASK64_S16_F4 = 0x37,
+ IMG_DATA_FORMAT_FMASK64_S16_F8 = 0x38,
+ IMG_DATA_FORMAT_4_4 = 0x39,
+ IMG_DATA_FORMAT_6_5_5 = 0x3a,
+ IMG_DATA_FORMAT_1 = 0x3b,
+ IMG_DATA_FORMAT_1_REVERSED = 0x3c,
+ IMG_DATA_FORMAT_32_AS_8 = 0x3d,
+ IMG_DATA_FORMAT_32_AS_8_8 = 0x3e,
+ IMG_DATA_FORMAT_32_AS_32_32_32_32 = 0x3f,
+} IMG_DATA_FORMAT;
+typedef enum BUF_NUM_FORMAT {
+ BUF_NUM_FORMAT_UNORM = 0x0,
+ BUF_NUM_FORMAT_SNORM = 0x1,
+ BUF_NUM_FORMAT_USCALED = 0x2,
+ BUF_NUM_FORMAT_SSCALED = 0x3,
+ BUF_NUM_FORMAT_UINT = 0x4,
+ BUF_NUM_FORMAT_SINT = 0x5,
+ BUF_NUM_FORMAT_RESERVED_6 = 0x6,
+ BUF_NUM_FORMAT_FLOAT = 0x7,
+} BUF_NUM_FORMAT;
+typedef enum IMG_NUM_FORMAT {
+ IMG_NUM_FORMAT_UNORM = 0x0,
+ IMG_NUM_FORMAT_SNORM = 0x1,
+ IMG_NUM_FORMAT_USCALED = 0x2,
+ IMG_NUM_FORMAT_SSCALED = 0x3,
+ IMG_NUM_FORMAT_UINT = 0x4,
+ IMG_NUM_FORMAT_SINT = 0x5,
+ IMG_NUM_FORMAT_RESERVED_6 = 0x6,
+ IMG_NUM_FORMAT_FLOAT = 0x7,
+ IMG_NUM_FORMAT_RESERVED_8 = 0x8,
+ IMG_NUM_FORMAT_SRGB = 0x9,
+ IMG_NUM_FORMAT_RESERVED_10 = 0xa,
+ IMG_NUM_FORMAT_RESERVED_11 = 0xb,
+ IMG_NUM_FORMAT_RESERVED_12 = 0xc,
+ IMG_NUM_FORMAT_RESERVED_13 = 0xd,
+ IMG_NUM_FORMAT_RESERVED_14 = 0xe,
+ IMG_NUM_FORMAT_RESERVED_15 = 0xf,
+} IMG_NUM_FORMAT;
+typedef enum TileType {
+ ARRAY_COLOR_TILE = 0x0,
+ ARRAY_DEPTH_TILE = 0x1,
+} TileType;
+typedef enum NonDispTilingOrder {
+ ADDR_SURF_MICRO_TILING_DISPLAY = 0x0,
+ ADDR_SURF_MICRO_TILING_NON_DISPLAY = 0x1,
+} NonDispTilingOrder;
+typedef enum MicroTileMode {
+ ADDR_SURF_DISPLAY_MICRO_TILING = 0x0,
+ ADDR_SURF_THIN_MICRO_TILING = 0x1,
+ ADDR_SURF_DEPTH_MICRO_TILING = 0x2,
+ ADDR_SURF_ROTATED_MICRO_TILING = 0x3,
+ ADDR_SURF_THICK_MICRO_TILING = 0x4,
+} MicroTileMode;
+typedef enum TileSplit {
+ ADDR_SURF_TILE_SPLIT_64B = 0x0,
+ ADDR_SURF_TILE_SPLIT_128B = 0x1,
+ ADDR_SURF_TILE_SPLIT_256B = 0x2,
+ ADDR_SURF_TILE_SPLIT_512B = 0x3,
+ ADDR_SURF_TILE_SPLIT_1KB = 0x4,
+ ADDR_SURF_TILE_SPLIT_2KB = 0x5,
+ ADDR_SURF_TILE_SPLIT_4KB = 0x6,
+} TileSplit;
+typedef enum SampleSplit {
+ ADDR_SURF_SAMPLE_SPLIT_1 = 0x0,
+ ADDR_SURF_SAMPLE_SPLIT_2 = 0x1,
+ ADDR_SURF_SAMPLE_SPLIT_4 = 0x2,
+ ADDR_SURF_SAMPLE_SPLIT_8 = 0x3,
+} SampleSplit;
+typedef enum PipeConfig {
+ ADDR_SURF_P2 = 0x0,
+ ADDR_SURF_P2_RESERVED0 = 0x1,
+ ADDR_SURF_P2_RESERVED1 = 0x2,
+ ADDR_SURF_P2_RESERVED2 = 0x3,
+ ADDR_SURF_P4_8x16 = 0x4,
+ ADDR_SURF_P4_16x16 = 0x5,
+ ADDR_SURF_P4_16x32 = 0x6,
+ ADDR_SURF_P4_32x32 = 0x7,
+ ADDR_SURF_P8_16x16_8x16 = 0x8,
+ ADDR_SURF_P8_16x32_8x16 = 0x9,
+ ADDR_SURF_P8_32x32_8x16 = 0xa,
+ ADDR_SURF_P8_16x32_16x16 = 0xb,
+ ADDR_SURF_P8_32x32_16x16 = 0xc,
+ ADDR_SURF_P8_32x32_16x32 = 0xd,
+ ADDR_SURF_P8_32x64_32x32 = 0xe,
+ ADDR_SURF_P8_RESERVED0 = 0xf,
+ ADDR_SURF_P16_32x32_8x16 = 0x10,
+ ADDR_SURF_P16_32x32_16x16 = 0x11,
+} PipeConfig;
+typedef enum NumBanks {
+ ADDR_SURF_2_BANK = 0x0,
+ ADDR_SURF_4_BANK = 0x1,
+ ADDR_SURF_8_BANK = 0x2,
+ ADDR_SURF_16_BANK = 0x3,
+} NumBanks;
+typedef enum BankWidth {
+ ADDR_SURF_BANK_WIDTH_1 = 0x0,
+ ADDR_SURF_BANK_WIDTH_2 = 0x1,
+ ADDR_SURF_BANK_WIDTH_4 = 0x2,
+ ADDR_SURF_BANK_WIDTH_8 = 0x3,
+} BankWidth;
+typedef enum BankHeight {
+ ADDR_SURF_BANK_HEIGHT_1 = 0x0,
+ ADDR_SURF_BANK_HEIGHT_2 = 0x1,
+ ADDR_SURF_BANK_HEIGHT_4 = 0x2,
+ ADDR_SURF_BANK_HEIGHT_8 = 0x3,
+} BankHeight;
+typedef enum BankWidthHeight {
+ ADDR_SURF_BANK_WH_1 = 0x0,
+ ADDR_SURF_BANK_WH_2 = 0x1,
+ ADDR_SURF_BANK_WH_4 = 0x2,
+ ADDR_SURF_BANK_WH_8 = 0x3,
+} BankWidthHeight;
+typedef enum MacroTileAspect {
+ ADDR_SURF_MACRO_ASPECT_1 = 0x0,
+ ADDR_SURF_MACRO_ASPECT_2 = 0x1,
+ ADDR_SURF_MACRO_ASPECT_4 = 0x2,
+ ADDR_SURF_MACRO_ASPECT_8 = 0x3,
+} MacroTileAspect;
+typedef enum GATCL1RequestType {
+ GATCL1_TYPE_NORMAL = 0x0,
+ GATCL1_TYPE_SHOOTDOWN = 0x1,
+ GATCL1_TYPE_BYPASS = 0x2,
+} GATCL1RequestType;
+typedef enum TCC_CACHE_POLICIES {
+ TCC_CACHE_POLICY_LRU = 0x0,
+ TCC_CACHE_POLICY_STREAM = 0x1,
+} TCC_CACHE_POLICIES;
+typedef enum MTYPE {
+ MTYPE_NC_NV = 0x0,
+ MTYPE_NC = 0x1,
+ MTYPE_CC = 0x2,
+ MTYPE_UC = 0x3,
+} MTYPE;
+typedef enum PERFMON_COUNTER_MODE {
+ PERFMON_COUNTER_MODE_ACCUM = 0x0,
+ PERFMON_COUNTER_MODE_ACTIVE_CYCLES = 0x1,
+ PERFMON_COUNTER_MODE_MAX = 0x2,
+ PERFMON_COUNTER_MODE_DIRTY = 0x3,
+ PERFMON_COUNTER_MODE_SAMPLE = 0x4,
+ PERFMON_COUNTER_MODE_CYCLES_SINCE_FIRST_EVENT = 0x5,
+ PERFMON_COUNTER_MODE_CYCLES_SINCE_LAST_EVENT = 0x6,
+ PERFMON_COUNTER_MODE_CYCLES_GE_HI = 0x7,
+ PERFMON_COUNTER_MODE_CYCLES_EQ_HI = 0x8,
+ PERFMON_COUNTER_MODE_INACTIVE_CYCLES = 0x9,
+ PERFMON_COUNTER_MODE_RESERVED = 0xf,
+} PERFMON_COUNTER_MODE;
+typedef enum PERFMON_SPM_MODE {
+ PERFMON_SPM_MODE_OFF = 0x0,
+ PERFMON_SPM_MODE_16BIT_CLAMP = 0x1,
+ PERFMON_SPM_MODE_16BIT_NO_CLAMP = 0x2,
+ PERFMON_SPM_MODE_32BIT_CLAMP = 0x3,
+ PERFMON_SPM_MODE_32BIT_NO_CLAMP = 0x4,
+ PERFMON_SPM_MODE_RESERVED_5 = 0x5,
+ PERFMON_SPM_MODE_RESERVED_6 = 0x6,
+ PERFMON_SPM_MODE_RESERVED_7 = 0x7,
+ PERFMON_SPM_MODE_TEST_MODE_0 = 0x8,
+ PERFMON_SPM_MODE_TEST_MODE_1 = 0x9,
+ PERFMON_SPM_MODE_TEST_MODE_2 = 0xa,
+} PERFMON_SPM_MODE;
+typedef enum SurfaceTiling {
+ ARRAY_LINEAR = 0x0,
+ ARRAY_TILED = 0x1,
+} SurfaceTiling;
+typedef enum SurfaceArray {
+ ARRAY_1D = 0x0,
+ ARRAY_2D = 0x1,
+ ARRAY_3D = 0x2,
+ ARRAY_3D_SLICE = 0x3,
+} SurfaceArray;
+typedef enum ColorArray {
+ ARRAY_2D_ALT_COLOR = 0x0,
+ ARRAY_2D_COLOR = 0x1,
+ ARRAY_3D_SLICE_COLOR = 0x3,
+} ColorArray;
+typedef enum DepthArray {
+ ARRAY_2D_ALT_DEPTH = 0x0,
+ ARRAY_2D_DEPTH = 0x1,
+} DepthArray;
+typedef enum ENUM_NUM_SIMD_PER_CU {
+ NUM_SIMD_PER_CU = 0x4,
+} ENUM_NUM_SIMD_PER_CU;
+typedef enum MEM_PWR_FORCE_CTRL {
+ NO_FORCE_REQUEST = 0x0,
+ FORCE_LIGHT_SLEEP_REQUEST = 0x1,
+ FORCE_DEEP_SLEEP_REQUEST = 0x2,
+ FORCE_SHUT_DOWN_REQUEST = 0x3,
+} MEM_PWR_FORCE_CTRL;
+typedef enum MEM_PWR_FORCE_CTRL2 {
+ NO_FORCE_REQ = 0x0,
+ FORCE_LIGHT_SLEEP_REQ = 0x1,
+} MEM_PWR_FORCE_CTRL2;
+typedef enum MEM_PWR_DIS_CTRL {
+ ENABLE_MEM_PWR_CTRL = 0x0,
+ DISABLE_MEM_PWR_CTRL = 0x1,
+} MEM_PWR_DIS_CTRL;
+typedef enum MEM_PWR_SEL_CTRL {
+ DYNAMIC_SHUT_DOWN_ENABLE = 0x0,
+ DYNAMIC_DEEP_SLEEP_ENABLE = 0x1,
+ DYNAMIC_LIGHT_SLEEP_ENABLE = 0x2,
+} MEM_PWR_SEL_CTRL;
+typedef enum MEM_PWR_SEL_CTRL2 {
+ DYNAMIC_DEEP_SLEEP_EN = 0x0,
+ DYNAMIC_LIGHT_SLEEP_EN = 0x1,
+} MEM_PWR_SEL_CTRL2;
+
+#endif /* ACP_2_2_ENUM_H */
diff --git a/sound/soc/amd/include/acp_2_2_sh_mask.h b/sound/soc/amd/include/acp_2_2_sh_mask.h
new file mode 100644
index 0000000000..32d2d41043
--- /dev/null
+++ b/sound/soc/amd/include/acp_2_2_sh_mask.h
@@ -0,0 +1,2292 @@
+/*
+ * ACP_2_2 Register documentation
+ *
+ * Copyright (C) 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef ACP_2_2_SH_MASK_H
+#define ACP_2_2_SH_MASK_H
+
+#define ACP_DMA_CNTL_0__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_0__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_0__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_0__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_0__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_0__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_0__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_0__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_0__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_0__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_1__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_1__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_1__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_1__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_1__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_1__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_1__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_1__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_1__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_1__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_2__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_2__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_2__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_2__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_2__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_2__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_2__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_2__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_2__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_2__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_3__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_3__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_3__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_3__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_3__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_3__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_3__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_3__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_3__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_3__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_4__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_4__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_4__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_4__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_4__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_4__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_4__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_4__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_4__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_4__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_5__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_5__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_5__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_5__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_5__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_5__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_5__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_5__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_5__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_5__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_6__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_6__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_6__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_6__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_6__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_6__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_6__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_6__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_6__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_6__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_7__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_7__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_7__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_7__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_7__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_7__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_7__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_7__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_7__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_7__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_8__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_8__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_8__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_8__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_8__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_8__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_8__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_8__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_8__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_8__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_9__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_9__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_9__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_9__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_9__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_9__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_9__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_9__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_9__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_9__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_10__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_10__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_10__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_10__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_10__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_10__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_10__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_10__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_10__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_10__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_11__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_11__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_11__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_11__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_11__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_11__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_11__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_11__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_11__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_11__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_12__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_12__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_12__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_12__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_12__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_12__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_12__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_12__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_12__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_12__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_13__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_13__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_13__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_13__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_13__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_13__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_13__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_13__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_13__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_13__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_14__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_14__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_14__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_14__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_14__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_14__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_14__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_14__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_14__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_14__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_CNTL_15__DMAChRst_MASK 0x1
+#define ACP_DMA_CNTL_15__DMAChRst__SHIFT 0x0
+#define ACP_DMA_CNTL_15__DMAChRun_MASK 0x2
+#define ACP_DMA_CNTL_15__DMAChRun__SHIFT 0x1
+#define ACP_DMA_CNTL_15__DMAChIOCEn_MASK 0x4
+#define ACP_DMA_CNTL_15__DMAChIOCEn__SHIFT 0x2
+#define ACP_DMA_CNTL_15__Circular_DMA_En_MASK 0x8
+#define ACP_DMA_CNTL_15__Circular_DMA_En__SHIFT 0x3
+#define ACP_DMA_CNTL_15__DMAChGracefulRstEn_MASK 0x10
+#define ACP_DMA_CNTL_15__DMAChGracefulRstEn__SHIFT 0x4
+#define ACP_DMA_DSCR_STRT_IDX_0__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_0__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_1__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_1__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_2__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_2__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_3__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_3__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_4__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_4__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_5__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_5__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_6__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_6__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_7__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_7__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_8__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_8__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_9__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_9__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_10__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_10__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_11__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_11__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_12__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_12__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_13__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_13__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_14__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_14__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_STRT_IDX_15__DMAChDscrStrtIdx_MASK 0x3ff
+#define ACP_DMA_DSCR_STRT_IDX_15__DMAChDscrStrtIdx__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_0__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_0__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_1__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_1__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_2__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_2__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_3__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_3__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_4__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_4__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_5__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_5__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_6__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_6__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_7__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_7__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_8__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_8__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_9__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_9__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_10__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_10__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_11__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_11__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_12__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_12__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_13__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_13__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_14__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_14__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_DSCR_CNT_15__DMAChDscrCnt_MASK 0x3ff
+#define ACP_DMA_DSCR_CNT_15__DMAChDscrCnt__SHIFT 0x0
+#define ACP_DMA_PRIO_0__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_0__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_1__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_1__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_2__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_2__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_3__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_3__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_4__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_4__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_5__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_5__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_6__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_6__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_7__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_7__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_8__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_8__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_9__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_9__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_10__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_10__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_11__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_11__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_12__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_12__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_13__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_13__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_14__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_14__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_PRIO_15__DMAChPrioLvl_MASK 0x1
+#define ACP_DMA_PRIO_15__DMAChPrioLvl__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_0__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_0__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_1__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_1__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_2__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_2__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_3__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_3__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_4__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_4__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_5__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_5__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_6__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_6__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_7__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_7__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_8__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_8__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_9__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_9__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_10__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_10__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_11__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_11__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_12__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_12__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_13__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_13__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_14__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_14__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_DSCR_15__DMAChCurDscrIdx_MASK 0x3ff
+#define ACP_DMA_CUR_DSCR_15__DMAChCurDscrIdx__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_0__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_0__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_1__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_1__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_2__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_2__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_3__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_3__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_4__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_4__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_5__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_5__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_6__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_6__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_7__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_7__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_8__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_8__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_9__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_9__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_10__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_10__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_11__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_11__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_12__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_12__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_13__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_13__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_14__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_14__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_CUR_TRANS_CNT_15__DMAChCurTransCnt_MASK 0x1ffff
+#define ACP_DMA_CUR_TRANS_CNT_15__DMAChCurTransCnt__SHIFT 0x0
+#define ACP_DMA_ERR_STS_0__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_0__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_0__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_0__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_1__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_1__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_1__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_1__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_2__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_2__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_2__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_2__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_3__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_3__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_3__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_3__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_4__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_4__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_4__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_4__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_5__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_5__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_5__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_5__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_6__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_6__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_6__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_6__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_7__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_7__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_7__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_7__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_8__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_8__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_8__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_8__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_9__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_9__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_9__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_9__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_10__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_10__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_10__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_10__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_11__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_11__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_11__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_11__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_12__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_12__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_12__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_12__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_13__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_13__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_13__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_13__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_14__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_14__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_14__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_14__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_ERR_STS_15__DMAChTermErr_MASK 0x1
+#define ACP_DMA_ERR_STS_15__DMAChTermErr__SHIFT 0x0
+#define ACP_DMA_ERR_STS_15__DMAChErrCode_MASK 0x1e
+#define ACP_DMA_ERR_STS_15__DMAChErrCode__SHIFT 0x1
+#define ACP_DMA_DESC_BASE_ADDR__DescriptorBaseAddr_MASK 0xffffffff
+#define ACP_DMA_DESC_BASE_ADDR__DescriptorBaseAddr__SHIFT 0x0
+#define ACP_DMA_DESC_MAX_NUM_DSCR__MaximumNumberDescr_MASK 0xf
+#define ACP_DMA_DESC_MAX_NUM_DSCR__MaximumNumberDescr__SHIFT 0x0
+#define ACP_DMA_CH_STS__DMAChSts_MASK 0xffff
+#define ACP_DMA_CH_STS__DMAChSts__SHIFT 0x0
+#define ACP_DMA_CH_GROUP__DMAChanelGrouping_MASK 0x1
+#define ACP_DMA_CH_GROUP__DMAChanelGrouping__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET0__Offset_MASK 0xfffffff
+#define ACP_DSP0_CACHE_OFFSET0__Offset__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_CACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_CACHE_SIZE0__Size_MASK 0xffffff
+#define ACP_DSP0_CACHE_SIZE0__Size__SHIFT 0x0
+#define ACP_DSP0_CACHE_SIZE0__PageEnable_MASK 0x80000000
+#define ACP_DSP0_CACHE_SIZE0__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_CACHE_OFFSET1__Offset_MASK 0xfffffff
+#define ACP_DSP0_CACHE_OFFSET1__Offset__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_CACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_CACHE_SIZE1__Size_MASK 0xffffff
+#define ACP_DSP0_CACHE_SIZE1__Size__SHIFT 0x0
+#define ACP_DSP0_CACHE_SIZE1__PageEnable_MASK 0x80000000
+#define ACP_DSP0_CACHE_SIZE1__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_CACHE_OFFSET2__Offset_MASK 0xfffffff
+#define ACP_DSP0_CACHE_OFFSET2__Offset__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET2__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_CACHE_OFFSET2__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_CACHE_SIZE2__Size_MASK 0xffffff
+#define ACP_DSP0_CACHE_SIZE2__Size__SHIFT 0x0
+#define ACP_DSP0_CACHE_SIZE2__PageEnable_MASK 0x80000000
+#define ACP_DSP0_CACHE_SIZE2__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_CACHE_OFFSET3__Offset_MASK 0xfffffff
+#define ACP_DSP0_CACHE_OFFSET3__Offset__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET3__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_CACHE_OFFSET3__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_CACHE_SIZE3__Size_MASK 0xffffff
+#define ACP_DSP0_CACHE_SIZE3__Size__SHIFT 0x0
+#define ACP_DSP0_CACHE_SIZE3__PageEnable_MASK 0x80000000
+#define ACP_DSP0_CACHE_SIZE3__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_CACHE_OFFSET4__Offset_MASK 0xfffffff
+#define ACP_DSP0_CACHE_OFFSET4__Offset__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET4__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_CACHE_OFFSET4__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_CACHE_SIZE4__Size_MASK 0xffffff
+#define ACP_DSP0_CACHE_SIZE4__Size__SHIFT 0x0
+#define ACP_DSP0_CACHE_SIZE4__PageEnable_MASK 0x80000000
+#define ACP_DSP0_CACHE_SIZE4__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_CACHE_OFFSET5__Offset_MASK 0xfffffff
+#define ACP_DSP0_CACHE_OFFSET5__Offset__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET5__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_CACHE_OFFSET5__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_CACHE_SIZE5__Size_MASK 0xffffff
+#define ACP_DSP0_CACHE_SIZE5__Size__SHIFT 0x0
+#define ACP_DSP0_CACHE_SIZE5__PageEnable_MASK 0x80000000
+#define ACP_DSP0_CACHE_SIZE5__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_CACHE_OFFSET6__Offset_MASK 0xfffffff
+#define ACP_DSP0_CACHE_OFFSET6__Offset__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET6__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_CACHE_OFFSET6__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_CACHE_SIZE6__Size_MASK 0xffffff
+#define ACP_DSP0_CACHE_SIZE6__Size__SHIFT 0x0
+#define ACP_DSP0_CACHE_SIZE6__PageEnable_MASK 0x80000000
+#define ACP_DSP0_CACHE_SIZE6__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_CACHE_OFFSET7__Offset_MASK 0xfffffff
+#define ACP_DSP0_CACHE_OFFSET7__Offset__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET7__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_CACHE_OFFSET7__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_CACHE_SIZE7__Size_MASK 0xffffff
+#define ACP_DSP0_CACHE_SIZE7__Size__SHIFT 0x0
+#define ACP_DSP0_CACHE_SIZE7__PageEnable_MASK 0x80000000
+#define ACP_DSP0_CACHE_SIZE7__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_CACHE_OFFSET8__Offset_MASK 0xfffffff
+#define ACP_DSP0_CACHE_OFFSET8__Offset__SHIFT 0x0
+#define ACP_DSP0_CACHE_OFFSET8__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_CACHE_OFFSET8__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_CACHE_SIZE8__Size_MASK 0xffffff
+#define ACP_DSP0_CACHE_SIZE8__Size__SHIFT 0x0
+#define ACP_DSP0_CACHE_SIZE8__PageEnable_MASK 0x80000000
+#define ACP_DSP0_CACHE_SIZE8__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_NONCACHE_OFFSET0__Offset_MASK 0xfffffff
+#define ACP_DSP0_NONCACHE_OFFSET0__Offset__SHIFT 0x0
+#define ACP_DSP0_NONCACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_NONCACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_NONCACHE_SIZE0__Size_MASK 0xffffff
+#define ACP_DSP0_NONCACHE_SIZE0__Size__SHIFT 0x0
+#define ACP_DSP0_NONCACHE_SIZE0__PageEnable_MASK 0x80000000
+#define ACP_DSP0_NONCACHE_SIZE0__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_NONCACHE_OFFSET1__Offset_MASK 0xfffffff
+#define ACP_DSP0_NONCACHE_OFFSET1__Offset__SHIFT 0x0
+#define ACP_DSP0_NONCACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP0_NONCACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP0_NONCACHE_SIZE1__Size_MASK 0xffffff
+#define ACP_DSP0_NONCACHE_SIZE1__Size__SHIFT 0x0
+#define ACP_DSP0_NONCACHE_SIZE1__PageEnable_MASK 0x80000000
+#define ACP_DSP0_NONCACHE_SIZE1__PageEnable__SHIFT 0x1f
+#define ACP_DSP0_DEBUG_PC__DebugPC_MASK 0xffffffff
+#define ACP_DSP0_DEBUG_PC__DebugPC__SHIFT 0x0
+#define ACP_DSP0_NMI_SEL__NMISel_MASK 0x1
+#define ACP_DSP0_NMI_SEL__NMISel__SHIFT 0x0
+#define ACP_DSP0_CLKRST_CNTL__ClkEn_MASK 0x1
+#define ACP_DSP0_CLKRST_CNTL__ClkEn__SHIFT 0x0
+#define ACP_DSP0_CLKRST_CNTL__SoftResetDSP_MASK 0x2
+#define ACP_DSP0_CLKRST_CNTL__SoftResetDSP__SHIFT 0x1
+#define ACP_DSP0_CLKRST_CNTL__InternalSoftResetMode_MASK 0x4
+#define ACP_DSP0_CLKRST_CNTL__InternalSoftResetMode__SHIFT 0x2
+#define ACP_DSP0_CLKRST_CNTL__ExternalSoftResetMode_MASK 0x8
+#define ACP_DSP0_CLKRST_CNTL__ExternalSoftResetMode__SHIFT 0x3
+#define ACP_DSP0_CLKRST_CNTL__SoftResetDSPDone_MASK 0x10
+#define ACP_DSP0_CLKRST_CNTL__SoftResetDSPDone__SHIFT 0x4
+#define ACP_DSP0_CLKRST_CNTL__Clk_ON_Status_MASK 0x20
+#define ACP_DSP0_CLKRST_CNTL__Clk_ON_Status__SHIFT 0x5
+#define ACP_DSP0_RUNSTALL__RunStallCntl_MASK 0x1
+#define ACP_DSP0_RUNSTALL__RunStallCntl__SHIFT 0x0
+#define ACP_DSP0_OCD_HALT_ON_RST__OCD_HALT_ON_RST_MASK 0x1
+#define ACP_DSP0_OCD_HALT_ON_RST__OCD_HALT_ON_RST__SHIFT 0x0
+#define ACP_DSP0_WAIT_MODE__WaitMode_MASK 0x1
+#define ACP_DSP0_WAIT_MODE__WaitMode__SHIFT 0x0
+#define ACP_DSP0_VECT_SEL__StaticVectorSel_MASK 0x1
+#define ACP_DSP0_VECT_SEL__StaticVectorSel__SHIFT 0x0
+#define ACP_DSP0_DEBUG_REG1__ACP_DSP_DEBUG_REG1_MASK 0xffffffff
+#define ACP_DSP0_DEBUG_REG1__ACP_DSP_DEBUG_REG1__SHIFT 0x0
+#define ACP_DSP0_DEBUG_REG2__ACP_DSP_DEBUG_REG2_MASK 0xffffffff
+#define ACP_DSP0_DEBUG_REG2__ACP_DSP_DEBUG_REG2__SHIFT 0x0
+#define ACP_DSP0_DEBUG_REG3__ACP_DSP_DEBUG_REG3_MASK 0xffffffff
+#define ACP_DSP0_DEBUG_REG3__ACP_DSP_DEBUG_REG3__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET0__Offset_MASK 0xfffffff
+#define ACP_DSP1_CACHE_OFFSET0__Offset__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_CACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_CACHE_SIZE0__Size_MASK 0xffffff
+#define ACP_DSP1_CACHE_SIZE0__Size__SHIFT 0x0
+#define ACP_DSP1_CACHE_SIZE0__PageEnable_MASK 0x80000000
+#define ACP_DSP1_CACHE_SIZE0__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_CACHE_OFFSET1__Offset_MASK 0xfffffff
+#define ACP_DSP1_CACHE_OFFSET1__Offset__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_CACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_CACHE_SIZE1__Size_MASK 0xffffff
+#define ACP_DSP1_CACHE_SIZE1__Size__SHIFT 0x0
+#define ACP_DSP1_CACHE_SIZE1__PageEnable_MASK 0x80000000
+#define ACP_DSP1_CACHE_SIZE1__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_CACHE_OFFSET2__Offset_MASK 0xfffffff
+#define ACP_DSP1_CACHE_OFFSET2__Offset__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET2__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_CACHE_OFFSET2__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_CACHE_SIZE2__Size_MASK 0xffffff
+#define ACP_DSP1_CACHE_SIZE2__Size__SHIFT 0x0
+#define ACP_DSP1_CACHE_SIZE2__PageEnable_MASK 0x80000000
+#define ACP_DSP1_CACHE_SIZE2__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_CACHE_OFFSET3__Offset_MASK 0xfffffff
+#define ACP_DSP1_CACHE_OFFSET3__Offset__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET3__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_CACHE_OFFSET3__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_CACHE_SIZE3__Size_MASK 0xffffff
+#define ACP_DSP1_CACHE_SIZE3__Size__SHIFT 0x0
+#define ACP_DSP1_CACHE_SIZE3__PageEnable_MASK 0x80000000
+#define ACP_DSP1_CACHE_SIZE3__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_CACHE_OFFSET4__Offset_MASK 0xfffffff
+#define ACP_DSP1_CACHE_OFFSET4__Offset__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET4__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_CACHE_OFFSET4__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_CACHE_SIZE4__Size_MASK 0xffffff
+#define ACP_DSP1_CACHE_SIZE4__Size__SHIFT 0x0
+#define ACP_DSP1_CACHE_SIZE4__PageEnable_MASK 0x80000000
+#define ACP_DSP1_CACHE_SIZE4__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_CACHE_OFFSET5__Offset_MASK 0xfffffff
+#define ACP_DSP1_CACHE_OFFSET5__Offset__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET5__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_CACHE_OFFSET5__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_CACHE_SIZE5__Size_MASK 0xffffff
+#define ACP_DSP1_CACHE_SIZE5__Size__SHIFT 0x0
+#define ACP_DSP1_CACHE_SIZE5__PageEnable_MASK 0x80000000
+#define ACP_DSP1_CACHE_SIZE5__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_CACHE_OFFSET6__Offset_MASK 0xfffffff
+#define ACP_DSP1_CACHE_OFFSET6__Offset__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET6__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_CACHE_OFFSET6__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_CACHE_SIZE6__Size_MASK 0xffffff
+#define ACP_DSP1_CACHE_SIZE6__Size__SHIFT 0x0
+#define ACP_DSP1_CACHE_SIZE6__PageEnable_MASK 0x80000000
+#define ACP_DSP1_CACHE_SIZE6__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_CACHE_OFFSET7__Offset_MASK 0xfffffff
+#define ACP_DSP1_CACHE_OFFSET7__Offset__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET7__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_CACHE_OFFSET7__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_CACHE_SIZE7__Size_MASK 0xffffff
+#define ACP_DSP1_CACHE_SIZE7__Size__SHIFT 0x0
+#define ACP_DSP1_CACHE_SIZE7__PageEnable_MASK 0x80000000
+#define ACP_DSP1_CACHE_SIZE7__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_CACHE_OFFSET8__Offset_MASK 0xfffffff
+#define ACP_DSP1_CACHE_OFFSET8__Offset__SHIFT 0x0
+#define ACP_DSP1_CACHE_OFFSET8__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_CACHE_OFFSET8__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_CACHE_SIZE8__Size_MASK 0xffffff
+#define ACP_DSP1_CACHE_SIZE8__Size__SHIFT 0x0
+#define ACP_DSP1_CACHE_SIZE8__PageEnable_MASK 0x80000000
+#define ACP_DSP1_CACHE_SIZE8__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_NONCACHE_OFFSET0__Offset_MASK 0xfffffff
+#define ACP_DSP1_NONCACHE_OFFSET0__Offset__SHIFT 0x0
+#define ACP_DSP1_NONCACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_NONCACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_NONCACHE_SIZE0__Size_MASK 0xffffff
+#define ACP_DSP1_NONCACHE_SIZE0__Size__SHIFT 0x0
+#define ACP_DSP1_NONCACHE_SIZE0__PageEnable_MASK 0x80000000
+#define ACP_DSP1_NONCACHE_SIZE0__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_NONCACHE_OFFSET1__Offset_MASK 0xfffffff
+#define ACP_DSP1_NONCACHE_OFFSET1__Offset__SHIFT 0x0
+#define ACP_DSP1_NONCACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP1_NONCACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP1_NONCACHE_SIZE1__Size_MASK 0xffffff
+#define ACP_DSP1_NONCACHE_SIZE1__Size__SHIFT 0x0
+#define ACP_DSP1_NONCACHE_SIZE1__PageEnable_MASK 0x80000000
+#define ACP_DSP1_NONCACHE_SIZE1__PageEnable__SHIFT 0x1f
+#define ACP_DSP1_DEBUG_PC__DebugPC_MASK 0xffffffff
+#define ACP_DSP1_DEBUG_PC__DebugPC__SHIFT 0x0
+#define ACP_DSP1_NMI_SEL__NMISel_MASK 0x1
+#define ACP_DSP1_NMI_SEL__NMISel__SHIFT 0x0
+#define ACP_DSP1_CLKRST_CNTL__ClkEn_MASK 0x1
+#define ACP_DSP1_CLKRST_CNTL__ClkEn__SHIFT 0x0
+#define ACP_DSP1_CLKRST_CNTL__SoftResetDSP_MASK 0x2
+#define ACP_DSP1_CLKRST_CNTL__SoftResetDSP__SHIFT 0x1
+#define ACP_DSP1_CLKRST_CNTL__InternalSoftResetMode_MASK 0x4
+#define ACP_DSP1_CLKRST_CNTL__InternalSoftResetMode__SHIFT 0x2
+#define ACP_DSP1_CLKRST_CNTL__ExternalSoftResetMode_MASK 0x8
+#define ACP_DSP1_CLKRST_CNTL__ExternalSoftResetMode__SHIFT 0x3
+#define ACP_DSP1_CLKRST_CNTL__SoftResetDSPDone_MASK 0x10
+#define ACP_DSP1_CLKRST_CNTL__SoftResetDSPDone__SHIFT 0x4
+#define ACP_DSP1_CLKRST_CNTL__Clk_ON_Status_MASK 0x20
+#define ACP_DSP1_CLKRST_CNTL__Clk_ON_Status__SHIFT 0x5
+#define ACP_DSP1_RUNSTALL__RunStallCntl_MASK 0x1
+#define ACP_DSP1_RUNSTALL__RunStallCntl__SHIFT 0x0
+#define ACP_DSP1_OCD_HALT_ON_RST__OCD_HALT_ON_RST_MASK 0x1
+#define ACP_DSP1_OCD_HALT_ON_RST__OCD_HALT_ON_RST__SHIFT 0x0
+#define ACP_DSP1_WAIT_MODE__WaitMode_MASK 0x1
+#define ACP_DSP1_WAIT_MODE__WaitMode__SHIFT 0x0
+#define ACP_DSP1_VECT_SEL__StaticVectorSel_MASK 0x1
+#define ACP_DSP1_VECT_SEL__StaticVectorSel__SHIFT 0x0
+#define ACP_DSP1_DEBUG_REG1__ACP_DSP_DEBUG_REG1_MASK 0xffffffff
+#define ACP_DSP1_DEBUG_REG1__ACP_DSP_DEBUG_REG1__SHIFT 0x0
+#define ACP_DSP1_DEBUG_REG2__ACP_DSP_DEBUG_REG2_MASK 0xffffffff
+#define ACP_DSP1_DEBUG_REG2__ACP_DSP_DEBUG_REG2__SHIFT 0x0
+#define ACP_DSP1_DEBUG_REG3__ACP_DSP_DEBUG_REG3_MASK 0xffffffff
+#define ACP_DSP1_DEBUG_REG3__ACP_DSP_DEBUG_REG3__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET0__Offset_MASK 0xfffffff
+#define ACP_DSP2_CACHE_OFFSET0__Offset__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_CACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_CACHE_SIZE0__Size_MASK 0xffffff
+#define ACP_DSP2_CACHE_SIZE0__Size__SHIFT 0x0
+#define ACP_DSP2_CACHE_SIZE0__PageEnable_MASK 0x80000000
+#define ACP_DSP2_CACHE_SIZE0__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_CACHE_OFFSET1__Offset_MASK 0xfffffff
+#define ACP_DSP2_CACHE_OFFSET1__Offset__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_CACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_CACHE_SIZE1__Size_MASK 0xffffff
+#define ACP_DSP2_CACHE_SIZE1__Size__SHIFT 0x0
+#define ACP_DSP2_CACHE_SIZE1__PageEnable_MASK 0x80000000
+#define ACP_DSP2_CACHE_SIZE1__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_CACHE_OFFSET2__Offset_MASK 0xfffffff
+#define ACP_DSP2_CACHE_OFFSET2__Offset__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET2__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_CACHE_OFFSET2__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_CACHE_SIZE2__Size_MASK 0xffffff
+#define ACP_DSP2_CACHE_SIZE2__Size__SHIFT 0x0
+#define ACP_DSP2_CACHE_SIZE2__PageEnable_MASK 0x80000000
+#define ACP_DSP2_CACHE_SIZE2__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_CACHE_OFFSET3__Offset_MASK 0xfffffff
+#define ACP_DSP2_CACHE_OFFSET3__Offset__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET3__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_CACHE_OFFSET3__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_CACHE_SIZE3__Size_MASK 0xffffff
+#define ACP_DSP2_CACHE_SIZE3__Size__SHIFT 0x0
+#define ACP_DSP2_CACHE_SIZE3__PageEnable_MASK 0x80000000
+#define ACP_DSP2_CACHE_SIZE3__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_CACHE_OFFSET4__Offset_MASK 0xfffffff
+#define ACP_DSP2_CACHE_OFFSET4__Offset__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET4__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_CACHE_OFFSET4__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_CACHE_SIZE4__Size_MASK 0xffffff
+#define ACP_DSP2_CACHE_SIZE4__Size__SHIFT 0x0
+#define ACP_DSP2_CACHE_SIZE4__PageEnable_MASK 0x80000000
+#define ACP_DSP2_CACHE_SIZE4__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_CACHE_OFFSET5__Offset_MASK 0xfffffff
+#define ACP_DSP2_CACHE_OFFSET5__Offset__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET5__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_CACHE_OFFSET5__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_CACHE_SIZE5__Size_MASK 0xffffff
+#define ACP_DSP2_CACHE_SIZE5__Size__SHIFT 0x0
+#define ACP_DSP2_CACHE_SIZE5__PageEnable_MASK 0x80000000
+#define ACP_DSP2_CACHE_SIZE5__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_CACHE_OFFSET6__Offset_MASK 0xfffffff
+#define ACP_DSP2_CACHE_OFFSET6__Offset__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET6__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_CACHE_OFFSET6__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_CACHE_SIZE6__Size_MASK 0xffffff
+#define ACP_DSP2_CACHE_SIZE6__Size__SHIFT 0x0
+#define ACP_DSP2_CACHE_SIZE6__PageEnable_MASK 0x80000000
+#define ACP_DSP2_CACHE_SIZE6__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_CACHE_OFFSET7__Offset_MASK 0xfffffff
+#define ACP_DSP2_CACHE_OFFSET7__Offset__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET7__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_CACHE_OFFSET7__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_CACHE_SIZE7__Size_MASK 0xffffff
+#define ACP_DSP2_CACHE_SIZE7__Size__SHIFT 0x0
+#define ACP_DSP2_CACHE_SIZE7__PageEnable_MASK 0x80000000
+#define ACP_DSP2_CACHE_SIZE7__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_CACHE_OFFSET8__Offset_MASK 0xfffffff
+#define ACP_DSP2_CACHE_OFFSET8__Offset__SHIFT 0x0
+#define ACP_DSP2_CACHE_OFFSET8__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_CACHE_OFFSET8__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_CACHE_SIZE8__Size_MASK 0xffffff
+#define ACP_DSP2_CACHE_SIZE8__Size__SHIFT 0x0
+#define ACP_DSP2_CACHE_SIZE8__PageEnable_MASK 0x80000000
+#define ACP_DSP2_CACHE_SIZE8__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_NONCACHE_OFFSET0__Offset_MASK 0xfffffff
+#define ACP_DSP2_NONCACHE_OFFSET0__Offset__SHIFT 0x0
+#define ACP_DSP2_NONCACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_NONCACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_NONCACHE_SIZE0__Size_MASK 0xffffff
+#define ACP_DSP2_NONCACHE_SIZE0__Size__SHIFT 0x0
+#define ACP_DSP2_NONCACHE_SIZE0__PageEnable_MASK 0x80000000
+#define ACP_DSP2_NONCACHE_SIZE0__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_NONCACHE_OFFSET1__Offset_MASK 0xfffffff
+#define ACP_DSP2_NONCACHE_OFFSET1__Offset__SHIFT 0x0
+#define ACP_DSP2_NONCACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
+#define ACP_DSP2_NONCACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
+#define ACP_DSP2_NONCACHE_SIZE1__Size_MASK 0xffffff
+#define ACP_DSP2_NONCACHE_SIZE1__Size__SHIFT 0x0
+#define ACP_DSP2_NONCACHE_SIZE1__PageEnable_MASK 0x80000000
+#define ACP_DSP2_NONCACHE_SIZE1__PageEnable__SHIFT 0x1f
+#define ACP_DSP2_DEBUG_PC__DebugPC_MASK 0xffffffff
+#define ACP_DSP2_DEBUG_PC__DebugPC__SHIFT 0x0
+#define ACP_DSP2_NMI_SEL__NMISel_MASK 0x1
+#define ACP_DSP2_NMI_SEL__NMISel__SHIFT 0x0
+#define ACP_DSP2_CLKRST_CNTL__ClkEn_MASK 0x1
+#define ACP_DSP2_CLKRST_CNTL__ClkEn__SHIFT 0x0
+#define ACP_DSP2_CLKRST_CNTL__SoftResetDSP_MASK 0x2
+#define ACP_DSP2_CLKRST_CNTL__SoftResetDSP__SHIFT 0x1
+#define ACP_DSP2_CLKRST_CNTL__InternalSoftResetMode_MASK 0x4
+#define ACP_DSP2_CLKRST_CNTL__InternalSoftResetMode__SHIFT 0x2
+#define ACP_DSP2_CLKRST_CNTL__ExternalSoftResetMode_MASK 0x8
+#define ACP_DSP2_CLKRST_CNTL__ExternalSoftResetMode__SHIFT 0x3
+#define ACP_DSP2_CLKRST_CNTL__SoftResetDSPDone_MASK 0x10
+#define ACP_DSP2_CLKRST_CNTL__SoftResetDSPDone__SHIFT 0x4
+#define ACP_DSP2_CLKRST_CNTL__Clk_ON_Status_MASK 0x20
+#define ACP_DSP2_CLKRST_CNTL__Clk_ON_Status__SHIFT 0x5
+#define ACP_DSP2_RUNSTALL__RunStallCntl_MASK 0x1
+#define ACP_DSP2_RUNSTALL__RunStallCntl__SHIFT 0x0
+#define ACP_DSP2_OCD_HALT_ON_RST__OCD_HALT_ON_RST_MASK 0x1
+#define ACP_DSP2_OCD_HALT_ON_RST__OCD_HALT_ON_RST__SHIFT 0x0
+#define ACP_DSP2_WAIT_MODE__WaitMode_MASK 0x1
+#define ACP_DSP2_WAIT_MODE__WaitMode__SHIFT 0x0
+#define ACP_DSP2_VECT_SEL__StaticVectorSel_MASK 0x1
+#define ACP_DSP2_VECT_SEL__StaticVectorSel__SHIFT 0x0
+#define ACP_DSP2_DEBUG_REG1__ACP_DSP_DEBUG_REG1_MASK 0xffffffff
+#define ACP_DSP2_DEBUG_REG1__ACP_DSP_DEBUG_REG1__SHIFT 0x0
+#define ACP_DSP2_DEBUG_REG2__ACP_DSP_DEBUG_REG2_MASK 0xffffffff
+#define ACP_DSP2_DEBUG_REG2__ACP_DSP_DEBUG_REG2__SHIFT 0x0
+#define ACP_DSP2_DEBUG_REG3__ACP_DSP_DEBUG_REG3_MASK 0xffffffff
+#define ACP_DSP2_DEBUG_REG3__ACP_DSP_DEBUG_REG3__SHIFT 0x0
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBDataSwap_MASK 0x3
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBDataSwap__SHIFT 0x0
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBEnbMultRdReq_MASK 0x4
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBEnbMultRdReq__SHIFT 0x2
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBEnbMultWrReq_MASK 0x18
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBEnbMultWrReq__SHIFT 0x3
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBMaxReadBurst_MASK 0x60
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBMaxReadBurst__SHIFT 0x5
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBStallEnb_MASK 0x80
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBStallEnb__SHIFT 0x7
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBNackChkEnb_MASK 0x100
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBNackChkEnb__SHIFT 0x8
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBAdrWinViolChkEnb_MASK 0x200
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBAdrWinViolChkEnb__SHIFT 0x9
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBUrgEnb_MASK 0x400
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBUrgEnb__SHIFT 0xa
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBUrgCntMult_MASK 0x1800
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBUrgCntMult__SHIFT 0xb
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBStallMode_MASK 0x2000
+#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBStallMode__SHIFT 0xd
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViolOver_MASK 0x2000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViolOver__SHIFT 0x19
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViolSource_MASK 0x1c000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViolSource__SHIFT 0x1a
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViol_MASK 0x20000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViol__SHIFT 0x1d
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBNackOver_MASK 0x40000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBNackOver__SHIFT 0x1e
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBNackVal_MASK 0x80000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBNackVal__SHIFT 0x1f
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViolOver_MASK 0x2000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViolOver__SHIFT 0x19
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViolSource_MASK 0x1c000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViolSource__SHIFT 0x1a
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViol_MASK 0x20000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViol__SHIFT 0x1d
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBNackOver_MASK 0x40000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBNackOver__SHIFT 0x1e
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBNackVal_MASK 0x80000000
+#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBNackVal__SHIFT 0x1f
+#define ACP_DAGB_Onion_TransPerf_Counter_Control__EnbDAGBTransPerfCntr_MASK 0x1
+#define ACP_DAGB_Onion_TransPerf_Counter_Control__EnbDAGBTransPerfCntr__SHIFT 0x0
+#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime_MASK 0x1ffff
+#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime__SHIFT 0x0
+#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr_MASK 0x80000000
+#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr__SHIFT 0x1f
+#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime_MASK 0x1ffff
+#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime__SHIFT 0x0
+#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr_MASK 0x80000000
+#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr__SHIFT 0x1f
+#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime_MASK 0x1ffff
+#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime__SHIFT 0x0
+#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr_MASK 0x80000000
+#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr__SHIFT 0x1f
+#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime_MASK 0x1ffff
+#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime__SHIFT 0x0
+#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr_MASK 0x80000000
+#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr__SHIFT 0x1f
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBDataSwap_MASK 0x3
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBDataSwap__SHIFT 0x0
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBEnbMultRdReq_MASK 0x4
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBEnbMultRdReq__SHIFT 0x2
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBEnbMultWrReq_MASK 0x18
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBEnbMultWrReq__SHIFT 0x3
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBMaxReadBurst_MASK 0x60
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBMaxReadBurst__SHIFT 0x5
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBStallEnb_MASK 0x80
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBStallEnb__SHIFT 0x7
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBNackChkEnb_MASK 0x100
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBNackChkEnb__SHIFT 0x8
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBAdrWinViolChkEnb_MASK 0x200
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBAdrWinViolChkEnb__SHIFT 0x9
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBUrgEnb_MASK 0x400
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBUrgEnb__SHIFT 0xa
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBUrgCntMult_MASK 0x1800
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBUrgCntMult__SHIFT 0xb
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBStallMode_MASK 0x2000
+#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBStallMode__SHIFT 0xd
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViolOver_MASK 0x2000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViolOver__SHIFT 0x19
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViolSource_MASK 0x1c000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViolSource__SHIFT 0x1a
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViol_MASK 0x20000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViol__SHIFT 0x1d
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBNackOver_MASK 0x40000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBNackOver__SHIFT 0x1e
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBNackVal_MASK 0x80000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBNackVal__SHIFT 0x1f
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViolOver_MASK 0x2000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViolOver__SHIFT 0x19
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViolSource_MASK 0x1c000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViolSource__SHIFT 0x1a
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViol_MASK 0x20000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViol__SHIFT 0x1d
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBNackOver_MASK 0x40000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBNackOver__SHIFT 0x1e
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBNackVal_MASK 0x80000000
+#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBNackVal__SHIFT 0x1f
+#define ACP_DAGB_Garlic_TransPerf_Counter_Control__EnbDAGBTransPerfCntr_MASK 0x1
+#define ACP_DAGB_Garlic_TransPerf_Counter_Control__EnbDAGBTransPerfCntr__SHIFT 0x0
+#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime_MASK 0x1ffff
+#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime__SHIFT 0x0
+#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr_MASK 0x80000000
+#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr__SHIFT 0x1f
+#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime_MASK 0x1ffff
+#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime__SHIFT 0x0
+#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr_MASK 0x80000000
+#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr__SHIFT 0x1f
+#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime_MASK 0x1ffff
+#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime__SHIFT 0x0
+#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr_MASK 0x80000000
+#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr__SHIFT 0x1f
+#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime_MASK 0x1ffff
+#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime__SHIFT 0x0
+#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr_MASK 0x80000000
+#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr__SHIFT 0x1f
+#define ACP_DAGB_PAGE_SIZE_GRP_1__AXI2DAGBPageSize_MASK 0x3
+#define ACP_DAGB_PAGE_SIZE_GRP_1__AXI2DAGBPageSize__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBBaseAddr_MASK 0xfffffff
+#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBBaseAddr__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBSnoopSel_MASK 0x20000000
+#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBSnoopSel__SHIFT 0x1d
+#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBTargetMemSel_MASK 0x40000000
+#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBTargetMemSel__SHIFT 0x1e
+#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBGrpEnable_MASK 0x80000000
+#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBGrpEnable__SHIFT 0x1f
+#define ACP_DAGB_PAGE_SIZE_GRP_2__AXI2DAGBPageSize_MASK 0x3
+#define ACP_DAGB_PAGE_SIZE_GRP_2__AXI2DAGBPageSize__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBBaseAddr_MASK 0xfffffff
+#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBBaseAddr__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBSnoopSel_MASK 0x20000000
+#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBSnoopSel__SHIFT 0x1d
+#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBTargetMemSel_MASK 0x40000000
+#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBTargetMemSel__SHIFT 0x1e
+#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBGrpEnable_MASK 0x80000000
+#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBGrpEnable__SHIFT 0x1f
+#define ACP_DAGB_PAGE_SIZE_GRP_3__AXI2DAGBPageSize_MASK 0x3
+#define ACP_DAGB_PAGE_SIZE_GRP_3__AXI2DAGBPageSize__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBBaseAddr_MASK 0xfffffff
+#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBBaseAddr__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBSnoopSel_MASK 0x20000000
+#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBSnoopSel__SHIFT 0x1d
+#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBTargetMemSel_MASK 0x40000000
+#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBTargetMemSel__SHIFT 0x1e
+#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBGrpEnable_MASK 0x80000000
+#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBGrpEnable__SHIFT 0x1f
+#define ACP_DAGB_PAGE_SIZE_GRP_4__AXI2DAGBPageSize_MASK 0x3
+#define ACP_DAGB_PAGE_SIZE_GRP_4__AXI2DAGBPageSize__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBBaseAddr_MASK 0xfffffff
+#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBBaseAddr__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBSnoopSel_MASK 0x20000000
+#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBSnoopSel__SHIFT 0x1d
+#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBTargetMemSel_MASK 0x40000000
+#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBTargetMemSel__SHIFT 0x1e
+#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBGrpEnable_MASK 0x80000000
+#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBGrpEnable__SHIFT 0x1f
+#define ACP_DAGB_PAGE_SIZE_GRP_5__AXI2DAGBPageSize_MASK 0x3
+#define ACP_DAGB_PAGE_SIZE_GRP_5__AXI2DAGBPageSize__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBBaseAddr_MASK 0xfffffff
+#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBBaseAddr__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBSnoopSel_MASK 0x20000000
+#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBSnoopSel__SHIFT 0x1d
+#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBTargetMemSel_MASK 0x40000000
+#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBTargetMemSel__SHIFT 0x1e
+#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBGrpEnable_MASK 0x80000000
+#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBGrpEnable__SHIFT 0x1f
+#define ACP_DAGB_PAGE_SIZE_GRP_6__AXI2DAGBPageSize_MASK 0x3
+#define ACP_DAGB_PAGE_SIZE_GRP_6__AXI2DAGBPageSize__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBBaseAddr_MASK 0xfffffff
+#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBBaseAddr__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBSnoopSel_MASK 0x20000000
+#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBSnoopSel__SHIFT 0x1d
+#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBTargetMemSel_MASK 0x40000000
+#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBTargetMemSel__SHIFT 0x1e
+#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBGrpEnable_MASK 0x80000000
+#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBGrpEnable__SHIFT 0x1f
+#define ACP_DAGB_PAGE_SIZE_GRP_7__AXI2DAGBPageSize_MASK 0x3
+#define ACP_DAGB_PAGE_SIZE_GRP_7__AXI2DAGBPageSize__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBBaseAddr_MASK 0xfffffff
+#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBBaseAddr__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBSnoopSel_MASK 0x20000000
+#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBSnoopSel__SHIFT 0x1d
+#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBTargetMemSel_MASK 0x40000000
+#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBTargetMemSel__SHIFT 0x1e
+#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBGrpEnable_MASK 0x80000000
+#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBGrpEnable__SHIFT 0x1f
+#define ACP_DAGB_PAGE_SIZE_GRP_8__AXI2DAGBPageSize_MASK 0x3
+#define ACP_DAGB_PAGE_SIZE_GRP_8__AXI2DAGBPageSize__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBBaseAddr_MASK 0xfffffff
+#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBBaseAddr__SHIFT 0x0
+#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBSnoopSel_MASK 0x20000000
+#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBSnoopSel__SHIFT 0x1d
+#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBTargetMemSel_MASK 0x40000000
+#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBTargetMemSel__SHIFT 0x1e
+#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBGrpEnable_MASK 0x80000000
+#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBGrpEnable__SHIFT 0x1f
+#define ACP_DAGB_ATU_CTRL__AXI2DAGBCacheInvalidate_MASK 0x1
+#define ACP_DAGB_ATU_CTRL__AXI2DAGBCacheInvalidate__SHIFT 0x0
+#define ACP_CONTROL__ClkEn_MASK 0x1
+#define ACP_CONTROL__ClkEn__SHIFT 0x0
+#define ACP_CONTROL__JtagEn_MASK 0x400
+#define ACP_CONTROL__JtagEn__SHIFT 0xa
+#define ACP_STATUS__ClkOn_MASK 0x1
+#define ACP_STATUS__ClkOn__SHIFT 0x0
+#define ACP_STATUS__ACPRefClkSpd_MASK 0x2
+#define ACP_STATUS__ACPRefClkSpd__SHIFT 0x1
+#define ACP_STATUS__SMUStutterLastEdge_MASK 0x4
+#define ACP_STATUS__SMUStutterLastEdge__SHIFT 0x2
+#define ACP_STATUS__MCStutterLastEdge_MASK 0x8
+#define ACP_STATUS__MCStutterLastEdge__SHIFT 0x3
+#define ACP_SOFT_RESET__SoftResetAud_MASK 0x100
+#define ACP_SOFT_RESET__SoftResetAud__SHIFT 0x8
+#define ACP_SOFT_RESET__SoftResetDMA_MASK 0x200
+#define ACP_SOFT_RESET__SoftResetDMA__SHIFT 0x9
+#define ACP_SOFT_RESET__InternalSoftResetMode_MASK 0x4000
+#define ACP_SOFT_RESET__InternalSoftResetMode__SHIFT 0xe
+#define ACP_SOFT_RESET__ExternalSoftResetMode_MASK 0x8000
+#define ACP_SOFT_RESET__ExternalSoftResetMode__SHIFT 0xf
+#define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000
+#define ACP_SOFT_RESET__SoftResetAudDone__SHIFT 0x18
+#define ACP_SOFT_RESET__SoftResetDMADone_MASK 0x2000000
+#define ACP_SOFT_RESET__SoftResetDMADone__SHIFT 0x19
+#define ACP_PwrMgmt_CNTL__SCLKSleepCntl_MASK 0x3
+#define ACP_PwrMgmt_CNTL__SCLKSleepCntl__SHIFT 0x0
+#define ACP_CAC_INDICATOR_CONTROL__ACP_Cac_Indicator_Counter_MASK 0xffff
+#define ACP_CAC_INDICATOR_CONTROL__ACP_Cac_Indicator_Counter__SHIFT 0x0
+#define ACP_SMU_MAILBOX__ACP_SMU_Mailbox_MASK 0xffffffff
+#define ACP_SMU_MAILBOX__ACP_SMU_Mailbox__SHIFT 0x0
+#define ACP_FUTURE_REG_SCLK_0__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_SCLK_0__ACPFutureReg__SHIFT 0x0
+#define ACP_FUTURE_REG_SCLK_1__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_SCLK_1__ACPFutureReg__SHIFT 0x0
+#define ACP_FUTURE_REG_SCLK_2__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_SCLK_2__ACPFutureReg__SHIFT 0x0
+#define ACP_FUTURE_REG_SCLK_3__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_SCLK_3__ACPFutureReg__SHIFT 0x0
+#define ACP_FUTURE_REG_SCLK_4__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_SCLK_4__ACPFutureReg__SHIFT 0x0
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_ask_cnt_enable_MASK 0x1
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_ask_cnt_enable__SHIFT 0x0
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_go_cnt_enable_MASK 0x2
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_go_cnt_enable__SHIFT 0x1
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_exp_respcnt_enable_MASK 0x4
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_exp_respcnt_enable__SHIFT 0x2
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_actual_respcnt_enable_MASK 0x8
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_actual_respcnt_enable__SHIFT 0x3
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_ask_cnt_enable_MASK 0x10
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_ask_cnt_enable__SHIFT 0x4
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_go_cnt_enable_MASK 0x20
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_go_cnt_enable__SHIFT 0x5
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_exp_respcnt_enable_MASK 0x40
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_exp_respcnt_enable__SHIFT 0x6
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_actual_respcnt_enable_MASK 0x80
+#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_actual_respcnt_enable__SHIFT 0x7
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_ask_cnt_enable_MASK 0x100
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_ask_cnt_enable__SHIFT 0x8
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_go_cnt_enable_MASK 0x200
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_go_cnt_enable__SHIFT 0x9
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_exp_respcnt_enable_MASK 0x400
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_exp_respcnt_enable__SHIFT 0xa
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_actual_respcnt_enable_MASK 0x800
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_actual_respcnt_enable__SHIFT 0xb
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_ask_cnt_enable_MASK 0x1000
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_ask_cnt_enable__SHIFT 0xc
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_go_cnt_enable_MASK 0x2000
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_go_cnt_enable__SHIFT 0xd
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_exp_respcnt_enable_MASK 0x4000
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_exp_respcnt_enable__SHIFT 0xe
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_actual_respcnt_enable_MASK 0x8000
+#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_actual_respcnt_enable__SHIFT 0xf
+#define ACP_DAGBG_WR_ASK_CNT__garlic_wr_only_ask_cnt_MASK 0xffff
+#define ACP_DAGBG_WR_ASK_CNT__garlic_wr_only_ask_cnt__SHIFT 0x0
+#define ACP_DAGBG_WR_GO_CNT__garlic_wr_only_go_cnt_MASK 0xffff
+#define ACP_DAGBG_WR_GO_CNT__garlic_wr_only_go_cnt__SHIFT 0x0
+#define ACP_DAGBG_WR_EXP_RESP_CNT__garlic_wr_exp_resp_cnt_MASK 0xffff
+#define ACP_DAGBG_WR_EXP_RESP_CNT__garlic_wr_exp_resp_cnt__SHIFT 0x0
+#define ACP_DAGBG_WR_ACTUAL_RESP_CNT__garlic_wr_actual_resp_cnt_MASK 0xffff
+#define ACP_DAGBG_WR_ACTUAL_RESP_CNT__garlic_wr_actual_resp_cnt__SHIFT 0x0
+#define ACP_DAGBG_RD_ASK_CNT__garlic_rd_only_ask_cnt_MASK 0xffff
+#define ACP_DAGBG_RD_ASK_CNT__garlic_rd_only_ask_cnt__SHIFT 0x0
+#define ACP_DAGBG_RD_GO_CNT__garlic_rd_only_go_cnt_MASK 0xffff
+#define ACP_DAGBG_RD_GO_CNT__garlic_rd_only_go_cnt__SHIFT 0x0
+#define ACP_DAGBG_RD_EXP_RESP_CNT__garlic_rd_exp_resp_cnt_MASK 0xffff
+#define ACP_DAGBG_RD_EXP_RESP_CNT__garlic_rd_exp_resp_cnt__SHIFT 0x0
+#define ACP_DAGBG_RD_ACTUAL_RESP_CNT__garlic_rd_actual_resp_cnt_MASK 0xffff
+#define ACP_DAGBG_RD_ACTUAL_RESP_CNT__garlic_rd_actual_resp_cnt__SHIFT 0x0
+#define ACP_DAGBO_WR_ASK_CNT__onion_wr_only_ask_cnt_MASK 0xffff
+#define ACP_DAGBO_WR_ASK_CNT__onion_wr_only_ask_cnt__SHIFT 0x0
+#define ACP_DAGBO_WR_GO_CNT__onion_wr_only_go_cnt_MASK 0xffff
+#define ACP_DAGBO_WR_GO_CNT__onion_wr_only_go_cnt__SHIFT 0x0
+#define ACP_DAGBO_WR_EXP_RESP_CNT__onion_wr_exp_resp_cnt_MASK 0xffff
+#define ACP_DAGBO_WR_EXP_RESP_CNT__onion_wr_exp_resp_cnt__SHIFT 0x0
+#define ACP_DAGBO_WR_ACTUAL_RESP_CNT__onion_wr_actual_resp_cnt_MASK 0xffff
+#define ACP_DAGBO_WR_ACTUAL_RESP_CNT__onion_wr_actual_resp_cnt__SHIFT 0x0
+#define ACP_DAGBO_RD_ASK_CNT__onion_rd_only_ask_cnt_MASK 0xffff
+#define ACP_DAGBO_RD_ASK_CNT__onion_rd_only_ask_cnt__SHIFT 0x0
+#define ACP_DAGBO_RD_GO_CNT__onion_rd_only_go_cnt_MASK 0xffff
+#define ACP_DAGBO_RD_GO_CNT__onion_rd_only_go_cnt__SHIFT 0x0
+#define ACP_DAGBO_RD_EXP_RESP_CNT__onion_rd_exp_resp_cnt_MASK 0xffff
+#define ACP_DAGBO_RD_EXP_RESP_CNT__onion_rd_exp_resp_cnt__SHIFT 0x0
+#define ACP_DAGBO_RD_ACTUAL_RESP_CNT__onion_rd_actual_resp_cnt_MASK 0xffff
+#define ACP_DAGBO_RD_ACTUAL_RESP_CNT__onion_rd_actual_resp_cnt__SHIFT 0x0
+#define ACP_BRB_CONTROL__BRB_BlockSharedRAMArbCntrl_MASK 0xf
+#define ACP_BRB_CONTROL__BRB_BlockSharedRAMArbCntrl__SHIFT 0x0
+#define ACP_EXTERNAL_INTR_ENB__ACPExtIntrEnb_MASK 0x1
+#define ACP_EXTERNAL_INTR_ENB__ACPExtIntrEnb__SHIFT 0x0
+#define ACP_EXTERNAL_INTR_CNTL__ACPErrMask_MASK 0x1
+#define ACP_EXTERNAL_INTR_CNTL__ACPErrMask__SHIFT 0x0
+#define ACP_EXTERNAL_INTR_CNTL__I2SMicDataAvMask_MASK 0x2
+#define ACP_EXTERNAL_INTR_CNTL__I2SMicDataAvMask__SHIFT 0x1
+#define ACP_EXTERNAL_INTR_CNTL__I2SSpkr0DataEmptyMask_MASK 0x4
+#define ACP_EXTERNAL_INTR_CNTL__I2SSpkr0DataEmptyMask__SHIFT 0x2
+#define ACP_EXTERNAL_INTR_CNTL__I2SSpkr1DataEmptyMask_MASK 0x8
+#define ACP_EXTERNAL_INTR_CNTL__I2SSpkr1DataEmptyMask__SHIFT 0x3
+#define ACP_EXTERNAL_INTR_CNTL__I2SBTDataAvMask_MASK 0x10
+#define ACP_EXTERNAL_INTR_CNTL__I2SBTDataAvMask__SHIFT 0x4
+#define ACP_EXTERNAL_INTR_CNTL__AzaliaIntrMask_MASK 0x40
+#define ACP_EXTERNAL_INTR_CNTL__AzaliaIntrMask__SHIFT 0x6
+#define ACP_EXTERNAL_INTR_CNTL__DSP0TimeoutMask_MASK 0x100
+#define ACP_EXTERNAL_INTR_CNTL__DSP0TimeoutMask__SHIFT 0x8
+#define ACP_EXTERNAL_INTR_CNTL__DSP1TimeoutMask_MASK 0x200
+#define ACP_EXTERNAL_INTR_CNTL__DSP1TimeoutMask__SHIFT 0x9
+#define ACP_EXTERNAL_INTR_CNTL__DSP2TimeoutMask_MASK 0x400
+#define ACP_EXTERNAL_INTR_CNTL__DSP2TimeoutMask__SHIFT 0xa
+#define ACP_EXTERNAL_INTR_CNTL__I2SBTDataEmptyMask_MASK 0x800
+#define ACP_EXTERNAL_INTR_CNTL__I2SBTDataEmptyMask__SHIFT 0xb
+#define ACP_EXTERNAL_INTR_CNTL__DMAIOCMask_MASK 0xffff0000
+#define ACP_EXTERNAL_INTR_CNTL__DMAIOCMask__SHIFT 0x10
+#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErr_MASK 0x1
+#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErr__SHIFT 0x0
+#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErrSource_MASK 0xe
+#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErrSource__SHIFT 0x1
+#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErrSourceOver_MASK 0x10
+#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErrSourceOver__SHIFT 0x4
+#define ACP_ERROR_SOURCE_STS__BRBAddrErr_MASK 0x20
+#define ACP_ERROR_SOURCE_STS__BRBAddrErr__SHIFT 0x5
+#define ACP_ERROR_SOURCE_STS__BRBAddrErrSource_MASK 0x3c0
+#define ACP_ERROR_SOURCE_STS__BRBAddrErrSource__SHIFT 0x6
+#define ACP_ERROR_SOURCE_STS__BRBAddrErrSourceOver_MASK 0x400
+#define ACP_ERROR_SOURCE_STS__BRBAddrErrSourceOver__SHIFT 0xa
+#define ACP_ERROR_SOURCE_STS__I2SMicOverFlowErr_MASK 0x800
+#define ACP_ERROR_SOURCE_STS__I2SMicOverFlowErr__SHIFT 0xb
+#define ACP_ERROR_SOURCE_STS__I2SSpeaker0OverFlowErr_MASK 0x1000
+#define ACP_ERROR_SOURCE_STS__I2SSpeaker0OverFlowErr__SHIFT 0xc
+#define ACP_ERROR_SOURCE_STS__I2SSpeaker1OverFlowErr_MASK 0x2000
+#define ACP_ERROR_SOURCE_STS__I2SSpeaker1OverFlowErr__SHIFT 0xd
+#define ACP_ERROR_SOURCE_STS__I2SBTRxFifoOverFlowErr_MASK 0x4000
+#define ACP_ERROR_SOURCE_STS__I2SBTRxFifoOverFlowErr__SHIFT 0xe
+#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErr_MASK 0x8000
+#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErr__SHIFT 0xf
+#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErrSource_MASK 0x70000
+#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErrSource__SHIFT 0x10
+#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErrSourceOver_MASK 0x80000
+#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErrSourceOver__SHIFT 0x13
+#define ACP_ERROR_SOURCE_STS__DAGBErr_MASK 0x100000
+#define ACP_ERROR_SOURCE_STS__DAGBErr__SHIFT 0x14
+#define ACP_ERROR_SOURCE_STS__DAGBErrSource_MASK 0x1e00000
+#define ACP_ERROR_SOURCE_STS__DAGBErrSource__SHIFT 0x15
+#define ACP_ERROR_SOURCE_STS__DAGBErrSourceOver_MASK 0x2000000
+#define ACP_ERROR_SOURCE_STS__DAGBErrSourceOver__SHIFT 0x19
+#define ACP_ERROR_SOURCE_STS__DMATermOnErr_MASK 0x4000000
+#define ACP_ERROR_SOURCE_STS__DMATermOnErr__SHIFT 0x1a
+#define ACP_ERROR_SOURCE_STS__I2SBTTxFifoOverFlowErr_MASK 0x10000000
+#define ACP_ERROR_SOURCE_STS__I2SBTTxFifoOverFlowErr__SHIFT 0x1c
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP0_MASK 0x1
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP0__SHIFT 0x0
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP1_MASK 0x2
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP1__SHIFT 0x1
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP2_MASK 0x4
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP2__SHIFT 0x2
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP0_MASK 0x100
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP0__SHIFT 0x8
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP1_MASK 0x200
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP1__SHIFT 0x9
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP2_MASK 0x400
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP2__SHIFT 0xa
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP0Host_MASK 0x10000
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP0Host__SHIFT 0x10
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP1Host_MASK 0x20000
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP1Host__SHIFT 0x11
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP2Host_MASK 0x40000
+#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP2Host__SHIFT 0x12
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP0_MASK 0x1
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP0__SHIFT 0x0
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP1_MASK 0x2
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP1__SHIFT 0x1
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP2_MASK 0x4
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP2__SHIFT 0x2
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP0_MASK 0x100
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP0__SHIFT 0x8
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP1_MASK 0x200
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP1__SHIFT 0x9
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP2_MASK 0x400
+#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP2__SHIFT 0xa
+#define ACP_DSP_SW_INTR_CNTL__EnbKernelIntrDSP0Mask_MASK 0x10000
+#define ACP_DSP_SW_INTR_CNTL__EnbKernelIntrDSP0Mask__SHIFT 0x10
+#define ACP_DSP_SW_INTR_CNTL__EmbKernelIntrDSP1Mask_MASK 0x20000
+#define ACP_DSP_SW_INTR_CNTL__EmbKernelIntrDSP1Mask__SHIFT 0x11
+#define ACP_DSP_SW_INTR_CNTL__EmbKernelIntrDSP2Mask_MASK 0x40000
+#define ACP_DSP_SW_INTR_CNTL__EmbKernelIntrDSP2Mask__SHIFT 0x12
+#define ACP_DAGBG_TIMEOUT_CNTL__DAGBGTimeoutValue_MASK 0x3ffff
+#define ACP_DAGBG_TIMEOUT_CNTL__DAGBGTimeoutValue__SHIFT 0x0
+#define ACP_DAGBG_TIMEOUT_CNTL__CntEn_MASK 0x80000000
+#define ACP_DAGBG_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
+#define ACP_DAGBO_TIMEOUT_CNTL__DAGBOTimeoutValue_MASK 0x3ffff
+#define ACP_DAGBO_TIMEOUT_CNTL__DAGBOTimeoutValue__SHIFT 0x0
+#define ACP_DAGBO_TIMEOUT_CNTL__CntEn_MASK 0x80000000
+#define ACP_DAGBO_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
+#define ACP_EXTERNAL_INTR_STAT__ACPErrStat_MASK 0x1
+#define ACP_EXTERNAL_INTR_STAT__ACPErrStat__SHIFT 0x0
+#define ACP_EXTERNAL_INTR_STAT__ACPErrAck_MASK 0x1
+#define ACP_EXTERNAL_INTR_STAT__ACPErrAck__SHIFT 0x0
+#define ACP_EXTERNAL_INTR_STAT__I2SMicDataAvStat_MASK 0x2
+#define ACP_EXTERNAL_INTR_STAT__I2SMicDataAvStat__SHIFT 0x1
+#define ACP_EXTERNAL_INTR_STAT__I2SMicDataAvAck_MASK 0x2
+#define ACP_EXTERNAL_INTR_STAT__I2SMicDataAvAck__SHIFT 0x1
+#define ACP_EXTERNAL_INTR_STAT__I2SSpkr0DataEmptyStat_MASK 0x4
+#define ACP_EXTERNAL_INTR_STAT__I2SSpkr0DataEmptyStat__SHIFT 0x2
+#define ACP_EXTERNAL_INTR_STAT__I2SSpkr0DataEmptyAck_MASK 0x4
+#define ACP_EXTERNAL_INTR_STAT__I2SSpkr0DataEmptyAck__SHIFT 0x2
+#define ACP_EXTERNAL_INTR_STAT__I2SSpkr1DataEmptyStat_MASK 0x8
+#define ACP_EXTERNAL_INTR_STAT__I2SSpkr1DataEmptyStat__SHIFT 0x3
+#define ACP_EXTERNAL_INTR_STAT__I2SSpkr1DataEmptyAck_MASK 0x8
+#define ACP_EXTERNAL_INTR_STAT__I2SSpkr1DataEmptyAck__SHIFT 0x3
+#define ACP_EXTERNAL_INTR_STAT__I2SBTDataAvStat_MASK 0x10
+#define ACP_EXTERNAL_INTR_STAT__I2SBTDataAvStat__SHIFT 0x4
+#define ACP_EXTERNAL_INTR_STAT__I2SBTDataAvAck_MASK 0x10
+#define ACP_EXTERNAL_INTR_STAT__I2SBTDataAvAck__SHIFT 0x4
+#define ACP_EXTERNAL_INTR_STAT__AzaliaIntrStat_MASK 0x40
+#define ACP_EXTERNAL_INTR_STAT__AzaliaIntrStat__SHIFT 0x6
+#define ACP_EXTERNAL_INTR_STAT__AzaliaIntrAck_MASK 0x40
+#define ACP_EXTERNAL_INTR_STAT__AzaliaIntrAck__SHIFT 0x6
+#define ACP_EXTERNAL_INTR_STAT__DSP0TimeoutStat_MASK 0x100
+#define ACP_EXTERNAL_INTR_STAT__DSP0TimeoutStat__SHIFT 0x8
+#define ACP_EXTERNAL_INTR_STAT__DSP0TimeoutAck_MASK 0x100
+#define ACP_EXTERNAL_INTR_STAT__DSP0TimeoutAck__SHIFT 0x8
+#define ACP_EXTERNAL_INTR_STAT__DSP1TimeoutStat_MASK 0x200
+#define ACP_EXTERNAL_INTR_STAT__DSP1TimeoutStat__SHIFT 0x9
+#define ACP_EXTERNAL_INTR_STAT__DSP1TimeoutAck_MASK 0x200
+#define ACP_EXTERNAL_INTR_STAT__DSP1TimeoutAck__SHIFT 0x9
+#define ACP_EXTERNAL_INTR_STAT__DSP2TimeoutStat_MASK 0x400
+#define ACP_EXTERNAL_INTR_STAT__DSP2TimeoutStat__SHIFT 0xa
+#define ACP_EXTERNAL_INTR_STAT__DSP2TimeoutAck_MASK 0x400
+#define ACP_EXTERNAL_INTR_STAT__DSP2TimeoutAck__SHIFT 0xa
+#define ACP_EXTERNAL_INTR_STAT__I2SBTDataEmptyStat_MASK 0x800
+#define ACP_EXTERNAL_INTR_STAT__I2SBTDataEmptyStat__SHIFT 0xb
+#define ACP_EXTERNAL_INTR_STAT__I2SBTDataEmptyAck_MASK 0x800
+#define ACP_EXTERNAL_INTR_STAT__I2SBTDataEmptyAck__SHIFT 0xb
+#define ACP_EXTERNAL_INTR_STAT__DMAIOCStat_MASK 0xffff0000
+#define ACP_EXTERNAL_INTR_STAT__DMAIOCStat__SHIFT 0x10
+#define ACP_EXTERNAL_INTR_STAT__DMAIOCAck_MASK 0xffff0000
+#define ACP_EXTERNAL_INTR_STAT__DMAIOCAck__SHIFT 0x10
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP0Stat_MASK 0x1
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP0Stat__SHIFT 0x0
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP0Ack_MASK 0x1
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP0Ack__SHIFT 0x0
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP1Stat_MASK 0x2
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP1Stat__SHIFT 0x1
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP1Ack_MASK 0x2
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP1Ack__SHIFT 0x1
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP2Stat_MASK 0x4
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP2Stat__SHIFT 0x2
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP2Ack_MASK 0x4
+#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP2Ack__SHIFT 0x2
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP0Stat_MASK 0x100
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP0Stat__SHIFT 0x8
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP0Ack_MASK 0x100
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP0Ack__SHIFT 0x8
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP1Stat_MASK 0x200
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP1Stat__SHIFT 0x9
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP1Ack_MASK 0x200
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP1Ack__SHIFT 0x9
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP2Stat_MASK 0x400
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP2Stat__SHIFT 0xa
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP2Ack_MASK 0x400
+#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP2Ack__SHIFT 0xa
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP0Stat_MASK 0x10000
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP0Stat__SHIFT 0x10
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP0Ack_MASK 0x10000
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP0Ack__SHIFT 0x10
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP1Stat_MASK 0x20000
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP1Stat__SHIFT 0x11
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP1Ack_MASK 0x20000
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP1Ack__SHIFT 0x11
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP2Stat_MASK 0x40000
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP2Stat__SHIFT 0x12
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP2Ack_MASK 0x40000
+#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP2Ack__SHIFT 0x12
+#define ACP_DSP0_INTR_CNTL__ACPErrMask_MASK 0x1
+#define ACP_DSP0_INTR_CNTL__ACPErrMask__SHIFT 0x0
+#define ACP_DSP0_INTR_CNTL__I2SMicDataAvMask_MASK 0x2
+#define ACP_DSP0_INTR_CNTL__I2SMicDataAvMask__SHIFT 0x1
+#define ACP_DSP0_INTR_CNTL__I2SSpkr0DataEmptyMask_MASK 0x4
+#define ACP_DSP0_INTR_CNTL__I2SSpkr0DataEmptyMask__SHIFT 0x2
+#define ACP_DSP0_INTR_CNTL__I2SSpkr1DataEmptyMask_MASK 0x8
+#define ACP_DSP0_INTR_CNTL__I2SSpkr1DataEmptyMask__SHIFT 0x3
+#define ACP_DSP0_INTR_CNTL__I2SBTDataAvMask_MASK 0x10
+#define ACP_DSP0_INTR_CNTL__I2SBTDataAvMask__SHIFT 0x4
+#define ACP_DSP0_INTR_CNTL__AzaliaIntrMask_MASK 0x40
+#define ACP_DSP0_INTR_CNTL__AzaliaIntrMask__SHIFT 0x6
+#define ACP_DSP0_INTR_CNTL__SMUMailboxWriteMask_MASK 0x100
+#define ACP_DSP0_INTR_CNTL__SMUMailboxWriteMask__SHIFT 0x8
+#define ACP_DSP0_INTR_CNTL__SMUStutterStatusMask_MASK 0x200
+#define ACP_DSP0_INTR_CNTL__SMUStutterStatusMask__SHIFT 0x9
+#define ACP_DSP0_INTR_CNTL__MCStutterStatusMask_MASK 0x400
+#define ACP_DSP0_INTR_CNTL__MCStutterStatusMask__SHIFT 0xa
+#define ACP_DSP0_INTR_CNTL__DSPExtTimerMask_MASK 0x800
+#define ACP_DSP0_INTR_CNTL__DSPExtTimerMask__SHIFT 0xb
+#define ACP_DSP0_INTR_CNTL__DSPSemRespMask_MASK 0x1000
+#define ACP_DSP0_INTR_CNTL__DSPSemRespMask__SHIFT 0xc
+#define ACP_DSP0_INTR_CNTL__I2SBTDataEmptyMask_MASK 0x2000
+#define ACP_DSP0_INTR_CNTL__I2SBTDataEmptyMask__SHIFT 0xd
+#define ACP_DSP0_INTR_CNTL__DMAIOCMask_MASK 0xffff0000
+#define ACP_DSP0_INTR_CNTL__DMAIOCMask__SHIFT 0x10
+#define ACP_DSP0_INTR_STAT__ACPErrStat_MASK 0x1
+#define ACP_DSP0_INTR_STAT__ACPErrStat__SHIFT 0x0
+#define ACP_DSP0_INTR_STAT__ACPErrAck_MASK 0x1
+#define ACP_DSP0_INTR_STAT__ACPErrAck__SHIFT 0x0
+#define ACP_DSP0_INTR_STAT__I2SMicDataAvStat_MASK 0x2
+#define ACP_DSP0_INTR_STAT__I2SMicDataAvStat__SHIFT 0x1
+#define ACP_DSP0_INTR_STAT__I2SMicDataAvAck_MASK 0x2
+#define ACP_DSP0_INTR_STAT__I2SMicDataAvAck__SHIFT 0x1
+#define ACP_DSP0_INTR_STAT__I2SSpkr0DataEmptyStat_MASK 0x4
+#define ACP_DSP0_INTR_STAT__I2SSpkr0DataEmptyStat__SHIFT 0x2
+#define ACP_DSP0_INTR_STAT__I2SSpkr0DataEmptyAck_MASK 0x4
+#define ACP_DSP0_INTR_STAT__I2SSpkr0DataEmptyAck__SHIFT 0x2
+#define ACP_DSP0_INTR_STAT__I2SSpkr1DataEmptyStat_MASK 0x8
+#define ACP_DSP0_INTR_STAT__I2SSpkr1DataEmptyStat__SHIFT 0x3
+#define ACP_DSP0_INTR_STAT__I2SSpkr1DataEmptyAck_MASK 0x8
+#define ACP_DSP0_INTR_STAT__I2SSpkr1DataEmptyAck__SHIFT 0x3
+#define ACP_DSP0_INTR_STAT__I2SBTDataAvStat_MASK 0x10
+#define ACP_DSP0_INTR_STAT__I2SBTDataAvStat__SHIFT 0x4
+#define ACP_DSP0_INTR_STAT__I2SBTDataAvAck_MASK 0x10
+#define ACP_DSP0_INTR_STAT__I2SBTDataAvAck__SHIFT 0x4
+#define ACP_DSP0_INTR_STAT__AzaliaIntrStat_MASK 0x40
+#define ACP_DSP0_INTR_STAT__AzaliaIntrStat__SHIFT 0x6
+#define ACP_DSP0_INTR_STAT__AzaliaIntrAck_MASK 0x40
+#define ACP_DSP0_INTR_STAT__AzaliaIntrAck__SHIFT 0x6
+#define ACP_DSP0_INTR_STAT__SMUMailboxWriteStat_MASK 0x100
+#define ACP_DSP0_INTR_STAT__SMUMailboxWriteStat__SHIFT 0x8
+#define ACP_DSP0_INTR_STAT__SMUMailboxWriteAck_MASK 0x100
+#define ACP_DSP0_INTR_STAT__SMUMailboxWriteAck__SHIFT 0x8
+#define ACP_DSP0_INTR_STAT__SMUStutterStatusStat_MASK 0x200
+#define ACP_DSP0_INTR_STAT__SMUStutterStatusStat__SHIFT 0x9
+#define ACP_DSP0_INTR_STAT__SMUStutterStatusAck_MASK 0x200
+#define ACP_DSP0_INTR_STAT__SMUStutterStatusAck__SHIFT 0x9
+#define ACP_DSP0_INTR_STAT__MCStutterStatusStat_MASK 0x400
+#define ACP_DSP0_INTR_STAT__MCStutterStatusStat__SHIFT 0xa
+#define ACP_DSP0_INTR_STAT__MCStutterStatusAck_MASK 0x400
+#define ACP_DSP0_INTR_STAT__MCStutterStatusAck__SHIFT 0xa
+#define ACP_DSP0_INTR_STAT__DSPExtTimerStat_MASK 0x800
+#define ACP_DSP0_INTR_STAT__DSPExtTimerStat__SHIFT 0xb
+#define ACP_DSP0_INTR_STAT__DSPExtTimerAck_MASK 0x800
+#define ACP_DSP0_INTR_STAT__DSPExtTimerAck__SHIFT 0xb
+#define ACP_DSP0_INTR_STAT__DSPSemRespStat_MASK 0x1000
+#define ACP_DSP0_INTR_STAT__DSPSemRespStat__SHIFT 0xc
+#define ACP_DSP0_INTR_STAT__DSPSemRespAck_MASK 0x1000
+#define ACP_DSP0_INTR_STAT__DSPSemRespAck__SHIFT 0xc
+#define ACP_DSP0_INTR_STAT__I2SBTDataEmptyStat_MASK 0x2000
+#define ACP_DSP0_INTR_STAT__I2SBTDataEmptyStat__SHIFT 0xd
+#define ACP_DSP0_INTR_STAT__I2SBTDataEmptyAck_MASK 0x2000
+#define ACP_DSP0_INTR_STAT__I2SBTDataEmptyAck__SHIFT 0xd
+#define ACP_DSP0_INTR_STAT__DMAIOCStat_MASK 0xffff0000
+#define ACP_DSP0_INTR_STAT__DMAIOCStat__SHIFT 0x10
+#define ACP_DSP0_INTR_STAT__DMAIOCAck_MASK 0xffff0000
+#define ACP_DSP0_INTR_STAT__DMAIOCAck__SHIFT 0x10
+#define ACP_DSP0_TIMEOUT_CNTL__DSP0TimeoutValue_MASK 0x3ffff
+#define ACP_DSP0_TIMEOUT_CNTL__DSP0TimeoutValue__SHIFT 0x0
+#define ACP_DSP0_TIMEOUT_CNTL__CntEn_MASK 0x80000000
+#define ACP_DSP0_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
+#define ACP_DSP1_INTR_CNTL__ACPErrMask_MASK 0x1
+#define ACP_DSP1_INTR_CNTL__ACPErrMask__SHIFT 0x0
+#define ACP_DSP1_INTR_CNTL__I2SMicDataAvMask_MASK 0x2
+#define ACP_DSP1_INTR_CNTL__I2SMicDataAvMask__SHIFT 0x1
+#define ACP_DSP1_INTR_CNTL__I2SSpkr0DataEmptyMask_MASK 0x4
+#define ACP_DSP1_INTR_CNTL__I2SSpkr0DataEmptyMask__SHIFT 0x2
+#define ACP_DSP1_INTR_CNTL__I2SSpkr1DataEmptyMask_MASK 0x8
+#define ACP_DSP1_INTR_CNTL__I2SSpkr1DataEmptyMask__SHIFT 0x3
+#define ACP_DSP1_INTR_CNTL__I2SBTDataAvMask_MASK 0x10
+#define ACP_DSP1_INTR_CNTL__I2SBTDataAvMask__SHIFT 0x4
+#define ACP_DSP1_INTR_CNTL__AzaliaIntrMask_MASK 0x40
+#define ACP_DSP1_INTR_CNTL__AzaliaIntrMask__SHIFT 0x6
+#define ACP_DSP1_INTR_CNTL__SMUMailboxWriteMask_MASK 0x100
+#define ACP_DSP1_INTR_CNTL__SMUMailboxWriteMask__SHIFT 0x8
+#define ACP_DSP1_INTR_CNTL__SMUStutterStatusMask_MASK 0x200
+#define ACP_DSP1_INTR_CNTL__SMUStutterStatusMask__SHIFT 0x9
+#define ACP_DSP1_INTR_CNTL__MCStutterStatusMask_MASK 0x400
+#define ACP_DSP1_INTR_CNTL__MCStutterStatusMask__SHIFT 0xa
+#define ACP_DSP1_INTR_CNTL__DSPExtTimerMask_MASK 0x800
+#define ACP_DSP1_INTR_CNTL__DSPExtTimerMask__SHIFT 0xb
+#define ACP_DSP1_INTR_CNTL__DSPSemRespMask_MASK 0x1000
+#define ACP_DSP1_INTR_CNTL__DSPSemRespMask__SHIFT 0xc
+#define ACP_DSP1_INTR_CNTL__I2SBTDataEmptyMask_MASK 0x2000
+#define ACP_DSP1_INTR_CNTL__I2SBTDataEmptyMask__SHIFT 0xd
+#define ACP_DSP1_INTR_CNTL__DMAIOCMask_MASK 0xffff0000
+#define ACP_DSP1_INTR_CNTL__DMAIOCMask__SHIFT 0x10
+#define ACP_DSP1_INTR_STAT__ACPErrStat_MASK 0x1
+#define ACP_DSP1_INTR_STAT__ACPErrStat__SHIFT 0x0
+#define ACP_DSP1_INTR_STAT__ACPErrAck_MASK 0x1
+#define ACP_DSP1_INTR_STAT__ACPErrAck__SHIFT 0x0
+#define ACP_DSP1_INTR_STAT__I2SMicDataAvStat_MASK 0x2
+#define ACP_DSP1_INTR_STAT__I2SMicDataAvStat__SHIFT 0x1
+#define ACP_DSP1_INTR_STAT__I2SMicDataAvAck_MASK 0x2
+#define ACP_DSP1_INTR_STAT__I2SMicDataAvAck__SHIFT 0x1
+#define ACP_DSP1_INTR_STAT__I2SSpkr0DataEmptyStat_MASK 0x4
+#define ACP_DSP1_INTR_STAT__I2SSpkr0DataEmptyStat__SHIFT 0x2
+#define ACP_DSP1_INTR_STAT__I2SSpkr0DataEmptyAck_MASK 0x4
+#define ACP_DSP1_INTR_STAT__I2SSpkr0DataEmptyAck__SHIFT 0x2
+#define ACP_DSP1_INTR_STAT__I2SSpkr1DataEmptyStat_MASK 0x8
+#define ACP_DSP1_INTR_STAT__I2SSpkr1DataEmptyStat__SHIFT 0x3
+#define ACP_DSP1_INTR_STAT__I2SSpkr1DataEmptyAck_MASK 0x8
+#define ACP_DSP1_INTR_STAT__I2SSpkr1DataEmptyAck__SHIFT 0x3
+#define ACP_DSP1_INTR_STAT__I2SBTDataAvStat_MASK 0x10
+#define ACP_DSP1_INTR_STAT__I2SBTDataAvStat__SHIFT 0x4
+#define ACP_DSP1_INTR_STAT__I2SBTDataAvAck_MASK 0x10
+#define ACP_DSP1_INTR_STAT__I2SBTDataAvAck__SHIFT 0x4
+#define ACP_DSP1_INTR_STAT__AzaliaIntrStat_MASK 0x40
+#define ACP_DSP1_INTR_STAT__AzaliaIntrStat__SHIFT 0x6
+#define ACP_DSP1_INTR_STAT__AzaliaIntrAck_MASK 0x40
+#define ACP_DSP1_INTR_STAT__AzaliaIntrAck__SHIFT 0x6
+#define ACP_DSP1_INTR_STAT__SMUMailboxWriteStat_MASK 0x100
+#define ACP_DSP1_INTR_STAT__SMUMailboxWriteStat__SHIFT 0x8
+#define ACP_DSP1_INTR_STAT__SMUMailboxWriteAck_MASK 0x100
+#define ACP_DSP1_INTR_STAT__SMUMailboxWriteAck__SHIFT 0x8
+#define ACP_DSP1_INTR_STAT__SMUStutterStatusStat_MASK 0x200
+#define ACP_DSP1_INTR_STAT__SMUStutterStatusStat__SHIFT 0x9
+#define ACP_DSP1_INTR_STAT__SMUStutterStatusAck_MASK 0x200
+#define ACP_DSP1_INTR_STAT__SMUStutterStatusAck__SHIFT 0x9
+#define ACP_DSP1_INTR_STAT__MCStutterStatusStat_MASK 0x400
+#define ACP_DSP1_INTR_STAT__MCStutterStatusStat__SHIFT 0xa
+#define ACP_DSP1_INTR_STAT__MCStutterStatusAck_MASK 0x400
+#define ACP_DSP1_INTR_STAT__MCStutterStatusAck__SHIFT 0xa
+#define ACP_DSP1_INTR_STAT__DSPExtTimerStat_MASK 0x800
+#define ACP_DSP1_INTR_STAT__DSPExtTimerStat__SHIFT 0xb
+#define ACP_DSP1_INTR_STAT__DSPExtTimerAck_MASK 0x800
+#define ACP_DSP1_INTR_STAT__DSPExtTimerAck__SHIFT 0xb
+#define ACP_DSP1_INTR_STAT__DSPSemRespStat_MASK 0x1000
+#define ACP_DSP1_INTR_STAT__DSPSemRespStat__SHIFT 0xc
+#define ACP_DSP1_INTR_STAT__DSPSemRespAck_MASK 0x1000
+#define ACP_DSP1_INTR_STAT__DSPSemRespAck__SHIFT 0xc
+#define ACP_DSP1_INTR_STAT__I2SBTDataEmptyStat_MASK 0x2000
+#define ACP_DSP1_INTR_STAT__I2SBTDataEmptyStat__SHIFT 0xd
+#define ACP_DSP1_INTR_STAT__I2SBTDataEmptyAck_MASK 0x2000
+#define ACP_DSP1_INTR_STAT__I2SBTDataEmptyAck__SHIFT 0xd
+#define ACP_DSP1_INTR_STAT__DMAIOCStat_MASK 0xffff0000
+#define ACP_DSP1_INTR_STAT__DMAIOCStat__SHIFT 0x10
+#define ACP_DSP1_INTR_STAT__DMAIOCAck_MASK 0xffff0000
+#define ACP_DSP1_INTR_STAT__DMAIOCAck__SHIFT 0x10
+#define ACP_DSP1_TIMEOUT_CNTL__DSP1TimeoutValue_MASK 0x3ffff
+#define ACP_DSP1_TIMEOUT_CNTL__DSP1TimeoutValue__SHIFT 0x0
+#define ACP_DSP1_TIMEOUT_CNTL__CntEn_MASK 0x80000000
+#define ACP_DSP1_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
+#define ACP_DSP2_INTR_CNTL__ACPErrMask_MASK 0x1
+#define ACP_DSP2_INTR_CNTL__ACPErrMask__SHIFT 0x0
+#define ACP_DSP2_INTR_CNTL__I2SMicDataAvMask_MASK 0x2
+#define ACP_DSP2_INTR_CNTL__I2SMicDataAvMask__SHIFT 0x1
+#define ACP_DSP2_INTR_CNTL__I2SSpkr0DataEmptyMask_MASK 0x4
+#define ACP_DSP2_INTR_CNTL__I2SSpkr0DataEmptyMask__SHIFT 0x2
+#define ACP_DSP2_INTR_CNTL__I2SSpkr1DataEmptyMask_MASK 0x8
+#define ACP_DSP2_INTR_CNTL__I2SSpkr1DataEmptyMask__SHIFT 0x3
+#define ACP_DSP2_INTR_CNTL__I2SBTDataAvMask_MASK 0x10
+#define ACP_DSP2_INTR_CNTL__I2SBTDataAvMask__SHIFT 0x4
+#define ACP_DSP2_INTR_CNTL__AzaliaIntrMask_MASK 0x40
+#define ACP_DSP2_INTR_CNTL__AzaliaIntrMask__SHIFT 0x6
+#define ACP_DSP2_INTR_CNTL__SMUMailboxWriteMask_MASK 0x100
+#define ACP_DSP2_INTR_CNTL__SMUMailboxWriteMask__SHIFT 0x8
+#define ACP_DSP2_INTR_CNTL__SMUStutterStatusMask_MASK 0x200
+#define ACP_DSP2_INTR_CNTL__SMUStutterStatusMask__SHIFT 0x9
+#define ACP_DSP2_INTR_CNTL__MCStutterStatusMask_MASK 0x400
+#define ACP_DSP2_INTR_CNTL__MCStutterStatusMask__SHIFT 0xa
+#define ACP_DSP2_INTR_CNTL__DSPExtTimerMask_MASK 0x800
+#define ACP_DSP2_INTR_CNTL__DSPExtTimerMask__SHIFT 0xb
+#define ACP_DSP2_INTR_CNTL__DSPSemRespMask_MASK 0x1000
+#define ACP_DSP2_INTR_CNTL__DSPSemRespMask__SHIFT 0xc
+#define ACP_DSP2_INTR_CNTL__I2SBTDataEmptyMask_MASK 0x2000
+#define ACP_DSP2_INTR_CNTL__I2SBTDataEmptyMask__SHIFT 0xd
+#define ACP_DSP2_INTR_CNTL__DMAIOCMask_MASK 0xffff0000
+#define ACP_DSP2_INTR_CNTL__DMAIOCMask__SHIFT 0x10
+#define ACP_DSP2_INTR_STAT__ACPErrStat_MASK 0x1
+#define ACP_DSP2_INTR_STAT__ACPErrStat__SHIFT 0x0
+#define ACP_DSP2_INTR_STAT__ACPErrAck_MASK 0x1
+#define ACP_DSP2_INTR_STAT__ACPErrAck__SHIFT 0x0
+#define ACP_DSP2_INTR_STAT__I2SMicDataAvStat_MASK 0x2
+#define ACP_DSP2_INTR_STAT__I2SMicDataAvStat__SHIFT 0x1
+#define ACP_DSP2_INTR_STAT__I2SMicDataAvAck_MASK 0x2
+#define ACP_DSP2_INTR_STAT__I2SMicDataAvAck__SHIFT 0x1
+#define ACP_DSP2_INTR_STAT__I2SSpkr0DataEmptyStat_MASK 0x4
+#define ACP_DSP2_INTR_STAT__I2SSpkr0DataEmptyStat__SHIFT 0x2
+#define ACP_DSP2_INTR_STAT__I2SSpkr0DataEmptyAck_MASK 0x4
+#define ACP_DSP2_INTR_STAT__I2SSpkr0DataEmptyAck__SHIFT 0x2
+#define ACP_DSP2_INTR_STAT__I2SSpkr1DataEmptyStat_MASK 0x8
+#define ACP_DSP2_INTR_STAT__I2SSpkr1DataEmptyStat__SHIFT 0x3
+#define ACP_DSP2_INTR_STAT__I2SSpkr1DataEmptyAck_MASK 0x8
+#define ACP_DSP2_INTR_STAT__I2SSpkr1DataEmptyAck__SHIFT 0x3
+#define ACP_DSP2_INTR_STAT__I2SBTDataAvStat_MASK 0x10
+#define ACP_DSP2_INTR_STAT__I2SBTDataAvStat__SHIFT 0x4
+#define ACP_DSP2_INTR_STAT__I2SBTDataAvAck_MASK 0x10
+#define ACP_DSP2_INTR_STAT__I2SBTDataAvAck__SHIFT 0x4
+#define ACP_DSP2_INTR_STAT__AzaliaIntrStat_MASK 0x40
+#define ACP_DSP2_INTR_STAT__AzaliaIntrStat__SHIFT 0x6
+#define ACP_DSP2_INTR_STAT__AzaliaIntrAck_MASK 0x40
+#define ACP_DSP2_INTR_STAT__AzaliaIntrAck__SHIFT 0x6
+#define ACP_DSP2_INTR_STAT__SMUMailboxWriteStat_MASK 0x100
+#define ACP_DSP2_INTR_STAT__SMUMailboxWriteStat__SHIFT 0x8
+#define ACP_DSP2_INTR_STAT__SMUMailboxWriteAck_MASK 0x100
+#define ACP_DSP2_INTR_STAT__SMUMailboxWriteAck__SHIFT 0x8
+#define ACP_DSP2_INTR_STAT__SMUStutterStatusStat_MASK 0x200
+#define ACP_DSP2_INTR_STAT__SMUStutterStatusStat__SHIFT 0x9
+#define ACP_DSP2_INTR_STAT__SMUStutterStatusAck_MASK 0x200
+#define ACP_DSP2_INTR_STAT__SMUStutterStatusAck__SHIFT 0x9
+#define ACP_DSP2_INTR_STAT__MCStutterStatusStat_MASK 0x400
+#define ACP_DSP2_INTR_STAT__MCStutterStatusStat__SHIFT 0xa
+#define ACP_DSP2_INTR_STAT__MCStutterStatusAck_MASK 0x400
+#define ACP_DSP2_INTR_STAT__MCStutterStatusAck__SHIFT 0xa
+#define ACP_DSP2_INTR_STAT__DSPExtTimerStat_MASK 0x800
+#define ACP_DSP2_INTR_STAT__DSPExtTimerStat__SHIFT 0xb
+#define ACP_DSP2_INTR_STAT__DSPExtTimerAck_MASK 0x800
+#define ACP_DSP2_INTR_STAT__DSPExtTimerAck__SHIFT 0xb
+#define ACP_DSP2_INTR_STAT__DSPSemRespStat_MASK 0x1000
+#define ACP_DSP2_INTR_STAT__DSPSemRespStat__SHIFT 0xc
+#define ACP_DSP2_INTR_STAT__DSPSemRespAck_MASK 0x1000
+#define ACP_DSP2_INTR_STAT__DSPSemRespAck__SHIFT 0xc
+#define ACP_DSP2_INTR_STAT__I2SBTDataEmptyStat_MASK 0x2000
+#define ACP_DSP2_INTR_STAT__I2SBTDataEmptyStat__SHIFT 0xd
+#define ACP_DSP2_INTR_STAT__I2SBTDataEmptyAck_MASK 0x2000
+#define ACP_DSP2_INTR_STAT__I2SBTDataEmptyAck__SHIFT 0xd
+#define ACP_DSP2_INTR_STAT__DMAIOCStat_MASK 0xffff0000
+#define ACP_DSP2_INTR_STAT__DMAIOCStat__SHIFT 0x10
+#define ACP_DSP2_INTR_STAT__DMAIOCAck_MASK 0xffff0000
+#define ACP_DSP2_INTR_STAT__DMAIOCAck__SHIFT 0x10
+#define ACP_DSP2_TIMEOUT_CNTL__DSP2TimeoutValue_MASK 0x3ffff
+#define ACP_DSP2_TIMEOUT_CNTL__DSP2TimeoutValue__SHIFT 0x0
+#define ACP_DSP2_TIMEOUT_CNTL__CntEn_MASK 0x80000000
+#define ACP_DSP2_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
+#define ACP_DSP0_EXT_TIMER_CNTL__TimerCount_MASK 0xffffff
+#define ACP_DSP0_EXT_TIMER_CNTL__TimerCount__SHIFT 0x0
+#define ACP_DSP0_EXT_TIMER_CNTL__TimerCntl_MASK 0xc0000000
+#define ACP_DSP0_EXT_TIMER_CNTL__TimerCntl__SHIFT 0x1e
+#define ACP_DSP1_EXT_TIMER_CNTL__TimerCount_MASK 0xffffff
+#define ACP_DSP1_EXT_TIMER_CNTL__TimerCount__SHIFT 0x0
+#define ACP_DSP1_EXT_TIMER_CNTL__TimerCntl_MASK 0xc0000000
+#define ACP_DSP1_EXT_TIMER_CNTL__TimerCntl__SHIFT 0x1e
+#define ACP_DSP2_EXT_TIMER_CNTL__TimerCount_MASK 0xffffff
+#define ACP_DSP2_EXT_TIMER_CNTL__TimerCount__SHIFT 0x0
+#define ACP_DSP2_EXT_TIMER_CNTL__TimerCntl_MASK 0xc0000000
+#define ACP_DSP2_EXT_TIMER_CNTL__TimerCntl__SHIFT 0x1e
+#define ACP_AXI2DAGB_SEM_0__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_0__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_1__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_1__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_2__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_2__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_3__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_3__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_4__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_4__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_5__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_5__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_6__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_6__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_7__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_7__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_8__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_8__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_9__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_9__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_10__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_10__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_11__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_11__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_12__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_12__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_13__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_13__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_14__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_14__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_15__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_15__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_16__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_16__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_17__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_17__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_18__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_18__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_19__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_19__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_20__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_20__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_21__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_21__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_22__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_22__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_23__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_23__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_24__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_24__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_25__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_25__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_26__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_26__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_27__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_27__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_28__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_28__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_29__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_29__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_30__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_30__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_31__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_31__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_32__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_32__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_33__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_33__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_34__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_34__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_35__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_35__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_36__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_36__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_37__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_37__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_38__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_38__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_39__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_39__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_40__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_40__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_41__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_41__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_42__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_42__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_43__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_43__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_44__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_44__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_45__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_45__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_46__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_46__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_AXI2DAGB_SEM_47__AXI2DAGBGblSemReg_MASK 0x1
+#define ACP_AXI2DAGB_SEM_47__AXI2DAGBGblSemReg__SHIFT 0x0
+#define ACP_SRBM_Client_Base_Addr__SRBM_Client_base_addr_MASK 0xff
+#define ACP_SRBM_Client_Base_Addr__SRBM_Client_base_addr__SHIFT 0x0
+#define ACP_SRBM_Client_RDDATA__ReadData_MASK 0xffffffff
+#define ACP_SRBM_Client_RDDATA__ReadData__SHIFT 0x0
+#define ACP_SRBM_Cycle_Sts__SRBM_Client_Sts_MASK 0x1
+#define ACP_SRBM_Cycle_Sts__SRBM_Client_Sts__SHIFT 0x0
+#define ACP_SRBM_Targ_Idx_Addr__SRBM_Targ_Idx_addr_MASK 0x7ffffff
+#define ACP_SRBM_Targ_Idx_Addr__SRBM_Targ_Idx_addr__SHIFT 0x0
+#define ACP_SRBM_Targ_Idx_Data__SRBM_Targ_Idx_Data_MASK 0xffffffff
+#define ACP_SRBM_Targ_Idx_Data__SRBM_Targ_Idx_Data__SHIFT 0x0
+#define ACP_SEMA_ADDR_LOW__ADDR_9_3_MASK 0x7f
+#define ACP_SEMA_ADDR_LOW__ADDR_9_3__SHIFT 0x0
+#define ACP_SEMA_ADDR_HIGH__ADDR_39_10_MASK 0x3fffffff
+#define ACP_SEMA_ADDR_HIGH__ADDR_39_10__SHIFT 0x0
+#define ACP_SEMA_CMD__REQ_CMD_MASK 0xf
+#define ACP_SEMA_CMD__REQ_CMD__SHIFT 0x0
+#define ACP_SEMA_CMD__WR_PHASE_MASK 0x30
+#define ACP_SEMA_CMD__WR_PHASE__SHIFT 0x4
+#define ACP_SEMA_CMD__VMID_EN_MASK 0x80
+#define ACP_SEMA_CMD__VMID_EN__SHIFT 0x7
+#define ACP_SEMA_CMD__VMID_MASK 0xf00
+#define ACP_SEMA_CMD__VMID__SHIFT 0x8
+#define ACP_SEMA_CMD__ATC_MASK 0x1000
+#define ACP_SEMA_CMD__ATC__SHIFT 0xc
+#define ACP_SEMA_STS__REQ_STS_MASK 0x3
+#define ACP_SEMA_STS__REQ_STS__SHIFT 0x0
+#define ACP_SEMA_STS__REQ_RESP_AVAIL_MASK 0x100
+#define ACP_SEMA_STS__REQ_RESP_AVAIL__SHIFT 0x8
+#define ACP_SEMA_REQ__ISSUE_POLL_REQ_MASK 0x1
+#define ACP_SEMA_REQ__ISSUE_POLL_REQ__SHIFT 0x0
+#define ACP_FW_STATUS__RUN_MASK 0x1
+#define ACP_FW_STATUS__RUN__SHIFT 0x0
+#define ACP_FUTURE_REG_ACLK_0__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_ACLK_0__ACPFutureReg__SHIFT 0x0
+#define ACP_FUTURE_REG_ACLK_1__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_ACLK_1__ACPFutureReg__SHIFT 0x0
+#define ACP_FUTURE_REG_ACLK_2__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_ACLK_2__ACPFutureReg__SHIFT 0x0
+#define ACP_FUTURE_REG_ACLK_3__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_ACLK_3__ACPFutureReg__SHIFT 0x0
+#define ACP_FUTURE_REG_ACLK_4__ACPFutureReg_MASK 0xffffffff
+#define ACP_FUTURE_REG_ACLK_4__ACPFutureReg__SHIFT 0x0
+#define ACP_TIMER__ACP_Timer_count_MASK 0xffffffff
+#define ACP_TIMER__ACP_Timer_count__SHIFT 0x0
+#define ACP_TIMER_CNTL__ACP_Timer_control_MASK 0x1
+#define ACP_TIMER_CNTL__ACP_Timer_control__SHIFT 0x0
+#define ACP_DSP0_TIMER__ACP_DSP0_timer_MASK 0xffffff
+#define ACP_DSP0_TIMER__ACP_DSP0_timer__SHIFT 0x0
+#define ACP_DSP1_TIMER__ACP_DSP1_timer_MASK 0xffffff
+#define ACP_DSP1_TIMER__ACP_DSP1_timer__SHIFT 0x0
+#define ACP_DSP2_TIMER__ACP_DSP2_timer_MASK 0xffffff
+#define ACP_DSP2_TIMER__ACP_DSP2_timer__SHIFT 0x0
+#define ACP_I2S_TRANSMIT_BYTE_CNT_HIGH__i2s_sp_tx_byte_cnt_high_MASK 0xffffffff
+#define ACP_I2S_TRANSMIT_BYTE_CNT_HIGH__i2s_sp_tx_byte_cnt_high__SHIFT 0x0
+#define ACP_I2S_TRANSMIT_BYTE_CNT_LOW__i2s_sp_tx_byte_cnt_low_MASK 0xffffffff
+#define ACP_I2S_TRANSMIT_BYTE_CNT_LOW__i2s_sp_tx_byte_cnt_low__SHIFT 0x0
+#define ACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH__i2s_bt_tx_byte_cnt_high_MASK 0xffffffff
+#define ACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH__i2s_bt_tx_byte_cnt_high__SHIFT 0x0
+#define ACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW__i2s_bt_tx_byte_cnt_low_MASK 0xffffffff
+#define ACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW__i2s_bt_tx_byte_cnt_low__SHIFT 0x0
+#define ACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH__i2s_bt_rx_byte_cnt_high_MASK 0xffffffff
+#define ACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH__i2s_bt_rx_byte_cnt_high__SHIFT 0x0
+#define ACP_I2S_BT_RECEIVE_BYTE_CNT_LOW__i2s_bt_rx_byte_cnt_low_MASK 0xffffffff
+#define ACP_I2S_BT_RECEIVE_BYTE_CNT_LOW__i2s_bt_rx_byte_cnt_low__SHIFT 0x0
+#define ACP_DSP0_CS_STATE__DSP0_CS_state_MASK 0x1
+#define ACP_DSP0_CS_STATE__DSP0_CS_state__SHIFT 0x0
+#define ACP_DSP1_CS_STATE__DSP1_CS_state_MASK 0x1
+#define ACP_DSP1_CS_STATE__DSP1_CS_state__SHIFT 0x0
+#define ACP_DSP2_CS_STATE__DSP2_CS_state_MASK 0x1
+#define ACP_DSP2_CS_STATE__DSP2_CS_state__SHIFT 0x0
+#define ACP_SCRATCH_REG_BASE_ADDR__SCRATCH_REG_BASE_ADDR_MASK 0x7ffff
+#define ACP_SCRATCH_REG_BASE_ADDR__SCRATCH_REG_BASE_ADDR__SHIFT 0x0
+#define CC_ACP_EFUSE__DSP0_DISABLE_MASK 0x2
+#define CC_ACP_EFUSE__DSP0_DISABLE__SHIFT 0x1
+#define CC_ACP_EFUSE__DSP1_DISABLE_MASK 0x4
+#define CC_ACP_EFUSE__DSP1_DISABLE__SHIFT 0x2
+#define CC_ACP_EFUSE__DSP2_DISABLE_MASK 0x8
+#define CC_ACP_EFUSE__DSP2_DISABLE__SHIFT 0x3
+#define CC_ACP_EFUSE__ACP_DISABLE_MASK 0x10
+#define CC_ACP_EFUSE__ACP_DISABLE__SHIFT 0x4
+#define ACP_PGFSM_RETAIN_REG__ACP_P1_ON_OFF_MASK 0x1
+#define ACP_PGFSM_RETAIN_REG__ACP_P1_ON_OFF__SHIFT 0x0
+#define ACP_PGFSM_RETAIN_REG__ACP_P2_ON_OFF_MASK 0x2
+#define ACP_PGFSM_RETAIN_REG__ACP_P2_ON_OFF__SHIFT 0x1
+#define ACP_PGFSM_RETAIN_REG__ACP_DSP0_ON_OFF_MASK 0x4
+#define ACP_PGFSM_RETAIN_REG__ACP_DSP0_ON_OFF__SHIFT 0x2
+#define ACP_PGFSM_RETAIN_REG__ACP_DSP1_ON_OFF_MASK 0x8
+#define ACP_PGFSM_RETAIN_REG__ACP_DSP1_ON_OFF__SHIFT 0x3
+#define ACP_PGFSM_RETAIN_REG__ACP_DSP2_ON_OFF_MASK 0x10
+#define ACP_PGFSM_RETAIN_REG__ACP_DSP2_ON_OFF__SHIFT 0x4
+#define ACP_PGFSM_RETAIN_REG__ACP_AZ_ON_OFF_MASK 0x20
+#define ACP_PGFSM_RETAIN_REG__ACP_AZ_ON_OFF__SHIFT 0x5
+#define ACP_PGFSM_CONFIG_REG__FSM_ADDR_MASK 0xff
+#define ACP_PGFSM_CONFIG_REG__FSM_ADDR__SHIFT 0x0
+#define ACP_PGFSM_CONFIG_REG__Power_Down_MASK 0x100
+#define ACP_PGFSM_CONFIG_REG__Power_Down__SHIFT 0x8
+#define ACP_PGFSM_CONFIG_REG__Power_Up_MASK 0x200
+#define ACP_PGFSM_CONFIG_REG__Power_Up__SHIFT 0x9
+#define ACP_PGFSM_CONFIG_REG__P1_Select_MASK 0x400
+#define ACP_PGFSM_CONFIG_REG__P1_Select__SHIFT 0xa
+#define ACP_PGFSM_CONFIG_REG__P2_Select_MASK 0x800
+#define ACP_PGFSM_CONFIG_REG__P2_Select__SHIFT 0xb
+#define ACP_PGFSM_CONFIG_REG__Wr_MASK 0x1000
+#define ACP_PGFSM_CONFIG_REG__Wr__SHIFT 0xc
+#define ACP_PGFSM_CONFIG_REG__Rd_MASK 0x2000
+#define ACP_PGFSM_CONFIG_REG__Rd__SHIFT 0xd
+#define ACP_PGFSM_CONFIG_REG__RdData_Reset_MASK 0x4000
+#define ACP_PGFSM_CONFIG_REG__RdData_Reset__SHIFT 0xe
+#define ACP_PGFSM_CONFIG_REG__Short_Format_MASK 0x8000
+#define ACP_PGFSM_CONFIG_REG__Short_Format__SHIFT 0xf
+#define ACP_PGFSM_CONFIG_REG__BPM_CG_MG_FGCG_MASK 0x3ff0000
+#define ACP_PGFSM_CONFIG_REG__BPM_CG_MG_FGCG__SHIFT 0x10
+#define ACP_PGFSM_CONFIG_REG__SRBM_override_MASK 0x4000000
+#define ACP_PGFSM_CONFIG_REG__SRBM_override__SHIFT 0x1a
+#define ACP_PGFSM_CONFIG_REG__Rsvd_BPM_Addr_MASK 0x8000000
+#define ACP_PGFSM_CONFIG_REG__Rsvd_BPM_Addr__SHIFT 0x1b
+#define ACP_PGFSM_CONFIG_REG__REG_ADDR_MASK 0xf0000000
+#define ACP_PGFSM_CONFIG_REG__REG_ADDR__SHIFT 0x1c
+#define ACP_PGFSM_WRITE_REG__Write_value_MASK 0xffffffff
+#define ACP_PGFSM_WRITE_REG__Write_value__SHIFT 0x0
+#define ACP_PGFSM_READ_REG_0__Read_value_MASK 0xffffff
+#define ACP_PGFSM_READ_REG_0__Read_value__SHIFT 0x0
+#define ACP_PGFSM_READ_REG_1__Read_value_MASK 0xffffff
+#define ACP_PGFSM_READ_REG_1__Read_value__SHIFT 0x0
+#define ACP_PGFSM_READ_REG_2__Read_value_MASK 0xffffff
+#define ACP_PGFSM_READ_REG_2__Read_value__SHIFT 0x0
+#define ACP_PGFSM_READ_REG_3__Read_value_MASK 0xffffff
+#define ACP_PGFSM_READ_REG_3__Read_value__SHIFT 0x0
+#define ACP_PGFSM_READ_REG_4__Read_value_MASK 0xffffff
+#define ACP_PGFSM_READ_REG_4__Read_value__SHIFT 0x0
+#define ACP_PGFSM_READ_REG_5__Read_value_MASK 0xffffff
+#define ACP_PGFSM_READ_REG_5__Read_value__SHIFT 0x0
+#define ACP_IP_PGFSM_ENABLE__ACP_IP_ACCESS_MASK 0x1
+#define ACP_IP_PGFSM_ENABLE__ACP_IP_ACCESS__SHIFT 0x0
+#define ACP_I2S_PIN_CONFIG__ACP_I2S_PIN_CONFIG_MASK 0x3
+#define ACP_I2S_PIN_CONFIG__ACP_I2S_PIN_CONFIG__SHIFT 0x0
+#define ACP_AZALIA_I2S_SELECT__AZ_I2S_SELECT_MASK 0x1
+#define ACP_AZALIA_I2S_SELECT__AZ_I2S_SELECT__SHIFT 0x0
+#define ACP_CHIP_PKG_FOR_PAD_ISOLATION__external_fch_package_MASK 0x1
+#define ACP_CHIP_PKG_FOR_PAD_ISOLATION__external_fch_package__SHIFT 0x0
+#define ACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL__ACP_AUDIO_PAD_pullup_disable_MASK 0x7ff
+#define ACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL__ACP_AUDIO_PAD_pullup_disable__SHIFT 0x0
+#define ACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL__ACP_AUDIO_PAD_pulldown_enable_MASK 0x7ff0000
+#define ACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL__ACP_AUDIO_PAD_pulldown_enable__SHIFT 0x10
+#define ACP_BT_UART_PAD_SEL__ACP_BT_UART_PAD_SEL_MASK 0x1
+#define ACP_BT_UART_PAD_SEL__ACP_BT_UART_PAD_SEL__SHIFT 0x0
+#define ACP_SCRATCH_REG_0__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_0__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_1__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_1__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_2__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_2__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_3__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_3__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_4__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_4__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_5__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_5__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_6__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_6__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_7__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_7__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_8__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_8__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_9__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_9__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_10__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_10__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_11__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_11__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_12__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_12__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_13__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_13__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_14__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_14__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_15__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_15__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_16__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_16__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_17__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_17__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_18__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_18__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_19__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_19__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_20__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_20__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_21__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_21__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_22__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_22__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_23__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_23__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_24__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_24__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_25__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_25__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_26__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_26__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_27__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_27__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_28__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_28__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_29__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_29__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_30__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_30__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_31__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_31__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_32__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_32__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_33__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_33__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_34__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_34__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_35__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_35__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_36__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_36__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_37__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_37__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_38__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_38__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_39__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_39__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_40__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_40__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_41__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_41__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_42__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_42__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_43__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_43__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_44__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_44__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_45__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_45__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_46__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_46__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_SCRATCH_REG_47__ACP_SCRATCH_REG_MASK 0xffffffff
+#define ACP_SCRATCH_REG_47__ACP_SCRATCH_REG__SHIFT 0x0
+#define ACP_VOICE_WAKEUP_ENABLE__voice_wakeup_enable_MASK 0x1
+#define ACP_VOICE_WAKEUP_ENABLE__voice_wakeup_enable__SHIFT 0x0
+#define ACP_VOICE_WAKEUP_STATUS__voice_wakeup_status_MASK 0x1
+#define ACP_VOICE_WAKEUP_STATUS__voice_wakeup_status__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_LOWER_THRESHOLD__i2s_voice_wakeup_lower_threshold_MASK 0xffffffff
+#define I2S_VOICE_WAKEUP_LOWER_THRESHOLD__i2s_voice_wakeup_lower_threshold__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_HIGHER_THRESHOLD__i2s_voice_wakeup_higher_threshold_MASK 0xffffffff
+#define I2S_VOICE_WAKEUP_HIGHER_THRESHOLD__i2s_voice_wakeup_higher_threshold__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_NO_OF_SAMPLES__i2s_voice_wakeup_no_of_samples_MASK 0xffff
+#define I2S_VOICE_WAKEUP_NO_OF_SAMPLES__i2s_voice_wakeup_no_of_samples__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_NO_OF_PEAKS__i2s_voice_wakeup_no_of_peaks_MASK 0xffff
+#define I2S_VOICE_WAKEUP_NO_OF_PEAKS__i2s_voice_wakeup_no_of_peaks__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_DURATION_OF_N_PEAKS__i2s_voice_wakeup_duration_of_n_peaks_MASK 0xffffffff
+#define I2S_VOICE_WAKEUP_DURATION_OF_N_PEAKS__i2s_voice_wakeup_duration_of_n_peaks__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_BITCLK_TOGGLE_DETECTION__i2s_voice_wakeup_bitclk_toggle_wakeup_en_MASK 0x1
+#define I2S_VOICE_WAKEUP_BITCLK_TOGGLE_DETECTION__i2s_voice_wakeup_bitclk_toggle_wakeup_en__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_DATA_PATH_SWITCH__i2s_voice_wakeup_data_path_switch_req_MASK 0x1
+#define I2S_VOICE_WAKEUP_DATA_PATH_SWITCH__i2s_voice_wakeup_data_path_switch_req__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_DATA_PATH_SWITCH__i2s_voice_wakeup_data_path_switch_ack_MASK 0x2
+#define I2S_VOICE_WAKEUP_DATA_PATH_SWITCH__i2s_voice_wakeup_data_path_switch_ack__SHIFT 0x1
+#define I2S_VOICE_WAKEUP_DATA_POINTER__i2s_voice_wakeup_data_pointer_MASK 0xffffffff
+#define I2S_VOICE_WAKEUP_DATA_POINTER__i2s_voice_wakeup_data_pointer__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_AUTH_MATCH__i2s_voice_wakeup_authentication_valid_MASK 0x1
+#define I2S_VOICE_WAKEUP_AUTH_MATCH__i2s_voice_wakeup_authentication_valid__SHIFT 0x0
+#define I2S_VOICE_WAKEUP_AUTH_MATCH__i2s_voice_wakeup_authentication_match_MASK 0x2
+#define I2S_VOICE_WAKEUP_AUTH_MATCH__i2s_voice_wakeup_authentication_match__SHIFT 0x1
+#define I2S_VOICE_WAKEUP_8KB_WRAP__i2s_voice_wakeup_8kb_wrap_MASK 0x1
+#define I2S_VOICE_WAKEUP_8KB_WRAP__i2s_voice_wakeup_8kb_wrap__SHIFT 0x0
+#define ACP_I2S_RECEIVED_BYTE_CNT_HIGH__i2s_mic_rx_byte_cnt_high_MASK 0xffffffff
+#define ACP_I2S_RECEIVED_BYTE_CNT_HIGH__i2s_mic_rx_byte_cnt_high__SHIFT 0x0
+#define ACP_I2S_RECEIVED_BYTE_CNT_LOW__i2s_mic_rx_byte_cnt_low_MASK 0xffffffff
+#define ACP_I2S_RECEIVED_BYTE_CNT_LOW__i2s_mic_rx_byte_cnt_low__SHIFT 0x0
+#define ACP_I2S_MICSP_TRANSMIT_BYTE_CNT_HIGH__i2s_micsp_tx_byte_cnt_high_MASK 0xffffffff
+#define ACP_I2S_MICSP_TRANSMIT_BYTE_CNT_HIGH__i2s_micsp_tx_byte_cnt_high__SHIFT 0x0
+#define ACP_I2S_MICSP_TRANSMIT_BYTE_CNT_LOW__i2s_micsp_tx_byte_cnt_low_MASK 0xffffffff
+#define ACP_I2S_MICSP_TRANSMIT_BYTE_CNT_LOW__i2s_micsp_tx_byte_cnt_low__SHIFT 0x0
+#define ACP_MEM_SHUT_DOWN_REQ_LO__ACP_ShutDownReq_RAML_MASK 0xffffffff
+#define ACP_MEM_SHUT_DOWN_REQ_LO__ACP_ShutDownReq_RAML__SHIFT 0x0
+#define ACP_MEM_SHUT_DOWN_REQ_HI__ACP_ShutDownReq_RAMH_MASK 0xffff
+#define ACP_MEM_SHUT_DOWN_REQ_HI__ACP_ShutDownReq_RAMH__SHIFT 0x0
+#define ACP_MEM_SHUT_DOWN_STS_LO__ACP_ShutDownSts_RAML_MASK 0xffffffff
+#define ACP_MEM_SHUT_DOWN_STS_LO__ACP_ShutDownSts_RAML__SHIFT 0x0
+#define ACP_MEM_SHUT_DOWN_STS_HI__ACP_ShutDownSts_RAMH_MASK 0xffff
+#define ACP_MEM_SHUT_DOWN_STS_HI__ACP_ShutDownSts_RAMH__SHIFT 0x0
+#define ACP_MEM_DEEP_SLEEP_REQ_LO__ACP_DeepSleepReq_RAML_MASK 0xffffffff
+#define ACP_MEM_DEEP_SLEEP_REQ_LO__ACP_DeepSleepReq_RAML__SHIFT 0x0
+#define ACP_MEM_DEEP_SLEEP_REQ_HI__ACP_DeepSleepReq_RAMH_MASK 0xffff
+#define ACP_MEM_DEEP_SLEEP_REQ_HI__ACP_DeepSleepReq_RAMH__SHIFT 0x0
+#define ACP_MEM_DEEP_SLEEP_STS_LO__ACP_DeepSleepSts_RAML_MASK 0xffffffff
+#define ACP_MEM_DEEP_SLEEP_STS_LO__ACP_DeepSleepSts_RAML__SHIFT 0x0
+#define ACP_MEM_DEEP_SLEEP_STS_HI__ACP_DeepSleepSts_RAMH_MASK 0xffff
+#define ACP_MEM_DEEP_SLEEP_STS_HI__ACP_DeepSleepSts_RAMH__SHIFT 0x0
+#define ACP_MEM_WAKEUP_FROM_SHUT_DOWN_LO__acp_mem_wakeup_from_shut_down_lo_MASK 0xffffffff
+#define ACP_MEM_WAKEUP_FROM_SHUT_DOWN_LO__acp_mem_wakeup_from_shut_down_lo__SHIFT 0x0
+#define ACP_MEM_WAKEUP_FROM_SHUT_DOWN_HI__acp_mem_wakeup_from_shut_down_hi_MASK 0xffff
+#define ACP_MEM_WAKEUP_FROM_SHUT_DOWN_HI__acp_mem_wakeup_from_shut_down_hi__SHIFT 0x0
+#define ACP_MEM_WAKEUP_FROM_SLEEP_LO__acp_mem_wakeup_from_sleep_lo_MASK 0xffffffff
+#define ACP_MEM_WAKEUP_FROM_SLEEP_LO__acp_mem_wakeup_from_sleep_lo__SHIFT 0x0
+#define ACP_MEM_WAKEUP_FROM_SLEEP_HI__acp_mem_wakeup_from_sleep_hi_MASK 0xffff
+#define ACP_MEM_WAKEUP_FROM_SLEEP_HI__acp_mem_wakeup_from_sleep_hi__SHIFT 0x0
+#define ACP_I2SSP_IER__I2SSP_IEN_MASK 0x1
+#define ACP_I2SSP_IER__I2SSP_IEN__SHIFT 0x0
+#define ACP_I2SSP_IRER__I2SSP_RXEN_MASK 0x1
+#define ACP_I2SSP_IRER__I2SSP_RXEN__SHIFT 0x0
+#define ACP_I2SSP_ITER__I2SSP_TXEN_MASK 0x1
+#define ACP_I2SSP_ITER__I2SSP_TXEN__SHIFT 0x0
+#define ACP_I2SSP_CER__I2SSP_CLKEN_MASK 0x1
+#define ACP_I2SSP_CER__I2SSP_CLKEN__SHIFT 0x0
+#define ACP_I2SSP_CCR__I2SSP_SCLKG_MASK 0x7
+#define ACP_I2SSP_CCR__I2SSP_SCLKG__SHIFT 0x0
+#define ACP_I2SSP_CCR__I2SSP_WSS_MASK 0x18
+#define ACP_I2SSP_CCR__I2SSP_WSS__SHIFT 0x3
+#define ACP_I2SSP_RXFFR__I2SSP_RXFFR_MASK 0x1
+#define ACP_I2SSP_RXFFR__I2SSP_RXFFR__SHIFT 0x0
+#define ACP_I2SSP_TXFFR__I2SSP_TXFFR_MASK 0x1
+#define ACP_I2SSP_TXFFR__I2SSP_TXFFR__SHIFT 0x0
+#define ACP_I2SSP_LRBR0__I2SSP_LRBR0_MASK 0xffffffff
+#define ACP_I2SSP_LRBR0__I2SSP_LRBR0__SHIFT 0x0
+#define ACP_I2SSP_RRBR0__I2SSP_RRBR0_MASK 0xffffffff
+#define ACP_I2SSP_RRBR0__I2SSP_RRBR0__SHIFT 0x0
+#define ACP_I2SSP_RER0__I2SSP_RXCHEN0_MASK 0x1
+#define ACP_I2SSP_RER0__I2SSP_RXCHEN0__SHIFT 0x0
+#define ACP_I2SSP_TER0__I2SSP_TXCHEN0_MASK 0x1
+#define ACP_I2SSP_TER0__I2SSP_TXCHEN0__SHIFT 0x0
+#define ACP_I2SSP_RCR0__I2SSP_WLEN_MASK 0x7
+#define ACP_I2SSP_RCR0__I2SSP_WLEN__SHIFT 0x0
+#define ACP_I2SSP_TCR0__I2SSP_WLEN_MASK 0x7
+#define ACP_I2SSP_TCR0__I2SSP_WLEN__SHIFT 0x0
+#define ACP_I2SSP_ISR0__I2SSP_RXDA_MASK 0x1
+#define ACP_I2SSP_ISR0__I2SSP_RXDA__SHIFT 0x0
+#define ACP_I2SSP_ISR0__I2SSP_RXFO_MASK 0x2
+#define ACP_I2SSP_ISR0__I2SSP_RXFO__SHIFT 0x1
+#define ACP_I2SSP_ISR0__I2SSP_TXFE_MASK 0x10
+#define ACP_I2SSP_ISR0__I2SSP_TXFE__SHIFT 0x4
+#define ACP_I2SSP_ISR0__I2SSP_TXFO_MASK 0x20
+#define ACP_I2SSP_ISR0__I2SSP_TXFO__SHIFT 0x5
+#define ACP_I2SSP_IMR0__I2SSP_RXDAM_MASK 0x1
+#define ACP_I2SSP_IMR0__I2SSP_RXDAM__SHIFT 0x0
+#define ACP_I2SSP_IMR0__I2SSP_RXFOM_MASK 0x2
+#define ACP_I2SSP_IMR0__I2SSP_RXFOM__SHIFT 0x1
+#define ACP_I2SSP_IMR0__I2SSP_TXFEM_MASK 0x10
+#define ACP_I2SSP_IMR0__I2SSP_TXFEM__SHIFT 0x4
+#define ACP_I2SSP_IMR0__I2SSP_TXFOM_MASK 0x20
+#define ACP_I2SSP_IMR0__I2SSP_TXFOM__SHIFT 0x5
+#define ACP_I2SSP_ROR0__I2SSP_RXCHO_MASK 0x1
+#define ACP_I2SSP_ROR0__I2SSP_RXCHO__SHIFT 0x0
+#define ACP_I2SSP_TOR0__I2SSP_TXCHO_MASK 0x1
+#define ACP_I2SSP_TOR0__I2SSP_TXCHO__SHIFT 0x0
+#define ACP_I2SSP_RFCR0__I2SSP_RXCHDT_MASK 0xf
+#define ACP_I2SSP_RFCR0__I2SSP_RXCHDT__SHIFT 0x0
+#define ACP_I2SSP_TFCR0__I2SSP_TXCHET_MASK 0xf
+#define ACP_I2SSP_TFCR0__I2SSP_TXCHET__SHIFT 0x0
+#define ACP_I2SSP_RFF0__I2SSP_RXCHFR_MASK 0x1
+#define ACP_I2SSP_RFF0__I2SSP_RXCHFR__SHIFT 0x0
+#define ACP_I2SSP_TFF0__I2SSP_TXCHFR_MASK 0x1
+#define ACP_I2SSP_TFF0__I2SSP_TXCHFR__SHIFT 0x0
+#define ACP_I2SSP_RXDMA__I2SSP_RXDMA_MASK 0xffffffff
+#define ACP_I2SSP_RXDMA__I2SSP_RXDMA__SHIFT 0x0
+#define ACP_I2SSP_RRXDMA__I2SSP_RRXDMA_MASK 0x1
+#define ACP_I2SSP_RRXDMA__I2SSP_RRXDMA__SHIFT 0x0
+#define ACP_I2SSP_TXDMA__I2SSP_TXDMA_MASK 0xffffffff
+#define ACP_I2SSP_TXDMA__I2SSP_TXDMA__SHIFT 0x0
+#define ACP_I2SSP_RTXDMA__I2SSP_RTXDMA_MASK 0x1
+#define ACP_I2SSP_RTXDMA__I2SSP_RTXDMA__SHIFT 0x0
+#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_0_MASK 0x7
+#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_0__SHIFT 0x0
+#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_1_MASK 0x38
+#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_1__SHIFT 0x3
+#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_2_MASK 0x380
+#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_2__SHIFT 0x7
+#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_3_MASK 0x1c00
+#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_3__SHIFT 0xa
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_APB_DATA_WIDTH_MASK 0x3
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_APB_DATA_WIDTH__SHIFT 0x0
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_FIFO_DEPTH_GLOBAL_MASK 0xc
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_FIFO_DEPTH_GLOBAL__SHIFT 0x2
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_MODE_EN_MASK 0x10
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_MODE_EN__SHIFT 0x4
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TRANSMITTER_BLOCK_MASK 0x20
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TRANSMITTER_BLOCK__SHIFT 0x5
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_RECEIVER_BLOCK_MASK 0x40
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_RECEIVER_BLOCK__SHIFT 0x6
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_RX_CHANNLES_MASK 0x180
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_RX_CHANNLES__SHIFT 0x7
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_CHANNLES_MASK 0x600
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_CHANNLES__SHIFT 0x9
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_0_MASK 0x70000
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_0__SHIFT 0x10
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_1_MASK 0x380000
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_1__SHIFT 0x13
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_2_MASK 0x1c00000
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_2__SHIFT 0x16
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_3_MASK 0xe000000
+#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_3__SHIFT 0x19
+#define ACP_I2SSP_COMP_VERSION__I2SSP_APB_DATA_WIDTH_MASK 0xffffffff
+#define ACP_I2SSP_COMP_VERSION__I2SSP_APB_DATA_WIDTH__SHIFT 0x0
+#define ACP_I2SSP_COMP_TYPE__I2SSP_COMP_TYPE_MASK 0xffffffff
+#define ACP_I2SSP_COMP_TYPE__I2SSP_COMP_TYPE__SHIFT 0x0
+#define ACP_I2SMICSP_IER__I2SMICSP_IEN_MASK 0x1
+#define ACP_I2SMICSP_IER__I2SMICSP_IEN__SHIFT 0x0
+#define ACP_I2SMICSP_IRER__I2SMICSP_RXEN_MASK 0x1
+#define ACP_I2SMICSP_IRER__I2SMICSP_RXEN__SHIFT 0x0
+#define ACP_I2SMICSP_ITER__I2SMICSP_TXEN_MASK 0x1
+#define ACP_I2SMICSP_ITER__I2SMICSP_TXEN__SHIFT 0x0
+#define ACP_I2SMICSP_CER__I2SMICSP_CLKEN_MASK 0x1
+#define ACP_I2SMICSP_CER__I2SMICSP_CLKEN__SHIFT 0x0
+#define ACP_I2SMICSP_CCR__I2SMICSP_SCLKG_MASK 0x7
+#define ACP_I2SMICSP_CCR__I2SMICSP_SCLKG__SHIFT 0x0
+#define ACP_I2SMICSP_CCR__I2SMICSP_WSS_MASK 0x18
+#define ACP_I2SMICSP_CCR__I2SMICSP_WSS__SHIFT 0x3
+#define ACP_I2SMICSP_RXFFR__I2SMICSP_RXFFR_MASK 0x1
+#define ACP_I2SMICSP_RXFFR__I2SMICSP_RXFFR__SHIFT 0x0
+#define ACP_I2SMICSP_TXFFR__I2SMICSP_TXFFR_MASK 0x1
+#define ACP_I2SMICSP_TXFFR__I2SMICSP_TXFFR__SHIFT 0x0
+#define ACP_I2SMICSP_LRBR0__I2SMICSP_LRBR0_MASK 0xffffffff
+#define ACP_I2SMICSP_LRBR0__I2SMICSP_LRBR0__SHIFT 0x0
+#define ACP_I2SMICSP_RRBR0__I2SMICSP_RRBR0_MASK 0xffffffff
+#define ACP_I2SMICSP_RRBR0__I2SMICSP_RRBR0__SHIFT 0x0
+#define ACP_I2SMICSP_RER0__I2SMICSP_RXCHEN0_MASK 0x1
+#define ACP_I2SMICSP_RER0__I2SMICSP_RXCHEN0__SHIFT 0x0
+#define ACP_I2SMICSP_TER0__I2SMICSP_TXCHEN0_MASK 0x1
+#define ACP_I2SMICSP_TER0__I2SMICSP_TXCHEN0__SHIFT 0x0
+#define ACP_I2SMICSP_RCR0__I2SMICSP_WLEN_MASK 0x7
+#define ACP_I2SMICSP_RCR0__I2SMICSP_WLEN__SHIFT 0x0
+#define ACP_I2SMICSP_TCR0__I2SMICSP_WLEN_MASK 0x7
+#define ACP_I2SMICSP_TCR0__I2SMICSP_WLEN__SHIFT 0x0
+#define ACP_I2SMICSP_ISR0__I2SMICSP_RXDA_MASK 0x1
+#define ACP_I2SMICSP_ISR0__I2SMICSP_RXDA__SHIFT 0x0
+#define ACP_I2SMICSP_ISR0__I2SMICSP_RXFO_MASK 0x2
+#define ACP_I2SMICSP_ISR0__I2SMICSP_RXFO__SHIFT 0x1
+#define ACP_I2SMICSP_ISR0__I2SMICSP_TXFE_MASK 0x10
+#define ACP_I2SMICSP_ISR0__I2SMICSP_TXFE__SHIFT 0x4
+#define ACP_I2SMICSP_ISR0__I2SMICSP_TXFO_MASK 0x20
+#define ACP_I2SMICSP_ISR0__I2SMICSP_TXFO__SHIFT 0x5
+#define ACP_I2SMICSP_IMR0__I2SMICSP_RXDAM_MASK 0x1
+#define ACP_I2SMICSP_IMR0__I2SMICSP_RXDAM__SHIFT 0x0
+#define ACP_I2SMICSP_IMR0__I2SMICSP_RXFOM_MASK 0x2
+#define ACP_I2SMICSP_IMR0__I2SMICSP_RXFOM__SHIFT 0x1
+#define ACP_I2SMICSP_IMR0__I2SMICSP_TXFEM_MASK 0x10
+#define ACP_I2SMICSP_IMR0__I2SMICSP_TXFEM__SHIFT 0x4
+#define ACP_I2SMICSP_IMR0__I2SMICSP_TXFOM_MASK 0x20
+#define ACP_I2SMICSP_IMR0__I2SMICSP_TXFOM__SHIFT 0x5
+#define ACP_I2SMICSP_ROR0__I2SMICSP_RXCHO_MASK 0x1
+#define ACP_I2SMICSP_ROR0__I2SMICSP_RXCHO__SHIFT 0x0
+#define ACP_I2SMICSP_TOR0__I2SMICSP_TXCHO_MASK 0x1
+#define ACP_I2SMICSP_TOR0__I2SMICSP_TXCHO__SHIFT 0x0
+#define ACP_I2SMICSP_RFCR0__I2SMICSP_RXCHDT_MASK 0xf
+#define ACP_I2SMICSP_RFCR0__I2SMICSP_RXCHDT__SHIFT 0x0
+#define ACP_I2SMICSP_TFCR0__I2SMICSP_TXCHET_MASK 0xf
+#define ACP_I2SMICSP_TFCR0__I2SMICSP_TXCHET__SHIFT 0x0
+#define ACP_I2SMICSP_RFF0__I2SMICSP_RXCHFR_MASK 0x1
+#define ACP_I2SMICSP_RFF0__I2SMICSP_RXCHFR__SHIFT 0x0
+#define ACP_I2SMICSP_TFF0__I2SMICSP_TXCHFR_MASK 0x1
+#define ACP_I2SMICSP_TFF0__I2SMICSP_TXCHFR__SHIFT 0x0
+#define ACP_I2SMICSP_LRBR1__I2SMICSP_LRBR1_MASK 0xffffffff
+#define ACP_I2SMICSP_LRBR1__I2SMICSP_LRBR1__SHIFT 0x0
+#define ACP_I2SMICSP_RRBR1__I2SMICSP_RRBR1_MASK 0xffffffff
+#define ACP_I2SMICSP_RRBR1__I2SMICSP_RRBR1__SHIFT 0x0
+#define ACP_I2SMICSP_RER1__I2SMICSP_RXCHEN1_MASK 0x1
+#define ACP_I2SMICSP_RER1__I2SMICSP_RXCHEN1__SHIFT 0x0
+#define ACP_I2SMICSP_TER1__I2SMICSP_TXCHEN1_MASK 0x1
+#define ACP_I2SMICSP_TER1__I2SMICSP_TXCHEN1__SHIFT 0x0
+#define ACP_I2SMICSP_RCR1__I2SMICSP_WLEN_MASK 0x7
+#define ACP_I2SMICSP_RCR1__I2SMICSP_WLEN__SHIFT 0x0
+#define ACP_I2SMICSP_TCR1__I2SMICSP_WLEN_MASK 0x7
+#define ACP_I2SMICSP_TCR1__I2SMICSP_WLEN__SHIFT 0x0
+#define ACP_I2SMICSP_ISR1__I2SMICSP_RXDA_MASK 0x1
+#define ACP_I2SMICSP_ISR1__I2SMICSP_RXDA__SHIFT 0x0
+#define ACP_I2SMICSP_ISR1__I2SMICSP_RXFO_MASK 0x2
+#define ACP_I2SMICSP_ISR1__I2SMICSP_RXFO__SHIFT 0x1
+#define ACP_I2SMICSP_ISR1__I2SMICSP_TXFE_MASK 0x10
+#define ACP_I2SMICSP_ISR1__I2SMICSP_TXFE__SHIFT 0x4
+#define ACP_I2SMICSP_ISR1__I2SMICSP_TXFO_MASK 0x20
+#define ACP_I2SMICSP_ISR1__I2SMICSP_TXFO__SHIFT 0x5
+#define ACP_I2SMICSP_IMR1__I2SMICSP_RXDAM_MASK 0x1
+#define ACP_I2SMICSP_IMR1__I2SMICSP_RXDAM__SHIFT 0x0
+#define ACP_I2SMICSP_IMR1__I2SMICSP_RXFOM_MASK 0x2
+#define ACP_I2SMICSP_IMR1__I2SMICSP_RXFOM__SHIFT 0x1
+#define ACP_I2SMICSP_IMR1__I2SMICSP_TXFEM_MASK 0x10
+#define ACP_I2SMICSP_IMR1__I2SMICSP_TXFEM__SHIFT 0x4
+#define ACP_I2SMICSP_IMR1__I2SMICSP_TXFOM_MASK 0x20
+#define ACP_I2SMICSP_IMR1__I2SMICSP_TXFOM__SHIFT 0x5
+#define ACP_I2SMICSP_ROR1__I2SMICSP_RXCHO_MASK 0x1
+#define ACP_I2SMICSP_ROR1__I2SMICSP_RXCHO__SHIFT 0x0
+#define ACP_I2SMICSP_TOR1__I2SMICSP_TXCHO_MASK 0x1
+#define ACP_I2SMICSP_TOR1__I2SMICSP_TXCHO__SHIFT 0x0
+#define ACP_I2SMICSP_RFCR1__I2SMICSP_RXCHDT_MASK 0xf
+#define ACP_I2SMICSP_RFCR1__I2SMICSP_RXCHDT__SHIFT 0x0
+#define ACP_I2SMICSP_TFCR1__I2SMICSP_TXCHET_MASK 0xf
+#define ACP_I2SMICSP_TFCR1__I2SMICSP_TXCHET__SHIFT 0x0
+#define ACP_I2SMICSP_RFF1__I2SMICSP_RXCHFR_MASK 0x1
+#define ACP_I2SMICSP_RFF1__I2SMICSP_RXCHFR__SHIFT 0x0
+#define ACP_I2SMICSP_TFF1__I2SMICSP_TXCHFR_MASK 0x1
+#define ACP_I2SMICSP_TFF1__I2SMICSP_TXCHFR__SHIFT 0x0
+#define ACP_I2SMICSP_RXDMA__I2SMICSP_RXDMA_MASK 0xffffffff
+#define ACP_I2SMICSP_RXDMA__I2SMICSP_RXDMA__SHIFT 0x0
+#define ACP_I2SMICSP_RRXDMA__I2SMICSP_RRXDMA_MASK 0x1
+#define ACP_I2SMICSP_RRXDMA__I2SMICSP_RRXDMA__SHIFT 0x0
+#define ACP_I2SMICSP_TXDMA__I2SMICSP_TXDMA_MASK 0xffffffff
+#define ACP_I2SMICSP_TXDMA__I2SMICSP_TXDMA__SHIFT 0x0
+#define ACP_I2SMICSP_RTXDMA__I2SMICSP_RTXDMA_MASK 0x1
+#define ACP_I2SMICSP_RTXDMA__I2SMICSP_RTXDMA__SHIFT 0x0
+#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_0_MASK 0x7
+#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_0__SHIFT 0x0
+#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_1_MASK 0x38
+#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_1__SHIFT 0x3
+#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_2_MASK 0x380
+#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_2__SHIFT 0x7
+#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_3_MASK 0x1c00
+#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_3__SHIFT 0xa
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_APB_DATA_WIDTH_MASK 0x3
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_APB_DATA_WIDTH__SHIFT 0x0
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_FIFO_DEPTH_GLOBAL_MASK 0xc
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_FIFO_DEPTH_GLOBAL__SHIFT 0x2
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_MODE_EN_MASK 0x10
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_MODE_EN__SHIFT 0x4
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TRANSMITTER_BLOCK_MASK 0x20
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TRANSMITTER_BLOCK__SHIFT 0x5
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_RECEIVER_BLOCK_MASK 0x40
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_RECEIVER_BLOCK__SHIFT 0x6
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_RX_CHANNLES_MASK 0x180
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_RX_CHANNLES__SHIFT 0x7
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_CHANNLES_MASK 0x600
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_CHANNLES__SHIFT 0x9
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_0_MASK 0x70000
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_0__SHIFT 0x10
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_1_MASK 0x380000
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_1__SHIFT 0x13
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_2_MASK 0x1c00000
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_2__SHIFT 0x16
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_3_MASK 0xe000000
+#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_3__SHIFT 0x19
+#define ACP_I2SMICSP_COMP_VERSION__I2SMICSP_APB_DATA_WIDTH_MASK 0xffffffff
+#define ACP_I2SMICSP_COMP_VERSION__I2SMICSP_APB_DATA_WIDTH__SHIFT 0x0
+#define ACP_I2SMICSP_COMP_TYPE__I2SMICSP_COMP_TYPE_MASK 0xffffffff
+#define ACP_I2SMICSP_COMP_TYPE__I2SMICSP_COMP_TYPE__SHIFT 0x0
+#define ACP_I2SBT_IER__I2SBT_IEN_MASK 0x1
+#define ACP_I2SBT_IER__I2SBT_IEN__SHIFT 0x0
+#define ACP_I2SBT_IRER__I2SBT_RXEN_MASK 0x1
+#define ACP_I2SBT_IRER__I2SBT_RXEN__SHIFT 0x0
+#define ACP_I2SBT_ITER__I2SBT_TXEN_MASK 0x1
+#define ACP_I2SBT_ITER__I2SBT_TXEN__SHIFT 0x0
+#define ACP_I2SBT_CER__I2SBT_CLKEN_MASK 0x1
+#define ACP_I2SBT_CER__I2SBT_CLKEN__SHIFT 0x0
+#define ACP_I2SBT_CCR__I2SBT_SCLKG_MASK 0x7
+#define ACP_I2SBT_CCR__I2SBT_SCLKG__SHIFT 0x0
+#define ACP_I2SBT_CCR__I2SBT_WSS_MASK 0x18
+#define ACP_I2SBT_CCR__I2SBT_WSS__SHIFT 0x3
+#define ACP_I2SBT_RXFFR__I2SBT_RXFFR_MASK 0x1
+#define ACP_I2SBT_RXFFR__I2SBT_RXFFR__SHIFT 0x0
+#define ACP_I2SBT_TXFFR__I2SBT_TXFFR_MASK 0x1
+#define ACP_I2SBT_TXFFR__I2SBT_TXFFR__SHIFT 0x0
+#define ACP_I2SBT_LRBR0__I2SBT_LRBR0_MASK 0xffffffff
+#define ACP_I2SBT_LRBR0__I2SBT_LRBR0__SHIFT 0x0
+#define ACP_I2SBT_RRBR0__I2SBT_RRBR0_MASK 0xffffffff
+#define ACP_I2SBT_RRBR0__I2SBT_RRBR0__SHIFT 0x0
+#define ACP_I2SBT_RER0__I2SBT_RXCHEN0_MASK 0x1
+#define ACP_I2SBT_RER0__I2SBT_RXCHEN0__SHIFT 0x0
+#define ACP_I2SBT_TER0__I2SBT_TXCHEN0_MASK 0x1
+#define ACP_I2SBT_TER0__I2SBT_TXCHEN0__SHIFT 0x0
+#define ACP_I2SBT_RCR0__I2SBT_WLEN_MASK 0x7
+#define ACP_I2SBT_RCR0__I2SBT_WLEN__SHIFT 0x0
+#define ACP_I2SBT_TCR0__I2SBT_WLEN_MASK 0x7
+#define ACP_I2SBT_TCR0__I2SBT_WLEN__SHIFT 0x0
+#define ACP_I2SBT_ISR0__I2SBT_RXDA_MASK 0x1
+#define ACP_I2SBT_ISR0__I2SBT_RXDA__SHIFT 0x0
+#define ACP_I2SBT_ISR0__I2SBT_RXFO_MASK 0x2
+#define ACP_I2SBT_ISR0__I2SBT_RXFO__SHIFT 0x1
+#define ACP_I2SBT_ISR0__I2SBT_TXFE_MASK 0x10
+#define ACP_I2SBT_ISR0__I2SBT_TXFE__SHIFT 0x4
+#define ACP_I2SBT_ISR0__I2SBT_TXFO_MASK 0x20
+#define ACP_I2SBT_ISR0__I2SBT_TXFO__SHIFT 0x5
+#define ACP_I2SBT_IMR0__I2SBT_RXDAM_MASK 0x1
+#define ACP_I2SBT_IMR0__I2SBT_RXDAM__SHIFT 0x0
+#define ACP_I2SBT_IMR0__I2SBT_RXFOM_MASK 0x2
+#define ACP_I2SBT_IMR0__I2SBT_RXFOM__SHIFT 0x1
+#define ACP_I2SBT_IMR0__I2SBT_TXFEM_MASK 0x10
+#define ACP_I2SBT_IMR0__I2SBT_TXFEM__SHIFT 0x4
+#define ACP_I2SBT_IMR0__I2SBT_TXFOM_MASK 0x20
+#define ACP_I2SBT_IMR0__I2SBT_TXFOM__SHIFT 0x5
+#define ACP_I2SBT_ROR0__I2SBT_RXCHO_MASK 0x1
+#define ACP_I2SBT_ROR0__I2SBT_RXCHO__SHIFT 0x0
+#define ACP_I2SBT_TOR0__I2SBT_TXCHO_MASK 0x1
+#define ACP_I2SBT_TOR0__I2SBT_TXCHO__SHIFT 0x0
+#define ACP_I2SBT_RFCR0__I2SBT_RXCHDT_MASK 0xf
+#define ACP_I2SBT_RFCR0__I2SBT_RXCHDT__SHIFT 0x0
+#define ACP_I2SBT_TFCR0__I2SBT_TXCHET_MASK 0xf
+#define ACP_I2SBT_TFCR0__I2SBT_TXCHET__SHIFT 0x0
+#define ACP_I2SBT_RFF0__I2SBT_RXCHFR_MASK 0x1
+#define ACP_I2SBT_RFF0__I2SBT_RXCHFR__SHIFT 0x0
+#define ACP_I2SBT_TFF0__I2SBT_TXCHFR_MASK 0x1
+#define ACP_I2SBT_TFF0__I2SBT_TXCHFR__SHIFT 0x0
+#define ACP_I2SBT_LRBR1__I2SBT_LRBR1_MASK 0xffffffff
+#define ACP_I2SBT_LRBR1__I2SBT_LRBR1__SHIFT 0x0
+#define ACP_I2SBT_RRBR1__I2SBT_RRBR1_MASK 0xffffffff
+#define ACP_I2SBT_RRBR1__I2SBT_RRBR1__SHIFT 0x0
+#define ACP_I2SBT_RER1__I2SBT_RXCHEN1_MASK 0x1
+#define ACP_I2SBT_RER1__I2SBT_RXCHEN1__SHIFT 0x0
+#define ACP_I2SBT_TER1__I2SBT_TXCHEN1_MASK 0x1
+#define ACP_I2SBT_TER1__I2SBT_TXCHEN1__SHIFT 0x0
+#define ACP_I2SBT_RCR1__I2SBT_WLEN_MASK 0x7
+#define ACP_I2SBT_RCR1__I2SBT_WLEN__SHIFT 0x0
+#define ACP_I2SBT_TCR1__I2SBT_WLEN_MASK 0x7
+#define ACP_I2SBT_TCR1__I2SBT_WLEN__SHIFT 0x0
+#define ACP_I2SBT_ISR1__I2SBT_RXDA_MASK 0x1
+#define ACP_I2SBT_ISR1__I2SBT_RXDA__SHIFT 0x0
+#define ACP_I2SBT_ISR1__I2SBT_RXFO_MASK 0x2
+#define ACP_I2SBT_ISR1__I2SBT_RXFO__SHIFT 0x1
+#define ACP_I2SBT_ISR1__I2SBT_TXFE_MASK 0x10
+#define ACP_I2SBT_ISR1__I2SBT_TXFE__SHIFT 0x4
+#define ACP_I2SBT_ISR1__I2SBT_TXFO_MASK 0x20
+#define ACP_I2SBT_ISR1__I2SBT_TXFO__SHIFT 0x5
+#define ACP_I2SBT_IMR1__I2SBT_RXDAM_MASK 0x1
+#define ACP_I2SBT_IMR1__I2SBT_RXDAM__SHIFT 0x0
+#define ACP_I2SBT_IMR1__I2SBT_RXFOM_MASK 0x2
+#define ACP_I2SBT_IMR1__I2SBT_RXFOM__SHIFT 0x1
+#define ACP_I2SBT_IMR1__I2SBT_TXFEM_MASK 0x10
+#define ACP_I2SBT_IMR1__I2SBT_TXFEM__SHIFT 0x4
+#define ACP_I2SBT_IMR1__I2SBT_TXFOM_MASK 0x20
+#define ACP_I2SBT_IMR1__I2SBT_TXFOM__SHIFT 0x5
+#define ACP_I2SBT_ROR1__I2SBT_RXCHO_MASK 0x1
+#define ACP_I2SBT_ROR1__I2SBT_RXCHO__SHIFT 0x0
+#define ACP_I2SBT_TOR1__I2SBT_TXCHO_MASK 0x1
+#define ACP_I2SBT_TOR1__I2SBT_TXCHO__SHIFT 0x0
+#define ACP_I2SBT_RFCR1__I2SBT_RXCHDT_MASK 0xf
+#define ACP_I2SBT_RFCR1__I2SBT_RXCHDT__SHIFT 0x0
+#define ACP_I2SBT_TFCR1__I2SBT_TXCHET_MASK 0xf
+#define ACP_I2SBT_TFCR1__I2SBT_TXCHET__SHIFT 0x0
+#define ACP_I2SBT_RFF1__I2SBT_RXCHFR_MASK 0x1
+#define ACP_I2SBT_RFF1__I2SBT_RXCHFR__SHIFT 0x0
+#define ACP_I2SBT_TFF1__I2SBT_TXCHFR_MASK 0x1
+#define ACP_I2SBT_TFF1__I2SBT_TXCHFR__SHIFT 0x0
+#define ACP_I2SBT_RXDMA__I2SBT_RXDMA_MASK 0xffffffff
+#define ACP_I2SBT_RXDMA__I2SBT_RXDMA__SHIFT 0x0
+#define ACP_I2SBT_RRXDMA__I2SBT_RRXDMA_MASK 0x1
+#define ACP_I2SBT_RRXDMA__I2SBT_RRXDMA__SHIFT 0x0
+#define ACP_I2SBT_TXDMA__I2SBT_TXDMA_MASK 0xffffffff
+#define ACP_I2SBT_TXDMA__I2SBT_TXDMA__SHIFT 0x0
+#define ACP_I2SBT_RTXDMA__I2SBT_RTXDMA_MASK 0x1
+#define ACP_I2SBT_RTXDMA__I2SBT_RTXDMA__SHIFT 0x0
+#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_0_MASK 0x7
+#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_0__SHIFT 0x0
+#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_1_MASK 0x38
+#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_1__SHIFT 0x3
+#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_2_MASK 0x380
+#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_2__SHIFT 0x7
+#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_3_MASK 0x1c00
+#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_3__SHIFT 0xa
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_APB_DATA_WIDTH_MASK 0x3
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_APB_DATA_WIDTH__SHIFT 0x0
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_FIFO_DEPTH_GLOBAL_MASK 0xc
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_FIFO_DEPTH_GLOBAL__SHIFT 0x2
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_MODE_EN_MASK 0x10
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_MODE_EN__SHIFT 0x4
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TRANSMITTER_BLOCK_MASK 0x20
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TRANSMITTER_BLOCK__SHIFT 0x5
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_RECEIVER_BLOCK_MASK 0x40
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_RECEIVER_BLOCK__SHIFT 0x6
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_RX_CHANNLES_MASK 0x180
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_RX_CHANNLES__SHIFT 0x7
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_CHANNLES_MASK 0x600
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_CHANNLES__SHIFT 0x9
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_0_MASK 0x70000
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_0__SHIFT 0x10
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_1_MASK 0x380000
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_1__SHIFT 0x13
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_2_MASK 0x1c00000
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_2__SHIFT 0x16
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_3_MASK 0xe000000
+#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_3__SHIFT 0x19
+#define ACP_I2SBT_COMP_VERSION__I2SBT_APB_DATA_WIDTH_MASK 0xffffffff
+#define ACP_I2SBT_COMP_VERSION__I2SBT_APB_DATA_WIDTH__SHIFT 0x0
+#define ACP_I2SBT_COMP_TYPE__I2SBT_COMP_TYPE_MASK 0xffffffff
+#define ACP_I2SBT_COMP_TYPE__I2SBT_COMP_TYPE__SHIFT 0x0
+
+#endif /* ACP_2_2_SH_MASK_H */
diff --git a/sound/soc/amd/mach-config.h b/sound/soc/amd/mach-config.h
new file mode 100644
index 0000000000..d392e6d6e6
--- /dev/null
+++ b/sound/soc/amd/mach-config.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Author: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
+ */
+#ifndef __AMD_MACH_CONFIG_H
+#define __AMD_MACH_CONFIG_H
+
+#include <sound/soc-acpi.h>
+
+#define FLAG_AMD_SOF BIT(1)
+#define FLAG_AMD_SOF_ONLY_DMIC BIT(2)
+#define FLAG_AMD_LEGACY BIT(3)
+
+#define ACP_PCI_DEV_ID 0x15E2
+
+extern struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_amd_vangogh_sof_machines[];
+
+struct config_entry {
+ u32 flags;
+ u16 device;
+ const struct dmi_system_id *dmi_table;
+};
+
+#endif
diff --git a/sound/soc/amd/ps/Makefile b/sound/soc/amd/ps/Makefile
new file mode 100644
index 0000000000..f2a5eaf2fa
--- /dev/null
+++ b/sound/soc/amd/ps/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Pink Sardine platform Support
+snd-pci-ps-objs := pci-ps.o
+snd-ps-pdm-dma-objs := ps-pdm-dma.o
+snd-soc-ps-mach-objs := ps-mach.o
+snd-ps-sdw-dma-objs := ps-sdw-dma.o
+
+obj-$(CONFIG_SND_SOC_AMD_PS) += snd-pci-ps.o
+obj-$(CONFIG_SND_SOC_AMD_PS) += snd-ps-pdm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_PS) += snd-ps-sdw-dma.o
+obj-$(CONFIG_SND_SOC_AMD_PS_MACH) += snd-soc-ps-mach.o
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h
new file mode 100644
index 0000000000..8b853b8d02
--- /dev/null
+++ b/sound/soc/amd/ps/acp63.h
@@ -0,0 +1,290 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ALSA SoC PDM Driver
+ *
+ * Copyright (C) 2022, 2023 Advanced Micro Devices, Inc. All rights reserved.
+ */
+
+#include <sound/acp63_chip_offset_byte.h>
+
+#define ACP_DEVICE_ID 0x15E2
+#define ACP63_REG_START 0x1240000
+#define ACP63_REG_END 0x1250200
+#define ACP63_DEVS 5
+
+#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
+#define ACP_PGFSM_CNTL_POWER_ON_MASK 1
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0
+#define ACP_PGFSM_STATUS_MASK 3
+#define ACP_POWERED_ON 0
+#define ACP_POWER_ON_IN_PROGRESS 1
+#define ACP_POWERED_OFF 2
+#define ACP_POWER_OFF_IN_PROGRESS 3
+
+#define ACP_ERROR_MASK 0x20000000
+#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
+#define PDM_DMA_STAT 0x10
+
+#define PDM_DMA_INTR_MASK 0x10000
+#define ACP_ERROR_STAT 29
+#define PDM_DECIMATION_FACTOR 2
+#define ACP_PDM_CLK_FREQ_MASK 7
+#define ACP_WOV_GAIN_CONTROL GENMASK(4, 3)
+#define ACP_PDM_ENABLE 1
+#define ACP_PDM_DISABLE 0
+#define ACP_PDM_DMA_EN_STATUS 2
+#define TWO_CH 2
+#define DELAY_US 5
+#define ACP_COUNTER 20000
+
+#define ACP_SRAM_PTE_OFFSET 0x03800000
+#define PAGE_SIZE_4K_ENABLE 2
+#define PDM_PTE_OFFSET 0
+#define PDM_MEM_WINDOW_START 0x4000000
+
+#define CAPTURE_MIN_NUM_PERIODS 4
+#define CAPTURE_MAX_NUM_PERIODS 4
+#define CAPTURE_MAX_PERIOD_SIZE 8192
+#define CAPTURE_MIN_PERIOD_SIZE 4096
+
+#define MAX_BUFFER (CAPTURE_MAX_PERIOD_SIZE * CAPTURE_MAX_NUM_PERIODS)
+#define MIN_BUFFER MAX_BUFFER
+
+/* time in ms for runtime suspend delay */
+#define ACP_SUSPEND_DELAY_MS 2000
+
+#define ACP_DMIC_DEV 2
+
+/* ACP63_PDM_MODE_DEVS corresponds to platform devices count for ACP PDM configuration */
+#define ACP63_PDM_MODE_DEVS 3
+
+/*
+ * ACP63_SDW0_MODE_DEVS corresponds to platform devices count for
+ * SW0 SoundWire manager instance configuration
+ */
+#define ACP63_SDW0_MODE_DEVS 2
+
+/*
+ * ACP63_SDW0_SDW1_MODE_DEVS corresponds to platform devices count for SW0 + SW1 SoundWire manager
+ * instances configuration
+ */
+#define ACP63_SDW0_SDW1_MODE_DEVS 3
+
+/*
+ * ACP63_SDW0_PDM_MODE_DEVS corresponds to platform devices count for SW0 manager
+ * instance + ACP PDM controller configuration
+ */
+#define ACP63_SDW0_PDM_MODE_DEVS 4
+
+/*
+ * ACP63_SDW0_SDW1_PDM_MODE_DEVS corresponds to platform devices count for
+ * SW0 + SW1 SoundWire manager instances + ACP PDM controller configuration
+ */
+#define ACP63_SDW0_SDW1_PDM_MODE_DEVS 5
+#define ACP63_DMIC_ADDR 2
+#define ACP63_SDW_ADDR 5
+#define AMD_SDW_MAX_MANAGERS 2
+
+/* time in ms for acp timeout */
+#define ACP_TIMEOUT 500
+
+/* ACP63_PDM_DEV_CONFIG corresponds to platform device configuration for ACP PDM controller */
+#define ACP63_PDM_DEV_CONFIG BIT(0)
+
+/* ACP63_SDW_DEV_CONFIG corresponds to platform device configuration for SDW manager instances */
+#define ACP63_SDW_DEV_CONFIG BIT(1)
+
+/*
+ * ACP63_SDW_PDM_DEV_CONFIG corresponds to platform device configuration for ACP PDM + SoundWire
+ * manager instance combination.
+ */
+#define ACP63_SDW_PDM_DEV_CONFIG GENMASK(1, 0)
+#define ACP_SDW0_STAT BIT(21)
+#define ACP_SDW1_STAT BIT(2)
+#define ACP_ERROR_IRQ BIT(29)
+
+#define ACP_AUDIO0_TX_THRESHOLD 0x1c
+#define ACP_AUDIO1_TX_THRESHOLD 0x1a
+#define ACP_AUDIO2_TX_THRESHOLD 0x18
+#define ACP_AUDIO0_RX_THRESHOLD 0x1b
+#define ACP_AUDIO1_RX_THRESHOLD 0x19
+#define ACP_AUDIO2_RX_THRESHOLD 0x17
+#define ACP_P1_AUDIO1_TX_THRESHOLD BIT(6)
+#define ACP_P1_AUDIO1_RX_THRESHOLD BIT(5)
+#define ACP_SDW_DMA_IRQ_MASK 0x1F800000
+#define ACP_P1_SDW_DMA_IRQ_MASK 0x60
+#define ACP63_SDW0_DMA_MAX_STREAMS 6
+#define ACP63_SDW1_DMA_MAX_STREAMS 2
+#define ACP_P1_AUDIO_TX_THRESHOLD 6
+
+/*
+ * Below entries describes SDW0 instance DMA stream id and DMA irq bit mapping
+ * in ACP_EXTENAL_INTR_CNTL register.
+ * Stream id IRQ Bit
+ * 0 (SDW0_AUDIO0_TX) 28
+ * 1 (SDW0_AUDIO1_TX) 26
+ * 2 (SDW0_AUDIO2_TX) 24
+ * 3 (SDW0_AUDIO0_RX) 27
+ * 4 (SDW0_AUDIO1_RX) 25
+ * 5 (SDW0_AUDIO2_RX) 23
+ */
+#define SDW0_DMA_TX_IRQ_MASK(i) (ACP_AUDIO0_TX_THRESHOLD - (2 * (i)))
+#define SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3)))
+
+/*
+ * Below entries describes SDW1 instance DMA stream id and DMA irq bit mapping
+ * in ACP_EXTENAL_INTR_CNTL1 register.
+ * Stream id IRQ Bit
+ * 0 (SDW1_AUDIO1_TX) 6
+ * 1 (SDW1_AUDIO1_RX) 5
+ */
+#define SDW1_DMA_IRQ_MASK(i) (ACP_P1_AUDIO_TX_THRESHOLD - (i))
+
+#define ACP_DELAY_US 5
+#define ACP_SDW_RING_BUFF_ADDR_OFFSET (128 * 1024)
+#define SDW0_MEM_WINDOW_START 0x4800000
+#define ACP_SDW_SRAM_PTE_OFFSET 0x03800400
+#define SDW0_PTE_OFFSET 0x400
+#define SDW_FIFO_SIZE 0x100
+#define SDW_DMA_SIZE 0x40
+#define ACP_SDW0_FIFO_OFFSET 0x100
+#define ACP_SDW_PTE_OFFSET 0x100
+#define SDW_FIFO_OFFSET 0x100
+#define SDW_PTE_OFFSET(i) (SDW0_PTE_OFFSET + ((i) * 0x600))
+#define ACP_SDW_FIFO_OFFSET(i) (ACP_SDW0_FIFO_OFFSET + ((i) * 0x500))
+#define SDW_MEM_WINDOW_START(i) (SDW0_MEM_WINDOW_START + ((i) * 0xC0000))
+
+#define SDW_PLAYBACK_MIN_NUM_PERIODS 2
+#define SDW_PLAYBACK_MAX_NUM_PERIODS 8
+#define SDW_PLAYBACK_MAX_PERIOD_SIZE 8192
+#define SDW_PLAYBACK_MIN_PERIOD_SIZE 1024
+#define SDW_CAPTURE_MIN_NUM_PERIODS 2
+#define SDW_CAPTURE_MAX_NUM_PERIODS 8
+#define SDW_CAPTURE_MAX_PERIOD_SIZE 8192
+#define SDW_CAPTURE_MIN_PERIOD_SIZE 1024
+
+#define SDW_MAX_BUFFER (SDW_PLAYBACK_MAX_PERIOD_SIZE * SDW_PLAYBACK_MAX_NUM_PERIODS)
+#define SDW_MIN_BUFFER SDW_MAX_BUFFER
+
+enum acp_config {
+ ACP_CONFIG_0 = 0,
+ ACP_CONFIG_1,
+ ACP_CONFIG_2,
+ ACP_CONFIG_3,
+ ACP_CONFIG_4,
+ ACP_CONFIG_5,
+ ACP_CONFIG_6,
+ ACP_CONFIG_7,
+ ACP_CONFIG_8,
+ ACP_CONFIG_9,
+ ACP_CONFIG_10,
+ ACP_CONFIG_11,
+ ACP_CONFIG_12,
+ ACP_CONFIG_13,
+ ACP_CONFIG_14,
+ ACP_CONFIG_15,
+};
+
+enum amd_sdw0_channel {
+ ACP_SDW0_AUDIO0_TX = 0,
+ ACP_SDW0_AUDIO1_TX,
+ ACP_SDW0_AUDIO2_TX,
+ ACP_SDW0_AUDIO0_RX,
+ ACP_SDW0_AUDIO1_RX,
+ ACP_SDW0_AUDIO2_RX,
+};
+
+enum amd_sdw1_channel {
+ ACP_SDW1_AUDIO1_TX,
+ ACP_SDW1_AUDIO1_RX,
+};
+
+struct pdm_stream_instance {
+ u16 num_pages;
+ u16 channels;
+ dma_addr_t dma_addr;
+ u64 bytescount;
+ void __iomem *acp63_base;
+};
+
+struct pdm_dev_data {
+ u32 pdm_irq;
+ void __iomem *acp63_base;
+ struct mutex *acp_lock;
+ struct snd_pcm_substream *capture_stream;
+};
+
+struct sdw_dma_dev_data {
+ void __iomem *acp_base;
+ struct mutex *acp_lock; /* used to protect acp common register access */
+ struct snd_pcm_substream *sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS];
+ struct snd_pcm_substream *sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS];
+};
+
+struct acp_sdw_dma_stream {
+ u16 num_pages;
+ u16 channels;
+ u32 stream_id;
+ u32 instance;
+ dma_addr_t dma_addr;
+ u64 bytescount;
+};
+
+union acp_sdw_dma_count {
+ struct {
+ u32 low;
+ u32 high;
+ } bcount;
+ u64 bytescount;
+};
+
+struct sdw_dma_ring_buf_reg {
+ u32 reg_dma_size;
+ u32 reg_fifo_addr;
+ u32 reg_fifo_size;
+ u32 reg_ring_buf_size;
+ u32 reg_ring_buf_addr;
+ u32 water_mark_size_reg;
+ u32 pos_low_reg;
+ u32 pos_high_reg;
+};
+
+/**
+ * struct acp63_dev_data - acp pci driver context
+ * @acp63_base: acp mmio base
+ * @res: resource
+ * @pdev: array of child platform device node structures
+ * @acp_lock: used to protect acp common registers
+ * @sdw_fw_node: SoundWire controller fw node handle
+ * @pdev_config: platform device configuration
+ * @pdev_count: platform devices count
+ * @pdm_dev_index: pdm platform device index
+ * @sdw_manager_count: SoundWire manager instance count
+ * @sdw0_dev_index: SoundWire Manager-0 platform device index
+ * @sdw1_dev_index: SoundWire Manager-1 platform device index
+ * @sdw_dma_dev_index: SoundWire DMA controller platform device index
+ * @sdw0-dma_intr_stat: DMA interrupt status array for SoundWire manager-SW0 instance
+ * @sdw_dma_intr_stat: DMA interrupt status array for SoundWire manager-SW1 instance
+ * @acp_reset: flag set to true when bus reset is applied across all
+ * the active SoundWire manager instances
+ */
+
+struct acp63_dev_data {
+ void __iomem *acp63_base;
+ struct resource *res;
+ struct platform_device *pdev[ACP63_DEVS];
+ struct mutex acp_lock; /* protect shared registers */
+ struct fwnode_handle *sdw_fw_node;
+ u16 pdev_config;
+ u16 pdev_count;
+ u16 pdm_dev_index;
+ u8 sdw_manager_count;
+ u16 sdw0_dev_index;
+ u16 sdw1_dev_index;
+ u16 sdw_dma_dev_index;
+ u16 sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS];
+ u16 sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS];
+ bool acp_reset;
+};
+
+int snd_amd_acp_find_config(struct pci_dev *pci);
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
new file mode 100644
index 0000000000..4af3c36653
--- /dev/null
+++ b/sound/soc/amd/ps/pci-ps.c
@@ -0,0 +1,742 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * AMD Pink Sardine ACP PCI Driver
+ *
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
+#include <linux/interrupt.h>
+#include <sound/pcm_params.h>
+#include <linux/pm_runtime.h>
+#include <linux/iopoll.h>
+#include <linux/soundwire/sdw_amd.h>
+
+#include "acp63.h"
+
+static int acp63_power_on(void __iomem *acp_base)
+{
+ u32 val;
+
+ val = readl(acp_base + ACP_PGFSM_STATUS);
+
+ if (!val)
+ return val;
+
+ if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS)
+ writel(ACP_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL);
+
+ return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP_TIMEOUT);
+}
+
+static int acp63_reset(void __iomem *acp_base)
+{
+ u32 val;
+ int ret;
+
+ writel(1, acp_base + ACP_SOFT_RESET);
+
+ ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val,
+ val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK,
+ DELAY_US, ACP_TIMEOUT);
+ if (ret)
+ return ret;
+
+ writel(0, acp_base + ACP_SOFT_RESET);
+
+ return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT);
+}
+
+static void acp63_enable_interrupts(void __iomem *acp_base)
+{
+ writel(1, acp_base + ACP_EXTERNAL_INTR_ENB);
+ writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static void acp63_disable_interrupts(void __iomem *acp_base)
+{
+ writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT);
+ writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL);
+ writel(0, acp_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static int acp63_init(void __iomem *acp_base, struct device *dev)
+{
+ int ret;
+
+ ret = acp63_power_on(acp_base);
+ if (ret) {
+ dev_err(dev, "ACP power on failed\n");
+ return ret;
+ }
+ writel(0x01, acp_base + ACP_CONTROL);
+ ret = acp63_reset(acp_base);
+ if (ret) {
+ dev_err(dev, "ACP reset failed\n");
+ return ret;
+ }
+ acp63_enable_interrupts(acp_base);
+ return 0;
+}
+
+static int acp63_deinit(void __iomem *acp_base, struct device *dev)
+{
+ int ret;
+
+ acp63_disable_interrupts(acp_base);
+ ret = acp63_reset(acp_base);
+ if (ret) {
+ dev_err(dev, "ACP reset failed\n");
+ return ret;
+ }
+ writel(0, acp_base + ACP_CONTROL);
+ return 0;
+}
+
+static irqreturn_t acp63_irq_thread(int irq, void *context)
+{
+ struct sdw_dma_dev_data *sdw_dma_data;
+ struct acp63_dev_data *adata = context;
+ u32 stream_index;
+ u16 pdev_index;
+
+ pdev_index = adata->sdw_dma_dev_index;
+ sdw_dma_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
+
+ for (stream_index = 0; stream_index < ACP63_SDW0_DMA_MAX_STREAMS; stream_index++) {
+ if (adata->sdw0_dma_intr_stat[stream_index]) {
+ if (sdw_dma_data->sdw0_dma_stream[stream_index])
+ snd_pcm_period_elapsed(sdw_dma_data->sdw0_dma_stream[stream_index]);
+ adata->sdw0_dma_intr_stat[stream_index] = 0;
+ }
+ }
+ for (stream_index = 0; stream_index < ACP63_SDW1_DMA_MAX_STREAMS; stream_index++) {
+ if (adata->sdw1_dma_intr_stat[stream_index]) {
+ if (sdw_dma_data->sdw1_dma_stream[stream_index])
+ snd_pcm_period_elapsed(sdw_dma_data->sdw1_dma_stream[stream_index]);
+ adata->sdw1_dma_intr_stat[stream_index] = 0;
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
+{
+ struct acp63_dev_data *adata;
+ struct pdm_dev_data *ps_pdm_data;
+ struct amd_sdw_manager *amd_manager;
+ u32 ext_intr_stat, ext_intr_stat1;
+ u32 stream_id = 0;
+ u16 irq_flag = 0;
+ u16 sdw_dma_irq_flag = 0;
+ u16 pdev_index;
+ u16 index;
+
+ adata = dev_id;
+ if (!adata)
+ return IRQ_NONE;
+ /* ACP interrupts will be cleared by reading particular bit and writing
+ * same value to the status register. writing zero's doesn't have any
+ * effect.
+ * Bit by bit checking of IRQ field is implemented.
+ */
+ ext_intr_stat = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
+ if (ext_intr_stat & ACP_SDW0_STAT) {
+ writel(ACP_SDW0_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
+ pdev_index = adata->sdw0_dev_index;
+ amd_manager = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
+ if (amd_manager)
+ schedule_work(&amd_manager->amd_sdw_irq_thread);
+ irq_flag = 1;
+ }
+
+ ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+ if (ext_intr_stat1 & ACP_SDW1_STAT) {
+ writel(ACP_SDW1_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+ pdev_index = adata->sdw1_dev_index;
+ amd_manager = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
+ if (amd_manager)
+ schedule_work(&amd_manager->amd_sdw_irq_thread);
+ irq_flag = 1;
+ }
+
+ if (ext_intr_stat & ACP_ERROR_IRQ) {
+ writel(ACP_ERROR_IRQ, adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
+ /* TODO: Report SoundWire Manager instance errors */
+ writel(0, adata->acp63_base + ACP_SW0_I2S_ERROR_REASON);
+ writel(0, adata->acp63_base + ACP_SW1_I2S_ERROR_REASON);
+ writel(0, adata->acp63_base + ACP_ERROR_STATUS);
+ irq_flag = 1;
+ }
+
+ if (ext_intr_stat & BIT(PDM_DMA_STAT)) {
+ pdev_index = adata->pdm_dev_index;
+ ps_pdm_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
+ writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
+ if (ps_pdm_data->capture_stream)
+ snd_pcm_period_elapsed(ps_pdm_data->capture_stream);
+ irq_flag = 1;
+ }
+ if (ext_intr_stat & ACP_SDW_DMA_IRQ_MASK) {
+ for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) {
+ if (ext_intr_stat & BIT(index)) {
+ writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
+ switch (index) {
+ case ACP_AUDIO0_TX_THRESHOLD:
+ stream_id = ACP_SDW0_AUDIO0_TX;
+ break;
+ case ACP_AUDIO1_TX_THRESHOLD:
+ stream_id = ACP_SDW0_AUDIO1_TX;
+ break;
+ case ACP_AUDIO2_TX_THRESHOLD:
+ stream_id = ACP_SDW0_AUDIO2_TX;
+ break;
+ case ACP_AUDIO0_RX_THRESHOLD:
+ stream_id = ACP_SDW0_AUDIO0_RX;
+ break;
+ case ACP_AUDIO1_RX_THRESHOLD:
+ stream_id = ACP_SDW0_AUDIO1_RX;
+ break;
+ case ACP_AUDIO2_RX_THRESHOLD:
+ stream_id = ACP_SDW0_AUDIO2_RX;
+ break;
+ }
+
+ adata->sdw0_dma_intr_stat[stream_id] = 1;
+ sdw_dma_irq_flag = 1;
+ }
+ }
+ }
+
+ if (ext_intr_stat1 & ACP_P1_AUDIO1_RX_THRESHOLD) {
+ writel(ACP_P1_AUDIO1_RX_THRESHOLD,
+ adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+ adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_RX] = 1;
+ sdw_dma_irq_flag = 1;
+ }
+
+ if (ext_intr_stat1 & ACP_P1_AUDIO1_TX_THRESHOLD) {
+ writel(ACP_P1_AUDIO1_TX_THRESHOLD,
+ adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+ adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_TX] = 1;
+ sdw_dma_irq_flag = 1;
+ }
+
+ if (sdw_dma_irq_flag)
+ return IRQ_WAKE_THREAD;
+
+ if (irq_flag)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static int sdw_amd_scan_controller(struct device *dev)
+{
+ struct acp63_dev_data *acp_data;
+ struct fwnode_handle *link;
+ char name[32];
+ u32 sdw_manager_bitmap;
+ u8 count = 0;
+ u32 acp_sdw_power_mode = 0;
+ int index;
+ int ret;
+
+ acp_data = dev_get_drvdata(dev);
+ /*
+ * Current implementation is based on MIPI DisCo 2.0 spec.
+ * Found controller, find links supported.
+ */
+ ret = fwnode_property_read_u32_array((acp_data->sdw_fw_node), "mipi-sdw-manager-list",
+ &sdw_manager_bitmap, 1);
+
+ if (ret) {
+ dev_dbg(dev, "Failed to read mipi-sdw-manager-list: %d\n", ret);
+ return -EINVAL;
+ }
+ count = hweight32(sdw_manager_bitmap);
+ /* Check count is within bounds */
+ if (count > AMD_SDW_MAX_MANAGERS) {
+ dev_err(dev, "Manager count %d exceeds max %d\n", count, AMD_SDW_MAX_MANAGERS);
+ return -EINVAL;
+ }
+
+ if (!count) {
+ dev_dbg(dev, "No SoundWire Managers detected\n");
+ return -EINVAL;
+ }
+ dev_dbg(dev, "ACPI reports %d SoundWire Manager devices\n", count);
+ acp_data->sdw_manager_count = count;
+ for (index = 0; index < count; index++) {
+ snprintf(name, sizeof(name), "mipi-sdw-link-%d-subproperties", index);
+ link = fwnode_get_named_child_node(acp_data->sdw_fw_node, name);
+ if (!link) {
+ dev_err(dev, "Manager node %s not found\n", name);
+ return -EIO;
+ }
+
+ ret = fwnode_property_read_u32(link, "amd-sdw-power-mode", &acp_sdw_power_mode);
+ if (ret)
+ return ret;
+ /*
+ * when SoundWire configuration is selected from acp pin config,
+ * based on manager instances count, acp init/de-init sequence should be
+ * executed as part of PM ops only when Bus reset is applied for the active
+ * SoundWire manager instances.
+ */
+ if (acp_sdw_power_mode != AMD_SDW_POWER_OFF_MODE) {
+ acp_data->acp_reset = false;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static int get_acp63_device_config(u32 config, struct pci_dev *pci, struct acp63_dev_data *acp_data)
+{
+ struct acpi_device *dmic_dev;
+ struct acpi_device *sdw_dev;
+ const union acpi_object *obj;
+ bool is_dmic_dev = false;
+ bool is_sdw_dev = false;
+ int ret;
+
+ dmic_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0);
+ if (dmic_dev) {
+ /* is_dmic_dev flag will be set when ACP PDM controller device exists */
+ if (!acpi_dev_get_property(dmic_dev, "acp-audio-device-type",
+ ACPI_TYPE_INTEGER, &obj) &&
+ obj->integer.value == ACP_DMIC_DEV)
+ is_dmic_dev = true;
+ }
+
+ sdw_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_SDW_ADDR, 0);
+ if (sdw_dev) {
+ acp_data->sdw_fw_node = acpi_fwnode_handle(sdw_dev);
+ ret = sdw_amd_scan_controller(&pci->dev);
+ /* is_sdw_dev flag will be set when SoundWire Manager device exists */
+ if (!ret)
+ is_sdw_dev = true;
+ }
+ if (!is_dmic_dev && !is_sdw_dev)
+ return -ENODEV;
+ dev_dbg(&pci->dev, "Audio Mode %d\n", config);
+ switch (config) {
+ case ACP_CONFIG_4:
+ case ACP_CONFIG_5:
+ case ACP_CONFIG_10:
+ case ACP_CONFIG_11:
+ if (is_dmic_dev) {
+ acp_data->pdev_config = ACP63_PDM_DEV_CONFIG;
+ acp_data->pdev_count = ACP63_PDM_MODE_DEVS;
+ }
+ break;
+ case ACP_CONFIG_2:
+ case ACP_CONFIG_3:
+ if (is_sdw_dev) {
+ switch (acp_data->sdw_manager_count) {
+ case 1:
+ acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
+ acp_data->pdev_count = ACP63_SDW0_MODE_DEVS;
+ break;
+ case 2:
+ acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
+ acp_data->pdev_count = ACP63_SDW0_SDW1_MODE_DEVS;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ break;
+ case ACP_CONFIG_6:
+ case ACP_CONFIG_7:
+ case ACP_CONFIG_12:
+ case ACP_CONFIG_8:
+ case ACP_CONFIG_13:
+ case ACP_CONFIG_14:
+ if (is_dmic_dev && is_sdw_dev) {
+ switch (acp_data->sdw_manager_count) {
+ case 1:
+ acp_data->pdev_config = ACP63_SDW_PDM_DEV_CONFIG;
+ acp_data->pdev_count = ACP63_SDW0_PDM_MODE_DEVS;
+ break;
+ case 2:
+ acp_data->pdev_config = ACP63_SDW_PDM_DEV_CONFIG;
+ acp_data->pdev_count = ACP63_SDW0_SDW1_PDM_MODE_DEVS;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (is_dmic_dev) {
+ acp_data->pdev_config = ACP63_PDM_DEV_CONFIG;
+ acp_data->pdev_count = ACP63_PDM_MODE_DEVS;
+ } else if (is_sdw_dev) {
+ switch (acp_data->sdw_manager_count) {
+ case 1:
+ acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
+ acp_data->pdev_count = ACP63_SDW0_MODE_DEVS;
+ break;
+ case 2:
+ acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
+ acp_data->pdev_count = ACP63_SDW0_SDW1_MODE_DEVS;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static void acp63_fill_platform_dev_info(struct platform_device_info *pdevinfo,
+ struct device *parent,
+ struct fwnode_handle *fw_node,
+ char *name, unsigned int id,
+ const struct resource *res,
+ unsigned int num_res,
+ const void *data,
+ size_t size_data)
+{
+ pdevinfo->name = name;
+ pdevinfo->id = id;
+ pdevinfo->parent = parent;
+ pdevinfo->num_res = num_res;
+ pdevinfo->res = res;
+ pdevinfo->data = data;
+ pdevinfo->size_data = size_data;
+ pdevinfo->fwnode = fw_node;
+}
+
+static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data *adata, u32 addr)
+{
+ struct acp_sdw_pdata *sdw_pdata;
+ struct platform_device_info pdevinfo[ACP63_DEVS];
+ struct device *parent;
+ int index;
+ int ret;
+
+ parent = &pci->dev;
+ dev_dbg(&pci->dev,
+ "%s pdev_config:0x%x pdev_count:0x%x\n", __func__, adata->pdev_config,
+ adata->pdev_count);
+ if (adata->pdev_config) {
+ adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL);
+ if (!adata->res) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+ adata->res->flags = IORESOURCE_MEM;
+ adata->res->start = addr;
+ adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START);
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ }
+
+ switch (adata->pdev_config) {
+ case ACP63_PDM_DEV_CONFIG:
+ adata->pdm_dev_index = 0;
+ acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma",
+ 0, adata->res, 1, NULL, 0);
+ acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "dmic-codec",
+ 0, NULL, 0, NULL, 0);
+ acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "acp_ps_mach",
+ 0, NULL, 0, NULL, 0);
+ break;
+ case ACP63_SDW_DEV_CONFIG:
+ if (adata->pdev_count == ACP63_SDW0_MODE_DEVS) {
+ sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata),
+ GFP_KERNEL);
+ if (!sdw_pdata) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+
+ sdw_pdata->instance = 0;
+ sdw_pdata->acp_sdw_lock = &adata->acp_lock;
+ adata->sdw0_dev_index = 0;
+ adata->sdw_dma_dev_index = 1;
+ acp63_fill_platform_dev_info(&pdevinfo[0], parent, adata->sdw_fw_node,
+ "amd_sdw_manager", 0, adata->res, 1,
+ sdw_pdata, sizeof(struct acp_sdw_pdata));
+ acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "amd_ps_sdw_dma",
+ 0, adata->res, 1, NULL, 0);
+ } else if (adata->pdev_count == ACP63_SDW0_SDW1_MODE_DEVS) {
+ sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata) * 2,
+ GFP_KERNEL);
+ if (!sdw_pdata) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+
+ sdw_pdata[0].instance = 0;
+ sdw_pdata[1].instance = 1;
+ sdw_pdata[0].acp_sdw_lock = &adata->acp_lock;
+ sdw_pdata[1].acp_sdw_lock = &adata->acp_lock;
+ sdw_pdata->acp_sdw_lock = &adata->acp_lock;
+ adata->sdw0_dev_index = 0;
+ adata->sdw1_dev_index = 1;
+ adata->sdw_dma_dev_index = 2;
+ acp63_fill_platform_dev_info(&pdevinfo[0], parent, adata->sdw_fw_node,
+ "amd_sdw_manager", 0, adata->res, 1,
+ &sdw_pdata[0], sizeof(struct acp_sdw_pdata));
+ acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node,
+ "amd_sdw_manager", 1, adata->res, 1,
+ &sdw_pdata[1], sizeof(struct acp_sdw_pdata));
+ acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "amd_ps_sdw_dma",
+ 0, adata->res, 1, NULL, 0);
+ }
+ break;
+ case ACP63_SDW_PDM_DEV_CONFIG:
+ if (adata->pdev_count == ACP63_SDW0_PDM_MODE_DEVS) {
+ sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata),
+ GFP_KERNEL);
+ if (!sdw_pdata) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+
+ sdw_pdata->instance = 0;
+ sdw_pdata->acp_sdw_lock = &adata->acp_lock;
+ adata->pdm_dev_index = 0;
+ adata->sdw0_dev_index = 1;
+ adata->sdw_dma_dev_index = 2;
+ acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma",
+ 0, adata->res, 1, NULL, 0);
+ acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node,
+ "amd_sdw_manager", 0, adata->res, 1,
+ sdw_pdata, sizeof(struct acp_sdw_pdata));
+ acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "amd_ps_sdw_dma",
+ 0, adata->res, 1, NULL, 0);
+ acp63_fill_platform_dev_info(&pdevinfo[3], parent, NULL, "dmic-codec",
+ 0, NULL, 0, NULL, 0);
+ } else if (adata->pdev_count == ACP63_SDW0_SDW1_PDM_MODE_DEVS) {
+ sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata) * 2,
+ GFP_KERNEL);
+ if (!sdw_pdata) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+ sdw_pdata[0].instance = 0;
+ sdw_pdata[1].instance = 1;
+ sdw_pdata[0].acp_sdw_lock = &adata->acp_lock;
+ sdw_pdata[1].acp_sdw_lock = &adata->acp_lock;
+ adata->pdm_dev_index = 0;
+ adata->sdw0_dev_index = 1;
+ adata->sdw1_dev_index = 2;
+ adata->sdw_dma_dev_index = 3;
+ acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma",
+ 0, adata->res, 1, NULL, 0);
+ acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node,
+ "amd_sdw_manager", 0, adata->res, 1,
+ &sdw_pdata[0], sizeof(struct acp_sdw_pdata));
+ acp63_fill_platform_dev_info(&pdevinfo[2], parent, adata->sdw_fw_node,
+ "amd_sdw_manager", 1, adata->res, 1,
+ &sdw_pdata[1], sizeof(struct acp_sdw_pdata));
+ acp63_fill_platform_dev_info(&pdevinfo[3], parent, NULL, "amd_ps_sdw_dma",
+ 0, adata->res, 1, NULL, 0);
+ acp63_fill_platform_dev_info(&pdevinfo[4], parent, NULL, "dmic-codec",
+ 0, NULL, 0, NULL, 0);
+ }
+ break;
+ default:
+ dev_dbg(&pci->dev, "No PDM or SoundWire manager devices found\n");
+ return 0;
+ }
+
+ for (index = 0; index < adata->pdev_count; index++) {
+ adata->pdev[index] = platform_device_register_full(&pdevinfo[index]);
+ if (IS_ERR(adata->pdev[index])) {
+ dev_err(&pci->dev,
+ "cannot register %s device\n", pdevinfo[index].name);
+ ret = PTR_ERR(adata->pdev[index]);
+ goto unregister_devs;
+ }
+ }
+ return 0;
+unregister_devs:
+ for (--index; index >= 0; index--)
+ platform_device_unregister(adata->pdev[index]);
+de_init:
+ if (acp63_deinit(adata->acp63_base, &pci->dev))
+ dev_err(&pci->dev, "ACP de-init failed\n");
+ return ret;
+}
+
+static int snd_acp63_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ struct acp63_dev_data *adata;
+ u32 addr;
+ u32 irqflags, flag;
+ int val;
+ int ret;
+
+ irqflags = IRQF_SHARED;
+
+ /* Return if acp config flag is defined */
+ flag = snd_amd_acp_find_config(pci);
+ if (flag)
+ return -ENODEV;
+
+ /* Pink Sardine device check */
+ switch (pci->revision) {
+ case 0x63:
+ break;
+ default:
+ dev_dbg(&pci->dev, "acp63 pci device not found\n");
+ return -ENODEV;
+ }
+ if (pci_enable_device(pci)) {
+ dev_err(&pci->dev, "pci_enable_device failed\n");
+ return -ENODEV;
+ }
+
+ ret = pci_request_regions(pci, "AMD ACP6.2 audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+ }
+ adata = devm_kzalloc(&pci->dev, sizeof(struct acp63_dev_data),
+ GFP_KERNEL);
+ if (!adata) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+
+ addr = pci_resource_start(pci, 0);
+ adata->acp63_base = devm_ioremap(&pci->dev, addr,
+ pci_resource_len(pci, 0));
+ if (!adata->acp63_base) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+ /*
+ * By default acp_reset flag is set to true. i.e acp_deinit() and acp_init()
+ * will be invoked for all ACP configurations during suspend/resume callbacks.
+ * This flag should be set to false only when SoundWire manager power mode
+ * set to ClockStopMode.
+ */
+ adata->acp_reset = true;
+ pci_set_master(pci);
+ pci_set_drvdata(pci, adata);
+ mutex_init(&adata->acp_lock);
+ ret = acp63_init(adata->acp63_base, &pci->dev);
+ if (ret)
+ goto release_regions;
+ ret = devm_request_threaded_irq(&pci->dev, pci->irq, acp63_irq_handler,
+ acp63_irq_thread, irqflags, "ACP_PCI_IRQ", adata);
+ if (ret) {
+ dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
+ goto de_init;
+ }
+ val = readl(adata->acp63_base + ACP_PIN_CONFIG);
+ ret = get_acp63_device_config(val, pci, adata);
+ /* ACP PCI driver probe should be continued even PDM or SoundWire Devices are not found */
+ if (ret) {
+ dev_dbg(&pci->dev, "get acp device config failed:%d\n", ret);
+ goto skip_pdev_creation;
+ }
+ ret = create_acp63_platform_devs(pci, adata, addr);
+ if (ret < 0) {
+ dev_err(&pci->dev, "ACP platform devices creation failed\n");
+ goto de_init;
+ }
+skip_pdev_creation:
+ pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_put_noidle(&pci->dev);
+ pm_runtime_allow(&pci->dev);
+ return 0;
+de_init:
+ if (acp63_deinit(adata->acp63_base, &pci->dev))
+ dev_err(&pci->dev, "ACP de-init failed\n");
+release_regions:
+ pci_release_regions(pci);
+disable_pci:
+ pci_disable_device(pci);
+
+ return ret;
+}
+
+static int __maybe_unused snd_acp63_suspend(struct device *dev)
+{
+ struct acp63_dev_data *adata;
+ int ret = 0;
+
+ adata = dev_get_drvdata(dev);
+ if (adata->acp_reset) {
+ ret = acp63_deinit(adata->acp63_base, dev);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+ }
+ return ret;
+}
+
+static int __maybe_unused snd_acp63_resume(struct device *dev)
+{
+ struct acp63_dev_data *adata;
+ int ret = 0;
+
+ adata = dev_get_drvdata(dev);
+ if (adata->acp_reset) {
+ ret = acp63_init(adata->acp63_base, dev);
+ if (ret)
+ dev_err(dev, "ACP init failed\n");
+ }
+ return ret;
+}
+
+static const struct dev_pm_ops acp63_pm_ops = {
+ SET_RUNTIME_PM_OPS(snd_acp63_suspend, snd_acp63_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(snd_acp63_suspend, snd_acp63_resume)
+};
+
+static void snd_acp63_remove(struct pci_dev *pci)
+{
+ struct acp63_dev_data *adata;
+ int ret, index;
+
+ adata = pci_get_drvdata(pci);
+ for (index = 0; index < adata->pdev_count; index++)
+ platform_device_unregister(adata->pdev[index]);
+ ret = acp63_deinit(adata->acp63_base, &pci->dev);
+ if (ret)
+ dev_err(&pci->dev, "ACP de-init failed\n");
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_get_noresume(&pci->dev);
+ pci_release_regions(pci);
+ pci_disable_device(pci);
+}
+
+static const struct pci_device_id snd_acp63_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
+ .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
+ .class_mask = 0xffffff },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_acp63_ids);
+
+static struct pci_driver ps_acp63_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = snd_acp63_ids,
+ .probe = snd_acp63_probe,
+ .remove = snd_acp63_remove,
+ .driver = {
+ .pm = &acp63_pm_ops,
+ }
+};
+
+module_pci_driver(ps_acp63_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_AUTHOR("Syed.SabaKareem@amd.com");
+MODULE_DESCRIPTION("AMD ACP Pink Sardine PCI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/ps/ps-mach.c b/sound/soc/amd/ps/ps-mach.c
new file mode 100644
index 0000000000..3ffbe4fdaf
--- /dev/null
+++ b/sound/soc/amd/ps/ps-mach.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Machine driver for AMD Pink Sardine platform using DMIC
+ *
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ */
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/module.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <linux/io.h>
+#include <linux/dmi.h>
+
+#include "acp63.h"
+
+#define DRV_NAME "acp_ps_mach"
+
+SND_SOC_DAILINK_DEF(acp63_pdm,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp_ps_pdm_dma.0")));
+
+SND_SOC_DAILINK_DEF(dmic_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec.0",
+ "dmic-hifi")));
+
+SND_SOC_DAILINK_DEF(pdm_platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_ps_pdm_dma.0")));
+
+static struct snd_soc_dai_link acp63_dai_pdm[] = {
+ {
+ .name = "acp63-dmic-capture",
+ .stream_name = "DMIC capture",
+ .capture_only = 1,
+ SND_SOC_DAILINK_REG(acp63_pdm, dmic_codec, pdm_platform),
+ },
+};
+
+static struct snd_soc_card acp63_card = {
+ .name = "acp63",
+ .owner = THIS_MODULE,
+ .dai_link = acp63_dai_pdm,
+ .num_links = 1,
+};
+
+static int acp63_probe(struct platform_device *pdev)
+{
+ struct acp63_pdm *machine = NULL;
+ struct snd_soc_card *card;
+ int ret;
+
+ platform_set_drvdata(pdev, &acp63_card);
+ card = platform_get_drvdata(pdev);
+ acp63_card.dev = &pdev->dev;
+
+ snd_soc_card_set_drvdata(card, machine);
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret) {
+ return dev_err_probe(&pdev->dev, ret,
+ "snd_soc_register_card(%s) failed\n",
+ card->name);
+ }
+
+ return 0;
+}
+
+static struct platform_driver acp63_mach_driver = {
+ .driver = {
+ .name = "acp_ps_mach",
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = acp63_probe,
+};
+
+module_platform_driver(acp63_mach_driver);
+
+MODULE_AUTHOR("Syed.SabaKareem@amd.com");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/ps/ps-pdm-dma.c b/sound/soc/amd/ps/ps-pdm-dma.c
new file mode 100644
index 0000000000..d48f7c5af2
--- /dev/null
+++ b/sound/soc/amd/ps/ps-pdm-dma.c
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * AMD ALSA SoC Pink Sardine PDM Driver
+ *
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/bitfield.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/pm_runtime.h>
+
+#include "acp63.h"
+
+#define DRV_NAME "acp_ps_pdm_dma"
+
+static int pdm_gain = 3;
+module_param(pdm_gain, int, 0644);
+MODULE_PARM_DESC(pdm_gain, "Gain control (0-3)");
+
+static const struct snd_pcm_hardware acp63_pdm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
+static void acp63_init_pdm_ring_buffer(u32 physical_addr, u32 buffer_size,
+ u32 watermark_size, void __iomem *acp_base)
+{
+ writel(physical_addr, acp_base + ACP_WOV_RX_RINGBUFADDR);
+ writel(buffer_size, acp_base + ACP_WOV_RX_RINGBUFSIZE);
+ writel(watermark_size, acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
+ writel(0x01, acp_base + ACPAXI2AXI_ATU_CTRL);
+}
+
+static void acp63_enable_pdm_clock(void __iomem *acp_base)
+{
+ u32 pdm_clk_enable, pdm_ctrl;
+
+ pdm_clk_enable = ACP_PDM_CLK_FREQ_MASK;
+ pdm_ctrl = 0x00;
+
+ writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
+ pdm_ctrl = readl(acp_base + ACP_WOV_MISC_CTRL);
+ pdm_ctrl &= ~ACP_WOV_GAIN_CONTROL;
+ pdm_ctrl |= FIELD_PREP(ACP_WOV_GAIN_CONTROL, clamp(pdm_gain, 0, 3));
+ writel(pdm_ctrl, acp_base + ACP_WOV_MISC_CTRL);
+}
+
+static void acp63_enable_pdm_interrupts(struct pdm_dev_data *adata)
+{
+ u32 ext_int_ctrl;
+
+ mutex_lock(adata->acp_lock);
+ ext_int_ctrl = readl(adata->acp63_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_int_ctrl |= PDM_DMA_INTR_MASK;
+ writel(ext_int_ctrl, adata->acp63_base + ACP_EXTERNAL_INTR_CNTL);
+ mutex_unlock(adata->acp_lock);
+}
+
+static void acp63_disable_pdm_interrupts(struct pdm_dev_data *adata)
+{
+ u32 ext_int_ctrl;
+
+ mutex_lock(adata->acp_lock);
+ ext_int_ctrl = readl(adata->acp63_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_int_ctrl &= ~PDM_DMA_INTR_MASK;
+ writel(ext_int_ctrl, adata->acp63_base + ACP_EXTERNAL_INTR_CNTL);
+ mutex_unlock(adata->acp_lock);
+}
+
+static bool acp63_check_pdm_dma_status(void __iomem *acp_base)
+{
+ bool pdm_dma_status;
+ u32 pdm_enable, pdm_dma_enable;
+
+ pdm_dma_status = false;
+ pdm_enable = readl(acp_base + ACP_WOV_PDM_ENABLE);
+ pdm_dma_enable = readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_enable & ACP_PDM_ENABLE) && (pdm_dma_enable & ACP_PDM_DMA_EN_STATUS))
+ pdm_dma_status = true;
+
+ return pdm_dma_status;
+}
+
+static int acp63_start_pdm_dma(void __iomem *acp_base)
+{
+ u32 pdm_enable;
+ u32 pdm_dma_enable;
+ int timeout;
+
+ pdm_enable = 0x01;
+ pdm_dma_enable = 0x01;
+
+ acp63_enable_pdm_clock(acp_base);
+ writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
+ writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ timeout = 0;
+ while (++timeout < ACP_COUNTER) {
+ pdm_dma_enable = readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_dma_enable & 0x02) == ACP_PDM_DMA_EN_STATUS)
+ return 0;
+ udelay(DELAY_US);
+ }
+ return -ETIMEDOUT;
+}
+
+static int acp63_stop_pdm_dma(void __iomem *acp_base)
+{
+ u32 pdm_enable, pdm_dma_enable;
+ int timeout;
+
+ pdm_enable = 0x00;
+ pdm_dma_enable = 0x00;
+
+ pdm_enable = readl(acp_base + ACP_WOV_PDM_ENABLE);
+ pdm_dma_enable = readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if (pdm_dma_enable & 0x01) {
+ pdm_dma_enable = 0x02;
+ writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ timeout = 0;
+ while (++timeout < ACP_COUNTER) {
+ pdm_dma_enable = readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_dma_enable & 0x02) == 0x00)
+ break;
+ udelay(DELAY_US);
+ }
+ if (timeout == ACP_COUNTER)
+ return -ETIMEDOUT;
+ }
+ if (pdm_enable == ACP_PDM_ENABLE) {
+ pdm_enable = ACP_PDM_DISABLE;
+ writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
+ }
+ writel(0x01, acp_base + ACP_WOV_PDM_FIFO_FLUSH);
+ return 0;
+}
+
+static void acp63_config_dma(struct pdm_stream_instance *rtd, int direction)
+{
+ u16 page_idx;
+ u32 low, high, val;
+ dma_addr_t addr;
+
+ addr = rtd->dma_addr;
+ val = PDM_PTE_OFFSET;
+
+ /* Group Enable */
+ writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp63_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
+ writel(PAGE_SIZE_4K_ENABLE, rtd->acp63_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
+ for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+
+ writel(low, rtd->acp63_base + ACP_SCRATCH_REG_0 + val);
+ high |= BIT(31);
+ writel(high, rtd->acp63_base + ACP_SCRATCH_REG_0 + val + 4);
+ val += 8;
+ addr += PAGE_SIZE;
+ }
+}
+
+static int acp63_pdm_dma_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime;
+ struct pdm_dev_data *adata;
+ struct pdm_stream_instance *pdm_data;
+ int ret;
+
+ runtime = substream->runtime;
+ adata = dev_get_drvdata(component->dev);
+ pdm_data = kzalloc(sizeof(*pdm_data), GFP_KERNEL);
+ if (!pdm_data)
+ return -EINVAL;
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ runtime->hw = acp63_pdm_hardware_capture;
+
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(pdm_data);
+ return ret;
+ }
+
+ acp63_enable_pdm_interrupts(adata);
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ adata->capture_stream = substream;
+
+ pdm_data->acp63_base = adata->acp63_base;
+ runtime->private_data = pdm_data;
+ return ret;
+}
+
+static int acp63_pdm_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct pdm_stream_instance *rtd;
+ size_t size, period_bytes;
+
+ rtd = substream->runtime->private_data;
+ if (!rtd)
+ return -EINVAL;
+ size = params_buffer_bytes(params);
+ period_bytes = params_period_bytes(params);
+ rtd->dma_addr = substream->runtime->dma_addr;
+ rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+ acp63_config_dma(rtd, substream->stream);
+ acp63_init_pdm_ring_buffer(PDM_MEM_WINDOW_START, size,
+ period_bytes, rtd->acp63_base);
+ return 0;
+}
+
+static u64 acp63_pdm_get_byte_count(struct pdm_stream_instance *rtd,
+ int direction)
+{
+ u32 high, low;
+ u64 byte_count;
+
+ high = readl(rtd->acp63_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);
+ byte_count = high;
+ low = readl(rtd->acp63_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);
+ byte_count = (byte_count << 32) | low;
+ return byte_count;
+}
+
+static snd_pcm_uframes_t acp63_pdm_dma_pointer(struct snd_soc_component *comp,
+ struct snd_pcm_substream *stream)
+{
+ struct pdm_stream_instance *rtd;
+ u32 pos, buffersize;
+ u64 bytescount;
+
+ rtd = stream->runtime->private_data;
+ buffersize = frames_to_bytes(stream->runtime,
+ stream->runtime->buffer_size);
+ bytescount = acp63_pdm_get_byte_count(rtd, stream->stream);
+ if (bytescount > rtd->bytescount)
+ bytescount -= rtd->bytescount;
+ pos = do_div(bytescount, buffersize);
+ return bytes_to_frames(stream->runtime, pos);
+}
+
+static int acp63_pdm_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct device *parent = component->dev->parent;
+
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ parent, MIN_BUFFER, MAX_BUFFER);
+ return 0;
+}
+
+static int acp63_pdm_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ acp63_disable_pdm_interrupts(adata);
+ adata->capture_stream = NULL;
+ kfree(runtime->private_data);
+ return 0;
+}
+
+static int acp63_pdm_dai_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct pdm_stream_instance *rtd;
+ int ret;
+ bool pdm_status;
+ unsigned int ch_mask;
+
+ rtd = substream->runtime->private_data;
+ ret = 0;
+ switch (substream->runtime->channels) {
+ case TWO_CH:
+ ch_mask = 0x00;
+ break;
+ default:
+ return -EINVAL;
+ }
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ writel(ch_mask, rtd->acp63_base + ACP_WOV_PDM_NO_OF_CHANNELS);
+ writel(PDM_DECIMATION_FACTOR, rtd->acp63_base + ACP_WOV_PDM_DECIMATION_FACTOR);
+ rtd->bytescount = acp63_pdm_get_byte_count(rtd, substream->stream);
+ pdm_status = acp63_check_pdm_dma_status(rtd->acp63_base);
+ if (!pdm_status)
+ ret = acp63_start_pdm_dma(rtd->acp63_base);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ pdm_status = acp63_check_pdm_dma_status(rtd->acp63_base);
+ if (pdm_status)
+ ret = acp63_stop_pdm_dma(rtd->acp63_base);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static const struct snd_soc_dai_ops acp63_pdm_dai_ops = {
+ .trigger = acp63_pdm_dai_trigger,
+};
+
+static struct snd_soc_dai_driver acp63_pdm_dai_driver = {
+ .name = "acp_ps_pdm_dma.0",
+ .capture = {
+ .rates = SNDRV_PCM_RATE_48000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ },
+ .ops = &acp63_pdm_dai_ops,
+};
+
+static const struct snd_soc_component_driver acp63_pdm_component = {
+ .name = DRV_NAME,
+ .open = acp63_pdm_dma_open,
+ .close = acp63_pdm_dma_close,
+ .hw_params = acp63_pdm_dma_hw_params,
+ .pointer = acp63_pdm_dma_pointer,
+ .pcm_construct = acp63_pdm_dma_new,
+};
+
+static int acp63_pdm_audio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct pdm_dev_data *adata;
+ struct acp63_dev_data *acp_data;
+ struct device *parent;
+ int status;
+
+ parent = pdev->dev.parent;
+ acp_data = dev_get_drvdata(parent);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ adata->acp63_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!adata->acp63_base)
+ return -ENOMEM;
+
+ adata->capture_stream = NULL;
+ adata->acp_lock = &acp_data->acp_lock;
+ dev_set_drvdata(&pdev->dev, adata);
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp63_pdm_component,
+ &acp63_pdm_dai_driver, 1);
+ if (status) {
+ dev_err(&pdev->dev, "Fail to register acp pdm dai\n");
+
+ return -ENODEV;
+ }
+ pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ return 0;
+}
+
+static void acp63_pdm_audio_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int __maybe_unused acp63_pdm_resume(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+ struct snd_pcm_runtime *runtime;
+ struct pdm_stream_instance *rtd;
+ u32 period_bytes, buffer_len;
+
+ adata = dev_get_drvdata(dev);
+ if (adata->capture_stream && adata->capture_stream->runtime) {
+ runtime = adata->capture_stream->runtime;
+ rtd = runtime->private_data;
+ period_bytes = frames_to_bytes(runtime, runtime->period_size);
+ buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
+ acp63_config_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
+ acp63_init_pdm_ring_buffer(PDM_MEM_WINDOW_START, buffer_len,
+ period_bytes, adata->acp63_base);
+ }
+ acp63_enable_pdm_interrupts(adata);
+ return 0;
+}
+
+static int __maybe_unused acp63_pdm_suspend(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ acp63_disable_pdm_interrupts(adata);
+ return 0;
+}
+
+static int __maybe_unused acp63_pdm_runtime_resume(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ acp63_enable_pdm_interrupts(adata);
+ return 0;
+}
+
+static const struct dev_pm_ops acp63_pdm_pm_ops = {
+ SET_RUNTIME_PM_OPS(acp63_pdm_suspend, acp63_pdm_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(acp63_pdm_suspend, acp63_pdm_resume)
+};
+
+static struct platform_driver acp63_pdm_dma_driver = {
+ .probe = acp63_pdm_audio_probe,
+ .remove_new = acp63_pdm_audio_remove,
+ .driver = {
+ .name = "acp_ps_pdm_dma",
+ .pm = &acp63_pdm_pm_ops,
+ },
+};
+
+module_platform_driver(acp63_pdm_dma_driver);
+
+MODULE_AUTHOR("Syed.SabaKareem@amd.com");
+MODULE_DESCRIPTION("AMD PINK SARDINE PDM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c
new file mode 100644
index 0000000000..6230d1b122
--- /dev/null
+++ b/sound/soc/amd/ps/ps-sdw-dma.c
@@ -0,0 +1,566 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * AMD ALSA SoC Pink Sardine SoundWire DMA Driver
+ *
+ * Copyright 2023 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/pm_runtime.h>
+#include <linux/soundwire/sdw_amd.h>
+#include "acp63.h"
+
+#define DRV_NAME "amd_ps_sdw_dma"
+
+static struct sdw_dma_ring_buf_reg sdw0_dma_ring_buf_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
+ {ACP_AUDIO0_TX_DMA_SIZE, ACP_AUDIO0_TX_FIFOADDR, ACP_AUDIO0_TX_FIFOSIZE,
+ ACP_AUDIO0_TX_RINGBUFSIZE, ACP_AUDIO0_TX_RINGBUFADDR, ACP_AUDIO0_TX_INTR_WATERMARK_SIZE,
+ ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH},
+ {ACP_AUDIO1_TX_DMA_SIZE, ACP_AUDIO1_TX_FIFOADDR, ACP_AUDIO1_TX_FIFOSIZE,
+ ACP_AUDIO1_TX_RINGBUFSIZE, ACP_AUDIO1_TX_RINGBUFADDR, ACP_AUDIO1_TX_INTR_WATERMARK_SIZE,
+ ACP_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH},
+ {ACP_AUDIO2_TX_DMA_SIZE, ACP_AUDIO2_TX_FIFOADDR, ACP_AUDIO2_TX_FIFOSIZE,
+ ACP_AUDIO2_TX_RINGBUFSIZE, ACP_AUDIO2_TX_RINGBUFADDR, ACP_AUDIO2_TX_INTR_WATERMARK_SIZE,
+ ACP_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH},
+ {ACP_AUDIO0_RX_DMA_SIZE, ACP_AUDIO0_RX_FIFOADDR, ACP_AUDIO0_RX_FIFOSIZE,
+ ACP_AUDIO0_RX_RINGBUFSIZE, ACP_AUDIO0_RX_RINGBUFADDR, ACP_AUDIO0_RX_INTR_WATERMARK_SIZE,
+ ACP_AUDIO0_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH},
+ {ACP_AUDIO1_RX_DMA_SIZE, ACP_AUDIO1_RX_FIFOADDR, ACP_AUDIO1_RX_FIFOSIZE,
+ ACP_AUDIO1_RX_RINGBUFSIZE, ACP_AUDIO1_RX_RINGBUFADDR, ACP_AUDIO1_RX_INTR_WATERMARK_SIZE,
+ ACP_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH},
+ {ACP_AUDIO2_RX_DMA_SIZE, ACP_AUDIO2_RX_FIFOADDR, ACP_AUDIO2_RX_FIFOSIZE,
+ ACP_AUDIO2_RX_RINGBUFSIZE, ACP_AUDIO2_RX_RINGBUFADDR, ACP_AUDIO2_RX_INTR_WATERMARK_SIZE,
+ ACP_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH}
+};
+
+/*
+ * SDW1 instance supports one TX stream and one RX stream.
+ * For TX/RX streams DMA registers programming for SDW1 instance, it uses ACP_P1_AUDIO1 register
+ * set as per hardware register documentation
+ */
+static struct sdw_dma_ring_buf_reg sdw1_dma_ring_buf_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
+ {ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE,
+ ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR,
+ ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE,
+ ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH},
+ {ACP_P1_AUDIO1_RX_DMA_SIZE, ACP_P1_AUDIO1_RX_FIFOADDR, ACP_P1_AUDIO1_RX_FIFOSIZE,
+ ACP_P1_AUDIO1_RX_RINGBUFSIZE, ACP_P1_AUDIO1_RX_RINGBUFADDR,
+ ACP_P1_AUDIO1_RX_INTR_WATERMARK_SIZE,
+ ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH},
+};
+
+static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
+ ACP_SW0_AUDIO0_TX_EN,
+ ACP_SW0_AUDIO1_TX_EN,
+ ACP_SW0_AUDIO2_TX_EN,
+ ACP_SW0_AUDIO0_RX_EN,
+ ACP_SW0_AUDIO1_RX_EN,
+ ACP_SW0_AUDIO2_RX_EN,
+};
+
+/*
+ * SDW1 instance supports one TX stream and one RX stream.
+ * For TX/RX streams DMA enable register programming for SDW1 instance,
+ * it uses ACP_SW1_AUDIO1_TX_EN and ACP_SW1_AUDIO1_RX_EN registers
+ * as per hardware register documentation.
+ */
+static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
+ ACP_SW1_AUDIO1_TX_EN,
+ ACP_SW1_AUDIO1_RX_EN,
+};
+
+static const struct snd_pcm_hardware acp63_sdw_hardware_playback = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .buffer_bytes_max = SDW_PLAYBACK_MAX_NUM_PERIODS * SDW_PLAYBACK_MAX_PERIOD_SIZE,
+ .period_bytes_min = SDW_PLAYBACK_MIN_PERIOD_SIZE,
+ .period_bytes_max = SDW_PLAYBACK_MAX_PERIOD_SIZE,
+ .periods_min = SDW_PLAYBACK_MIN_NUM_PERIODS,
+ .periods_max = SDW_PLAYBACK_MAX_NUM_PERIODS,
+};
+
+static const struct snd_pcm_hardware acp63_sdw_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .buffer_bytes_max = SDW_CAPTURE_MAX_NUM_PERIODS * SDW_CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = SDW_CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = SDW_CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = SDW_CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = SDW_CAPTURE_MAX_NUM_PERIODS,
+};
+
+static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, bool enable)
+{
+ u32 ext_intr_cntl, ext_intr_cntl1;
+ u32 irq_mask = ACP_SDW_DMA_IRQ_MASK;
+ u32 irq_mask1 = ACP_P1_SDW_DMA_IRQ_MASK;
+
+ if (enable) {
+ ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_intr_cntl |= irq_mask;
+ writel(ext_intr_cntl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1);
+ ext_intr_cntl1 |= irq_mask1;
+ writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1);
+ } else {
+ ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_intr_cntl &= ~irq_mask;
+ writel(ext_intr_cntl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1);
+ ext_intr_cntl1 &= ~irq_mask1;
+ writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1);
+ }
+}
+
+static void acp63_config_dma(struct acp_sdw_dma_stream *stream, void __iomem *acp_base,
+ u32 stream_id)
+{
+ u16 page_idx;
+ u32 low, high, val;
+ u32 sdw_dma_pte_offset;
+ dma_addr_t addr;
+
+ addr = stream->dma_addr;
+ sdw_dma_pte_offset = SDW_PTE_OFFSET(stream->instance);
+ val = sdw_dma_pte_offset + (stream_id * ACP_SDW_PTE_OFFSET);
+
+ /* Group Enable */
+ writel(ACP_SDW_SRAM_PTE_OFFSET | BIT(31), acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2);
+ writel(PAGE_SIZE_4K_ENABLE, acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2);
+ for (page_idx = 0; page_idx < stream->num_pages; page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+
+ writel(low, acp_base + ACP_SCRATCH_REG_0 + val);
+ high |= BIT(31);
+ writel(high, acp_base + ACP_SCRATCH_REG_0 + val + 4);
+ val += 8;
+ addr += PAGE_SIZE;
+ }
+ writel(0x1, acp_base + ACPAXI2AXI_ATU_CTRL);
+}
+
+static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, u32 size,
+ u32 manager_instance)
+{
+ u32 reg_dma_size;
+ u32 reg_fifo_addr;
+ u32 reg_fifo_size;
+ u32 reg_ring_buf_size;
+ u32 reg_ring_buf_addr;
+ u32 sdw_fifo_addr;
+ u32 sdw_fifo_offset;
+ u32 sdw_ring_buf_addr;
+ u32 sdw_ring_buf_size;
+ u32 sdw_mem_window_offset;
+
+ switch (manager_instance) {
+ case ACP_SDW0:
+ reg_dma_size = sdw0_dma_ring_buf_reg[stream_id].reg_dma_size;
+ reg_fifo_addr = sdw0_dma_ring_buf_reg[stream_id].reg_fifo_addr;
+ reg_fifo_size = sdw0_dma_ring_buf_reg[stream_id].reg_fifo_size;
+ reg_ring_buf_size = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_size;
+ reg_ring_buf_addr = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_addr;
+ break;
+ case ACP_SDW1:
+ reg_dma_size = sdw1_dma_ring_buf_reg[stream_id].reg_dma_size;
+ reg_fifo_addr = sdw1_dma_ring_buf_reg[stream_id].reg_fifo_addr;
+ reg_fifo_size = sdw1_dma_ring_buf_reg[stream_id].reg_fifo_size;
+ reg_ring_buf_size = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_size;
+ reg_ring_buf_addr = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_addr;
+ break;
+ default:
+ return -EINVAL;
+ }
+ sdw_fifo_offset = ACP_SDW_FIFO_OFFSET(manager_instance);
+ sdw_mem_window_offset = SDW_MEM_WINDOW_START(manager_instance);
+ sdw_fifo_addr = sdw_fifo_offset + (stream_id * SDW_FIFO_OFFSET);
+ sdw_ring_buf_addr = sdw_mem_window_offset + (stream_id * ACP_SDW_RING_BUFF_ADDR_OFFSET);
+ sdw_ring_buf_size = size;
+ writel(sdw_ring_buf_size, acp_base + reg_ring_buf_size);
+ writel(sdw_ring_buf_addr, acp_base + reg_ring_buf_addr);
+ writel(sdw_fifo_addr, acp_base + reg_fifo_addr);
+ writel(SDW_DMA_SIZE, acp_base + reg_dma_size);
+ writel(SDW_FIFO_SIZE, acp_base + reg_fifo_size);
+ return 0;
+}
+
+static int acp63_sdw_dma_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime;
+ struct acp_sdw_dma_stream *stream;
+ struct snd_soc_dai *cpu_dai;
+ struct amd_sdw_manager *amd_manager;
+ struct snd_soc_pcm_runtime *prtd = substream->private_data;
+ int ret;
+
+ runtime = substream->runtime;
+ cpu_dai = asoc_rtd_to_cpu(prtd, 0);
+ amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
+ stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+ if (!stream)
+ return -ENOMEM;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ runtime->hw = acp63_sdw_hardware_playback;
+ else
+ runtime->hw = acp63_sdw_hardware_capture;
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(stream);
+ return ret;
+ }
+
+ stream->stream_id = cpu_dai->id;
+ stream->instance = amd_manager->instance;
+ runtime->private_data = stream;
+ return ret;
+}
+
+static int acp63_sdw_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct acp_sdw_dma_stream *stream;
+ struct sdw_dma_dev_data *sdw_data;
+ u32 period_bytes;
+ u32 water_mark_size_reg;
+ u32 irq_mask, ext_intr_ctrl;
+ u64 size;
+ u32 stream_id;
+ u32 acp_ext_intr_cntl_reg;
+ int ret;
+
+ sdw_data = dev_get_drvdata(component->dev);
+ stream = substream->runtime->private_data;
+ if (!stream)
+ return -EINVAL;
+ stream_id = stream->stream_id;
+ switch (stream->instance) {
+ case ACP_SDW0:
+ sdw_data->sdw0_dma_stream[stream_id] = substream;
+ water_mark_size_reg = sdw0_dma_ring_buf_reg[stream_id].water_mark_size_reg;
+ acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ irq_mask = BIT(SDW0_DMA_TX_IRQ_MASK(stream_id));
+ else
+ irq_mask = BIT(SDW0_DMA_RX_IRQ_MASK(stream_id));
+ break;
+ case ACP_SDW1:
+ sdw_data->sdw1_dma_stream[stream_id] = substream;
+ acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1;
+ water_mark_size_reg = sdw1_dma_ring_buf_reg[stream_id].water_mark_size_reg;
+ irq_mask = BIT(SDW1_DMA_IRQ_MASK(stream_id));
+ break;
+ default:
+ return -EINVAL;
+ }
+ size = params_buffer_bytes(params);
+ period_bytes = params_period_bytes(params);
+ stream->dma_addr = substream->runtime->dma_addr;
+ stream->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+ acp63_config_dma(stream, sdw_data->acp_base, stream_id);
+ ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, stream_id, size,
+ stream->instance);
+ if (ret) {
+ dev_err(component->dev, "Invalid DMA channel\n");
+ return -EINVAL;
+ }
+ ext_intr_ctrl = readl(sdw_data->acp_base + acp_ext_intr_cntl_reg);
+ ext_intr_ctrl |= irq_mask;
+ writel(ext_intr_ctrl, sdw_data->acp_base + acp_ext_intr_cntl_reg);
+ writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
+ return 0;
+}
+
+static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base)
+{
+ union acp_sdw_dma_count byte_count;
+ u32 pos_low_reg, pos_high_reg;
+
+ byte_count.bytescount = 0;
+ switch (stream->instance) {
+ case ACP_SDW0:
+ pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
+ pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
+ break;
+ case ACP_SDW1:
+ pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
+ pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
+ break;
+ default:
+ goto POINTER_RETURN_BYTES;
+ }
+ if (pos_low_reg) {
+ byte_count.bcount.high = readl(acp_base + pos_high_reg);
+ byte_count.bcount.low = readl(acp_base + pos_low_reg);
+ }
+POINTER_RETURN_BYTES:
+ return byte_count.bytescount;
+}
+
+static snd_pcm_uframes_t acp63_sdw_dma_pointer(struct snd_soc_component *comp,
+ struct snd_pcm_substream *substream)
+{
+ struct sdw_dma_dev_data *sdw_data;
+ struct acp_sdw_dma_stream *stream;
+ u32 pos, buffersize;
+ u64 bytescount;
+
+ sdw_data = dev_get_drvdata(comp->dev);
+ stream = substream->runtime->private_data;
+ buffersize = frames_to_bytes(substream->runtime,
+ substream->runtime->buffer_size);
+ bytescount = acp63_sdw_get_byte_count(stream, sdw_data->acp_base);
+ if (bytescount > stream->bytescount)
+ bytescount -= stream->bytescount;
+ pos = do_div(bytescount, buffersize);
+ return bytes_to_frames(substream->runtime, pos);
+}
+
+static int acp63_sdw_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct device *parent = component->dev->parent;
+
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ parent, SDW_MIN_BUFFER, SDW_MAX_BUFFER);
+ return 0;
+}
+
+static int acp63_sdw_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct sdw_dma_dev_data *sdw_data;
+ struct acp_sdw_dma_stream *stream;
+
+ sdw_data = dev_get_drvdata(component->dev);
+ stream = substream->runtime->private_data;
+ if (!stream)
+ return -EINVAL;
+ switch (stream->instance) {
+ case ACP_SDW0:
+ sdw_data->sdw0_dma_stream[stream->stream_id] = NULL;
+ break;
+ case ACP_SDW1:
+ sdw_data->sdw1_dma_stream[stream->stream_id] = NULL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ kfree(stream);
+ return 0;
+}
+
+static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream,
+ void __iomem *acp_base, bool sdw_dma_enable)
+{
+ struct acp_sdw_dma_stream *stream;
+ u32 stream_id;
+ u32 sdw_dma_en_reg;
+ u32 sdw_dma_en_stat_reg;
+ u32 sdw_dma_stat;
+ u32 dma_enable;
+
+ stream = substream->runtime->private_data;
+ stream_id = stream->stream_id;
+ switch (stream->instance) {
+ case ACP_SDW0:
+ sdw_dma_en_reg = sdw0_dma_enable_reg[stream_id];
+ break;
+ case ACP_SDW1:
+ sdw_dma_en_reg = sdw1_dma_enable_reg[stream_id];
+ break;
+ default:
+ return -EINVAL;
+ }
+ sdw_dma_en_stat_reg = sdw_dma_en_reg + 4;
+ dma_enable = sdw_dma_enable;
+ writel(dma_enable, acp_base + sdw_dma_en_reg);
+ return readl_poll_timeout(acp_base + sdw_dma_en_stat_reg, sdw_dma_stat,
+ (sdw_dma_stat == dma_enable), ACP_DELAY_US, ACP_COUNTER);
+}
+
+static int acp63_sdw_dma_trigger(struct snd_soc_component *comp,
+ struct snd_pcm_substream *substream,
+ int cmd)
+{
+ struct sdw_dma_dev_data *sdw_data;
+ int ret;
+
+ sdw_data = dev_get_drvdata(comp->dev);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, true);
+ break;
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_STOP:
+ ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, false);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ if (ret)
+ dev_err(comp->dev, "trigger %d failed: %d", cmd, ret);
+ return ret;
+}
+
+static const struct snd_soc_component_driver acp63_sdw_component = {
+ .name = DRV_NAME,
+ .open = acp63_sdw_dma_open,
+ .close = acp63_sdw_dma_close,
+ .hw_params = acp63_sdw_dma_hw_params,
+ .trigger = acp63_sdw_dma_trigger,
+ .pointer = acp63_sdw_dma_pointer,
+ .pcm_construct = acp63_sdw_dma_new,
+};
+
+static int acp63_sdw_platform_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct sdw_dma_dev_data *sdw_data;
+ struct acp63_dev_data *acp_data;
+ struct device *parent;
+ int status;
+
+ parent = pdev->dev.parent;
+ acp_data = dev_get_drvdata(parent);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ sdw_data = devm_kzalloc(&pdev->dev, sizeof(*sdw_data), GFP_KERNEL);
+ if (!sdw_data)
+ return -ENOMEM;
+
+ sdw_data->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!sdw_data->acp_base)
+ return -ENOMEM;
+
+ sdw_data->acp_lock = &acp_data->acp_lock;
+ dev_set_drvdata(&pdev->dev, sdw_data);
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp63_sdw_component,
+ NULL, 0);
+ if (status) {
+ dev_err(&pdev->dev, "Fail to register sdw dma component\n");
+ return status;
+ }
+ pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ return 0;
+}
+
+static void acp63_sdw_platform_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)
+{
+ struct acp_sdw_dma_stream *stream;
+ struct snd_pcm_substream *substream;
+ struct snd_pcm_runtime *runtime;
+ u32 period_bytes, buf_size, water_mark_size_reg;
+ u32 stream_count;
+ int index, instance, ret;
+
+ for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) {
+ if (instance == ACP_SDW0)
+ stream_count = ACP63_SDW0_DMA_MAX_STREAMS;
+ else
+ stream_count = ACP63_SDW1_DMA_MAX_STREAMS;
+
+ for (index = 0; index < stream_count; index++) {
+ if (instance == ACP_SDW0) {
+ substream = sdw_data->sdw0_dma_stream[index];
+ water_mark_size_reg =
+ sdw0_dma_ring_buf_reg[index].water_mark_size_reg;
+ } else {
+ substream = sdw_data->sdw1_dma_stream[index];
+ water_mark_size_reg =
+ sdw1_dma_ring_buf_reg[index].water_mark_size_reg;
+ }
+
+ if (substream && substream->runtime) {
+ runtime = substream->runtime;
+ stream = runtime->private_data;
+ period_bytes = frames_to_bytes(runtime, runtime->period_size);
+ buf_size = frames_to_bytes(runtime, runtime->buffer_size);
+ acp63_config_dma(stream, sdw_data->acp_base, index);
+ ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index,
+ buf_size, instance);
+ if (ret)
+ return ret;
+ writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
+ }
+ }
+ }
+ acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, true);
+ return 0;
+}
+
+static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev)
+{
+ struct sdw_dma_dev_data *sdw_data;
+
+ sdw_data = dev_get_drvdata(dev);
+ return acp_restore_sdw_dma_config(sdw_data);
+}
+
+static const struct dev_pm_ops acp63_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(NULL, acp63_sdw_pcm_resume)
+};
+
+static struct platform_driver acp63_sdw_dma_driver = {
+ .probe = acp63_sdw_platform_probe,
+ .remove_new = acp63_sdw_platform_remove,
+ .driver = {
+ .name = "amd_ps_sdw_dma",
+ .pm = &acp63_pm_ops,
+ },
+};
+
+module_platform_driver(acp63_sdw_dma_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP6.3 PS SDW DMA Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/raven/Makefile b/sound/soc/amd/raven/Makefile
new file mode 100644
index 0000000000..62c22b6ed9
--- /dev/null
+++ b/sound/soc/amd/raven/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Raven Ridge platform Support
+snd-pci-acp3x-objs := pci-acp3x.o
+snd-acp3x-pcm-dma-objs := acp3x-pcm-dma.o
+snd-acp3x-i2s-objs := acp3x-i2s.o
+obj-$(CONFIG_SND_SOC_AMD_ACP3x) += snd-pci-acp3x.o
+obj-$(CONFIG_SND_SOC_AMD_ACP3x) += snd-acp3x-pcm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_ACP3x) += snd-acp3x-i2s.o
diff --git a/sound/soc/amd/raven/acp3x-i2s.c b/sound/soc/amd/raven/acp3x-i2s.c
new file mode 100644
index 0000000000..4ba8368948
--- /dev/null
+++ b/sound/soc/amd/raven/acp3x-i2s.c
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ALSA SoC PCM Driver
+//
+//Copyright 2016 Advanced Micro Devices, Inc.
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/dma-mapping.h>
+
+#include "acp3x.h"
+
+#define DRV_NAME "acp3x_i2s_playcap"
+
+static int acp3x_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
+ unsigned int fmt)
+{
+ struct i2s_dev_data *adata;
+ int mode;
+
+ adata = snd_soc_dai_get_drvdata(cpu_dai);
+ mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+ switch (mode) {
+ case SND_SOC_DAIFMT_I2S:
+ adata->tdm_mode = TDM_DISABLE;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ adata->tdm_mode = TDM_ENABLE;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int acp3x_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai,
+ u32 tx_mask, u32 rx_mask, int slots, int slot_width)
+{
+ struct i2s_dev_data *adata;
+ u32 frm_len;
+ u16 slot_len;
+
+ adata = snd_soc_dai_get_drvdata(cpu_dai);
+
+ /* These values are as per Hardware Spec */
+ switch (slot_width) {
+ case SLOT_WIDTH_8:
+ slot_len = 8;
+ break;
+ case SLOT_WIDTH_16:
+ slot_len = 16;
+ break;
+ case SLOT_WIDTH_24:
+ slot_len = 24;
+ break;
+ case SLOT_WIDTH_32:
+ slot_len = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ frm_len = FRM_LEN | (slots << 15) | (slot_len << 18);
+ adata->tdm_fmt = frm_len;
+ return 0;
+}
+
+static int acp3x_i2s_hwparams(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct i2s_stream_instance *rtd;
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp3x_platform_info *pinfo;
+ struct i2s_dev_data *adata;
+ u32 val;
+ u32 reg_val, frmt_reg;
+
+ prtd = asoc_substream_to_rtd(substream);
+ rtd = substream->runtime->private_data;
+ card = prtd->card;
+ adata = snd_soc_dai_get_drvdata(dai);
+ pinfo = snd_soc_card_get_drvdata(card);
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ else
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ }
+
+ /* These values are as per Hardware Spec */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_S8:
+ rtd->xfer_resolution = 0x0;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ rtd->xfer_resolution = 0x02;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ rtd->xfer_resolution = 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ rtd->xfer_resolution = 0x05;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_ITER;
+ frmt_reg = mmACP_BTTDM_TXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_ITER;
+ frmt_reg = mmACP_I2STDM_TXFRMT;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_IRER;
+ frmt_reg = mmACP_BTTDM_RXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_IRER;
+ frmt_reg = mmACP_I2STDM_RXFRMT;
+ }
+ }
+ if (adata->tdm_mode) {
+ val = rv_readl(rtd->acp3x_base + reg_val);
+ rv_writel(val | 0x2, rtd->acp3x_base + reg_val);
+ rv_writel(adata->tdm_fmt, rtd->acp3x_base + frmt_reg);
+ }
+ val = rv_readl(rtd->acp3x_base + reg_val);
+ val &= ~ACP3x_ITER_IRER_SAMP_LEN_MASK;
+ val = val | (rtd->xfer_resolution << 3);
+ rv_writel(val, rtd->acp3x_base + reg_val);
+ return 0;
+}
+
+static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct i2s_stream_instance *rtd;
+ u32 ret, val, period_bytes, reg_val, ier_val, water_val;
+ u32 buf_size, buf_reg;
+
+ rtd = substream->runtime->private_data;
+ period_bytes = frames_to_bytes(substream->runtime,
+ substream->runtime->period_size);
+ buf_size = frames_to_bytes(substream->runtime,
+ substream->runtime->buffer_size);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ rtd->bytescount = acp_get_byte_count(rtd,
+ substream->stream);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ water_val =
+ mmACP_BT_TX_INTR_WATERMARK_SIZE;
+ reg_val = mmACP_BTTDM_ITER;
+ ier_val = mmACP_BTTDM_IER;
+ buf_reg = mmACP_BT_TX_RINGBUFSIZE;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ water_val =
+ mmACP_I2S_TX_INTR_WATERMARK_SIZE;
+ reg_val = mmACP_I2STDM_ITER;
+ ier_val = mmACP_I2STDM_IER;
+ buf_reg = mmACP_I2S_TX_RINGBUFSIZE;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ water_val =
+ mmACP_BT_RX_INTR_WATERMARK_SIZE;
+ reg_val = mmACP_BTTDM_IRER;
+ ier_val = mmACP_BTTDM_IER;
+ buf_reg = mmACP_BT_RX_RINGBUFSIZE;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ water_val =
+ mmACP_I2S_RX_INTR_WATERMARK_SIZE;
+ reg_val = mmACP_I2STDM_IRER;
+ ier_val = mmACP_I2STDM_IER;
+ buf_reg = mmACP_I2S_RX_RINGBUFSIZE;
+ }
+ }
+ rv_writel(period_bytes, rtd->acp3x_base + water_val);
+ rv_writel(buf_size, rtd->acp3x_base + buf_reg);
+ val = rv_readl(rtd->acp3x_base + reg_val);
+ val = val | BIT(0);
+ rv_writel(val, rtd->acp3x_base + reg_val);
+ rv_writel(1, rtd->acp3x_base + ier_val);
+ ret = 0;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_ITER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_ITER;
+ }
+
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_IRER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_IRER;
+ }
+ }
+ val = rv_readl(rtd->acp3x_base + reg_val);
+ val = val & ~BIT(0);
+ rv_writel(val, rtd->acp3x_base + reg_val);
+
+ if (!(rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER) & BIT(0)) &&
+ !(rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER) & BIT(0)))
+ rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER);
+ if (!(rv_readl(rtd->acp3x_base + mmACP_I2STDM_ITER) & BIT(0)) &&
+ !(rv_readl(rtd->acp3x_base + mmACP_I2STDM_IRER) & BIT(0)))
+ rv_writel(0, rtd->acp3x_base + mmACP_I2STDM_IER);
+ ret = 0;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static const struct snd_soc_dai_ops acp3x_i2s_dai_ops = {
+ .hw_params = acp3x_i2s_hwparams,
+ .trigger = acp3x_i2s_trigger,
+ .set_fmt = acp3x_i2s_set_fmt,
+ .set_tdm_slot = acp3x_i2s_set_tdm_slot,
+};
+
+static const struct snd_soc_component_driver acp3x_dai_component = {
+ .name = DRV_NAME,
+ .legacy_dai_naming = 1,
+};
+
+static struct snd_soc_dai_driver acp3x_i2s_dai = {
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &acp3x_i2s_dai_ops,
+};
+
+static int acp3x_dai_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct i2s_dev_data *adata;
+ int ret;
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dev_data),
+ GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENOMEM;
+ }
+ adata->acp3x_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!adata->acp3x_base)
+ return -ENOMEM;
+
+ adata->i2s_irq = res->start;
+ dev_set_drvdata(&pdev->dev, adata);
+ ret = devm_snd_soc_register_component(&pdev->dev,
+ &acp3x_dai_component, &acp3x_i2s_dai, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to register acp i2s dai\n");
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static struct platform_driver acp3x_dai_driver = {
+ .probe = acp3x_dai_probe,
+ .driver = {
+ .name = "acp3x_i2s_playcap",
+ },
+};
+
+module_platform_driver(acp3x_dai_driver);
+
+MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
+MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:"DRV_NAME);
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
new file mode 100644
index 0000000000..9538f3ffc5
--- /dev/null
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -0,0 +1,526 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ALSA SoC PCM Driver
+//
+//Copyright 2016 Advanced Micro Devices, Inc.
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+#include "acp3x.h"
+
+#define DRV_NAME "acp3x_rv_i2s_dma"
+
+static const struct snd_pcm_hardware acp3x_pcm_hardware_playback = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
+ .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
+ .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
+ .periods_min = PLAYBACK_MIN_NUM_PERIODS,
+ .periods_max = PLAYBACK_MAX_NUM_PERIODS,
+};
+
+static const struct snd_pcm_hardware acp3x_pcm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
+static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
+{
+ struct i2s_dev_data *rv_i2s_data;
+ u16 play_flag, cap_flag;
+ u32 val;
+
+ rv_i2s_data = dev_id;
+ if (!rv_i2s_data)
+ return IRQ_NONE;
+
+ play_flag = 0;
+ cap_flag = 0;
+ val = rv_readl(rv_i2s_data->acp3x_base + mmACP_EXTERNAL_INTR_STAT);
+ if ((val & BIT(BT_TX_THRESHOLD)) && rv_i2s_data->play_stream) {
+ rv_writel(BIT(BT_TX_THRESHOLD), rv_i2s_data->acp3x_base +
+ mmACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(rv_i2s_data->play_stream);
+ play_flag = 1;
+ }
+ if ((val & BIT(I2S_TX_THRESHOLD)) &&
+ rv_i2s_data->i2ssp_play_stream) {
+ rv_writel(BIT(I2S_TX_THRESHOLD),
+ rv_i2s_data->acp3x_base + mmACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(rv_i2s_data->i2ssp_play_stream);
+ play_flag = 1;
+ }
+
+ if ((val & BIT(BT_RX_THRESHOLD)) && rv_i2s_data->capture_stream) {
+ rv_writel(BIT(BT_RX_THRESHOLD), rv_i2s_data->acp3x_base +
+ mmACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(rv_i2s_data->capture_stream);
+ cap_flag = 1;
+ }
+ if ((val & BIT(I2S_RX_THRESHOLD)) &&
+ rv_i2s_data->i2ssp_capture_stream) {
+ rv_writel(BIT(I2S_RX_THRESHOLD),
+ rv_i2s_data->acp3x_base + mmACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(rv_i2s_data->i2ssp_capture_stream);
+ cap_flag = 1;
+ }
+
+ if (play_flag | cap_flag)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
+{
+ u16 page_idx;
+ u32 low, high, val, acp_fifo_addr, reg_fifo_addr;
+ u32 reg_dma_size, reg_fifo_size;
+ dma_addr_t addr;
+
+ addr = rtd->dma_addr;
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ val = ACP_SRAM_BT_PB_PTE_OFFSET;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ val = ACP_SRAM_SP_PB_PTE_OFFSET;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ val = ACP_SRAM_BT_CP_PTE_OFFSET;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ val = ACP_SRAM_SP_CP_PTE_OFFSET;
+ }
+ }
+ /* Group Enable */
+ rv_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp3x_base +
+ mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
+ rv_writel(PAGE_SIZE_4K_ENABLE, rtd->acp3x_base +
+ mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
+
+ for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+
+ rv_writel(low, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val);
+ high |= BIT(31);
+ rv_writel(high, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val
+ + 4);
+ /* Move to next physically contiguous page */
+ val += 8;
+ addr += PAGE_SIZE;
+ }
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_dma_size = mmACP_BT_TX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ BT_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = mmACP_BT_TX_FIFOADDR;
+ reg_fifo_size = mmACP_BT_TX_FIFOSIZE;
+ rv_writel(I2S_BT_TX_MEM_WINDOW_START,
+ rtd->acp3x_base + mmACP_BT_TX_RINGBUFADDR);
+ break;
+
+ case I2S_SP_INSTANCE:
+ default:
+ reg_dma_size = mmACP_I2S_TX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ SP_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = mmACP_I2S_TX_FIFOADDR;
+ reg_fifo_size = mmACP_I2S_TX_FIFOSIZE;
+ rv_writel(I2S_SP_TX_MEM_WINDOW_START,
+ rtd->acp3x_base + mmACP_I2S_TX_RINGBUFADDR);
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_dma_size = mmACP_BT_RX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ BT_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = mmACP_BT_RX_FIFOADDR;
+ reg_fifo_size = mmACP_BT_RX_FIFOSIZE;
+ rv_writel(I2S_BT_RX_MEM_WINDOW_START,
+ rtd->acp3x_base + mmACP_BT_RX_RINGBUFADDR);
+ break;
+
+ case I2S_SP_INSTANCE:
+ default:
+ reg_dma_size = mmACP_I2S_RX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ SP_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = mmACP_I2S_RX_FIFOADDR;
+ reg_fifo_size = mmACP_I2S_RX_FIFOSIZE;
+ rv_writel(I2S_SP_RX_MEM_WINDOW_START,
+ rtd->acp3x_base + mmACP_I2S_RX_RINGBUFADDR);
+ }
+ }
+ rv_writel(DMA_SIZE, rtd->acp3x_base + reg_dma_size);
+ rv_writel(acp_fifo_addr, rtd->acp3x_base + reg_fifo_addr);
+ rv_writel(FIFO_SIZE, rtd->acp3x_base + reg_fifo_size);
+ rv_writel(BIT(I2S_RX_THRESHOLD) | BIT(BT_RX_THRESHOLD)
+ | BIT(I2S_TX_THRESHOLD) | BIT(BT_TX_THRESHOLD),
+ rtd->acp3x_base + mmACP_EXTERNAL_INTR_CNTL);
+}
+
+static int acp3x_dma_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime;
+ struct snd_soc_pcm_runtime *prtd;
+ struct i2s_dev_data *adata;
+ struct i2s_stream_instance *i2s_data;
+ int ret;
+
+ runtime = substream->runtime;
+ prtd = asoc_substream_to_rtd(substream);
+ component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+ adata = dev_get_drvdata(component->dev);
+ i2s_data = kzalloc(sizeof(*i2s_data), GFP_KERNEL);
+ if (!i2s_data)
+ return -EINVAL;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ runtime->hw = acp3x_pcm_hardware_playback;
+ else
+ runtime->hw = acp3x_pcm_hardware_capture;
+
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(i2s_data);
+ return ret;
+ }
+
+ i2s_data->acp3x_base = adata->acp3x_base;
+ runtime->private_data = i2s_data;
+ return ret;
+}
+
+
+static int acp3x_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct i2s_stream_instance *rtd;
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp3x_platform_info *pinfo;
+ struct i2s_dev_data *adata;
+ u64 size;
+
+ prtd = asoc_substream_to_rtd(substream);
+ card = prtd->card;
+ pinfo = snd_soc_card_get_drvdata(card);
+ adata = dev_get_drvdata(component->dev);
+ rtd = substream->runtime->private_data;
+ if (!rtd)
+ return -EINVAL;
+
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ adata->play_stream = substream;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_play_stream = substream;
+ }
+ } else {
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ adata->capture_stream = substream;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_capture_stream = substream;
+ }
+ }
+ } else {
+ pr_err("pinfo failed\n");
+ }
+ size = params_buffer_bytes(params);
+ rtd->dma_addr = substream->runtime->dma_addr;
+ rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+ config_acp3x_dma(rtd, substream->stream);
+ return 0;
+}
+
+static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct i2s_stream_instance *rtd;
+ u32 pos;
+ u32 buffersize;
+ u64 bytescount;
+
+ rtd = substream->runtime->private_data;
+
+ buffersize = frames_to_bytes(substream->runtime,
+ substream->runtime->buffer_size);
+ bytescount = acp_get_byte_count(rtd, substream->stream);
+ if (bytescount > rtd->bytescount)
+ bytescount -= rtd->bytescount;
+ pos = do_div(bytescount, buffersize);
+ return bytes_to_frames(substream->runtime, pos);
+}
+
+static int acp3x_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct device *parent = component->dev->parent;
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ parent, MIN_BUFFER, MAX_BUFFER);
+ return 0;
+}
+
+static int acp3x_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *prtd;
+ struct i2s_dev_data *adata;
+ struct i2s_stream_instance *ins;
+
+ prtd = asoc_substream_to_rtd(substream);
+ component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+ adata = dev_get_drvdata(component->dev);
+ ins = substream->runtime->private_data;
+ if (!ins)
+ return -EINVAL;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (ins->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ adata->play_stream = NULL;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_play_stream = NULL;
+ }
+ } else {
+ switch (ins->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ adata->capture_stream = NULL;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_capture_stream = NULL;
+ }
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_component_driver acp3x_i2s_component = {
+ .name = DRV_NAME,
+ .open = acp3x_dma_open,
+ .close = acp3x_dma_close,
+ .hw_params = acp3x_dma_hw_params,
+ .pointer = acp3x_dma_pointer,
+ .pcm_construct = acp3x_dma_new,
+};
+
+static int acp3x_audio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct i2s_dev_data *adata;
+ unsigned int irqflags;
+ int status;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "platform_data not retrieved\n");
+ return -ENODEV;
+ }
+ irqflags = *((unsigned int *)(pdev->dev.platform_data));
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ adata->acp3x_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!adata->acp3x_base)
+ return -ENOMEM;
+
+ status = platform_get_irq(pdev, 0);
+ if (status < 0)
+ return status;
+ adata->i2s_irq = status;
+
+ dev_set_drvdata(&pdev->dev, adata);
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp3x_i2s_component,
+ NULL, 0);
+ if (status) {
+ dev_err(&pdev->dev, "Fail to register acp i2s component\n");
+ return -ENODEV;
+ }
+ status = devm_request_irq(&pdev->dev, adata->i2s_irq, i2s_irq_handler,
+ irqflags, "ACP3x_I2S_IRQ", adata);
+ if (status) {
+ dev_err(&pdev->dev, "ACP3x I2S IRQ request failed\n");
+ return -ENODEV;
+ }
+
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ return 0;
+}
+
+static void acp3x_audio_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int acp3x_resume(struct device *dev)
+{
+ struct i2s_dev_data *adata;
+ u32 val, reg_val, frmt_val;
+
+ reg_val = 0;
+ frmt_val = 0;
+ adata = dev_get_drvdata(dev);
+
+ if (adata->play_stream && adata->play_stream->runtime) {
+ struct i2s_stream_instance *rtd =
+ adata->play_stream->runtime->private_data;
+ config_acp3x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK);
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_ITER;
+ frmt_val = mmACP_BTTDM_TXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_ITER;
+ frmt_val = mmACP_I2STDM_TXFRMT;
+ }
+ rv_writel((rtd->xfer_resolution << 3),
+ rtd->acp3x_base + reg_val);
+ }
+ if (adata->capture_stream && adata->capture_stream->runtime) {
+ struct i2s_stream_instance *rtd =
+ adata->capture_stream->runtime->private_data;
+ config_acp3x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_IRER;
+ frmt_val = mmACP_BTTDM_RXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_IRER;
+ frmt_val = mmACP_I2STDM_RXFRMT;
+ }
+ rv_writel((rtd->xfer_resolution << 3),
+ rtd->acp3x_base + reg_val);
+ }
+ if (adata->tdm_mode == TDM_ENABLE) {
+ rv_writel(adata->tdm_fmt, adata->acp3x_base + frmt_val);
+ val = rv_readl(adata->acp3x_base + reg_val);
+ rv_writel(val | 0x2, adata->acp3x_base + reg_val);
+ }
+ rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+
+static int acp3x_pcm_runtime_suspend(struct device *dev)
+{
+ struct i2s_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+
+ rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
+
+ return 0;
+}
+
+static int acp3x_pcm_runtime_resume(struct device *dev)
+{
+ struct i2s_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+
+ rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static const struct dev_pm_ops acp3x_pm_ops = {
+ .runtime_suspend = acp3x_pcm_runtime_suspend,
+ .runtime_resume = acp3x_pcm_runtime_resume,
+ .resume = acp3x_resume,
+};
+
+static struct platform_driver acp3x_dma_driver = {
+ .probe = acp3x_audio_probe,
+ .remove_new = acp3x_audio_remove,
+ .driver = {
+ .name = "acp3x_rv_i2s_dma",
+ .pm = &acp3x_pm_ops,
+ },
+};
+
+module_platform_driver(acp3x_dma_driver);
+
+MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
+MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:"DRV_NAME);
diff --git a/sound/soc/amd/raven/acp3x.h b/sound/soc/amd/raven/acp3x.h
new file mode 100644
index 0000000000..7702f628ec
--- /dev/null
+++ b/sound/soc/amd/raven/acp3x.h
@@ -0,0 +1,162 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ALSA SoC PCM Driver
+ *
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ */
+
+#include "chip_offset_byte.h"
+#include <sound/pcm.h>
+#define I2S_SP_INSTANCE 0x01
+#define I2S_BT_INSTANCE 0x02
+
+#define TDM_ENABLE 1
+#define TDM_DISABLE 0
+
+#define ACP3x_DEVS 4
+#define ACP3x_PHY_BASE_ADDRESS 0x1240000
+#define ACP3x_I2S_MODE 0
+#define ACP3x_REG_START 0x1240000
+#define ACP3x_REG_END 0x1250200
+#define ACP3x_I2STDM_REG_START 0x1242400
+#define ACP3x_I2STDM_REG_END 0x1242410
+#define ACP3x_BT_TDM_REG_START 0x1242800
+#define ACP3x_BT_TDM_REG_END 0x1242810
+#define I2S_MODE 0x04
+#define I2S_RX_THRESHOLD 27
+#define I2S_TX_THRESHOLD 28
+#define BT_TX_THRESHOLD 26
+#define BT_RX_THRESHOLD 25
+#define ACP_ERR_INTR_MASK 29
+#define ACP3x_POWER_ON 0x00
+#define ACP3x_POWER_ON_IN_PROGRESS 0x01
+#define ACP3x_POWER_OFF 0x02
+#define ACP3x_POWER_OFF_IN_PROGRESS 0x03
+#define ACP3x_SOFT_RESET__SoftResetAudDone_MASK 0x00010001
+
+#define ACP_SRAM_PTE_OFFSET 0x02050000
+#define ACP_SRAM_SP_PB_PTE_OFFSET 0x0
+#define ACP_SRAM_SP_CP_PTE_OFFSET 0x100
+#define ACP_SRAM_BT_PB_PTE_OFFSET 0x200
+#define ACP_SRAM_BT_CP_PTE_OFFSET 0x300
+#define PAGE_SIZE_4K_ENABLE 0x2
+#define I2S_SP_TX_MEM_WINDOW_START 0x4000000
+#define I2S_SP_RX_MEM_WINDOW_START 0x4020000
+#define I2S_BT_TX_MEM_WINDOW_START 0x4040000
+#define I2S_BT_RX_MEM_WINDOW_START 0x4060000
+
+#define SP_PB_FIFO_ADDR_OFFSET 0x500
+#define SP_CAPT_FIFO_ADDR_OFFSET 0x700
+#define BT_PB_FIFO_ADDR_OFFSET 0x900
+#define BT_CAPT_FIFO_ADDR_OFFSET 0xB00
+#define PLAYBACK_MIN_NUM_PERIODS 2
+#define PLAYBACK_MAX_NUM_PERIODS 8
+#define PLAYBACK_MAX_PERIOD_SIZE 8192
+#define PLAYBACK_MIN_PERIOD_SIZE 1024
+#define CAPTURE_MIN_NUM_PERIODS 2
+#define CAPTURE_MAX_NUM_PERIODS 8
+#define CAPTURE_MAX_PERIOD_SIZE 8192
+#define CAPTURE_MIN_PERIOD_SIZE 1024
+
+#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
+#define MIN_BUFFER MAX_BUFFER
+#define FIFO_SIZE 0x100
+#define DMA_SIZE 0x40
+#define FRM_LEN 0x100
+
+#define SLOT_WIDTH_8 0x08
+#define SLOT_WIDTH_16 0x10
+#define SLOT_WIDTH_24 0x18
+#define SLOT_WIDTH_32 0x20
+#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00
+#define ACP_PGFSM_STATUS_MASK 0x03
+#define ACP_POWERED_ON 0x00
+#define ACP_POWER_ON_IN_PROGRESS 0x01
+#define ACP_POWERED_OFF 0x02
+#define ACP_POWER_OFF_IN_PROGRESS 0x03
+
+#define ACP3x_ITER_IRER_SAMP_LEN_MASK 0x38
+#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
+
+struct acp3x_platform_info {
+ u16 play_i2s_instance;
+ u16 cap_i2s_instance;
+ u16 capture_channel;
+};
+
+struct i2s_dev_data {
+ bool tdm_mode;
+ int i2s_irq;
+ u16 i2s_instance;
+ u32 tdm_fmt;
+ u32 substream_type;
+ void __iomem *acp3x_base;
+ struct snd_pcm_substream *play_stream;
+ struct snd_pcm_substream *capture_stream;
+ struct snd_pcm_substream *i2ssp_play_stream;
+ struct snd_pcm_substream *i2ssp_capture_stream;
+};
+
+struct i2s_stream_instance {
+ u16 num_pages;
+ u16 i2s_instance;
+ u16 capture_channel;
+ u16 direction;
+ u16 channels;
+ u32 xfer_resolution;
+ u32 val;
+ dma_addr_t dma_addr;
+ u64 bytescount;
+ void __iomem *acp3x_base;
+};
+
+static inline u32 rv_readl(void __iomem *base_addr)
+{
+ return readl(base_addr - ACP3x_PHY_BASE_ADDRESS);
+}
+
+static inline void rv_writel(u32 val, void __iomem *base_addr)
+{
+ writel(val, base_addr - ACP3x_PHY_BASE_ADDRESS);
+}
+
+static inline u64 acp_get_byte_count(struct i2s_stream_instance *rtd,
+ int direction)
+{
+ u64 byte_count;
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_BT_TX_LINEARPOSITIONCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_I2S_TX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_I2S_TX_LINEARPOSITIONCNTR_LOW);
+ }
+
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_BT_RX_LINEARPOSITIONCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_I2S_RX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_I2S_RX_LINEARPOSITIONCNTR_LOW);
+ }
+ }
+ return byte_count;
+}
diff --git a/sound/soc/amd/raven/chip_offset_byte.h b/sound/soc/amd/raven/chip_offset_byte.h
new file mode 100644
index 0000000000..9c1fac58fb
--- /dev/null
+++ b/sound/soc/amd/raven/chip_offset_byte.h
@@ -0,0 +1,639 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ACP 3.0 Register Documentation
+ *
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ */
+
+#ifndef _acp_ip_OFFSET_HEADER
+#define _acp_ip_OFFSET_HEADER
+// Registers from ACP_DMA block
+
+#define mmACP_DMA_CNTL_0 0x1240000
+#define mmACP_DMA_CNTL_1 0x1240004
+#define mmACP_DMA_CNTL_2 0x1240008
+#define mmACP_DMA_CNTL_3 0x124000C
+#define mmACP_DMA_CNTL_4 0x1240010
+#define mmACP_DMA_CNTL_5 0x1240014
+#define mmACP_DMA_CNTL_6 0x1240018
+#define mmACP_DMA_CNTL_7 0x124001C
+#define mmACP_DMA_DSCR_STRT_IDX_0 0x1240020
+#define mmACP_DMA_DSCR_STRT_IDX_1 0x1240024
+#define mmACP_DMA_DSCR_STRT_IDX_2 0x1240028
+#define mmACP_DMA_DSCR_STRT_IDX_3 0x124002C
+#define mmACP_DMA_DSCR_STRT_IDX_4 0x1240030
+#define mmACP_DMA_DSCR_STRT_IDX_5 0x1240034
+#define mmACP_DMA_DSCR_STRT_IDX_6 0x1240038
+#define mmACP_DMA_DSCR_STRT_IDX_7 0x124003C
+#define mmACP_DMA_DSCR_CNT_0 0x1240040
+#define mmACP_DMA_DSCR_CNT_1 0x1240044
+#define mmACP_DMA_DSCR_CNT_2 0x1240048
+#define mmACP_DMA_DSCR_CNT_3 0x124004C
+#define mmACP_DMA_DSCR_CNT_4 0x1240050
+#define mmACP_DMA_DSCR_CNT_5 0x1240054
+#define mmACP_DMA_DSCR_CNT_6 0x1240058
+#define mmACP_DMA_DSCR_CNT_7 0x124005C
+#define mmACP_DMA_PRIO_0 0x1240060
+#define mmACP_DMA_PRIO_1 0x1240064
+#define mmACP_DMA_PRIO_2 0x1240068
+#define mmACP_DMA_PRIO_3 0x124006C
+#define mmACP_DMA_PRIO_4 0x1240070
+#define mmACP_DMA_PRIO_5 0x1240074
+#define mmACP_DMA_PRIO_6 0x1240078
+#define mmACP_DMA_PRIO_7 0x124007C
+#define mmACP_DMA_CUR_DSCR_0 0x1240080
+#define mmACP_DMA_CUR_DSCR_1 0x1240084
+#define mmACP_DMA_CUR_DSCR_2 0x1240088
+#define mmACP_DMA_CUR_DSCR_3 0x124008C
+#define mmACP_DMA_CUR_DSCR_4 0x1240090
+#define mmACP_DMA_CUR_DSCR_5 0x1240094
+#define mmACP_DMA_CUR_DSCR_6 0x1240098
+#define mmACP_DMA_CUR_DSCR_7 0x124009C
+#define mmACP_DMA_CUR_TRANS_CNT_0 0x12400A0
+#define mmACP_DMA_CUR_TRANS_CNT_1 0x12400A4
+#define mmACP_DMA_CUR_TRANS_CNT_2 0x12400A8
+#define mmACP_DMA_CUR_TRANS_CNT_3 0x12400AC
+#define mmACP_DMA_CUR_TRANS_CNT_4 0x12400B0
+#define mmACP_DMA_CUR_TRANS_CNT_5 0x12400B4
+#define mmACP_DMA_CUR_TRANS_CNT_6 0x12400B8
+#define mmACP_DMA_CUR_TRANS_CNT_7 0x12400BC
+#define mmACP_DMA_ERR_STS_0 0x12400C0
+#define mmACP_DMA_ERR_STS_1 0x12400C4
+#define mmACP_DMA_ERR_STS_2 0x12400C8
+#define mmACP_DMA_ERR_STS_3 0x12400CC
+#define mmACP_DMA_ERR_STS_4 0x12400D0
+#define mmACP_DMA_ERR_STS_5 0x12400D4
+#define mmACP_DMA_ERR_STS_6 0x12400D8
+#define mmACP_DMA_ERR_STS_7 0x12400DC
+#define mmACP_DMA_DESC_BASE_ADDR 0x12400E0
+#define mmACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4
+#define mmACP_DMA_CH_STS 0x12400E8
+#define mmACP_DMA_CH_GROUP 0x12400EC
+#define mmACP_DMA_CH_RST_STS 0x12400F0
+
+
+// Registers from ACP_AXI2AXIATU block
+
+#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0x1240C00
+#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1 0x1240C04
+#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_2 0x1240C08
+#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_2 0x1240C0C
+#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_3 0x1240C10
+#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_3 0x1240C14
+#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_4 0x1240C18
+#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_4 0x1240C1C
+#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0x1240C20
+#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0x1240C24
+#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_6 0x1240C28
+#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_6 0x1240C2C
+#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_7 0x1240C30
+#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_7 0x1240C34
+#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_8 0x1240C38
+#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_8 0x1240C3C
+#define mmACPAXI2AXI_ATU_CTRL 0x1240C40
+
+
+// Registers from ACP_CLKRST block
+
+#define mmACP_SOFT_RESET 0x1241000
+#define mmACP_CONTROL 0x1241004
+#define mmACP_STATUS 0x1241008
+#define mmACP_DSP0_OCD_HALT_ON_RST 0x124100C
+#define mmACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
+
+
+// Registers from ACP_MISC block
+
+#define mmACP_EXTERNAL_INTR_ENB 0x1241800
+#define mmACP_EXTERNAL_INTR_CNTL 0x1241804
+#define mmACP_EXTERNAL_INTR_STAT 0x1241808
+#define mmACP_DSP0_INTR_CNTL 0x124180C
+#define mmACP_DSP0_INTR_STAT 0x1241810
+#define mmACP_DSP_SW_INTR_CNTL 0x1241814
+#define mmACP_DSP_SW_INTR_STAT 0x1241818
+#define mmACP_SW_INTR_TRIG 0x124181C
+#define mmACP_SMU_MAILBOX 0x1241820
+#define mmDSP_INTERRUPT_ROUTING_CTRL 0x1241824
+#define mmACP_DSP0_WATCHDOG_TIMER_CNTL 0x1241828
+#define mmACP_DSP0_EXT_TIMER1_CNTL 0x124182C
+#define mmACP_DSP0_EXT_TIMER2_CNTL 0x1241830
+#define mmACP_DSP0_EXT_TIMER3_CNTL 0x1241834
+#define mmACP_DSP0_EXT_TIMER4_CNTL 0x1241838
+#define mmACP_DSP0_EXT_TIMER5_CNTL 0x124183C
+#define mmACP_DSP0_EXT_TIMER6_CNTL 0x1241840
+#define mmACP_DSP0_EXT_TIMER1_CURR_VALUE 0x1241844
+#define mmACP_DSP0_EXT_TIMER2_CURR_VALUE 0x1241848
+#define mmACP_DSP0_EXT_TIMER3_CURR_VALUE 0x124184C
+#define mmACP_DSP0_EXT_TIMER4_CURR_VALUE 0x1241850
+#define mmACP_DSP0_EXT_TIMER5_CURR_VALUE 0x1241854
+#define mmACP_DSP0_EXT_TIMER6_CURR_VALUE 0x1241858
+#define mmACP_FW_STATUS 0x124185C
+#define mmACP_TIMER 0x1241874
+#define mmACP_TIMER_CNTL 0x1241878
+#define mmACP_PGMEM_CTRL 0x12418C0
+#define mmACP_ERROR_STATUS 0x12418C4
+#define mmACP_SW_I2S_ERROR_REASON 0x12418C8
+#define mmACP_MEM_PG_STS 0x12418CC
+
+
+// Registers from ACP_PGFSM block
+
+#define mmACP_I2S_PIN_CONFIG 0x1241400
+#define mmACP_PAD_PULLUP_PULLDOWN_CTRL 0x1241404
+#define mmACP_PAD_DRIVE_STRENGTH_CTRL 0x1241408
+#define mmACP_SW_PAD_KEEPER_EN 0x124140C
+#define mmACP_SW_WAKE_EN 0x1241410
+#define mmACP_I2S_WAKE_EN 0x1241414
+#define mmACP_PME_EN 0x1241418
+#define mmACP_PGFSM_CONTROL 0x124141C
+#define mmACP_PGFSM_STATUS 0x1241420
+
+
+// Registers from ACP_SCRATCH block
+
+#define mmACP_SCRATCH_REG_0 0x1250000
+#define mmACP_SCRATCH_REG_1 0x1250004
+#define mmACP_SCRATCH_REG_2 0x1250008
+#define mmACP_SCRATCH_REG_3 0x125000C
+#define mmACP_SCRATCH_REG_4 0x1250010
+#define mmACP_SCRATCH_REG_5 0x1250014
+#define mmACP_SCRATCH_REG_6 0x1250018
+#define mmACP_SCRATCH_REG_7 0x125001C
+#define mmACP_SCRATCH_REG_8 0x1250020
+#define mmACP_SCRATCH_REG_9 0x1250024
+#define mmACP_SCRATCH_REG_10 0x1250028
+#define mmACP_SCRATCH_REG_11 0x125002C
+#define mmACP_SCRATCH_REG_12 0x1250030
+#define mmACP_SCRATCH_REG_13 0x1250034
+#define mmACP_SCRATCH_REG_14 0x1250038
+#define mmACP_SCRATCH_REG_15 0x125003C
+#define mmACP_SCRATCH_REG_16 0x1250040
+#define mmACP_SCRATCH_REG_17 0x1250044
+#define mmACP_SCRATCH_REG_18 0x1250048
+#define mmACP_SCRATCH_REG_19 0x125004C
+#define mmACP_SCRATCH_REG_20 0x1250050
+#define mmACP_SCRATCH_REG_21 0x1250054
+#define mmACP_SCRATCH_REG_22 0x1250058
+#define mmACP_SCRATCH_REG_23 0x125005C
+#define mmACP_SCRATCH_REG_24 0x1250060
+#define mmACP_SCRATCH_REG_25 0x1250064
+#define mmACP_SCRATCH_REG_26 0x1250068
+#define mmACP_SCRATCH_REG_27 0x125006C
+#define mmACP_SCRATCH_REG_28 0x1250070
+#define mmACP_SCRATCH_REG_29 0x1250074
+#define mmACP_SCRATCH_REG_30 0x1250078
+#define mmACP_SCRATCH_REG_31 0x125007C
+#define mmACP_SCRATCH_REG_32 0x1250080
+#define mmACP_SCRATCH_REG_33 0x1250084
+#define mmACP_SCRATCH_REG_34 0x1250088
+#define mmACP_SCRATCH_REG_35 0x125008C
+#define mmACP_SCRATCH_REG_36 0x1250090
+#define mmACP_SCRATCH_REG_37 0x1250094
+#define mmACP_SCRATCH_REG_38 0x1250098
+#define mmACP_SCRATCH_REG_39 0x125009C
+#define mmACP_SCRATCH_REG_40 0x12500A0
+#define mmACP_SCRATCH_REG_41 0x12500A4
+#define mmACP_SCRATCH_REG_42 0x12500A8
+#define mmACP_SCRATCH_REG_43 0x12500AC
+#define mmACP_SCRATCH_REG_44 0x12500B0
+#define mmACP_SCRATCH_REG_45 0x12500B4
+#define mmACP_SCRATCH_REG_46 0x12500B8
+#define mmACP_SCRATCH_REG_47 0x12500BC
+#define mmACP_SCRATCH_REG_48 0x12500C0
+#define mmACP_SCRATCH_REG_49 0x12500C4
+#define mmACP_SCRATCH_REG_50 0x12500C8
+#define mmACP_SCRATCH_REG_51 0x12500CC
+#define mmACP_SCRATCH_REG_52 0x12500D0
+#define mmACP_SCRATCH_REG_53 0x12500D4
+#define mmACP_SCRATCH_REG_54 0x12500D8
+#define mmACP_SCRATCH_REG_55 0x12500DC
+#define mmACP_SCRATCH_REG_56 0x12500E0
+#define mmACP_SCRATCH_REG_57 0x12500E4
+#define mmACP_SCRATCH_REG_58 0x12500E8
+#define mmACP_SCRATCH_REG_59 0x12500EC
+#define mmACP_SCRATCH_REG_60 0x12500F0
+#define mmACP_SCRATCH_REG_61 0x12500F4
+#define mmACP_SCRATCH_REG_62 0x12500F8
+#define mmACP_SCRATCH_REG_63 0x12500FC
+#define mmACP_SCRATCH_REG_64 0x1250100
+#define mmACP_SCRATCH_REG_65 0x1250104
+#define mmACP_SCRATCH_REG_66 0x1250108
+#define mmACP_SCRATCH_REG_67 0x125010C
+#define mmACP_SCRATCH_REG_68 0x1250110
+#define mmACP_SCRATCH_REG_69 0x1250114
+#define mmACP_SCRATCH_REG_70 0x1250118
+#define mmACP_SCRATCH_REG_71 0x125011C
+#define mmACP_SCRATCH_REG_72 0x1250120
+#define mmACP_SCRATCH_REG_73 0x1250124
+#define mmACP_SCRATCH_REG_74 0x1250128
+#define mmACP_SCRATCH_REG_75 0x125012C
+#define mmACP_SCRATCH_REG_76 0x1250130
+#define mmACP_SCRATCH_REG_77 0x1250134
+#define mmACP_SCRATCH_REG_78 0x1250138
+#define mmACP_SCRATCH_REG_79 0x125013C
+#define mmACP_SCRATCH_REG_80 0x1250140
+#define mmACP_SCRATCH_REG_81 0x1250144
+#define mmACP_SCRATCH_REG_82 0x1250148
+#define mmACP_SCRATCH_REG_83 0x125014C
+#define mmACP_SCRATCH_REG_84 0x1250150
+#define mmACP_SCRATCH_REG_85 0x1250154
+#define mmACP_SCRATCH_REG_86 0x1250158
+#define mmACP_SCRATCH_REG_87 0x125015C
+#define mmACP_SCRATCH_REG_88 0x1250160
+#define mmACP_SCRATCH_REG_89 0x1250164
+#define mmACP_SCRATCH_REG_90 0x1250168
+#define mmACP_SCRATCH_REG_91 0x125016C
+#define mmACP_SCRATCH_REG_92 0x1250170
+#define mmACP_SCRATCH_REG_93 0x1250174
+#define mmACP_SCRATCH_REG_94 0x1250178
+#define mmACP_SCRATCH_REG_95 0x125017C
+#define mmACP_SCRATCH_REG_96 0x1250180
+#define mmACP_SCRATCH_REG_97 0x1250184
+#define mmACP_SCRATCH_REG_98 0x1250188
+#define mmACP_SCRATCH_REG_99 0x125018C
+#define mmACP_SCRATCH_REG_100 0x1250190
+#define mmACP_SCRATCH_REG_101 0x1250194
+#define mmACP_SCRATCH_REG_102 0x1250198
+#define mmACP_SCRATCH_REG_103 0x125019C
+#define mmACP_SCRATCH_REG_104 0x12501A0
+#define mmACP_SCRATCH_REG_105 0x12501A4
+#define mmACP_SCRATCH_REG_106 0x12501A8
+#define mmACP_SCRATCH_REG_107 0x12501AC
+#define mmACP_SCRATCH_REG_108 0x12501B0
+#define mmACP_SCRATCH_REG_109 0x12501B4
+#define mmACP_SCRATCH_REG_110 0x12501B8
+#define mmACP_SCRATCH_REG_111 0x12501BC
+#define mmACP_SCRATCH_REG_112 0x12501C0
+#define mmACP_SCRATCH_REG_113 0x12501C4
+#define mmACP_SCRATCH_REG_114 0x12501C8
+#define mmACP_SCRATCH_REG_115 0x12501CC
+#define mmACP_SCRATCH_REG_116 0x12501D0
+#define mmACP_SCRATCH_REG_117 0x12501D4
+#define mmACP_SCRATCH_REG_118 0x12501D8
+#define mmACP_SCRATCH_REG_119 0x12501DC
+#define mmACP_SCRATCH_REG_120 0x12501E0
+#define mmACP_SCRATCH_REG_121 0x12501E4
+#define mmACP_SCRATCH_REG_122 0x12501E8
+#define mmACP_SCRATCH_REG_123 0x12501EC
+#define mmACP_SCRATCH_REG_124 0x12501F0
+#define mmACP_SCRATCH_REG_125 0x12501F4
+#define mmACP_SCRATCH_REG_126 0x12501F8
+#define mmACP_SCRATCH_REG_127 0x12501FC
+#define mmACP_SCRATCH_REG_128 0x1250200
+
+
+// Registers from ACP_SW_ACLK block
+
+#define mmSW_CORB_Base_Address 0x1243200
+#define mmSW_CORB_Write_Pointer 0x1243204
+#define mmSW_CORB_Read_Pointer 0x1243208
+#define mmSW_CORB_Control 0x124320C
+#define mmSW_CORB_Size 0x1243214
+#define mmSW_RIRB_Base_Address 0x1243218
+#define mmSW_RIRB_Write_Pointer 0x124321C
+#define mmSW_RIRB_Response_Interrupt_Count 0x1243220
+#define mmSW_RIRB_Control 0x1243224
+#define mmSW_RIRB_Size 0x1243228
+#define mmSW_RIRB_FIFO_MIN_THDL 0x124322C
+#define mmSW_imm_cmd_UPPER_WORD 0x1243230
+#define mmSW_imm_cmd_LOWER_QWORD 0x1243234
+#define mmSW_imm_resp_UPPER_WORD 0x1243238
+#define mmSW_imm_resp_LOWER_QWORD 0x124323C
+#define mmSW_imm_cmd_sts 0x1243240
+#define mmSW_BRA_BASE_ADDRESS 0x1243244
+#define mmSW_BRA_TRANSFER_SIZE 0x1243248
+#define mmSW_BRA_DMA_BUSY 0x124324C
+#define mmSW_BRA_RESP 0x1243250
+#define mmSW_BRA_RESP_FRAME_ADDR 0x1243254
+#define mmSW_BRA_CURRENT_TRANSFER_SIZE 0x1243258
+#define mmSW_STATE_CHANGE_STATUS_0TO7 0x124325C
+#define mmSW_STATE_CHANGE_STATUS_8TO11 0x1243260
+#define mmSW_STATE_CHANGE_STATUS_MASK_0to7 0x1243264
+#define mmSW_STATE_CHANGE_STATUS_MASK_8to11 0x1243268
+#define mmSW_CLK_FREQUENCY_CTRL 0x124326C
+#define mmSW_ERROR_INTR_MASK 0x1243270
+#define mmSW_PHY_TEST_MODE_DATA_OFF 0x1243274
+
+
+// Registers from ACP_SW_SWCLK block
+
+#define mmACP_SW_EN 0x1243000
+#define mmACP_SW_EN_STATUS 0x1243004
+#define mmACP_SW_FRAMESIZE 0x1243008
+#define mmACP_SW_SSP_Counter 0x124300C
+#define mmACP_SW_Audio_TX_EN 0x1243010
+#define mmACP_SW_Audio_TX_EN_STATUS 0x1243014
+#define mmACP_SW_Audio_TX_Frame_Format 0x1243018
+#define mmACP_SW_Audio_TX_SampleInterval 0x124301C
+#define mmACP_SW_Audio_TX_Hctrl_DP0 0x1243020
+#define mmACP_SW_Audio_TX_Hctrl_DP1 0x1243024
+#define mmACP_SW_Audio_TX_Hctrl_DP2 0x1243028
+#define mmACP_SW_Audio_TX_Hctrl_DP3 0x124302C
+#define mmACP_SW_Audio_TX_offset_DP0 0x1243030
+#define mmACP_SW_Audio_TX_offset_DP1 0x1243034
+#define mmACP_SW_Audio_TX_offset_DP2 0x1243038
+#define mmACP_SW_Audio_TX_offset_DP3 0x124303C
+#define mmACP_SW_Audio_TX_Channel_Enable_DP0 0x1243040
+#define mmACP_SW_Audio_TX_Channel_Enable_DP1 0x1243044
+#define mmACP_SW_Audio_TX_Channel_Enable_DP2 0x1243048
+#define mmACP_SW_Audio_TX_Channel_Enable_DP3 0x124304C
+#define mmACP_SW_BT_TX_EN 0x1243050
+#define mmACP_SW_BT_TX_EN_STATUS 0x1243054
+#define mmACP_SW_BT_TX_Frame_Format 0x1243058
+#define mmACP_SW_BT_TX_SampleInterval 0x124305C
+#define mmACP_SW_BT_TX_Hctrl 0x1243060
+#define mmACP_SW_BT_TX_offset 0x1243064
+#define mmACP_SW_BT_TX_Channel_Enable_DP0 0x1243068
+#define mmACP_SW_Headset_TX_EN 0x124306C
+#define mmACP_SW_Headset_TX_EN_STATUS 0x1243070
+#define mmACP_SW_Headset_TX_Frame_Format 0x1243074
+#define mmACP_SW_Headset_TX_SampleInterval 0x1243078
+#define mmACP_SW_Headset_TX_Hctrl 0x124307C
+#define mmACP_SW_Headset_TX_offset 0x1243080
+#define mmACP_SW_Headset_TX_Channel_Enable_DP0 0x1243084
+#define mmACP_SW_Audio_RX_EN 0x1243088
+#define mmACP_SW_Audio_RX_EN_STATUS 0x124308C
+#define mmACP_SW_Audio_RX_Frame_Format 0x1243090
+#define mmACP_SW_Audio_RX_SampleInterval 0x1243094
+#define mmACP_SW_Audio_RX_Hctrl_DP0 0x1243098
+#define mmACP_SW_Audio_RX_Hctrl_DP1 0x124309C
+#define mmACP_SW_Audio_RX_Hctrl_DP2 0x1243100
+#define mmACP_SW_Audio_RX_Hctrl_DP3 0x1243104
+#define mmACP_SW_Audio_RX_offset_DP0 0x1243108
+#define mmACP_SW_Audio_RX_offset_DP1 0x124310C
+#define mmACP_SW_Audio_RX_offset_DP2 0x1243110
+#define mmACP_SW_Audio_RX_offset_DP3 0x1243114
+#define mmACP_SW_Audio_RX_Channel_Enable_DP0 0x1243118
+#define mmACP_SW_Audio_RX_Channel_Enable_DP1 0x124311C
+#define mmACP_SW_Audio_RX_Channel_Enable_DP2 0x1243120
+#define mmACP_SW_Audio_RX_Channel_Enable_DP3 0x1243124
+#define mmACP_SW_BT_RX_EN 0x1243128
+#define mmACP_SW_BT_RX_EN_STATUS 0x124312C
+#define mmACP_SW_BT_RX_Frame_Format 0x1243130
+#define mmACP_SW_BT_RX_SampleInterval 0x1243134
+#define mmACP_SW_BT_RX_Hctrl 0x1243138
+#define mmACP_SW_BT_RX_offset 0x124313C
+#define mmACP_SW_BT_RX_Channel_Enable_DP0 0x1243140
+#define mmACP_SW_Headset_RX_EN 0x1243144
+#define mmACP_SW_Headset_RX_EN_STATUS 0x1243148
+#define mmACP_SW_Headset_RX_Frame_Format 0x124314C
+#define mmACP_SW_Headset_RX_SampleInterval 0x1243150
+#define mmACP_SW_Headset_RX_Hctrl 0x1243154
+#define mmACP_SW_Headset_RX_offset 0x1243158
+#define mmACP_SW_Headset_RX_Channel_Enable_DP0 0x124315C
+#define mmACP_SW_BPT_PORT_EN 0x1243160
+#define mmACP_SW_BPT_PORT_EN_STATUS 0x1243164
+#define mmACP_SW_BPT_PORT_Frame_Format 0x1243168
+#define mmACP_SW_BPT_PORT_SampleInterval 0x124316C
+#define mmACP_SW_BPT_PORT_Hctrl 0x1243170
+#define mmACP_SW_BPT_PORT_offset 0x1243174
+#define mmACP_SW_BPT_PORT_Channel_Enable 0x1243178
+#define mmACP_SW_BPT_PORT_First_byte_addr 0x124317C
+#define mmACP_SW_CLK_RESUME_CTRL 0x1243180
+#define mmACP_SW_CLK_RESUME_Delay_Cntr 0x1243184
+#define mmACP_SW_BUS_RESET_CTRL 0x1243188
+#define mmACP_SW_PRBS_ERR_STATUS 0x124318C
+
+
+// Registers from ACP_AUDIO_BUFFERS block
+
+#define mmACP_I2S_RX_RINGBUFADDR 0x1242000
+#define mmACP_I2S_RX_RINGBUFSIZE 0x1242004
+#define mmACP_I2S_RX_LINKPOSITIONCNTR 0x1242008
+#define mmACP_I2S_RX_FIFOADDR 0x124200C
+#define mmACP_I2S_RX_FIFOSIZE 0x1242010
+#define mmACP_I2S_RX_DMA_SIZE 0x1242014
+#define mmACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1242018
+#define mmACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x124201C
+#define mmACP_I2S_RX_INTR_WATERMARK_SIZE 0x1242020
+#define mmACP_I2S_TX_RINGBUFADDR 0x1242024
+#define mmACP_I2S_TX_RINGBUFSIZE 0x1242028
+#define mmACP_I2S_TX_LINKPOSITIONCNTR 0x124202C
+#define mmACP_I2S_TX_FIFOADDR 0x1242030
+#define mmACP_I2S_TX_FIFOSIZE 0x1242034
+#define mmACP_I2S_TX_DMA_SIZE 0x1242038
+#define mmACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x124203C
+#define mmACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1242040
+#define mmACP_I2S_TX_INTR_WATERMARK_SIZE 0x1242044
+#define mmACP_BT_RX_RINGBUFADDR 0x1242048
+#define mmACP_BT_RX_RINGBUFSIZE 0x124204C
+#define mmACP_BT_RX_LINKPOSITIONCNTR 0x1242050
+#define mmACP_BT_RX_FIFOADDR 0x1242054
+#define mmACP_BT_RX_FIFOSIZE 0x1242058
+#define mmACP_BT_RX_DMA_SIZE 0x124205C
+#define mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1242060
+#define mmACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x1242064
+#define mmACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068
+#define mmACP_BT_TX_RINGBUFADDR 0x124206C
+#define mmACP_BT_TX_RINGBUFSIZE 0x1242070
+#define mmACP_BT_TX_LINKPOSITIONCNTR 0x1242074
+#define mmACP_BT_TX_FIFOADDR 0x1242078
+#define mmACP_BT_TX_FIFOSIZE 0x124207C
+#define mmACP_BT_TX_DMA_SIZE 0x1242080
+#define mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1242084
+#define mmACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x1242088
+#define mmACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C
+#define mmACP_HS_RX_RINGBUFADDR 0x1242090
+#define mmACP_HS_RX_RINGBUFSIZE 0x1242094
+#define mmACP_HS_RX_LINKPOSITIONCNTR 0x1242098
+#define mmACP_HS_RX_FIFOADDR 0x124209C
+#define mmACP_HS_RX_FIFOSIZE 0x12420A0
+#define mmACP_HS_RX_DMA_SIZE 0x12420A4
+#define mmACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x12420A8
+#define mmACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x12420AC
+#define mmACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0
+#define mmACP_HS_TX_RINGBUFADDR 0x12420B4
+#define mmACP_HS_TX_RINGBUFSIZE 0x12420B8
+#define mmACP_HS_TX_LINKPOSITIONCNTR 0x12420BC
+#define mmACP_HS_TX_FIFOADDR 0x12420C0
+#define mmACP_HS_TX_FIFOSIZE 0x12420C4
+#define mmACP_HS_TX_DMA_SIZE 0x12420C8
+#define mmACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x12420CC
+#define mmACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x12420D0
+#define mmACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4
+
+
+// Registers from ACP_I2S_TDM block
+
+#define mmACP_I2STDM_IER 0x1242400
+#define mmACP_I2STDM_IRER 0x1242404
+#define mmACP_I2STDM_RXFRMT 0x1242408
+#define mmACP_I2STDM_ITER 0x124240C
+#define mmACP_I2STDM_TXFRMT 0x1242410
+
+
+// Registers from ACP_BT_TDM block
+
+#define mmACP_BTTDM_IER 0x1242800
+#define mmACP_BTTDM_IRER 0x1242804
+#define mmACP_BTTDM_RXFRMT 0x1242808
+#define mmACP_BTTDM_ITER 0x124280C
+#define mmACP_BTTDM_TXFRMT 0x1242810
+
+
+// Registers from AZALIA_IP block
+
+#define mmAudio_Az_Global_Capabilities 0x1200000
+#define mmAudio_Az_Minor_Version 0x1200002
+#define mmAudio_Az_Major_Version 0x1200003
+#define mmAudio_Az_Output_Payload_Capability 0x1200004
+#define mmAudio_Az_Input_Payload_Capability 0x1200006
+#define mmAudio_Az_Global_Control 0x1200008
+#define mmAudio_Az_Wake_Enable 0x120000C
+#define mmAudio_Az_State_Change_Status 0x120000E
+#define mmAudio_Az_Global_Status 0x1200010
+#define mmAudio_Az_Linked_List_Capability_Header 0x1200014
+#define mmAudio_Az_Output_Stream_Payload_Capability 0x1200018
+#define mmAudio_Az_Input_Stream_Payload_Capability 0x120001A
+#define mmAudio_Az_Interrupt_Control 0x1200020
+#define mmAudio_Az_Interrupt_Status 0x1200024
+#define mmAudio_Az_Wall_Clock_Counter 0x1200030
+#define mmAudio_Az_Stream_Synchronization 0x1200038
+#define mmAudio_Az_CORB_Lower_Base_Address 0x1200040
+#define mmAudio_Az_CORB_Upper_Base_Address 0x1200044
+#define mmAudio_Az_CORB_Write_Pointer 0x1200048
+#define mmAudio_Az_CORB_Read_Pointer 0x120004A
+#define mmAudio_Az_CORB_Control 0x120004C
+#define mmAudio_Az_CORB_Status 0x120004D
+#define mmAudio_Az_CORB_Size 0x120004E
+#define mmAudio_Az_RIRB_Lower_Base_Address 0x1200050
+#define mmAudio_Az_RIRB_Upper_Base_Address 0x1200054
+#define mmAudio_Az_RIRB_Write_Pointer 0x1200058
+#define mmAudio_Az_RIRB_Response_Interrupt_Count 0x120005A
+#define mmAudio_Az_RIRB_Control 0x120005C
+#define mmAudio_Az_RIRB_Status 0x120005D
+#define mmAudio_Az_RIRB_Size 0x120005E
+#define mmAudio_Az_Immediate_Command_Output_Interface 0x1200060
+#define mmAudio_Az_Immediate_Response_Input_Interface 0x1200064
+#define mmAudio_Az_Immediate_Command_Status 0x1200068
+#define mmAudio_Az_DPLBASE 0x1200070
+#define mmAudio_Az_DPUBASE 0x1200074
+#define mmAudio_Az_Input_SD0CTL_and_STS 0x1200080
+#define mmAudio_Az_Input_SD0LPIB 0x1200084
+#define mmAudio_Az_Input_SD0CBL 0x1200088
+#define mmAudio_Az_Input_SD0LVI 0x120008C
+#define mmAudio_Az_Input_SD0FIFOS 0x1200090
+#define mmAudio_Az_Input_SD0FMT 0x1200092
+#define mmAudio_Az_Input_SD0BDPL 0x1200098
+#define mmAudio_Az_Input_SD0BDPU 0x120009C
+#define mmAudio_Az_Input_SD1CTL_and_STS 0x12000A0
+#define mmAudio_Az_Input_SD1LPIB 0x12000A4
+#define mmAudio_Az_Input_SD1CBL 0x12000A8
+#define mmAudio_Az_Input_SD1LVI 0x12000AC
+#define mmAudio_Az_Input_SD1FIFOS 0x12000B0
+#define mmAudio_Az_Input_SD1FMT 0x12000B2
+#define mmAudio_Az_Input_SD1BDPL 0x12000B8
+#define mmAudio_Az_Input_SD1BDPU 0x12000BC
+#define mmAudio_Az_Input_SD2CTL_and_STS 0x12000C0
+#define mmAudio_Az_Input_SD2LPIB 0x12000C4
+#define mmAudio_Az_Input_SD2CBL 0x12000C8
+#define mmAudio_Az_Input_SD2LVI 0x12000CC
+#define mmAudio_Az_Input_SD2FIFOS 0x12000D0
+#define mmAudio_Az_Input_SD2FMT 0x12000D2
+#define mmAudio_Az_Input_SD2BDPL 0x12000D8
+#define mmAudio_Az_Input_SD2BDPU 0x12000DC
+#define mmAudio_Az_Input_SD3CTL_and_STS 0x12000E0
+#define mmAudio_Az_Input_SD3LPIB 0x12000E4
+#define mmAudio_Az_Input_SD3CBL 0x12000E8
+#define mmAudio_Az_Input_SD3LVI 0x12000EC
+#define mmAudio_Az_Input_SD3FIFOS 0x12000F0
+#define mmAudio_Az_Input_SD3FMT 0x12000F2
+#define mmAudio_Az_Input_SD3BDPL 0x12000F8
+#define mmAudio_Az_Input_SD3BDPU 0x12000FC
+#define mmAudio_Az_Output_SD0CTL_and_STS 0x1200100
+#define mmAudio_Az_Output_SD0LPIB 0x1200104
+#define mmAudio_Az_Output_SD0CBL 0x1200108
+#define mmAudio_Az_Output_SD0LVI 0x120010C
+#define mmAudio_Az_Output_SD0FIFOS 0x1200110
+#define mmAudio_Az_Output_SD0FMT 0x1200112
+#define mmAudio_Az_Output_SD0BDPL 0x1200118
+#define mmAudio_Az_Output_SD0BDPU 0x120011C
+#define mmAudio_Az_Output_SD1CTL_and_STS 0x1200120
+#define mmAudio_Az_Output_SD1LPIB 0x1200124
+#define mmAudio_Az_Output_SD1CBL 0x1200128
+#define mmAudio_Az_Output_SD1LVI 0x120012C
+#define mmAudio_Az_Output_SD1FIFOS 0x1200130
+#define mmAudio_Az_Output_SD1FMT 0x1200132
+#define mmAudio_Az_Output_SD1BDPL 0x1200138
+#define mmAudio_Az_Output_SD1BDPU 0x120013C
+#define mmAudio_Az_Output_SD2CTL_and_STS 0x1200140
+#define mmAudio_Az_Output_SD2LPIB 0x1200144
+#define mmAudio_Az_Output_SD2CBL 0x1200148
+#define mmAudio_Az_Output_SD2LVI 0x120014C
+#define mmAudio_Az_Output_SD2FIFOS 0x1200150
+#define mmAudio_Az_Output_SD2FMT 0x1200152
+#define mmAudio_Az_Output_SD2BDPL 0x1200158
+#define mmAudio_Az_Output_SD2BDPU 0x120015C
+#define mmAudio_Az_Output_SD3CTL_and_STS 0x1200160
+#define mmAudio_Az_Output_SD3LPIB 0x1200164
+#define mmAudio_Az_Output_SD3CBL 0x1200168
+#define mmAudio_Az_Output_SD3LVI 0x120016C
+#define mmAudio_Az_Output_SD3FIFOS 0x1200170
+#define mmAudio_Az_Output_SD3FMT 0x1200172
+#define mmAudio_Az_Output_SD3BDPL 0x1200178
+#define mmAudio_Az_Output_SD3BDPU 0x120017C
+#define mmAudioAZ_Misc_Control_Register_1 0x1200180
+#define mmAudioAZ_Misc_Control_Register_2 0x1200182
+#define mmAudioAZ_Misc_Control_Register_3 0x1200183
+#define mmAudio_AZ_Multiple_Links_Capability_Header 0x1200200
+#define mmAudio_AZ_Multiple_Links_Capability_Declaration 0x1200204
+#define mmAudio_AZ_Link0_Capabilities 0x1200240
+#define mmAudio_AZ_Link0_Control 0x1200244
+#define mmAudio_AZ_Link0_Output_Stream_ID 0x1200248
+#define mmAudio_AZ_Link0_SDI_Identifier 0x120024C
+#define mmAudio_AZ_Link0_Per_Stream_Overhead 0x1200250
+#define mmAudio_AZ_Link0_Wall_Frame_Counter 0x1200258
+#define mmAudio_AZ_Link0_Output_Payload_Capability_L 0x1200260
+#define mmAudio_AZ_Link0_Output_Payload_Capability_U 0x1200264
+#define mmAudio_AZ_Link0_Input_Payload_Capability_L 0x1200270
+#define mmAudio_AZ_Link0_Input_Payload_Capability_U 0x1200274
+#define mmAudio_Az_Input_SD0LICBA 0x1202084
+#define mmAudio_Az_Input_SD1LICBA 0x12020A4
+#define mmAudio_Az_Input_SD2LICBA 0x12020C4
+#define mmAudio_Az_Input_SD3LICBA 0x12020E4
+#define mmAudio_Az_Output_SD0LICBA 0x1202104
+#define mmAudio_Az_Output_SD1LICBA 0x1202124
+#define mmAudio_Az_Output_SD2LICBA 0x1202144
+#define mmAudio_Az_Output_SD3LICBA 0x1202164
+#define mmAUDIO_AZ_POWER_MANAGEMENT_CONTROL 0x1204000
+#define mmAUDIO_AZ_IOC_SOFTRST_CONTROL 0x1204004
+#define mmAUDIO_AZ_IOC_CLKGATE_CONTROL 0x1204008
+
+
+// Registers from ACP_AZALIA block
+
+#define mmACP_AZ_PAGE0_LBASE_ADDR 0x1243800
+#define mmACP_AZ_PAGE0_UBASE_ADDR 0x1243804
+#define mmACP_AZ_PAGE0_PGEN_SIZE 0x1243808
+#define mmACP_AZ_PAGE0_OFFSET 0x124380C
+#define mmACP_AZ_PAGE1_LBASE_ADDR 0x1243810
+#define mmACP_AZ_PAGE1_UBASE_ADDR 0x1243814
+#define mmACP_AZ_PAGE1_PGEN_SIZE 0x1243818
+#define mmACP_AZ_PAGE1_OFFSET 0x124381C
+#define mmACP_AZ_PAGE2_LBASE_ADDR 0x1243820
+#define mmACP_AZ_PAGE2_UBASE_ADDR 0x1243824
+#define mmACP_AZ_PAGE2_PGEN_SIZE 0x1243828
+#define mmACP_AZ_PAGE2_OFFSET 0x124382C
+#define mmACP_AZ_PAGE3_LBASE_ADDR 0x1243830
+#define mmACP_AZ_PAGE3_UBASE_ADDR 0x1243834
+#define mmACP_AZ_PAGE3_PGEN_SIZE 0x1243838
+#define mmACP_AZ_PAGE3_OFFSET 0x124383C
+#define mmACP_AZ_PAGE4_LBASE_ADDR 0x1243840
+#define mmACP_AZ_PAGE4_UBASE_ADDR 0x1243844
+#define mmACP_AZ_PAGE4_PGEN_SIZE 0x1243848
+#define mmACP_AZ_PAGE4_OFFSET 0x124384C
+#define mmACP_AZ_PAGE5_LBASE_ADDR 0x1243850
+#define mmACP_AZ_PAGE5_UBASE_ADDR 0x1243854
+#define mmACP_AZ_PAGE5_PGEN_SIZE 0x1243858
+#define mmACP_AZ_PAGE5_OFFSET 0x124385C
+#define mmACP_AZ_PAGE6_LBASE_ADDR 0x1243860
+#define mmACP_AZ_PAGE6_UBASE_ADDR 0x1243864
+#define mmACP_AZ_PAGE6_PGEN_SIZE 0x1243868
+#define mmACP_AZ_PAGE6_OFFSET 0x124386C
+#define mmACP_AZ_PAGE7_LBASE_ADDR 0x1243870
+#define mmACP_AZ_PAGE7_UBASE_ADDR 0x1243874
+#define mmACP_AZ_PAGE7_PGEN_SIZE 0x1243878
+#define mmACP_AZ_PAGE7_OFFSET 0x124387C
+
+
+#endif
diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c
new file mode 100644
index 0000000000..a013a607b3
--- /dev/null
+++ b/sound/soc/amd/raven/pci-acp3x.c
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ACP PCI Driver
+//
+//Copyright 2016 Advanced Micro Devices, Inc.
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/delay.h>
+
+#include "acp3x.h"
+
+struct acp3x_dev_data {
+ void __iomem *acp3x_base;
+ bool acp3x_audio_mode;
+ struct resource *res;
+ struct platform_device *pdev[ACP3x_DEVS];
+ u32 pme_en;
+};
+
+static int acp3x_power_on(struct acp3x_dev_data *adata)
+{
+ void __iomem *acp3x_base = adata->acp3x_base;
+ u32 val;
+ int timeout;
+
+ val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
+
+ if (val == 0)
+ return val;
+
+ if (!((val & ACP_PGFSM_STATUS_MASK) ==
+ ACP_POWER_ON_IN_PROGRESS))
+ rv_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
+ acp3x_base + mmACP_PGFSM_CONTROL);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
+ if (!val) {
+ /* ACP power On clears PME_EN.
+ * Restore the value to its prior state
+ */
+ rv_writel(adata->pme_en, acp3x_base + mmACP_PME_EN);
+ return 0;
+ }
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int acp3x_reset(void __iomem *acp3x_base)
+{
+ u32 val;
+ int timeout;
+
+ rv_writel(1, acp3x_base + mmACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
+ if (val & ACP3x_SOFT_RESET__SoftResetAudDone_MASK)
+ break;
+ cpu_relax();
+ }
+ rv_writel(0, acp3x_base + mmACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
+ if (!val)
+ return 0;
+ cpu_relax();
+ }
+ return -ETIMEDOUT;
+}
+
+static void acp3x_enable_interrupts(void __iomem *acp_base)
+{
+ rv_writel(0x01, acp_base + mmACP_EXTERNAL_INTR_ENB);
+}
+
+static void acp3x_disable_interrupts(void __iomem *acp_base)
+{
+ rv_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base +
+ mmACP_EXTERNAL_INTR_STAT);
+ rv_writel(0x00, acp_base + mmACP_EXTERNAL_INTR_CNTL);
+ rv_writel(0x00, acp_base + mmACP_EXTERNAL_INTR_ENB);
+}
+
+static int acp3x_init(struct acp3x_dev_data *adata)
+{
+ void __iomem *acp3x_base = adata->acp3x_base;
+ int ret;
+
+ /* power on */
+ ret = acp3x_power_on(adata);
+ if (ret) {
+ pr_err("ACP3x power on failed\n");
+ return ret;
+ }
+ /* Reset */
+ ret = acp3x_reset(acp3x_base);
+ if (ret) {
+ pr_err("ACP3x reset failed\n");
+ return ret;
+ }
+ acp3x_enable_interrupts(acp3x_base);
+ return 0;
+}
+
+static int acp3x_deinit(void __iomem *acp3x_base)
+{
+ int ret;
+
+ acp3x_disable_interrupts(acp3x_base);
+ /* Reset */
+ ret = acp3x_reset(acp3x_base);
+ if (ret) {
+ pr_err("ACP3x reset failed\n");
+ return ret;
+ }
+ return 0;
+}
+
+static int snd_acp3x_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ struct acp3x_dev_data *adata;
+ struct platform_device_info pdevinfo[ACP3x_DEVS];
+ unsigned int irqflags;
+ int ret, i;
+ u32 addr, val;
+
+ /* Raven device detection */
+ if (pci->revision != 0x00)
+ return -ENODEV;
+
+ if (pci_enable_device(pci)) {
+ dev_err(&pci->dev, "pci_enable_device failed\n");
+ return -ENODEV;
+ }
+
+ ret = pci_request_regions(pci, "AMD ACP3x audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+ }
+
+ adata = devm_kzalloc(&pci->dev, sizeof(struct acp3x_dev_data),
+ GFP_KERNEL);
+ if (!adata) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+
+ irqflags = IRQF_SHARED;
+
+ addr = pci_resource_start(pci, 0);
+ adata->acp3x_base = devm_ioremap(&pci->dev, addr,
+ pci_resource_len(pci, 0));
+ if (!adata->acp3x_base) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+ pci_set_master(pci);
+ pci_set_drvdata(pci, adata);
+ /* Save ACP_PME_EN state */
+ adata->pme_en = rv_readl(adata->acp3x_base + mmACP_PME_EN);
+ ret = acp3x_init(adata);
+ if (ret)
+ goto release_regions;
+
+ val = rv_readl(adata->acp3x_base + mmACP_I2S_PIN_CONFIG);
+ switch (val) {
+ case I2S_MODE:
+ adata->res = devm_kzalloc(&pci->dev,
+ sizeof(struct resource) * 4,
+ GFP_KERNEL);
+ if (!adata->res) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+
+ adata->res[0].name = "acp3x_i2s_iomem";
+ adata->res[0].flags = IORESOURCE_MEM;
+ adata->res[0].start = addr;
+ adata->res[0].end = addr + (ACP3x_REG_END - ACP3x_REG_START);
+
+ adata->res[1].name = "acp3x_i2s_sp";
+ adata->res[1].flags = IORESOURCE_MEM;
+ adata->res[1].start = addr + ACP3x_I2STDM_REG_START;
+ adata->res[1].end = addr + ACP3x_I2STDM_REG_END;
+
+ adata->res[2].name = "acp3x_i2s_bt";
+ adata->res[2].flags = IORESOURCE_MEM;
+ adata->res[2].start = addr + ACP3x_BT_TDM_REG_START;
+ adata->res[2].end = addr + ACP3x_BT_TDM_REG_END;
+
+ adata->res[3].name = "acp3x_i2s_irq";
+ adata->res[3].flags = IORESOURCE_IRQ;
+ adata->res[3].start = pci->irq;
+ adata->res[3].end = adata->res[3].start;
+
+ adata->acp3x_audio_mode = ACP3x_I2S_MODE;
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ pdevinfo[0].name = "acp3x_rv_i2s_dma";
+ pdevinfo[0].id = 0;
+ pdevinfo[0].parent = &pci->dev;
+ pdevinfo[0].num_res = 4;
+ pdevinfo[0].res = &adata->res[0];
+ pdevinfo[0].data = &irqflags;
+ pdevinfo[0].size_data = sizeof(irqflags);
+
+ pdevinfo[1].name = "acp3x_i2s_playcap";
+ pdevinfo[1].id = 0;
+ pdevinfo[1].parent = &pci->dev;
+ pdevinfo[1].num_res = 1;
+ pdevinfo[1].res = &adata->res[1];
+
+ pdevinfo[2].name = "acp3x_i2s_playcap";
+ pdevinfo[2].id = 1;
+ pdevinfo[2].parent = &pci->dev;
+ pdevinfo[2].num_res = 1;
+ pdevinfo[2].res = &adata->res[1];
+
+ pdevinfo[3].name = "acp3x_i2s_playcap";
+ pdevinfo[3].id = 2;
+ pdevinfo[3].parent = &pci->dev;
+ pdevinfo[3].num_res = 1;
+ pdevinfo[3].res = &adata->res[2];
+ for (i = 0; i < ACP3x_DEVS; i++) {
+ adata->pdev[i] =
+ platform_device_register_full(&pdevinfo[i]);
+ if (IS_ERR(adata->pdev[i])) {
+ dev_err(&pci->dev, "cannot register %s device\n",
+ pdevinfo[i].name);
+ ret = PTR_ERR(adata->pdev[i]);
+ goto unregister_devs;
+ }
+ }
+ break;
+ default:
+ dev_info(&pci->dev, "ACP audio mode : %d\n", val);
+ break;
+ }
+ pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_put_noidle(&pci->dev);
+ pm_runtime_allow(&pci->dev);
+ return 0;
+
+unregister_devs:
+ if (val == I2S_MODE)
+ for (i = 0; i < ACP3x_DEVS; i++)
+ platform_device_unregister(adata->pdev[i]);
+de_init:
+ if (acp3x_deinit(adata->acp3x_base))
+ dev_err(&pci->dev, "ACP de-init failed\n");
+release_regions:
+ pci_release_regions(pci);
+disable_pci:
+ pci_disable_device(pci);
+
+ return ret;
+}
+
+static int snd_acp3x_suspend(struct device *dev)
+{
+ int ret;
+ struct acp3x_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = acp3x_deinit(adata->acp3x_base);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+ else
+ dev_dbg(dev, "ACP de-initialized\n");
+
+ return 0;
+}
+
+static int snd_acp3x_resume(struct device *dev)
+{
+ int ret;
+ struct acp3x_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = acp3x_init(adata);
+ if (ret) {
+ dev_err(dev, "ACP init failed\n");
+ return ret;
+ }
+ return 0;
+}
+
+static const struct dev_pm_ops acp3x_pm = {
+ .runtime_suspend = snd_acp3x_suspend,
+ .runtime_resume = snd_acp3x_resume,
+ .resume = snd_acp3x_resume,
+};
+
+static void snd_acp3x_remove(struct pci_dev *pci)
+{
+ struct acp3x_dev_data *adata;
+ int i, ret;
+
+ adata = pci_get_drvdata(pci);
+ if (adata->acp3x_audio_mode == ACP3x_I2S_MODE) {
+ for (i = 0; i < ACP3x_DEVS; i++)
+ platform_device_unregister(adata->pdev[i]);
+ }
+ ret = acp3x_deinit(adata->acp3x_base);
+ if (ret)
+ dev_err(&pci->dev, "ACP de-init failed\n");
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_get_noresume(&pci->dev);
+ pci_release_regions(pci);
+ pci_disable_device(pci);
+}
+
+static const struct pci_device_id snd_acp3x_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x15e2),
+ .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
+ .class_mask = 0xffffff },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_acp3x_ids);
+
+static struct pci_driver acp3x_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = snd_acp3x_ids,
+ .probe = snd_acp3x_probe,
+ .remove = snd_acp3x_remove,
+ .driver = {
+ .pm = &acp3x_pm,
+ }
+};
+
+module_pci_driver(acp3x_driver);
+
+MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
+MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
+MODULE_DESCRIPTION("AMD ACP3x PCI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/renoir/Makefile b/sound/soc/amd/renoir/Makefile
new file mode 100644
index 0000000000..4a82690aec
--- /dev/null
+++ b/sound/soc/amd/renoir/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Renoir platform Support
+snd-rn-pci-acp3x-objs := rn-pci-acp3x.o
+snd-acp3x-pdm-dma-objs := acp3x-pdm-dma.o
+snd-acp3x-rn-objs := acp3x-rn.o
+obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-rn-pci-acp3x.o
+obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-acp3x-pdm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_RENOIR_MACH) += snd-acp3x-rn.o
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
new file mode 100644
index 0000000000..c3b47e9bd2
--- /dev/null
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -0,0 +1,504 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ALSA SoC PDM Driver
+//
+//Copyright 2020 Advanced Micro Devices, Inc.
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/bitfield.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+#include "rn_acp3x.h"
+
+#define DRV_NAME "acp_rn_pdm_dma"
+
+static int pdm_gain = 3;
+module_param(pdm_gain, int, 0644);
+MODULE_PARM_DESC(pdm_gain, "Gain control (0-3)");
+
+static const struct snd_pcm_hardware acp_pdm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
+static irqreturn_t pdm_irq_handler(int irq, void *dev_id)
+{
+ struct pdm_dev_data *rn_pdm_data;
+ u16 cap_flag;
+ u32 val;
+
+ rn_pdm_data = dev_id;
+ if (!rn_pdm_data)
+ return IRQ_NONE;
+
+ cap_flag = 0;
+ val = rn_readl(rn_pdm_data->acp_base + ACP_EXTERNAL_INTR_STAT);
+ if ((val & BIT(PDM_DMA_STAT)) && rn_pdm_data->capture_stream) {
+ rn_writel(BIT(PDM_DMA_STAT), rn_pdm_data->acp_base +
+ ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(rn_pdm_data->capture_stream);
+ cap_flag = 1;
+ }
+
+ if (cap_flag)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static void init_pdm_ring_buffer(u32 physical_addr,
+ u32 buffer_size,
+ u32 watermark_size,
+ void __iomem *acp_base)
+{
+ rn_writel(physical_addr, acp_base + ACP_WOV_RX_RINGBUFADDR);
+ rn_writel(buffer_size, acp_base + ACP_WOV_RX_RINGBUFSIZE);
+ rn_writel(watermark_size, acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
+ rn_writel(0x01, acp_base + ACPAXI2AXI_ATU_CTRL);
+}
+
+static void enable_pdm_clock(void __iomem *acp_base)
+{
+ u32 pdm_clk_enable, pdm_ctrl;
+
+ pdm_clk_enable = ACP_PDM_CLK_FREQ_MASK;
+
+ rn_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
+ pdm_ctrl = rn_readl(acp_base + ACP_WOV_MISC_CTRL);
+ pdm_ctrl &= ~ACP_WOV_GAIN_CONTROL;
+ pdm_ctrl |= FIELD_PREP(ACP_WOV_GAIN_CONTROL, clamp(pdm_gain, 0, 3));
+ rn_writel(pdm_ctrl, acp_base + ACP_WOV_MISC_CTRL);
+}
+
+static void enable_pdm_interrupts(void __iomem *acp_base)
+{
+ u32 ext_int_ctrl;
+
+ ext_int_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_int_ctrl |= PDM_DMA_INTR_MASK;
+ rn_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static void disable_pdm_interrupts(void __iomem *acp_base)
+{
+ u32 ext_int_ctrl;
+
+ ext_int_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_int_ctrl |= ~PDM_DMA_INTR_MASK;
+ rn_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static bool check_pdm_dma_status(void __iomem *acp_base)
+{
+ bool pdm_dma_status;
+ u32 pdm_enable, pdm_dma_enable;
+
+ pdm_dma_status = false;
+ pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
+ pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_enable & ACP_PDM_ENABLE) && (pdm_dma_enable &
+ ACP_PDM_DMA_EN_STATUS))
+ pdm_dma_status = true;
+ return pdm_dma_status;
+}
+
+static int start_pdm_dma(void __iomem *acp_base)
+{
+ u32 pdm_enable;
+ u32 pdm_dma_enable;
+ int timeout;
+
+ pdm_enable = 0x01;
+ pdm_dma_enable = 0x01;
+
+ enable_pdm_clock(acp_base);
+ rn_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
+ rn_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ timeout = 0;
+ while (++timeout < ACP_COUNTER) {
+ pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_dma_enable & 0x02) == ACP_PDM_DMA_EN_STATUS)
+ return 0;
+ udelay(DELAY_US);
+ }
+ return -ETIMEDOUT;
+}
+
+static int stop_pdm_dma(void __iomem *acp_base)
+{
+ u32 pdm_enable, pdm_dma_enable;
+ int timeout;
+
+ pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
+ pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if (pdm_dma_enable & 0x01) {
+ pdm_dma_enable = 0x02;
+ rn_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ timeout = 0;
+ while (++timeout < ACP_COUNTER) {
+ pdm_dma_enable = rn_readl(acp_base +
+ ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_dma_enable & 0x02) == 0x00)
+ break;
+ udelay(DELAY_US);
+ }
+ if (timeout == ACP_COUNTER)
+ return -ETIMEDOUT;
+ }
+ if (pdm_enable == ACP_PDM_ENABLE) {
+ pdm_enable = ACP_PDM_DISABLE;
+ rn_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
+ }
+ rn_writel(0x01, acp_base + ACP_WOV_PDM_FIFO_FLUSH);
+ return 0;
+}
+
+static void config_acp_dma(struct pdm_stream_instance *rtd, int direction)
+{
+ u16 page_idx;
+ u32 low, high, val;
+ dma_addr_t addr;
+
+ addr = rtd->dma_addr;
+ val = 0;
+
+ /* Group Enable */
+ rn_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp_base +
+ ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
+ rn_writel(PAGE_SIZE_4K_ENABLE, rtd->acp_base +
+ ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
+
+ for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+
+ rn_writel(low, rtd->acp_base + ACP_SCRATCH_REG_0 + val);
+ high |= BIT(31);
+ rn_writel(high, rtd->acp_base + ACP_SCRATCH_REG_0 + val + 4);
+ val += 8;
+ addr += PAGE_SIZE;
+ }
+}
+
+static int acp_pdm_dma_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime;
+ struct pdm_dev_data *adata;
+ struct pdm_stream_instance *pdm_data;
+ int ret;
+
+ runtime = substream->runtime;
+ adata = dev_get_drvdata(component->dev);
+ pdm_data = kzalloc(sizeof(*pdm_data), GFP_KERNEL);
+ if (!pdm_data)
+ return -EINVAL;
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ runtime->hw = acp_pdm_hardware_capture;
+
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(pdm_data);
+ return ret;
+ }
+
+ enable_pdm_interrupts(adata->acp_base);
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ adata->capture_stream = substream;
+
+ pdm_data->acp_base = adata->acp_base;
+ runtime->private_data = pdm_data;
+ return ret;
+}
+
+static int acp_pdm_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct pdm_stream_instance *rtd;
+ size_t size, period_bytes;
+
+ rtd = substream->runtime->private_data;
+ if (!rtd)
+ return -EINVAL;
+ size = params_buffer_bytes(params);
+ period_bytes = params_period_bytes(params);
+ rtd->dma_addr = substream->runtime->dma_addr;
+ rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+ config_acp_dma(rtd, substream->stream);
+ init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes,
+ rtd->acp_base);
+ return 0;
+}
+
+static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd,
+ int direction)
+{
+ union acp_pdm_dma_count byte_count;
+
+ byte_count.bcount.high =
+ rn_readl(rtd->acp_base +
+ ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);
+ byte_count.bcount.low =
+ rn_readl(rtd->acp_base +
+ ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);
+ return byte_count.bytescount;
+}
+
+static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp,
+ struct snd_pcm_substream *stream)
+{
+ struct pdm_stream_instance *rtd;
+ u32 pos, buffersize;
+ u64 bytescount;
+
+ rtd = stream->runtime->private_data;
+ buffersize = frames_to_bytes(stream->runtime,
+ stream->runtime->buffer_size);
+ bytescount = acp_pdm_get_byte_count(rtd, stream->stream);
+ if (bytescount > rtd->bytescount)
+ bytescount -= rtd->bytescount;
+ pos = do_div(bytescount, buffersize);
+ return bytes_to_frames(stream->runtime, pos);
+}
+
+static int acp_pdm_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct device *parent = component->dev->parent;
+
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ parent, MIN_BUFFER, MAX_BUFFER);
+ return 0;
+}
+
+static int acp_pdm_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
+
+ disable_pdm_interrupts(adata->acp_base);
+ adata->capture_stream = NULL;
+ return 0;
+}
+
+static int acp_pdm_dai_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct pdm_stream_instance *rtd;
+ int ret;
+ bool pdm_status;
+ unsigned int ch_mask;
+
+ rtd = substream->runtime->private_data;
+ ret = 0;
+ switch (substream->runtime->channels) {
+ case TWO_CH:
+ ch_mask = 0x00;
+ break;
+ default:
+ return -EINVAL;
+ }
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ rn_writel(ch_mask, rtd->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
+ rn_writel(PDM_DECIMATION_FACTOR, rtd->acp_base +
+ ACP_WOV_PDM_DECIMATION_FACTOR);
+ rtd->bytescount = acp_pdm_get_byte_count(rtd,
+ substream->stream);
+ pdm_status = check_pdm_dma_status(rtd->acp_base);
+ if (!pdm_status)
+ ret = start_pdm_dma(rtd->acp_base);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ pdm_status = check_pdm_dma_status(rtd->acp_base);
+ if (pdm_status)
+ ret = stop_pdm_dma(rtd->acp_base);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static const struct snd_soc_dai_ops acp_pdm_dai_ops = {
+ .trigger = acp_pdm_dai_trigger,
+};
+
+static struct snd_soc_dai_driver acp_pdm_dai_driver = {
+ .capture = {
+ .rates = SNDRV_PCM_RATE_48000,
+ .formats = SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ },
+ .ops = &acp_pdm_dai_ops,
+};
+
+static const struct snd_soc_component_driver acp_pdm_component = {
+ .name = DRV_NAME,
+ .open = acp_pdm_dma_open,
+ .close = acp_pdm_dma_close,
+ .hw_params = acp_pdm_dma_hw_params,
+ .pointer = acp_pdm_dma_pointer,
+ .pcm_construct = acp_pdm_dma_new,
+ .legacy_dai_naming = 1,
+};
+
+static int acp_pdm_audio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct pdm_dev_data *adata;
+ unsigned int irqflags;
+ int status;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "platform_data not retrieved\n");
+ return -ENODEV;
+ }
+ irqflags = *((unsigned int *)(pdev->dev.platform_data));
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ adata->acp_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!adata->acp_base)
+ return -ENOMEM;
+
+ status = platform_get_irq(pdev, 0);
+ if (status < 0)
+ return status;
+ adata->pdm_irq = status;
+
+ adata->capture_stream = NULL;
+
+ dev_set_drvdata(&pdev->dev, adata);
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp_pdm_component,
+ &acp_pdm_dai_driver, 1);
+ if (status) {
+ dev_err(&pdev->dev, "Fail to register acp pdm dai\n");
+
+ return -ENODEV;
+ }
+ status = devm_request_irq(&pdev->dev, adata->pdm_irq, pdm_irq_handler,
+ irqflags, "ACP_PDM_IRQ", adata);
+ if (status) {
+ dev_err(&pdev->dev, "ACP PDM IRQ request failed\n");
+ return -ENODEV;
+ }
+ pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ return 0;
+}
+
+static void acp_pdm_audio_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int acp_pdm_resume(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+ struct snd_pcm_runtime *runtime;
+ struct pdm_stream_instance *rtd;
+ u32 period_bytes, buffer_len;
+
+ adata = dev_get_drvdata(dev);
+ if (adata->capture_stream && adata->capture_stream->runtime) {
+ runtime = adata->capture_stream->runtime;
+ rtd = runtime->private_data;
+ period_bytes = frames_to_bytes(runtime, runtime->period_size);
+ buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
+ config_acp_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
+ init_pdm_ring_buffer(MEM_WINDOW_START, buffer_len, period_bytes,
+ adata->acp_base);
+ }
+ enable_pdm_interrupts(adata->acp_base);
+ return 0;
+}
+
+static int acp_pdm_runtime_suspend(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ disable_pdm_interrupts(adata->acp_base);
+
+ return 0;
+}
+
+static int acp_pdm_runtime_resume(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ enable_pdm_interrupts(adata->acp_base);
+ return 0;
+}
+
+static const struct dev_pm_ops acp_pdm_pm_ops = {
+ .runtime_suspend = acp_pdm_runtime_suspend,
+ .runtime_resume = acp_pdm_runtime_resume,
+ .resume = acp_pdm_resume,
+};
+
+static struct platform_driver acp_pdm_dma_driver = {
+ .probe = acp_pdm_audio_probe,
+ .remove_new = acp_pdm_audio_remove,
+ .driver = {
+ .name = "acp_rn_pdm_dma",
+ .pm = &acp_pdm_pm_ops,
+ },
+};
+
+module_platform_driver(acp_pdm_dma_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP3x Renior PDM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/renoir/acp3x-rn.c b/sound/soc/amd/renoir/acp3x-rn.c
new file mode 100644
index 0000000000..5d979a7b77
--- /dev/null
+++ b/sound/soc/amd/renoir/acp3x-rn.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Machine driver for AMD Renoir platform using DMIC
+//
+//Copyright 2020 Advanced Micro Devices, Inc.
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/module.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <linux/io.h>
+
+#include "rn_acp3x.h"
+
+#define DRV_NAME "acp_pdm_mach"
+
+SND_SOC_DAILINK_DEF(acp_pdm,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp_rn_pdm_dma.0")));
+
+SND_SOC_DAILINK_DEF(dmic_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec.0",
+ "dmic-hifi")));
+
+SND_SOC_DAILINK_DEF(platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_rn_pdm_dma.0")));
+
+static struct snd_soc_dai_link acp_dai_pdm[] = {
+ {
+ .name = "acp3x-dmic-capture",
+ .stream_name = "DMIC capture",
+ .capture_only = 1,
+ SND_SOC_DAILINK_REG(acp_pdm, dmic_codec, platform),
+ },
+};
+
+static struct snd_soc_card acp_card = {
+ .name = "acp",
+ .owner = THIS_MODULE,
+ .dai_link = acp_dai_pdm,
+ .num_links = 1,
+};
+
+static int acp_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct acp_pdm *machine = NULL;
+ struct snd_soc_card *card;
+
+ card = &acp_card;
+ acp_card.dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, machine);
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret) {
+ return dev_err_probe(&pdev->dev, ret,
+ "snd_soc_register_card(%s) failed\n",
+ card->name);
+ }
+ return 0;
+}
+
+static struct platform_driver acp_mach_driver = {
+ .driver = {
+ .name = "acp_pdm_mach",
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = acp_probe,
+};
+
+module_platform_driver(acp_mach_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c
new file mode 100644
index 0000000000..b3812b70f5
--- /dev/null
+++ b/sound/soc/amd/renoir/rn-pci-acp3x.c
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD Renoir ACP PCI Driver
+//
+//Copyright 2020 Advanced Micro Devices, Inc.
+
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+
+#include "rn_acp3x.h"
+
+static int acp_power_gating;
+module_param(acp_power_gating, int, 0644);
+MODULE_PARM_DESC(acp_power_gating, "Enable acp power gating");
+
+/*
+ * dmic_acpi_check = -1 - Use ACPI/DMI method to detect the DMIC hardware presence at runtime
+ * = 0 - Skip the DMIC device creation and return probe failure
+ * = 1 - Force DMIC support
+ */
+static int dmic_acpi_check = ACP_DMIC_AUTO;
+module_param(dmic_acpi_check, bint, 0644);
+MODULE_PARM_DESC(dmic_acpi_check, "Digital microphone presence (-1=auto, 0=none, 1=force)");
+
+struct acp_dev_data {
+ void __iomem *acp_base;
+ struct resource *res;
+ struct platform_device *pdev[ACP_DEVS];
+};
+
+static int rn_acp_power_on(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ val = rn_readl(acp_base + ACP_PGFSM_STATUS);
+
+ if (val == 0)
+ return val;
+
+ if ((val & ACP_PGFSM_STATUS_MASK) !=
+ ACP_POWER_ON_IN_PROGRESS)
+ rn_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
+ acp_base + ACP_PGFSM_CONTROL);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rn_readl(acp_base + ACP_PGFSM_STATUS);
+ if (!val)
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int rn_acp_power_off(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ rn_writel(ACP_PGFSM_CNTL_POWER_OFF_MASK,
+ acp_base + ACP_PGFSM_CONTROL);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rn_readl(acp_base + ACP_PGFSM_STATUS);
+ if ((val & ACP_PGFSM_STATUS_MASK) == ACP_POWERED_OFF)
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int rn_acp_reset(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ rn_writel(1, acp_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rn_readl(acp_base + ACP_SOFT_RESET);
+ if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
+ break;
+ cpu_relax();
+ }
+ rn_writel(0, acp_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rn_readl(acp_base + ACP_SOFT_RESET);
+ if (!val)
+ return 0;
+ cpu_relax();
+ }
+ return -ETIMEDOUT;
+}
+
+static void rn_acp_enable_interrupts(void __iomem *acp_base)
+{
+ u32 ext_intr_ctrl;
+
+ rn_writel(0x01, acp_base + ACP_EXTERNAL_INTR_ENB);
+ ext_intr_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_intr_ctrl |= ACP_ERROR_MASK;
+ rn_writel(ext_intr_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static void rn_acp_disable_interrupts(void __iomem *acp_base)
+{
+ rn_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base +
+ ACP_EXTERNAL_INTR_STAT);
+ rn_writel(0x00, acp_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static int rn_acp_init(void __iomem *acp_base)
+{
+ int ret;
+
+ /* power on */
+ ret = rn_acp_power_on(acp_base);
+ if (ret) {
+ pr_err("ACP power on failed\n");
+ return ret;
+ }
+ rn_writel(0x01, acp_base + ACP_CONTROL);
+ /* Reset */
+ ret = rn_acp_reset(acp_base);
+ if (ret) {
+ pr_err("ACP reset failed\n");
+ return ret;
+ }
+ rn_writel(0x03, acp_base + ACP_CLKMUX_SEL);
+ rn_acp_enable_interrupts(acp_base);
+ return 0;
+}
+
+static int rn_acp_deinit(void __iomem *acp_base)
+{
+ int ret;
+
+ rn_acp_disable_interrupts(acp_base);
+ /* Reset */
+ ret = rn_acp_reset(acp_base);
+ if (ret) {
+ pr_err("ACP reset failed\n");
+ return ret;
+ }
+ rn_writel(0x00, acp_base + ACP_CLKMUX_SEL);
+ rn_writel(0x00, acp_base + ACP_CONTROL);
+ /* power off */
+ if (acp_power_gating) {
+ ret = rn_acp_power_off(acp_base);
+ if (ret) {
+ pr_err("ACP power off failed\n");
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static const struct dmi_system_id rn_acp_quirk_table[] = {
+ {
+ /* Lenovo IdeaPad S340-14API */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81NB"),
+ }
+ },
+ {
+ /* Lenovo IdeaPad Flex 5 14ARE05 */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81X2"),
+ }
+ },
+ {
+ /* Lenovo IdeaPad 5 15ARE05 */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81YQ"),
+ }
+ },
+ {
+ /* Lenovo ThinkPad E14 Gen 2 */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "20T6CTO1WW"),
+ }
+ },
+ {
+ /* Lenovo ThinkPad X395 */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "20NLCTO1WW"),
+ }
+ },
+ {}
+};
+
+static int snd_rn_acp_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ struct acp_dev_data *adata;
+ struct platform_device_info pdevinfo[ACP_DEVS];
+#if defined(CONFIG_ACPI)
+ acpi_handle handle;
+ acpi_integer dmic_status;
+#endif
+ const struct dmi_system_id *dmi_id;
+ unsigned int irqflags, flag;
+ int ret, index;
+ u32 addr;
+
+ /* Return if acp config flag is defined */
+ flag = snd_amd_acp_find_config(pci);
+ if (flag)
+ return -ENODEV;
+
+ /* Renoir device check */
+ if (pci->revision != 0x01)
+ return -ENODEV;
+
+ if (pci_enable_device(pci)) {
+ dev_err(&pci->dev, "pci_enable_device failed\n");
+ return -ENODEV;
+ }
+
+ ret = pci_request_regions(pci, "AMD ACP3x audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+ }
+
+ adata = devm_kzalloc(&pci->dev, sizeof(struct acp_dev_data),
+ GFP_KERNEL);
+ if (!adata) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+
+ /* check for msi interrupt support */
+ ret = pci_enable_msi(pci);
+ if (ret)
+ /* msi is not enabled */
+ irqflags = IRQF_SHARED;
+ else
+ /* msi is enabled */
+ irqflags = 0;
+
+ addr = pci_resource_start(pci, 0);
+ adata->acp_base = devm_ioremap(&pci->dev, addr,
+ pci_resource_len(pci, 0));
+ if (!adata->acp_base) {
+ ret = -ENOMEM;
+ goto disable_msi;
+ }
+ pci_set_master(pci);
+ pci_set_drvdata(pci, adata);
+ ret = rn_acp_init(adata->acp_base);
+ if (ret)
+ goto disable_msi;
+
+ if (!dmic_acpi_check) {
+ ret = -ENODEV;
+ goto de_init;
+ } else if (dmic_acpi_check == ACP_DMIC_AUTO) {
+#if defined(CONFIG_ACPI)
+ handle = ACPI_HANDLE(&pci->dev);
+ ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status);
+ if (ACPI_FAILURE(ret)) {
+ ret = -ENODEV;
+ goto de_init;
+ }
+ if (!dmic_status) {
+ ret = -ENODEV;
+ goto de_init;
+ }
+#endif
+ dmi_id = dmi_first_match(rn_acp_quirk_table);
+ if (dmi_id && !dmi_id->driver_data) {
+ dev_info(&pci->dev, "ACPI settings override using DMI (ACP mic is not present)");
+ ret = -ENODEV;
+ goto de_init;
+ }
+ }
+
+ adata->res = devm_kzalloc(&pci->dev,
+ sizeof(struct resource) * 2,
+ GFP_KERNEL);
+ if (!adata->res) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+
+ adata->res[0].name = "acp_pdm_iomem";
+ adata->res[0].flags = IORESOURCE_MEM;
+ adata->res[0].start = addr;
+ adata->res[0].end = addr + (ACP_REG_END - ACP_REG_START);
+ adata->res[1].name = "acp_pdm_irq";
+ adata->res[1].flags = IORESOURCE_IRQ;
+ adata->res[1].start = pci->irq;
+ adata->res[1].end = pci->irq;
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ pdevinfo[0].name = "acp_rn_pdm_dma";
+ pdevinfo[0].id = 0;
+ pdevinfo[0].parent = &pci->dev;
+ pdevinfo[0].num_res = 2;
+ pdevinfo[0].res = adata->res;
+ pdevinfo[0].data = &irqflags;
+ pdevinfo[0].size_data = sizeof(irqflags);
+
+ pdevinfo[1].name = "dmic-codec";
+ pdevinfo[1].id = 0;
+ pdevinfo[1].parent = &pci->dev;
+ pdevinfo[2].name = "acp_pdm_mach";
+ pdevinfo[2].id = 0;
+ pdevinfo[2].parent = &pci->dev;
+ for (index = 0; index < ACP_DEVS; index++) {
+ adata->pdev[index] =
+ platform_device_register_full(&pdevinfo[index]);
+ if (IS_ERR(adata->pdev[index])) {
+ dev_err(&pci->dev, "cannot register %s device\n",
+ pdevinfo[index].name);
+ ret = PTR_ERR(adata->pdev[index]);
+ goto unregister_devs;
+ }
+ }
+ pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_put_noidle(&pci->dev);
+ pm_runtime_allow(&pci->dev);
+ return 0;
+
+unregister_devs:
+ for (index = 0; index < ACP_DEVS; index++)
+ platform_device_unregister(adata->pdev[index]);
+de_init:
+ if (rn_acp_deinit(adata->acp_base))
+ dev_err(&pci->dev, "ACP de-init failed\n");
+disable_msi:
+ pci_disable_msi(pci);
+release_regions:
+ pci_release_regions(pci);
+disable_pci:
+ pci_disable_device(pci);
+
+ return ret;
+}
+
+static int snd_rn_acp_suspend(struct device *dev)
+{
+ int ret;
+ struct acp_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = rn_acp_deinit(adata->acp_base);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+ else
+ dev_dbg(dev, "ACP de-initialized\n");
+
+ return ret;
+}
+
+static int snd_rn_acp_resume(struct device *dev)
+{
+ int ret;
+ struct acp_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = rn_acp_init(adata->acp_base);
+ if (ret) {
+ dev_err(dev, "ACP init failed\n");
+ return ret;
+ }
+ return 0;
+}
+
+static const struct dev_pm_ops rn_acp_pm = {
+ .runtime_suspend = snd_rn_acp_suspend,
+ .runtime_resume = snd_rn_acp_resume,
+ .suspend = snd_rn_acp_suspend,
+ .resume = snd_rn_acp_resume,
+ .restore = snd_rn_acp_resume,
+ .poweroff = snd_rn_acp_suspend,
+};
+
+static void snd_rn_acp_remove(struct pci_dev *pci)
+{
+ struct acp_dev_data *adata;
+ int ret, index;
+
+ adata = pci_get_drvdata(pci);
+ for (index = 0; index < ACP_DEVS; index++)
+ platform_device_unregister(adata->pdev[index]);
+ ret = rn_acp_deinit(adata->acp_base);
+ if (ret)
+ dev_err(&pci->dev, "ACP de-init failed\n");
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_get_noresume(&pci->dev);
+ pci_disable_msi(pci);
+ pci_release_regions(pci);
+ pci_disable_device(pci);
+}
+
+static const struct pci_device_id snd_rn_acp_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
+ .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
+ .class_mask = 0xffffff },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_rn_acp_ids);
+
+static struct pci_driver rn_acp_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = snd_rn_acp_ids,
+ .probe = snd_rn_acp_probe,
+ .remove = snd_rn_acp_remove,
+ .driver = {
+ .pm = &rn_acp_pm,
+ }
+};
+
+module_pci_driver(rn_acp_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP Renoir PCI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
new file mode 100644
index 0000000000..7d0f4e6a28
--- /dev/null
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ALSA SoC PDM Driver
+ *
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ */
+
+#include "rn_chip_offset_byte.h"
+
+#define ACP_DEVS 3
+#define ACP_PHY_BASE_ADDRESS 0x1240000
+#define ACP_REG_START 0x1240000
+#define ACP_REG_END 0x1250200
+
+#define ACP_DEVICE_ID 0x15E2
+#define ACP_POWER_ON 0x00
+#define ACP_POWER_ON_IN_PROGRESS 0x01
+#define ACP_POWER_OFF 0x02
+#define ACP_POWER_OFF_IN_PROGRESS 0x03
+#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
+
+#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00
+#define ACP_PGFSM_STATUS_MASK 0x03
+#define ACP_POWERED_ON 0x00
+#define ACP_POWER_ON_IN_PROGRESS 0x01
+#define ACP_POWERED_OFF 0x02
+#define ACP_POWER_OFF_IN_PROGRESS 0x03
+
+#define ACP_ERROR_MASK 0x20000000
+#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
+#define PDM_DMA_STAT 0x10
+#define PDM_DMA_INTR_MASK 0x10000
+#define ACP_ERROR_STAT 29
+#define PDM_DECIMATION_FACTOR 0x2
+#define ACP_PDM_CLK_FREQ_MASK 0x07
+#define ACP_WOV_GAIN_CONTROL GENMASK(4, 3)
+#define ACP_PDM_ENABLE 0x01
+#define ACP_PDM_DISABLE 0x00
+#define ACP_PDM_DMA_EN_STATUS 0x02
+#define TWO_CH 0x02
+#define DELAY_US 5
+#define ACP_COUNTER 20000
+/* time in ms for runtime suspend delay */
+#define ACP_SUSPEND_DELAY_MS 2000
+
+#define ACP_SRAM_PTE_OFFSET 0x02050000
+#define PAGE_SIZE_4K_ENABLE 0x2
+#define MEM_WINDOW_START 0x4000000
+
+#define CAPTURE_MIN_NUM_PERIODS 4
+#define CAPTURE_MAX_NUM_PERIODS 4
+#define CAPTURE_MAX_PERIOD_SIZE 8192
+#define CAPTURE_MIN_PERIOD_SIZE 4096
+
+#define MAX_BUFFER (CAPTURE_MAX_PERIOD_SIZE * CAPTURE_MAX_NUM_PERIODS)
+#define MIN_BUFFER MAX_BUFFER
+#define ACP_DMIC_AUTO -1
+
+struct pdm_dev_data {
+ u32 pdm_irq;
+ void __iomem *acp_base;
+ struct snd_pcm_substream *capture_stream;
+};
+
+struct pdm_stream_instance {
+ u16 num_pages;
+ u16 channels;
+ dma_addr_t dma_addr;
+ u64 bytescount;
+ void __iomem *acp_base;
+};
+
+union acp_pdm_dma_count {
+ struct {
+ u32 low;
+ u32 high;
+ } bcount;
+ u64 bytescount;
+};
+
+static inline u32 rn_readl(void __iomem *base_addr)
+{
+ return readl(base_addr - ACP_PHY_BASE_ADDRESS);
+}
+
+static inline void rn_writel(u32 val, void __iomem *base_addr)
+{
+ writel(val, base_addr - ACP_PHY_BASE_ADDRESS);
+}
+
+/* Machine configuration */
+int snd_amd_acp_find_config(struct pci_dev *pci);
diff --git a/sound/soc/amd/renoir/rn_chip_offset_byte.h b/sound/soc/amd/renoir/rn_chip_offset_byte.h
new file mode 100644
index 0000000000..d20d967b5f
--- /dev/null
+++ b/sound/soc/amd/renoir/rn_chip_offset_byte.h
@@ -0,0 +1,349 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ACP 3.1 Register Documentation
+ *
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ */
+
+#ifndef _rn_OFFSET_HEADER
+#define _rn_OFFSET_HEADER
+// Registers from ACP_DMA block
+
+#define ACP_DMA_CNTL_0 0x1240000
+#define ACP_DMA_CNTL_1 0x1240004
+#define ACP_DMA_CNTL_2 0x1240008
+#define ACP_DMA_CNTL_3 0x124000C
+#define ACP_DMA_CNTL_4 0x1240010
+#define ACP_DMA_CNTL_5 0x1240014
+#define ACP_DMA_CNTL_6 0x1240018
+#define ACP_DMA_CNTL_7 0x124001C
+#define ACP_DMA_DSCR_STRT_IDX_0 0x1240020
+#define ACP_DMA_DSCR_STRT_IDX_1 0x1240024
+#define ACP_DMA_DSCR_STRT_IDX_2 0x1240028
+#define ACP_DMA_DSCR_STRT_IDX_3 0x124002C
+#define ACP_DMA_DSCR_STRT_IDX_4 0x1240030
+#define ACP_DMA_DSCR_STRT_IDX_5 0x1240034
+#define ACP_DMA_DSCR_STRT_IDX_6 0x1240038
+#define ACP_DMA_DSCR_STRT_IDX_7 0x124003C
+#define ACP_DMA_DSCR_CNT_0 0x1240040
+#define ACP_DMA_DSCR_CNT_1 0x1240044
+#define ACP_DMA_DSCR_CNT_2 0x1240048
+#define ACP_DMA_DSCR_CNT_3 0x124004C
+#define ACP_DMA_DSCR_CNT_4 0x1240050
+#define ACP_DMA_DSCR_CNT_5 0x1240054
+#define ACP_DMA_DSCR_CNT_6 0x1240058
+#define ACP_DMA_DSCR_CNT_7 0x124005C
+#define ACP_DMA_PRIO_0 0x1240060
+#define ACP_DMA_PRIO_1 0x1240064
+#define ACP_DMA_PRIO_2 0x1240068
+#define ACP_DMA_PRIO_3 0x124006C
+#define ACP_DMA_PRIO_4 0x1240070
+#define ACP_DMA_PRIO_5 0x1240074
+#define ACP_DMA_PRIO_6 0x1240078
+#define ACP_DMA_PRIO_7 0x124007C
+#define ACP_DMA_CUR_DSCR_0 0x1240080
+#define ACP_DMA_CUR_DSCR_1 0x1240084
+#define ACP_DMA_CUR_DSCR_2 0x1240088
+#define ACP_DMA_CUR_DSCR_3 0x124008C
+#define ACP_DMA_CUR_DSCR_4 0x1240090
+#define ACP_DMA_CUR_DSCR_5 0x1240094
+#define ACP_DMA_CUR_DSCR_6 0x1240098
+#define ACP_DMA_CUR_DSCR_7 0x124009C
+#define ACP_DMA_CUR_TRANS_CNT_0 0x12400A0
+#define ACP_DMA_CUR_TRANS_CNT_1 0x12400A4
+#define ACP_DMA_CUR_TRANS_CNT_2 0x12400A8
+#define ACP_DMA_CUR_TRANS_CNT_3 0x12400AC
+#define ACP_DMA_CUR_TRANS_CNT_4 0x12400B0
+#define ACP_DMA_CUR_TRANS_CNT_5 0x12400B4
+#define ACP_DMA_CUR_TRANS_CNT_6 0x12400B8
+#define ACP_DMA_CUR_TRANS_CNT_7 0x12400BC
+#define ACP_DMA_ERR_STS_0 0x12400C0
+#define ACP_DMA_ERR_STS_1 0x12400C4
+#define ACP_DMA_ERR_STS_2 0x12400C8
+#define ACP_DMA_ERR_STS_3 0x12400CC
+#define ACP_DMA_ERR_STS_4 0x12400D0
+#define ACP_DMA_ERR_STS_5 0x12400D4
+#define ACP_DMA_ERR_STS_6 0x12400D8
+#define ACP_DMA_ERR_STS_7 0x12400DC
+#define ACP_DMA_DESC_BASE_ADDR 0x12400E0
+#define ACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4
+#define ACP_DMA_CH_STS 0x12400E8
+#define ACP_DMA_CH_GROUP 0x12400EC
+#define ACP_DMA_CH_RST_STS 0x12400F0
+
+// Registers from ACP_AXI2AXIATU block
+
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0x1240C00
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_1 0x1240C04
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2 0x1240C08
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_2 0x1240C0C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_3 0x1240C10
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_3 0x1240C14
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_4 0x1240C18
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_4 0x1240C1C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0x1240C20
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0x1240C24
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_6 0x1240C28
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_6 0x1240C2C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_7 0x1240C30
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_7 0x1240C34
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_8 0x1240C38
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_8 0x1240C3C
+#define ACPAXI2AXI_ATU_CTRL 0x1240C40
+
+// Registers from ACP_CLKRST block
+
+#define ACP_SOFT_RESET 0x1241000
+#define ACP_CONTROL 0x1241004
+#define ACP_STATUS 0x1241008
+#define ACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
+
+// Registers from ACP_MISC block
+
+#define ACP_EXTERNAL_INTR_ENB 0x1241800
+#define ACP_EXTERNAL_INTR_CNTL 0x1241804
+#define ACP_EXTERNAL_INTR_STAT 0x1241808
+#define ACP_PGMEM_CTRL 0x12418C0
+#define ACP_ERROR_STATUS 0x12418C4
+#define ACP_SW_I2S_ERROR_REASON 0x12418C8
+#define ACP_MEM_PG_STS 0x12418CC
+
+// Registers from ACP_PGFSM block
+
+#define ACP_I2S_PIN_CONFIG 0x1241400
+#define ACP_PAD_PULLUP_PULLDOWN_CTRL 0x1241404
+#define ACP_PAD_DRIVE_STRENGTH_CTRL 0x1241408
+#define ACP_SW_PAD_KEEPER_EN 0x124140C
+#define ACP_PGFSM_CONTROL 0x124141C
+#define ACP_PGFSM_STATUS 0x1241420
+#define ACP_CLKMUX_SEL 0x1241424
+#define ACP_DEVICE_STATE 0x1241428
+#define AZ_DEVICE_STATE 0x124142C
+#define ACP_INTR_URGENCY_TIMER 0x1241430
+#define AZ_INTR_URGENCY_TIMER 0x1241434
+
+// Registers from ACP_SCRATCH block
+
+#define ACP_SCRATCH_REG_0 0x1250000
+#define ACP_SCRATCH_REG_1 0x1250004
+#define ACP_SCRATCH_REG_2 0x1250008
+#define ACP_SCRATCH_REG_3 0x125000C
+#define ACP_SCRATCH_REG_4 0x1250010
+#define ACP_SCRATCH_REG_5 0x1250014
+#define ACP_SCRATCH_REG_6 0x1250018
+#define ACP_SCRATCH_REG_7 0x125001C
+#define ACP_SCRATCH_REG_8 0x1250020
+#define ACP_SCRATCH_REG_9 0x1250024
+#define ACP_SCRATCH_REG_10 0x1250028
+#define ACP_SCRATCH_REG_11 0x125002C
+#define ACP_SCRATCH_REG_12 0x1250030
+#define ACP_SCRATCH_REG_13 0x1250034
+#define ACP_SCRATCH_REG_14 0x1250038
+#define ACP_SCRATCH_REG_15 0x125003C
+#define ACP_SCRATCH_REG_16 0x1250040
+#define ACP_SCRATCH_REG_17 0x1250044
+#define ACP_SCRATCH_REG_18 0x1250048
+#define ACP_SCRATCH_REG_19 0x125004C
+#define ACP_SCRATCH_REG_20 0x1250050
+#define ACP_SCRATCH_REG_21 0x1250054
+#define ACP_SCRATCH_REG_22 0x1250058
+#define ACP_SCRATCH_REG_23 0x125005C
+#define ACP_SCRATCH_REG_24 0x1250060
+#define ACP_SCRATCH_REG_25 0x1250064
+#define ACP_SCRATCH_REG_26 0x1250068
+#define ACP_SCRATCH_REG_27 0x125006C
+#define ACP_SCRATCH_REG_28 0x1250070
+#define ACP_SCRATCH_REG_29 0x1250074
+#define ACP_SCRATCH_REG_30 0x1250078
+#define ACP_SCRATCH_REG_31 0x125007C
+#define ACP_SCRATCH_REG_32 0x1250080
+#define ACP_SCRATCH_REG_33 0x1250084
+#define ACP_SCRATCH_REG_34 0x1250088
+#define ACP_SCRATCH_REG_35 0x125008C
+#define ACP_SCRATCH_REG_36 0x1250090
+#define ACP_SCRATCH_REG_37 0x1250094
+#define ACP_SCRATCH_REG_38 0x1250098
+#define ACP_SCRATCH_REG_39 0x125009C
+#define ACP_SCRATCH_REG_40 0x12500A0
+#define ACP_SCRATCH_REG_41 0x12500A4
+#define ACP_SCRATCH_REG_42 0x12500A8
+#define ACP_SCRATCH_REG_43 0x12500AC
+#define ACP_SCRATCH_REG_44 0x12500B0
+#define ACP_SCRATCH_REG_45 0x12500B4
+#define ACP_SCRATCH_REG_46 0x12500B8
+#define ACP_SCRATCH_REG_47 0x12500BC
+#define ACP_SCRATCH_REG_48 0x12500C0
+#define ACP_SCRATCH_REG_49 0x12500C4
+#define ACP_SCRATCH_REG_50 0x12500C8
+#define ACP_SCRATCH_REG_51 0x12500CC
+#define ACP_SCRATCH_REG_52 0x12500D0
+#define ACP_SCRATCH_REG_53 0x12500D4
+#define ACP_SCRATCH_REG_54 0x12500D8
+#define ACP_SCRATCH_REG_55 0x12500DC
+#define ACP_SCRATCH_REG_56 0x12500E0
+#define ACP_SCRATCH_REG_57 0x12500E4
+#define ACP_SCRATCH_REG_58 0x12500E8
+#define ACP_SCRATCH_REG_59 0x12500EC
+#define ACP_SCRATCH_REG_60 0x12500F0
+#define ACP_SCRATCH_REG_61 0x12500F4
+#define ACP_SCRATCH_REG_62 0x12500F8
+#define ACP_SCRATCH_REG_63 0x12500FC
+#define ACP_SCRATCH_REG_64 0x1250100
+#define ACP_SCRATCH_REG_65 0x1250104
+#define ACP_SCRATCH_REG_66 0x1250108
+#define ACP_SCRATCH_REG_67 0x125010C
+#define ACP_SCRATCH_REG_68 0x1250110
+#define ACP_SCRATCH_REG_69 0x1250114
+#define ACP_SCRATCH_REG_70 0x1250118
+#define ACP_SCRATCH_REG_71 0x125011C
+#define ACP_SCRATCH_REG_72 0x1250120
+#define ACP_SCRATCH_REG_73 0x1250124
+#define ACP_SCRATCH_REG_74 0x1250128
+#define ACP_SCRATCH_REG_75 0x125012C
+#define ACP_SCRATCH_REG_76 0x1250130
+#define ACP_SCRATCH_REG_77 0x1250134
+#define ACP_SCRATCH_REG_78 0x1250138
+#define ACP_SCRATCH_REG_79 0x125013C
+#define ACP_SCRATCH_REG_80 0x1250140
+#define ACP_SCRATCH_REG_81 0x1250144
+#define ACP_SCRATCH_REG_82 0x1250148
+#define ACP_SCRATCH_REG_83 0x125014C
+#define ACP_SCRATCH_REG_84 0x1250150
+#define ACP_SCRATCH_REG_85 0x1250154
+#define ACP_SCRATCH_REG_86 0x1250158
+#define ACP_SCRATCH_REG_87 0x125015C
+#define ACP_SCRATCH_REG_88 0x1250160
+#define ACP_SCRATCH_REG_89 0x1250164
+#define ACP_SCRATCH_REG_90 0x1250168
+#define ACP_SCRATCH_REG_91 0x125016C
+#define ACP_SCRATCH_REG_92 0x1250170
+#define ACP_SCRATCH_REG_93 0x1250174
+#define ACP_SCRATCH_REG_94 0x1250178
+#define ACP_SCRATCH_REG_95 0x125017C
+#define ACP_SCRATCH_REG_96 0x1250180
+#define ACP_SCRATCH_REG_97 0x1250184
+#define ACP_SCRATCH_REG_98 0x1250188
+#define ACP_SCRATCH_REG_99 0x125018C
+#define ACP_SCRATCH_REG_100 0x1250190
+#define ACP_SCRATCH_REG_101 0x1250194
+#define ACP_SCRATCH_REG_102 0x1250198
+#define ACP_SCRATCH_REG_103 0x125019C
+#define ACP_SCRATCH_REG_104 0x12501A0
+#define ACP_SCRATCH_REG_105 0x12501A4
+#define ACP_SCRATCH_REG_106 0x12501A8
+#define ACP_SCRATCH_REG_107 0x12501AC
+#define ACP_SCRATCH_REG_108 0x12501B0
+#define ACP_SCRATCH_REG_109 0x12501B4
+#define ACP_SCRATCH_REG_110 0x12501B8
+#define ACP_SCRATCH_REG_111 0x12501BC
+#define ACP_SCRATCH_REG_112 0x12501C0
+#define ACP_SCRATCH_REG_113 0x12501C4
+#define ACP_SCRATCH_REG_114 0x12501C8
+#define ACP_SCRATCH_REG_115 0x12501CC
+#define ACP_SCRATCH_REG_116 0x12501D0
+#define ACP_SCRATCH_REG_117 0x12501D4
+#define ACP_SCRATCH_REG_118 0x12501D8
+#define ACP_SCRATCH_REG_119 0x12501DC
+#define ACP_SCRATCH_REG_120 0x12501E0
+#define ACP_SCRATCH_REG_121 0x12501E4
+#define ACP_SCRATCH_REG_122 0x12501E8
+#define ACP_SCRATCH_REG_123 0x12501EC
+#define ACP_SCRATCH_REG_124 0x12501F0
+#define ACP_SCRATCH_REG_125 0x12501F4
+#define ACP_SCRATCH_REG_126 0x12501F8
+#define ACP_SCRATCH_REG_127 0x12501FC
+#define ACP_SCRATCH_REG_128 0x1250200
+
+// Registers from ACP_AUDIO_BUFFERS block
+
+#define ACP_I2S_RX_RINGBUFADDR 0x1242000
+#define ACP_I2S_RX_RINGBUFSIZE 0x1242004
+#define ACP_I2S_RX_LINKPOSITIONCNTR 0x1242008
+#define ACP_I2S_RX_FIFOADDR 0x124200C
+#define ACP_I2S_RX_FIFOSIZE 0x1242010
+#define ACP_I2S_RX_DMA_SIZE 0x1242014
+#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1242018
+#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x124201C
+#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x1242020
+#define ACP_I2S_TX_RINGBUFADDR 0x1242024
+#define ACP_I2S_TX_RINGBUFSIZE 0x1242028
+#define ACP_I2S_TX_LINKPOSITIONCNTR 0x124202C
+#define ACP_I2S_TX_FIFOADDR 0x1242030
+#define ACP_I2S_TX_FIFOSIZE 0x1242034
+#define ACP_I2S_TX_DMA_SIZE 0x1242038
+#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x124203C
+#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1242040
+#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x1242044
+#define ACP_BT_RX_RINGBUFADDR 0x1242048
+#define ACP_BT_RX_RINGBUFSIZE 0x124204C
+#define ACP_BT_RX_LINKPOSITIONCNTR 0x1242050
+#define ACP_BT_RX_FIFOADDR 0x1242054
+#define ACP_BT_RX_FIFOSIZE 0x1242058
+#define ACP_BT_RX_DMA_SIZE 0x124205C
+#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1242060
+#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x1242064
+#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068
+#define ACP_BT_TX_RINGBUFADDR 0x124206C
+#define ACP_BT_TX_RINGBUFSIZE 0x1242070
+#define ACP_BT_TX_LINKPOSITIONCNTR 0x1242074
+#define ACP_BT_TX_FIFOADDR 0x1242078
+#define ACP_BT_TX_FIFOSIZE 0x124207C
+#define ACP_BT_TX_DMA_SIZE 0x1242080
+#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1242084
+#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x1242088
+#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C
+#define ACP_HS_RX_RINGBUFADDR 0x1242090
+#define ACP_HS_RX_RINGBUFSIZE 0x1242094
+#define ACP_HS_RX_LINKPOSITIONCNTR 0x1242098
+#define ACP_HS_RX_FIFOADDR 0x124209C
+#define ACP_HS_RX_FIFOSIZE 0x12420A0
+#define ACP_HS_RX_DMA_SIZE 0x12420A4
+#define ACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x12420A8
+#define ACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x12420AC
+#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0
+#define ACP_HS_TX_RINGBUFADDR 0x12420B4
+#define ACP_HS_TX_RINGBUFSIZE 0x12420B8
+#define ACP_HS_TX_LINKPOSITIONCNTR 0x12420BC
+#define ACP_HS_TX_FIFOADDR 0x12420C0
+#define ACP_HS_TX_FIFOSIZE 0x12420C4
+#define ACP_HS_TX_DMA_SIZE 0x12420C8
+#define ACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x12420CC
+#define ACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x12420D0
+#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4
+
+// Registers from ACP_I2S_TDM block
+
+#define ACP_I2STDM_IER 0x1242400
+#define ACP_I2STDM_IRER 0x1242404
+#define ACP_I2STDM_RXFRMT 0x1242408
+#define ACP_I2STDM_ITER 0x124240C
+#define ACP_I2STDM_TXFRMT 0x1242410
+
+// Registers from ACP_BT_TDM block
+
+#define ACP_BTTDM_IER 0x1242800
+#define ACP_BTTDM_IRER 0x1242804
+#define ACP_BTTDM_RXFRMT 0x1242808
+#define ACP_BTTDM_ITER 0x124280C
+#define ACP_BTTDM_TXFRMT 0x1242810
+
+// Registers from ACP_WOV block
+
+#define ACP_WOV_PDM_ENABLE 0x1242C04
+#define ACP_WOV_PDM_DMA_ENABLE 0x1242C08
+#define ACP_WOV_RX_RINGBUFADDR 0x1242C0C
+#define ACP_WOV_RX_RINGBUFSIZE 0x1242C10
+#define ACP_WOV_RX_LINKPOSITIONCNTR 0x1242C14
+#define ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH 0x1242C18
+#define ACP_WOV_RX_LINEARPOSITIONCNTR_LOW 0x1242C1C
+#define ACP_WOV_RX_INTR_WATERMARK_SIZE 0x1242C20
+#define ACP_WOV_PDM_FIFO_FLUSH 0x1242C24
+#define ACP_WOV_PDM_NO_OF_CHANNELS 0x1242C28
+#define ACP_WOV_PDM_DECIMATION_FACTOR 0x1242C2C
+#define ACP_WOV_PDM_VAD_CTRL 0x1242C30
+#define ACP_WOV_BUFFER_STATUS 0x1242C58
+#define ACP_WOV_MISC_CTRL 0x1242C5C
+#define ACP_WOV_CLK_CTRL 0x1242C60
+#define ACP_PDM_VAD_DYNAMIC_CLK_GATING_EN 0x1242C64
+#define ACP_WOV_ERROR_STATUS_REGISTER 0x1242C68
+#endif
diff --git a/sound/soc/amd/rpl/Makefile b/sound/soc/amd/rpl/Makefile
new file mode 100644
index 0000000000..11a33a05e9
--- /dev/null
+++ b/sound/soc/amd/rpl/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+# RPL platform Support
+snd-rpl-pci-acp6x-objs := rpl-pci-acp6x.o
+
+obj-$(CONFIG_SND_SOC_AMD_RPL_ACP6x) += snd-rpl-pci-acp6x.o
diff --git a/sound/soc/amd/rpl/rpl-pci-acp6x.c b/sound/soc/amd/rpl/rpl-pci-acp6x.c
new file mode 100644
index 0000000000..a8e548ed99
--- /dev/null
+++ b/sound/soc/amd/rpl/rpl-pci-acp6x.c
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * AMD RPL ACP PCI Driver
+ *
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "rpl_acp6x.h"
+
+struct rpl_dev_data {
+ void __iomem *acp6x_base;
+};
+
+static int rpl_power_on(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ val = rpl_acp_readl(acp_base + ACP_PGFSM_STATUS);
+
+ if (!val)
+ return val;
+
+ if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS)
+ rpl_acp_writel(ACP_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rpl_acp_readl(acp_base + ACP_PGFSM_STATUS);
+ if (!val)
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int rpl_reset(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ rpl_acp_writel(1, acp_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rpl_acp_readl(acp_base + ACP_SOFT_RESET);
+ if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
+ break;
+ cpu_relax();
+ }
+ rpl_acp_writel(0, acp_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rpl_acp_readl(acp_base + ACP_SOFT_RESET);
+ if (!val)
+ return 0;
+ cpu_relax();
+ }
+ return -ETIMEDOUT;
+}
+
+static int rpl_init(void __iomem *acp_base)
+{
+ int ret;
+
+ /* power on */
+ ret = rpl_power_on(acp_base);
+ if (ret) {
+ pr_err("ACP power on failed\n");
+ return ret;
+ }
+ rpl_acp_writel(0x01, acp_base + ACP_CONTROL);
+ /* Reset */
+ ret = rpl_reset(acp_base);
+ if (ret) {
+ pr_err("ACP reset failed\n");
+ return ret;
+ }
+ rpl_acp_writel(0x03, acp_base + ACP_CLKMUX_SEL);
+ return 0;
+}
+
+static int rpl_deinit(void __iomem *acp_base)
+{
+ int ret;
+
+ /* Reset */
+ ret = rpl_reset(acp_base);
+ if (ret) {
+ pr_err("ACP reset failed\n");
+ return ret;
+ }
+ rpl_acp_writel(0x00, acp_base + ACP_CLKMUX_SEL);
+ rpl_acp_writel(0x00, acp_base + ACP_CONTROL);
+ return 0;
+}
+
+static int snd_rpl_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ struct rpl_dev_data *adata;
+ u32 addr;
+ int ret;
+
+ /* RPL device check */
+ switch (pci->revision) {
+ case 0x62:
+ break;
+ default:
+ dev_dbg(&pci->dev, "acp6x pci device not found\n");
+ return -ENODEV;
+ }
+ if (pci_enable_device(pci)) {
+ dev_err(&pci->dev, "pci_enable_device failed\n");
+ return -ENODEV;
+ }
+
+ ret = pci_request_regions(pci, "AMD ACP6x audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+ }
+
+ adata = devm_kzalloc(&pci->dev, sizeof(struct rpl_dev_data),
+ GFP_KERNEL);
+ if (!adata) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+
+ addr = pci_resource_start(pci, 0);
+ adata->acp6x_base = devm_ioremap(&pci->dev, addr,
+ pci_resource_len(pci, 0));
+ if (!adata->acp6x_base) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+ pci_set_master(pci);
+ pci_set_drvdata(pci, adata);
+ ret = rpl_init(adata->acp6x_base);
+ if (ret)
+ goto release_regions;
+ pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_put_noidle(&pci->dev);
+ pm_runtime_allow(&pci->dev);
+
+ return 0;
+release_regions:
+ pci_release_regions(pci);
+disable_pci:
+ pci_disable_device(pci);
+
+ return ret;
+}
+
+static int __maybe_unused snd_rpl_suspend(struct device *dev)
+{
+ struct rpl_dev_data *adata;
+ int ret;
+
+ adata = dev_get_drvdata(dev);
+ ret = rpl_deinit(adata->acp6x_base);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+ return ret;
+}
+
+static int __maybe_unused snd_rpl_resume(struct device *dev)
+{
+ struct rpl_dev_data *adata;
+ int ret;
+
+ adata = dev_get_drvdata(dev);
+ ret = rpl_init(adata->acp6x_base);
+ if (ret)
+ dev_err(dev, "ACP init failed\n");
+ return ret;
+}
+
+static const struct dev_pm_ops rpl_pm = {
+ SET_RUNTIME_PM_OPS(snd_rpl_suspend, snd_rpl_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(snd_rpl_suspend, snd_rpl_resume)
+};
+
+static void snd_rpl_remove(struct pci_dev *pci)
+{
+ struct rpl_dev_data *adata;
+ int ret;
+
+ adata = pci_get_drvdata(pci);
+ ret = rpl_deinit(adata->acp6x_base);
+ if (ret)
+ dev_err(&pci->dev, "ACP de-init failed\n");
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_get_noresume(&pci->dev);
+ pci_release_regions(pci);
+ pci_disable_device(pci);
+}
+
+static const struct pci_device_id snd_rpl_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
+ .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
+ .class_mask = 0xffffff },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_rpl_ids);
+
+static struct pci_driver rpl_acp6x_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = snd_rpl_ids,
+ .probe = snd_rpl_probe,
+ .remove = snd_rpl_remove,
+ .driver = {
+ .pm = &rpl_pm,
+ }
+};
+
+module_pci_driver(rpl_acp6x_driver);
+
+MODULE_DESCRIPTION("AMD ACP RPL PCI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/rpl/rpl_acp6x.h b/sound/soc/amd/rpl/rpl_acp6x.h
new file mode 100644
index 0000000000..f5816a3363
--- /dev/null
+++ b/sound/soc/amd/rpl/rpl_acp6x.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ACP Driver
+ *
+ * Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+ */
+
+#include "rpl_acp6x_chip_offset_byte.h"
+
+#define ACP_DEVICE_ID 0x15E2
+#define ACP6x_PHY_BASE_ADDRESS 0x1240000
+
+#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
+#define ACP_PGFSM_CNTL_POWER_ON_MASK 1
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0
+#define ACP_PGFSM_STATUS_MASK 3
+#define ACP_POWERED_ON 0
+#define ACP_POWER_ON_IN_PROGRESS 1
+#define ACP_POWERED_OFF 2
+#define ACP_POWER_OFF_IN_PROGRESS 3
+
+#define DELAY_US 5
+#define ACP_COUNTER 20000
+
+/* time in ms for runtime suspend delay */
+#define ACP_SUSPEND_DELAY_MS 2000
+
+static inline u32 rpl_acp_readl(void __iomem *base_addr)
+{
+ return readl(base_addr - ACP6x_PHY_BASE_ADDRESS);
+}
+
+static inline void rpl_acp_writel(u32 val, void __iomem *base_addr)
+{
+ writel(val, base_addr - ACP6x_PHY_BASE_ADDRESS);
+}
diff --git a/sound/soc/amd/rpl/rpl_acp6x_chip_offset_byte.h b/sound/soc/amd/rpl/rpl_acp6x_chip_offset_byte.h
new file mode 100644
index 0000000000..456498f539
--- /dev/null
+++ b/sound/soc/amd/rpl/rpl_acp6x_chip_offset_byte.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ACP 6.2 Register Documentation
+ *
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ */
+
+#ifndef _rpl_acp6x_OFFSET_HEADER
+#define _rpl_acp6x_OFFSET_HEADER
+
+/* Registers from ACP_CLKRST block */
+#define ACP_SOFT_RESET 0x1241000
+#define ACP_CONTROL 0x1241004
+#define ACP_STATUS 0x1241008
+#define ACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
+#define ACP_PGFSM_CONTROL 0x124101C
+#define ACP_PGFSM_STATUS 0x1241020
+#define ACP_CLKMUX_SEL 0x1241024
+
+/* Registers from ACP_AON block */
+#define ACP_PME_EN 0x1241400
+#define ACP_DEVICE_STATE 0x1241404
+#define AZ_DEVICE_STATE 0x1241408
+#define ACP_PIN_CONFIG 0x1241440
+#define ACP_PAD_PULLUP_CTRL 0x1241444
+#define ACP_PAD_PULLDOWN_CTRL 0x1241448
+#define ACP_PAD_DRIVE_STRENGTH_CTRL 0x124144C
+#define ACP_PAD_SCHMEN_CTRL 0x1241450
+
+#endif
diff --git a/sound/soc/amd/vangogh/Makefile b/sound/soc/amd/vangogh/Makefile
new file mode 100644
index 0000000000..c9e53e04e2
--- /dev/null
+++ b/sound/soc/amd/vangogh/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Vangogh platform Support
+snd-pci-acp5x-objs := pci-acp5x.o
+snd-acp5x-i2s-objs := acp5x-i2s.o
+snd-acp5x-pcm-dma-objs := acp5x-pcm-dma.o
+snd-soc-acp5x-mach-objs := acp5x-mach.o
+
+obj-$(CONFIG_SND_SOC_AMD_ACP5x) += snd-pci-acp5x.o
+obj-$(CONFIG_SND_SOC_AMD_ACP5x) += snd-acp5x-i2s.o
+obj-$(CONFIG_SND_SOC_AMD_ACP5x) += snd-acp5x-pcm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_VANGOGH_MACH) += snd-soc-acp5x-mach.o
diff --git a/sound/soc/amd/vangogh/acp5x-i2s.c b/sound/soc/amd/vangogh/acp5x-i2s.c
new file mode 100644
index 0000000000..773e96f1b4
--- /dev/null
+++ b/sound/soc/amd/vangogh/acp5x-i2s.c
@@ -0,0 +1,416 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ALSA SoC PCM Driver
+//
+// Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/dma-mapping.h>
+
+#include "acp5x.h"
+
+#define DRV_NAME "acp5x_i2s_playcap"
+
+static int acp5x_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
+ unsigned int fmt)
+{
+ struct i2s_dev_data *adata;
+ int mode;
+
+ adata = snd_soc_dai_get_drvdata(cpu_dai);
+ mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+ switch (mode) {
+ case SND_SOC_DAIFMT_I2S:
+ adata->tdm_mode = TDM_DISABLE;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ adata->tdm_mode = TDM_ENABLE;
+ break;
+ default:
+ return -EINVAL;
+ }
+ mode = fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
+ switch (mode) {
+ case SND_SOC_DAIFMT_BP_FP:
+ adata->master_mode = I2S_MASTER_MODE_ENABLE;
+ break;
+ case SND_SOC_DAIFMT_BC_FC:
+ adata->master_mode = I2S_MASTER_MODE_DISABLE;
+ break;
+ }
+ return 0;
+}
+
+static int acp5x_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai,
+ u32 tx_mask, u32 rx_mask,
+ int slots, int slot_width)
+{
+ struct i2s_dev_data *adata;
+ u32 frm_len;
+ u16 slot_len;
+
+ adata = snd_soc_dai_get_drvdata(cpu_dai);
+
+ /* These values are as per Hardware Spec */
+ switch (slot_width) {
+ case SLOT_WIDTH_8:
+ slot_len = 8;
+ break;
+ case SLOT_WIDTH_16:
+ slot_len = 16;
+ break;
+ case SLOT_WIDTH_24:
+ slot_len = 24;
+ break;
+ case SLOT_WIDTH_32:
+ slot_len = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ frm_len = FRM_LEN | (slots << 15) | (slot_len << 18);
+ adata->tdm_fmt = frm_len;
+ return 0;
+}
+
+static int acp5x_i2s_hwparams(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct i2s_stream_instance *rtd;
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp5x_platform_info *pinfo;
+ struct i2s_dev_data *adata;
+
+ u32 val;
+ u32 reg_val, frmt_reg;
+ u32 lrclk_div_val, bclk_div_val;
+
+ lrclk_div_val = 0;
+ bclk_div_val = 0;
+ prtd = asoc_substream_to_rtd(substream);
+ rtd = substream->runtime->private_data;
+ card = prtd->card;
+ adata = snd_soc_dai_get_drvdata(dai);
+ pinfo = snd_soc_card_get_drvdata(card);
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ else
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ }
+
+ /* These values are as per Hardware Spec */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_S8:
+ rtd->xfer_resolution = 0x0;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ rtd->xfer_resolution = 0x02;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ rtd->xfer_resolution = 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ rtd->xfer_resolution = 0x05;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_ITER;
+ frmt_reg = ACP_HSTDM_TXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_ITER;
+ frmt_reg = ACP_I2STDM_TXFRMT;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_IRER;
+ frmt_reg = ACP_HSTDM_RXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_IRER;
+ frmt_reg = ACP_I2STDM_RXFRMT;
+ }
+ }
+ if (adata->tdm_mode) {
+ val = acp_readl(rtd->acp5x_base + reg_val);
+ acp_writel(val | 0x2, rtd->acp5x_base + reg_val);
+ acp_writel(adata->tdm_fmt, rtd->acp5x_base + frmt_reg);
+ }
+ val = acp_readl(rtd->acp5x_base + reg_val);
+ val &= ~ACP5x_ITER_IRER_SAMP_LEN_MASK;
+ val = val | (rtd->xfer_resolution << 3);
+ acp_writel(val, rtd->acp5x_base + reg_val);
+
+ if (adata->master_mode) {
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ switch (params_rate(params)) {
+ case 8000:
+ bclk_div_val = 768;
+ break;
+ case 16000:
+ bclk_div_val = 384;
+ break;
+ case 24000:
+ bclk_div_val = 256;
+ break;
+ case 32000:
+ bclk_div_val = 192;
+ break;
+ case 44100:
+ case 48000:
+ bclk_div_val = 128;
+ break;
+ case 88200:
+ case 96000:
+ bclk_div_val = 64;
+ break;
+ case 192000:
+ bclk_div_val = 32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ lrclk_div_val = 32;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ switch (params_rate(params)) {
+ case 8000:
+ bclk_div_val = 384;
+ break;
+ case 16000:
+ bclk_div_val = 192;
+ break;
+ case 24000:
+ bclk_div_val = 128;
+ break;
+ case 32000:
+ bclk_div_val = 96;
+ break;
+ case 44100:
+ case 48000:
+ bclk_div_val = 64;
+ break;
+ case 88200:
+ case 96000:
+ bclk_div_val = 32;
+ break;
+ case 192000:
+ bclk_div_val = 16;
+ break;
+ default:
+ return -EINVAL;
+ }
+ lrclk_div_val = 64;
+ break;
+ default:
+ return -EINVAL;
+ }
+ rtd->lrclk_div = lrclk_div_val;
+ rtd->bclk_div = bclk_div_val;
+ }
+ return 0;
+}
+
+static int acp5x_i2s_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct i2s_stream_instance *rtd;
+ struct i2s_dev_data *adata;
+ u32 ret, val, period_bytes, reg_val, ier_val, water_val;
+ u32 buf_size, buf_reg;
+
+ adata = snd_soc_dai_get_drvdata(dai);
+ rtd = substream->runtime->private_data;
+ period_bytes = frames_to_bytes(substream->runtime,
+ substream->runtime->period_size);
+ buf_size = frames_to_bytes(substream->runtime,
+ substream->runtime->buffer_size);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ rtd->bytescount = acp_get_byte_count(rtd,
+ substream->stream);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ water_val =
+ ACP_HS_TX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_HSTDM_ITER;
+ ier_val = ACP_HSTDM_IER;
+ buf_reg = ACP_HS_TX_RINGBUFSIZE;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ water_val =
+ ACP_I2S_TX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_I2STDM_ITER;
+ ier_val = ACP_I2STDM_IER;
+ buf_reg = ACP_I2S_TX_RINGBUFSIZE;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ water_val =
+ ACP_HS_RX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_HSTDM_IRER;
+ ier_val = ACP_HSTDM_IER;
+ buf_reg = ACP_HS_RX_RINGBUFSIZE;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ water_val =
+ ACP_I2S_RX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_I2STDM_IRER;
+ ier_val = ACP_I2STDM_IER;
+ buf_reg = ACP_I2S_RX_RINGBUFSIZE;
+ }
+ }
+ acp_writel(period_bytes, rtd->acp5x_base + water_val);
+ acp_writel(buf_size, rtd->acp5x_base + buf_reg);
+ if (adata->master_mode)
+ acp5x_set_i2s_clk(adata, rtd);
+ val = acp_readl(rtd->acp5x_base + reg_val);
+ val = val | BIT(0);
+ acp_writel(val, rtd->acp5x_base + reg_val);
+ acp_writel(1, rtd->acp5x_base + ier_val);
+ ret = 0;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_ITER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_ITER;
+ }
+
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_IRER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_IRER;
+ }
+ }
+ val = acp_readl(rtd->acp5x_base + reg_val);
+ val = val & ~BIT(0);
+ acp_writel(val, rtd->acp5x_base + reg_val);
+
+ if (!(acp_readl(rtd->acp5x_base + ACP_HSTDM_ITER) & BIT(0)) &&
+ !(acp_readl(rtd->acp5x_base + ACP_HSTDM_IRER) & BIT(0)))
+ acp_writel(0, rtd->acp5x_base + ACP_HSTDM_IER);
+ if (!(acp_readl(rtd->acp5x_base + ACP_I2STDM_ITER) & BIT(0)) &&
+ !(acp_readl(rtd->acp5x_base + ACP_I2STDM_IRER) & BIT(0)))
+ acp_writel(0, rtd->acp5x_base + ACP_I2STDM_IER);
+ ret = 0;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static const struct snd_soc_dai_ops acp5x_i2s_dai_ops = {
+ .hw_params = acp5x_i2s_hwparams,
+ .trigger = acp5x_i2s_trigger,
+ .set_fmt = acp5x_i2s_set_fmt,
+ .set_tdm_slot = acp5x_i2s_set_tdm_slot,
+};
+
+static const struct snd_soc_component_driver acp5x_dai_component = {
+ .name = "acp5x-i2s",
+ .legacy_dai_naming = 1,
+};
+
+static struct snd_soc_dai_driver acp5x_i2s_dai = {
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .ops = &acp5x_i2s_dai_ops,
+};
+
+static int acp5x_dai_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct i2s_dev_data *adata;
+ int ret;
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dev_data),
+ GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENOMEM;
+ }
+ adata->acp5x_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!adata->acp5x_base)
+ return -ENOMEM;
+
+ adata->master_mode = I2S_MASTER_MODE_ENABLE;
+ dev_set_drvdata(&pdev->dev, adata);
+ ret = devm_snd_soc_register_component(&pdev->dev,
+ &acp5x_dai_component,
+ &acp5x_i2s_dai, 1);
+ if (ret)
+ dev_err(&pdev->dev, "Fail to register acp i2s dai\n");
+ return ret;
+}
+
+static struct platform_driver acp5x_dai_driver = {
+ .probe = acp5x_dai_probe,
+ .driver = {
+ .name = "acp5x_i2s_playcap",
+ },
+};
+
+module_platform_driver(acp5x_dai_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP5.x CPU DAI Driver");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/vangogh/acp5x-mach.c b/sound/soc/amd/vangogh/acp5x-mach.c
new file mode 100644
index 0000000000..2ccc95d577
--- /dev/null
+++ b/sound/soc/amd/vangogh/acp5x-mach.c
@@ -0,0 +1,496 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Machine driver for AMD Vangogh platform using either
+ * NAU8821 & CS35L41 or NAU8821 & MAX98388 codecs.
+ *
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/input-event-codes.h>
+#include <linux/module.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include "../../codecs/nau8821.h"
+#include "acp5x.h"
+
+#define DRV_NAME "acp5x_mach"
+#define DUAL_CHANNEL 2
+#define ACP5X_NAU8821_BCLK 3072000
+#define ACP5X_NAU8821_FREQ_OUT 12288000
+#define ACP5X_NAU8821_COMP_NAME "i2c-NVTN2020:00"
+#define ACP5X_NAU8821_DAI_NAME "nau8821-hifi"
+#define ACP5X_CS35L41_COMP_LNAME "spi-VLV1776:00"
+#define ACP5X_CS35L41_COMP_RNAME "spi-VLV1776:01"
+#define ACP5X_CS35L41_DAI_NAME "cs35l41-pcm"
+#define ACP5X_MAX98388_COMP_LNAME "i2c-ADS8388:00"
+#define ACP5X_MAX98388_COMP_RNAME "i2c-ADS8388:01"
+#define ACP5X_MAX98388_DAI_NAME "max98388-aif1"
+
+static struct snd_soc_jack vg_headset;
+
+SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("acp5x_i2s_dma.0")));
+SND_SOC_DAILINK_DEF(acp5x_i2s, DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.0")));
+SND_SOC_DAILINK_DEF(acp5x_bt, DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.1")));
+SND_SOC_DAILINK_DEF(nau8821, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_NAU8821_COMP_NAME,
+ ACP5X_NAU8821_DAI_NAME)));
+
+static struct snd_soc_jack_pin acp5x_nau8821_jack_pins[] = {
+ {
+ .pin = "Headphone",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+static const struct snd_kcontrol_new acp5x_8821_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Int Mic"),
+};
+
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_dapm_context *dapm = w->dapm;
+ struct snd_soc_card *card = dapm->card;
+ struct snd_soc_dai *dai;
+ int ret = 0;
+
+ dai = snd_soc_card_get_codec_dai(card, ACP5X_NAU8821_DAI_NAME);
+ if (!dai) {
+ dev_err(card->dev, "Codec dai not found\n");
+ return -EIO;
+ }
+
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(card->dev, "set sysclk err = %d\n", ret);
+ return -EIO;
+ }
+ } else {
+ ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_FLL_BLK, 0, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ dev_err(dai->dev, "can't set BLK clock %d\n", ret);
+ ret = snd_soc_dai_set_pll(dai, 0, 0, ACP5X_NAU8821_BCLK, ACP5X_NAU8821_FREQ_OUT);
+ if (ret < 0)
+ dev_err(dai->dev, "can't set FLL: %d\n", ret);
+ }
+
+ return ret;
+}
+
+static int acp5x_8821_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+ int ret;
+
+ /*
+ * Headset buttons map to the google Reference headset.
+ * These can be configured by userspace.
+ */
+ ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
+ SND_JACK_HEADSET | SND_JACK_BTN_0,
+ &vg_headset, acp5x_nau8821_jack_pins,
+ ARRAY_SIZE(acp5x_nau8821_jack_pins));
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(vg_headset.jack, SND_JACK_BTN_0, KEY_MEDIA);
+ nau8821_enable_jack_detect(component, &vg_headset);
+
+ return ret;
+}
+
+static const unsigned int rates[] = {
+ 48000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+};
+
+static const unsigned int channels[] = {
+ 2,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
+ .count = ARRAY_SIZE(channels),
+ .list = channels,
+ .mask = 0,
+};
+
+static const unsigned int acp5x_nau8821_format[] = {32};
+
+static struct snd_pcm_hw_constraint_list constraints_sample_bits = {
+ .list = acp5x_nau8821_format,
+ .count = ARRAY_SIZE(acp5x_nau8821_format),
+};
+
+static int acp5x_8821_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card);
+
+ machine->play_i2s_instance = I2S_SP_INSTANCE;
+ machine->cap_i2s_instance = I2S_SP_INSTANCE;
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ &constraints_sample_bits);
+
+ return 0;
+}
+
+static int acp5x_nau8821_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *dai = snd_soc_card_get_codec_dai(card, ACP5X_NAU8821_DAI_NAME);
+ int ret, bclk;
+
+ if (!dai)
+ return -EINVAL;
+
+ ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_FLL_BLK, 0, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ dev_err(card->dev, "can't set FS clock %d\n", ret);
+
+ bclk = snd_soc_params_to_bclk(params);
+ if (bclk < 0) {
+ dev_err(dai->dev, "Fail to get BCLK rate: %d\n", bclk);
+ return bclk;
+ }
+
+ ret = snd_soc_dai_set_pll(dai, 0, 0, bclk, params_rate(params) * 256);
+ if (ret < 0)
+ dev_err(card->dev, "can't set FLL: %d\n", ret);
+
+ return ret;
+}
+
+static const struct snd_soc_ops acp5x_8821_ops = {
+ .startup = acp5x_8821_startup,
+ .hw_params = acp5x_nau8821_hw_params,
+};
+
+static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ machine->play_i2s_instance = I2S_HS_INSTANCE;
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+
+ return 0;
+}
+
+static int acp5x_cs35l41_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ unsigned int bclk, rate = params_rate(params);
+ struct snd_soc_component *comp;
+ int ret, i;
+
+ switch (rate) {
+ case 48000:
+ bclk = 1536000;
+ break;
+ default:
+ bclk = 0;
+ break;
+ }
+
+ for_each_rtd_components(rtd, i, comp) {
+ if (!(strcmp(comp->name, ACP5X_CS35L41_COMP_LNAME)) ||
+ !(strcmp(comp->name, ACP5X_CS35L41_COMP_RNAME))) {
+ if (!bclk) {
+ dev_err(comp->dev, "Invalid sample rate: 0x%x\n", rate);
+ return -EINVAL;
+ }
+
+ ret = snd_soc_component_set_sysclk(comp, 0, 0, bclk, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(comp->dev, "failed to set SYSCLK: %d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_ops acp5x_cs35l41_play_ops = {
+ .startup = acp5x_cs35l41_startup,
+ .hw_params = acp5x_cs35l41_hw_params,
+};
+
+static struct snd_soc_codec_conf acp5x_cs35l41_conf[] = {
+ {
+ .dlc = COMP_CODEC_CONF(ACP5X_CS35L41_COMP_LNAME),
+ .name_prefix = "Left",
+ },
+ {
+ .dlc = COMP_CODEC_CONF(ACP5X_CS35L41_COMP_RNAME),
+ .name_prefix = "Right",
+ },
+};
+
+SND_SOC_DAILINK_DEF(cs35l41, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_CS35L41_COMP_LNAME,
+ ACP5X_CS35L41_DAI_NAME),
+ COMP_CODEC(ACP5X_CS35L41_COMP_RNAME,
+ ACP5X_CS35L41_DAI_NAME)));
+
+static struct snd_soc_dai_link acp5x_8821_35l41_dai[] = {
+ {
+ .name = "acp5x-8821-play",
+ .stream_name = "Playback/Capture",
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .ops = &acp5x_8821_ops,
+ .init = acp5x_8821_init,
+ SND_SOC_DAILINK_REG(acp5x_i2s, nau8821, platform),
+ },
+ {
+ .name = "acp5x-CS35L41-Stereo",
+ .stream_name = "CS35L41 Stereo Playback",
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_playback = 1,
+ .playback_only = 1,
+ .ops = &acp5x_cs35l41_play_ops,
+ SND_SOC_DAILINK_REG(acp5x_bt, cs35l41, platform),
+ },
+};
+
+static const struct snd_soc_dapm_widget acp5x_8821_35l41_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Int Mic", NULL),
+ SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+ platform_clock_control,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route acp5x_8821_35l41_audio_route[] = {
+ /* HP jack connectors - unknown if we have jack detection */
+ { "Headphone", NULL, "HPOL" },
+ { "Headphone", NULL, "HPOR" },
+ { "MICL", NULL, "Headset Mic" },
+ { "MICR", NULL, "Headset Mic" },
+ { "DMIC", NULL, "Int Mic" },
+
+ { "Headphone", NULL, "Platform Clock" },
+ { "Headset Mic", NULL, "Platform Clock" },
+ { "Int Mic", NULL, "Platform Clock" },
+};
+
+static struct snd_soc_card acp5x_8821_35l41_card = {
+ .name = "acp5x",
+ .owner = THIS_MODULE,
+ .dai_link = acp5x_8821_35l41_dai,
+ .num_links = ARRAY_SIZE(acp5x_8821_35l41_dai),
+ .dapm_widgets = acp5x_8821_35l41_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(acp5x_8821_35l41_widgets),
+ .dapm_routes = acp5x_8821_35l41_audio_route,
+ .num_dapm_routes = ARRAY_SIZE(acp5x_8821_35l41_audio_route),
+ .codec_conf = acp5x_cs35l41_conf,
+ .num_configs = ARRAY_SIZE(acp5x_cs35l41_conf),
+ .controls = acp5x_8821_controls,
+ .num_controls = ARRAY_SIZE(acp5x_8821_controls),
+};
+
+static int acp5x_max98388_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ machine->play_i2s_instance = I2S_HS_INSTANCE;
+
+ runtime->hw.channels_max = DUAL_CHANNEL;
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+ return 0;
+}
+
+static const struct snd_soc_ops acp5x_max98388_play_ops = {
+ .startup = acp5x_max98388_startup,
+};
+
+static struct snd_soc_codec_conf acp5x_max98388_conf[] = {
+ {
+ .dlc = COMP_CODEC_CONF(ACP5X_MAX98388_COMP_LNAME),
+ .name_prefix = "Left",
+ },
+ {
+ .dlc = COMP_CODEC_CONF(ACP5X_MAX98388_COMP_RNAME),
+ .name_prefix = "Right",
+ },
+};
+
+SND_SOC_DAILINK_DEF(max98388, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_MAX98388_COMP_LNAME,
+ ACP5X_MAX98388_DAI_NAME),
+ COMP_CODEC(ACP5X_MAX98388_COMP_RNAME,
+ ACP5X_MAX98388_DAI_NAME)));
+
+static struct snd_soc_dai_link acp5x_8821_98388_dai[] = {
+ {
+ .name = "acp5x-8821-play",
+ .stream_name = "Playback/Capture",
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .ops = &acp5x_8821_ops,
+ .init = acp5x_8821_init,
+ SND_SOC_DAILINK_REG(acp5x_i2s, nau8821, platform),
+ },
+ {
+ .name = "acp5x-max98388-play",
+ .stream_name = "MAX98388 Playback",
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_playback = 1,
+ .playback_only = 1,
+ .ops = &acp5x_max98388_play_ops,
+ SND_SOC_DAILINK_REG(acp5x_bt, max98388, platform),
+ },
+};
+
+static const struct snd_soc_dapm_widget acp5x_8821_98388_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Int Mic", NULL),
+ SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+ platform_clock_control,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SPK("SPK", NULL),
+};
+
+static const struct snd_soc_dapm_route acp5x_8821_98388_route[] = {
+ { "Headphone", NULL, "HPOL" },
+ { "Headphone", NULL, "HPOR" },
+ { "MICL", NULL, "Headset Mic" },
+ { "MICR", NULL, "Headset Mic" },
+ { "DMIC", NULL, "Int Mic" },
+
+ { "Headphone", NULL, "Platform Clock" },
+ { "Headset Mic", NULL, "Platform Clock" },
+ { "Int Mic", NULL, "Platform Clock" },
+
+ { "SPK", NULL, "Left BE_OUT" },
+ { "SPK", NULL, "Right BE_OUT" },
+};
+
+static struct snd_soc_card acp5x_8821_98388_card = {
+ .name = "acp5x-max98388",
+ .owner = THIS_MODULE,
+ .dai_link = acp5x_8821_98388_dai,
+ .num_links = ARRAY_SIZE(acp5x_8821_98388_dai),
+ .dapm_widgets = acp5x_8821_98388_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(acp5x_8821_98388_widgets),
+ .dapm_routes = acp5x_8821_98388_route,
+ .num_dapm_routes = ARRAY_SIZE(acp5x_8821_98388_route),
+ .codec_conf = acp5x_max98388_conf,
+ .num_configs = ARRAY_SIZE(acp5x_max98388_conf),
+ .controls = acp5x_8821_controls,
+ .num_controls = ARRAY_SIZE(acp5x_8821_controls),
+};
+
+static const struct dmi_system_id acp5x_vg_quirk_table[] = {
+ {
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Valve"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"),
+ },
+ .driver_data = (void *)&acp5x_8821_35l41_card,
+ },
+ {
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Valve"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"),
+ },
+ .driver_data = (void *)&acp5x_8821_98388_card,
+ },
+ {}
+};
+
+static int acp5x_probe(struct platform_device *pdev)
+{
+ const struct dmi_system_id *dmi_id;
+ struct acp5x_platform_info *machine;
+ struct device *dev = &pdev->dev;
+ struct snd_soc_card *card;
+ int ret;
+
+ dmi_id = dmi_first_match(acp5x_vg_quirk_table);
+ if (!dmi_id || !dmi_id->driver_data)
+ return -ENODEV;
+
+ machine = devm_kzalloc(dev, sizeof(*machine), GFP_KERNEL);
+ if (!machine)
+ return -ENOMEM;
+
+ card = dmi_id->driver_data;
+ card->dev = dev;
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, machine);
+
+ ret = devm_snd_soc_register_card(dev, card);
+ if (ret)
+ return dev_err_probe(dev, ret, "Register card (%s) failed\n", card->name);
+
+ return 0;
+}
+
+static struct platform_driver acp5x_mach_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = acp5x_probe,
+};
+
+module_platform_driver(acp5x_mach_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("NAU8821/CS35L41 & NAU8821/MAX98388 audio support");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/vangogh/acp5x-pcm-dma.c b/sound/soc/amd/vangogh/acp5x-pcm-dma.c
new file mode 100644
index 0000000000..587dec5bb3
--- /dev/null
+++ b/sound/soc/amd/vangogh/acp5x-pcm-dma.c
@@ -0,0 +1,514 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ALSA SoC PCM Driver
+//
+// Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+#include "acp5x.h"
+
+#define DRV_NAME "acp5x_i2s_dma"
+
+static const struct snd_pcm_hardware acp5x_pcm_hardware_playback = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
+ .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
+ .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
+ .periods_min = PLAYBACK_MIN_NUM_PERIODS,
+ .periods_max = PLAYBACK_MAX_NUM_PERIODS,
+};
+
+static const struct snd_pcm_hardware acp5x_pcm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
+static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
+{
+ struct i2s_dev_data *vg_i2s_data;
+ u16 irq_flag;
+ u32 val;
+
+ vg_i2s_data = dev_id;
+ if (!vg_i2s_data)
+ return IRQ_NONE;
+
+ irq_flag = 0;
+ val = acp_readl(vg_i2s_data->acp5x_base + ACP_EXTERNAL_INTR_STAT);
+ if ((val & BIT(HS_TX_THRESHOLD)) && vg_i2s_data->play_stream) {
+ acp_writel(BIT(HS_TX_THRESHOLD), vg_i2s_data->acp5x_base +
+ ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(vg_i2s_data->play_stream);
+ irq_flag = 1;
+ }
+ if ((val & BIT(I2S_TX_THRESHOLD)) && vg_i2s_data->i2ssp_play_stream) {
+ acp_writel(BIT(I2S_TX_THRESHOLD),
+ vg_i2s_data->acp5x_base + ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(vg_i2s_data->i2ssp_play_stream);
+ irq_flag = 1;
+ }
+
+ if ((val & BIT(HS_RX_THRESHOLD)) && vg_i2s_data->capture_stream) {
+ acp_writel(BIT(HS_RX_THRESHOLD), vg_i2s_data->acp5x_base +
+ ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(vg_i2s_data->capture_stream);
+ irq_flag = 1;
+ }
+ if ((val & BIT(I2S_RX_THRESHOLD)) && vg_i2s_data->i2ssp_capture_stream) {
+ acp_writel(BIT(I2S_RX_THRESHOLD),
+ vg_i2s_data->acp5x_base + ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(vg_i2s_data->i2ssp_capture_stream);
+ irq_flag = 1;
+ }
+
+ if (irq_flag)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static void config_acp5x_dma(struct i2s_stream_instance *rtd, int direction)
+{
+ u16 page_idx;
+ u32 low, high, val, acp_fifo_addr, reg_fifo_addr;
+ u32 reg_dma_size, reg_fifo_size;
+ dma_addr_t addr;
+
+ addr = rtd->dma_addr;
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ val = ACP_SRAM_HS_PB_PTE_OFFSET;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ val = ACP_SRAM_SP_PB_PTE_OFFSET;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ val = ACP_SRAM_HS_CP_PTE_OFFSET;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ val = ACP_SRAM_SP_CP_PTE_OFFSET;
+ }
+ }
+ /* Group Enable */
+ acp_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp5x_base +
+ ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
+ acp_writel(PAGE_SIZE_4K_ENABLE, rtd->acp5x_base +
+ ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
+
+ for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+
+ acp_writel(low, rtd->acp5x_base + ACP_SCRATCH_REG_0 + val);
+ high |= BIT(31);
+ acp_writel(high, rtd->acp5x_base + ACP_SCRATCH_REG_0 + val + 4);
+ /* Move to next physically contiguous page */
+ val += 8;
+ addr += PAGE_SIZE;
+ }
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_dma_size = ACP_HS_TX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ HS_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_HS_TX_FIFOADDR;
+ reg_fifo_size = ACP_HS_TX_FIFOSIZE;
+ acp_writel(I2S_HS_TX_MEM_WINDOW_START,
+ rtd->acp5x_base + ACP_HS_TX_RINGBUFADDR);
+ break;
+
+ case I2S_SP_INSTANCE:
+ default:
+ reg_dma_size = ACP_I2S_TX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ SP_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_I2S_TX_FIFOADDR;
+ reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
+ acp_writel(I2S_SP_TX_MEM_WINDOW_START,
+ rtd->acp5x_base + ACP_I2S_TX_RINGBUFADDR);
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_dma_size = ACP_HS_RX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ HS_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_HS_RX_FIFOADDR;
+ reg_fifo_size = ACP_HS_RX_FIFOSIZE;
+ acp_writel(I2S_HS_RX_MEM_WINDOW_START,
+ rtd->acp5x_base + ACP_HS_RX_RINGBUFADDR);
+ break;
+
+ case I2S_SP_INSTANCE:
+ default:
+ reg_dma_size = ACP_I2S_RX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ SP_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
+ reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
+ acp_writel(I2S_SP_RX_MEM_WINDOW_START,
+ rtd->acp5x_base + ACP_I2S_RX_RINGBUFADDR);
+ }
+ }
+ acp_writel(DMA_SIZE, rtd->acp5x_base + reg_dma_size);
+ acp_writel(acp_fifo_addr, rtd->acp5x_base + reg_fifo_addr);
+ acp_writel(FIFO_SIZE, rtd->acp5x_base + reg_fifo_size);
+ acp_writel(BIT(I2S_RX_THRESHOLD) | BIT(HS_RX_THRESHOLD)
+ | BIT(I2S_TX_THRESHOLD) | BIT(HS_TX_THRESHOLD),
+ rtd->acp5x_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static int acp5x_dma_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime;
+ struct snd_soc_pcm_runtime *prtd;
+ struct i2s_dev_data *adata;
+ struct i2s_stream_instance *i2s_data;
+ int ret;
+
+ runtime = substream->runtime;
+ prtd = asoc_substream_to_rtd(substream);
+ component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+ adata = dev_get_drvdata(component->dev);
+
+ i2s_data = kzalloc(sizeof(*i2s_data), GFP_KERNEL);
+ if (!i2s_data)
+ return -ENOMEM;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ runtime->hw = acp5x_pcm_hardware_playback;
+ else
+ runtime->hw = acp5x_pcm_hardware_capture;
+
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(i2s_data);
+ return ret;
+ }
+ i2s_data->acp5x_base = adata->acp5x_base;
+ runtime->private_data = i2s_data;
+ return ret;
+}
+
+static int acp5x_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct i2s_stream_instance *rtd;
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp5x_platform_info *pinfo;
+ struct i2s_dev_data *adata;
+ u64 size;
+
+ prtd = asoc_substream_to_rtd(substream);
+ card = prtd->card;
+ pinfo = snd_soc_card_get_drvdata(card);
+ adata = dev_get_drvdata(component->dev);
+ rtd = substream->runtime->private_data;
+
+ if (!rtd)
+ return -EINVAL;
+
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ adata->play_stream = substream;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_play_stream = substream;
+ }
+ } else {
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ adata->capture_stream = substream;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_capture_stream = substream;
+ }
+ }
+ } else {
+ dev_err(component->dev, "pinfo failed\n");
+ return -EINVAL;
+ }
+ size = params_buffer_bytes(params);
+ rtd->dma_addr = substream->runtime->dma_addr;
+ rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+ config_acp5x_dma(rtd, substream->stream);
+ return 0;
+}
+
+static snd_pcm_uframes_t acp5x_dma_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct i2s_stream_instance *rtd;
+ u32 pos;
+ u32 buffersize;
+ u64 bytescount;
+
+ rtd = substream->runtime->private_data;
+ buffersize = frames_to_bytes(substream->runtime,
+ substream->runtime->buffer_size);
+ bytescount = acp_get_byte_count(rtd, substream->stream);
+ if (bytescount > rtd->bytescount)
+ bytescount -= rtd->bytescount;
+ pos = do_div(bytescount, buffersize);
+ return bytes_to_frames(substream->runtime, pos);
+}
+
+static int acp5x_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct device *parent = component->dev->parent;
+
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ parent, MIN_BUFFER, MAX_BUFFER);
+ return 0;
+}
+
+static int acp5x_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *prtd;
+ struct i2s_dev_data *adata;
+ struct i2s_stream_instance *ins;
+
+ prtd = asoc_substream_to_rtd(substream);
+ component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+ adata = dev_get_drvdata(component->dev);
+ ins = substream->runtime->private_data;
+ if (!ins)
+ return -EINVAL;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (ins->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ adata->play_stream = NULL;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_play_stream = NULL;
+ }
+ } else {
+ switch (ins->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ adata->capture_stream = NULL;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_capture_stream = NULL;
+ }
+ }
+ kfree(ins);
+ return 0;
+}
+
+static const struct snd_soc_component_driver acp5x_i2s_component = {
+ .name = DRV_NAME,
+ .open = acp5x_dma_open,
+ .close = acp5x_dma_close,
+ .hw_params = acp5x_dma_hw_params,
+ .pointer = acp5x_dma_pointer,
+ .pcm_construct = acp5x_dma_new,
+};
+
+static int acp5x_audio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct i2s_dev_data *adata;
+ unsigned int irqflags;
+ int status;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "platform_data not retrieved\n");
+ return -ENODEV;
+ }
+ irqflags = *((unsigned int *)(pdev->dev.platform_data));
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ adata->acp5x_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!adata->acp5x_base)
+ return -ENOMEM;
+
+ status = platform_get_irq(pdev, 0);
+ if (status < 0)
+ return status;
+ adata->i2s_irq = status;
+
+ dev_set_drvdata(&pdev->dev, adata);
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp5x_i2s_component,
+ NULL, 0);
+ if (status) {
+ dev_err(&pdev->dev, "Fail to register acp i2s component\n");
+ return status;
+ }
+ status = devm_request_irq(&pdev->dev, adata->i2s_irq, i2s_irq_handler,
+ irqflags, "ACP5x_I2S_IRQ", adata);
+ if (status) {
+ dev_err(&pdev->dev, "ACP5x I2S IRQ request failed\n");
+ return status;
+ }
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ return 0;
+}
+
+static void acp5x_audio_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int __maybe_unused acp5x_pcm_resume(struct device *dev)
+{
+ struct i2s_dev_data *adata;
+ struct i2s_stream_instance *rtd;
+ u32 val;
+
+ adata = dev_get_drvdata(dev);
+
+ if (adata->play_stream && adata->play_stream->runtime) {
+ rtd = adata->play_stream->runtime->private_data;
+ config_acp5x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK);
+ acp_writel((rtd->xfer_resolution << 3), rtd->acp5x_base + ACP_HSTDM_ITER);
+ if (adata->tdm_mode == TDM_ENABLE) {
+ acp_writel(adata->tdm_fmt, adata->acp5x_base + ACP_HSTDM_TXFRMT);
+ val = acp_readl(adata->acp5x_base + ACP_HSTDM_ITER);
+ acp_writel(val | 0x2, adata->acp5x_base + ACP_HSTDM_ITER);
+ }
+ }
+ if (adata->i2ssp_play_stream && adata->i2ssp_play_stream->runtime) {
+ rtd = adata->i2ssp_play_stream->runtime->private_data;
+ config_acp5x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK);
+ acp_writel((rtd->xfer_resolution << 3), rtd->acp5x_base + ACP_I2STDM_ITER);
+ if (adata->tdm_mode == TDM_ENABLE) {
+ acp_writel(adata->tdm_fmt, adata->acp5x_base + ACP_I2STDM_TXFRMT);
+ val = acp_readl(adata->acp5x_base + ACP_I2STDM_ITER);
+ acp_writel(val | 0x2, adata->acp5x_base + ACP_I2STDM_ITER);
+ }
+ }
+
+ if (adata->capture_stream && adata->capture_stream->runtime) {
+ rtd = adata->capture_stream->runtime->private_data;
+ config_acp5x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
+ acp_writel((rtd->xfer_resolution << 3), rtd->acp5x_base + ACP_HSTDM_IRER);
+ if (adata->tdm_mode == TDM_ENABLE) {
+ acp_writel(adata->tdm_fmt, adata->acp5x_base + ACP_HSTDM_RXFRMT);
+ val = acp_readl(adata->acp5x_base + ACP_HSTDM_IRER);
+ acp_writel(val | 0x2, adata->acp5x_base + ACP_HSTDM_IRER);
+ }
+ }
+ if (adata->i2ssp_capture_stream && adata->i2ssp_capture_stream->runtime) {
+ rtd = adata->i2ssp_capture_stream->runtime->private_data;
+ config_acp5x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
+ acp_writel((rtd->xfer_resolution << 3), rtd->acp5x_base + ACP_I2STDM_IRER);
+ if (adata->tdm_mode == TDM_ENABLE) {
+ acp_writel(adata->tdm_fmt, adata->acp5x_base + ACP_I2STDM_RXFRMT);
+ val = acp_readl(adata->acp5x_base + ACP_I2STDM_IRER);
+ acp_writel(val | 0x2, adata->acp5x_base + ACP_I2STDM_IRER);
+ }
+ }
+ acp_writel(1, adata->acp5x_base + ACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static int __maybe_unused acp5x_pcm_suspend(struct device *dev)
+{
+ struct i2s_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ acp_writel(0, adata->acp5x_base + ACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static int __maybe_unused acp5x_pcm_runtime_resume(struct device *dev)
+{
+ struct i2s_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ acp_writel(1, adata->acp5x_base + ACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static const struct dev_pm_ops acp5x_pm_ops = {
+ SET_RUNTIME_PM_OPS(acp5x_pcm_suspend,
+ acp5x_pcm_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(acp5x_pcm_suspend, acp5x_pcm_resume)
+};
+
+static struct platform_driver acp5x_dma_driver = {
+ .probe = acp5x_audio_probe,
+ .remove_new = acp5x_audio_remove,
+ .driver = {
+ .name = "acp5x_i2s_dma",
+ .pm = &acp5x_pm_ops,
+ },
+};
+
+module_platform_driver(acp5x_dma_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP 5.x PCM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/vangogh/acp5x.h b/sound/soc/amd/vangogh/acp5x.h
new file mode 100644
index 0000000000..ac1936a8c4
--- /dev/null
+++ b/sound/soc/amd/vangogh/acp5x.h
@@ -0,0 +1,224 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ALSA SoC PCM Driver
+ *
+ * Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+ */
+
+#include "vg_chip_offset_byte.h"
+#include <sound/pcm.h>
+
+#define ACP5x_PHY_BASE_ADDRESS 0x1240000
+#define ACP_DEVICE_ID 0x15E2
+#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
+
+#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00
+#define ACP_PGFSM_STATUS_MASK 0x03
+#define ACP_POWERED_ON 0x00
+#define ACP_POWER_ON_IN_PROGRESS 0x01
+#define ACP_POWERED_OFF 0x02
+#define ACP_POWER_OFF_IN_PROGRESS 0x03
+
+#define ACP_ERR_INTR_MASK 0x20000000
+#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
+
+#define ACP5x_DEVS 4
+#define ACP5x_REG_START 0x1240000
+#define ACP5x_REG_END 0x1250200
+#define ACP5x_I2STDM_REG_START 0x1242400
+#define ACP5x_I2STDM_REG_END 0x1242410
+#define ACP5x_HS_TDM_REG_START 0x1242814
+#define ACP5x_HS_TDM_REG_END 0x1242824
+#define I2S_MODE 0
+#define ACP5x_I2S_MODE 1
+#define ACP5x_RES 4
+#define I2S_RX_THRESHOLD 27
+#define I2S_TX_THRESHOLD 28
+#define HS_TX_THRESHOLD 24
+#define HS_RX_THRESHOLD 23
+
+#define I2S_SP_INSTANCE 1
+#define I2S_HS_INSTANCE 2
+
+#define ACP_SRAM_PTE_OFFSET 0x02050000
+#define ACP_SRAM_SP_PB_PTE_OFFSET 0x0
+#define ACP_SRAM_SP_CP_PTE_OFFSET 0x100
+#define ACP_SRAM_HS_PB_PTE_OFFSET 0x200
+#define ACP_SRAM_HS_CP_PTE_OFFSET 0x300
+#define PAGE_SIZE_4K_ENABLE 0x2
+#define I2S_SP_TX_MEM_WINDOW_START 0x4000000
+#define I2S_SP_RX_MEM_WINDOW_START 0x4020000
+#define I2S_HS_TX_MEM_WINDOW_START 0x4040000
+#define I2S_HS_RX_MEM_WINDOW_START 0x4060000
+
+#define SP_PB_FIFO_ADDR_OFFSET 0x500
+#define SP_CAPT_FIFO_ADDR_OFFSET 0x700
+#define HS_PB_FIFO_ADDR_OFFSET 0x900
+#define HS_CAPT_FIFO_ADDR_OFFSET 0xB00
+#define PLAYBACK_MIN_NUM_PERIODS 2
+#define PLAYBACK_MAX_NUM_PERIODS 8
+#define PLAYBACK_MAX_PERIOD_SIZE 8192
+#define PLAYBACK_MIN_PERIOD_SIZE 1024
+#define CAPTURE_MIN_NUM_PERIODS 2
+#define CAPTURE_MAX_NUM_PERIODS 8
+#define CAPTURE_MAX_PERIOD_SIZE 8192
+#define CAPTURE_MIN_PERIOD_SIZE 1024
+
+#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
+#define MIN_BUFFER MAX_BUFFER
+#define FIFO_SIZE 0x100
+#define DMA_SIZE 0x40
+#define FRM_LEN 0x100
+
+#define I2S_MASTER_MODE_ENABLE 1
+#define I2S_MASTER_MODE_DISABLE 0
+
+#define SLOT_WIDTH_8 8
+#define SLOT_WIDTH_16 16
+#define SLOT_WIDTH_24 24
+#define SLOT_WIDTH_32 32
+#define TDM_ENABLE 1
+#define TDM_DISABLE 0
+#define ACP5x_ITER_IRER_SAMP_LEN_MASK 0x38
+
+struct i2s_dev_data {
+ bool tdm_mode;
+ bool master_mode;
+ int i2s_irq;
+ u16 i2s_instance;
+ u32 tdm_fmt;
+ void __iomem *acp5x_base;
+ struct snd_pcm_substream *play_stream;
+ struct snd_pcm_substream *capture_stream;
+ struct snd_pcm_substream *i2ssp_play_stream;
+ struct snd_pcm_substream *i2ssp_capture_stream;
+};
+
+struct i2s_stream_instance {
+ u16 num_pages;
+ u16 i2s_instance;
+ u16 direction;
+ u16 channels;
+ u32 xfer_resolution;
+ u32 val;
+ dma_addr_t dma_addr;
+ u64 bytescount;
+ void __iomem *acp5x_base;
+ u32 lrclk_div;
+ u32 bclk_div;
+};
+
+union acp_dma_count {
+ struct {
+ u32 low;
+ u32 high;
+ } bcount;
+ u64 bytescount;
+};
+
+struct acp5x_platform_info {
+ u16 play_i2s_instance;
+ u16 cap_i2s_instance;
+};
+
+union acp_i2stdm_mstrclkgen {
+ struct {
+ u32 i2stdm_master_mode : 1;
+ u32 i2stdm_format_mode : 1;
+ u32 i2stdm_lrclk_div_val : 9;
+ u32 i2stdm_bclk_div_val : 11;
+ u32:10;
+ } bitfields, bits;
+ u32 u32_all;
+};
+
+/* common header file uses exact offset rather than relative
+ * offset which requires subtraction logic from base_addr
+ * for accessing ACP5x MMIO space registers
+ */
+static inline u32 acp_readl(void __iomem *base_addr)
+{
+ return readl(base_addr - ACP5x_PHY_BASE_ADDRESS);
+}
+
+static inline void acp_writel(u32 val, void __iomem *base_addr)
+{
+ writel(val, base_addr - ACP5x_PHY_BASE_ADDRESS);
+}
+
+int snd_amd_acp_find_config(struct pci_dev *pci);
+
+static inline u64 acp_get_byte_count(struct i2s_stream_instance *rtd,
+ int direction)
+{
+ union acp_dma_count byte_count;
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ byte_count.bcount.high =
+ acp_readl(rtd->acp5x_base +
+ ACP_HS_TX_LINEARPOSCNTR_HIGH);
+ byte_count.bcount.low =
+ acp_readl(rtd->acp5x_base +
+ ACP_HS_TX_LINEARPOSCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ byte_count.bcount.high =
+ acp_readl(rtd->acp5x_base +
+ ACP_I2S_TX_LINEARPOSCNTR_HIGH);
+ byte_count.bcount.low =
+ acp_readl(rtd->acp5x_base +
+ ACP_I2S_TX_LINEARPOSCNTR_LOW);
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ byte_count.bcount.high =
+ acp_readl(rtd->acp5x_base +
+ ACP_HS_RX_LINEARPOSCNTR_HIGH);
+ byte_count.bcount.low =
+ acp_readl(rtd->acp5x_base +
+ ACP_HS_RX_LINEARPOSCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ byte_count.bcount.high =
+ acp_readl(rtd->acp5x_base +
+ ACP_I2S_RX_LINEARPOSCNTR_HIGH);
+ byte_count.bcount.low =
+ acp_readl(rtd->acp5x_base +
+ ACP_I2S_RX_LINEARPOSCNTR_LOW);
+ }
+ }
+ return byte_count.bytescount;
+}
+
+static inline void acp5x_set_i2s_clk(struct i2s_dev_data *adata,
+ struct i2s_stream_instance *rtd)
+{
+ union acp_i2stdm_mstrclkgen mclkgen;
+ u32 master_reg;
+
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ master_reg = ACP_I2STDM2_MSTRCLKGEN;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ master_reg = ACP_I2STDM0_MSTRCLKGEN;
+ break;
+ }
+
+ mclkgen.bits.i2stdm_master_mode = 0x1;
+ if (adata->tdm_mode)
+ mclkgen.bits.i2stdm_format_mode = 0x01;
+ else
+ mclkgen.bits.i2stdm_format_mode = 0x00;
+
+ mclkgen.bits.i2stdm_bclk_div_val = rtd->bclk_div;
+ mclkgen.bits.i2stdm_lrclk_div_val = rtd->lrclk_div;
+ acp_writel(mclkgen.u32_all, rtd->acp5x_base + master_reg);
+}
diff --git a/sound/soc/amd/vangogh/pci-acp5x.c b/sound/soc/amd/vangogh/pci-acp5x.c
new file mode 100644
index 0000000000..c4634a8a17
--- /dev/null
+++ b/sound/soc/amd/vangogh/pci-acp5x.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD Vangogh ACP PCI Driver
+//
+// Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+
+#include "acp5x.h"
+
+struct acp5x_dev_data {
+ void __iomem *acp5x_base;
+ bool acp5x_audio_mode;
+ struct resource *res;
+ struct platform_device *pdev[ACP5x_DEVS];
+};
+
+static int acp5x_power_on(void __iomem *acp5x_base)
+{
+ u32 val;
+ int timeout;
+
+ val = acp_readl(acp5x_base + ACP_PGFSM_STATUS);
+
+ if (val == 0)
+ return val;
+
+ if ((val & ACP_PGFSM_STATUS_MASK) !=
+ ACP_POWER_ON_IN_PROGRESS)
+ acp_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
+ acp5x_base + ACP_PGFSM_CONTROL);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = acp_readl(acp5x_base + ACP_PGFSM_STATUS);
+ if ((val & ACP_PGFSM_STATUS_MASK) == ACP_POWERED_ON)
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int acp5x_reset(void __iomem *acp5x_base)
+{
+ u32 val;
+ int timeout;
+
+ acp_writel(1, acp5x_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = acp_readl(acp5x_base + ACP_SOFT_RESET);
+ if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
+ break;
+ cpu_relax();
+ }
+ acp_writel(0, acp5x_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = acp_readl(acp5x_base + ACP_SOFT_RESET);
+ if (!val)
+ return 0;
+ cpu_relax();
+ }
+ return -ETIMEDOUT;
+}
+
+static void acp5x_enable_interrupts(void __iomem *acp5x_base)
+{
+ acp_writel(0x01, acp5x_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static void acp5x_disable_interrupts(void __iomem *acp5x_base)
+{
+ acp_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp5x_base +
+ ACP_EXTERNAL_INTR_STAT);
+ acp_writel(0x00, acp5x_base + ACP_EXTERNAL_INTR_CNTL);
+ acp_writel(0x00, acp5x_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static int acp5x_init(void __iomem *acp5x_base)
+{
+ int ret;
+
+ /* power on */
+ ret = acp5x_power_on(acp5x_base);
+ if (ret) {
+ pr_err("ACP5x power on failed\n");
+ return ret;
+ }
+ acp_writel(0x01, acp5x_base + ACP_CONTROL);
+ /* Reset */
+ ret = acp5x_reset(acp5x_base);
+ if (ret) {
+ pr_err("ACP5x reset failed\n");
+ return ret;
+ }
+ acp_writel(0x03, acp5x_base + ACP_CLKMUX_SEL);
+ acp5x_enable_interrupts(acp5x_base);
+ return 0;
+}
+
+static int acp5x_deinit(void __iomem *acp5x_base)
+{
+ int ret;
+
+ acp5x_disable_interrupts(acp5x_base);
+ /* Reset */
+ ret = acp5x_reset(acp5x_base);
+ if (ret) {
+ pr_err("ACP5x reset failed\n");
+ return ret;
+ }
+ acp_writel(0x00, acp5x_base + ACP_CLKMUX_SEL);
+ acp_writel(0x00, acp5x_base + ACP_CONTROL);
+ return 0;
+}
+
+static int snd_acp5x_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ struct acp5x_dev_data *adata;
+ struct platform_device_info pdevinfo[ACP5x_DEVS];
+ unsigned int irqflags, flag;
+ int ret, i;
+ u32 addr, val;
+
+ /* Return if acp config flag is defined */
+ flag = snd_amd_acp_find_config(pci);
+ if (flag)
+ return -ENODEV;
+
+ irqflags = IRQF_SHARED;
+ if (pci->revision != 0x50)
+ return -ENODEV;
+
+ if (pci_enable_device(pci)) {
+ dev_err(&pci->dev, "pci_enable_device failed\n");
+ return -ENODEV;
+ }
+
+ ret = pci_request_regions(pci, "AMD ACP5x audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+ }
+
+ adata = devm_kzalloc(&pci->dev, sizeof(struct acp5x_dev_data),
+ GFP_KERNEL);
+ if (!adata) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+ addr = pci_resource_start(pci, 0);
+ adata->acp5x_base = devm_ioremap(&pci->dev, addr,
+ pci_resource_len(pci, 0));
+ if (!adata->acp5x_base) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+ pci_set_master(pci);
+ pci_set_drvdata(pci, adata);
+ ret = acp5x_init(adata->acp5x_base);
+ if (ret)
+ goto release_regions;
+
+ val = acp_readl(adata->acp5x_base + ACP_PIN_CONFIG);
+ switch (val) {
+ case I2S_MODE:
+ adata->res = devm_kzalloc(&pci->dev,
+ sizeof(struct resource) * ACP5x_RES,
+ GFP_KERNEL);
+ if (!adata->res) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+
+ adata->res[0].name = "acp5x_i2s_iomem";
+ adata->res[0].flags = IORESOURCE_MEM;
+ adata->res[0].start = addr;
+ adata->res[0].end = addr + (ACP5x_REG_END - ACP5x_REG_START);
+
+ adata->res[1].name = "acp5x_i2s_sp";
+ adata->res[1].flags = IORESOURCE_MEM;
+ adata->res[1].start = addr + ACP5x_I2STDM_REG_START;
+ adata->res[1].end = addr + ACP5x_I2STDM_REG_END;
+
+ adata->res[2].name = "acp5x_i2s_hs";
+ adata->res[2].flags = IORESOURCE_MEM;
+ adata->res[2].start = addr + ACP5x_HS_TDM_REG_START;
+ adata->res[2].end = addr + ACP5x_HS_TDM_REG_END;
+
+ adata->res[3].name = "acp5x_i2s_irq";
+ adata->res[3].flags = IORESOURCE_IRQ;
+ adata->res[3].start = pci->irq;
+ adata->res[3].end = adata->res[3].start;
+
+ adata->acp5x_audio_mode = ACP5x_I2S_MODE;
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ pdevinfo[0].name = "acp5x_i2s_dma";
+ pdevinfo[0].id = 0;
+ pdevinfo[0].parent = &pci->dev;
+ pdevinfo[0].num_res = 4;
+ pdevinfo[0].res = &adata->res[0];
+ pdevinfo[0].data = &irqflags;
+ pdevinfo[0].size_data = sizeof(irqflags);
+
+ pdevinfo[1].name = "acp5x_i2s_playcap";
+ pdevinfo[1].id = 0;
+ pdevinfo[1].parent = &pci->dev;
+ pdevinfo[1].num_res = 1;
+ pdevinfo[1].res = &adata->res[1];
+
+ pdevinfo[2].name = "acp5x_i2s_playcap";
+ pdevinfo[2].id = 1;
+ pdevinfo[2].parent = &pci->dev;
+ pdevinfo[2].num_res = 1;
+ pdevinfo[2].res = &adata->res[2];
+
+ pdevinfo[3].name = "acp5x_mach";
+ pdevinfo[3].id = 0;
+ pdevinfo[3].parent = &pci->dev;
+ for (i = 0; i < ACP5x_DEVS; i++) {
+ adata->pdev[i] =
+ platform_device_register_full(&pdevinfo[i]);
+ if (IS_ERR(adata->pdev[i])) {
+ dev_err(&pci->dev, "cannot register %s device\n",
+ pdevinfo[i].name);
+ ret = PTR_ERR(adata->pdev[i]);
+ goto unregister_devs;
+ }
+ }
+ break;
+ default:
+ dev_info(&pci->dev, "ACP audio mode : %d\n", val);
+ }
+ pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_put_noidle(&pci->dev);
+ pm_runtime_allow(&pci->dev);
+ return 0;
+
+unregister_devs:
+ for (--i; i >= 0; i--)
+ platform_device_unregister(adata->pdev[i]);
+de_init:
+ if (acp5x_deinit(adata->acp5x_base))
+ dev_err(&pci->dev, "ACP de-init failed\n");
+release_regions:
+ pci_release_regions(pci);
+disable_pci:
+ pci_disable_device(pci);
+
+ return ret;
+}
+
+static int __maybe_unused snd_acp5x_suspend(struct device *dev)
+{
+ int ret;
+ struct acp5x_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = acp5x_deinit(adata->acp5x_base);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+ else
+ dev_dbg(dev, "ACP de-initialized\n");
+
+ return ret;
+}
+
+static int __maybe_unused snd_acp5x_resume(struct device *dev)
+{
+ int ret;
+ struct acp5x_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = acp5x_init(adata->acp5x_base);
+ if (ret) {
+ dev_err(dev, "ACP init failed\n");
+ return ret;
+ }
+ return 0;
+}
+
+static const struct dev_pm_ops acp5x_pm = {
+ SET_RUNTIME_PM_OPS(snd_acp5x_suspend,
+ snd_acp5x_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(snd_acp5x_suspend, snd_acp5x_resume)
+};
+
+static void snd_acp5x_remove(struct pci_dev *pci)
+{
+ struct acp5x_dev_data *adata;
+ int i, ret;
+
+ adata = pci_get_drvdata(pci);
+ if (adata->acp5x_audio_mode == ACP5x_I2S_MODE) {
+ for (i = 0; i < ACP5x_DEVS; i++)
+ platform_device_unregister(adata->pdev[i]);
+ }
+ ret = acp5x_deinit(adata->acp5x_base);
+ if (ret)
+ dev_err(&pci->dev, "ACP de-init failed\n");
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_get_noresume(&pci->dev);
+ pci_release_regions(pci);
+ pci_disable_device(pci);
+}
+
+static const struct pci_device_id snd_acp5x_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
+ .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
+ .class_mask = 0xffffff },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_acp5x_ids);
+
+static struct pci_driver acp5x_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = snd_acp5x_ids,
+ .probe = snd_acp5x_probe,
+ .remove = snd_acp5x_remove,
+ .driver = {
+ .pm = &acp5x_pm,
+ }
+};
+
+module_pci_driver(acp5x_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD Vangogh ACP PCI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/vangogh/vg_chip_offset_byte.h b/sound/soc/amd/vangogh/vg_chip_offset_byte.h
new file mode 100644
index 0000000000..b1165ae142
--- /dev/null
+++ b/sound/soc/amd/vangogh/vg_chip_offset_byte.h
@@ -0,0 +1,337 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ACP 5.x Register Documentation
+ *
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ */
+
+#ifndef _acp_ip_OFFSET_HEADER
+#define _acp_ip_OFFSET_HEADER
+
+/* Registers from ACP_DMA block */
+#define ACP_DMA_CNTL_0 0x1240000
+#define ACP_DMA_CNTL_1 0x1240004
+#define ACP_DMA_CNTL_2 0x1240008
+#define ACP_DMA_CNTL_3 0x124000C
+#define ACP_DMA_CNTL_4 0x1240010
+#define ACP_DMA_CNTL_5 0x1240014
+#define ACP_DMA_CNTL_6 0x1240018
+#define ACP_DMA_CNTL_7 0x124001C
+#define ACP_DMA_DSCR_STRT_IDX_0 0x1240020
+#define ACP_DMA_DSCR_STRT_IDX_1 0x1240024
+#define ACP_DMA_DSCR_STRT_IDX_2 0x1240028
+#define ACP_DMA_DSCR_STRT_IDX_3 0x124002C
+#define ACP_DMA_DSCR_STRT_IDX_4 0x1240030
+#define ACP_DMA_DSCR_STRT_IDX_5 0x1240034
+#define ACP_DMA_DSCR_STRT_IDX_6 0x1240038
+#define ACP_DMA_DSCR_STRT_IDX_7 0x124003C
+#define ACP_DMA_DSCR_CNT_0 0x1240040
+#define ACP_DMA_DSCR_CNT_1 0x1240044
+#define ACP_DMA_DSCR_CNT_2 0x1240048
+#define ACP_DMA_DSCR_CNT_3 0x124004C
+#define ACP_DMA_DSCR_CNT_4 0x1240050
+#define ACP_DMA_DSCR_CNT_5 0x1240054
+#define ACP_DMA_DSCR_CNT_6 0x1240058
+#define ACP_DMA_DSCR_CNT_7 0x124005C
+#define ACP_DMA_PRIO_0 0x1240060
+#define ACP_DMA_PRIO_1 0x1240064
+#define ACP_DMA_PRIO_2 0x1240068
+#define ACP_DMA_PRIO_3 0x124006C
+#define ACP_DMA_PRIO_4 0x1240070
+#define ACP_DMA_PRIO_5 0x1240074
+#define ACP_DMA_PRIO_6 0x1240078
+#define ACP_DMA_PRIO_7 0x124007C
+#define ACP_DMA_CUR_DSCR_0 0x1240080
+#define ACP_DMA_CUR_DSCR_1 0x1240084
+#define ACP_DMA_CUR_DSCR_2 0x1240088
+#define ACP_DMA_CUR_DSCR_3 0x124008C
+#define ACP_DMA_CUR_DSCR_4 0x1240090
+#define ACP_DMA_CUR_DSCR_5 0x1240094
+#define ACP_DMA_CUR_DSCR_6 0x1240098
+#define ACP_DMA_CUR_DSCR_7 0x124009C
+#define ACP_DMA_CUR_TRANS_CNT_0 0x12400A0
+#define ACP_DMA_CUR_TRANS_CNT_1 0x12400A4
+#define ACP_DMA_CUR_TRANS_CNT_2 0x12400A8
+#define ACP_DMA_CUR_TRANS_CNT_3 0x12400AC
+#define ACP_DMA_CUR_TRANS_CNT_4 0x12400B0
+#define ACP_DMA_CUR_TRANS_CNT_5 0x12400B4
+#define ACP_DMA_CUR_TRANS_CNT_6 0x12400B8
+#define ACP_DMA_CUR_TRANS_CNT_7 0x12400BC
+#define ACP_DMA_ERR_STS_0 0x12400C0
+#define ACP_DMA_ERR_STS_1 0x12400C4
+#define ACP_DMA_ERR_STS_2 0x12400C8
+#define ACP_DMA_ERR_STS_3 0x12400CC
+#define ACP_DMA_ERR_STS_4 0x12400D0
+#define ACP_DMA_ERR_STS_5 0x12400D4
+#define ACP_DMA_ERR_STS_6 0x12400D8
+#define ACP_DMA_ERR_STS_7 0x12400DC
+#define ACP_DMA_DESC_BASE_ADDR 0x12400E0
+#define ACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4
+#define ACP_DMA_CH_STS 0x12400E8
+#define ACP_DMA_CH_GROUP 0x12400EC
+#define ACP_DMA_CH_RST_STS 0x12400F0
+
+/* Registers from ACP_AXI2AXIATU block */
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0x1240C00
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_1 0x1240C04
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2 0x1240C08
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_2 0x1240C0C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_3 0x1240C10
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_3 0x1240C14
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_4 0x1240C18
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_4 0x1240C1C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0x1240C20
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0x1240C24
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_6 0x1240C28
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_6 0x1240C2C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_7 0x1240C30
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_7 0x1240C34
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_8 0x1240C38
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_8 0x1240C3C
+#define ACPAXI2AXI_ATU_CTRL 0x1240C40
+
+/* Registers from ACP_CLKRST block */
+#define ACP_SOFT_RESET 0x1241000
+#define ACP_CONTROL 0x1241004
+#define ACP_STATUS 0x1241008
+#define ACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
+
+/* Registers from ACP_MISC block */
+#define ACP_EXTERNAL_INTR_ENB 0x1241800
+#define ACP_EXTERNAL_INTR_CNTL 0x1241804
+#define ACP_EXTERNAL_INTR_STAT 0x1241808
+#define ACP_ERROR_STATUS 0x12418C4
+#define ACP_SW_I2S_ERROR_REASON 0x12418C8
+#define ACP_MEM_PG_STS 0x12418CC
+#define ACP_PGMEM_DEEP_SLEEP_CTRL 0x12418D0
+#define ACP_PGMEM_SHUT_DOWN_CTRL 0x12418D4
+
+/* Registers from ACP_PGFSM block */
+#define ACP_PIN_CONFIG 0x1241400
+#define ACP_PAD_PULLUP_CTRL 0x1241404
+#define ACP_PAD_PULLDOWN_CTRL 0x1241408
+#define ACP_PAD_DRIVE_STRENGTH_CTRL 0x124140C
+#define ACP_PAD_SCHMEN_CTRL 0x1241410
+#define ACP_SW_PAD_KEEPER_EN 0x1241414
+#define ACP_SW_WAKE_EN 0x1241418
+#define ACP_I2S_WAKE_EN 0x124141C
+#define ACP_PME_EN 0x1241420
+#define ACP_PGFSM_CONTROL 0x1241424
+#define ACP_PGFSM_STATUS 0x1241428
+#define ACP_CLKMUX_SEL 0x124142C
+#define ACP_DEVICE_STATE 0x1241430
+#define AZ_DEVICE_STATE 0x1241434
+#define ACP_INTR_URGENCY_TIMER 0x1241438
+#define AZ_INTR_URGENCY_TIMER 0x124143C
+#define ACP_AON_SW_INTR_TRIG 0x1241440
+
+/* Registers from ACP_SCRATCH block */
+#define ACP_SCRATCH_REG_0 0x1250000
+#define ACP_SCRATCH_REG_1 0x1250004
+#define ACP_SCRATCH_REG_2 0x1250008
+#define ACP_SCRATCH_REG_3 0x125000C
+#define ACP_SCRATCH_REG_4 0x1250010
+#define ACP_SCRATCH_REG_5 0x1250014
+#define ACP_SCRATCH_REG_6 0x1250018
+#define ACP_SCRATCH_REG_7 0x125001C
+#define ACP_SCRATCH_REG_8 0x1250020
+#define ACP_SCRATCH_REG_9 0x1250024
+#define ACP_SCRATCH_REG_10 0x1250028
+#define ACP_SCRATCH_REG_11 0x125002C
+#define ACP_SCRATCH_REG_12 0x1250030
+#define ACP_SCRATCH_REG_13 0x1250034
+#define ACP_SCRATCH_REG_14 0x1250038
+#define ACP_SCRATCH_REG_15 0x125003C
+#define ACP_SCRATCH_REG_16 0x1250040
+#define ACP_SCRATCH_REG_17 0x1250044
+#define ACP_SCRATCH_REG_18 0x1250048
+#define ACP_SCRATCH_REG_19 0x125004C
+#define ACP_SCRATCH_REG_20 0x1250050
+#define ACP_SCRATCH_REG_21 0x1250054
+#define ACP_SCRATCH_REG_22 0x1250058
+#define ACP_SCRATCH_REG_23 0x125005C
+#define ACP_SCRATCH_REG_24 0x1250060
+#define ACP_SCRATCH_REG_25 0x1250064
+#define ACP_SCRATCH_REG_26 0x1250068
+#define ACP_SCRATCH_REG_27 0x125006C
+#define ACP_SCRATCH_REG_28 0x1250070
+#define ACP_SCRATCH_REG_29 0x1250074
+#define ACP_SCRATCH_REG_30 0x1250078
+#define ACP_SCRATCH_REG_31 0x125007C
+#define ACP_SCRATCH_REG_32 0x1250080
+#define ACP_SCRATCH_REG_33 0x1250084
+#define ACP_SCRATCH_REG_34 0x1250088
+#define ACP_SCRATCH_REG_35 0x125008C
+#define ACP_SCRATCH_REG_36 0x1250090
+#define ACP_SCRATCH_REG_37 0x1250094
+#define ACP_SCRATCH_REG_38 0x1250098
+#define ACP_SCRATCH_REG_39 0x125009C
+#define ACP_SCRATCH_REG_40 0x12500A0
+#define ACP_SCRATCH_REG_41 0x12500A4
+#define ACP_SCRATCH_REG_42 0x12500A8
+#define ACP_SCRATCH_REG_43 0x12500AC
+#define ACP_SCRATCH_REG_44 0x12500B0
+#define ACP_SCRATCH_REG_45 0x12500B4
+#define ACP_SCRATCH_REG_46 0x12500B8
+#define ACP_SCRATCH_REG_47 0x12500BC
+#define ACP_SCRATCH_REG_48 0x12500C0
+#define ACP_SCRATCH_REG_49 0x12500C4
+#define ACP_SCRATCH_REG_50 0x12500C8
+#define ACP_SCRATCH_REG_51 0x12500CC
+#define ACP_SCRATCH_REG_52 0x12500D0
+#define ACP_SCRATCH_REG_53 0x12500D4
+#define ACP_SCRATCH_REG_54 0x12500D8
+#define ACP_SCRATCH_REG_55 0x12500DC
+#define ACP_SCRATCH_REG_56 0x12500E0
+#define ACP_SCRATCH_REG_57 0x12500E4
+#define ACP_SCRATCH_REG_58 0x12500E8
+#define ACP_SCRATCH_REG_59 0x12500EC
+#define ACP_SCRATCH_REG_60 0x12500F0
+#define ACP_SCRATCH_REG_61 0x12500F4
+#define ACP_SCRATCH_REG_62 0x12500F8
+#define ACP_SCRATCH_REG_63 0x12500FC
+#define ACP_SCRATCH_REG_64 0x1250100
+#define ACP_SCRATCH_REG_65 0x1250104
+#define ACP_SCRATCH_REG_66 0x1250108
+#define ACP_SCRATCH_REG_67 0x125010C
+#define ACP_SCRATCH_REG_68 0x1250110
+#define ACP_SCRATCH_REG_69 0x1250114
+#define ACP_SCRATCH_REG_70 0x1250118
+#define ACP_SCRATCH_REG_71 0x125011C
+#define ACP_SCRATCH_REG_72 0x1250120
+#define ACP_SCRATCH_REG_73 0x1250124
+#define ACP_SCRATCH_REG_74 0x1250128
+#define ACP_SCRATCH_REG_75 0x125012C
+#define ACP_SCRATCH_REG_76 0x1250130
+#define ACP_SCRATCH_REG_77 0x1250134
+#define ACP_SCRATCH_REG_78 0x1250138
+#define ACP_SCRATCH_REG_79 0x125013C
+#define ACP_SCRATCH_REG_80 0x1250140
+#define ACP_SCRATCH_REG_81 0x1250144
+#define ACP_SCRATCH_REG_82 0x1250148
+#define ACP_SCRATCH_REG_83 0x125014C
+#define ACP_SCRATCH_REG_84 0x1250150
+#define ACP_SCRATCH_REG_85 0x1250154
+#define ACP_SCRATCH_REG_86 0x1250158
+#define ACP_SCRATCH_REG_87 0x125015C
+#define ACP_SCRATCH_REG_88 0x1250160
+#define ACP_SCRATCH_REG_89 0x1250164
+#define ACP_SCRATCH_REG_90 0x1250168
+#define ACP_SCRATCH_REG_91 0x125016C
+#define ACP_SCRATCH_REG_92 0x1250170
+#define ACP_SCRATCH_REG_93 0x1250174
+#define ACP_SCRATCH_REG_94 0x1250178
+#define ACP_SCRATCH_REG_95 0x125017C
+#define ACP_SCRATCH_REG_96 0x1250180
+#define ACP_SCRATCH_REG_97 0x1250184
+#define ACP_SCRATCH_REG_98 0x1250188
+#define ACP_SCRATCH_REG_99 0x125018C
+#define ACP_SCRATCH_REG_100 0x1250190
+#define ACP_SCRATCH_REG_101 0x1250194
+#define ACP_SCRATCH_REG_102 0x1250198
+#define ACP_SCRATCH_REG_103 0x125019C
+#define ACP_SCRATCH_REG_104 0x12501A0
+#define ACP_SCRATCH_REG_105 0x12501A4
+#define ACP_SCRATCH_REG_106 0x12501A8
+#define ACP_SCRATCH_REG_107 0x12501AC
+#define ACP_SCRATCH_REG_108 0x12501B0
+#define ACP_SCRATCH_REG_109 0x12501B4
+#define ACP_SCRATCH_REG_110 0x12501B8
+#define ACP_SCRATCH_REG_111 0x12501BC
+#define ACP_SCRATCH_REG_112 0x12501C0
+#define ACP_SCRATCH_REG_113 0x12501C4
+#define ACP_SCRATCH_REG_114 0x12501C8
+#define ACP_SCRATCH_REG_115 0x12501CC
+#define ACP_SCRATCH_REG_116 0x12501D0
+#define ACP_SCRATCH_REG_117 0x12501D4
+#define ACP_SCRATCH_REG_118 0x12501D8
+#define ACP_SCRATCH_REG_119 0x12501DC
+#define ACP_SCRATCH_REG_120 0x12501E0
+#define ACP_SCRATCH_REG_121 0x12501E4
+#define ACP_SCRATCH_REG_122 0x12501E8
+#define ACP_SCRATCH_REG_123 0x12501EC
+#define ACP_SCRATCH_REG_124 0x12501F0
+#define ACP_SCRATCH_REG_125 0x12501F4
+#define ACP_SCRATCH_REG_126 0x12501F8
+#define ACP_SCRATCH_REG_127 0x12501FC
+#define ACP_SCRATCH_REG_128 0x1250200
+
+/* Registers from ACP_AUDIO_BUFFERS block */
+#define ACP_I2S_RX_RINGBUFADDR 0x1242000
+#define ACP_I2S_RX_RINGBUFSIZE 0x1242004
+#define ACP_I2S_RX_LINKPOSITIONCNTR 0x1242008
+#define ACP_I2S_RX_FIFOADDR 0x124200C
+#define ACP_I2S_RX_FIFOSIZE 0x1242010
+#define ACP_I2S_RX_DMA_SIZE 0x1242014
+#define ACP_I2S_RX_LINEARPOSCNTR_HIGH 0x1242018
+#define ACP_I2S_RX_LINEARPOSCNTR_LOW 0x124201C
+#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x1242020
+#define ACP_I2S_TX_RINGBUFADDR 0x1242024
+#define ACP_I2S_TX_RINGBUFSIZE 0x1242028
+#define ACP_I2S_TX_LINKPOSITIONCNTR 0x124202C
+#define ACP_I2S_TX_FIFOADDR 0x1242030
+#define ACP_I2S_TX_FIFOSIZE 0x1242034
+#define ACP_I2S_TX_DMA_SIZE 0x1242038
+#define ACP_I2S_TX_LINEARPOSCNTR_HIGH 0x124203C
+#define ACP_I2S_TX_LINEARPOSCNTR_LOW 0x1242040
+#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x1242044
+#define ACP_BT_RX_RINGBUFADDR 0x1242048
+#define ACP_BT_RX_RINGBUFSIZE 0x124204C
+#define ACP_BT_RX_LINKPOSITIONCNTR 0x1242050
+#define ACP_BT_RX_FIFOADDR 0x1242054
+#define ACP_BT_RX_FIFOSIZE 0x1242058
+#define ACP_BT_RX_DMA_SIZE 0x124205C
+#define ACP_BT_RX_LINEARPOSCNTR_HIGH 0x1242060
+#define ACP_BT_RX_LINEARPOSCNTR_LOW 0x1242064
+#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068
+#define ACP_BT_TX_RINGBUFADDR 0x124206C
+#define ACP_BT_TX_RINGBUFSIZE 0x1242070
+#define ACP_BT_TX_LINKPOSITIONCNTR 0x1242074
+#define ACP_BT_TX_FIFOADDR 0x1242078
+#define ACP_BT_TX_FIFOSIZE 0x124207C
+#define ACP_BT_TX_DMA_SIZE 0x1242080
+#define ACP_BT_TX_LINEARPOSCNTR_HIGH 0x1242084
+#define ACP_BT_TX_LINEARPOSCNTR_LOW 0x1242088
+#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C
+#define ACP_HS_RX_RINGBUFADDR 0x1242090
+#define ACP_HS_RX_RINGBUFSIZE 0x1242094
+#define ACP_HS_RX_LINKPOSITIONCNTR 0x1242098
+#define ACP_HS_RX_FIFOADDR 0x124209C
+#define ACP_HS_RX_FIFOSIZE 0x12420A0
+#define ACP_HS_RX_DMA_SIZE 0x12420A4
+#define ACP_HS_RX_LINEARPOSCNTR_HIGH 0x12420A8
+#define ACP_HS_RX_LINEARPOSCNTR_LOW 0x12420AC
+#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0
+#define ACP_HS_TX_RINGBUFADDR 0x12420B4
+#define ACP_HS_TX_RINGBUFSIZE 0x12420B8
+#define ACP_HS_TX_LINKPOSITIONCNTR 0x12420BC
+#define ACP_HS_TX_FIFOADDR 0x12420C0
+#define ACP_HS_TX_FIFOSIZE 0x12420C4
+#define ACP_HS_TX_DMA_SIZE 0x12420C8
+#define ACP_HS_TX_LINEARPOSCNTR_HIGH 0x12420CC
+#define ACP_HS_TX_LINEARPOSCNTR_LOW 0x12420D0
+#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4
+
+/* Registers from ACP_I2S_TDM block */
+#define ACP_I2STDM_IER 0x1242400
+#define ACP_I2STDM_IRER 0x1242404
+#define ACP_I2STDM_RXFRMT 0x1242408
+#define ACP_I2STDM_ITER 0x124240C
+#define ACP_I2STDM_TXFRMT 0x1242410
+#define ACP_I2STDM0_MSTRCLKGEN 0x1242414
+#define ACP_I2STDM1_MSTRCLKGEN 0x1242418
+#define ACP_I2STDM2_MSTRCLKGEN 0x124241C
+#define ACP_I2STDM_REFCLKGEN 0x1242420
+
+/* Registers from ACP_BT_TDM block */
+#define ACP_BTTDM_IER 0x1242800
+#define ACP_BTTDM_IRER 0x1242804
+#define ACP_BTTDM_RXFRMT 0x1242808
+#define ACP_BTTDM_ITER 0x124280C
+#define ACP_BTTDM_TXFRMT 0x1242810
+#define ACP_HSTDM_IER 0x1242814
+#define ACP_HSTDM_IRER 0x1242818
+#define ACP_HSTDM_RXFRMT 0x124281C
+#define ACP_HSTDM_ITER 0x1242820
+#define ACP_HSTDM_TXFRMT 0x1242824
+#endif
diff --git a/sound/soc/amd/yc/Makefile b/sound/soc/amd/yc/Makefile
new file mode 100644
index 0000000000..dc29744403
--- /dev/null
+++ b/sound/soc/amd/yc/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Yellow Carp platform Support
+snd-pci-acp6x-objs := pci-acp6x.o
+snd-acp6x-pdm-dma-objs := acp6x-pdm-dma.o
+snd-soc-acp6x-mach-objs := acp6x-mach.o
+
+obj-$(CONFIG_SND_SOC_AMD_ACP6x) += snd-pci-acp6x.o
+obj-$(CONFIG_SND_SOC_AMD_ACP6x) += snd-acp6x-pdm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_YC_MACH) += snd-soc-acp6x-mach.o
diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
new file mode 100644
index 0000000000..d83cb6e4c6
--- /dev/null
+++ b/sound/soc/amd/yc/acp6x-mach.c
@@ -0,0 +1,459 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Machine driver for AMD Yellow Carp platform using DMIC
+ *
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ */
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/module.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <linux/io.h>
+#include <linux/dmi.h>
+#include <linux/acpi.h>
+
+#include "acp6x.h"
+
+#define DRV_NAME "acp_yc_mach"
+
+SND_SOC_DAILINK_DEF(acp6x_pdm,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp_yc_pdm_dma.0")));
+
+SND_SOC_DAILINK_DEF(dmic_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec.0",
+ "dmic-hifi")));
+
+SND_SOC_DAILINK_DEF(pdm_platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_yc_pdm_dma.0")));
+
+static struct snd_soc_dai_link acp6x_dai_pdm[] = {
+ {
+ .name = "acp6x-dmic-capture",
+ .stream_name = "DMIC capture",
+ .capture_only = 1,
+ SND_SOC_DAILINK_REG(acp6x_pdm, dmic_codec, pdm_platform),
+ },
+};
+
+static struct snd_soc_card acp6x_card = {
+ .name = "acp6x",
+ .owner = THIS_MODULE,
+ .dai_link = acp6x_dai_pdm,
+ .num_links = 1,
+};
+
+static const struct dmi_system_id yc_acp_quirk_table[] = {
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5525"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21D1"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21D2"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21D3"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21D4"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21D5"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CF"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CG"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CQ"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CR"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CM"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CN"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CH"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CJ"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CK"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21CL"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21EF"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21EM"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21EN"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21HY"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21J5"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21J6"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "82QF"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "82TL"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "82UG"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "82V2"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "82YM"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M5402RA"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M6400RC"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M3402RA"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "E1504FA"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 B7ED"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 15 2022"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Razer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Blade 14 (2022) - RZ09-0427"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "RB"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Swift SFA16-41"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "IRBIS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_BOARD_NAME, "8A42"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_BOARD_NAME, "8A43"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_BOARD_NAME, "8A22"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_BOARD_NAME, "8A3E"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_BOARD_NAME, "8B2F"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "MECHREVO"),
+ DMI_MATCH(DMI_BOARD_NAME, "MRID6"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "System76"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "pang12"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "System76"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "pang13"),
+ }
+ },
+ {}
+};
+
+static int acp6x_probe(struct platform_device *pdev)
+{
+ const struct dmi_system_id *dmi_id;
+ struct acp6x_pdm *machine = NULL;
+ struct snd_soc_card *card;
+ struct acpi_device *adev;
+ int ret;
+
+ /* check the parent device's firmware node has _DSD or not */
+ adev = ACPI_COMPANION(pdev->dev.parent);
+ if (adev) {
+ const union acpi_object *obj;
+
+ if (!acpi_dev_get_property(adev, "AcpDmicConnected", ACPI_TYPE_INTEGER, &obj) &&
+ obj->integer.value == 1)
+ platform_set_drvdata(pdev, &acp6x_card);
+ }
+
+ /* check for any DMI overrides */
+ dmi_id = dmi_first_match(yc_acp_quirk_table);
+ if (dmi_id)
+ platform_set_drvdata(pdev, dmi_id->driver_data);
+
+ card = platform_get_drvdata(pdev);
+ if (!card)
+ return -ENODEV;
+ dev_info(&pdev->dev, "Enabling ACP DMIC support via %s", dmi_id ? "DMI" : "ACPI");
+ acp6x_card.dev = &pdev->dev;
+
+ snd_soc_card_set_drvdata(card, machine);
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret) {
+ return dev_err_probe(&pdev->dev, ret,
+ "snd_soc_register_card(%s) failed\n",
+ card->name);
+ }
+ return 0;
+}
+
+static struct platform_driver acp6x_mach_driver = {
+ .driver = {
+ .name = "acp_yc_mach",
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = acp6x_probe,
+};
+
+module_platform_driver(acp6x_mach_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/yc/acp6x-pdm-dma.c b/sound/soc/amd/yc/acp6x-pdm-dma.c
new file mode 100644
index 0000000000..72c4591e45
--- /dev/null
+++ b/sound/soc/amd/yc/acp6x-pdm-dma.c
@@ -0,0 +1,455 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * AMD ALSA SoC Yellow Carp PDM Driver
+ *
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/bitfield.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/pm_runtime.h>
+
+#include "acp6x.h"
+
+#define DRV_NAME "acp_yc_pdm_dma"
+
+static int pdm_gain = 3;
+module_param(pdm_gain, int, 0644);
+MODULE_PARM_DESC(pdm_gain, "Gain control (0-3)");
+
+static const struct snd_pcm_hardware acp6x_pdm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
+static void acp6x_init_pdm_ring_buffer(u32 physical_addr, u32 buffer_size,
+ u32 watermark_size, void __iomem *acp_base)
+{
+ acp6x_writel(physical_addr, acp_base + ACP_WOV_RX_RINGBUFADDR);
+ acp6x_writel(buffer_size, acp_base + ACP_WOV_RX_RINGBUFSIZE);
+ acp6x_writel(watermark_size, acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
+ acp6x_writel(0x01, acp_base + ACPAXI2AXI_ATU_CTRL);
+}
+
+static void acp6x_enable_pdm_clock(void __iomem *acp_base)
+{
+ u32 pdm_clk_enable, pdm_ctrl;
+
+ pdm_clk_enable = ACP_PDM_CLK_FREQ_MASK;
+ pdm_ctrl = 0x00;
+
+ acp6x_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
+ pdm_ctrl = acp6x_readl(acp_base + ACP_WOV_MISC_CTRL);
+ pdm_ctrl &= ~ACP_WOV_GAIN_CONTROL;
+ pdm_ctrl |= FIELD_PREP(ACP_WOV_GAIN_CONTROL, clamp(pdm_gain, 0, 3));
+ acp6x_writel(pdm_ctrl, acp_base + ACP_WOV_MISC_CTRL);
+}
+
+static void acp6x_enable_pdm_interrupts(void __iomem *acp_base)
+{
+ u32 ext_int_ctrl;
+
+ ext_int_ctrl = acp6x_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_int_ctrl |= PDM_DMA_INTR_MASK;
+ acp6x_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static void acp6x_disable_pdm_interrupts(void __iomem *acp_base)
+{
+ u32 ext_int_ctrl;
+
+ ext_int_ctrl = acp6x_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_int_ctrl &= ~PDM_DMA_INTR_MASK;
+ acp6x_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static bool acp6x_check_pdm_dma_status(void __iomem *acp_base)
+{
+ bool pdm_dma_status;
+ u32 pdm_enable, pdm_dma_enable;
+
+ pdm_dma_status = false;
+ pdm_enable = acp6x_readl(acp_base + ACP_WOV_PDM_ENABLE);
+ pdm_dma_enable = acp6x_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_enable & ACP_PDM_ENABLE) && (pdm_dma_enable & ACP_PDM_DMA_EN_STATUS))
+ pdm_dma_status = true;
+
+ return pdm_dma_status;
+}
+
+static int acp6x_start_pdm_dma(void __iomem *acp_base)
+{
+ u32 pdm_enable;
+ u32 pdm_dma_enable;
+ int timeout;
+
+ pdm_enable = 0x01;
+ pdm_dma_enable = 0x01;
+
+ acp6x_enable_pdm_clock(acp_base);
+ acp6x_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
+ acp6x_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ timeout = 0;
+ while (++timeout < ACP_COUNTER) {
+ pdm_dma_enable = acp6x_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_dma_enable & 0x02) == ACP_PDM_DMA_EN_STATUS)
+ return 0;
+ udelay(DELAY_US);
+ }
+ return -ETIMEDOUT;
+}
+
+static int acp6x_stop_pdm_dma(void __iomem *acp_base)
+{
+ u32 pdm_enable, pdm_dma_enable;
+ int timeout;
+
+ pdm_enable = 0x00;
+ pdm_dma_enable = 0x00;
+
+ pdm_enable = acp6x_readl(acp_base + ACP_WOV_PDM_ENABLE);
+ pdm_dma_enable = acp6x_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if (pdm_dma_enable & 0x01) {
+ pdm_dma_enable = 0x02;
+ acp6x_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ timeout = 0;
+ while (++timeout < ACP_COUNTER) {
+ pdm_dma_enable = acp6x_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_dma_enable & 0x02) == 0x00)
+ break;
+ udelay(DELAY_US);
+ }
+ if (timeout == ACP_COUNTER)
+ return -ETIMEDOUT;
+ }
+ if (pdm_enable == ACP_PDM_ENABLE) {
+ pdm_enable = ACP_PDM_DISABLE;
+ acp6x_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
+ }
+ acp6x_writel(0x01, acp_base + ACP_WOV_PDM_FIFO_FLUSH);
+ return 0;
+}
+
+static void acp6x_config_dma(struct pdm_stream_instance *rtd, int direction)
+{
+ u16 page_idx;
+ u32 low, high, val;
+ dma_addr_t addr;
+
+ addr = rtd->dma_addr;
+ val = PDM_PTE_OFFSET;
+
+ /* Group Enable */
+ acp6x_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp6x_base +
+ ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
+ acp6x_writel(PAGE_SIZE_4K_ENABLE, rtd->acp6x_base +
+ ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
+ for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+
+ acp6x_writel(low, rtd->acp6x_base + ACP_SCRATCH_REG_0 + val);
+ high |= BIT(31);
+ acp6x_writel(high, rtd->acp6x_base + ACP_SCRATCH_REG_0 + val + 4);
+ val += 8;
+ addr += PAGE_SIZE;
+ }
+}
+
+static int acp6x_pdm_dma_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime;
+ struct pdm_dev_data *adata;
+ struct pdm_stream_instance *pdm_data;
+ int ret;
+
+ runtime = substream->runtime;
+ adata = dev_get_drvdata(component->dev);
+ pdm_data = kzalloc(sizeof(*pdm_data), GFP_KERNEL);
+ if (!pdm_data)
+ return -EINVAL;
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ runtime->hw = acp6x_pdm_hardware_capture;
+
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(pdm_data);
+ return ret;
+ }
+
+ acp6x_enable_pdm_interrupts(adata->acp6x_base);
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ adata->capture_stream = substream;
+
+ pdm_data->acp6x_base = adata->acp6x_base;
+ runtime->private_data = pdm_data;
+ return ret;
+}
+
+static int acp6x_pdm_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct pdm_stream_instance *rtd;
+ size_t size, period_bytes;
+
+ rtd = substream->runtime->private_data;
+ if (!rtd)
+ return -EINVAL;
+ size = params_buffer_bytes(params);
+ period_bytes = params_period_bytes(params);
+ rtd->dma_addr = substream->runtime->dma_addr;
+ rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+ acp6x_config_dma(rtd, substream->stream);
+ acp6x_init_pdm_ring_buffer(PDM_MEM_WINDOW_START, size,
+ period_bytes, rtd->acp6x_base);
+ return 0;
+}
+
+static u64 acp6x_pdm_get_byte_count(struct pdm_stream_instance *rtd,
+ int direction)
+{
+ union acp_pdm_dma_count byte_count;
+
+ byte_count.bcount.high =
+ acp6x_readl(rtd->acp6x_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);
+ byte_count.bcount.low =
+ acp6x_readl(rtd->acp6x_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);
+ return byte_count.bytescount;
+}
+
+static snd_pcm_uframes_t acp6x_pdm_dma_pointer(struct snd_soc_component *comp,
+ struct snd_pcm_substream *stream)
+{
+ struct pdm_stream_instance *rtd;
+ u32 pos, buffersize;
+ u64 bytescount;
+
+ rtd = stream->runtime->private_data;
+ buffersize = frames_to_bytes(stream->runtime,
+ stream->runtime->buffer_size);
+ bytescount = acp6x_pdm_get_byte_count(rtd, stream->stream);
+ if (bytescount > rtd->bytescount)
+ bytescount -= rtd->bytescount;
+ pos = do_div(bytescount, buffersize);
+ return bytes_to_frames(stream->runtime, pos);
+}
+
+static int acp6x_pdm_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct device *parent = component->dev->parent;
+
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ parent, MIN_BUFFER, MAX_BUFFER);
+ return 0;
+}
+
+static int acp6x_pdm_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
+
+ acp6x_disable_pdm_interrupts(adata->acp6x_base);
+ adata->capture_stream = NULL;
+ return 0;
+}
+
+static int acp6x_pdm_dai_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct pdm_stream_instance *rtd;
+ int ret;
+ bool pdm_status;
+ unsigned int ch_mask;
+
+ rtd = substream->runtime->private_data;
+ ret = 0;
+ switch (substream->runtime->channels) {
+ case TWO_CH:
+ ch_mask = 0x00;
+ break;
+ default:
+ return -EINVAL;
+ }
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ acp6x_writel(ch_mask, rtd->acp6x_base + ACP_WOV_PDM_NO_OF_CHANNELS);
+ acp6x_writel(PDM_DECIMATION_FACTOR, rtd->acp6x_base +
+ ACP_WOV_PDM_DECIMATION_FACTOR);
+ rtd->bytescount = acp6x_pdm_get_byte_count(rtd, substream->stream);
+ pdm_status = acp6x_check_pdm_dma_status(rtd->acp6x_base);
+ if (!pdm_status)
+ ret = acp6x_start_pdm_dma(rtd->acp6x_base);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ pdm_status = acp6x_check_pdm_dma_status(rtd->acp6x_base);
+ if (pdm_status)
+ ret = acp6x_stop_pdm_dma(rtd->acp6x_base);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static const struct snd_soc_dai_ops acp6x_pdm_dai_ops = {
+ .trigger = acp6x_pdm_dai_trigger,
+};
+
+static struct snd_soc_dai_driver acp6x_pdm_dai_driver = {
+ .capture = {
+ .rates = SNDRV_PCM_RATE_48000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ },
+ .ops = &acp6x_pdm_dai_ops,
+};
+
+static const struct snd_soc_component_driver acp6x_pdm_component = {
+ .name = DRV_NAME,
+ .open = acp6x_pdm_dma_open,
+ .close = acp6x_pdm_dma_close,
+ .hw_params = acp6x_pdm_dma_hw_params,
+ .pointer = acp6x_pdm_dma_pointer,
+ .pcm_construct = acp6x_pdm_dma_new,
+ .legacy_dai_naming = 1,
+};
+
+static int acp6x_pdm_audio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct pdm_dev_data *adata;
+ int status;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ adata->acp6x_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!adata->acp6x_base)
+ return -ENOMEM;
+
+ adata->capture_stream = NULL;
+
+ dev_set_drvdata(&pdev->dev, adata);
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp6x_pdm_component,
+ &acp6x_pdm_dai_driver, 1);
+ if (status) {
+ dev_err(&pdev->dev, "Fail to register acp pdm dai\n");
+
+ return -ENODEV;
+ }
+ pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ return 0;
+}
+
+static void acp6x_pdm_audio_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int __maybe_unused acp6x_pdm_resume(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+ struct snd_pcm_runtime *runtime;
+ struct pdm_stream_instance *rtd;
+ u32 period_bytes, buffer_len;
+
+ adata = dev_get_drvdata(dev);
+ if (adata->capture_stream && adata->capture_stream->runtime) {
+ runtime = adata->capture_stream->runtime;
+ rtd = runtime->private_data;
+ period_bytes = frames_to_bytes(runtime, runtime->period_size);
+ buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
+ acp6x_config_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
+ acp6x_init_pdm_ring_buffer(PDM_MEM_WINDOW_START, buffer_len,
+ period_bytes, adata->acp6x_base);
+ }
+ acp6x_enable_pdm_interrupts(adata->acp6x_base);
+ return 0;
+}
+
+static int __maybe_unused acp6x_pdm_suspend(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ acp6x_disable_pdm_interrupts(adata->acp6x_base);
+ return 0;
+}
+
+static int __maybe_unused acp6x_pdm_runtime_resume(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ acp6x_enable_pdm_interrupts(adata->acp6x_base);
+ return 0;
+}
+
+static const struct dev_pm_ops acp6x_pdm_pm_ops = {
+ SET_RUNTIME_PM_OPS(acp6x_pdm_suspend, acp6x_pdm_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(acp6x_pdm_suspend, acp6x_pdm_resume)
+};
+
+static struct platform_driver acp6x_pdm_dma_driver = {
+ .probe = acp6x_pdm_audio_probe,
+ .remove_new = acp6x_pdm_audio_remove,
+ .driver = {
+ .name = "acp_yc_pdm_dma",
+ .pm = &acp6x_pdm_pm_ops,
+ },
+};
+
+module_platform_driver(acp6x_pdm_dma_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP6x YC PDM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/yc/acp6x.h b/sound/soc/amd/yc/acp6x.h
new file mode 100644
index 0000000000..2de7d1edf0
--- /dev/null
+++ b/sound/soc/amd/yc/acp6x.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ALSA SoC PDM Driver
+ *
+ * Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+ */
+
+#include "acp6x_chip_offset_byte.h"
+
+#define ACP_DEVICE_ID 0x15E2
+#define ACP6x_PHY_BASE_ADDRESS 0x1240000
+#define ACP6x_REG_START 0x1240000
+#define ACP6x_REG_END 0x1250200
+#define ACP6x_DEVS 3
+#define ACP6x_PDM_MODE 1
+
+#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
+#define ACP_PGFSM_CNTL_POWER_ON_MASK 1
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0
+#define ACP_PGFSM_STATUS_MASK 3
+#define ACP_POWERED_ON 0
+#define ACP_POWER_ON_IN_PROGRESS 1
+#define ACP_POWERED_OFF 2
+#define ACP_POWER_OFF_IN_PROGRESS 3
+
+#define ACP_ERROR_MASK 0x20000000
+#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
+#define PDM_DMA_STAT 0x10
+
+#define PDM_DMA_INTR_MASK 0x10000
+#define ACP_ERROR_STAT 29
+#define PDM_DECIMATION_FACTOR 2
+#define ACP_PDM_CLK_FREQ_MASK 7
+#define ACP_WOV_GAIN_CONTROL GENMASK(4, 3)
+#define ACP_PDM_ENABLE 1
+#define ACP_PDM_DISABLE 0
+#define ACP_PDM_DMA_EN_STATUS 2
+#define TWO_CH 2
+#define DELAY_US 5
+#define ACP_COUNTER 20000
+
+#define ACP_SRAM_PTE_OFFSET 0x03800000
+#define PAGE_SIZE_4K_ENABLE 2
+#define PDM_PTE_OFFSET 0
+#define PDM_MEM_WINDOW_START 0x4000000
+
+#define CAPTURE_MIN_NUM_PERIODS 4
+#define CAPTURE_MAX_NUM_PERIODS 4
+#define CAPTURE_MAX_PERIOD_SIZE 8192
+#define CAPTURE_MIN_PERIOD_SIZE 4096
+
+#define MAX_BUFFER (CAPTURE_MAX_PERIOD_SIZE * CAPTURE_MAX_NUM_PERIODS)
+#define MIN_BUFFER MAX_BUFFER
+
+/* time in ms for runtime suspend delay */
+#define ACP_SUSPEND_DELAY_MS 2000
+
+enum acp_config {
+ ACP_CONFIG_0 = 0,
+ ACP_CONFIG_1,
+ ACP_CONFIG_2,
+ ACP_CONFIG_3,
+ ACP_CONFIG_4,
+ ACP_CONFIG_5,
+ ACP_CONFIG_6,
+ ACP_CONFIG_7,
+ ACP_CONFIG_8,
+ ACP_CONFIG_9,
+ ACP_CONFIG_10,
+ ACP_CONFIG_11,
+ ACP_CONFIG_12,
+ ACP_CONFIG_13,
+ ACP_CONFIG_14,
+ ACP_CONFIG_15,
+};
+
+struct pdm_dev_data {
+ u32 pdm_irq;
+ void __iomem *acp6x_base;
+ struct snd_pcm_substream *capture_stream;
+};
+
+struct pdm_stream_instance {
+ u16 num_pages;
+ u16 channels;
+ dma_addr_t dma_addr;
+ u64 bytescount;
+ void __iomem *acp6x_base;
+};
+
+union acp_pdm_dma_count {
+ struct {
+ u32 low;
+ u32 high;
+ } bcount;
+ u64 bytescount;
+};
+
+static inline u32 acp6x_readl(void __iomem *base_addr)
+{
+ return readl(base_addr - ACP6x_PHY_BASE_ADDRESS);
+}
+
+static inline void acp6x_writel(u32 val, void __iomem *base_addr)
+{
+ writel(val, base_addr - ACP6x_PHY_BASE_ADDRESS);
+}
+
+int snd_amd_acp_find_config(struct pci_dev *pci);
+
diff --git a/sound/soc/amd/yc/acp6x_chip_offset_byte.h b/sound/soc/amd/yc/acp6x_chip_offset_byte.h
new file mode 100644
index 0000000000..f05fb2dfb5
--- /dev/null
+++ b/sound/soc/amd/yc/acp6x_chip_offset_byte.h
@@ -0,0 +1,444 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ACP 6.x Register Documentation
+ *
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ */
+
+#ifndef _acp6x_OFFSET_HEADER
+#define _acp6x_OFFSET_HEADER
+
+/* Registers from ACP_DMA block */
+#define ACP_DMA_CNTL_0 0x1240000
+#define ACP_DMA_CNTL_1 0x1240004
+#define ACP_DMA_CNTL_2 0x1240008
+#define ACP_DMA_CNTL_3 0x124000C
+#define ACP_DMA_CNTL_4 0x1240010
+#define ACP_DMA_CNTL_5 0x1240014
+#define ACP_DMA_CNTL_6 0x1240018
+#define ACP_DMA_CNTL_7 0x124001C
+#define ACP_DMA_DSCR_STRT_IDX_0 0x1240020
+#define ACP_DMA_DSCR_STRT_IDX_1 0x1240024
+#define ACP_DMA_DSCR_STRT_IDX_2 0x1240028
+#define ACP_DMA_DSCR_STRT_IDX_3 0x124002C
+#define ACP_DMA_DSCR_STRT_IDX_4 0x1240030
+#define ACP_DMA_DSCR_STRT_IDX_5 0x1240034
+#define ACP_DMA_DSCR_STRT_IDX_6 0x1240038
+#define ACP_DMA_DSCR_STRT_IDX_7 0x124003C
+#define ACP_DMA_DSCR_CNT_0 0x1240040
+#define ACP_DMA_DSCR_CNT_1 0x1240044
+#define ACP_DMA_DSCR_CNT_2 0x1240048
+#define ACP_DMA_DSCR_CNT_3 0x124004C
+#define ACP_DMA_DSCR_CNT_4 0x1240050
+#define ACP_DMA_DSCR_CNT_5 0x1240054
+#define ACP_DMA_DSCR_CNT_6 0x1240058
+#define ACP_DMA_DSCR_CNT_7 0x124005C
+#define ACP_DMA_PRIO_0 0x1240060
+#define ACP_DMA_PRIO_1 0x1240064
+#define ACP_DMA_PRIO_2 0x1240068
+#define ACP_DMA_PRIO_3 0x124006C
+#define ACP_DMA_PRIO_4 0x1240070
+#define ACP_DMA_PRIO_5 0x1240074
+#define ACP_DMA_PRIO_6 0x1240078
+#define ACP_DMA_PRIO_7 0x124007C
+#define ACP_DMA_CUR_DSCR_0 0x1240080
+#define ACP_DMA_CUR_DSCR_1 0x1240084
+#define ACP_DMA_CUR_DSCR_2 0x1240088
+#define ACP_DMA_CUR_DSCR_3 0x124008C
+#define ACP_DMA_CUR_DSCR_4 0x1240090
+#define ACP_DMA_CUR_DSCR_5 0x1240094
+#define ACP_DMA_CUR_DSCR_6 0x1240098
+#define ACP_DMA_CUR_DSCR_7 0x124009C
+#define ACP_DMA_CUR_TRANS_CNT_0 0x12400A0
+#define ACP_DMA_CUR_TRANS_CNT_1 0x12400A4
+#define ACP_DMA_CUR_TRANS_CNT_2 0x12400A8
+#define ACP_DMA_CUR_TRANS_CNT_3 0x12400AC
+#define ACP_DMA_CUR_TRANS_CNT_4 0x12400B0
+#define ACP_DMA_CUR_TRANS_CNT_5 0x12400B4
+#define ACP_DMA_CUR_TRANS_CNT_6 0x12400B8
+#define ACP_DMA_CUR_TRANS_CNT_7 0x12400BC
+#define ACP_DMA_ERR_STS_0 0x12400C0
+#define ACP_DMA_ERR_STS_1 0x12400C4
+#define ACP_DMA_ERR_STS_2 0x12400C8
+#define ACP_DMA_ERR_STS_3 0x12400CC
+#define ACP_DMA_ERR_STS_4 0x12400D0
+#define ACP_DMA_ERR_STS_5 0x12400D4
+#define ACP_DMA_ERR_STS_6 0x12400D8
+#define ACP_DMA_ERR_STS_7 0x12400DC
+#define ACP_DMA_DESC_BASE_ADDR 0x12400E0
+#define ACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4
+#define ACP_DMA_CH_STS 0x12400E8
+#define ACP_DMA_CH_GROUP 0x12400EC
+#define ACP_DMA_CH_RST_STS 0x12400F0
+
+/* Registers from ACP_AXI2AXIATU block */
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0x1240C00
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_1 0x1240C04
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2 0x1240C08
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_2 0x1240C0C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_3 0x1240C10
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_3 0x1240C14
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_4 0x1240C18
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_4 0x1240C1C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0x1240C20
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0x1240C24
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_6 0x1240C28
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_6 0x1240C2C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_7 0x1240C30
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_7 0x1240C34
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_8 0x1240C38
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_8 0x1240C3C
+#define ACPAXI2AXI_ATU_CTRL 0x1240C40
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_9 0x1240C44
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_9 0x1240C48
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_10 0x1240C4C
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_10 0x1240C50
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_11 0x1240C54
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_11 0x1240C58
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_12 0x1240C5C
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_12 0x1240C60
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_13 0x1240C64
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_13 0x1240C68
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_14 0x1240C6C
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_14 0x1240C70
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_15 0x1240C74
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_15 0x1240C78
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_16 0x1240C7C
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_16 0x1240C80
+
+/* Registers from ACP_CLKRST block */
+#define ACP_SOFT_RESET 0x1241000
+#define ACP_CONTROL 0x1241004
+#define ACP_STATUS 0x1241008
+#define ACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
+#define ACP_ZSC_DSP_CTRL 0x1241014
+#define ACP_ZSC_STS 0x1241018
+#define ACP_PGFSM_CONTROL 0x1241024
+#define ACP_PGFSM_STATUS 0x1241028
+#define ACP_CLKMUX_SEL 0x124102C
+
+/* Registers from ACP_AON block */
+#define ACP_PME_EN 0x1241400
+#define ACP_DEVICE_STATE 0x1241404
+#define AZ_DEVICE_STATE 0x1241408
+#define ACP_PIN_CONFIG 0x1241440
+#define ACP_PAD_PULLUP_CTRL 0x1241444
+#define ACP_PAD_PULLDOWN_CTRL 0x1241448
+#define ACP_PAD_DRIVE_STRENGTH_CTRL 0x124144C
+#define ACP_PAD_SCHMEN_CTRL 0x1241450
+#define ACP_SW_PAD_KEEPER_EN 0x1241454
+#define ACP_SW_WAKE_EN 0x1241458
+#define ACP_I2S_WAKE_EN 0x124145C
+#define ACP_SW1_WAKE_EN 0x1241460
+
+/* Registers from ACP_P1_MISC block */
+#define ACP_EXTERNAL_INTR_ENB 0x1241A00
+#define ACP_EXTERNAL_INTR_CNTL 0x1241A04
+#define ACP_EXTERNAL_INTR_CNTL1 0x1241A08
+#define ACP_EXTERNAL_INTR_STAT 0x1241A0C
+#define ACP_EXTERNAL_INTR_STAT1 0x1241A10
+#define ACP_ERROR_STATUS 0x1241A4C
+#define ACP_P1_SW_I2S_ERROR_REASON 0x1241A50
+#define ACP_P1_SW_POS_TRACK_I2S_TX_CTRL 0x1241A6C
+#define ACP_P1_SW_I2S_TX_DMA_POS 0x1241A70
+#define ACP_P1_SW_POS_TRACK_I2S_RX_CTRL 0x1241A74
+#define ACP_P1_SW_I2S_RX_DMA_POS 0x1241A78
+#define ACP_P1_DMIC_I2S_GPIO_INTR_CTRL 0x1241A7C
+#define ACP_P1_DMIC_I2S_GPIO_INTR_STATUS 0x1241A80
+#define ACP_SCRATCH_REG_BASE_ADDR 0x1241A84
+#define ACP_P1_SW_POS_TRACK_BT_TX_CTRL 0x1241A88
+#define ACP_P1_SW_BT_TX_DMA_POS 0x1241A8C
+#define ACP_P1_SW_POS_TRACK_HS_TX_CTRL 0x1241A90
+#define ACP_P1_SW_HS_TX_DMA_POS 0x1241A94
+#define ACP_P1_SW_POS_TRACK_BT_RX_CTRL 0x1241A98
+#define ACP_P1_SW_BT_RX_DMA_POS 0x1241A9C
+#define ACP_P1_SW_POS_TRACK_HS_RX_CTRL 0x1241AA0
+#define ACP_P1_SW_HS_RX_DMA_POS 0x1241AA4
+
+/* Registers from ACP_AUDIO_BUFFERS block */
+#define ACP_I2S_RX_RINGBUFADDR 0x1242000
+#define ACP_I2S_RX_RINGBUFSIZE 0x1242004
+#define ACP_I2S_RX_LINKPOSITIONCNTR 0x1242008
+#define ACP_I2S_RX_FIFOADDR 0x124200C
+#define ACP_I2S_RX_FIFOSIZE 0x1242010
+#define ACP_I2S_RX_DMA_SIZE 0x1242014
+#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1242018
+#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x124201C
+#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x1242020
+#define ACP_I2S_TX_RINGBUFADDR 0x1242024
+#define ACP_I2S_TX_RINGBUFSIZE 0x1242028
+#define ACP_I2S_TX_LINKPOSITIONCNTR 0x124202C
+#define ACP_I2S_TX_FIFOADDR 0x1242030
+#define ACP_I2S_TX_FIFOSIZE 0x1242034
+#define ACP_I2S_TX_DMA_SIZE 0x1242038
+#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x124203C
+#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1242040
+#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x1242044
+#define ACP_BT_RX_RINGBUFADDR 0x1242048
+#define ACP_BT_RX_RINGBUFSIZE 0x124204C
+#define ACP_BT_RX_LINKPOSITIONCNTR 0x1242050
+#define ACP_BT_RX_FIFOADDR 0x1242054
+#define ACP_BT_RX_FIFOSIZE 0x1242058
+#define ACP_BT_RX_DMA_SIZE 0x124205C
+#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1242060
+#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x1242064
+#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068
+#define ACP_BT_TX_RINGBUFADDR 0x124206C
+#define ACP_BT_TX_RINGBUFSIZE 0x1242070
+#define ACP_BT_TX_LINKPOSITIONCNTR 0x1242074
+#define ACP_BT_TX_FIFOADDR 0x1242078
+#define ACP_BT_TX_FIFOSIZE 0x124207C
+#define ACP_BT_TX_DMA_SIZE 0x1242080
+#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1242084
+#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x1242088
+#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C
+#define ACP_HS_RX_RINGBUFADDR 0x1242090
+#define ACP_HS_RX_RINGBUFSIZE 0x1242094
+#define ACP_HS_RX_LINKPOSITIONCNTR 0x1242098
+#define ACP_HS_RX_FIFOADDR 0x124209C
+#define ACP_HS_RX_FIFOSIZE 0x12420A0
+#define ACP_HS_RX_DMA_SIZE 0x12420A4
+#define ACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x12420A8
+#define ACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x12420AC
+#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0
+#define ACP_HS_TX_RINGBUFADDR 0x12420B4
+#define ACP_HS_TX_RINGBUFSIZE 0x12420B8
+#define ACP_HS_TX_LINKPOSITIONCNTR 0x12420BC
+#define ACP_HS_TX_FIFOADDR 0x12420C0
+#define ACP_HS_TX_FIFOSIZE 0x12420C4
+#define ACP_HS_TX_DMA_SIZE 0x12420C8
+#define ACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x12420CC
+#define ACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x12420D0
+#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4
+
+/* Registers from ACP_I2S_TDM block */
+#define ACP_I2STDM_IER 0x1242400
+#define ACP_I2STDM_IRER 0x1242404
+#define ACP_I2STDM_RXFRMT 0x1242408
+#define ACP_I2STDM_ITER 0x124240C
+#define ACP_I2STDM_TXFRMT 0x1242410
+#define ACP_I2STDM0_MSTRCLKGEN 0x1242414
+#define ACP_I2STDM1_MSTRCLKGEN 0x1242418
+#define ACP_I2STDM2_MSTRCLKGEN 0x124241C
+#define ACP_I2STDM_REFCLKGEN 0x1242420
+
+/* Registers from ACP_BT_TDM block */
+#define ACP_BTTDM_IER 0x1242800
+#define ACP_BTTDM_IRER 0x1242804
+#define ACP_BTTDM_RXFRMT 0x1242808
+#define ACP_BTTDM_ITER 0x124280C
+#define ACP_BTTDM_TXFRMT 0x1242810
+#define ACP_HSTDM_IER 0x1242814
+#define ACP_HSTDM_IRER 0x1242818
+#define ACP_HSTDM_RXFRMT 0x124281C
+#define ACP_HSTDM_ITER 0x1242820
+#define ACP_HSTDM_TXFRMT 0x1242824
+
+/* Registers from ACP_WOV block */
+#define ACP_WOV_PDM_ENABLE 0x1242C04
+#define ACP_WOV_PDM_DMA_ENABLE 0x1242C08
+#define ACP_WOV_RX_RINGBUFADDR 0x1242C0C
+#define ACP_WOV_RX_RINGBUFSIZE 0x1242C10
+#define ACP_WOV_RX_LINKPOSITIONCNTR 0x1242C14
+#define ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH 0x1242C18
+#define ACP_WOV_RX_LINEARPOSITIONCNTR_LOW 0x1242C1C
+#define ACP_WOV_RX_INTR_WATERMARK_SIZE 0x1242C20
+#define ACP_WOV_PDM_FIFO_FLUSH 0x1242C24
+#define ACP_WOV_PDM_NO_OF_CHANNELS 0x1242C28
+#define ACP_WOV_PDM_DECIMATION_FACTOR 0x1242C2C
+#define ACP_WOV_PDM_VAD_CTRL 0x1242C30
+#define ACP_WOV_WAKE 0x1242C54
+#define ACP_WOV_BUFFER_STATUS 0x1242C58
+#define ACP_WOV_MISC_CTRL 0x1242C5C
+#define ACP_WOV_CLK_CTRL 0x1242C60
+#define ACP_PDM_VAD_DYNAMIC_CLK_GATING_EN 0x1242C64
+#define ACP_WOV_ERROR_STATUS_REGISTER 0x1242C68
+#define ACP_PDM_CLKDIV 0x1242C6C
+
+/* Registers from ACP_P1_AUDIO_BUFFERS block */
+#define ACP_P1_I2S_RX_RINGBUFADDR 0x1243A00
+#define ACP_P1_I2S_RX_RINGBUFSIZE 0x1243A04
+#define ACP_P1_I2S_RX_LINKPOSITIONCNTR 0x1243A08
+#define ACP_P1_I2S_RX_FIFOADDR 0x1243A0C
+#define ACP_P1_I2S_RX_FIFOSIZE 0x1243A10
+#define ACP_P1_I2S_RX_DMA_SIZE 0x1243A14
+#define ACP_P1_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1243A18
+#define ACP_P1_I2S_RX_LINEARPOSITIONCNTR_LOW 0x1243A1C
+#define ACP_P1_I2S_RX_INTR_WATERMARK_SIZE 0x1243A20
+#define ACP_P1_I2S_TX_RINGBUFADDR 0x1243A24
+#define ACP_P1_I2S_TX_RINGBUFSIZE 0x1243A28
+#define ACP_P1_I2S_TX_LINKPOSITIONCNTR 0x1243A2C
+#define ACP_P1_I2S_TX_FIFOADDR 0x1243A30
+#define ACP_P1_I2S_TX_FIFOSIZE 0x1243A34
+#define ACP_P1_I2S_TX_DMA_SIZE 0x1243A38
+#define ACP_P1_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x1243A3C
+#define ACP_P1_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1243A40
+#define ACP_P1_I2S_TX_INTR_WATERMARK_SIZE 0x1243A44
+#define ACP_P1_BT_RX_RINGBUFADDR 0x1243A48
+#define ACP_P1_BT_RX_RINGBUFSIZE 0x1243A4C
+#define ACP_P1_BT_RX_LINKPOSITIONCNTR 0x1243A50
+#define ACP_P1_BT_RX_FIFOADDR 0x1243A54
+#define ACP_P1_BT_RX_FIFOSIZE 0x1243A58
+#define ACP_P1_BT_RX_DMA_SIZE 0x1243A5C
+#define ACP_P1_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1243A60
+#define ACP_P1_BT_RX_LINEARPOSITIONCNTR_LOW 0x1243A64
+#define ACP_P1_BT_RX_INTR_WATERMARK_SIZE 0x1243A68
+#define ACP_P1_BT_TX_RINGBUFADDR 0x1243A6C
+#define ACP_P1_BT_TX_RINGBUFSIZE 0x1243A70
+#define ACP_P1_BT_TX_LINKPOSITIONCNTR 0x1243A74
+#define ACP_P1_BT_TX_FIFOADDR 0x1243A78
+#define ACP_P1_BT_TX_FIFOSIZE 0x1243A7C
+#define ACP_P1_BT_TX_DMA_SIZE 0x1243A80
+#define ACP_P1_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1243A84
+#define ACP_P1_BT_TX_LINEARPOSITIONCNTR_LOW 0x1243A88
+#define ACP_P1_BT_TX_INTR_WATERMARK_SIZE 0x1243A8C
+#define ACP_P1_HS_RX_RINGBUFADDR 0x1243A90
+#define ACP_P1_HS_RX_RINGBUFSIZE 0x1243A94
+#define ACP_P1_HS_RX_LINKPOSITIONCNTR 0x1243A98
+#define ACP_P1_HS_RX_FIFOADDR 0x1243A9C
+#define ACP_P1_HS_RX_FIFOSIZE 0x1243AA0
+#define ACP_P1_HS_RX_DMA_SIZE 0x1243AA4
+#define ACP_P1_HS_RX_LINEARPOSITIONCNTR_HIGH 0x1243AA8
+#define ACP_P1_HS_RX_LINEARPOSITIONCNTR_LOW 0x1243AAC
+#define ACP_P1_HS_RX_INTR_WATERMARK_SIZE 0x1243AB0
+#define ACP_P1_HS_TX_RINGBUFADDR 0x1243AB4
+#define ACP_P1_HS_TX_RINGBUFSIZE 0x1243AB8
+#define ACP_P1_HS_TX_LINKPOSITIONCNTR 0x1243ABC
+#define ACP_P1_HS_TX_FIFOADDR 0x1243AC0
+#define ACP_P1_HS_TX_FIFOSIZE 0x1243AC4
+#define ACP_P1_HS_TX_DMA_SIZE 0x1243AC8
+#define ACP_P1_HS_TX_LINEARPOSITIONCNTR_HIGH 0x1243ACC
+#define ACP_P1_HS_TX_LINEARPOSITIONCNTR_LOW 0x1243AD0
+#define ACP_P1_HS_TX_INTR_WATERMARK_SIZE 0x1243AD4
+
+/* Registers from ACP_SCRATCH block */
+#define ACP_SCRATCH_REG_0 0x1250000
+#define ACP_SCRATCH_REG_1 0x1250004
+#define ACP_SCRATCH_REG_2 0x1250008
+#define ACP_SCRATCH_REG_3 0x125000C
+#define ACP_SCRATCH_REG_4 0x1250010
+#define ACP_SCRATCH_REG_5 0x1250014
+#define ACP_SCRATCH_REG_6 0x1250018
+#define ACP_SCRATCH_REG_7 0x125001C
+#define ACP_SCRATCH_REG_8 0x1250020
+#define ACP_SCRATCH_REG_9 0x1250024
+#define ACP_SCRATCH_REG_10 0x1250028
+#define ACP_SCRATCH_REG_11 0x125002C
+#define ACP_SCRATCH_REG_12 0x1250030
+#define ACP_SCRATCH_REG_13 0x1250034
+#define ACP_SCRATCH_REG_14 0x1250038
+#define ACP_SCRATCH_REG_15 0x125003C
+#define ACP_SCRATCH_REG_16 0x1250040
+#define ACP_SCRATCH_REG_17 0x1250044
+#define ACP_SCRATCH_REG_18 0x1250048
+#define ACP_SCRATCH_REG_19 0x125004C
+#define ACP_SCRATCH_REG_20 0x1250050
+#define ACP_SCRATCH_REG_21 0x1250054
+#define ACP_SCRATCH_REG_22 0x1250058
+#define ACP_SCRATCH_REG_23 0x125005C
+#define ACP_SCRATCH_REG_24 0x1250060
+#define ACP_SCRATCH_REG_25 0x1250064
+#define ACP_SCRATCH_REG_26 0x1250068
+#define ACP_SCRATCH_REG_27 0x125006C
+#define ACP_SCRATCH_REG_28 0x1250070
+#define ACP_SCRATCH_REG_29 0x1250074
+#define ACP_SCRATCH_REG_30 0x1250078
+#define ACP_SCRATCH_REG_31 0x125007C
+#define ACP_SCRATCH_REG_32 0x1250080
+#define ACP_SCRATCH_REG_33 0x1250084
+#define ACP_SCRATCH_REG_34 0x1250088
+#define ACP_SCRATCH_REG_35 0x125008C
+#define ACP_SCRATCH_REG_36 0x1250090
+#define ACP_SCRATCH_REG_37 0x1250094
+#define ACP_SCRATCH_REG_38 0x1250098
+#define ACP_SCRATCH_REG_39 0x125009C
+#define ACP_SCRATCH_REG_40 0x12500A0
+#define ACP_SCRATCH_REG_41 0x12500A4
+#define ACP_SCRATCH_REG_42 0x12500A8
+#define ACP_SCRATCH_REG_43 0x12500AC
+#define ACP_SCRATCH_REG_44 0x12500B0
+#define ACP_SCRATCH_REG_45 0x12500B4
+#define ACP_SCRATCH_REG_46 0x12500B8
+#define ACP_SCRATCH_REG_47 0x12500BC
+#define ACP_SCRATCH_REG_48 0x12500C0
+#define ACP_SCRATCH_REG_49 0x12500C4
+#define ACP_SCRATCH_REG_50 0x12500C8
+#define ACP_SCRATCH_REG_51 0x12500CC
+#define ACP_SCRATCH_REG_52 0x12500D0
+#define ACP_SCRATCH_REG_53 0x12500D4
+#define ACP_SCRATCH_REG_54 0x12500D8
+#define ACP_SCRATCH_REG_55 0x12500DC
+#define ACP_SCRATCH_REG_56 0x12500E0
+#define ACP_SCRATCH_REG_57 0x12500E4
+#define ACP_SCRATCH_REG_58 0x12500E8
+#define ACP_SCRATCH_REG_59 0x12500EC
+#define ACP_SCRATCH_REG_60 0x12500F0
+#define ACP_SCRATCH_REG_61 0x12500F4
+#define ACP_SCRATCH_REG_62 0x12500F8
+#define ACP_SCRATCH_REG_63 0x12500FC
+#define ACP_SCRATCH_REG_64 0x1250100
+#define ACP_SCRATCH_REG_65 0x1250104
+#define ACP_SCRATCH_REG_66 0x1250108
+#define ACP_SCRATCH_REG_67 0x125010C
+#define ACP_SCRATCH_REG_68 0x1250110
+#define ACP_SCRATCH_REG_69 0x1250114
+#define ACP_SCRATCH_REG_70 0x1250118
+#define ACP_SCRATCH_REG_71 0x125011C
+#define ACP_SCRATCH_REG_72 0x1250120
+#define ACP_SCRATCH_REG_73 0x1250124
+#define ACP_SCRATCH_REG_74 0x1250128
+#define ACP_SCRATCH_REG_75 0x125012C
+#define ACP_SCRATCH_REG_76 0x1250130
+#define ACP_SCRATCH_REG_77 0x1250134
+#define ACP_SCRATCH_REG_78 0x1250138
+#define ACP_SCRATCH_REG_79 0x125013C
+#define ACP_SCRATCH_REG_80 0x1250140
+#define ACP_SCRATCH_REG_81 0x1250144
+#define ACP_SCRATCH_REG_82 0x1250148
+#define ACP_SCRATCH_REG_83 0x125014C
+#define ACP_SCRATCH_REG_84 0x1250150
+#define ACP_SCRATCH_REG_85 0x1250154
+#define ACP_SCRATCH_REG_86 0x1250158
+#define ACP_SCRATCH_REG_87 0x125015C
+#define ACP_SCRATCH_REG_88 0x1250160
+#define ACP_SCRATCH_REG_89 0x1250164
+#define ACP_SCRATCH_REG_90 0x1250168
+#define ACP_SCRATCH_REG_91 0x125016C
+#define ACP_SCRATCH_REG_92 0x1250170
+#define ACP_SCRATCH_REG_93 0x1250174
+#define ACP_SCRATCH_REG_94 0x1250178
+#define ACP_SCRATCH_REG_95 0x125017C
+#define ACP_SCRATCH_REG_96 0x1250180
+#define ACP_SCRATCH_REG_97 0x1250184
+#define ACP_SCRATCH_REG_98 0x1250188
+#define ACP_SCRATCH_REG_99 0x125018C
+#define ACP_SCRATCH_REG_100 0x1250190
+#define ACP_SCRATCH_REG_101 0x1250194
+#define ACP_SCRATCH_REG_102 0x1250198
+#define ACP_SCRATCH_REG_103 0x125019C
+#define ACP_SCRATCH_REG_104 0x12501A0
+#define ACP_SCRATCH_REG_105 0x12501A4
+#define ACP_SCRATCH_REG_106 0x12501A8
+#define ACP_SCRATCH_REG_107 0x12501AC
+#define ACP_SCRATCH_REG_108 0x12501B0
+#define ACP_SCRATCH_REG_109 0x12501B4
+#define ACP_SCRATCH_REG_110 0x12501B8
+#define ACP_SCRATCH_REG_111 0x12501BC
+#define ACP_SCRATCH_REG_112 0x12501C0
+#define ACP_SCRATCH_REG_113 0x12501C4
+#define ACP_SCRATCH_REG_114 0x12501C8
+#define ACP_SCRATCH_REG_115 0x12501CC
+#define ACP_SCRATCH_REG_116 0x12501D0
+#define ACP_SCRATCH_REG_117 0x12501D4
+#define ACP_SCRATCH_REG_118 0x12501D8
+#define ACP_SCRATCH_REG_119 0x12501DC
+#define ACP_SCRATCH_REG_120 0x12501E0
+#define ACP_SCRATCH_REG_121 0x12501E4
+#define ACP_SCRATCH_REG_122 0x12501E8
+#define ACP_SCRATCH_REG_123 0x12501EC
+#define ACP_SCRATCH_REG_124 0x12501F0
+#define ACP_SCRATCH_REG_125 0x12501F4
+#define ACP_SCRATCH_REG_126 0x12501F8
+#define ACP_SCRATCH_REG_127 0x12501FC
+#define ACP_SCRATCH_REG_128 0x1250200
+#endif
diff --git a/sound/soc/amd/yc/pci-acp6x.c b/sound/soc/amd/yc/pci-acp6x.c
new file mode 100644
index 0000000000..7af6a349b1
--- /dev/null
+++ b/sound/soc/amd/yc/pci-acp6x.c
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * AMD Yellow Carp ACP PCI Driver
+ *
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <sound/pcm_params.h>
+#include <linux/pm_runtime.h>
+
+#include "acp6x.h"
+
+struct acp6x_dev_data {
+ void __iomem *acp6x_base;
+ struct resource *res;
+ bool acp6x_audio_mode;
+ struct platform_device *pdev[ACP6x_DEVS];
+};
+
+static int acp6x_power_on(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ val = acp6x_readl(acp_base + ACP_PGFSM_STATUS);
+
+ if (!val)
+ return val;
+
+ if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS)
+ acp6x_writel(ACP_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = acp6x_readl(acp_base + ACP_PGFSM_STATUS);
+ if (!val)
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int acp6x_reset(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ acp6x_writel(1, acp_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = acp6x_readl(acp_base + ACP_SOFT_RESET);
+ if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
+ break;
+ cpu_relax();
+ }
+ acp6x_writel(0, acp_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = acp6x_readl(acp_base + ACP_SOFT_RESET);
+ if (!val)
+ return 0;
+ cpu_relax();
+ }
+ return -ETIMEDOUT;
+}
+
+static void acp6x_enable_interrupts(void __iomem *acp_base)
+{
+ acp6x_writel(0x01, acp_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static void acp6x_disable_interrupts(void __iomem *acp_base)
+{
+ acp6x_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base +
+ ACP_EXTERNAL_INTR_STAT);
+ acp6x_writel(0x00, acp_base + ACP_EXTERNAL_INTR_CNTL);
+ acp6x_writel(0x00, acp_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static int acp6x_init(void __iomem *acp_base)
+{
+ int ret;
+
+ /* power on */
+ ret = acp6x_power_on(acp_base);
+ if (ret) {
+ pr_err("ACP power on failed\n");
+ return ret;
+ }
+ acp6x_writel(0x01, acp_base + ACP_CONTROL);
+ /* Reset */
+ ret = acp6x_reset(acp_base);
+ if (ret) {
+ pr_err("ACP reset failed\n");
+ return ret;
+ }
+ acp6x_writel(0x03, acp_base + ACP_CLKMUX_SEL);
+ acp6x_enable_interrupts(acp_base);
+ return 0;
+}
+
+static int acp6x_deinit(void __iomem *acp_base)
+{
+ int ret;
+
+ acp6x_disable_interrupts(acp_base);
+ /* Reset */
+ ret = acp6x_reset(acp_base);
+ if (ret) {
+ pr_err("ACP reset failed\n");
+ return ret;
+ }
+ acp6x_writel(0x00, acp_base + ACP_CLKMUX_SEL);
+ acp6x_writel(0x00, acp_base + ACP_CONTROL);
+ return 0;
+}
+
+static irqreturn_t acp6x_irq_handler(int irq, void *dev_id)
+{
+ struct acp6x_dev_data *adata;
+ struct pdm_dev_data *yc_pdm_data;
+ u32 val;
+
+ adata = dev_id;
+ if (!adata)
+ return IRQ_NONE;
+
+ val = acp6x_readl(adata->acp6x_base + ACP_EXTERNAL_INTR_STAT);
+ if (val & BIT(PDM_DMA_STAT)) {
+ yc_pdm_data = dev_get_drvdata(&adata->pdev[0]->dev);
+ acp6x_writel(BIT(PDM_DMA_STAT), adata->acp6x_base + ACP_EXTERNAL_INTR_STAT);
+ if (yc_pdm_data->capture_stream)
+ snd_pcm_period_elapsed(yc_pdm_data->capture_stream);
+ return IRQ_HANDLED;
+ }
+ return IRQ_NONE;
+}
+
+static int snd_acp6x_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ struct acp6x_dev_data *adata;
+ struct platform_device_info pdevinfo[ACP6x_DEVS];
+ int index = 0;
+ int val = 0x00;
+ u32 addr;
+ unsigned int irqflags, flag;
+ int ret;
+
+ irqflags = IRQF_SHARED;
+
+ /* Return if acp config flag is defined */
+ flag = snd_amd_acp_find_config(pci);
+ if (flag)
+ return -ENODEV;
+
+ /* Yellow Carp device check */
+ switch (pci->revision) {
+ case 0x60:
+ case 0x6f:
+ break;
+ default:
+ dev_dbg(&pci->dev, "acp6x pci device not found\n");
+ return -ENODEV;
+ }
+ if (pci_enable_device(pci)) {
+ dev_err(&pci->dev, "pci_enable_device failed\n");
+ return -ENODEV;
+ }
+
+ ret = pci_request_regions(pci, "AMD ACP3x audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+ }
+
+ adata = devm_kzalloc(&pci->dev, sizeof(struct acp6x_dev_data),
+ GFP_KERNEL);
+ if (!adata) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+
+ addr = pci_resource_start(pci, 0);
+ adata->acp6x_base = devm_ioremap(&pci->dev, addr,
+ pci_resource_len(pci, 0));
+ if (!adata->acp6x_base) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+ pci_set_master(pci);
+ pci_set_drvdata(pci, adata);
+ ret = acp6x_init(adata->acp6x_base);
+ if (ret)
+ goto release_regions;
+ val = acp6x_readl(adata->acp6x_base + ACP_PIN_CONFIG);
+ switch (val) {
+ case ACP_CONFIG_0:
+ case ACP_CONFIG_1:
+ case ACP_CONFIG_2:
+ case ACP_CONFIG_3:
+ case ACP_CONFIG_9:
+ case ACP_CONFIG_15:
+ dev_info(&pci->dev, "Audio Mode %d\n", val);
+ break;
+ default:
+ adata->res = devm_kzalloc(&pci->dev,
+ sizeof(struct resource),
+ GFP_KERNEL);
+ if (!adata->res) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+
+ adata->res->name = "acp_iomem";
+ adata->res->flags = IORESOURCE_MEM;
+ adata->res->start = addr;
+ adata->res->end = addr + (ACP6x_REG_END - ACP6x_REG_START);
+
+ adata->acp6x_audio_mode = ACP6x_PDM_MODE;
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ pdevinfo[0].name = "acp_yc_pdm_dma";
+ pdevinfo[0].id = 0;
+ pdevinfo[0].parent = &pci->dev;
+ pdevinfo[0].num_res = 1;
+ pdevinfo[0].res = adata->res;
+
+ pdevinfo[1].name = "dmic-codec";
+ pdevinfo[1].id = 0;
+ pdevinfo[1].parent = &pci->dev;
+
+ pdevinfo[2].name = "acp_yc_mach";
+ pdevinfo[2].id = 0;
+ pdevinfo[2].parent = &pci->dev;
+
+ for (index = 0; index < ACP6x_DEVS; index++) {
+ adata->pdev[index] =
+ platform_device_register_full(&pdevinfo[index]);
+ if (IS_ERR(adata->pdev[index])) {
+ dev_err(&pci->dev, "cannot register %s device\n",
+ pdevinfo[index].name);
+ ret = PTR_ERR(adata->pdev[index]);
+ goto unregister_devs;
+ }
+ }
+ break;
+ }
+ ret = devm_request_irq(&pci->dev, pci->irq, acp6x_irq_handler,
+ irqflags, "ACP_PCI_IRQ", adata);
+ if (ret) {
+ dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
+ goto unregister_devs;
+ }
+ pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_put_noidle(&pci->dev);
+ pm_runtime_allow(&pci->dev);
+
+ return 0;
+unregister_devs:
+ for (--index; index >= 0; index--)
+ platform_device_unregister(adata->pdev[index]);
+de_init:
+ if (acp6x_deinit(adata->acp6x_base))
+ dev_err(&pci->dev, "ACP de-init failed\n");
+release_regions:
+ pci_release_regions(pci);
+disable_pci:
+ pci_disable_device(pci);
+
+ return ret;
+}
+
+static int __maybe_unused snd_acp6x_suspend(struct device *dev)
+{
+ struct acp6x_dev_data *adata;
+ int ret;
+
+ adata = dev_get_drvdata(dev);
+ ret = acp6x_deinit(adata->acp6x_base);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+ return ret;
+}
+
+static int __maybe_unused snd_acp6x_resume(struct device *dev)
+{
+ struct acp6x_dev_data *adata;
+ int ret;
+
+ adata = dev_get_drvdata(dev);
+ ret = acp6x_init(adata->acp6x_base);
+ if (ret)
+ dev_err(dev, "ACP init failed\n");
+ return ret;
+}
+
+static const struct dev_pm_ops acp6x_pm = {
+ SET_RUNTIME_PM_OPS(snd_acp6x_suspend, snd_acp6x_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(snd_acp6x_suspend, snd_acp6x_resume)
+};
+
+static void snd_acp6x_remove(struct pci_dev *pci)
+{
+ struct acp6x_dev_data *adata;
+ int ret, index;
+
+ adata = pci_get_drvdata(pci);
+ if (adata->acp6x_audio_mode == ACP6x_PDM_MODE) {
+ for (index = 0; index < ACP6x_DEVS; index++)
+ platform_device_unregister(adata->pdev[index]);
+ }
+ ret = acp6x_deinit(adata->acp6x_base);
+ if (ret)
+ dev_err(&pci->dev, "ACP de-init failed\n");
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_get_noresume(&pci->dev);
+ pci_release_regions(pci);
+ pci_disable_device(pci);
+}
+
+static const struct pci_device_id snd_acp6x_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
+ .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
+ .class_mask = 0xffffff },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_acp6x_ids);
+
+static struct pci_driver yc_acp6x_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = snd_acp6x_ids,
+ .probe = snd_acp6x_probe,
+ .remove = snd_acp6x_remove,
+ .driver = {
+ .pm = &acp6x_pm,
+ }
+};
+
+module_pci_driver(yc_acp6x_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP Yellow Carp PCI driver");
+MODULE_LICENSE("GPL v2");