From: Sean Nyekjaer <sean.nyekjaer@prevas.dk>
To: linux-gpio@vger.kernel.org
Cc: Sean Nyekjaer <sean.nyekjaer@prevas.dk>, devicetree@vger.kernel.org
Subject: [PATCH v4 1/2] gpio: add TI SN65HVS885 spi industrial input serializer driver
Date: Thu, 21 Jan 2016 07:41:35 +0100 [thread overview]
Message-ID: <1453358496-4902-1-git-send-email-sean.nyekjaer@prevas.dk> (raw)
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>
---
Changes since v3:
- none
Changes since v2:
- Wrong SPI mode. The correct mode is MODE 0
drivers/gpio/Kconfig | 9 ++-
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-sn65hvs885.c | 144 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 152 insertions(+), 2 deletions(-)
create mode 100644 drivers/gpio/gpio-sn65hvs885.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index cb212eb..d320f50 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1018,6 +1018,13 @@ config GPIO_MC33880
SPI driver for Freescale MC33880 high-side/low-side switch.
This provides GPIO interface supporting inputs and outputs.
+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 "SPI or I2C GPIO expanders"
@@ -1031,8 +1038,6 @@ config GPIO_MCP23S08
This provides a GPIO interface supporting inputs and outputs.
The I2C versions of the chips can be used as interrupt-controller.
-endmenu
-
menu "USB GPIO expanders"
depends on USB
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 548e9b5..db7d035 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -120,3 +120,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..6dceecc
--- /dev/null
+++ b/drivers/gpio/gpio-sn65hvs885.c
@@ -0,0 +1,144 @@
+/*
+ * 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;
+ int latch_gpio;
+ 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 % SN65HVS885_NUMBER_GPIOS;
+ u8 d8;
+ struct spi_transfer t = {
+ .rx_buf = &d8,
+ .len = 1,
+ };
+
+ if (gpio_is_valid(chip->latch_gpio)) {
+ gpio_set_value_cansleep(chip->latch_gpio, 0);
+ gpio_set_value_cansleep(chip->latch_gpio, 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);
+
+ chip->latch_gpio = of_get_named_gpio(spi->dev.of_node, "latch-gpio", 0);
+ if (chip->latch_gpio < 0) {
+ dev_err(&spi->dev, "latch-gpio property not found\n");
+ return -ENODEV;
+ }
+
+ if (gpio_is_valid(chip->latch_gpio)) {
+ ret = devm_gpio_request_one(&spi->dev,
+ chip->latch_gpio,
+ GPIOF_OUT_INIT_HIGH, "gpio-latch");
+ if (ret) {
+ dev_err(&spi->dev, "unable to get latch gpio\n");
+ return -ENODEV;
+ }
+ }
+
+ ret = gpiochip_add(&chip->gpio_chip);
+
+ if (ret != 0) {
+ mutex_destroy(&chip->lock);
+ devm_gpio_free(&spi->dev, chip->latch_gpio);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int sn65hvs885_remove(struct spi_device *spi)
+{
+ struct sn65hvs885_chip *chip = spi_get_drvdata(spi);
+
+ devm_gpio_free(&spi->dev, chip->latch_gpio);
+
+ 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 <sean.nyekjaer@prevas.dk>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("sn65hvs885 Industrial input serializer");
--
2.7.0
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next reply other threads:[~2016-01-21 6:41 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-21 6:41 Sean Nyekjaer [this message]
2016-01-21 6:41 ` [PATCH v4 2/2] gpio: sn65hvs885: Add DT binding documentation Sean Nyekjaer
2016-01-22 16:01 ` Rob Herring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1453358496-4902-1-git-send-email-sean.nyekjaer@prevas.dk \
--to=sean.nyekjaer@prevas.dk \
--cc=devicetree@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).