[PATCH 4/4] gpio: 74x164: Add latch GPIO support

From: J. Neuschäfer via B4 Relay
Date: Fri Dec 13 2024 - 12:33:22 EST


From: "J. Neuschäfer" <j.ne@xxxxxxxxxx>

The Fairchild MM74HC595 and other compatible parts have a latch clock
input (also known as storage register clock input), which must be
clocked once in order to apply any value that was serially shifted in.

This patch adds driver support for using a GPIO that connects to the
latch clock.

Signed-off-by: J. Neuschäfer <j.ne@xxxxxxxxxx>
---
drivers/gpio/gpio-74x164.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c
index 187032efa5b5cd1aa7aea7b2d55f6c06df4ccac4..8e87eeb7a1c7a8c71079c8d837dc5c426db8b65b 100644
--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -7,6 +7,7 @@
*/

#include <linux/bitops.h>
+#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/module.h>
@@ -21,6 +22,7 @@ struct gen_74x164_chip {
struct gpio_chip gpio_chip;
struct mutex lock;
struct gpio_desc *gpiod_oe;
+ struct gpio_desc *gpiod_latch;
u32 registers;
/*
* Since the registers are chained, every byte sent will make
@@ -34,8 +36,20 @@ struct gen_74x164_chip {

static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
{
- return spi_write(to_spi_device(chip->gpio_chip.parent), chip->buffer,
+ int ret;
+
+ ret = spi_write(to_spi_device(chip->gpio_chip.parent), chip->buffer,
chip->registers);
+ if (ret)
+ return ret;
+
+ if (chip->gpiod_latch) {
+ gpiod_set_value_cansleep(chip->gpiod_latch, 1);
+ udelay(1);
+ gpiod_set_value_cansleep(chip->gpiod_latch, 0);
+ }
+
+ return 0;
}

static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
@@ -127,6 +141,11 @@ static int gen_74x164_probe(struct spi_device *spi)
if (IS_ERR(chip->gpiod_oe))
return PTR_ERR(chip->gpiod_oe);

+ chip->gpiod_latch = devm_gpiod_get_optional(&spi->dev, "latch",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(chip->gpiod_latch))
+ return PTR_ERR(chip->gpiod_latch);
+
spi_set_drvdata(spi, chip);

chip->gpio_chip.label = spi->modalias;

--
2.45.2