diff mbox

gpio: add TI SN65HVS885 spi industrial input serializer driver

Message ID 1440770225-10771-1-git-send-email-sean.nyekjaer@prevas.dk
State New
Headers show

Commit Message

Sean Nyekjær Aug. 28, 2015, 1:57 p.m. UTC
Simple gpiolib driver for TI SN65HVS885 industrial input serializer.
The TI SN65HVS885 only support inputs.

Signed-off-by: Sean Nyekjaer <sean.nyekjaer@prevas.dk>
Reviewed-by: Martin Hundebøll <martin.hundeboll@prevas.dk>
---
 drivers/gpio/Kconfig           |   7 +++
 drivers/gpio/Makefile          |   1 +
 drivers/gpio/gpio-sn65hvs885.c | 119 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 drivers/gpio/gpio-sn65hvs885.c
diff mbox

Patch

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b4fc9e4..f7bd926 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1011,6 +1011,13 @@  config GPIO_ZX
 	help
 	  Say yes here to support the GPIO device on ZTE ZX SoCs.
 
+config GPIO_SN65HVS885
+        tristate "Texas Instruments sn65hvs885 input serializer 8-bit shift register"
+        depends on SPI_MASTER && OF
+        help
+          Driver for Texas Instruments sn65hvs885 input serializer.
+          This provides a GPIO interface supporting inputs.
+
 endmenu
 
 menu "USB GPIO expanders"
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 558b867..b60491a 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -117,3 +117,4 @@  obj-$(CONFIG_GPIO_XTENSA)	+= gpio-xtensa.o
 obj-$(CONFIG_GPIO_ZEVIO)	+= gpio-zevio.o
 obj-$(CONFIG_GPIO_ZYNQ)		+= gpio-zynq.o
 obj-$(CONFIG_GPIO_ZX)		+= gpio-zx.o
+obj-$(CONFIG_GPIO_SN65HVS885)	+= gpio-sn65hvs885.o
diff --git a/drivers/gpio/gpio-sn65hvs885.c b/drivers/gpio/gpio-sn65hvs885.c
new file mode 100644
index 0000000..280facd
--- /dev/null
+++ b/drivers/gpio/gpio-sn65hvs885.c
@@ -0,0 +1,119 @@ 
+/*
+ * Copyright (C) 2015 Sean Nyekjaer, Prevas
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+
+#define SN65HVS885_NUMBER_GPIOS	8
+
+struct sn65hvs885_chip {
+	struct gpio_chip	gpio_chip;
+	struct mutex		lock;	/* protect from simultaneous accesses */
+};
+
+static struct sn65hvs885_chip *
+sn65hvs885_gpio_to_chip(struct gpio_chip *gc)
+{
+	return container_of(gc, struct sn65hvs885_chip, gpio_chip);
+}
+
+static int sn65hvs885_get_value(struct gpio_chip *gc, unsigned offset)
+{
+	struct sn65hvs885_chip *chip = sn65hvs885_gpio_to_chip(gc);
+	struct spi_device *spi = to_spi_device(chip->gpio_chip.dev);
+	int ret;
+	u8 pin = offset % 8;
+	u8 d8;
+	struct spi_transfer t = {
+		.rx_buf = &d8,
+		.len = 1,
+	};
+
+	mutex_lock(&chip->lock);
+	spi_sync_transfer(spi, &t, 1);
+	mutex_unlock(&chip->lock);
+	ret = (d8 >> pin) & 0x1;
+
+	return ret;
+}
+
+static int sn65hvs885_probe(struct spi_device *spi)
+{
+	struct sn65hvs885_chip *chip;
+	int ret;
+
+	spi->bits_per_word = 8;
+
+	ret = spi_setup(spi);
+	if (ret < 0)
+		return ret;
+
+	chip = devm_kzalloc(&spi->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	spi_set_drvdata(spi, chip);
+
+	chip->gpio_chip.label = spi->modalias;
+	chip->gpio_chip.get = sn65hvs885_get_value;
+	chip->gpio_chip.base = -1;
+	chip->gpio_chip.ngpio = SN65HVS885_NUMBER_GPIOS;
+	chip->gpio_chip.can_sleep = true;
+	chip->gpio_chip.dev = &spi->dev;
+	chip->gpio_chip.owner = THIS_MODULE;
+
+	mutex_init(&chip->lock);
+
+	ret = gpiochip_add(&chip->gpio_chip);
+	if (ret) {
+		mutex_destroy(&chip->lock);
+		kfree(chip);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int sn65hvs885_remove(struct spi_device *spi)
+{
+	struct sn65hvs885_chip *chip = spi_get_drvdata(spi);
+
+	gpiochip_remove(&chip->gpio_chip);
+
+	mutex_destroy(&chip->lock);
+
+	return 0;
+}
+
+static const struct spi_device_id sn65hvs885_id[] = {
+	{ "sn65hvs885", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, sn65hvs885_id);
+
+static struct spi_driver sn65hvs885_driver = {
+	.driver = {
+		.name = "sn65hvs885",
+		.owner = THIS_MODULE,
+	},
+	.probe = sn65hvs885_probe,
+	.remove = sn65hvs885_remove,
+	.id_table = sn65hvs885_id,
+};
+
+module_spi_driver(sn65hvs885_driver);
+
+MODULE_AUTHOR("Sean Nyekjaer");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("sn65hvs885 Industrial input serializer");