.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * GPIO driver for the ACCES 104-IDIO-16 family |
---|
3 | 4 | * Copyright (C) 2015 William Breathitt Gray |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License, version 2, as |
---|
7 | | - * published by the Free Software Foundation. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, but |
---|
10 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
12 | | - * General Public License for more details. |
---|
13 | 5 | * |
---|
14 | 6 | * This driver supports the following ACCES devices: 104-IDIO-16, |
---|
15 | 7 | * 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8. |
---|
.. | .. |
---|
59 | 51 | static int idio_16_gpio_get_direction(struct gpio_chip *chip, unsigned offset) |
---|
60 | 52 | { |
---|
61 | 53 | if (offset > 15) |
---|
62 | | - return 1; |
---|
| 54 | + return GPIO_LINE_DIRECTION_IN; |
---|
63 | 55 | |
---|
64 | | - return 0; |
---|
| 56 | + return GPIO_LINE_DIRECTION_OUT; |
---|
65 | 57 | } |
---|
66 | 58 | |
---|
67 | 59 | static int idio_16_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
---|
.. | .. |
---|
232 | 224 | "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15" |
---|
233 | 225 | }; |
---|
234 | 226 | |
---|
| 227 | +static int idio_16_irq_init_hw(struct gpio_chip *gc) |
---|
| 228 | +{ |
---|
| 229 | + struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc); |
---|
| 230 | + |
---|
| 231 | + /* Disable IRQ by default */ |
---|
| 232 | + outb(0, idio16gpio->base + 2); |
---|
| 233 | + outb(0, idio16gpio->base + 1); |
---|
| 234 | + |
---|
| 235 | + return 0; |
---|
| 236 | +} |
---|
| 237 | + |
---|
235 | 238 | static int idio_16_probe(struct device *dev, unsigned int id) |
---|
236 | 239 | { |
---|
237 | 240 | struct idio_16_gpio *idio16gpio; |
---|
238 | 241 | const char *const name = dev_name(dev); |
---|
| 242 | + struct gpio_irq_chip *girq; |
---|
239 | 243 | int err; |
---|
240 | 244 | |
---|
241 | 245 | idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL); |
---|
.. | .. |
---|
264 | 268 | idio16gpio->base = base[id]; |
---|
265 | 269 | idio16gpio->out_state = 0xFFFF; |
---|
266 | 270 | |
---|
| 271 | + girq = &idio16gpio->chip.irq; |
---|
| 272 | + girq->chip = &idio_16_irqchip; |
---|
| 273 | + /* This will let us handle the parent IRQ in the driver */ |
---|
| 274 | + girq->parent_handler = NULL; |
---|
| 275 | + girq->num_parents = 0; |
---|
| 276 | + girq->parents = NULL; |
---|
| 277 | + girq->default_type = IRQ_TYPE_NONE; |
---|
| 278 | + girq->handler = handle_edge_irq; |
---|
| 279 | + girq->init_hw = idio_16_irq_init_hw; |
---|
| 280 | + |
---|
267 | 281 | raw_spin_lock_init(&idio16gpio->lock); |
---|
268 | 282 | |
---|
269 | 283 | err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); |
---|
270 | 284 | if (err) { |
---|
271 | 285 | dev_err(dev, "GPIO registering failed (%d)\n", err); |
---|
272 | | - return err; |
---|
273 | | - } |
---|
274 | | - |
---|
275 | | - /* Disable IRQ by default */ |
---|
276 | | - outb(0, base[id] + 2); |
---|
277 | | - outb(0, base[id] + 1); |
---|
278 | | - |
---|
279 | | - err = gpiochip_irqchip_add(&idio16gpio->chip, &idio_16_irqchip, 0, |
---|
280 | | - handle_edge_irq, IRQ_TYPE_NONE); |
---|
281 | | - if (err) { |
---|
282 | | - dev_err(dev, "Could not add irqchip (%d)\n", err); |
---|
283 | 286 | return err; |
---|
284 | 287 | } |
---|
285 | 288 | |
---|