1 // SPDX-License-Identifier: GPL-2.0-only
3 * GPIO driver for the ACCES PCI-IDIO-16
4 * Copyright (C) 2017 William Breathitt Gray
6 #include <linux/bits.h>
7 #include <linux/device.h>
8 #include <linux/errno.h>
9 #include <linux/gpio/driver.h>
10 #include <linux/interrupt.h>
11 #include <linux/irqdesc.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/pci.h>
15 #include <linux/spinlock.h>
16 #include <linux/types.h>
18 #include "gpio-idio-16.h"
21 * struct idio_16_gpio - GPIO device private data structure
22 * @chip: instance of the gpio_chip
23 * @lock: synchronization lock to prevent I/O race conditions
24 * @reg: I/O address offset for the GPIO device registers
25 * @state: ACCES IDIO-16 device state
26 * @irq_mask: I/O bits affected by interrupts
29 struct gpio_chip chip;
31 struct idio_16 __iomem *reg;
32 struct idio_16_state state;
33 unsigned long irq_mask;
36 static int idio_16_gpio_get_direction(struct gpio_chip *chip,
39 if (idio_16_get_direction(offset))
40 return GPIO_LINE_DIRECTION_IN;
42 return GPIO_LINE_DIRECTION_OUT;
45 static int idio_16_gpio_direction_input(struct gpio_chip *chip,
51 static int idio_16_gpio_direction_output(struct gpio_chip *chip,
52 unsigned int offset, int value)
54 chip->set(chip, offset, value);
58 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
60 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
62 return idio_16_get(idio16gpio->reg, &idio16gpio->state, offset);
65 static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
66 unsigned long *mask, unsigned long *bits)
68 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
70 idio_16_get_multiple(idio16gpio->reg, &idio16gpio->state, mask, bits);
74 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
77 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
79 idio_16_set(idio16gpio->reg, &idio16gpio->state, offset, value);
82 static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
83 unsigned long *mask, unsigned long *bits)
85 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
87 idio_16_set_multiple(idio16gpio->reg, &idio16gpio->state, mask, bits);
90 static void idio_16_irq_ack(struct irq_data *data)
94 static void idio_16_irq_mask(struct irq_data *data)
96 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
97 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
98 const unsigned long mask = BIT(irqd_to_hwirq(data));
101 idio16gpio->irq_mask &= ~mask;
103 if (!idio16gpio->irq_mask) {
104 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
106 iowrite8(0, &idio16gpio->reg->irq_ctl);
108 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
111 gpiochip_disable_irq(chip, irqd_to_hwirq(data));
114 static void idio_16_irq_unmask(struct irq_data *data)
116 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
117 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
118 const unsigned long mask = BIT(irqd_to_hwirq(data));
119 const unsigned long prev_irq_mask = idio16gpio->irq_mask;
122 gpiochip_enable_irq(chip, irqd_to_hwirq(data));
124 idio16gpio->irq_mask |= mask;
126 if (!prev_irq_mask) {
127 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
129 ioread8(&idio16gpio->reg->irq_ctl);
131 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
135 static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
137 /* The only valid irq types are none and both-edges */
138 if (flow_type != IRQ_TYPE_NONE &&
139 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
145 static const struct irq_chip idio_16_irqchip = {
146 .name = "pci-idio-16",
147 .irq_ack = idio_16_irq_ack,
148 .irq_mask = idio_16_irq_mask,
149 .irq_unmask = idio_16_irq_unmask,
150 .irq_set_type = idio_16_irq_set_type,
151 .flags = IRQCHIP_IMMUTABLE,
152 GPIOCHIP_IRQ_RESOURCE_HELPERS,
155 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
157 struct idio_16_gpio *const idio16gpio = dev_id;
158 unsigned int irq_status;
159 struct gpio_chip *const chip = &idio16gpio->chip;
162 raw_spin_lock(&idio16gpio->lock);
164 irq_status = ioread8(&idio16gpio->reg->irq_status);
166 raw_spin_unlock(&idio16gpio->lock);
168 /* Make sure our device generated IRQ */
169 if (!(irq_status & 0x3) || !(irq_status & 0x4))
172 for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
173 generic_handle_domain_irq(chip->irq.domain, gpio);
175 raw_spin_lock(&idio16gpio->lock);
177 /* Clear interrupt */
178 iowrite8(0, &idio16gpio->reg->in0_7);
180 raw_spin_unlock(&idio16gpio->lock);
185 #define IDIO_16_NGPIO 32
186 static const char *idio_16_names[IDIO_16_NGPIO] = {
187 "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
188 "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
189 "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
190 "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
193 static int idio_16_irq_init_hw(struct gpio_chip *gc)
195 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
197 /* Disable IRQ by default and clear any pending interrupt */
198 iowrite8(0, &idio16gpio->reg->irq_ctl);
199 iowrite8(0, &idio16gpio->reg->in0_7);
204 static int idio_16_probe(struct pci_dev *pdev, const struct pci_device_id *id)
206 struct device *const dev = &pdev->dev;
207 struct idio_16_gpio *idio16gpio;
209 const size_t pci_bar_index = 2;
210 const char *const name = pci_name(pdev);
211 struct gpio_irq_chip *girq;
213 idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
217 err = pcim_enable_device(pdev);
219 dev_err(dev, "Failed to enable PCI device (%d)\n", err);
223 err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
225 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
229 idio16gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
231 /* Deactivate input filters */
232 iowrite8(0, &idio16gpio->reg->filter_ctl);
234 idio16gpio->chip.label = name;
235 idio16gpio->chip.parent = dev;
236 idio16gpio->chip.owner = THIS_MODULE;
237 idio16gpio->chip.base = -1;
238 idio16gpio->chip.ngpio = IDIO_16_NGPIO;
239 idio16gpio->chip.names = idio_16_names;
240 idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
241 idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
242 idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
243 idio16gpio->chip.get = idio_16_gpio_get;
244 idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
245 idio16gpio->chip.set = idio_16_gpio_set;
246 idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
248 idio_16_state_init(&idio16gpio->state);
250 girq = &idio16gpio->chip.irq;
251 gpio_irq_chip_set_chip(girq, &idio_16_irqchip);
252 /* This will let us handle the parent IRQ in the driver */
253 girq->parent_handler = NULL;
254 girq->num_parents = 0;
255 girq->parents = NULL;
256 girq->default_type = IRQ_TYPE_NONE;
257 girq->handler = handle_edge_irq;
258 girq->init_hw = idio_16_irq_init_hw;
260 raw_spin_lock_init(&idio16gpio->lock);
262 err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
264 dev_err(dev, "GPIO registering failed (%d)\n", err);
268 err = devm_request_irq(dev, pdev->irq, idio_16_irq_handler, IRQF_SHARED,
271 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
278 static const struct pci_device_id idio_16_pci_dev_id[] = {
279 { PCI_DEVICE(0x494F, 0x0DC8) }, { 0 }
281 MODULE_DEVICE_TABLE(pci, idio_16_pci_dev_id);
283 static struct pci_driver idio_16_driver = {
284 .name = "pci-idio-16",
285 .id_table = idio_16_pci_dev_id,
286 .probe = idio_16_probe
289 module_pci_driver(idio_16_driver);
291 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
292 MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver");
293 MODULE_LICENSE("GPL v2");
294 MODULE_IMPORT_NS(GPIO_IDIO_16);