diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/1103-ASoC-AMD-handle-ACP3x-i2s-watermark-interrupt.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/1103-ASoC-AMD-handle-ACP3x-i2s-watermark-interrupt.patch | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/1103-ASoC-AMD-handle-ACP3x-i2s-watermark-interrupt.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/1103-ASoC-AMD-handle-ACP3x-i2s-watermark-interrupt.patch new file mode 100644 index 00000000..29cf192e --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/1103-ASoC-AMD-handle-ACP3x-i2s-watermark-interrupt.patch @@ -0,0 +1,99 @@ +From 0550f8597afc1ea3d6f3aec554dac24cff85a558 Mon Sep 17 00:00:00 2001 +From: Maruthi Srinivas Bayyavarapu <Maruthi.Bayyavarapu@amd.com> +Date: Thu, 30 Mar 2017 13:28:45 +0530 +Subject: [PATCH 1103/4131] ASoC: AMD: handle ACP3x i2s watermark interrupt + +whenever audio data equal to I2S fifo watermark level is +produced/consumed, interrupt is generated. Amount of data is equal to +half of ALSA ring buffer size. Acknowledge the interrupt. + +Signed-off-by: Maruthi Bayyavarapu <maruthi.bayyavarapu@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + sound/soc/amd/raven/acp3x-pcm-dma.c | 49 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 49 insertions(+) + +diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c +index 3fd9f86..0ce04f0 100644 +--- a/sound/soc/amd/raven/acp3x-pcm-dma.c ++++ b/sound/soc/amd/raven/acp3x-pcm-dma.c +@@ -25,6 +25,7 @@ + #include "acp3x.h" + + struct i2s_dev_data { ++ unsigned int i2s_irq; + void __iomem *acp3x_base; + struct snd_pcm_substream *play_stream; + struct snd_pcm_substream *capture_stream; +@@ -135,6 +136,38 @@ static int acp3x_deinit(void __iomem *acp3x_base) + 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 struct snd_pcm_ops acp3x_dma_ops = { + .open = NULL, + .close = NULL, +@@ -211,6 +244,13 @@ static int acp3x_audio_probe(struct platform_device *pdev) + 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; + +@@ -234,6 +274,15 @@ static int acp3x_audio_probe(struct platform_device *pdev) + 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"); ++ snd_soc_unregister_platform(&pdev->dev); ++ snd_soc_unregister_component(&pdev->dev); ++ goto dev_err; ++ } ++ + return 0; + dev_err: + status = acp3x_deinit(adata->acp3x_base); +-- +2.7.4 + |