Lines Matching +full:spi +full:- +full:gpio
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2015-2023 Texas Instruments Incorporated - https://www.ti.com/
10 #include <linux/gpio/consumer.h>
11 #include <linux/gpio/driver.h>
14 #include <linux/spi/spi.h>
19 * struct pisosr_gpio - GPIO driver data
20 * @chip: GPIO controller chip
21 * @spi: SPI device pointer
24 * @load_gpio: GPIO pin used to load input into device
29 struct spi_device *spi; member
36 static int pisosr_gpio_refresh(struct pisosr_gpio *gpio) in pisosr_gpio_refresh() argument
40 mutex_lock(&gpio->lock); in pisosr_gpio_refresh()
42 if (gpio->load_gpio) { in pisosr_gpio_refresh()
43 gpiod_set_value_cansleep(gpio->load_gpio, 1); in pisosr_gpio_refresh()
45 gpiod_set_value_cansleep(gpio->load_gpio, 0); in pisosr_gpio_refresh()
49 ret = spi_read(gpio->spi, gpio->buffer, gpio->buffer_size); in pisosr_gpio_refresh()
51 mutex_unlock(&gpio->lock); in pisosr_gpio_refresh()
74 return -EINVAL; in pisosr_gpio_direction_output()
79 struct pisosr_gpio *gpio = gpiochip_get_data(chip); in pisosr_gpio_get() local
82 pisosr_gpio_refresh(gpio); in pisosr_gpio_get()
84 return (gpio->buffer[offset / 8] >> (offset % 8)) & 0x1; in pisosr_gpio_get()
90 struct pisosr_gpio *gpio = gpiochip_get_data(chip); in pisosr_gpio_get_multiple() local
95 pisosr_gpio_refresh(gpio); in pisosr_gpio_get_multiple()
97 bitmap_zero(bits, chip->ngpio); in pisosr_gpio_get_multiple()
98 for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) { in pisosr_gpio_get_multiple()
99 buffer_state = gpio->buffer[offset / 8] & gpio_mask; in pisosr_gpio_get_multiple()
107 .label = "pisosr-gpio",
114 .base = -1,
124 static int pisosr_gpio_probe(struct spi_device *spi) in pisosr_gpio_probe() argument
126 struct device *dev = &spi->dev; in pisosr_gpio_probe()
127 struct pisosr_gpio *gpio; in pisosr_gpio_probe() local
130 gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL); in pisosr_gpio_probe()
131 if (!gpio) in pisosr_gpio_probe()
132 return -ENOMEM; in pisosr_gpio_probe()
134 gpio->chip = template_chip; in pisosr_gpio_probe()
135 gpio->chip.parent = dev; in pisosr_gpio_probe()
136 of_property_read_u16(dev->of_node, "ngpios", &gpio->chip.ngpio); in pisosr_gpio_probe()
138 gpio->spi = spi; in pisosr_gpio_probe()
140 gpio->buffer_size = DIV_ROUND_UP(gpio->chip.ngpio, 8); in pisosr_gpio_probe()
141 gpio->buffer = devm_kzalloc(dev, gpio->buffer_size, GFP_KERNEL); in pisosr_gpio_probe()
142 if (!gpio->buffer) in pisosr_gpio_probe()
143 return -ENOMEM; in pisosr_gpio_probe()
145 gpio->load_gpio = devm_gpiod_get_optional(dev, "load", GPIOD_OUT_LOW); in pisosr_gpio_probe()
146 if (IS_ERR(gpio->load_gpio)) in pisosr_gpio_probe()
147 return dev_err_probe(dev, PTR_ERR(gpio->load_gpio), in pisosr_gpio_probe()
148 "Unable to allocate load GPIO\n"); in pisosr_gpio_probe()
150 mutex_init(&gpio->lock); in pisosr_gpio_probe()
151 ret = devm_add_action_or_reset(dev, pisosr_mutex_destroy, &gpio->lock); in pisosr_gpio_probe()
155 ret = devm_gpiochip_add_data(dev, &gpio->chip, gpio); in pisosr_gpio_probe()
165 { "pisosr-gpio", },
168 MODULE_DEVICE_TABLE(spi, pisosr_gpio_id_table);
171 { .compatible = "pisosr-gpio", },
178 .name = "pisosr-gpio",
187 MODULE_DESCRIPTION("SPI Compatible PISO Shift Register GPIO Driver");