[PATCH v2 5/5] spi: spi-gpio: switch to gpiod api

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux