forked from Minki/linux
ASoC: rockchip-i2s: Undo BCLK pinctrl changes
The version of the BCLK pinctrl management changes that made it into v5.19 has caused problems on some systems due to overly strict DT requirements but attempts to fix it have caused further breakage on other platforms. Just drop the changes for this release, we already have a better version queued for -next. Fixes:26b9f2fa7b
("ASoC: rockchip: i2s: Fix NULL pointer dereference when pinctrl is not found") Fixes:a5450aba73
("ASoC: rockchip: i2s: switch BCLK to GPIO") Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20220713130451.31481-1-broonie@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
26b9f2fa7b
commit
1e347f861d
@ -13,7 +13,6 @@
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spinlock.h>
|
||||
@ -55,40 +54,8 @@ struct rk_i2s_dev {
|
||||
const struct rk_i2s_pins *pins;
|
||||
unsigned int bclk_ratio;
|
||||
spinlock_t lock; /* tx/rx lock */
|
||||
struct pinctrl *pinctrl;
|
||||
struct pinctrl_state *bclk_on;
|
||||
struct pinctrl_state *bclk_off;
|
||||
};
|
||||
|
||||
static int i2s_pinctrl_select_bclk_on(struct rk_i2s_dev *i2s)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_on))
|
||||
ret = pinctrl_select_state(i2s->pinctrl,
|
||||
i2s->bclk_on);
|
||||
|
||||
if (ret)
|
||||
dev_err(i2s->dev, "bclk enable failed %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2s_pinctrl_select_bclk_off(struct rk_i2s_dev *i2s)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_off))
|
||||
ret = pinctrl_select_state(i2s->pinctrl,
|
||||
i2s->bclk_off);
|
||||
|
||||
if (ret)
|
||||
dev_err(i2s->dev, "bclk disable failed %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2s_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct rk_i2s_dev *i2s = dev_get_drvdata(dev);
|
||||
@ -125,49 +92,38 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)
|
||||
return snd_soc_dai_get_drvdata(dai);
|
||||
}
|
||||
|
||||
static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
|
||||
static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
int retry = 10;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock(&i2s->lock);
|
||||
if (on) {
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
|
||||
I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
regmap_update_bits(i2s->regmap, I2S_DMACR,
|
||||
I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
|
||||
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_XFER,
|
||||
I2S_XFER_TXS_START | I2S_XFER_RXS_START,
|
||||
I2S_XFER_TXS_START | I2S_XFER_RXS_START);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
regmap_update_bits(i2s->regmap, I2S_XFER,
|
||||
I2S_XFER_TXS_START | I2S_XFER_RXS_START,
|
||||
I2S_XFER_TXS_START | I2S_XFER_RXS_START);
|
||||
|
||||
i2s->tx_start = true;
|
||||
} else {
|
||||
i2s->tx_start = false;
|
||||
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
|
||||
I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
regmap_update_bits(i2s->regmap, I2S_DMACR,
|
||||
I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
|
||||
|
||||
if (!i2s->rx_start) {
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_XFER,
|
||||
I2S_XFER_TXS_START |
|
||||
I2S_XFER_RXS_START,
|
||||
I2S_XFER_TXS_STOP |
|
||||
I2S_XFER_RXS_STOP);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
regmap_update_bits(i2s->regmap, I2S_XFER,
|
||||
I2S_XFER_TXS_START |
|
||||
I2S_XFER_RXS_START,
|
||||
I2S_XFER_TXS_STOP |
|
||||
I2S_XFER_RXS_STOP);
|
||||
|
||||
udelay(150);
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_CLR,
|
||||
I2S_CLR_TXC | I2S_CLR_RXC,
|
||||
I2S_CLR_TXC | I2S_CLR_RXC);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
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);
|
||||
|
||||
@ -182,57 +138,44 @@ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
spin_unlock(&i2s->lock);
|
||||
if (ret < 0)
|
||||
dev_err(i2s->dev, "lrclk update failed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
|
||||
static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
int retry = 10;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock(&i2s->lock);
|
||||
if (on) {
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
|
||||
regmap_update_bits(i2s->regmap, I2S_DMACR,
|
||||
I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_XFER,
|
||||
regmap_update_bits(i2s->regmap, I2S_XFER,
|
||||
I2S_XFER_TXS_START | I2S_XFER_RXS_START,
|
||||
I2S_XFER_TXS_START | I2S_XFER_RXS_START);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
i2s->rx_start = true;
|
||||
} else {
|
||||
i2s->rx_start = false;
|
||||
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
|
||||
regmap_update_bits(i2s->regmap, I2S_DMACR,
|
||||
I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
if (!i2s->tx_start) {
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_XFER,
|
||||
regmap_update_bits(i2s->regmap, I2S_XFER,
|
||||
I2S_XFER_TXS_START |
|
||||
I2S_XFER_RXS_START,
|
||||
I2S_XFER_TXS_STOP |
|
||||
I2S_XFER_RXS_STOP);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
udelay(150);
|
||||
ret = regmap_update_bits(i2s->regmap, I2S_CLR,
|
||||
regmap_update_bits(i2s->regmap, I2S_CLR,
|
||||
I2S_CLR_TXC | I2S_CLR_RXC,
|
||||
I2S_CLR_TXC | I2S_CLR_RXC);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
regmap_read(i2s->regmap, I2S_CLR, &val);
|
||||
|
||||
/* Should wait for clear operation to finish */
|
||||
while (val) {
|
||||
regmap_read(i2s->regmap, I2S_CLR, &val);
|
||||
@ -244,12 +187,7 @@ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
spin_unlock(&i2s->lock);
|
||||
if (ret < 0)
|
||||
dev_err(i2s->dev, "lrclk update failed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
|
||||
@ -487,26 +425,17 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream,
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
|
||||
ret = rockchip_snd_rxctrl(i2s, 1);
|
||||
rockchip_snd_rxctrl(i2s, 1);
|
||||
else
|
||||
ret = rockchip_snd_txctrl(i2s, 1);
|
||||
/* Do not turn on bclk if lrclk open fails. */
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
i2s_pinctrl_select_bclk_on(i2s);
|
||||
rockchip_snd_txctrl(i2s, 1);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
if (!i2s->tx_start)
|
||||
i2s_pinctrl_select_bclk_off(i2s);
|
||||
ret = rockchip_snd_rxctrl(i2s, 0);
|
||||
} else {
|
||||
if (!i2s->rx_start)
|
||||
i2s_pinctrl_select_bclk_off(i2s);
|
||||
ret = rockchip_snd_txctrl(i2s, 0);
|
||||
}
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
|
||||
rockchip_snd_rxctrl(i2s, 0);
|
||||
else
|
||||
rockchip_snd_txctrl(i2s, 0);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
@ -807,36 +736,6 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
i2s->bclk_ratio = 64;
|
||||
i2s->pinctrl = devm_pinctrl_get(&pdev->dev);
|
||||
if (IS_ERR(i2s->pinctrl)) {
|
||||
dev_err(&pdev->dev, "failed to find i2s pinctrl\n");
|
||||
ret = PTR_ERR(i2s->pinctrl);
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
i2s->bclk_on = pinctrl_lookup_state(i2s->pinctrl,
|
||||
"bclk_on");
|
||||
if (IS_ERR_OR_NULL(i2s->bclk_on))
|
||||
dev_err(&pdev->dev, "failed to find i2s default state\n");
|
||||
else
|
||||
dev_dbg(&pdev->dev, "find i2s bclk state\n");
|
||||
|
||||
i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl,
|
||||
"bclk_off");
|
||||
if (IS_ERR_OR_NULL(i2s->bclk_off))
|
||||
dev_err(&pdev->dev, "failed to find i2s gpio state\n");
|
||||
else
|
||||
dev_dbg(&pdev->dev, "find i2s bclk_off state\n");
|
||||
|
||||
i2s_pinctrl_select_bclk_off(i2s);
|
||||
|
||||
i2s->playback_dma_data.addr = res->start + I2S_TXDR;
|
||||
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
i2s->playback_dma_data.maxburst = 4;
|
||||
|
||||
i2s->capture_dma_data.addr = res->start + I2S_RXDR;
|
||||
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
i2s->capture_dma_data.maxburst = 4;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, i2s);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user