1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver 4 * 5 * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> 6 * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> 7 */ 8 9 #include <linux/gpio/consumer.h> 10 #include <linux/gpio/driver.h> 11 #include <linux/module.h> 12 #include <linux/mutex.h> 13 #include <linux/property.h> 14 #include <linux/slab.h> 15 #include <linux/spi/spi.h> 16 17 #define GEN_74X164_NUMBER_GPIOS 8 18 19 struct gen_74x164_chip { 20 struct gpio_chip gpio_chip; 21 struct mutex lock; 22 struct gpio_desc *gpiod_oe; 23 u32 registers; 24 /* 25 * Since the registers are chained, every byte sent will make 26 * the previous byte shift to the next register in the 27 * chain. Thus, the first byte sent will end up in the last 28 * register at the end of the transfer. So, to have a logical 29 * numbering, store the bytes in reverse order. 30 */ 31 u8 buffer[]; 32 }; 33 34 static int __gen_74x164_write_config(struct gen_74x164_chip *chip) 35 { 36 return spi_write(to_spi_device(chip->gpio_chip.parent), chip->buffer, 37 chip->registers); 38 } 39 40 static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) 41 { 42 struct gen_74x164_chip *chip = gpiochip_get_data(gc); 43 u8 bank = chip->registers - 1 - offset / 8; 44 u8 pin = offset % 8; 45 int ret; 46 47 mutex_lock(&chip->lock); 48 ret = (chip->buffer[bank] >> pin) & 0x1; 49 mutex_unlock(&chip->lock); 50 51 return ret; 52 } 53 54 static void gen_74x164_set_value(struct gpio_chip *gc, 55 unsigned offset, int val) 56 { 57 struct gen_74x164_chip *chip = gpiochip_get_data(gc); 58 u8 bank = chip->registers - 1 - offset / 8; 59 u8 pin = offset % 8; 60 61 mutex_lock(&chip->lock); 62 if (val) 63 chip->buffer[bank] |= (1 << pin); 64 else 65 chip->buffer[bank] &= ~(1 << pin); 66 67 __gen_74x164_write_config(chip); 68 mutex_unlock(&chip->lock); 69 } 70 71 static void gen_74x164_set_multiple(struct gpio_chip *gc, unsigned long *mask, 72 unsigned long *bits) 73 { 74 struct gen_74x164_chip *chip = gpiochip_get_data(gc); 75 unsigned int i, idx, shift; 76 u8 bank, bankmask; 77 78 mutex_lock(&chip->lock); 79 for (i = 0, bank = chip->registers - 1; i < chip->registers; 80 i++, bank--) { 81 idx = i / sizeof(*mask); 82 shift = i % sizeof(*mask) * BITS_PER_BYTE; 83 bankmask = mask[idx] >> shift; 84 if (!bankmask) 85 continue; 86 87 chip->buffer[bank] &= ~bankmask; 88 chip->buffer[bank] |= bankmask & (bits[idx] >> shift); 89 } 90 __gen_74x164_write_config(chip); 91 mutex_unlock(&chip->lock); 92 } 93 94 static int gen_74x164_direction_output(struct gpio_chip *gc, 95 unsigned offset, int val) 96 { 97 gen_74x164_set_value(gc, offset, val); 98 return 0; 99 } 100 101 static int gen_74x164_probe(struct spi_device *spi) 102 { 103 struct gen_74x164_chip *chip; 104 u32 nregs; 105 int ret; 106 107 /* 108 * bits_per_word cannot be configured in platform data 109 */ 110 spi->bits_per_word = 8; 111 112 ret = spi_setup(spi); 113 if (ret < 0) 114 return ret; 115 116 ret = device_property_read_u32(&spi->dev, "registers-number", &nregs); 117 if (ret) { 118 dev_err(&spi->dev, "Missing 'registers-number' property.\n"); 119 return -EINVAL; 120 } 121 122 chip = devm_kzalloc(&spi->dev, sizeof(*chip) + nregs, GFP_KERNEL); 123 if (!chip) 124 return -ENOMEM; 125 126 chip->gpiod_oe = devm_gpiod_get_optional(&spi->dev, "enable", 127 GPIOD_OUT_LOW); 128 if (IS_ERR(chip->gpiod_oe)) 129 return PTR_ERR(chip->gpiod_oe); 130 131 gpiod_set_value_cansleep(chip->gpiod_oe, 1); 132 133 spi_set_drvdata(spi, chip); 134 135 chip->gpio_chip.label = spi->modalias; 136 chip->gpio_chip.direction_output = gen_74x164_direction_output; 137 chip->gpio_chip.get = gen_74x164_get_value; 138 chip->gpio_chip.set = gen_74x164_set_value; 139 chip->gpio_chip.set_multiple = gen_74x164_set_multiple; 140 chip->gpio_chip.base = -1; 141 142 chip->registers = nregs; 143 chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; 144 145 chip->gpio_chip.can_sleep = true; 146 chip->gpio_chip.parent = &spi->dev; 147 chip->gpio_chip.owner = THIS_MODULE; 148 149 mutex_init(&chip->lock); 150 151 ret = __gen_74x164_write_config(chip); 152 if (ret) { 153 dev_err(&spi->dev, "Failed writing: %d\n", ret); 154 goto exit_destroy; 155 } 156 157 ret = gpiochip_add_data(&chip->gpio_chip, chip); 158 if (!ret) 159 return 0; 160 161 exit_destroy: 162 mutex_destroy(&chip->lock); 163 164 return ret; 165 } 166 167 static int gen_74x164_remove(struct spi_device *spi) 168 { 169 struct gen_74x164_chip *chip = spi_get_drvdata(spi); 170 171 gpiod_set_value_cansleep(chip->gpiod_oe, 0); 172 gpiochip_remove(&chip->gpio_chip); 173 mutex_destroy(&chip->lock); 174 175 return 0; 176 } 177 178 static const struct of_device_id gen_74x164_dt_ids[] = { 179 { .compatible = "fairchild,74hc595" }, 180 { .compatible = "nxp,74lvc594" }, 181 {}, 182 }; 183 MODULE_DEVICE_TABLE(of, gen_74x164_dt_ids); 184 185 static struct spi_driver gen_74x164_driver = { 186 .driver = { 187 .name = "74x164", 188 .of_match_table = gen_74x164_dt_ids, 189 }, 190 .probe = gen_74x164_probe, 191 .remove = gen_74x164_remove, 192 }; 193 module_spi_driver(gen_74x164_driver); 194 195 MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); 196 MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); 197 MODULE_DESCRIPTION("GPIO expander driver for 74X164 8-bits shift register"); 198 MODULE_LICENSE("GPL v2"); 199