summaryrefslogtreecommitdiff
path: root/sound/soc/amd/ps/pci-ps.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/amd/ps/pci-ps.c')
-rw-r--r--sound/soc/amd/ps/pci-ps.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
index adad29667791..e4ddd80d0dd4 100644
--- a/sound/soc/amd/ps/pci-ps.c
+++ b/sound/soc/amd/ps/pci-ps.c
@@ -11,6 +11,8 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
+#include <linux/interrupt.h>
+#include <sound/pcm_params.h>
#include "acp62.h"
@@ -115,6 +117,27 @@ static int acp62_deinit(void __iomem *acp_base, struct device *dev)
return 0;
}
+static irqreturn_t acp62_irq_handler(int irq, void *dev_id)
+{
+ struct acp62_dev_data *adata;
+ struct pdm_dev_data *ps_pdm_data;
+ u32 val;
+
+ adata = dev_id;
+ if (!adata)
+ return IRQ_NONE;
+
+ val = acp62_readl(adata->acp62_base + ACP_EXTERNAL_INTR_STAT);
+ if (val & BIT(PDM_DMA_STAT)) {
+ ps_pdm_data = dev_get_drvdata(&adata->pdev[0]->dev);
+ acp62_writel(BIT(PDM_DMA_STAT), adata->acp62_base + ACP_EXTERNAL_INTR_STAT);
+ if (ps_pdm_data->capture_stream)
+ snd_pcm_period_elapsed(ps_pdm_data->capture_stream);
+ return IRQ_HANDLED;
+ }
+ return IRQ_NONE;
+}
+
static int snd_acp62_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
@@ -125,7 +148,9 @@ static int snd_acp62_probe(struct pci_dev *pci,
struct acpi_device *adev;
const union acpi_object *obj;
u32 addr;
+ unsigned int irqflags;
+ irqflags = IRQF_SHARED;
/* Pink Sardine device check */
switch (pci->revision) {
case 0x63:
@@ -218,6 +243,12 @@ static int snd_acp62_probe(struct pci_dev *pci,
ret = PTR_ERR(adata->pdev[index]);
goto unregister_devs;
}
+ ret = devm_request_irq(&pci->dev, pci->irq, acp62_irq_handler,
+ irqflags, "ACP_PCI_IRQ", adata);
+ if (ret) {
+ dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
+ goto unregister_devs;
+ }
}
}
break;