* Re: [PATCH] GPIO: add support for NXP 74HC164 GPIO expander
@ 2010-08-28 23:18 David Brownell
2010-08-29 10:10 ` Willy Tarreau
0 siblings, 1 reply; 9+ messages in thread
From: David Brownell @ 2010-08-28 23:18 UTC (permalink / raw)
To: linux-kernel, akpm, Samuel Ortiz, Miguel Gaio, Juhos Gabor,
David Brownell, Florian Fainelli
--- On Sat, 8/28/10, Florian Fainelli <florian@openwrt.org> wrote:
> This patch adds support for
> NXP's 74HC164 GPIO expander.
The 74164 parts are standard 74xxx series
discrete logic parts sold by many vendors
as 8 bit shift registers ... and in many
logic series (HC, HCT, more).
At least describe this as generic to all
those 8-bit shift registers, not just NXP.
And not as "GPIO expanders"; data sheets
describe them as shift registers. Kconfig
can say that the shift registers are being
used for GPIO (output) expansion.
I suppose it's reasonable not to support the
way these chips can be daisy-chained, but it'd
be worth a comment, IMO; that strikes me as a
think someone will add at some point, via some
platform data (e.g.32 GPIO outputs from 4 chips).
- Dave
p.s. I'd have to pull out my data sheet collection
to verify, but it might be the 74163 which can
be used as an 8 bit parallel to serial (input)
shift register...
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH] GPIO: add support for NXP 74HC164 GPIO expander 2010-08-28 23:18 [PATCH] GPIO: add support for NXP 74HC164 GPIO expander David Brownell @ 2010-08-29 10:10 ` Willy Tarreau 2010-08-29 15:37 ` [PATCH v2] GPIO: add support for 74HC164 serial-in/parallel-out 8-bit shift register Florian Fainelli 0 siblings, 1 reply; 9+ messages in thread From: Willy Tarreau @ 2010-08-29 10:10 UTC (permalink / raw) To: David Brownell Cc: linux-kernel, akpm, Samuel Ortiz, Miguel Gaio, Juhos Gabor, David Brownell, Florian Fainelli On Sat, Aug 28, 2010 at 04:18:51PM -0700, David Brownell wrote: > > --- On Sat, 8/28/10, Florian Fainelli <florian@openwrt.org> wrote: > > > This patch adds support for > > NXP's 74HC164 GPIO expander. > > The 74164 parts are standard 74xxx series > discrete logic parts sold by many vendors > as 8 bit shift registers ... and in many > logic series (HC, HCT, more). > > At least describe this as generic to all > those 8-bit shift registers, not just NXP. Indeed, that was my concern too. (...) > p.s. I'd have to pull out my data sheet collection > to verify, but it might be the 74163 which can > be used as an 8 bit parallel to serial (input) > shift register... no, it's the 74165. But it would be worth supporting both ! Willy ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2] GPIO: add support for 74HC164 serial-in/parallel-out 8-bit shift register 2010-08-29 10:10 ` Willy Tarreau @ 2010-08-29 15:37 ` Florian Fainelli 2010-08-30 23:43 ` David Brownell 0 siblings, 1 reply; 9+ messages in thread From: Florian Fainelli @ 2010-08-29 15:37 UTC (permalink / raw) To: Willy Tarreau Cc: David Brownell, linux-kernel, akpm, Samuel Ortiz, Miguel Gaio, Juhos Gabor, David Brownell Hi, Here is the second version of the patch: -- From: Miguel Gaio <miguel.gaio@efixo.com> This patch adds support for generic 74HC164 serial-in/parallel-out 8-bits shift register. This driver can be used as a GPIO output expander. Signed-off-by: Miguel Gaio <miguel.gaio@efixo.com> Signed-off-by: Juhos Gabor <juhosg@openwrt.org> Signed-off-by: Florian Fainelli <florian@openwrt.org> --- Changes since v1: - renamed nxp_ to gen_ since this driver is generic to all 74HC164 chips - added comment on this driver not handling the 74HC164 daisy-chaining - renamed misused GPIO expanders to Shift registers diff --git a/drivers/gpio/74hc164.c b/drivers/gpio/74hc164.c new file mode 100644 index 0000000..fa63215 --- /dev/null +++ b/drivers/gpio/74hc164.c @@ -0,0 +1,228 @@ +/* + * 74HC164 - Serial-in/parallel-out 8-bits shift register GPIO driver + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> + * + * 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. + * + * Note: this driver does not support the way 74HC164 chips can be + * daisy-chained. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/gpio.h> +#include <linux/bitops.h> +#include <linux/platform_device.h> +#include <linux/74hc164.h> + +#define GEN_74HC164_NUM_GPIOS 8 + +struct gen_74hc164_chip { + struct device *parent; + struct gpio_chip gpio_chip; + struct mutex lock; + long mask; +}; + +static void gen_74hc164_set_value(struct gpio_chip *, unsigned, int); + +static struct gen_74hc164_chip *gpio_to_chip(struct gpio_chip *gc) +{ + return container_of(gc, struct gen_74hc164_chip, gpio_chip); +} + +static int gen_74hc164_direction_input(struct gpio_chip *gc, unsigned offset) +{ + WARN_ON(1); + return -EINVAL; +} + +static int gen_74hc164_direction_output(struct gpio_chip *gc, + unsigned offset, int val) +{ + gen_74hc164_set_value(gc, offset, val); + return 0; +} + +static int gen_74hc164_get_value(struct gpio_chip *gc, unsigned offset) +{ + struct gen_74hc164_chip *chip = gpio_to_chip(gc); + int ret; + + mutex_lock(&chip->lock); + ret = test_bit(offset, &chip->mask); + mutex_unlock(&chip->lock); + + return ret; +} + +static void gen_74hc164_set_value(struct gpio_chip *gc, + unsigned offset, int val) +{ + struct gen_74hc164_chip *chip; + struct gen_74hc164_platform_data *pdata; + long mask; + int refresh; + int i; + + chip = gpio_to_chip(gc); + pdata = chip->parent->platform_data; + + mutex_lock(&chip->lock); + if (val) + refresh = (test_and_set_bit(offset, &chip->mask) != val); + else + refresh = (test_and_clear_bit(offset, &chip->mask) != val); + + if (refresh) { + mask = chip->mask; + for (i = 8; i > 0; --i, mask <<= 1) { + gpio_set_value(pdata->gpio_pin_data, mask & 0x80); + gpio_set_value(pdata->gpio_pin_clk, 1); + gpio_set_value(pdata->gpio_pin_clk, 0); + } + } + mutex_unlock(&chip->lock); +} + +static int __devinit gen_74hc164_probe(struct platform_device *pdev) +{ + struct gen_74hc164_platform_data *pdata; + struct gen_74hc164_chip *chip; + struct gpio_chip *gc; + int err; + + pdata = pdev->dev.platform_data; + if (pdata == NULL) { + dev_dbg(&pdev->dev, "no platform data specified\n"); + return -EINVAL; + } + + chip = kzalloc(sizeof(struct gen_74hc164_chip), GFP_KERNEL); + if (chip == NULL) { + dev_err(&pdev->dev, "no memory for private data\n"); + return -ENOMEM; + } + + err = gpio_request(pdata->gpio_pin_clk, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_clk, err); + goto err_free_chip; + } + + err = gpio_request(pdata->gpio_pin_data, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_data, err); + goto err_free_clk; + } + + err = gpio_direction_output(pdata->gpio_pin_clk, 0); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_clk, err); + goto err_free_data; + } + + err = gpio_direction_output(pdata->gpio_pin_data, 0); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_data, err); + goto err_free_data; + } + + chip->parent = &pdev->dev; + mutex_init(&chip->lock); + + gc = &chip->gpio_chip; + + gc->direction_input = gen_74hc164_direction_input; + gc->direction_output = gen_74hc164_direction_output; + gc->get = gen_74hc164_get_value; + gc->set = gen_74hc164_set_value; + gc->can_sleep = 1; + + gc->base = pdata->gpio_base; + gc->ngpio = GEN_74HC164_NUM_GPIOS; + gc->label = dev_name(chip->parent); + gc->dev = chip->parent; + gc->owner = THIS_MODULE; + + err = gpiochip_add(&chip->gpio_chip); + if (err) { + dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); + goto err_free_data; + } + + platform_set_drvdata(pdev, chip); + return 0; + +err_free_data: + gpio_free(pdata->gpio_pin_data); +err_free_clk: + gpio_free(pdata->gpio_pin_clk); +err_free_chip: + kfree(chip); + return err; +} + +static int gen_74hc164_remove(struct platform_device *pdev) +{ + struct gen_74hc164_chip *chip = platform_get_drvdata(pdev); + struct gen_74hc164_platform_data *pdata = pdev->dev.platform_data; + + if (chip) { + int err; + + err = gpiochip_remove(&chip->gpio_chip); + if (err) { + dev_err(&pdev->dev, + "unable to remove gpio chip, err=%d\n", + err); + return err; + } + + gpio_free(pdata->gpio_pin_clk); + gpio_free(pdata->gpio_pin_data); + + kfree(chip); + platform_set_drvdata(pdev, NULL); + } + + return 0; +} + +static struct platform_driver gen_74hc164_driver = { + .probe = gen_74hc164_probe, + .remove = __devexit_p(gen_74hc164_remove), + .driver = { + .name = GEN_74HC164_DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init gen_74hc164_init(void) +{ + return platform_driver_register(&gen_74hc164_driver); +} +subsys_initcall(gen_74hc164_init); + +static void __exit gen_74hc164_exit(void) +{ + platform_driver_unregister(&gen_74hc164_driver); +} +module_exit(gen_74hc164_exit); + +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); +MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); +MODULE_DESCRIPTION("GPIO expander driver for 74HC164 8-bits shift register"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" GEN_74HC164_DRIVER_NAME); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 510aa20..ec27ab6 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -361,4 +361,13 @@ config GPIO_JANZ_TTL This driver provides support for driving the pins in output mode only. Input mode is not supported. +comment "Shift registers:" + +config GPIO_74HC164 + tristate "74HC164 serial-in/parallel-out 8-bit shift register" + help + Platform driver for 74HC164 serial-in/parallel-out 8-outputs shift + registers. This driver can be used to provide access to more gpio + outputs. + endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fc6019d..2fcb2b8 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_GPIO_MAX7301) += max7301.o obj-$(CONFIG_GPIO_MAX732X) += max732x.o obj-$(CONFIG_GPIO_MC33880) += mc33880.o obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o +obj-$(CONFIG_GPIO_74HC164) += 74hc164.o obj-$(CONFIG_GPIO_PCA953X) += pca953x.o obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o obj-$(CONFIG_GPIO_PL061) += pl061.o diff --git a/include/linux/74hc164.h b/include/linux/74hc164.h new file mode 100644 index 0000000..dae3d46 --- /dev/null +++ b/include/linux/74hc164.h @@ -0,0 +1,22 @@ +/* + * 74HC164 - Serial-in/parallel-out 8-bits shift register + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * + * 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. + */ + +#ifndef __74HC164_H +#define __74HC164_H + +#define GEN_74HC164_DRIVER_NAME "74hc164" + +struct gen_74hc164_platform_data { + unsigned gpio_base; + unsigned gpio_pin_data; + unsigned gpio_pin_clk; +}; + +#endif /* __74HC164_H */ ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2] GPIO: add support for 74HC164 serial-in/parallel-out 8-bit shift register 2010-08-29 15:37 ` [PATCH v2] GPIO: add support for 74HC164 serial-in/parallel-out 8-bit shift register Florian Fainelli @ 2010-08-30 23:43 ` David Brownell 2010-08-31 8:17 ` Florian Fainelli 0 siblings, 1 reply; 9+ messages in thread From: David Brownell @ 2010-08-30 23:43 UTC (permalink / raw) To: Willy Tarreau, Florian Fainelli Cc: linux-kernel, akpm, Samuel Ortiz, Miguel Gaio, Juhos Gabor, dbrownell generic to all > 74HC164 chips Not just HC-series logic, also HCT, AC, etc (as I noted previously). I'm glad you took NXP (one of the N vendors) out of the name, but I think you should also take the logic series out; "74x164 might be sufficiently generic. > pdata->gpio_pin_clk, err); I'm a bit puzzled why you don't just hook the chip up using standard SPI signals... ISTR they matched up directly to what the chip needs, so no GPIOs were needed for interface glue. > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] GPIO: add support for 74HC164 serial-in/parallel-out 8-bit shift register 2010-08-30 23:43 ` David Brownell @ 2010-08-31 8:17 ` Florian Fainelli 2010-08-31 10:44 ` [PATCH v3] GPIO: add support for 74x164 " Florian Fainelli 0 siblings, 1 reply; 9+ messages in thread From: Florian Fainelli @ 2010-08-31 8:17 UTC (permalink / raw) To: David Brownell Cc: Willy Tarreau, linux-kernel, akpm, Samuel Ortiz, Miguel Gaio, Juhos Gabor, dbrownell Hi David, On Tuesday 31 August 2010 01:43:04 David Brownell wrote: > generic to all > > > 74HC164 chips > > Not just HC-series logic, also HCT, AC, etc (as > I noted previously). > > I'm glad you took NXP (one of the N vendors) > out of the name, but I think you should also > take the logic series out; "74x164 might be sufficiently generic. Allright, I will respin with those changes. Note that I chose to prefix the data structures with gen_ (for obvious C language reasons), I hope this is fine. > > > > pdata->gpio_pin_clk, err); > > I'm a bit puzzled why you don't just hook the > chip up using standard SPI signals... ISTR they > matched up directly to what the chip needs, so > no GPIOs were needed for interface glue. The board this driver is being used on had no SPI signals left I think, so it was hooked up on separate GPIO lines (which cannot be muxed to the GPIO pad). -- Florian ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3] GPIO: add support for 74x164 serial-in/parallel-out 8-bit shift register 2010-08-31 8:17 ` Florian Fainelli @ 2010-08-31 10:44 ` Florian Fainelli 2010-09-01 7:25 ` Florian Fainelli 2010-09-01 9:37 ` [PATCH v4] " Florian Fainelli 0 siblings, 2 replies; 9+ messages in thread From: Florian Fainelli @ 2010-08-31 10:44 UTC (permalink / raw) To: David Brownell Cc: Willy Tarreau, linux-kernel, akpm, Samuel Ortiz, Miguel Gaio, Juhos Gabor, dbrownell From: Miguel Gaio <miguel.gaio@efixo.com> This patch adds support for generic 74x164 serial-in/parallel-out 8-bits shift register. This driver can be used as a GPIO output expander. Signed-off-by: Miguel Gaio <miguel.gaio@efixo.com> Signed-off-by: Juhos Gabor <juhosg@openwrt.org> Signed-off-by: Florian Fainelli <florian@openwrt.org> --- Changes since v1: - renamed nxp_ to gen_ since this driver is generic to all 74HC164 chips - added comment on this driver not handling the 74HC164 daisy-chaining - renamed misused GPIO expanders to Shift registers Changes since v2: - rename 74hc164 to 74x164 diff --git a/drivers/gpio/74x164.c b/drivers/gpio/74x164.c new file mode 100644 index 0000000..9adeed4 --- /dev/null +++ b/drivers/gpio/74x164.c @@ -0,0 +1,228 @@ +/* + * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> + * + * 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. + * + * Note: this driver does not support the way 74x164 chips can be + * daisy-chained. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/gpio.h> +#include <linux/bitops.h> +#include <linux/platform_device.h> +#include <linux/74x164.h> + +#define GEN_74X164_NUM_GPIOS 8 + +struct gen_74x164_chip { + struct device *parent; + struct gpio_chip gpio_chip; + struct mutex lock; + long mask; +}; + +static void gen_74x164_set_value(struct gpio_chip *, unsigned, int); + +static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc) +{ + return container_of(gc, struct gen_74x164_chip, gpio_chip); +} + +static int gen_74x164_direction_input(struct gpio_chip *gc, unsigned offset) +{ + WARN_ON(1); + return -EINVAL; +} + +static int gen_74x164_direction_output(struct gpio_chip *gc, + unsigned offset, int val) +{ + gen_74x164_set_value(gc, offset, val); + return 0; +} + +static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) +{ + struct gen_74x164_chip *chip = gpio_to_chip(gc); + int ret; + + mutex_lock(&chip->lock); + ret = test_bit(offset, &chip->mask); + mutex_unlock(&chip->lock); + + return ret; +} + +static void gen_74x164_set_value(struct gpio_chip *gc, + unsigned offset, int val) +{ + struct gen_74x164_chip *chip; + struct gen_74x164_platform_data *pdata; + long mask; + int refresh; + int i; + + chip = gpio_to_chip(gc); + pdata = chip->parent->platform_data; + + mutex_lock(&chip->lock); + if (val) + refresh = (test_and_set_bit(offset, &chip->mask) != val); + else + refresh = (test_and_clear_bit(offset, &chip->mask) != val); + + if (refresh) { + mask = chip->mask; + for (i = 8; i > 0; --i, mask <<= 1) { + gpio_set_value(pdata->gpio_pin_data, mask & 0x80); + gpio_set_value(pdata->gpio_pin_clk, 1); + gpio_set_value(pdata->gpio_pin_clk, 0); + } + } + mutex_unlock(&chip->lock); +} + +static int __devinit gen_74x164_probe(struct platform_device *pdev) +{ + struct gen_74x164_platform_data *pdata; + struct gen_74x164_chip *chip; + struct gpio_chip *gc; + int err; + + pdata = pdev->dev.platform_data; + if (pdata == NULL) { + dev_dbg(&pdev->dev, "no platform data specified\n"); + return -EINVAL; + } + + chip = kzalloc(sizeof(struct gen_74x164_chip), GFP_KERNEL); + if (chip == NULL) { + dev_err(&pdev->dev, "no memory for private data\n"); + return -ENOMEM; + } + + err = gpio_request(pdata->gpio_pin_clk, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_clk, err); + goto err_free_chip; + } + + err = gpio_request(pdata->gpio_pin_data, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_data, err); + goto err_free_clk; + } + + err = gpio_direction_output(pdata->gpio_pin_clk, 0); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_clk, err); + goto err_free_data; + } + + err = gpio_direction_output(pdata->gpio_pin_data, 0); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_data, err); + goto err_free_data; + } + + chip->parent = &pdev->dev; + mutex_init(&chip->lock); + + gc = &chip->gpio_chip; + + gc->direction_input = gen_74x164_direction_input; + gc->direction_output = gen_74x164_direction_output; + gc->get = gen_74x164_get_value; + gc->set = gen_74x164_set_value; + gc->can_sleep = 1; + + gc->base = pdata->gpio_base; + gc->ngpio = GEN_74X164_NUM_GPIOS; + gc->label = dev_name(chip->parent); + gc->dev = chip->parent; + gc->owner = THIS_MODULE; + + err = gpiochip_add(&chip->gpio_chip); + if (err) { + dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); + goto err_free_data; + } + + platform_set_drvdata(pdev, chip); + return 0; + +err_free_data: + gpio_free(pdata->gpio_pin_data); +err_free_clk: + gpio_free(pdata->gpio_pin_clk); +err_free_chip: + kfree(chip); + return err; +} + +static int gen_74x164_remove(struct platform_device *pdev) +{ + struct gen_74x164_chip *chip = platform_get_drvdata(pdev); + struct gen_74x164_platform_data *pdata = pdev->dev.platform_data; + + if (chip) { + int err; + + err = gpiochip_remove(&chip->gpio_chip); + if (err) { + dev_err(&pdev->dev, + "unable to remove gpio chip, err=%d\n", + err); + return err; + } + + gpio_free(pdata->gpio_pin_clk); + gpio_free(pdata->gpio_pin_data); + + kfree(chip); + platform_set_drvdata(pdev, NULL); + } + + return 0; +} + +static struct platform_driver gen_74x164_driver = { + .probe = gen_74x164_probe, + .remove = __devexit_p(gen_74x164_remove), + .driver = { + .name = GEN_74X164_DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init gen_74x164_init(void) +{ + return platform_driver_register(&gen_74x164_driver); +} +subsys_initcall(gen_74x164_init); + +static void __exit gen_74x164_exit(void) +{ + platform_driver_unregister(&gen_74x164_driver); +} +module_exit(gen_74x164_exit); + +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); +MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); +MODULE_DESCRIPTION("GPIO expander driver for 74X164 8-bits shift register"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" GEN_74X164_DRIVER_NAME); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 510aa20..fc82c23 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -361,4 +361,13 @@ config GPIO_JANZ_TTL This driver provides support for driving the pins in output mode only. Input mode is not supported. +comment "Shift registers:" + +config GPIO_74X164 + tristate "74x164 serial-in/parallel-out 8-bits shift register" + help + Platform driver for 74x164 compatible serial-in/parallel-out + 8-outputs shift registers. This driver can be used to provide access + to more gpio outputs. + endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fc6019d..60456a4 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_GPIO_MAX7301) += max7301.o obj-$(CONFIG_GPIO_MAX732X) += max732x.o obj-$(CONFIG_GPIO_MC33880) += mc33880.o obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o +obj-$(CONFIG_GPIO_74X164) += 74x164.o obj-$(CONFIG_GPIO_PCA953X) += pca953x.o obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o obj-$(CONFIG_GPIO_PL061) += pl061.o diff --git a/include/linux/74x164.h b/include/linux/74x164.h new file mode 100644 index 0000000..1705732 --- /dev/null +++ b/include/linux/74x164.h @@ -0,0 +1,22 @@ +/* + * 74x164 - Serial-in/parallel-out 8-bits shift register + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * + * 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. + */ + +#ifndef __74X164_H +#define __74X164_H + +#define GEN_74X164_DRIVER_NAME "74x164" + +struct gen_74x164_platform_data { + unsigned gpio_base; + unsigned gpio_pin_data; + unsigned gpio_pin_clk; +}; + +#endif /* __74x164_H */ ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3] GPIO: add support for 74x164 serial-in/parallel-out 8-bit shift register 2010-08-31 10:44 ` [PATCH v3] GPIO: add support for 74x164 " Florian Fainelli @ 2010-09-01 7:25 ` Florian Fainelli 2010-09-01 9:37 ` [PATCH v4] " Florian Fainelli 1 sibling, 0 replies; 9+ messages in thread From: Florian Fainelli @ 2010-09-01 7:25 UTC (permalink / raw) To: David Brownell Cc: Willy Tarreau, linux-kernel, akpm, Samuel Ortiz, Miguel Gaio, Juhos Gabor, dbrownell On Tuesday 31 August 2010 12:44:07 Florian Fainelli wrote: > From: Miguel Gaio <miguel.gaio@efixo.com> > > This patch adds support for generic 74x164 serial-in/parallel-out 8-bits > shift register. This driver can be used as a GPIO output expander. > > Signed-off-by: Miguel Gaio <miguel.gaio@efixo.com> > Signed-off-by: Juhos Gabor <juhosg@openwrt.org> > Signed-off-by: Florian Fainelli <florian@openwrt.org> > --- > Changes since v1: > - renamed nxp_ to gen_ since this driver is generic to all 74HC164 chips > - added comment on this driver not handling the 74HC164 daisy-chaining > - renamed misused GPIO expanders to Shift registers > > Changes since v2: > - rename 74hc164 to 74x164 Miguel sent me a 4th version supporting daisy-chaining, I will resubmit it right away. > > diff --git a/drivers/gpio/74x164.c b/drivers/gpio/74x164.c > new file mode 100644 > index 0000000..9adeed4 > --- /dev/null > +++ b/drivers/gpio/74x164.c > @@ -0,0 +1,228 @@ > +/* > + * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO > driver + * > + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> > + * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> > + * > + * 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. > + * > + * Note: this driver does not support the way 74x164 chips can be > + * daisy-chained. > + */ > + > +#include <linux/module.h> > +#include <linux/init.h> > +#include <linux/slab.h> > +#include <linux/gpio.h> > +#include <linux/bitops.h> > +#include <linux/platform_device.h> > +#include <linux/74x164.h> > + > +#define GEN_74X164_NUM_GPIOS 8 > + > +struct gen_74x164_chip { > + struct device *parent; > + struct gpio_chip gpio_chip; > + struct mutex lock; > + long mask; > +}; > + > +static void gen_74x164_set_value(struct gpio_chip *, unsigned, int); > + > +static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc) > +{ > + return container_of(gc, struct gen_74x164_chip, gpio_chip); > +} > + > +static int gen_74x164_direction_input(struct gpio_chip *gc, unsigned > offset) +{ > + WARN_ON(1); > + return -EINVAL; > +} > + > +static int gen_74x164_direction_output(struct gpio_chip *gc, > + unsigned offset, int val) > +{ > + gen_74x164_set_value(gc, offset, val); > + return 0; > +} > + > +static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) > +{ > + struct gen_74x164_chip *chip = gpio_to_chip(gc); > + int ret; > + > + mutex_lock(&chip->lock); > + ret = test_bit(offset, &chip->mask); > + mutex_unlock(&chip->lock); > + > + return ret; > +} > + > +static void gen_74x164_set_value(struct gpio_chip *gc, > + unsigned offset, int val) > +{ > + struct gen_74x164_chip *chip; > + struct gen_74x164_platform_data *pdata; > + long mask; > + int refresh; > + int i; > + > + chip = gpio_to_chip(gc); > + pdata = chip->parent->platform_data; > + > + mutex_lock(&chip->lock); > + if (val) > + refresh = (test_and_set_bit(offset, &chip->mask) != val); > + else > + refresh = (test_and_clear_bit(offset, &chip->mask) != val); > + > + if (refresh) { > + mask = chip->mask; > + for (i = 8; i > 0; --i, mask <<= 1) { > + gpio_set_value(pdata->gpio_pin_data, mask & 0x80); > + gpio_set_value(pdata->gpio_pin_clk, 1); > + gpio_set_value(pdata->gpio_pin_clk, 0); > + } > + } > + mutex_unlock(&chip->lock); > +} > + > +static int __devinit gen_74x164_probe(struct platform_device *pdev) > +{ > + struct gen_74x164_platform_data *pdata; > + struct gen_74x164_chip *chip; > + struct gpio_chip *gc; > + int err; > + > + pdata = pdev->dev.platform_data; > + if (pdata == NULL) { > + dev_dbg(&pdev->dev, "no platform data specified\n"); > + return -EINVAL; > + } > + > + chip = kzalloc(sizeof(struct gen_74x164_chip), GFP_KERNEL); > + if (chip == NULL) { > + dev_err(&pdev->dev, "no memory for private data\n"); > + return -ENOMEM; > + } > + > + err = gpio_request(pdata->gpio_pin_clk, dev_name(&pdev->dev)); > + if (err) { > + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", > + pdata->gpio_pin_clk, err); > + goto err_free_chip; > + } > + > + err = gpio_request(pdata->gpio_pin_data, dev_name(&pdev->dev)); > + if (err) { > + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", > + pdata->gpio_pin_data, err); > + goto err_free_clk; > + } > + > + err = gpio_direction_output(pdata->gpio_pin_clk, 0); > + if (err) { > + dev_err(&pdev->dev, > + "unable to set direction of gpio %u, err=%d\n", > + pdata->gpio_pin_clk, err); > + goto err_free_data; > + } > + > + err = gpio_direction_output(pdata->gpio_pin_data, 0); > + if (err) { > + dev_err(&pdev->dev, > + "unable to set direction of gpio %u, err=%d\n", > + pdata->gpio_pin_data, err); > + goto err_free_data; > + } > + > + chip->parent = &pdev->dev; > + mutex_init(&chip->lock); > + > + gc = &chip->gpio_chip; > + > + gc->direction_input = gen_74x164_direction_input; > + gc->direction_output = gen_74x164_direction_output; > + gc->get = gen_74x164_get_value; > + gc->set = gen_74x164_set_value; > + gc->can_sleep = 1; > + > + gc->base = pdata->gpio_base; > + gc->ngpio = GEN_74X164_NUM_GPIOS; > + gc->label = dev_name(chip->parent); > + gc->dev = chip->parent; > + gc->owner = THIS_MODULE; > + > + err = gpiochip_add(&chip->gpio_chip); > + if (err) { > + dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); > + goto err_free_data; > + } > + > + platform_set_drvdata(pdev, chip); > + return 0; > + > +err_free_data: > + gpio_free(pdata->gpio_pin_data); > +err_free_clk: > + gpio_free(pdata->gpio_pin_clk); > +err_free_chip: > + kfree(chip); > + return err; > +} > + > +static int gen_74x164_remove(struct platform_device *pdev) > +{ > + struct gen_74x164_chip *chip = platform_get_drvdata(pdev); > + struct gen_74x164_platform_data *pdata = pdev->dev.platform_data; > + > + if (chip) { > + int err; > + > + err = gpiochip_remove(&chip->gpio_chip); > + if (err) { > + dev_err(&pdev->dev, > + "unable to remove gpio chip, err=%d\n", > + err); > + return err; > + } > + > + gpio_free(pdata->gpio_pin_clk); > + gpio_free(pdata->gpio_pin_data); > + > + kfree(chip); > + platform_set_drvdata(pdev, NULL); > + } > + > + return 0; > +} > + > +static struct platform_driver gen_74x164_driver = { > + .probe = gen_74x164_probe, > + .remove = __devexit_p(gen_74x164_remove), > + .driver = { > + .name = GEN_74X164_DRIVER_NAME, > + .owner = THIS_MODULE, > + }, > +}; > + > +static int __init gen_74x164_init(void) > +{ > + return platform_driver_register(&gen_74x164_driver); > +} > +subsys_initcall(gen_74x164_init); > + > +static void __exit gen_74x164_exit(void) > +{ > + platform_driver_unregister(&gen_74x164_driver); > +} > +module_exit(gen_74x164_exit); > + > +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); > +MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); > +MODULE_DESCRIPTION("GPIO expander driver for 74X164 8-bits shift > register"); +MODULE_LICENSE("GPL v2"); > +MODULE_ALIAS("platform:" GEN_74X164_DRIVER_NAME); > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > index 510aa20..fc82c23 100644 > --- a/drivers/gpio/Kconfig > +++ b/drivers/gpio/Kconfig > @@ -361,4 +361,13 @@ config GPIO_JANZ_TTL > This driver provides support for driving the pins in output > mode only. Input mode is not supported. > > +comment "Shift registers:" > + > +config GPIO_74X164 > + tristate "74x164 serial-in/parallel-out 8-bits shift register" > + help > + Platform driver for 74x164 compatible serial-in/parallel-out > + 8-outputs shift registers. This driver can be used to provide access > + to more gpio outputs. > + > endif > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile > index fc6019d..60456a4 100644 > --- a/drivers/gpio/Makefile > +++ b/drivers/gpio/Makefile > @@ -17,6 +17,7 @@ obj-$(CONFIG_GPIO_MAX7301) += max7301.o > obj-$(CONFIG_GPIO_MAX732X) += max732x.o > obj-$(CONFIG_GPIO_MC33880) += mc33880.o > obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o > +obj-$(CONFIG_GPIO_74X164) += 74x164.o > obj-$(CONFIG_GPIO_PCA953X) += pca953x.o > obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o > obj-$(CONFIG_GPIO_PL061) += pl061.o > diff --git a/include/linux/74x164.h b/include/linux/74x164.h > new file mode 100644 > index 0000000..1705732 > --- /dev/null > +++ b/include/linux/74x164.h > @@ -0,0 +1,22 @@ > +/* > + * 74x164 - Serial-in/parallel-out 8-bits shift register > + * > + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> > + * > + * 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. > + */ > + > +#ifndef __74X164_H > +#define __74X164_H > + > +#define GEN_74X164_DRIVER_NAME "74x164" > + > +struct gen_74x164_platform_data { > + unsigned gpio_base; > + unsigned gpio_pin_data; > + unsigned gpio_pin_clk; > +}; > + > +#endif /* __74x164_H */ -- Florian ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v4] GPIO: add support for 74x164 serial-in/parallel-out 8-bit shift register 2010-08-31 10:44 ` [PATCH v3] GPIO: add support for 74x164 " Florian Fainelli 2010-09-01 7:25 ` Florian Fainelli @ 2010-09-01 9:37 ` Florian Fainelli 2010-09-07 0:41 ` David Brownell 1 sibling, 1 reply; 9+ messages in thread From: Florian Fainelli @ 2010-09-01 9:37 UTC (permalink / raw) To: David Brownell Cc: Willy Tarreau, linux-kernel, akpm, Samuel Ortiz, Miguel Gaio, Juhos Gabor, dbrownell From: Miguel Gaio <miguel.gaio@efixo.com> This patch adds support for generic 74x164 serial-in/parallel-out 8-bits shift register. This driver can be used as a GPIO output expander. Signed-off-by: Miguel Gaio <miguel.gaio@efixo.com> Signed-off-by: Juhos Gabor <juhosg@openwrt.org> Signed-off-by: Florian Fainelli <florian@openwrt.org> --- Changes since v1: - renamed nxp_ to gen_ since this driver is generic to all 74HC164 chips - added comment on this driver not handling the 74HC164 daisy-chaining - renamed misused GPIO expanders to Shift registers Changes since v2: - rename 74hc164 to 74x164 Changes since v3: - support daisy-chaining of 74x164 up to 32 gpios diff --git a/drivers/gpio/74x164.c b/drivers/gpio/74x164.c new file mode 100644 index 0000000..62e44b7 --- /dev/null +++ b/drivers/gpio/74x164.c @@ -0,0 +1,231 @@ +/* + * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> + * + * 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/slab.h> +#include <linux/gpio.h> +#include <linux/bitops.h> +#include <linux/platform_device.h> +#include <linux/74x164.h> + +#define GEN_74X164_NUM_GPIOS 32 + +struct gen_74x164_chip { + struct device *parent; + struct gpio_chip gpio_chip; + struct mutex lock; + long mask; +}; + +static void gen_74x164_set_value(struct gpio_chip *, unsigned, int); + +static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc) +{ + return container_of(gc, struct gen_74x164_chip, gpio_chip); +} + +static int gen_74x164_direction_input(struct gpio_chip *gc, unsigned offset) +{ + WARN_ON(1); + return -EINVAL; +} + +static int gen_74x164_direction_output(struct gpio_chip *gc, + unsigned offset, int val) +{ + gen_74x164_set_value(gc, offset, val); + return 0; +} + +static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) +{ + struct gen_74x164_chip *chip = gpio_to_chip(gc); + int ret; + + mutex_lock(&chip->lock); + ret = test_bit(offset, &chip->mask); + mutex_unlock(&chip->lock); + + return ret; +} + +static void gen_74x164_set_value(struct gpio_chip *gc, + unsigned offset, int val) +{ + struct gen_74x164_chip *chip; + struct gen_74x164_platform_data *pdata; + long mask; + int refresh; + int i; + + chip = gpio_to_chip(gc); + pdata = chip->parent->platform_data; + + mutex_lock(&chip->lock); + if (val) + refresh = (test_and_set_bit(offset, &chip->mask) != val); + else + refresh = (test_and_clear_bit(offset, &chip->mask) != val); + + if (refresh) { + mask = chip->mask; + for (i = pdata->ngpio - 1; i >= 0; --i) { + gpio_set_value(pdata->gpio_pin_data, + test_bit(i, &mask)); + gpio_set_value(pdata->gpio_pin_clk, 1); + gpio_set_value(pdata->gpio_pin_clk, 0); + } + } + mutex_unlock(&chip->lock); +} + +static int __devinit gen_74x164_probe(struct platform_device *pdev) +{ + struct gen_74x164_platform_data *pdata; + struct gen_74x164_chip *chip; + struct gpio_chip *gc; + int err; + + pdata = pdev->dev.platform_data; + if (pdata == NULL) { + dev_dbg(&pdev->dev, "no platform data specified\n"); + return -EINVAL; + } + + if (pdata->ngpio > GEN_74X164_NUM_GPIOS) { + dev_err(&pdev->dev, "invalid gpio count %u\n", pdata->ngpio); + return -EINVAL; + } + + chip = kzalloc(sizeof(struct gen_74x164_chip), GFP_KERNEL); + if (chip == NULL) { + dev_err(&pdev->dev, "no memory for private data\n"); + return -ENOMEM; + } + + err = gpio_request(pdata->gpio_pin_clk, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_clk, err); + goto err_free_chip; + } + + err = gpio_request(pdata->gpio_pin_data, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_data, err); + goto err_free_clk; + } + + err = gpio_direction_output(pdata->gpio_pin_clk, 0); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_clk, err); + goto err_free_data; + } + + err = gpio_direction_output(pdata->gpio_pin_data, 0); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_data, err); + goto err_free_data; + } + + chip->parent = &pdev->dev; + mutex_init(&chip->lock); + + gc = &chip->gpio_chip; + + gc->direction_input = gen_74x164_direction_input; + gc->direction_output = gen_74x164_direction_output; + gc->get = gen_74x164_get_value; + gc->set = gen_74x164_set_value; + gc->can_sleep = 1; + + gc->base = pdata->gpio_base; + gc->ngpio = pdata->ngpio; + gc->label = dev_name(chip->parent); + gc->dev = chip->parent; + gc->owner = THIS_MODULE; + + err = gpiochip_add(&chip->gpio_chip); + if (err) { + dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); + goto err_free_data; + } + + platform_set_drvdata(pdev, chip); + return 0; + +err_free_data: + gpio_free(pdata->gpio_pin_data); +err_free_clk: + gpio_free(pdata->gpio_pin_clk); +err_free_chip: + kfree(chip); + return err; +} + +static int gen_74x164_remove(struct platform_device *pdev) +{ + struct gen_74x164_chip *chip = platform_get_drvdata(pdev); + struct gen_74x164_platform_data *pdata = pdev->dev.platform_data; + + if (chip) { + int err; + + err = gpiochip_remove(&chip->gpio_chip); + if (err) { + dev_err(&pdev->dev, + "unable to remove gpio chip, err=%d\n", + err); + return err; + } + + gpio_free(pdata->gpio_pin_clk); + gpio_free(pdata->gpio_pin_data); + + kfree(chip); + platform_set_drvdata(pdev, NULL); + } + + return 0; +} + +static struct platform_driver gen_74x164_driver = { + .probe = gen_74x164_probe, + .remove = __devexit_p(gen_74x164_remove), + .driver = { + .name = GEN_74X164_DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init gen_74x164_init(void) +{ + return platform_driver_register(&gen_74x164_driver); +} +subsys_initcall(gen_74x164_init); + +static void __exit gen_74x164_exit(void) +{ + platform_driver_unregister(&gen_74x164_driver); +} +module_exit(gen_74x164_exit); + +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); +MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); +MODULE_DESCRIPTION("GPIO expander driver for 74X164 8-bits shift register"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" GEN_74X164_DRIVER_NAME); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 510aa20..fc82c23 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -361,4 +361,13 @@ config GPIO_JANZ_TTL This driver provides support for driving the pins in output mode only. Input mode is not supported. +comment "Shift registers:" + +config GPIO_74X164 + tristate "74x164 serial-in/parallel-out 8-bits shift register" + help + Platform driver for 74x164 compatible serial-in/parallel-out + 8-outputs shift registers. This driver can be used to provide access + to more gpio outputs. + endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fc6019d..60456a4 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_GPIO_MAX7301) += max7301.o obj-$(CONFIG_GPIO_MAX732X) += max732x.o obj-$(CONFIG_GPIO_MC33880) += mc33880.o obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o +obj-$(CONFIG_GPIO_74X164) += 74x164.o obj-$(CONFIG_GPIO_PCA953X) += pca953x.o obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o obj-$(CONFIG_GPIO_PL061) += pl061.o diff --git a/include/linux/74x164.h b/include/linux/74x164.h new file mode 100644 index 0000000..b58b159 --- /dev/null +++ b/include/linux/74x164.h @@ -0,0 +1,23 @@ +/* + * 74x164 - Serial-in/parallel-out 8-bits shift register + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * + * 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. + */ + +#ifndef __74X164_H +#define __74X164_H + +#define GEN_74X164_DRIVER_NAME "74x164" + +struct gen_74x164_platform_data { + unsigned gpio_base; + unsigned ngpio; + unsigned gpio_pin_data; + unsigned gpio_pin_clk; +}; + +#endif /* __74x164_H */ ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v4] GPIO: add support for 74x164 serial-in/parallel-out 8-bit shift register 2010-09-01 9:37 ` [PATCH v4] " Florian Fainelli @ 2010-09-07 0:41 ` David Brownell 0 siblings, 0 replies; 9+ messages in thread From: David Brownell @ 2010-09-07 0:41 UTC (permalink / raw) To: Florian Fainelli Cc: Willy Tarreau, linux-kernel, akpm, Samuel Ortiz, Miguel Gaio, Juhos Gabor --- On Wed, 9/1/10, Florian Fainelli <florian@openwrt.org> wrote: > > Changes since v3: > - support daisy-chaining of 74x164 up to 32 gpios cool, a new feature! I kind of dislike doing this after having offereed feedback that you accepted, but I'm going to NAK this driver for mainline. The reasons are associated with a point I made in my last feedback. The chip interface is SPI (but it's not called that in the data sheets, true). This driver is two things: - maybe 85% looks like spi-over-gpio, cloning what the spi-gpio.c driver does (a three-wire SPI mode, using the NO_RX option, vs normal four-wire). The rest is a small 74x164 driver. So if there are spare GPIOs *this* driver can be used, but not if there's just a spare SPI select. If this were re-packaged as a small SPI protocol driver and a small SPI-over-GPIO instance both of the two components would be more reusable... Your current hardware can handle the SPI-over-GPIO approach, obviously. I'd ack a small 74x164 SPI protocol driver, which is what I expected when I saw the first post. But a conglomerate driver -- no. Sorry. - Dave ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-09-07 0:41 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-08-28 23:18 [PATCH] GPIO: add support for NXP 74HC164 GPIO expander David Brownell 2010-08-29 10:10 ` Willy Tarreau 2010-08-29 15:37 ` [PATCH v2] GPIO: add support for 74HC164 serial-in/parallel-out 8-bit shift register Florian Fainelli 2010-08-30 23:43 ` David Brownell 2010-08-31 8:17 ` Florian Fainelli 2010-08-31 10:44 ` [PATCH v3] GPIO: add support for 74x164 " Florian Fainelli 2010-09-01 7:25 ` Florian Fainelli 2010-09-01 9:37 ` [PATCH v4] " Florian Fainelli 2010-09-07 0:41 ` David Brownell
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox