diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0581-amd-i2s-i2s-audio-driver-for-raven-family.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/0581-amd-i2s-i2s-audio-driver-for-raven-family.patch | 2045 |
1 files changed, 2045 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0581-amd-i2s-i2s-audio-driver-for-raven-family.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0581-amd-i2s-i2s-audio-driver-for-raven-family.patch new file mode 100644 index 00000000..8ae6f1a1 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0581-amd-i2s-i2s-audio-driver-for-raven-family.patch @@ -0,0 +1,2045 @@ +From df835d22aab1da078631052550420c55b55e3900 Mon Sep 17 00:00:00 2001 +From: Sudheesh Mavila <sudheesh.mavila@amd.com> +Date: Thu, 24 Jan 2019 11:01:14 +0530 +Subject: [PATCH 0581/2940] amd-i2s i2s audio driver for raven family + +Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com> +--- + sound/soc/amd/Kconfig | 5 + + sound/soc/amd/Makefile | 2 + + sound/soc/amd/raven/Makefile | 8 + + sound/soc/amd/raven/acp3x-dummy5102.c | 161 +++++ + sound/soc/amd/raven/acp3x-pcm-dma.c | 797 +++++++++++++++++++++++++ + sound/soc/amd/raven/acp3x.h | 34 ++ + sound/soc/amd/raven/chip_offset_byte.h | 655 ++++++++++++++++++++ + sound/soc/amd/raven/dummy-w5102.c | 93 +++ + sound/soc/amd/raven/pci-acp3x.c | 192 ++++++ + 9 files changed, 1947 insertions(+) + mode change 100644 => 100755 sound/soc/amd/Kconfig + mode change 100644 => 100755 sound/soc/amd/Makefile + create mode 100755 sound/soc/amd/raven/Makefile + create mode 100755 sound/soc/amd/raven/acp3x-dummy5102.c + create mode 100755 sound/soc/amd/raven/acp3x-pcm-dma.c + create mode 100755 sound/soc/amd/raven/acp3x.h + create mode 100755 sound/soc/amd/raven/chip_offset_byte.h + create mode 100755 sound/soc/amd/raven/dummy-w5102.c + create mode 100755 sound/soc/amd/raven/pci-acp3x.c + +diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig +old mode 100644 +new mode 100755 +index 58c1dcb4d255..4daaf50fa0ef +--- a/sound/soc/amd/Kconfig ++++ b/sound/soc/amd/Kconfig +@@ -2,6 +2,11 @@ config SND_SOC_AMD_ACP + tristate "AMD Audio Coprocessor support" + help + This option enables ACP DMA support on AMD platform. ++ ++config SND_SOC_AMD_ACP3x ++ tristate "AMD Audio Coprocessor-v3.x support" ++ help ++ This option enables ACP v3.x I2S support on AMD platform. + + config SND_SOC_AMD_CZ_DA7219MX98357_MACH + tristate "AMD CZ support for DA7219 and MAX9835" +diff --git a/sound/soc/amd/Makefile b/sound/soc/amd/Makefile +old mode 100644 +new mode 100755 +index 79b0622fa5d3..0bd6628cd9cf +--- a/sound/soc/amd/Makefile ++++ b/sound/soc/amd/Makefile +@@ -2,6 +2,8 @@ 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 + ++obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/ ++ + 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 +diff --git a/sound/soc/amd/raven/Makefile b/sound/soc/amd/raven/Makefile +new file mode 100755 +index 000000000000..5db3afcb80bc +--- /dev/null ++++ b/sound/soc/amd/raven/Makefile +@@ -0,0 +1,8 @@ ++snd-pci-acp3x-objs := pci-acp3x.o ++snd-acp3x-pcm-dma-objs := acp3x-pcm-dma.o ++snd-soc-dummy-w5102-objs := dummy-w5102.o ++snd-soc-acp3x-mach-objs := acp3x-dummy5102.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-soc-dummy-w5102.o ++obj-$(CONFIG_SND_SOC_AMD_ACP3x) += snd-soc-acp3x-mach.o +diff --git a/sound/soc/amd/raven/acp3x-dummy5102.c b/sound/soc/amd/raven/acp3x-dummy5102.c +new file mode 100755 +index 000000000000..5ea717f26a4c +--- /dev/null ++++ b/sound/soc/amd/raven/acp3x-dummy5102.c +@@ -0,0 +1,161 @@ ++/* ++ * Machine driver for AMD ACP Audio engine using dummy codec ++ * ++ * Copyright 2016 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) 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/soc.h> ++#include <sound/soc-dapm.h> ++#include <linux/module.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++ ++static int acp3x_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 *cpu_dai = rtd->cpu_dai; ++ unsigned int fmt; ++ unsigned int slot_width; ++ unsigned int channels; ++ int ret = 0; ++ ++ fmt = params_format(params); ++ switch (fmt) { ++ case SNDRV_PCM_FORMAT_S16_LE: ++ slot_width = 16; ++ break; ++ case SNDRV_PCM_FORMAT_S24_LE: ++ slot_width = 32; ++ break; ++ case SNDRV_PCM_FORMAT_S32_LE: ++ slot_width = 32; ++ break; ++ default: ++ printk(KERN_WARNING "acp3x: unsupported PCM format"); ++ return -EINVAL; ++ } ++ ++ channels = params_channels(params); ++ ++ if (channels == 0x04) { ++ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 4, slot_width); ++ if (ret < 0) ++ return ret; ++ } else { ++ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, slot_width); ++ if (ret < 0) ++ return ret; ++ } ++ return 0; ++} ++ ++static struct snd_soc_ops acp3x_wm5102_ops = { ++ .hw_params = acp3x_hw_params, ++}; ++ ++static int acp3x_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ return 0; ++} ++ ++static struct snd_soc_dai_link acp3x_dai_w5102[] = { ++ { ++ .name = "RV-W5102-PLAY", ++ .stream_name = "Playback", ++ .platform_name = "acp3x_rv_i2s.0", ++ .cpu_dai_name = "acp3x_rv_i2s.0", ++ .codec_dai_name = "dummy_w5102_dai", ++ .codec_name = "dummy_w5102.0", ++ .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF ++ | SND_SOC_DAIFMT_CBM_CFM, ++ .ops = &acp3x_wm5102_ops, ++ .init = acp3x_init, ++ }, ++}; ++ ++static const struct snd_soc_dapm_widget acp3x_widgets[] = { ++ SND_SOC_DAPM_HP("Headphones", NULL), ++ SND_SOC_DAPM_MIC("Analog Mic", NULL), ++}; ++ ++static const struct snd_soc_dapm_route acp3x_audio_route[] = { ++ {"Headphones", NULL, "HPO L"}, ++ {"Headphones", NULL, "HPO R"}, ++ {"MIC1", NULL, "Analog Mic"}, ++}; ++ ++static struct snd_soc_card acp3x_card = { ++ .name = "acp3x", ++ .owner = THIS_MODULE, ++ .dai_link = acp3x_dai_w5102, ++ .num_links = 1, ++}; ++ ++static int acp3x_probe(struct platform_device *pdev) ++{ ++ int ret; ++ struct acp_wm5102 *machine = NULL; ++ struct snd_soc_card *card; ++ ++ card = &acp3x_card; ++ acp3x_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) { ++ dev_err(&pdev->dev, ++ "snd_soc_register_card(%s) failed: %d\n", ++ acp3x_card.name, ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static struct platform_driver acp3x_mach_driver = { ++ .driver = { ++ .name = "acp3x_w5102_mach", ++ .pm = &snd_soc_pm_ops, ++ }, ++ .probe = acp3x_probe, ++}; ++ ++static int __init acp3x_audio_init(void) ++{ ++ platform_driver_register(&acp3x_mach_driver); ++ return 0; ++} ++ ++static void __exit acp3x_audio_exit(void) ++{ ++ platform_driver_unregister(&acp3x_mach_driver); ++} ++ ++module_init(acp3x_audio_init); ++module_exit(acp3x_audio_exit); ++ ++MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com"); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c +new file mode 100755 +index 000000000000..3faf3456e35b +--- /dev/null ++++ b/sound/soc/amd/raven/acp3x-pcm-dma.c +@@ -0,0 +1,797 @@ ++/* ++ * AMD ALSA SoC PCM Driver ++ * ++ * Copyright 2016 Advanced Micro Devices, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ */ ++ ++#include <linux/platform_device.h> ++#include <linux/module.h> ++#include <linux/err.h> ++#include <linux/pm_runtime.h> ++#include <linux/io.h> ++ ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/soc.h> ++#include <sound/soc-dai.h> ++ ++#include "acp3x.h" ++#define DRV_NAME "acp3x-i2s-audio" ++ ++struct i2s_dev_data { ++ bool tdm_mode; ++ unsigned int i2s_irq; ++ u32 tdm_fmt; ++ void __iomem *acp3x_base; ++ struct snd_pcm_substream *play_stream; ++ struct snd_pcm_substream *capture_stream; ++}; ++ ++struct i2s_stream_instance { ++ u16 num_pages; ++ u16 channels; ++ u32 xfer_resolution; ++ u32 val; ++ struct page *pg; ++ void __iomem *acp3x_base; ++}; ++ ++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_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 = 6, ++ .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_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, ++}; ++ ++static int acp3x_power_on(void __iomem *acp3x_base, bool on) ++{ ++ u16 val, mask; ++ u32 timeout; ++ ++ if (on == true) { ++ val = 1; ++ mask = 0; ++ } else { ++ val = 0; ++ mask = 2; ++ } ++ ++ rv_writel(val, acp3x_base + mmACP_PGFSM_CONTROL); ++ timeout = 0; ++ while (true) { ++ val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS); ++ if ((val & 0x3) == mask) ++ break; ++ if (timeout > 100) { ++ pr_err("ACP3x power state change failure\n"); ++ return -ENODEV; ++ } ++ timeout++; ++ cpu_relax(); ++ } ++ return 0; ++} ++ ++static int acp3x_reset(void __iomem *acp3x_base) ++{ ++ u32 val, timeout; ++ ++ rv_writel(1, acp3x_base + mmACP_SOFT_RESET); ++ timeout = 0; ++ while (true) { ++ val = rv_readl(acp3x_base + mmACP_SOFT_RESET); ++ if ((val & 0x00010001) || timeout > 100) { ++ if (val & 0x00010001) ++ break; ++ return -ENODEV; ++ } ++ timeout++; ++ cpu_relax(); ++ } ++ ++ rv_writel(0, acp3x_base + mmACP_SOFT_RESET); ++ timeout = 0; ++ while (true) { ++ val = rv_readl(acp3x_base + mmACP_SOFT_RESET); ++ if (!val || timeout > 100) { ++ if (!val) ++ break; ++ return -ENODEV; ++ } ++ timeout++; ++ cpu_relax(); ++ } ++ return 0; ++} ++ ++static int acp3x_init(void __iomem *acp3x_base) ++{ ++ int ret; ++ ++ /* power on */ ++ ret = acp3x_power_on(acp3x_base, true); ++ 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; ++ } ++ ++ pr_info("ACP Initialized\n"); ++ return 0; ++} ++ ++static int acp3x_deinit(void __iomem *acp3x_base) ++{ ++ int ret; ++ ++ /* Reset */ ++ ret = acp3x_reset(acp3x_base); ++ if (ret) { ++ pr_err("ACP3x reset failed\n"); ++ return ret; ++ } ++ ++ /* power off */ ++ ret = acp3x_power_on(acp3x_base, false); ++ if (ret) { ++ pr_err("ACP3x power off failed\n"); ++ return ret; ++ } ++ ++ pr_info("ACP De-Initialized\n"); ++ return 0; ++} ++ ++static irqreturn_t i2s_irq_handler(int irq, void *dev_id) ++{ ++ u16 play_flag, cap_flag; ++ u32 val; ++ struct i2s_dev_data *rv_i2s_data = dev_id; ++ ++ if (rv_i2s_data == NULL) ++ return IRQ_NONE; ++ ++ play_flag = 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(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 (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; ++ u64 addr; ++ u32 low, high, val, acp_fifo_addr; ++ struct page *pg = rtd->pg; ++ ++ /* 8 scratch registers used to map one 64 bit address. ++ * For 2 pages (8192 * 2 bytes), it will be 16 registers. ++ */ ++ if (direction == SNDRV_PCM_STREAM_PLAYBACK) ++ val = 0; ++ else ++ val = rtd->num_pages * 8; ++ ++ for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) { ++ /* Load the low address of page int ACP SRAM through SRBM */ ++ addr = page_to_phys(pg); ++ 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 contiguos page */ ++ val += 8; ++ pg++; ++ } ++ ++ if (direction == SNDRV_PCM_STREAM_PLAYBACK) { ++ /* Config ringbuffer */ ++ rv_writel(MEM_WINDOW_START, rtd->acp3x_base + ++ mmACP_BT_TX_RINGBUFADDR); ++ rv_writel(MAX_BUFFER, rtd->acp3x_base + ++ mmACP_BT_TX_RINGBUFSIZE); ++ rv_writel(0x40, rtd->acp3x_base + mmACP_BT_TX_DMA_SIZE); ++ ++ /* Config audio fifo */ ++ acp_fifo_addr = ACP_SRAM_PTE_OFFSET + (rtd->num_pages * 8) ++ + 1024; ++ rv_writel(acp_fifo_addr, rtd->acp3x_base + ++ mmACP_BT_TX_FIFOADDR); ++ rv_writel(256, rtd->acp3x_base + mmACP_BT_TX_FIFOSIZE); ++ rv_writel(PLAYBACK_MIN_PERIOD_SIZE, rtd->acp3x_base + ++ mmACP_BT_TX_INTR_WATERMARK_SIZE); ++ } else { ++ /* Config ringbuffer */ ++ rv_writel(MEM_WINDOW_START + MAX_BUFFER, rtd->acp3x_base + ++ mmACP_BT_RX_RINGBUFADDR); ++ rv_writel(MAX_BUFFER, rtd->acp3x_base + ++ mmACP_BT_RX_RINGBUFSIZE); ++ rv_writel(0x40, rtd->acp3x_base + mmACP_BT_RX_DMA_SIZE); ++ ++ /* Config audio fifo */ ++ acp_fifo_addr = ACP_SRAM_PTE_OFFSET + ++ (rtd->num_pages * 8) + 1024 + 256; ++ rv_writel(acp_fifo_addr, rtd->acp3x_base + ++ mmACP_BT_RX_FIFOADDR); ++ rv_writel(256, rtd->acp3x_base + mmACP_BT_RX_FIFOSIZE); ++ rv_writel(CAPTURE_MIN_PERIOD_SIZE, rtd->acp3x_base + ++ mmACP_BT_RX_INTR_WATERMARK_SIZE); ++ } ++ ++ /* Enable watermark/period interrupt to host */ ++ rv_writel(BIT(BT_TX_THRESHOLD) | BIT(BT_RX_THRESHOLD), ++ rtd->acp3x_base + mmACP_EXTERNAL_INTR_CNTL); ++ rv_writel(BIT(0), rtd->acp3x_base + mmACPAXI2AXI_ATU_CTRL); ++} ++ ++static int acp3x_dma_open(struct snd_pcm_substream *substream) ++{ ++ int ret = 0; ++ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct snd_soc_pcm_runtime *prtd = substream->private_data; ++ struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, ++ DRV_NAME); ++ struct i2s_dev_data *adata = dev_get_drvdata(component->dev); ++ ++ struct i2s_stream_instance *i2s_data = kzalloc(sizeof( ++ struct i2s_stream_instance), GFP_KERNEL); ++ if (i2s_data == NULL) ++ 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"); ++ return ret; ++ } ++ ++ if (!adata->play_stream && !adata->capture_stream) ++ rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ adata->play_stream = substream; ++ else ++ adata->capture_stream = substream; ++ ++ i2s_data->acp3x_base = adata->acp3x_base; ++ runtime->private_data = i2s_data; ++ return 0; ++} ++ ++static int acp3x_dma_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ int status; ++ uint64_t size; ++ struct snd_dma_buffer *dma_buffer; ++ struct page *pg; ++ struct i2s_stream_instance *rtd = substream->runtime->private_data; ++ ++ if (rtd == NULL) ++ return -EINVAL; ++ ++ dma_buffer = &substream->dma_buffer; ++ size = params_buffer_bytes(params); ++ status = snd_pcm_lib_malloc_pages(substream, size); ++ if (status < 0) ++ return status; ++ ++ memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); ++ pg = virt_to_page(substream->dma_buffer.area); ++ if (pg != NULL) { ++ rtd->pg = pg; ++ rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); ++ config_acp3x_dma(rtd, substream->stream); ++ status = 0; ++ } else { ++ status = -ENOMEM; ++ } ++ return status; ++} ++ ++static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream) ++{ ++ u32 pos = 0; ++ struct i2s_stream_instance *rtd = substream->runtime->private_data; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ pos = rv_readl(rtd->acp3x_base + ++ mmACP_BT_TX_LINKPOSITIONCNTR); ++ else ++ pos = rv_readl(rtd->acp3x_base + ++ mmACP_BT_RX_LINKPOSITIONCNTR); ++ ++ if (pos >= MAX_BUFFER) ++ pos = 0; ++ ++ return bytes_to_frames(substream->runtime, pos); ++} ++ ++static int acp3x_dma_new(struct snd_soc_pcm_runtime *rtd) ++{ ++ return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, ++ SNDRV_DMA_TYPE_DEV, ++ NULL, MIN_BUFFER, ++ MAX_BUFFER); ++} ++ ++static int acp3x_dma_hw_free(struct snd_pcm_substream *substream) ++{ ++ return snd_pcm_lib_free_pages(substream); ++} ++ ++static int acp3x_dma_mmap(struct snd_pcm_substream *substream, ++ struct vm_area_struct *vma) ++{ ++ return snd_pcm_lib_default_mmap(substream, vma); ++} ++ ++static int acp3x_dma_close(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *prtd = substream->private_data; ++ struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, ++ DRV_NAME); ++ struct i2s_dev_data *adata = dev_get_drvdata(component->dev); ++ struct i2s_stream_instance *rtd = substream->runtime->private_data; ++ ++ kfree(rtd); ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ adata->play_stream = NULL; ++ else ++ adata->capture_stream = NULL; ++ ++ /* Disable ACP irq, when the current stream is being closed and ++ * another stream is also not active. ++ */ ++ if (!adata->play_stream && !adata->capture_stream) ++ rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); ++ ++ return 0; ++} ++ ++static struct snd_pcm_ops acp3x_dma_ops = { ++ .open = acp3x_dma_open, ++ .close = acp3x_dma_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = acp3x_dma_hw_params, ++ .hw_free = acp3x_dma_hw_free, ++ .pointer = acp3x_dma_pointer, ++ .mmap = acp3x_dma_mmap, ++}; ++ ++static int acp3x_dai_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) ++{ ++ ++ struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai); ++ ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ adata->tdm_mode = false; ++ break; ++ case SND_SOC_DAIFMT_DSP_A: ++ adata->tdm_mode = true; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int acp3x_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, ++ u32 rx_mask, int slots, int slot_width) ++{ ++ u32 val = 0; ++ u16 slot_len; ++ ++ struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai); ++ ++ switch (slot_width) { ++ case 8: ++ slot_len = 8; ++ break; ++ case 16: ++ slot_len = 16; ++ break; ++ case 24: ++ slot_len = 24; ++ break; ++ case 32: ++ slot_len = 0; ++ break; ++ default: ++ return -EINVAL; ++ break; ++ } ++ ++ val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER); ++ rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_ITER); ++ val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER); ++ rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_IRER); ++ ++ val = (FRM_LEN | ((slots) << 15) | (slot_len << 18)); ++ rv_writel(val, adata->acp3x_base + mmACP_BTTDM_TXFRMT); ++ rv_writel(val, adata->acp3x_base + mmACP_BTTDM_RXFRMT); ++ ++ adata->tdm_fmt = val; ++ return 0; ++} ++ ++static int acp3x_dai_i2s_hwparams(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ u32 val = 0; ++ struct i2s_stream_instance *rtd = substream->runtime->private_data; ++ ++ 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; ++ } ++ ++ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER); ++ val = val | (rtd->xfer_resolution << 3); ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER); ++ else ++ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER); ++ ++ return 0; ++} ++ ++static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream, ++ int cmd, struct snd_soc_dai *dai) ++{ ++ int ret = 0; ++ struct i2s_stream_instance *rtd = substream->runtime->private_data; ++ u32 val; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER); ++ val = val | BIT(0); ++ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER); ++ } else { ++ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER); ++ val = val | BIT(0); ++ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER); ++ } ++ rv_writel(1, rtd->acp3x_base + mmACP_BTTDM_IER); ++ break; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER); ++ val = val & ~BIT(0); ++ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER); ++ } else { ++ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER); ++ val = val & ~BIT(0); ++ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER); ++ } ++ rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++struct snd_soc_dai_ops acp3x_dai_i2s_ops = { ++ .hw_params = acp3x_dai_i2s_hwparams, ++ .trigger = acp3x_dai_i2s_trigger, ++ .set_fmt = acp3x_dai_i2s_set_fmt, ++ .set_tdm_slot = acp3x_dai_set_tdm_slot, ++}; ++ ++static struct snd_soc_dai_driver acp3x_i2s_dai_driver = { ++ .playback = { ++ .rates = SNDRV_PCM_RATE_8000_96000, ++ .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, ++ ++ .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_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE, ++ .channels_min = 2, ++ .channels_max = 2, ++ .rate_min = 8000, ++ .rate_max = 48000, ++ }, ++ .ops = &acp3x_dai_i2s_ops, ++}; ++ ++static const struct snd_soc_component_driver acp3x_i2s_component = { ++ .name = DRV_NAME, ++ .ops = &acp3x_dma_ops, ++ .pcm_new = acp3x_dma_new, ++}; ++ ++static int acp3x_audio_probe(struct platform_device *pdev) ++{ ++ int status; ++ struct resource *res; ++ struct i2s_dev_data *adata; ++ unsigned int irqflags; ++ ++ if (pdev->dev.platform_data == NULL) { ++ dev_err(&pdev->dev, "platform_data not retrieved\n"); ++ return -ENODEV; ++ } ++ irqflags = *((unsigned int *)(pdev->dev.platform_data)); ++ ++ adata = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dev_data), ++ GFP_KERNEL); ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); ++ return -ENODEV; ++ } ++ ++ adata->acp3x_base = devm_ioremap(&pdev->dev, res->start, ++ resource_size(res)); ++ ++ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); ++ return -ENODEV; ++ } ++ ++ adata->i2s_irq = res->start; ++ adata->play_stream = NULL; ++ adata->capture_stream = NULL; ++ ++ dev_set_drvdata(&pdev->dev, adata); ++ /* Initialize ACP */ ++ status = acp3x_init(adata->acp3x_base); ++ if (status) ++ return -ENODEV; ++ /* Group Enable */ ++ rv_writel(ACP_SRAM_PTE_OFFSET | BIT(31), adata->acp3x_base + ++ mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1); ++ rv_writel(PAGE_SIZE_4K_ENABLE, adata->acp3x_base + ++ mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); ++ ++ status = devm_snd_soc_register_component(&pdev->dev, ++ &acp3x_i2s_component, &acp3x_i2s_dai_driver, 1); ++ if (status != 0) { ++ dev_err(&pdev->dev, "Fail to register acp i2s dai\n"); ++ goto dev_err; ++ } ++ ++ 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"); ++ goto dev_err; ++ } ++ ++ pm_runtime_set_autosuspend_delay(&pdev->dev, 10000); ++ pm_runtime_use_autosuspend(&pdev->dev); ++ pm_runtime_enable(&pdev->dev); ++ return 0; ++dev_err: ++ status = acp3x_deinit(adata->acp3x_base); ++ if (status) ++ dev_err(&pdev->dev, "ACP de-init failed\n"); ++ else ++ dev_info(&pdev->dev, "ACP de-initialized\n"); ++ /*ignore device status and return driver probe error*/ ++ return -ENODEV; ++} ++ ++static int acp3x_audio_remove(struct platform_device *pdev) ++{ ++ int ret; ++ struct i2s_dev_data *adata = dev_get_drvdata(&pdev->dev); ++ ++ ret = acp3x_deinit(adata->acp3x_base); ++ if (ret) ++ dev_err(&pdev->dev, "ACP de-init failed\n"); ++ else ++ dev_info(&pdev->dev, "ACP de-initialized\n"); ++ ++ pm_runtime_disable(&pdev->dev); ++ return 0; ++} ++ ++static int acp3x_resume(struct device *dev) ++{ ++ int status; ++ u32 val; ++ struct i2s_dev_data *adata = dev_get_drvdata(dev); ++ ++ status = acp3x_init(adata->acp3x_base); ++ if (status) ++ return -ENODEV; ++ ++ 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); ++ rv_writel((rtd->xfer_resolution << 3), ++ rtd->acp3x_base + mmACP_BTTDM_ITER); ++ if (adata->tdm_mode == true) { ++ rv_writel(adata->tdm_fmt, adata->acp3x_base + ++ mmACP_BTTDM_TXFRMT); ++ val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER); ++ rv_writel((val | 0x2), adata->acp3x_base + ++ mmACP_BTTDM_ITER); ++ } ++ } ++ ++ 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); ++ rv_writel((rtd->xfer_resolution << 3), ++ rtd->acp3x_base + mmACP_BTTDM_IRER); ++ if (adata->tdm_mode == true) { ++ rv_writel(adata->tdm_fmt, adata->acp3x_base + ++ mmACP_BTTDM_RXFRMT); ++ val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER); ++ rv_writel((val | 0x2), adata->acp3x_base + ++ mmACP_BTTDM_IRER); ++ } ++ } ++ ++ rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); ++ return 0; ++} ++ ++ ++static int acp3x_pcm_runtime_suspend(struct device *dev) ++{ ++ int status; ++ struct i2s_dev_data *adata = dev_get_drvdata(dev); ++ ++ status = acp3x_deinit(adata->acp3x_base); ++ if (status) ++ dev_err(dev, "ACP de-init failed\n"); ++ else ++ dev_info(dev, "ACP de-initialized\n"); ++ ++ rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); ++ ++ return 0; ++} ++ ++static int acp3x_pcm_runtime_resume(struct device *dev) ++{ ++ int status; ++ struct i2s_dev_data *adata = dev_get_drvdata(dev); ++ ++ status = acp3x_init(adata->acp3x_base); ++ if (status) ++ return -ENODEV; ++ 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 = acp3x_audio_remove, ++ .driver = { ++ .name = "acp3x_rv_i2s", ++ .pm = &acp3x_pm_ops, ++ }, ++}; ++ ++module_platform_driver(acp3x_dma_driver); ++ ++MODULE_AUTHOR("Maruthi.Bayyavarapu@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 100755 +index 000000000000..2e901ee60287 +--- /dev/null ++++ b/sound/soc/amd/raven/acp3x.h +@@ -0,0 +1,34 @@ ++#include "chip_offset_byte.h" ++ ++#define ACP3x_PHY_BASE_ADDRESS 0x1240000 ++#define ACP3x_I2S_MODE 0 ++#define ACP3x_REG_START 0x1240000 ++#define ACP3x_REG_END 0x1250200 ++#define BT_TX_THRESHOLD 26 ++#define BT_RX_THRESHOLD 25 ++#define ACP_SRAM_PTE_OFFSET 0x02050000 ++#define PAGE_SIZE_4K_ENABLE 0x2 ++#define MEM_WINDOW_START 0x4000000 ++#define FRM_LEN 256 ++ ++#define PLAYBACK_MIN_NUM_PERIODS 8 ++#define PLAYBACK_MAX_NUM_PERIODS 8 ++#define PLAYBACK_MAX_PERIOD_SIZE 8192 ++#define PLAYBACK_MIN_PERIOD_SIZE 8192 ++#define CAPTURE_MIN_NUM_PERIODS 8 ++#define CAPTURE_MAX_NUM_PERIODS 8 ++#define CAPTURE_MAX_PERIOD_SIZE 8192 ++#define CAPTURE_MIN_PERIOD_SIZE 8192 ++ ++#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) ++#define MIN_BUFFER MAX_BUFFER ++ ++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); ++} +diff --git a/sound/soc/amd/raven/chip_offset_byte.h b/sound/soc/amd/raven/chip_offset_byte.h +new file mode 100755 +index 000000000000..3ce4c361d644 +--- /dev/null ++++ b/sound/soc/amd/raven/chip_offset_byte.h +@@ -0,0 +1,655 @@ ++/* ++ * ACP 3.0 Register documentation ++ * ++ * Copyright (C) 2016 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_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/dummy-w5102.c b/sound/soc/amd/raven/dummy-w5102.c +new file mode 100755 +index 000000000000..f766c112f559 +--- /dev/null ++++ b/sound/soc/amd/raven/dummy-w5102.c +@@ -0,0 +1,93 @@ ++/* ++ * dummy audio codec driver ++ * ++ * Copyright 2016 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) 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 <linux/module.h> ++#include <sound/soc.h> ++ ++#define W5102_RATES SNDRV_PCM_RATE_8000_96000 ++#define W5102_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ ++ SNDRV_PCM_FMTBIT_S32_LE | \ ++ SNDRV_PCM_FMTBIT_S24_LE) ++ ++static const struct snd_soc_dapm_widget w5102_widgets[] = { ++ SND_SOC_DAPM_OUTPUT("dummy-w5102-out"), ++ SND_SOC_DAPM_INPUT("dummy-w5102-in"), ++}; ++ ++static const struct snd_soc_dapm_route w5102_routes[] = { ++ { "dummy-w5102-out", NULL, "Playback" }, ++ { "Capture", NULL, "dummy-w5102-in" }, ++}; ++ ++static struct snd_soc_dai_driver w5102_stub_dai = { ++ .name = "dummy_w5102_dai", ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 6, ++ .rates = W5102_RATES, ++ .formats = W5102_FORMATS, ++ }, ++ .capture = { ++ .stream_name = "Capture", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = W5102_RATES, ++ .formats = W5102_FORMATS, ++ }, ++ ++}; ++ ++static const struct snd_soc_component_driver soc_component_wm5102_dummy = { ++ .dapm_widgets = w5102_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(w5102_widgets), ++ .dapm_routes = w5102_routes, ++ .num_dapm_routes = ARRAY_SIZE(w5102_routes), ++}; ++ ++static int dummy_w5102_probe(struct platform_device *pdev) ++{ ++ int ret; ++ ++ ret = devm_snd_soc_register_component(&pdev->dev, ++ &soc_component_wm5102_dummy, ++ &w5102_stub_dai, 1); ++ return ret; ++} ++ ++static struct platform_driver dummy_w5102_driver = { ++ .probe = dummy_w5102_probe, ++ .driver = { ++ .name = "dummy_w5102", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++module_platform_driver(dummy_w5102_driver); ++ ++MODULE_DESCRIPTION("dummy-w5102 dummy codec driver"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform: dummy_w5102"); +diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c +new file mode 100755 +index 000000000000..0d39aa8a8015 +--- /dev/null ++++ b/sound/soc/amd/raven/pci-acp3x.c +@@ -0,0 +1,192 @@ ++/* ++ * AMD ALSA SoC PCM Driver ++ * ++ * Copyright 2016 Advanced Micro Devices, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ */ ++ ++#include <linux/pci.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/interrupt.h> ++ ++#include "acp3x.h" ++ ++struct acp3x_dev_data { ++ void __iomem *acp3x_base; ++ bool acp3x_audio_mode; ++ struct resource *res; ++ struct platform_device *pdev[3]; ++}; ++ ++static int snd_acp3x_probe(struct pci_dev *pci, ++ const struct pci_device_id *pci_id) ++{ ++ int ret; ++ u32 addr, val; ++ struct acp3x_dev_data *adata; ++ struct platform_device_info pdevinfo; ++ unsigned int irqflags; ++ ++ 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 == NULL) { ++ 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->acp3x_base = ioremap(addr, pci_resource_len(pci, 0)); ++ if (adata->acp3x_base == NULL) { ++ ret = -ENOMEM; ++ goto release_regions; ++ } ++ ++ /* set pci bus-mastering */ ++ pci_set_master(pci); ++ ++ pci_set_drvdata(pci, adata); ++ ++ val = rv_readl(adata->acp3x_base + mmACP_I2S_PIN_CONFIG); ++ if (val == 0x4) { ++ adata->res = devm_kzalloc(&pci->dev, ++ sizeof(struct resource) * 2, ++ GFP_KERNEL); ++ if (adata->res == NULL) { ++ ret = -ENOMEM; ++ goto unmap_mmio; ++ } ++ ++ 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_irq"; ++ adata->res[1].flags = IORESOURCE_IRQ; ++ adata->res[1].start = pci->irq; ++ adata->res[1].end = pci->irq; ++ ++ adata->acp3x_audio_mode = ACP3x_I2S_MODE; ++ ++ memset(&pdevinfo, 0, sizeof(pdevinfo)); ++ pdevinfo.name = "acp3x_rv_i2s"; ++ pdevinfo.id = 0; ++ pdevinfo.parent = &pci->dev; ++ pdevinfo.num_res = 2; ++ pdevinfo.res = adata->res; ++ pdevinfo.data = &irqflags; ++ pdevinfo.size_data = sizeof(irqflags); ++ ++ adata->pdev[0] = platform_device_register_full(&pdevinfo); ++ if (adata->pdev[0] == NULL) { ++ dev_err(&pci->dev, "cannot register %s device\n", ++ pdevinfo.name); ++ ret = -ENODEV; ++ goto unmap_mmio; ++ } ++ ++ /* create dummy codec device */ ++ adata->pdev[1] = platform_device_register_simple("dummy_w5102", ++ 0, NULL, 0); ++ if (IS_ERR(adata->pdev[1])) { ++ dev_err(&pci->dev, "Cannot register dummy_w5102\n"); ++ ret = -ENODEV; ++ goto unregister_pdev0; ++ } ++ /* create dummy mach device */ ++ adata->pdev[2] = platform_device_register_simple( ++ "acp3x_w5102_mach", 0, NULL, 0); ++ if (IS_ERR(adata->pdev[2])) { ++ dev_err(&pci->dev, "Cannot register acp3x_w5102_mach\n"); ++ ret = -ENODEV; ++ goto unregister_pdev1; ++ } ++ } else { ++ dev_err(&pci->dev, "Inavlid ACP audio mode : %d\n", val); ++ ret = -ENODEV; ++ goto unmap_mmio; ++ } ++ ++ return 0; ++ ++unregister_pdev1: ++ platform_device_unregister(adata->pdev[1]); ++unregister_pdev0: ++ platform_device_unregister(adata->pdev[0]); ++unmap_mmio: ++ pci_disable_msi(pci); ++ iounmap(adata->acp3x_base); ++release_regions: ++ pci_release_regions(pci); ++disable_pci: ++ pci_disable_device(pci); ++ ++ return ret; ++} ++ ++static void snd_acp3x_remove(struct pci_dev *pci) ++{ ++ int i; ++ struct acp3x_dev_data *adata = pci_get_drvdata(pci); ++ ++ if (adata->acp3x_audio_mode == ACP3x_I2S_MODE) { ++ for (i = 2; i >= 0; i--) ++ platform_device_unregister(adata->pdev[i]); ++ } ++ ++ iounmap(adata->acp3x_base); ++ ++ pci_disable_msi(pci); ++ 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, ++}; ++ ++module_pci_driver(acp3x_driver); ++ ++MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com"); ++MODULE_DESCRIPTION("AMD ACP3x PCI driver"); ++MODULE_LICENSE("GPL v2"); +-- +2.17.1 + |