Commit 101a68e7 authored by Linus Walleij's avatar Linus Walleij Committed by Mark Brown

spi: davinci: Convert to use CS GPIO descriptors

This converts the DaVinci SPI master driver to use GPIO
descriptors for chip select handling.

DaVinci parses the device tree a second time for the chip
select GPIOs (no relying on the parsing already happening
in the SPI core) and handles inversion semantics locally.

We simply drop the extra parsing and set up and move the
CS handling to the core and gpiolib. The fact that the
driver is actively driving the GPIO in the
davinci_spi_chipselect() callback is confusing since the
host does not set SPI_MASTER_GPIO_SS so this should not
ever get called when using GPIO CS. I put in a comment
about this.

This driver also supports instantiation from board files,
but these are all using native chip selects so no problem
with GPIO lines here.

Cc: David Lechner <david@lechnology.com>
Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Cc: Linuxarm <linuxarm@huawei.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 054320b2
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h> #include <linux/spi/spi_bitbang.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -222,12 +221,17 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) ...@@ -222,12 +221,17 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
* Board specific chip select logic decides the polarity and cs * Board specific chip select logic decides the polarity and cs
* line for the controller * line for the controller
*/ */
if (spi->cs_gpio >= 0) { if (spi->cs_gpiod) {
/*
* FIXME: is this code ever executed? This host does not
* set SPI_MASTER_GPIO_SS so this chipselect callback should
* not get called from the SPI core when we are using
* GPIOs for chip select.
*/
if (value == BITBANG_CS_ACTIVE) if (value == BITBANG_CS_ACTIVE)
gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH); gpiod_set_value(spi->cs_gpiod, 1);
else else
gpio_set_value(spi->cs_gpio, gpiod_set_value(spi->cs_gpiod, 0);
!(spi->mode & SPI_CS_HIGH));
} else { } else {
if (value == BITBANG_CS_ACTIVE) { if (value == BITBANG_CS_ACTIVE) {
if (!(spi->mode & SPI_CS_WORD)) if (!(spi->mode & SPI_CS_WORD))
...@@ -418,7 +422,6 @@ static int davinci_spi_of_setup(struct spi_device *spi) ...@@ -418,7 +422,6 @@ static int davinci_spi_of_setup(struct spi_device *spi)
*/ */
static int davinci_spi_setup(struct spi_device *spi) static int davinci_spi_setup(struct spi_device *spi)
{ {
int retval = 0;
struct davinci_spi *dspi; struct davinci_spi *dspi;
struct spi_master *master = spi->master; struct spi_master *master = spi->master;
struct device_node *np = spi->dev.of_node; struct device_node *np = spi->dev.of_node;
...@@ -427,21 +430,11 @@ static int davinci_spi_setup(struct spi_device *spi) ...@@ -427,21 +430,11 @@ static int davinci_spi_setup(struct spi_device *spi)
dspi = spi_master_get_devdata(spi->master); dspi = spi_master_get_devdata(spi->master);
if (!(spi->mode & SPI_NO_CS)) { if (!(spi->mode & SPI_NO_CS)) {
if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) { if (np && spi->cs_gpiod)
retval = gpio_direction_output(
spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
internal_cs = false; internal_cs = false;
}
if (retval) {
dev_err(&spi->dev, "GPIO %d setup failed (%d)\n",
spi->cs_gpio, retval);
return retval;
}
if (internal_cs) { if (internal_cs)
set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select);
}
} }
if (spi->mode & SPI_READY) if (spi->mode & SPI_READY)
...@@ -962,6 +955,7 @@ static int davinci_spi_probe(struct platform_device *pdev) ...@@ -962,6 +955,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
if (ret) if (ret)
goto free_master; goto free_master;
master->use_gpio_descriptors = true;
master->dev.of_node = pdev->dev.of_node; master->dev.of_node = pdev->dev.of_node;
master->bus_num = pdev->id; master->bus_num = pdev->id;
master->num_chipselect = pdata->num_chipselect; master->num_chipselect = pdata->num_chipselect;
...@@ -980,27 +974,6 @@ static int davinci_spi_probe(struct platform_device *pdev) ...@@ -980,27 +974,6 @@ static int davinci_spi_probe(struct platform_device *pdev)
if (dspi->version == SPI_VERSION_2) if (dspi->version == SPI_VERSION_2)
dspi->bitbang.flags |= SPI_READY; dspi->bitbang.flags |= SPI_READY;
if (pdev->dev.of_node) {
int i;
for (i = 0; i < pdata->num_chipselect; i++) {
int cs_gpio = of_get_named_gpio(pdev->dev.of_node,
"cs-gpios", i);
if (cs_gpio == -EPROBE_DEFER) {
ret = cs_gpio;
goto free_clk;
}
if (gpio_is_valid(cs_gpio)) {
ret = devm_gpio_request(&pdev->dev, cs_gpio,
dev_name(&pdev->dev));
if (ret)
goto free_clk;
}
}
}
dspi->bitbang.txrx_bufs = davinci_spi_bufs; dspi->bitbang.txrx_bufs = davinci_spi_bufs;
ret = davinci_spi_request_dma(dspi); ret = davinci_spi_request_dma(dspi);
......
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