Linux 4.19.133
[linux/fpc-iii.git] / drivers / gpio / gpio-pci-idio-16.c
blob25d16b2af1c39b305830d837c5aff62ecaf95ae2
1 /*
2 * GPIO driver for the ACCES PCI-IDIO-16
3 * Copyright (C) 2017 William Breathitt Gray
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.
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.
14 #include <linux/bitmap.h>
15 #include <linux/bitops.h>
16 #include <linux/device.h>
17 #include <linux/errno.h>
18 #include <linux/gpio/driver.h>
19 #include <linux/interrupt.h>
20 #include <linux/irqdesc.h>
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/pci.h>
24 #include <linux/spinlock.h>
25 #include <linux/types.h>
27 /**
28 * struct idio_16_gpio_reg - GPIO device registers structure
29 * @out0_7: Read: FET Drive Outputs 0-7
30 * Write: FET Drive Outputs 0-7
31 * @in0_7: Read: Isolated Inputs 0-7
32 * Write: Clear Interrupt
33 * @irq_ctl: Read: Enable IRQ
34 * Write: Disable IRQ
35 * @filter_ctl: Read: Activate Input Filters 0-15
36 * Write: Deactivate Input Filters 0-15
37 * @out8_15: Read: FET Drive Outputs 8-15
38 * Write: FET Drive Outputs 8-15
39 * @in8_15: Read: Isolated Inputs 8-15
40 * Write: Unused
41 * @irq_status: Read: Interrupt status
42 * Write: Unused
44 struct idio_16_gpio_reg {
45 u8 out0_7;
46 u8 in0_7;
47 u8 irq_ctl;
48 u8 filter_ctl;
49 u8 out8_15;
50 u8 in8_15;
51 u8 irq_status;
54 /**
55 * struct idio_16_gpio - GPIO device private data structure
56 * @chip: instance of the gpio_chip
57 * @lock: synchronization lock to prevent I/O race conditions
58 * @reg: I/O address offset for the GPIO device registers
59 * @irq_mask: I/O bits affected by interrupts
61 struct idio_16_gpio {
62 struct gpio_chip chip;
63 raw_spinlock_t lock;
64 struct idio_16_gpio_reg __iomem *reg;
65 unsigned long irq_mask;
68 static int idio_16_gpio_get_direction(struct gpio_chip *chip,
69 unsigned int offset)
71 if (offset > 15)
72 return 1;
74 return 0;
77 static int idio_16_gpio_direction_input(struct gpio_chip *chip,
78 unsigned int offset)
80 return 0;
83 static int idio_16_gpio_direction_output(struct gpio_chip *chip,
84 unsigned int offset, int value)
86 chip->set(chip, offset, value);
87 return 0;
90 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
92 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
93 unsigned long mask = BIT(offset);
95 if (offset < 8)
96 return !!(ioread8(&idio16gpio->reg->out0_7) & mask);
98 if (offset < 16)
99 return !!(ioread8(&idio16gpio->reg->out8_15) & (mask >> 8));
101 if (offset < 24)
102 return !!(ioread8(&idio16gpio->reg->in0_7) & (mask >> 16));
104 return !!(ioread8(&idio16gpio->reg->in8_15) & (mask >> 24));
107 static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
108 unsigned long *mask, unsigned long *bits)
110 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
111 size_t i;
112 const unsigned int gpio_reg_size = 8;
113 unsigned int bits_offset;
114 size_t word_index;
115 unsigned int word_offset;
116 unsigned long word_mask;
117 const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
118 unsigned long port_state;
119 void __iomem *ports[] = {
120 &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
121 &idio16gpio->reg->in0_7, &idio16gpio->reg->in8_15,
124 /* clear bits array to a clean slate */
125 bitmap_zero(bits, chip->ngpio);
127 /* get bits are evaluated a gpio port register at a time */
128 for (i = 0; i < ARRAY_SIZE(ports); i++) {
129 /* gpio offset in bits array */
130 bits_offset = i * gpio_reg_size;
132 /* word index for bits array */
133 word_index = BIT_WORD(bits_offset);
135 /* gpio offset within current word of bits array */
136 word_offset = bits_offset % BITS_PER_LONG;
138 /* mask of get bits for current gpio within current word */
139 word_mask = mask[word_index] & (port_mask << word_offset);
140 if (!word_mask) {
141 /* no get bits in this port so skip to next one */
142 continue;
145 /* read bits from current gpio port */
146 port_state = ioread8(ports[i]);
148 /* store acquired bits at respective bits array offset */
149 bits[word_index] |= port_state << word_offset;
152 return 0;
155 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
156 int value)
158 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
159 unsigned int mask = BIT(offset);
160 void __iomem *base;
161 unsigned long flags;
162 unsigned int out_state;
164 if (offset > 15)
165 return;
167 if (offset > 7) {
168 mask >>= 8;
169 base = &idio16gpio->reg->out8_15;
170 } else
171 base = &idio16gpio->reg->out0_7;
173 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
175 if (value)
176 out_state = ioread8(base) | mask;
177 else
178 out_state = ioread8(base) & ~mask;
180 iowrite8(out_state, base);
182 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
185 static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
186 unsigned long *mask, unsigned long *bits)
188 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
189 unsigned long flags;
190 unsigned int out_state;
192 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
194 /* process output lines 0-7 */
195 if (*mask & 0xFF) {
196 out_state = ioread8(&idio16gpio->reg->out0_7) & ~*mask;
197 out_state |= *mask & *bits;
198 iowrite8(out_state, &idio16gpio->reg->out0_7);
201 /* shift to next output line word */
202 *mask >>= 8;
204 /* process output lines 8-15 */
205 if (*mask & 0xFF) {
206 *bits >>= 8;
207 out_state = ioread8(&idio16gpio->reg->out8_15) & ~*mask;
208 out_state |= *mask & *bits;
209 iowrite8(out_state, &idio16gpio->reg->out8_15);
212 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
215 static void idio_16_irq_ack(struct irq_data *data)
219 static void idio_16_irq_mask(struct irq_data *data)
221 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
222 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
223 const unsigned long mask = BIT(irqd_to_hwirq(data));
224 unsigned long flags;
226 idio16gpio->irq_mask &= ~mask;
228 if (!idio16gpio->irq_mask) {
229 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
231 iowrite8(0, &idio16gpio->reg->irq_ctl);
233 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
237 static void idio_16_irq_unmask(struct irq_data *data)
239 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
240 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
241 const unsigned long mask = BIT(irqd_to_hwirq(data));
242 const unsigned long prev_irq_mask = idio16gpio->irq_mask;
243 unsigned long flags;
245 idio16gpio->irq_mask |= mask;
247 if (!prev_irq_mask) {
248 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
250 ioread8(&idio16gpio->reg->irq_ctl);
252 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
256 static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
258 /* The only valid irq types are none and both-edges */
259 if (flow_type != IRQ_TYPE_NONE &&
260 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
261 return -EINVAL;
263 return 0;
266 static struct irq_chip idio_16_irqchip = {
267 .name = "pci-idio-16",
268 .irq_ack = idio_16_irq_ack,
269 .irq_mask = idio_16_irq_mask,
270 .irq_unmask = idio_16_irq_unmask,
271 .irq_set_type = idio_16_irq_set_type
274 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
276 struct idio_16_gpio *const idio16gpio = dev_id;
277 unsigned int irq_status;
278 struct gpio_chip *const chip = &idio16gpio->chip;
279 int gpio;
281 raw_spin_lock(&idio16gpio->lock);
283 irq_status = ioread8(&idio16gpio->reg->irq_status);
285 raw_spin_unlock(&idio16gpio->lock);
287 /* Make sure our device generated IRQ */
288 if (!(irq_status & 0x3) || !(irq_status & 0x4))
289 return IRQ_NONE;
291 for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
292 generic_handle_irq(irq_find_mapping(chip->irq.domain, gpio));
294 raw_spin_lock(&idio16gpio->lock);
296 /* Clear interrupt */
297 iowrite8(0, &idio16gpio->reg->in0_7);
299 raw_spin_unlock(&idio16gpio->lock);
301 return IRQ_HANDLED;
304 #define IDIO_16_NGPIO 32
305 static const char *idio_16_names[IDIO_16_NGPIO] = {
306 "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
307 "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
308 "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
309 "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
312 static int idio_16_probe(struct pci_dev *pdev, const struct pci_device_id *id)
314 struct device *const dev = &pdev->dev;
315 struct idio_16_gpio *idio16gpio;
316 int err;
317 const size_t pci_bar_index = 2;
318 const char *const name = pci_name(pdev);
320 idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
321 if (!idio16gpio)
322 return -ENOMEM;
324 err = pcim_enable_device(pdev);
325 if (err) {
326 dev_err(dev, "Failed to enable PCI device (%d)\n", err);
327 return err;
330 err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
331 if (err) {
332 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
333 return err;
336 idio16gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
338 /* Deactivate input filters */
339 iowrite8(0, &idio16gpio->reg->filter_ctl);
341 idio16gpio->chip.label = name;
342 idio16gpio->chip.parent = dev;
343 idio16gpio->chip.owner = THIS_MODULE;
344 idio16gpio->chip.base = -1;
345 idio16gpio->chip.ngpio = IDIO_16_NGPIO;
346 idio16gpio->chip.names = idio_16_names;
347 idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
348 idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
349 idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
350 idio16gpio->chip.get = idio_16_gpio_get;
351 idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
352 idio16gpio->chip.set = idio_16_gpio_set;
353 idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
355 raw_spin_lock_init(&idio16gpio->lock);
357 err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
358 if (err) {
359 dev_err(dev, "GPIO registering failed (%d)\n", err);
360 return err;
363 /* Disable IRQ by default and clear any pending interrupt */
364 iowrite8(0, &idio16gpio->reg->irq_ctl);
365 iowrite8(0, &idio16gpio->reg->in0_7);
367 err = gpiochip_irqchip_add(&idio16gpio->chip, &idio_16_irqchip, 0,
368 handle_edge_irq, IRQ_TYPE_NONE);
369 if (err) {
370 dev_err(dev, "Could not add irqchip (%d)\n", err);
371 return err;
374 err = devm_request_irq(dev, pdev->irq, idio_16_irq_handler, IRQF_SHARED,
375 name, idio16gpio);
376 if (err) {
377 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
378 return err;
381 return 0;
384 static const struct pci_device_id idio_16_pci_dev_id[] = {
385 { PCI_DEVICE(0x494F, 0x0DC8) }, { 0 }
387 MODULE_DEVICE_TABLE(pci, idio_16_pci_dev_id);
389 static struct pci_driver idio_16_driver = {
390 .name = "pci-idio-16",
391 .id_table = idio_16_pci_dev_id,
392 .probe = idio_16_probe
395 module_pci_driver(idio_16_driver);
397 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
398 MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver");
399 MODULE_LICENSE("GPL v2");