diff mbox series

[06/13] ASoC: amd: add acp6x irq handler

Message ID 20211011055621.13240-7-Vijendar.Mukunda@amd.com (mailing list archive)
State Superseded
Headers show
Series Add Yellow Carp platform ASoC driver | expand

Commit Message

Mukunda,Vijendar Oct. 11, 2021, 5:56 a.m. UTC
Add ACP6x irq handler for handling irq events for ACP IP.
Add pdm irq events handling.
Whenever audio data equal to the PDM watermark level are consumed,
interrupt is generated. Acknowledge the interrupt.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/yc/acp6x.h     |  2 ++
 sound/soc/amd/yc/pci-acp6x.c | 37 ++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

Comments

Joe Perches Oct. 11, 2021, 8:58 a.m. UTC | #1
On Mon, 2021-10-11 at 11:26 +0530, Vijendar Mukunda wrote:
> Add ACP6x irq handler for handling irq events for ACP IP.
> Add pdm irq events handling.
> Whenever audio data equal to the PDM watermark level are consumed,
> interrupt is generated. Acknowledge the interrupt.

> diff --git a/sound/soc/amd/yc/pci-acp6x.c b/sound/soc/amd/yc/pci-acp6x.c
[]
> @@ -116,6 +118,33 @@ static int acp6x_deinit(void __iomem *acp_base)
>  	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;
> +	u16 irq_flag;

irq_flag seems unnecessary.

> +	u32 val;
> +
> +	adata = dev_id;
> +	if (!adata)
> +		return IRQ_NONE;
> +
> +	irq_flag = 0;
> +	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);
> +		irq_flag = 1;

Could be:

		return IRQ_HANDLED;

> +	}
> +
> +	if (irq_flag)
> +		return IRQ_HANDLED;
> +	else
> +		return IRQ_NONE;

and
	return IRQ_NONE;

> +}
Mukunda,Vijendar Oct. 11, 2021, 9:28 a.m. UTC | #2
On 10/11/21 2:28 PM, Joe Perches wrote:
> On Mon, 2021-10-11 at 11:26 +0530, Vijendar Mukunda wrote:
>> Add ACP6x irq handler for handling irq events for ACP IP.
>> Add pdm irq events handling.
>> Whenever audio data equal to the PDM watermark level are consumed,
>> interrupt is generated. Acknowledge the interrupt.
> 
>> diff --git a/sound/soc/amd/yc/pci-acp6x.c b/sound/soc/amd/yc/pci-acp6x.c
> []
>> @@ -116,6 +118,33 @@ static int acp6x_deinit(void __iomem *acp_base)
>>  	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;
>> +	u16 irq_flag;
> 
> irq_flag seems unnecessary.
> 
>> +	u32 val;
>> +
>> +	adata = dev_id;
>> +	if (!adata)
>> +		return IRQ_NONE;
>> +
>> +	irq_flag = 0;
>> +	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);
>> +		irq_flag = 1;
> 
> Could be:
> 
> 		return IRQ_HANDLED;
  will fix it and post the new version.
> 
>> +	}
>> +
>> +	if (irq_flag)
>> +		return IRQ_HANDLED;
>> +	else
>> +		return IRQ_NONE;
> 
> and
> 	return IRQ_NONE;
> 
>> +}
> 
>
diff mbox series

Patch

diff --git a/sound/soc/amd/yc/acp6x.h b/sound/soc/amd/yc/acp6x.h
index d6b2c70ce9c8..4ea37794db84 100644
--- a/sound/soc/amd/yc/acp6x.h
+++ b/sound/soc/amd/yc/acp6x.h
@@ -25,6 +25,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,
@@ -46,6 +47,7 @@  enum acp_config {
 };
 
 struct pdm_dev_data {
+	u32 pdm_irq;
 	void __iomem *acp6x_base;
 	struct snd_pcm_substream *capture_stream;
 };
diff --git a/sound/soc/amd/yc/pci-acp6x.c b/sound/soc/amd/yc/pci-acp6x.c
index 26c8d652fd08..86b33f401e12 100644
--- a/sound/soc/amd/yc/pci-acp6x.c
+++ b/sound/soc/amd/yc/pci-acp6x.c
@@ -9,6 +9,8 @@ 
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <sound/pcm_params.h>
 
 #include "acp6x.h"
 
@@ -116,6 +118,33 @@  static int acp6x_deinit(void __iomem *acp_base)
 	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;
+	u16 irq_flag;
+	u32 val;
+
+	adata = dev_id;
+	if (!adata)
+		return IRQ_NONE;
+
+	irq_flag = 0;
+	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);
+		irq_flag = 1;
+	}
+
+	if (irq_flag)
+		return IRQ_HANDLED;
+	else
+		return IRQ_NONE;
+}
+
 static int snd_acp6x_probe(struct pci_dev *pci,
 			   const struct pci_device_id *pci_id)
 {
@@ -124,7 +153,9 @@  static int snd_acp6x_probe(struct pci_dev *pci,
 	int ret, index;
 	int val = 0x00;
 	u32 addr;
+	unsigned int irqflags;
 
+	irqflags = IRQF_SHARED;
 	/* Yellow Carp device check */
 	if (pci->revision != 0x60)
 		return -ENODEV;
@@ -208,6 +239,12 @@  static int snd_acp6x_probe(struct pci_dev *pci,
 		}
 		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;
+	}
 	return 0;
 unregister_devs:
 	for (--index; index >= 0; index--)