diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2019-12-05 00:32:30 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-12-10 10:56:53 +0100 |
commit | 453a4b6d8e1bdff2b8e1f56f4b8a8ef6d36b0e77 (patch) | |
tree | f73ac7fe244e18d761349b8a0fae806119c72fd3 /drivers/staging/fbtft | |
parent | 1184fd9966702a5a1cea73bdb6fe646b961c387c (diff) | |
download | lwn-453a4b6d8e1bdff2b8e1f56f4b8a8ef6d36b0e77.tar.gz lwn-453a4b6d8e1bdff2b8e1f56f4b8a8ef6d36b0e77.zip |
staging: fbtft: Do not hardcode SPI CS polarity inversion
The current use of the mode flag SPI_CS_HIGH is fragile: it
overwrites anything already assigned by the SPI core.
Assign ^= SPI_CS_HIGH since we might be active high
already, and that is usually the case with GPIOs used
for chip select, even if they are in practice active low.
Add a comment clarifying why ^= SPI_CS_HIGH is the right
choice here.
Reported-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20191204233230.22309-1-linus.walleij@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/fbtft')
-rw-r--r-- | drivers/staging/fbtft/fb_uc1611.c | 12 | ||||
-rw-r--r-- | drivers/staging/fbtft/fb_watterott.c | 13 |
2 files changed, 19 insertions, 6 deletions
diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c index e763205e9e4f..f61e373c75e9 100644 --- a/drivers/staging/fbtft/fb_uc1611.c +++ b/drivers/staging/fbtft/fb_uc1611.c @@ -63,11 +63,17 @@ static int init_display(struct fbtft_par *par) { int ret; - /* Set CS active high */ - par->spi->mode |= SPI_CS_HIGH; + /* + * Set CS active inverse polarity: just setting SPI_CS_HIGH does not + * work with GPIO based chip selects that are logically active high + * but inverted inside the GPIO library, so enforce inverted + * semantics. + */ + par->spi->mode ^= SPI_CS_HIGH; ret = spi_setup(par->spi); if (ret) { - dev_err(par->info->device, "Could not set SPI_CS_HIGH\n"); + dev_err(par->info->device, + "Could not set inverse CS polarity\n"); return ret; } diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c index 27cc8eabcbe9..76b25df376b8 100644 --- a/drivers/staging/fbtft/fb_watterott.c +++ b/drivers/staging/fbtft/fb_watterott.c @@ -150,10 +150,17 @@ static int init_display(struct fbtft_par *par) /* enable SPI interface by having CS and MOSI low during reset */ save_mode = par->spi->mode; - par->spi->mode |= SPI_CS_HIGH; - ret = spi_setup(par->spi); /* set CS inactive low */ + /* + * Set CS active inverse polarity: just setting SPI_CS_HIGH does not + * work with GPIO based chip selects that are logically active high + * but inverted inside the GPIO library, so enforce inverted + * semantics. + */ + par->spi->mode ^= SPI_CS_HIGH; + ret = spi_setup(par->spi); if (ret) { - dev_err(par->info->device, "Could not set SPI_CS_HIGH\n"); + dev_err(par->info->device, + "Could not set inverse CS polarity\n"); return ret; } write_reg(par, 0x00); /* make sure mode is set */ |