From f45e756958099c35d6afb746df1d40a1c6302cfc Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 07 Nov 2023 06:20:23 +0000
Subject: [PATCH] enable wifi gpio
---
kernel/sound/soc/rockchip/rockchip_i2s.c | 120 +++++++++++++++++++++++++++++++++---------------------------
1 files changed, 66 insertions(+), 54 deletions(-)
diff --git a/kernel/sound/soc/rockchip/rockchip_i2s.c b/kernel/sound/soc/rockchip/rockchip_i2s.c
index 262a954..5af12e4 100644
--- a/kernel/sound/soc/rockchip/rockchip_i2s.c
+++ b/kernel/sound/soc/rockchip/rockchip_i2s.c
@@ -61,6 +61,7 @@
bool is_master_mode;
const struct rk_i2s_pins *pins;
unsigned int bclk_fs;
+ spinlock_t lock; /* tx/rx lock */
unsigned int clk_trcm;
unsigned int mclk_root_rate;
@@ -69,9 +70,6 @@
bool mclk_calibrate;
};
-
-/* txctrl/rxctrl lock */
-static DEFINE_SPINLOCK(lock);
static int i2s_runtime_suspend(struct device *dev)
{
@@ -124,12 +122,51 @@
regcache_sync(i2s->regmap);
}
+static int rockchip_i2s_clear(struct rk_i2s_dev *i2s)
+{
+ unsigned int clr = I2S_CLR_TXC | I2S_CLR_RXC;
+ unsigned int val = 0;
+ int ret;
+
+ /*
+ * Workaround for FIFO clear on SLAVE mode:
+ *
+ * A Suggest to do reset hclk domain and then do mclk
+ * domain, especially for SLAVE mode without CLK in.
+ * at last, recovery regmap config.
+ *
+ * B Suggest to switch to MASTER, and then do FIFO clr,
+ * at last, bring back to SLAVE.
+ *
+ * Now we choose plan B here.
+ */
+ if (!i2s->is_master_mode)
+ regmap_update_bits(i2s->regmap, I2S_CKR,
+ I2S_CKR_MSS_MASK, I2S_CKR_MSS_MASTER);
+ regmap_update_bits(i2s->regmap, I2S_CLR, clr, clr);
+
+ ret = regmap_read_poll_timeout_atomic(i2s->regmap, I2S_CLR, val,
+ !(val & clr), 10, 100);
+ if (!i2s->is_master_mode)
+ regmap_update_bits(i2s->regmap, I2S_CKR,
+ I2S_CKR_MSS_MASK, I2S_CKR_MSS_SLAVE);
+ if (ret < 0) {
+ dev_warn(i2s->dev, "failed to clear fifo on %s mode\n",
+ i2s->is_master_mode ? "master" : "slave");
+ goto reset;
+ }
+
+ return 0;
+
+reset:
+ rockchip_i2s_reset(i2s);
+
+ return ret;
+}
+
static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
{
- unsigned int val = 0;
- int retry = 10;
-
- spin_lock(&lock);
+ spin_lock(&i2s->lock);
if (on) {
regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
@@ -153,33 +190,15 @@
I2S_XFER_RXS_STOP);
udelay(150);
- regmap_update_bits(i2s->regmap, I2S_CLR,
- I2S_CLR_TXC | I2S_CLR_RXC,
- I2S_CLR_TXC | I2S_CLR_RXC);
-
- regmap_read(i2s->regmap, I2S_CLR, &val);
-
- /* Should wait for clear operation to finish */
- while (val) {
- regmap_read(i2s->regmap, I2S_CLR, &val);
- retry--;
- if (!retry) {
- dev_warn(i2s->dev, "reset\n");
- rockchip_i2s_reset(i2s);
- break;
- }
- }
+ rockchip_i2s_clear(i2s);
}
}
- spin_unlock(&lock);
+ spin_unlock(&i2s->lock);
}
static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
{
- unsigned int val = 0;
- int retry = 10;
-
- spin_lock(&lock);
+ spin_lock(&i2s->lock);
if (on) {
regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
@@ -203,25 +222,10 @@
I2S_XFER_RXS_STOP);
udelay(150);
- regmap_update_bits(i2s->regmap, I2S_CLR,
- I2S_CLR_TXC | I2S_CLR_RXC,
- I2S_CLR_TXC | I2S_CLR_RXC);
-
- regmap_read(i2s->regmap, I2S_CLR, &val);
-
- /* Should wait for clear operation to finish */
- while (val) {
- regmap_read(i2s->regmap, I2S_CLR, &val);
- retry--;
- if (!retry) {
- dev_warn(i2s->dev, "reset\n");
- rockchip_i2s_reset(i2s);
- break;
- }
- }
+ rockchip_i2s_clear(i2s);
}
}
- spin_unlock(&lock);
+ spin_unlock(&i2s->lock);
}
static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
@@ -779,6 +783,7 @@
if (!i2s)
return -ENOMEM;
+ spin_lock_init(&i2s->lock);
i2s->dev = &pdev->dev;
i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
@@ -819,20 +824,23 @@
i2s->mclk = devm_clk_get(&pdev->dev, "i2s_clk");
if (IS_ERR(i2s->mclk)) {
dev_err(&pdev->dev, "Can't retrieve i2s master clock\n");
- return PTR_ERR(i2s->mclk);
+ ret = PTR_ERR(i2s->mclk);
+ goto err_clk;
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- regs = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(regs))
- return PTR_ERR(regs);
+ regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(regs)) {
+ ret = PTR_ERR(regs);
+ goto err_clk;
+ }
i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
&rockchip_i2s_regmap_config);
if (IS_ERR(i2s->regmap)) {
dev_err(&pdev->dev,
"Failed to initialise managed register map\n");
- return PTR_ERR(i2s->regmap);
+ ret = PTR_ERR(i2s->regmap);
+ goto err_clk;
}
i2s->playback_dma_data.addr = res->start + I2S_TXDR;
@@ -901,8 +909,11 @@
goto err_suspend;
}
- if (of_property_read_bool(node, "rockchip,no-dmaengine"))
- return ret;
+ if (of_property_read_bool(node, "rockchip,no-dmaengine")) {
+ dev_info(&pdev->dev, "Used for Multi-DAI\n");
+ return 0;
+ }
+
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (ret) {
dev_err(&pdev->dev, "Could not register PCM\n");
@@ -916,7 +927,8 @@
i2s_runtime_suspend(&pdev->dev);
err_pm_disable:
pm_runtime_disable(&pdev->dev);
-
+err_clk:
+ clk_disable_unprepare(i2s->hclk);
return ret;
}
--
Gitblit v1.6.2