Switch the driver to the gpiod api. While at it, remove the unused platform_data support. Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- drivers/spi/gpio_spi.c | 118 +++++++++++++++---------------------------------- include/spi/spi_gpio.h | 27 ----------- 2 files changed, 36 insertions(+), 109 deletions(-) diff --git a/drivers/spi/gpio_spi.c b/drivers/spi/gpio_spi.c index 36e6204283..6062bad98a 100644 --- a/drivers/spi/gpio_spi.c +++ b/drivers/spi/gpio_spi.c @@ -12,16 +12,19 @@ #include <driver.h> #include <errno.h> #include <gpio.h> +#include <linux/gpio/consumer.h> #include <init.h> #include <io.h> #include <malloc.h> #include <of_gpio.h> #include <spi/spi.h> -#include <spi/spi_gpio.h> struct gpio_spi { struct spi_master master; - struct gpio_spi_pdata *data; + struct gpio_desc *sck; + struct gpio_desc *mosi; + struct gpio_desc *miso; + struct gpio_descs *cs; }; #define priv_from_spi_device(s) container_of(s->master, struct gpio_spi, master) @@ -29,23 +32,28 @@ struct gpio_spi { static inline void setsck(const struct spi_device *spi, int is_on) { struct gpio_spi *priv = priv_from_spi_device(spi); - gpio_set_value(priv->data->sck, is_on); + + gpiod_set_value(priv->sck, is_on); } static inline void setmosi(const struct spi_device *spi, int is_on) { struct gpio_spi *priv = priv_from_spi_device(spi); - if (!gpio_is_valid(priv->data->mosi)) + + if (!priv->mosi) return; - gpio_set_value(priv->data->mosi, is_on); + + gpiod_set_value(priv->mosi, is_on); } static inline int getmiso(const struct spi_device *spi) { struct gpio_spi *priv = priv_from_spi_device(spi); - if (!gpio_is_valid(priv->data->miso)) + + if (!priv->miso) return 1; - return !!gpio_get_value(priv->data->miso); + + return !!gpiod_get_value(priv->miso); } static inline void spidelay(unsigned int nsecs) @@ -59,11 +67,13 @@ static int gpio_spi_set_cs(struct spi_device *spi, bool en) { struct gpio_spi *priv = priv_from_spi_device(spi); - if (!gpio_is_valid(priv->data->cs[spi->chip_select])) - return 0; - - gpio_set_value(priv->data->cs[spi->chip_select], - (spi->mode & SPI_CS_HIGH) ? en : !en); + /* + * Use the raw variant here. Devices using active high chip select + * either have the spi-cs-high property in the device tree or set + * SPI_CS_HIGH in their driver. + */ + gpiod_set_raw_value(priv->cs->desc[spi->chip_select], + (spi->mode & SPI_CS_HIGH) ? en : !en); return 0; } @@ -169,91 +179,35 @@ static int gpio_spi_setup(struct spi_device *spi) return 0; } -static int gpio_spi_of_probe(struct device *dev) -{ - struct device_node *np = dev->of_node; - struct gpio_spi_pdata *pdata; - int n, sck; - - if (!IS_ENABLED(CONFIG_OFDEVICE) || dev->platform_data) - return 0; - - sck = of_get_named_gpio(np, "sck-gpios", 0); - if (!gpio_is_valid(sck)) - return dev_err_probe(dev, sck < 0 ? sck : -EINVAL, - "missing mandatory SCK gpio\n"); - - pdata = xzalloc(sizeof(*pdata)); - pdata->sck = sck; - pdata->num_cs = MAX_CHIPSELECT; - - pdata->miso = of_get_named_gpio(np, "miso-gpios", 0); - if (!gpio_is_valid(pdata->miso)) - pdata->miso = SPI_GPIO_NO_MISO; - - pdata->mosi = of_get_named_gpio(np, "mosi-gpios", 0); - if (!gpio_is_valid(pdata->mosi)) - pdata->mosi = SPI_GPIO_NO_MOSI; - - for (n = 0; n < MAX_CHIPSELECT; n++) { - pdata->cs[n] = of_get_named_gpio(np, "cs-gpios", n); - if (!gpio_is_valid(pdata->cs[n])) - pdata->cs[n] = SPI_GPIO_NO_CS; - } - - dev->platform_data = pdata; - - return 0; -} - static int gpio_spi_probe(struct device *dev) { struct gpio_spi *priv; - struct gpio_spi_pdata *pdata; struct spi_master *master; - int n, ret; - - ret = gpio_spi_of_probe(dev); - if (ret) - return ret; - pdata = dev->platform_data; - ret = gpio_request_one(pdata->sck, GPIOF_DIR_OUT, "spi-sck"); - if (ret) - return ret; + priv = xzalloc(sizeof(*priv)); - if (pdata->miso != SPI_GPIO_NO_MISO) { - ret = gpio_request_one(pdata->miso, GPIOF_DIR_IN, "spi-miso"); - if (ret) - return ret; - } + priv->sck = gpiod_get(dev, "sck", GPIOD_OUT_LOW); + if (IS_ERR(priv->sck)) + return dev_err_probe(dev, PTR_ERR(priv->sck), "No SCK GPIO\n"); - if (pdata->mosi != SPI_GPIO_NO_MOSI) { - ret = gpio_request_one(pdata->mosi, GPIOF_DIR_OUT, "spi-mosi"); - if (ret) - return ret; - } + priv->miso = gpiod_get_optional(dev, "miso", GPIOD_IN); + if (IS_ERR(priv->miso)) + return dev_err_probe(dev, PTR_ERR(priv->miso), "No MISO GPIO\n"); - for (n = 0; n < pdata->num_cs; n++) { - char *cs_name; + priv->mosi = gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW); + if (IS_ERR(priv->mosi)) + return dev_err_probe(dev, PTR_ERR(priv->mosi), "No MOSI GPIO\n"); - if (!gpio_is_valid(pdata->cs[n])) - continue; + priv->cs = gpiod_get_array(dev, "cs", GPIOD_OUT_HIGH); + if (IS_ERR(priv->cs)) + return dev_err_probe(dev, PTR_ERR(priv->cs), "No CS GPIOs\n"); - cs_name = basprintf("spi-cs%d", n); - ret = gpio_request_one(pdata->cs[n], GPIOF_DIR_OUT, cs_name); - if (ret) - return ret; - } - - priv = xzalloc(sizeof(*priv)); - priv->data = pdata; master = &priv->master; master->dev = dev; master->bus_num = dev->id; master->setup = gpio_spi_setup; master->transfer = gpio_spi_transfer; - master->num_chipselect = priv->data->num_cs; + master->num_chipselect = priv->cs->ndescs; return spi_register_master(&priv->master); } diff --git a/include/spi/spi_gpio.h b/include/spi/spi_gpio.h deleted file mode 100644 index a18b7dbe07..0000000000 --- a/include/spi/spi_gpio.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * SPI master driver using generic bitbanged GPIO - * - * Sebastian Hesselbarth <sebastian.hesselbarth@xxxxxxxxx> - * - * Based on Linux driver - * Copyright (C) 2006,2008 David Brownell - */ - -#ifndef __SPI_GPIO_H -#define __SPI_GPIO_H - -#define MAX_CHIPSELECT 4 -#define SPI_GPIO_NO_CS (-1) -#define SPI_GPIO_NO_MISO (-1) -#define SPI_GPIO_NO_MOSI (-1) - -struct gpio_spi_pdata { - int sck; - int mosi; - int miso; - int cs[MAX_CHIPSELECT]; - int num_cs; -}; - -#endif -- 2.39.5