* [PATCH AUTOSEL 5.15 02/28] pinctrl: aspeed: Fix potential NULL dereference in aspeed_pinmux_set_mux()
[not found] <20220714042429.281816-1-sashal@kernel.org>
@ 2022-07-14 4:24 ` Sasha Levin
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 12/28] ASoC: rockchip: i2s: switch BCLK to GPIO Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2022-07-14 4:24 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Haowen Bai, Linus Walleij, Sasha Levin, andrew, joel,
linux-aspeed, openbmc, linux-gpio, linux-arm-kernel
From: Haowen Bai <baihaowen@meizu.com>
[ Upstream commit 84a85d3fef2e75b1fe9fc2af6f5267122555a1ed ]
pdesc could be null but still dereference pdesc->name and it will lead to
a null pointer access. So we move a null check before dereference.
Signed-off-by: Haowen Bai <baihaowen@meizu.com>
Link: https://lore.kernel.org/r/1650508019-22554-1-git-send-email-baihaowen@meizu.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pinctrl/aspeed/pinctrl-aspeed.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
index c94e24aadf92..83d47ff1cea8 100644
--- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c
+++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
@@ -236,11 +236,11 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
const struct aspeed_sig_expr **funcs;
const struct aspeed_sig_expr ***prios;
- pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name);
-
if (!pdesc)
return -EINVAL;
+ pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name);
+
prios = pdesc->prios;
if (!prios)
--
2.35.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH AUTOSEL 5.15 12/28] ASoC: rockchip: i2s: switch BCLK to GPIO
[not found] <20220714042429.281816-1-sashal@kernel.org>
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 02/28] pinctrl: aspeed: Fix potential NULL dereference in aspeed_pinmux_set_mux() Sasha Levin
@ 2022-07-14 4:24 ` Sasha Levin
2022-07-14 4:29 ` Chen-Yu Tsai
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 22/28] ARM: dts: stm32: use the correct clock source for CEC on stm32mp151 Sasha Levin
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 23/28] Revert "can: xilinx_can: Limit CANFD brp to 2" Sasha Levin
3 siblings, 1 reply; 6+ messages in thread
From: Sasha Levin @ 2022-07-14 4:24 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Judy Hsiao, Mark Brown, Sasha Levin, lgirdwood, perex, tiwai,
heiko, alsa-devel, linux-arm-kernel, linux-rockchip
From: Judy Hsiao <judyhsiao@chromium.org>
[ Upstream commit a5450aba737dae3ee1a64b282e609d8375d6700c ]
We discoverd that the state of BCLK on, LRCLK off and SD_MODE on
may cause the speaker melting issue. Removing LRCLK while BCLK
is present can cause unexpected output behavior including a large
DC output voltage as described in the Max98357a datasheet.
In order to:
1. prevent BCLK from turning on by other component.
2. keep BCLK and LRCLK being present at the same time
This patch switches BCLK to GPIO func before LRCLK output, and
configures BCLK func back during LRCLK is output.
Without this fix, BCLK is turned on 11 ms earlier than LRCK by the
da7219.
With this fix, BCLK is turned on only 0.4 ms earlier than LRCK by
the rockchip codec.
Signed-off-by: Judy Hsiao <judyhsiao@chromium.org>
Link: https://lore.kernel.org/r/20220615045643.3137287-1-judyhsiao@chromium.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/rockchip/rockchip_i2s.c | 160 ++++++++++++++++++++++++------
1 file changed, 129 insertions(+), 31 deletions(-)
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 2880a0537646..bde0ceaf100d 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -13,6 +13,7 @@
#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,8 +56,40 @@ 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);
@@ -93,38 +126,49 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)
return snd_soc_dai_get_drvdata(dai);
}
-static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
+static int 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) {
- regmap_update_bits(i2s->regmap, I2S_DMACR,
- I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
+ 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_XFER,
- I2S_XFER_TXS_START | I2S_XFER_RXS_START,
- I2S_XFER_TXS_START | I2S_XFER_RXS_START);
+ 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;
i2s->tx_start = true;
} else {
i2s->tx_start = false;
- regmap_update_bits(i2s->regmap, I2S_DMACR,
- I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
+ ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
+ I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
+ if (ret < 0)
+ goto end;
if (!i2s->rx_start) {
- regmap_update_bits(i2s->regmap, I2S_XFER,
- I2S_XFER_TXS_START |
- I2S_XFER_RXS_START,
- I2S_XFER_TXS_STOP |
- I2S_XFER_RXS_STOP);
+ 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;
udelay(150);
- regmap_update_bits(i2s->regmap, I2S_CLR,
- I2S_CLR_TXC | I2S_CLR_RXC,
- I2S_CLR_TXC | I2S_CLR_RXC);
+ 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_read(i2s->regmap, I2S_CLR, &val);
@@ -139,44 +183,57 @@ static void 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 void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
+static int 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) {
- regmap_update_bits(i2s->regmap, I2S_DMACR,
+ ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
+ if (ret < 0)
+ goto end;
- 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);
+ if (ret < 0)
+ goto end;
i2s->rx_start = true;
} else {
i2s->rx_start = false;
- regmap_update_bits(i2s->regmap, I2S_DMACR,
+ ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);
+ if (ret < 0)
+ goto end;
if (!i2s->tx_start) {
- 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_STOP |
I2S_XFER_RXS_STOP);
-
+ if (ret < 0)
+ goto end;
udelay(150);
- 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);
-
+ 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);
@@ -188,7 +245,12 @@ static void 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,
@@ -426,17 +488,26 @@ 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)
- rockchip_snd_rxctrl(i2s, 1);
+ ret = rockchip_snd_rxctrl(i2s, 1);
else
- rockchip_snd_txctrl(i2s, 1);
+ 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);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- rockchip_snd_rxctrl(i2s, 0);
- else
- rockchip_snd_txctrl(i2s, 0);
+ 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);
+ }
break;
default:
ret = -EINVAL;
@@ -737,6 +808,33 @@ 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");
+
+ 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);
--
2.35.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH AUTOSEL 5.15 22/28] ARM: dts: stm32: use the correct clock source for CEC on stm32mp151
[not found] <20220714042429.281816-1-sashal@kernel.org>
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 02/28] pinctrl: aspeed: Fix potential NULL dereference in aspeed_pinmux_set_mux() Sasha Levin
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 12/28] ASoC: rockchip: i2s: switch BCLK to GPIO Sasha Levin
@ 2022-07-14 4:24 ` Sasha Levin
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 23/28] Revert "can: xilinx_can: Limit CANFD brp to 2" Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2022-07-14 4:24 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Gabriel Fernandez, Alexandre Torgue, Sasha Levin, robh+dt,
krzysztof.kozlowski+dt, mcoquelin.stm32, devicetree, linux-stm32,
linux-arm-kernel
From: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
[ Upstream commit 78ece8cce1ba0c3f3e5a7c6c1b914b3794f04c44 ]
The peripheral clock of CEC is not LSE but CEC.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm/boot/dts/stm32mp151.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi
index 6992a4b0ba79..714ecd339c68 100644
--- a/arch/arm/boot/dts/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/stm32mp151.dtsi
@@ -553,7 +553,7 @@ cec: cec@40016000 {
compatible = "st,stm32-cec";
reg = <0x40016000 0x400>;
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&rcc CEC_K>, <&clk_lse>;
+ clocks = <&rcc CEC_K>, <&rcc CEC>;
clock-names = "cec", "hdmi-cec";
status = "disabled";
};
--
2.35.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH AUTOSEL 5.15 23/28] Revert "can: xilinx_can: Limit CANFD brp to 2"
[not found] <20220714042429.281816-1-sashal@kernel.org>
` (2 preceding siblings ...)
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 22/28] ARM: dts: stm32: use the correct clock source for CEC on stm32mp151 Sasha Levin
@ 2022-07-14 4:24 ` Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2022-07-14 4:24 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Srinivas Neeli, Marc Kleine-Budde, Sasha Levin, appana.durga.rao,
wg, davem, edumazet, kuba, pabeni, michal.simek, linux-can,
netdev, linux-arm-kernel
From: Srinivas Neeli <srinivas.neeli@xilinx.com>
[ Upstream commit c6da4590fe819dfe28a4f8037a8dc1e056542fb4 ]
This reverts commit 05ca14fdb6fe65614e0652d03e44b02748d25af7.
On early silicon engineering samples observed bit shrinking issue when
we use brp as 1. Hence updated brp_min as 2. As in production silicon
this issue is fixed, so reverting the patch.
Link: https://lore.kernel.org/all/20220609082433.1191060-2-srinivas.neeli@xilinx.com
Signed-off-by: Srinivas Neeli <srinivas.neeli@xilinx.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/can/xilinx_can.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index 262b783d1df8..a2e751f0ae0b 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -259,7 +259,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd2 = {
.tseg2_min = 1,
.tseg2_max = 128,
.sjw_max = 128,
- .brp_min = 2,
+ .brp_min = 1,
.brp_max = 256,
.brp_inc = 1,
};
@@ -272,7 +272,7 @@ static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = {
.tseg2_min = 1,
.tseg2_max = 16,
.sjw_max = 16,
- .brp_min = 2,
+ .brp_min = 1,
.brp_max = 256,
.brp_inc = 1,
};
--
2.35.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH AUTOSEL 5.15 12/28] ASoC: rockchip: i2s: switch BCLK to GPIO
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 12/28] ASoC: rockchip: i2s: switch BCLK to GPIO Sasha Levin
@ 2022-07-14 4:29 ` Chen-Yu Tsai
2022-07-17 23:04 ` Sasha Levin
0 siblings, 1 reply; 6+ messages in thread
From: Chen-Yu Tsai @ 2022-07-14 4:29 UTC (permalink / raw)
To: Sasha Levin
Cc: linux-kernel, stable, Judy Hsiao, Mark Brown, lgirdwood, perex,
tiwai, heiko, alsa-devel, linux-arm-kernel, linux-rockchip
Hi,
On Thu, Jul 14, 2022 at 12:25 PM Sasha Levin <sashal@kernel.org> wrote:
>
> From: Judy Hsiao <judyhsiao@chromium.org>
>
> [ Upstream commit a5450aba737dae3ee1a64b282e609d8375d6700c ]
>
> We discoverd that the state of BCLK on, LRCLK off and SD_MODE on
> may cause the speaker melting issue. Removing LRCLK while BCLK
> is present can cause unexpected output behavior including a large
> DC output voltage as described in the Max98357a datasheet.
>
> In order to:
> 1. prevent BCLK from turning on by other component.
> 2. keep BCLK and LRCLK being present at the same time
>
> This patch switches BCLK to GPIO func before LRCLK output, and
> configures BCLK func back during LRCLK is output.
>
> Without this fix, BCLK is turned on 11 ms earlier than LRCK by the
> da7219.
> With this fix, BCLK is turned on only 0.4 ms earlier than LRCK by
> the rockchip codec.
>
> Signed-off-by: Judy Hsiao <judyhsiao@chromium.org>
> Link: https://lore.kernel.org/r/20220615045643.3137287-1-judyhsiao@chromium.org
> Signed-off-by: Mark Brown <broonie@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
Please drop this one from all stable branches. It caused more problems
than it fixed and will be reverted for 5.19 [1]. The same patch, along
with a proper follow-up fix, are queued up for 5.20.
Regards
ChenYu
[1] https://lore.kernel.org/alsa-devel/20220713130451.31481-1-broonie@kernel.org/
> ---
> sound/soc/rockchip/rockchip_i2s.c | 160 ++++++++++++++++++++++++------
> 1 file changed, 129 insertions(+), 31 deletions(-)
>
> diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
> index 2880a0537646..bde0ceaf100d 100644
> --- a/sound/soc/rockchip/rockchip_i2s.c
> +++ b/sound/soc/rockchip/rockchip_i2s.c
> @@ -13,6 +13,7 @@
> #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,8 +56,40 @@ 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);
> @@ -93,38 +126,49 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)
> return snd_soc_dai_get_drvdata(dai);
> }
>
> -static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
> +static int 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) {
> - regmap_update_bits(i2s->regmap, I2S_DMACR,
> - I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
> + 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_XFER,
> - I2S_XFER_TXS_START | I2S_XFER_RXS_START,
> - I2S_XFER_TXS_START | I2S_XFER_RXS_START);
> + 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;
>
> i2s->tx_start = true;
> } else {
> i2s->tx_start = false;
>
> - regmap_update_bits(i2s->regmap, I2S_DMACR,
> - I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
> + ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
> + I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
> + if (ret < 0)
> + goto end;
>
> if (!i2s->rx_start) {
> - regmap_update_bits(i2s->regmap, I2S_XFER,
> - I2S_XFER_TXS_START |
> - I2S_XFER_RXS_START,
> - I2S_XFER_TXS_STOP |
> - I2S_XFER_RXS_STOP);
> + 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;
>
> udelay(150);
> - regmap_update_bits(i2s->regmap, I2S_CLR,
> - I2S_CLR_TXC | I2S_CLR_RXC,
> - I2S_CLR_TXC | I2S_CLR_RXC);
> + 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_read(i2s->regmap, I2S_CLR, &val);
>
> @@ -139,44 +183,57 @@ static void 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 void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
> +static int 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) {
> - regmap_update_bits(i2s->regmap, I2S_DMACR,
> + ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
> I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
> + if (ret < 0)
> + goto end;
>
> - 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);
> + if (ret < 0)
> + goto end;
>
> i2s->rx_start = true;
> } else {
> i2s->rx_start = false;
>
> - regmap_update_bits(i2s->regmap, I2S_DMACR,
> + ret = regmap_update_bits(i2s->regmap, I2S_DMACR,
> I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);
> + if (ret < 0)
> + goto end;
>
> if (!i2s->tx_start) {
> - 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_STOP |
> I2S_XFER_RXS_STOP);
> -
> + if (ret < 0)
> + goto end;
> udelay(150);
> - 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);
> -
> + 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);
> @@ -188,7 +245,12 @@ static void 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,
> @@ -426,17 +488,26 @@ 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)
> - rockchip_snd_rxctrl(i2s, 1);
> + ret = rockchip_snd_rxctrl(i2s, 1);
> else
> - rockchip_snd_txctrl(i2s, 1);
> + 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);
> break;
> case SNDRV_PCM_TRIGGER_SUSPEND:
> case SNDRV_PCM_TRIGGER_STOP:
> case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
> - rockchip_snd_rxctrl(i2s, 0);
> - else
> - rockchip_snd_txctrl(i2s, 0);
> + 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);
> + }
> break;
> default:
> ret = -EINVAL;
> @@ -737,6 +808,33 @@ 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");
> +
> + 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);
>
> --
> 2.35.1
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH AUTOSEL 5.15 12/28] ASoC: rockchip: i2s: switch BCLK to GPIO
2022-07-14 4:29 ` Chen-Yu Tsai
@ 2022-07-17 23:04 ` Sasha Levin
0 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2022-07-17 23:04 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: linux-kernel, stable, Judy Hsiao, Mark Brown, lgirdwood, perex,
tiwai, heiko, alsa-devel, linux-arm-kernel, linux-rockchip
On Thu, Jul 14, 2022 at 12:29:27PM +0800, Chen-Yu Tsai wrote:
>Hi,
>
>On Thu, Jul 14, 2022 at 12:25 PM Sasha Levin <sashal@kernel.org> wrote:
>>
>> From: Judy Hsiao <judyhsiao@chromium.org>
>>
>> [ Upstream commit a5450aba737dae3ee1a64b282e609d8375d6700c ]
>>
>> We discoverd that the state of BCLK on, LRCLK off and SD_MODE on
>> may cause the speaker melting issue. Removing LRCLK while BCLK
>> is present can cause unexpected output behavior including a large
>> DC output voltage as described in the Max98357a datasheet.
>>
>> In order to:
>> 1. prevent BCLK from turning on by other component.
>> 2. keep BCLK and LRCLK being present at the same time
>>
>> This patch switches BCLK to GPIO func before LRCLK output, and
>> configures BCLK func back during LRCLK is output.
>>
>> Without this fix, BCLK is turned on 11 ms earlier than LRCK by the
>> da7219.
>> With this fix, BCLK is turned on only 0.4 ms earlier than LRCK by
>> the rockchip codec.
>>
>> Signed-off-by: Judy Hsiao <judyhsiao@chromium.org>
>> Link: https://lore.kernel.org/r/20220615045643.3137287-1-judyhsiao@chromium.org
>> Signed-off-by: Mark Brown <broonie@kernel.org>
>> Signed-off-by: Sasha Levin <sashal@kernel.org>
>
>Please drop this one from all stable branches. It caused more problems
>than it fixed and will be reverted for 5.19 [1]. The same patch, along
>with a proper follow-up fix, are queued up for 5.20.
Now dropped, thanks!
--
Thanks,
Sasha
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-07-17 23:05 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20220714042429.281816-1-sashal@kernel.org>
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 02/28] pinctrl: aspeed: Fix potential NULL dereference in aspeed_pinmux_set_mux() Sasha Levin
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 12/28] ASoC: rockchip: i2s: switch BCLK to GPIO Sasha Levin
2022-07-14 4:29 ` Chen-Yu Tsai
2022-07-17 23:04 ` Sasha Levin
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 22/28] ARM: dts: stm32: use the correct clock source for CEC on stm32mp151 Sasha Levin
2022-07-14 4:24 ` [PATCH AUTOSEL 5.15 23/28] Revert "can: xilinx_can: Limit CANFD brp to 2" Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).