| From 59528088dd0cf69a8829add78b723f59d988703a Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 14 Jun 2021 16:45:07 +0200 |
| Subject: spi: spi-sun6i: Fix chipselect/clock bug |
| |
| From: Mirko Vogt <mirko-dev|linux@nanl.de> |
| |
| [ Upstream commit 0d7993b234c9fad8cb6bec6adfaa74694ba85ecb ] |
| |
| The current sun6i SPI implementation initializes the transfer too early, |
| resulting in SCK going high before the transfer. When using an additional |
| (gpio) chipselect with sun6i, the chipselect is asserted at a time when |
| clock is high, making the SPI transfer fail. |
| |
| This is due to SUN6I_GBL_CTL_BUS_ENABLE being written into |
| SUN6I_GBL_CTL_REG at an early stage. Moving that to the transfer |
| function, hence, right before the transfer starts, mitigates that |
| problem. |
| |
| Fixes: 3558fe900e8af (spi: sunxi: Add Allwinner A31 SPI controller driver) |
| Signed-off-by: Mirko Vogt <mirko-dev|linux@nanl.de> |
| Signed-off-by: Ralf Schlatterbeck <rsc@runtux.com> |
| Link: https://lore.kernel.org/r/20210614144507.y3udezjfbko7eavv@runtux.com |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/spi/spi-sun6i.c | 6 +++++- |
| 1 file changed, 5 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c |
| index 19238e1b76b4..803d92f8d031 100644 |
| --- a/drivers/spi/spi-sun6i.c |
| +++ b/drivers/spi/spi-sun6i.c |
| @@ -290,6 +290,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master, |
| } |
| |
| sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); |
| + /* Finally enable the bus - doing so before might raise SCK to HIGH */ |
| + reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG); |
| + reg |= SUN6I_GBL_CTL_BUS_ENABLE; |
| + sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg); |
| |
| /* Setup the transfer now... */ |
| if (sspi->tx_buf) |
| @@ -398,7 +402,7 @@ static int sun6i_spi_runtime_resume(struct device *dev) |
| } |
| |
| sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, |
| - SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); |
| + SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); |
| |
| return 0; |
| |
| -- |
| 2.30.2 |
| |