Lines Matching +full:gpio +full:- +full:trigger
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Timberdale FPGA GPIO driver
9 * Timberdale FPGA GPIO
13 #include <linux/gpio/driver.h>
21 #define DRIVER_NAME "timb-gpio"
37 struct gpio_chip gpio; member
42 static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, in timbgpio_update_bit() argument
45 struct timbgpio *tgpio = gpiochip_get_data(gpio); in timbgpio_update_bit()
49 spin_lock_irqsave(&tgpio->lock, flags); in timbgpio_update_bit()
50 reg = ioread32(tgpio->membase + offset); in timbgpio_update_bit()
57 iowrite32(reg, tgpio->membase + offset); in timbgpio_update_bit()
58 spin_unlock_irqrestore(&tgpio->lock, flags); in timbgpio_update_bit()
63 static int timbgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) in timbgpio_gpio_direction_input() argument
65 return timbgpio_update_bit(gpio, nr, TGPIODIR, true); in timbgpio_gpio_direction_input()
68 static int timbgpio_gpio_get(struct gpio_chip *gpio, unsigned nr) in timbgpio_gpio_get() argument
70 struct timbgpio *tgpio = gpiochip_get_data(gpio); in timbgpio_gpio_get()
73 value = ioread32(tgpio->membase + TGPIOVAL); in timbgpio_gpio_get()
77 static int timbgpio_gpio_direction_output(struct gpio_chip *gpio, in timbgpio_gpio_direction_output() argument
80 return timbgpio_update_bit(gpio, nr, TGPIODIR, false); in timbgpio_gpio_direction_output()
83 static int timbgpio_gpio_set(struct gpio_chip *gpio, unsigned int nr, int val) in timbgpio_gpio_set() argument
85 return timbgpio_update_bit(gpio, nr, TGPIOVAL, val != 0); in timbgpio_gpio_set()
88 static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset) in timbgpio_to_irq() argument
90 struct timbgpio *tgpio = gpiochip_get_data(gpio); in timbgpio_to_irq()
92 if (tgpio->irq_base <= 0) in timbgpio_to_irq()
93 return -EINVAL; in timbgpio_to_irq()
95 return tgpio->irq_base + offset; in timbgpio_to_irq()
99 * GPIO IRQ
104 int offset = d->irq - tgpio->irq_base; in timbgpio_irq_disable()
108 spin_lock_irqsave(&tgpio->lock, flags); in timbgpio_irq_disable()
109 tgpio->last_ier &= ~(1UL << offset); in timbgpio_irq_disable()
110 iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); in timbgpio_irq_disable()
111 spin_unlock_irqrestore(&tgpio->lock, flags); in timbgpio_irq_disable()
113 gpiochip_disable_irq(&tgpio->gpio, hwirq); in timbgpio_irq_disable()
119 int offset = d->irq - tgpio->irq_base; in timbgpio_irq_enable()
123 gpiochip_enable_irq(&tgpio->gpio, hwirq); in timbgpio_irq_enable()
125 spin_lock_irqsave(&tgpio->lock, flags); in timbgpio_irq_enable()
126 tgpio->last_ier |= 1UL << offset; in timbgpio_irq_enable()
127 iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); in timbgpio_irq_enable()
128 spin_unlock_irqrestore(&tgpio->lock, flags); in timbgpio_irq_enable()
131 static int timbgpio_irq_type(struct irq_data *d, unsigned trigger) in timbgpio_irq_type() argument
134 int offset = d->irq - tgpio->irq_base; in timbgpio_irq_type()
140 if (offset < 0 || offset >= tgpio->gpio.ngpio) in timbgpio_irq_type()
141 return -EINVAL; in timbgpio_irq_type()
143 ver = ioread32(tgpio->membase + TGPIO_VER); in timbgpio_irq_type()
145 spin_lock_irqsave(&tgpio->lock, flags); in timbgpio_irq_type()
147 lvr = ioread32(tgpio->membase + TGPIO_LVR); in timbgpio_irq_type()
148 flr = ioread32(tgpio->membase + TGPIO_FLR); in timbgpio_irq_type()
150 bflr = ioread32(tgpio->membase + TGPIO_BFLR); in timbgpio_irq_type()
152 if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { in timbgpio_irq_type()
155 if (trigger & IRQ_TYPE_LEVEL_HIGH) in timbgpio_irq_type()
161 if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { in timbgpio_irq_type()
163 ret = -EINVAL; in timbgpio_irq_type()
172 if (trigger & IRQ_TYPE_EDGE_FALLING) in timbgpio_irq_type()
178 iowrite32(lvr, tgpio->membase + TGPIO_LVR); in timbgpio_irq_type()
179 iowrite32(flr, tgpio->membase + TGPIO_FLR); in timbgpio_irq_type()
181 iowrite32(bflr, tgpio->membase + TGPIO_BFLR); in timbgpio_irq_type()
183 iowrite32(1 << offset, tgpio->membase + TGPIO_ICR); in timbgpio_irq_type()
186 spin_unlock_irqrestore(&tgpio->lock, flags); in timbgpio_irq_type()
197 data->chip->irq_ack(data); in timbgpio_irq()
198 ipr = ioread32(tgpio->membase + TGPIO_IPR); in timbgpio_irq()
199 iowrite32(ipr, tgpio->membase + TGPIO_ICR); in timbgpio_irq()
205 iowrite32(0, tgpio->membase + TGPIO_IER); in timbgpio_irq()
207 for_each_set_bit(offset, &ipr, tgpio->gpio.ngpio) in timbgpio_irq()
208 generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset)); in timbgpio_irq()
210 iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); in timbgpio_irq()
214 .name = "GPIO",
225 struct device *dev = &pdev->dev; in timbgpio_probe()
228 struct timbgpio_platform_data *pdata = dev_get_platdata(&pdev->dev); in timbgpio_probe()
231 if (!pdata || pdata->nr_pins > 32) { in timbgpio_probe()
233 return -EINVAL; in timbgpio_probe()
238 return -EINVAL; in timbgpio_probe()
240 tgpio->irq_base = pdata->irq_base; in timbgpio_probe()
242 spin_lock_init(&tgpio->lock); in timbgpio_probe()
244 tgpio->membase = devm_platform_ioremap_resource(pdev, 0); in timbgpio_probe()
245 if (IS_ERR(tgpio->membase)) in timbgpio_probe()
246 return PTR_ERR(tgpio->membase); in timbgpio_probe()
248 gc = &tgpio->gpio; in timbgpio_probe()
250 gc->label = dev_name(&pdev->dev); in timbgpio_probe()
251 gc->owner = THIS_MODULE; in timbgpio_probe()
252 gc->parent = &pdev->dev; in timbgpio_probe()
253 gc->direction_input = timbgpio_gpio_direction_input; in timbgpio_probe()
254 gc->get = timbgpio_gpio_get; in timbgpio_probe()
255 gc->direction_output = timbgpio_gpio_direction_output; in timbgpio_probe()
256 gc->set = timbgpio_gpio_set; in timbgpio_probe()
257 gc->to_irq = (irq >= 0 && tgpio->irq_base > 0) ? timbgpio_to_irq : NULL; in timbgpio_probe()
258 gc->dbg_show = NULL; in timbgpio_probe()
259 gc->base = pdata->gpio_base; in timbgpio_probe()
260 gc->ngpio = pdata->nr_pins; in timbgpio_probe()
261 gc->can_sleep = false; in timbgpio_probe()
263 err = devm_gpiochip_add_data(&pdev->dev, gc, tgpio); in timbgpio_probe()
268 iowrite32(0x0, tgpio->membase + TGPIO_IER); in timbgpio_probe()
270 if (irq < 0 || tgpio->irq_base <= 0) in timbgpio_probe()
273 for (i = 0; i < pdata->nr_pins; i++) { in timbgpio_probe()
274 irq_set_chip_and_handler(tgpio->irq_base + i, in timbgpio_probe()
276 irq_set_chip_data(tgpio->irq_base + i, tgpio); in timbgpio_probe()
277 irq_clear_status_flags(tgpio->irq_base + i, IRQ_NOREQUEST | IRQ_NOPROBE); in timbgpio_probe()
293 /*--------------------------------------------------------------------------*/