kernel-6.6/0627-BROKEN-dwc-i2s-support-Baikal-M-SoC.patch
Mikhail Novosyolov 754cb78a80 begin kernel 6.6
2024-02-22 15:51:17 +03:00

107 lines
3.2 KiB
Diff

From a1d78cf95aa6777e5e7b4cb117450b51c858d550 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@basealt.ru>
Date: Mon, 23 May 2022 19:35:08 +0400
Subject: [PATCH 627/631] (BROKEN) dwc-i2s: support Baikal-M SoC
* dw_i2s_probe: request all IRQs specified in device tree
* i2s_irq_handler: avoid flooding system with RX overrun warnings
Note that the sound frequency is distorted (i.e. playing 440 Hz
sine wave results in 467 Hz)
Signed-off-by: Alexey Sheplyakov <asheplyakov@basealt.ru>
X-feature-Baikal-M
[ Adapted for kernel 6.6 ]
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
---
sound/soc/dwc/dwc-i2s.c | 36 +++++++++++++++++++++++++-----------
sound/soc/dwc/local.h | 1 +
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
index 9ea4be56d3b7..ade5165a7087 100644
--- a/sound/soc/dwc/dwc-i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
@@ -102,6 +102,7 @@ static inline void i2s_enable_irqs(struct dw_i2s_dev *dev, u32 stream,
static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
{
+ unsigned int rxor_count;
struct dw_i2s_dev *dev = dev_id;
bool irq_valid = false;
u32 isr[4];
@@ -138,9 +139,13 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
irq_valid = true;
}
- /* Error Handling: TX */
+ /* Error Handling: RX */
if (isr[i] & ISR_RXFO) {
- dev_err_ratelimited(dev->dev, "RX overrun (ch_id=%d)\n", i);
+ rxor_count = READ_ONCE(dev->rx_overrun_count);
+ if (!(rxor_count & 0x3ff))
+ dev_dbg(dev->dev, "RX overrun (ch_id=%d)\n", i);
+ rxor_count++;
+ WRITE_ONCE(dev->rx_overrun_count, rxor_count);
irq_valid = true;
}
}
@@ -920,7 +925,8 @@ static int dw_i2s_probe(struct platform_device *pdev)
const struct i2s_platform_data *pdata = pdev->dev.platform_data;
struct dw_i2s_dev *dev;
struct resource *res;
- int ret, irq;
+ int ret, irq, irq_count;
+ unsigned idx;
struct snd_soc_dai_driver *dw_i2s_dai;
const char *clk_id;
@@ -958,16 +964,24 @@ static int dw_i2s_probe(struct platform_device *pdev)
return ret;
}
- irq = platform_get_irq_optional(pdev, 0);
- if (irq >= 0) {
- ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
- pdev->name, dev);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to request irq\n");
- goto err_assert_reset;
- }
+ irq_count = platform_irq_count(pdev);
+ if (irq_count < 0) /* - EPROBE_DEFER */
+ return irq_count;
+ else if (!irq_count) {
+ dev_err(&pdev->dev, "no IRQs found for device\n");
+ return -ENODEV;
}
+ for (idx = 0; idx < (unsigned)irq_count; idx++) {
+ irq = platform_get_irq_optional(pdev, idx);
+ if (irq >= 0) {
+ ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
+ pdev->name, dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to request irq\n");
+ return ret;
+ }
+
dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
if (pdata) {
diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h
index dce88c9ad5f3..be7a026e5f91 100644
--- a/sound/soc/dwc/local.h
+++ b/sound/soc/dwc/local.h
@@ -149,6 +149,7 @@ struct dw_i2s_dev {
bool *period_elapsed);
unsigned int tx_ptr;
unsigned int rx_ptr;
+ unsigned int rx_overrun_count;
};
#if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM)
--
2.40.1