Commit 55e77aba authored by Mark Brown's avatar Mark Brown

ASoC: rockchip: i2s: switch BCLK to GPIO

Merge series from Judy Hsiao <judyhsiao@chromium.org>:

The patches series is to fix the unexpected large DC output
voltage of Max98357a that burns the speakers on the rockchip
platform when BCLK and SD_MODE are ON but LRCLK is OFF.
parents 13d272d5 d92c3d13
...@@ -61,6 +61,13 @@ properties: ...@@ -61,6 +61,13 @@ properties:
- const: tx - const: tx
- const: rx - const: rx
pinctrl-names:
oneOf:
- const: default
- items:
- const: bclk_on
- const: bclk_off
power-domains: power-domains:
maxItems: 1 maxItems: 1
......
...@@ -65,8 +65,7 @@ static int i2s_pinctrl_select_bclk_on(struct rk_i2s_dev *i2s) ...@@ -65,8 +65,7 @@ static int i2s_pinctrl_select_bclk_on(struct rk_i2s_dev *i2s)
int ret = 0; int ret = 0;
if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_on)) if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_on))
ret = pinctrl_select_state(i2s->pinctrl, ret = pinctrl_select_state(i2s->pinctrl, i2s->bclk_on);
i2s->bclk_on);
if (ret) if (ret)
dev_err(i2s->dev, "bclk enable failed %d\n", ret); dev_err(i2s->dev, "bclk enable failed %d\n", ret);
...@@ -80,8 +79,7 @@ static int i2s_pinctrl_select_bclk_off(struct rk_i2s_dev *i2s) ...@@ -80,8 +79,7 @@ static int i2s_pinctrl_select_bclk_off(struct rk_i2s_dev *i2s)
int ret = 0; int ret = 0;
if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_off)) if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_off))
ret = pinctrl_select_state(i2s->pinctrl, ret = pinctrl_select_state(i2s->pinctrl, i2s->bclk_off);
i2s->bclk_off);
if (ret) if (ret)
dev_err(i2s->dev, "bclk disable failed %d\n", ret); dev_err(i2s->dev, "bclk disable failed %d\n", ret);
...@@ -134,41 +132,37 @@ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) ...@@ -134,41 +132,37 @@ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
spin_lock(&i2s->lock); spin_lock(&i2s->lock);
if (on) { if (on) {
ret = regmap_update_bits(i2s->regmap, I2S_DMACR, ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); I2S_DMACR_TDE_ENABLE,
I2S_DMACR_TDE_ENABLE);
if (ret < 0) if (ret < 0)
goto end; goto end;
ret = regmap_update_bits(i2s->regmap, I2S_XFER, ret = regmap_update_bits(i2s->regmap, I2S_XFER,
I2S_XFER_TXS_START | I2S_XFER_RXS_START, I2S_XFER_TXS_START | I2S_XFER_RXS_START,
I2S_XFER_TXS_START | I2S_XFER_RXS_START); I2S_XFER_TXS_START | I2S_XFER_RXS_START);
if (ret < 0) if (ret < 0)
goto end; goto end;
i2s->tx_start = true; i2s->tx_start = true;
} else { } else {
i2s->tx_start = false; i2s->tx_start = false;
ret = regmap_update_bits(i2s->regmap, I2S_DMACR, ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); I2S_DMACR_TDE_ENABLE,
I2S_DMACR_TDE_DISABLE);
if (ret < 0) if (ret < 0)
goto end; goto end;
if (!i2s->rx_start) { if (!i2s->rx_start) {
ret = regmap_update_bits(i2s->regmap, I2S_XFER, ret = regmap_update_bits(i2s->regmap, I2S_XFER,
I2S_XFER_TXS_START | I2S_XFER_TXS_START | I2S_XFER_RXS_START,
I2S_XFER_RXS_START, I2S_XFER_TXS_STOP | I2S_XFER_RXS_STOP);
I2S_XFER_TXS_STOP |
I2S_XFER_RXS_STOP);
if (ret < 0) if (ret < 0)
goto end; goto end;
udelay(150); udelay(150);
ret = regmap_update_bits(i2s->regmap, I2S_CLR, ret = regmap_update_bits(i2s->regmap, I2S_CLR,
I2S_CLR_TXC | I2S_CLR_RXC, I2S_CLR_TXC | I2S_CLR_RXC,
I2S_CLR_TXC | I2S_CLR_RXC); I2S_CLR_TXC | I2S_CLR_RXC);
if (ret < 0) if (ret < 0)
goto end; goto end;
regmap_read(i2s->regmap, I2S_CLR, &val); regmap_read(i2s->regmap, I2S_CLR, &val);
/* Should wait for clear operation to finish */ /* Should wait for clear operation to finish */
...@@ -199,37 +193,36 @@ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) ...@@ -199,37 +193,36 @@ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
spin_lock(&i2s->lock); spin_lock(&i2s->lock);
if (on) { if (on) {
ret = regmap_update_bits(i2s->regmap, I2S_DMACR, ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); I2S_DMACR_RDE_ENABLE,
I2S_DMACR_RDE_ENABLE);
if (ret < 0) if (ret < 0)
goto end; goto end;
ret = regmap_update_bits(i2s->regmap, I2S_XFER, ret = regmap_update_bits(i2s->regmap, I2S_XFER,
I2S_XFER_TXS_START | I2S_XFER_RXS_START, I2S_XFER_TXS_START | I2S_XFER_RXS_START,
I2S_XFER_TXS_START | I2S_XFER_RXS_START); I2S_XFER_TXS_START | I2S_XFER_RXS_START);
if (ret < 0) if (ret < 0)
goto end; goto end;
i2s->rx_start = true; i2s->rx_start = true;
} else { } else {
i2s->rx_start = false; i2s->rx_start = false;
ret = regmap_update_bits(i2s->regmap, I2S_DMACR, ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE); I2S_DMACR_RDE_ENABLE,
I2S_DMACR_RDE_DISABLE);
if (ret < 0) if (ret < 0)
goto end; goto end;
if (!i2s->tx_start) { if (!i2s->tx_start) {
ret = regmap_update_bits(i2s->regmap, I2S_XFER, ret = regmap_update_bits(i2s->regmap, I2S_XFER,
I2S_XFER_TXS_START | I2S_XFER_TXS_START | I2S_XFER_RXS_START,
I2S_XFER_RXS_START, I2S_XFER_TXS_STOP | I2S_XFER_RXS_STOP);
I2S_XFER_TXS_STOP |
I2S_XFER_RXS_STOP);
if (ret < 0) if (ret < 0)
goto end; goto end;
udelay(150); udelay(150);
ret = regmap_update_bits(i2s->regmap, I2S_CLR, ret = regmap_update_bits(i2s->regmap, I2S_CLR,
I2S_CLR_TXC | I2S_CLR_RXC, I2S_CLR_TXC | I2S_CLR_RXC,
I2S_CLR_TXC | I2S_CLR_RXC); I2S_CLR_TXC | I2S_CLR_RXC);
if (ret < 0) if (ret < 0)
goto end; goto end;
regmap_read(i2s->regmap, I2S_CLR, &val); regmap_read(i2s->regmap, I2S_CLR, &val);
...@@ -490,7 +483,6 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, ...@@ -490,7 +483,6 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream,
ret = rockchip_snd_rxctrl(i2s, 1); ret = rockchip_snd_rxctrl(i2s, 1);
else else
ret = rockchip_snd_txctrl(i2s, 1); ret = rockchip_snd_txctrl(i2s, 1);
/* Do not turn on bclk if lrclk open fails. */
if (ret < 0) if (ret < 0)
return ret; return ret;
i2s_pinctrl_select_bclk_on(i2s); i2s_pinctrl_select_bclk_on(i2s);
...@@ -808,24 +800,22 @@ static int rockchip_i2s_probe(struct platform_device *pdev) ...@@ -808,24 +800,22 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
i2s->bclk_ratio = 64; i2s->bclk_ratio = 64;
i2s->pinctrl = devm_pinctrl_get(&pdev->dev); i2s->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(i2s->pinctrl)) {
dev_err(&pdev->dev, "failed to find i2s pinctrl\n");
} else {
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(i2s->pinctrl)) {
if (IS_ERR_OR_NULL(i2s->bclk_off)) i2s->bclk_on = pinctrl_lookup_state(i2s->pinctrl, "bclk_on");
dev_err(&pdev->dev, "failed to find i2s gpio state\n"); if (!IS_ERR_OR_NULL(i2s->bclk_on)) {
else i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl, "bclk_off");
dev_dbg(&pdev->dev, "find i2s bclk_off state\n"); if (IS_ERR_OR_NULL(i2s->bclk_off)) {
dev_err(&pdev->dev, "failed to find i2s bclk_off\n");
i2s_pinctrl_select_bclk_off(i2s); goto err_clk;
}
}
} else {
dev_err(&pdev->dev, "failed to find i2s pinctrl\n");
} }
i2s_pinctrl_select_bclk_off(i2s);
i2s->playback_dma_data.addr = res->start + I2S_TXDR; i2s->playback_dma_data.addr = res->start + I2S_TXDR;
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->playback_dma_data.maxburst = 4; i2s->playback_dma_data.maxburst = 4;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment