^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Andrew F. Davis <afd@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * modify it under the terms of the GNU General Public License version 2 as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is distributed "as is" WITHOUT ANY WARRANTY of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * kind, whether expressed or implied; without even the implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * GNU General Public License version 2 for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define DEFAULT_NGPIO 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * struct pisosr_gpio - GPIO driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * @chip: GPIO controller chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * @spi: SPI device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * @buffer: Buffer for device reads
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * @buffer_size: Size of buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * @load_gpio: GPIO pin used to load input into device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @lock: Protects read sequences
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct pisosr_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct gpio_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct spi_device *spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) u8 *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) size_t buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct gpio_desc *load_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int pisosr_gpio_refresh(struct pisosr_gpio *gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) mutex_lock(&gpio->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (gpio->load_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) gpiod_set_value_cansleep(gpio->load_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) udelay(1); /* registers load time (~10ns) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) gpiod_set_value_cansleep(gpio->load_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) udelay(1); /* registers recovery time (~5ns) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ret = spi_read(gpio->spi, gpio->buffer, gpio->buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) mutex_unlock(&gpio->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int pisosr_gpio_get_direction(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* This device always input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return GPIO_LINE_DIRECTION_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static int pisosr_gpio_direction_input(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* This device always input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int pisosr_gpio_direction_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* This device is input only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int pisosr_gpio_get(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct pisosr_gpio *gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* Refresh may not always be needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) pisosr_gpio_refresh(gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return (gpio->buffer[offset / 8] >> (offset % 8)) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static int pisosr_gpio_get_multiple(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned long *mask, unsigned long *bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct pisosr_gpio *gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned long gpio_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned long buffer_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) pisosr_gpio_refresh(gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) bitmap_zero(bits, chip->ngpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) buffer_state = gpio->buffer[offset / 8] & gpio_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) bitmap_set_value8(bits, buffer_state, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static const struct gpio_chip template_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .label = "pisosr-gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .get_direction = pisosr_gpio_get_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .direction_input = pisosr_gpio_direction_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .direction_output = pisosr_gpio_direction_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .get = pisosr_gpio_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .get_multiple = pisosr_gpio_get_multiple,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .base = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .ngpio = DEFAULT_NGPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .can_sleep = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int pisosr_gpio_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct device *dev = &spi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct pisosr_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (!gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) spi_set_drvdata(spi, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) gpio->chip = template_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) gpio->chip.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) of_property_read_u16(dev->of_node, "ngpios", &gpio->chip.ngpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) gpio->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) gpio->buffer_size = DIV_ROUND_UP(gpio->chip.ngpio, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) gpio->buffer = devm_kzalloc(dev, gpio->buffer_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!gpio->buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) gpio->load_gpio = devm_gpiod_get_optional(dev, "load", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (IS_ERR(gpio->load_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return dev_err_probe(dev, PTR_ERR(gpio->load_gpio),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) "Unable to allocate load GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mutex_init(&gpio->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ret = gpiochip_add_data(&gpio->chip, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dev_err(dev, "Unable to register gpiochip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int pisosr_gpio_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct pisosr_gpio *gpio = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) gpiochip_remove(&gpio->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mutex_destroy(&gpio->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static const struct spi_device_id pisosr_gpio_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { "pisosr-gpio", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) MODULE_DEVICE_TABLE(spi, pisosr_gpio_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static const struct of_device_id pisosr_gpio_of_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { .compatible = "pisosr-gpio", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) MODULE_DEVICE_TABLE(of, pisosr_gpio_of_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static struct spi_driver pisosr_gpio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .name = "pisosr-gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .of_match_table = pisosr_gpio_of_match_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .probe = pisosr_gpio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .remove = pisosr_gpio_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .id_table = pisosr_gpio_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) module_spi_driver(pisosr_gpio_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) MODULE_DESCRIPTION("SPI Compatible PISO Shift Register GPIO Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) MODULE_LICENSE("GPL v2");