diff --git a/sound/soc/amd/ps/acp62.h b/sound/soc/amd/ps/acp62.h index 1f117f62465a..eed7a05ba112 100644 --- a/sound/soc/amd/ps/acp62.h +++ b/sound/soc/amd/ps/acp62.h @@ -24,6 +24,7 @@ #define ACP_ERROR_MASK 0x20000000 #define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF +#define PDM_DMA_STAT 0x10 enum acp_config { ACP_CONFIG_0 = 0, @@ -45,6 +46,7 @@ enum acp_config { }; struct pdm_dev_data { + u32 pdm_irq; void __iomem *acp62_base; struct snd_pcm_substream *capture_stream; }; 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 #include #include +#include +#include #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;