Simple gpiolib driver for TI SN65HVS885 industrial input serializer. The TI SN65HVS885 only support inputs. Signed-off-by: Sean Nyekjaer <sean.nyekjaer@xxxxxxxxx> Reviewed-by: Martin Hundebøll <martin.hundeboll@xxxxxxxxx> --- 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 --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"); -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html