aboutsummaryrefslogtreecommitdiffstats
path: root/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1101-ASoC-AMD-create-ACP3x-PCM-platform-device.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1101-ASoC-AMD-create-ACP3x-PCM-platform-device.patch')
-rw-r--r--meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1101-ASoC-AMD-create-ACP3x-PCM-platform-device.patch149
1 files changed, 149 insertions, 0 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1101-ASoC-AMD-create-ACP3x-PCM-platform-device.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1101-ASoC-AMD-create-ACP3x-PCM-platform-device.patch
new file mode 100644
index 00000000..68ea87a1
--- /dev/null
+++ b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1101-ASoC-AMD-create-ACP3x-PCM-platform-device.patch
@@ -0,0 +1,149 @@
+From 5de6a6c59f338b72cf60c084126fdb69e4ab32b7 Mon Sep 17 00:00:00 2001
+From: Maruthi Srinivas Bayyavarapu <Maruthi.Bayyavarapu@amd.com>
+Date: Wed, 29 Mar 2017 18:34:38 +0530
+Subject: [PATCH 1101/4131] ASoC: AMD: create ACP3x PCM platform device
+
+ACP 3x IP have I2S controller device as one of IP blocks.
+Create a platform device for it, so that PCM platform driver
+can be binded to this device. Pass PCI resources like MMIO, irq
+to the platform device.
+
+Signed-off-by: Maruthi Bayyavarapu <maruthi.bayyavarapu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ sound/soc/amd/raven/acp3x.h | 3 ++
+ sound/soc/amd/raven/pci-acp3x.c | 68 ++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 70 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/raven/acp3x.h b/sound/soc/amd/raven/acp3x.h
+index e9b4df0..1996faf 100644
+--- a/sound/soc/amd/raven/acp3x.h
++++ b/sound/soc/amd/raven/acp3x.h
+@@ -1,6 +1,9 @@
+ #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
+
+ static inline u32 rv_readl(void __iomem *base_addr)
+ {
+diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c
+index 204212b..a182013 100644
+--- a/sound/soc/amd/raven/pci-acp3x.c
++++ b/sound/soc/amd/raven/pci-acp3x.c
+@@ -15,19 +15,26 @@
+
+ #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;
+ };
+
+ static int snd_acp3x_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+ {
+ int ret;
+- u32 addr;
++ 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");
+@@ -47,6 +54,15 @@ static int snd_acp3x_probe(struct pci_dev *pci,
+ 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) {
+@@ -56,8 +72,55 @@ static int snd_acp3x_probe(struct pci_dev *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 = platform_device_register_full(&pdevinfo);
++ if (adata->pdev == NULL) {
++ dev_err(&pci->dev, "cannot register %s device\n",
++ pdevinfo.name);
++ ret = -ENODEV;
++ goto unmap_mmio;
++ }
++ } else {
++ dev_err(&pci->dev, "Inavlid ACP audio mode : %d\n", val);
++ ret = -ENODEV;
++ goto unmap_mmio;
++ }
++
+ return 0;
+
++unmap_mmio:
++ pci_disable_msi(pci);
++ iounmap(adata->acp3x_base);
+ release_regions:
+ pci_release_regions(pci);
+ disable_pci:
+@@ -70,7 +133,10 @@ static void snd_acp3x_remove(struct pci_dev *pci)
+ {
+ struct acp3x_dev_data *adata = pci_get_drvdata(pci);
+
++ platform_device_unregister(adata->pdev);
+ iounmap(adata->acp3x_base);
++
++ pci_disable_msi(pci);
+ pci_release_regions(pci);
+ pci_disable_device(pci);
+ }
+--
+2.7.4
+