From b22da3d8526a935aa31e086e63f60ff3246cb61c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 07:24:11 +0000
Subject: [PATCH] add stmac read mac form eeprom
---
kernel/sound/soc/rockchip/rockchip_i2s_tdm.c | 75 +++++++++++++++++++++++++++++++++++--
1 files changed, 70 insertions(+), 5 deletions(-)
diff --git a/kernel/sound/soc/rockchip/rockchip_i2s_tdm.c b/kernel/sound/soc/rockchip/rockchip_i2s_tdm.c
index 1824ea5..a8da138 100644
--- a/kernel/sound/soc/rockchip/rockchip_i2s_tdm.c
+++ b/kernel/sound/soc/rockchip/rockchip_i2s_tdm.c
@@ -27,6 +27,7 @@
#include <sound/dmaengine_pcm.h>
#include "rockchip_i2s_tdm.h"
+#include "rockchip_dlp.h"
#define DRV_NAME "rockchip-i2s-tdm"
@@ -266,7 +267,7 @@
writeq(val, addr);
break;
}
- /* fallthrough */
+ fallthrough;
default:
local_irq_save(flags);
writel(BIT(tx_offset) | (BIT(tx_offset) << 16),
@@ -328,7 +329,7 @@
writeq(val, addr);
break;
}
- /* fallthrough */
+ fallthrough;
default:
local_irq_save(flags);
writel((BIT(tx_offset) << 16),
@@ -395,6 +396,12 @@
default:
return -EINVAL;
}
+
+ regmap_update_bits(i2s_tdm->regmap, I2S_CLR, clr, clr);
+ ret = regmap_read_poll_timeout_atomic(i2s_tdm->regmap, I2S_CLR, val,
+ !(val & clr), 10, 100);
+ if (ret == 0)
+ return 0;
/*
* Workaround for FIFO clear on SLAVE mode:
@@ -654,6 +661,19 @@
case SND_SOC_DAIFMT_CBM_CFM:
val = I2S_CKR_MSS_SLAVE;
i2s_tdm->is_master_mode = false;
+ /*
+ * TRCM require TX/RX enabled at the same time, or need the one
+ * which provide clk enabled at first for master mode.
+ *
+ * It is quite a different for slave mode which does not have
+ * these restrictions, because the BCLK / LRCK are provided by
+ * external master devices.
+ *
+ * So, we just set the right clk path value on TRCM register on
+ * stage probe and then drop the trcm value to make TX / RX work
+ * independently.
+ */
+ i2s_tdm->clk_trcm = 0;
break;
default:
ret = -EINVAL;
@@ -924,13 +944,26 @@
switch (i2s_tdm->clk_trcm) {
case I2S_CKR_TRCM_TXONLY:
parent = clk_get_parent(i2s_tdm->mclk_tx);
+ /*
+ * API clk_has_parent is not available yet on GKI, so we
+ * use clk_set_parent directly and ignore the ret value.
+ * if the API has addressed on GKI, should remove it.
+ */
+#ifdef CONFIG_NO_GKI
if (clk_has_parent(i2s_tdm->mclk_rx, parent))
ret = clk_set_parent(i2s_tdm->mclk_rx, parent);
+#else
+ clk_set_parent(i2s_tdm->mclk_rx, parent);
+#endif
break;
case I2S_CKR_TRCM_RXONLY:
parent = clk_get_parent(i2s_tdm->mclk_rx);
+#ifdef CONFIG_NO_GKI
if (clk_has_parent(i2s_tdm->mclk_tx, parent))
ret = clk_set_parent(i2s_tdm->mclk_tx, parent);
+#else
+ clk_set_parent(i2s_tdm->mclk_tx, parent);
+#endif
break;
}
@@ -1789,6 +1822,12 @@
#ifdef CONFIG_CPU_RK3568
{ .compatible = "rockchip,rk3568-i2s-tdm", .data = &rk3568_i2s_soc_data },
#endif
+#ifdef CONFIG_CPU_RK3588
+ { .compatible = "rockchip,rk3588-i2s-tdm", },
+#endif
+#ifdef CONFIG_CPU_RV1106
+ { .compatible = "rockchip,rv1106-i2s-tdm", },
+#endif
#ifdef CONFIG_CPU_RV1126
{ .compatible = "rockchip,rv1126-i2s-tdm", .data = &rv1126_i2s_soc_data },
#endif
@@ -1998,6 +2037,28 @@
return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 1);
}
+static int rockchip_i2s_tdm_get_fifo_count(struct device *dev, int stream)
+{
+ struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+ int val = 0;
+
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ regmap_read(i2s_tdm->regmap, I2S_TXFIFOLR, &val);
+ else
+ regmap_read(i2s_tdm->regmap, I2S_RXFIFOLR, &val);
+
+ val = ((val & I2S_FIFOLR_TFL3_MASK) >> I2S_FIFOLR_TFL3_SHIFT) +
+ ((val & I2S_FIFOLR_TFL2_MASK) >> I2S_FIFOLR_TFL2_SHIFT) +
+ ((val & I2S_FIFOLR_TFL1_MASK) >> I2S_FIFOLR_TFL1_SHIFT) +
+ ((val & I2S_FIFOLR_TFL0_MASK) >> I2S_FIFOLR_TFL0_SHIFT);
+
+ return val;
+}
+
+static const struct snd_dlp_config dconfig = {
+ .get_fifo_count = rockchip_i2s_tdm_get_fifo_count,
+};
+
static irqreturn_t rockchip_i2s_tdm_isr(int irq, void *devid)
{
struct rk_i2s_tdm_dev *i2s_tdm = (struct rk_i2s_tdm_dev *)devid;
@@ -2050,7 +2111,7 @@
i2s_tdm->dev = &pdev->dev;
of_id = of_match_device(rockchip_i2s_tdm_match, &pdev->dev);
- if (!of_id || !of_id->data)
+ if (!of_id)
return -EINVAL;
spin_lock_init(&i2s_tdm->lock);
@@ -2170,7 +2231,7 @@
if (IS_ERR(i2s_tdm->regmap))
return PTR_ERR(i2s_tdm->regmap);
- irq = platform_get_irq(pdev, 0);
+ irq = platform_get_irq_optional(pdev, 0);
if (irq > 0) {
ret = devm_request_irq(&pdev->dev, irq, rockchip_i2s_tdm_isr,
IRQF_SHARED, node->name, i2s_tdm);
@@ -2264,7 +2325,11 @@
return 0;
}
- ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+ if (of_property_read_bool(node, "rockchip,digital-loopback"))
+ ret = devm_snd_dmaengine_dlp_register(&pdev->dev, &dconfig);
+ else
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+
if (ret) {
dev_err(&pdev->dev, "Could not register PCM\n");
return ret;
--
Gitblit v1.6.2