gpios: Add daisy-chaining and dt support to 74x164
Subsystems (3)
v3 cover gpios: Add daisy-chaining and dt support to 74x164
Hi all,
This is an attempt at adding the support for chained 8 bit shift registers that are present in the cfa-10049.
This patchset also adds dt documentation to the 74x164 gpio driver.
Thanks,
Maxime
Changes since v2:
* Fixed a memleak in the _write_config function when having an error.
Maxime Ripard (3):
gpio: 74x164: Add support for the daisy-chaining
gpio: 74x164: dts: Add documentation for the dt binding
ARM: dts: cfa10049: Add the 74HC595 gpio expanders
.../devicetree/bindings/gpio/gpio-74x164.txt | 22 +++++++ arch/arm/boot/dts/imx28-cfa10049.dts | 21 ++++++ drivers/gpio/gpio-74x164.c | 68 ++++++++++++++++++-- 3 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-74x164.txt
Signature · 1 line
1.7.9.5
PATCH v3 1/3 gpio: 74x164: Add support for the daisy-chaining
The shift registers have an output pin that, when enabled, propagates the values of its internal register to the pins. If another value comes to the register while the output pin is disabled, this new value will makae the older shift into the next register in the chain.
This patch adds support for daisy-chaining the registers, using the regular SPI chip select mechanism to manage the output pin, and the registers-number dt property to set the number of chained registers.
--- drivers/gpio/gpio-74x164.c | 68 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 7 deletions(-)
drivers/gpio/gpio-74x164.c +61 -7
@@ -14,14 +14,18 @@#include <linux/spi/spi.h> #include <linux/spi/74x164.h> #include <linux/gpio.h> +#include <linux/of_gpio.h> #include <linux/slab.h> #include <linux/module.h> +#define GEN_74X164_NUMBER_GPIOS 8 +struct gen_74x164_chip {struct spi_device *spi; +u8 *buffer;struct gpio_chip gpio_chip;struct mutex lock; -u8 port_config; +u32 registers; };static struct gen_74x164_chip *gpio_to_74x164_chip (struct gpio_chip *gc)
@@ -31,17 +35,47 @@ static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc)static int __gen_74x164_write_config (struct gen_74x164_chip *chip) { -return spi_write (chip->spi, - &chip->port_config,sizeof (chip->port_config)); +struct spi_message message; +struct spi_transfer *msg_buf; +int i, ret =0 ; + + msg_buf =kzalloc (chip->registers *sizeof (struct spi_transfer ), +GFP_KERNEL ); +if (!msg_buf) +return -ENOMEM ; + +spi_message_init (&message); + +/* +* Since the registers are chained, every byte sent will make +* the previous byte shift to the next register in the +* chain. Thus, the first byte send will end up in the last +* register at the end of the transfer. So, to have a logical +* numbering, send the bytes in reverse order so that the last +* byte of the buffer will end up in the last register. +*/ +for (i = chip->registers -1 ; i >=0 ; i--) { + msg_buf[i].tx_buf = chip->buffer +i; + msg_buf[i].len =sizeof (u8); +spi_message_add_tail (msg_buf + i, &message); + } + + ret =spi_sync (chip->spi, &message); + +kfree (msg_buf); + +return ret; }static int gen_74x164_get_value (struct gpio_chip *gc,unsigned offset) {struct gen_74x164_chip *chip =gpio_to_74x164_chip (gc); +u8 bank = offset /8 ; +u8 pin = offset %8 ;int ret;mutex_lock (&chip->lock); - ret = (chip->port_config >> offset) &0x1 ; + ret = (chip->buffer[bank] >> pin) &0x1 ;mutex_unlock (&chip->lock);return ret;
@@ -51,12 +85,14 @@ static void gen_74x164_set_value(struct gpio_chip *gc, unsigned offset, int val) {struct gen_74x164_chip *chip =gpio_to_74x164_chip (gc); +u8 bank = offset /8 ; +u8 pin = offset %8 ;mutex_lock (&chip->lock);if (val) - chip->port_config |= (1 << offset); + chip->buffer[bank] |= (1 << pin);else - chip->port_config &= ~(1 << offset); + chip->buffer[bank] &= ~(1 << pin);__gen_74x164_write_config (chip);mutex_unlock (&chip->lock);
@@ -75,6 +111,11 @@ static int __devinit gen_74x164_probe(struct spi_device *spi)struct gen_74x164_chip_platform_data *pdata;int ret; +if (!spi->dev.of_node) { +dev_err (&spi->dev,"No device tree data available.\n" ); +return -EINVAL ; + } +/* * bits_per_word cannot be configured in platform data */
@@ -104,7 +145,20 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) chip->gpio_chip.direction_output = gen_74x164_direction_output; chip->gpio_chip.get = gen_74x164_get_value; chip->gpio_chip.set = gen_74x164_set_value; - chip->gpio_chip.ngpio =8 ; + +if (of_property_read_u32 (spi->dev.of_node,"registers-number" , &chip->registers)) { +dev_err (&spi->dev,"Missing registers-number property in the DT.\n" ); + ret = -EINVAL ; + goto exit_destroy; + } + + chip->gpio_chip.ngpio =GEN_74X164_NUMBER_GPIOS * chip->registers; + chip->buffer =devm_kzalloc (&spi->dev, chip->gpio_chip.ngpio,GFP_KERNEL ); +if (!chip->buffer) { + ret = -ENOMEM ; + goto exit_destroy; + } + chip->gpio_chip.can_sleep =1 ; chip->gpio_chip.dev = &spi->dev; chip->gpio_chip.owner =THIS_MODULE ;
Signature · 1 line
1.7.9.5
PATCH 1/3 gpio: 74x164: Add support for the daisy-chaining
Quoted 10 lines · Maxime Ripard
The shift registers have an output pin that, when enabled, propagates the values of its internal register to the pins. If another value comes to the register while the output pin is disabled, this new value will makae the older shift into the next register in the chain.
This patch adds support for daisy-chaining the registers, using the regular SPI chip select mechanism to manage the output pin, and the registers-number dt property to set the number of chained registers.
Signed-off-by Maxime Ripard <[email protected]>
OK cool, but I just realized that this driver was added just two years ago by Gabor and Miguel, so I'd like to get their feedback before continuing.
I know I already merged the DT support and stuff, but better late than never.
Please include them on future postings of patches to this driver... (See To: line)
Miguel, Gabor: please look at this, I hope you can get hold of the patches. Please also check the stuff I've already merged here:
http://git.kernel.org/?p=linux/kernel/git/linusw/linux-gpio.git;a=shortlog;h=refs/heads/devel
Yours,
Linus Walleij
PATCH 1/3 gpio: 74x164: Add support for the daisy-chaining
2012.09.11. 19:05 keltez?ssel, Linus Walleij ?rta:
Quoted 21 lines
Quoted 10 lines · Maxime Ripard
The shift registers have an output pin that, when enabled, propagates the values of its internal register to the pins. If another value comes to the register while the output pin is disabled, this new value will makae the older shift into the next register in the chain.
This patch adds support for daisy-chaining the registers, using the regular SPI chip select mechanism to manage the output pin, and the registers-number dt property to set the number of chained registers.
Signed-off-by Maxime Ripard <[email protected]>OK cool, but I just realized that this driver was added just two years ago by Gabor and Miguel, so I'd like to get their feedback before continuing.
I know I already merged the DT support and stuff, but better late than never.
Quoted 7 lines
Please include them on future postings of patches to this driver... (See To: line)
Miguel, Gabor: please look at this, I hope you can get hold of the patches. Please also check the stuff I've already merged here:
http://git.kernel.org/?p=linux/kernel/git/linusw/linux-gpio.git;a=shortlog;h=refs/heads/devel
The merged patches look good in general. The merged patches look good in general. However I don't know anything about the 74x164 chip. The driver contain my copyright only because it was based on another driver which I wrote for a different chip.
-Gabor
PATCH 1/3 gpio: 74x164: Add support for the daisy-chaining
In reply to Linus WalleijQuoted 12 lines · Linus Walleij
Quoted 9 lines · Maxime Ripard
The shift registers have an output pin that, when enabled, propagates the values of its internal register to the pins. If another value comes to the register while the output pin is disabled, this new value will makae the older shift into the next register in the chain.
This patch adds support for daisy-chaining the registers, using the regular SPI chip select mechanism to manage the output pin, and the registers-number dt property to set the number of chained registers.
Quoted 5 lines
Quoted 1 line
Signed-off-by Maxime Ripard <[email protected]>OK cool, but I just realized that this driver was added just two years ago by Gabor and Miguel, so I'd like to get their feedback before continuing.
Tentatively applied waiting for feedback from Miguel...
Thanks!
Linus Walleij
PATCH 1/3 gpio: 74x164: Add support for the daisy-chaining
Quoted 13 lines · Linus Walleij
Quoted 12 lines · Linus Walleij
Quoted 9 lines · Maxime Ripard
The shift registers have an output pin that, when enabled, propagates the values of its internal register to the pins. If another value comes to the register while the output pin is disabled, this new value will makae the older shift into the next register in the chain.
This patch adds support for daisy-chaining the registers, using the regular SPI chip select mechanism to manage the output pin, and the registers-number dt property to set the number of chained registers.
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Signed-off-by Maxime Ripard <[email protected]>OK cool, but I just realized that this driver was added just two years ago by Gabor and Miguel, so I'd like to get their feedback before continuing.
Tentatively applied waiting for feedback from Miguel...
All is ok for me.
Miguel
Quoted 3 lines
Thanks!
Linus Walleij
PATCH v3 2/3 gpio: 74x164: dts: Add documentation for the dt binding
In reply to Maxime Ripard--- .../devicetree/bindings/gpio/gpio-74x164.txt | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-74x164.txt
Documentation/devicetree/bindings/gpio/gpio-74x164.txt new file +22 -0
@@ -0,0 +1,22 @@ +* Generic 8-bits shift register GPIO driver + +Required properties: +- compatible : Should be "fairchild,74hc595" +- reg : chip select number +- gpio-controller : Marks the device node as a gpio controller. +- #gpio-cells : Should be two. The first cell is the pin number and + the second cell is used to specify the gpio polarity: + 0 = active high + 1 = active low +- registers-number: Number of daisy-chained shift registers + +Example: + +gpio5: gpio5 at 0 { + compatible = "fairchild,74hc595"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + registers-number = <4>; + spi-max-frequency = <100000>; +};
Signature · 1 line
1.7.9.5
PATCH 2/3 gpio: 74x164: dts: Add documentation for the dt binding
Quoted 1 line · Maxime Ripard
Signed-off-by Maxime Ripard <[email protected]>
Applied (since I already merged the DT code).
Yours,
Linus Walleij
PATCH 2/3 gpio: 74x164: dts: Add documentation for the dt binding
Quoted 6 lines · Linus Walleij
Quoted 1 line · Maxime Ripard
Signed-off-by Maxime Ripard <[email protected]>Applied (since I already merged the DT code).
BTW: I don't have patch 3/3 in this series, does it exist? Or can you resend it? 1/3 and 2/3 are applied.
Yours,
Linus Walleij
PATCH v3 2/3 gpio: 74x164: dts: Add documentation for the dt binding
Hi Linus,
Le 11/09/2012 23:52, Linus Walleij a ?crit :
Quoted 10 lines · Linus Walleij
Quoted 6 lines
Quoted 1 line · Maxime Ripard
Signed-off-by Maxime Ripard <[email protected]>Applied (since I already merged the DT code).
BTW: I don't have patch 3/3 in this series, does it exist? Or can you resend it? 1/3 and 2/3 are applied.
Hmm, that's odd, but since it was about the CFA-10049 dts, Shawn already applied it, so I guess it's fine.
Thanks,
Maxime
Signature · 4 lines
Maxime Ripard, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH v3 3/3 ARM: dts: cfa10049: Add the 74HC595 gpio expanders
In reply to Maxime RipardAdd the two daisy-chains of 74hc595s shift registers available on the CFA-10049.
--- arch/arm/boot/dts/imx28-cfa10049.dts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
arch/arm/boot/dts/imx28-cfa10049.dts +21 -0
@@ -27,6 +27,8 @@ fsl,pinmux-ids = < 0x0181 /* MX28_PAD_GPMI_RDN__SSP3_SCK */ 0x01c1 /* MX28_PAD_GPMI_RESETN__SSP3_CMD */ + 0x0111 /* MX28_PAD_GPMI_CE1N__SSP3_D3 */ + 0x01a2 /* MX28_PAD_GPMI_ALE__SSP3_D4 */ >; fsl,drive-strength = <1>; fsl,voltage = <1>;
@@ -39,6 +41,25 @@ pinctrl-names = "default"; pinctrl-0 = <&spi3_pins_cfa10049>; status = "okay"; + + gpio5: gpio5 at 0 { + compatible = "fairchild,74hc595"; + gpio-controller; + #gpio-cells = <2>; + reg = <0>; + registers-number = <2>; + spi-max-frequency = <100000>; + }; + + gpio6: gpio6 at 1 { + compatible = "fairchild,74hc595"; + gpio-controller; + #gpio-cells = <2>; + reg = <1>; + registers-number = <4>; + spi-max-frequency = <100000>; + }; + }; };
Signature · 1 line
1.7.9.5
Shawn Guo
AppliedPATCH 3/3 ARM: dts: cfa10049: Add the 74HC595 gpio expanders
Quoted 4 lines · Maxime Ripard
Add the two daisy-chains of 74hc595s shift registers available on the CFA-10049.
Signed-off-by Maxime Ripard <[email protected]>
Applied, thanks.