1 // SPDX-License-Identifier: GPL-2.0-only
3 * GPIO driver for the ACCES PCIe-IDIO-24 family
4 * Copyright (C) 2018 William Breathitt Gray
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * This driver supports the following ACCES devices: PCIe-IDIO-24,
16 * PCIe-IDI-24, PCIe-IDO-24, and PCIe-IDIO-12.
18 #include <linux/bitmap.h>
19 #include <linux/bitops.h>
20 #include <linux/device.h>
21 #include <linux/errno.h>
22 #include <linux/gpio/driver.h>
23 #include <linux/interrupt.h>
24 #include <linux/irqdesc.h>
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/pci.h>
28 #include <linux/spinlock.h>
29 #include <linux/types.h>
32 * PLX PEX8311 PCI LCS_INTCSR Interrupt Control/Status
35 * 0: Enable Interrupt Sources (Bit 0)
36 * 1: Enable Interrupt Sources (Bit 1)
37 * 2: Generate Internal PCI Bus Internal SERR# Interrupt
38 * 3: Mailbox Interrupt Enable
39 * 4: Power Management Interrupt Enable
40 * 5: Power Management Interrupt
41 * 6: Slave Read Local Data Parity Check Error Enable
42 * 7: Slave Read Local Data Parity Check Error Status
43 * 8: Internal PCI Wire Interrupt Enable
44 * 9: PCI Express Doorbell Interrupt Enable
45 * 10: PCI Abort Interrupt Enable
46 * 11: Local Interrupt Input Enable
47 * 12: Retry Abort Enable
48 * 13: PCI Express Doorbell Interrupt Active
49 * 14: PCI Abort Interrupt Active
50 * 15: Local Interrupt Input Active
51 * 16: Local Interrupt Output Enable
52 * 17: Local Doorbell Interrupt Enable
53 * 18: DMA Channel 0 Interrupt Enable
54 * 19: DMA Channel 1 Interrupt Enable
55 * 20: Local Doorbell Interrupt Active
56 * 21: DMA Channel 0 Interrupt Active
57 * 22: DMA Channel 1 Interrupt Active
58 * 23: Built-In Self-Test (BIST) Interrupt Active
59 * 24: Direct Master was the Bus Master during a Master or Target Abort
60 * 25: DMA Channel 0 was the Bus Master during a Master or Target Abort
61 * 26: DMA Channel 1 was the Bus Master during a Master or Target Abort
62 * 27: Target Abort after internal 256 consecutive Master Retrys
63 * 28: PCI Bus wrote data to LCS_MBOX0
64 * 29: PCI Bus wrote data to LCS_MBOX1
65 * 30: PCI Bus wrote data to LCS_MBOX2
66 * 31: PCI Bus wrote data to LCS_MBOX3
68 #define PLX_PEX8311_PCI_LCS_INTCSR 0x68
69 #define INTCSR_INTERNAL_PCI_WIRE BIT(8)
70 #define INTCSR_LOCAL_INPUT BIT(11)
73 * struct idio_24_gpio_reg - GPIO device registers structure
74 * @out0_7: Read: FET Outputs 0-7
75 * Write: FET Outputs 0-7
76 * @out8_15: Read: FET Outputs 8-15
77 * Write: FET Outputs 8-15
78 * @out16_23: Read: FET Outputs 16-23
79 * Write: FET Outputs 16-23
80 * @ttl_out0_7: Read: TTL/CMOS Outputs 0-7
81 * Write: TTL/CMOS Outputs 0-7
82 * @in0_7: Read: Isolated Inputs 0-7
84 * @in8_15: Read: Isolated Inputs 8-15
86 * @in16_23: Read: Isolated Inputs 16-23
88 * @ttl_in0_7: Read: TTL/CMOS Inputs 0-7
90 * @cos0_7: Read: COS Status Inputs 0-7
91 * Write: COS Clear Inputs 0-7
92 * @cos8_15: Read: COS Status Inputs 8-15
93 * Write: COS Clear Inputs 8-15
94 * @cos16_23: Read: COS Status Inputs 16-23
95 * Write: COS Clear Inputs 16-23
96 * @cos_ttl0_7: Read: COS Status TTL/CMOS 0-7
97 * Write: COS Clear TTL/CMOS 0-7
98 * @ctl: Read: Control Register
99 * Write: Control Register
100 * @reserved: Read: Reserved
102 * @cos_enable: Read: COS Enable
104 * @soft_reset: Read: IRQ Output Pin Status
105 * Write: Software Board Reset
107 struct idio_24_gpio_reg {
127 * struct idio_24_gpio - GPIO device private data structure
128 * @chip: instance of the gpio_chip
129 * @lock: synchronization lock to prevent I/O race conditions
130 * @reg: I/O address offset for the GPIO device registers
131 * @irq_mask: I/O bits affected by interrupts
133 struct idio_24_gpio {
134 struct gpio_chip chip;
137 struct idio_24_gpio_reg __iomem *reg;
138 unsigned long irq_mask;
141 static int idio_24_gpio_get_direction(struct gpio_chip *chip,
144 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
145 const unsigned long out_mode_mask = BIT(1);
151 /* Isolated Inputs */
156 /* OUT MODE = 1 when TTL/CMOS Output Mode is set */
157 return !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask);
160 static int idio_24_gpio_direction_input(struct gpio_chip *chip,
163 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
165 unsigned int ctl_state;
166 const unsigned long out_mode_mask = BIT(1);
170 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
172 /* Clear TTL/CMOS Output Mode */
173 ctl_state = ioread8(&idio24gpio->reg->ctl) & ~out_mode_mask;
174 iowrite8(ctl_state, &idio24gpio->reg->ctl);
176 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
182 static int idio_24_gpio_direction_output(struct gpio_chip *chip,
183 unsigned int offset, int value)
185 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
187 unsigned int ctl_state;
188 const unsigned long out_mode_mask = BIT(1);
192 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
194 /* Set TTL/CMOS Output Mode */
195 ctl_state = ioread8(&idio24gpio->reg->ctl) | out_mode_mask;
196 iowrite8(ctl_state, &idio24gpio->reg->ctl);
198 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
201 chip->set(chip, offset, value);
205 static int idio_24_gpio_get(struct gpio_chip *chip, unsigned int offset)
207 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
208 const unsigned long offset_mask = BIT(offset % 8);
209 const unsigned long out_mode_mask = BIT(1);
213 return !!(ioread8(&idio24gpio->reg->out0_7) & offset_mask);
216 return !!(ioread8(&idio24gpio->reg->out8_15) & offset_mask);
219 return !!(ioread8(&idio24gpio->reg->out16_23) & offset_mask);
221 /* Isolated Inputs */
223 return !!(ioread8(&idio24gpio->reg->in0_7) & offset_mask);
226 return !!(ioread8(&idio24gpio->reg->in8_15) & offset_mask);
229 return !!(ioread8(&idio24gpio->reg->in16_23) & offset_mask);
231 /* TTL/CMOS Outputs */
232 if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
233 return !!(ioread8(&idio24gpio->reg->ttl_out0_7) & offset_mask);
235 /* TTL/CMOS Inputs */
236 return !!(ioread8(&idio24gpio->reg->ttl_in0_7) & offset_mask);
239 static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
240 unsigned long *mask, unsigned long *bits)
242 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
244 const unsigned int gpio_reg_size = 8;
245 unsigned int bits_offset;
247 unsigned int word_offset;
248 unsigned long word_mask;
249 const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
250 unsigned long port_state;
251 void __iomem *ports[] = {
252 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
253 &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
254 &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
256 const unsigned long out_mode_mask = BIT(1);
258 /* clear bits array to a clean slate */
259 bitmap_zero(bits, chip->ngpio);
261 /* get bits are evaluated a gpio port register at a time */
262 for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) {
263 /* gpio offset in bits array */
264 bits_offset = i * gpio_reg_size;
266 /* word index for bits array */
267 word_index = BIT_WORD(bits_offset);
269 /* gpio offset within current word of bits array */
270 word_offset = bits_offset % BITS_PER_LONG;
272 /* mask of get bits for current gpio within current word */
273 word_mask = mask[word_index] & (port_mask << word_offset);
275 /* no get bits in this port so skip to next one */
279 /* read bits from current gpio port (port 6 is TTL GPIO) */
281 port_state = ioread8(ports[i]);
282 else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
283 port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
285 port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
287 /* store acquired bits at respective bits array offset */
288 bits[word_index] |= (port_state << word_offset) & word_mask;
294 static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
297 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
298 const unsigned long out_mode_mask = BIT(1);
300 const unsigned int mask = BIT(offset % 8);
302 unsigned int out_state;
304 /* Isolated Inputs */
305 if (offset > 23 && offset < 48)
308 /* TTL/CMOS Inputs */
309 if (offset > 47 && !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
312 /* TTL/CMOS Outputs */
314 base = &idio24gpio->reg->ttl_out0_7;
316 else if (offset > 15)
317 base = &idio24gpio->reg->out16_23;
319 base = &idio24gpio->reg->out8_15;
321 base = &idio24gpio->reg->out0_7;
323 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
326 out_state = ioread8(base) | mask;
328 out_state = ioread8(base) & ~mask;
330 iowrite8(out_state, base);
332 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
335 static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
336 unsigned long *mask, unsigned long *bits)
338 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
340 unsigned long bits_offset;
341 unsigned long gpio_mask;
342 const unsigned int gpio_reg_size = 8;
343 const unsigned long port_mask = GENMASK(gpio_reg_size, 0);
345 unsigned int out_state;
346 void __iomem *ports[] = {
347 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
348 &idio24gpio->reg->out16_23
350 const unsigned long out_mode_mask = BIT(1);
351 const unsigned int ttl_offset = 48;
352 const size_t ttl_i = BIT_WORD(ttl_offset);
353 const unsigned int word_offset = ttl_offset % BITS_PER_LONG;
354 const unsigned long ttl_mask = (mask[ttl_i] >> word_offset) & port_mask;
355 const unsigned long ttl_bits = (bits[ttl_i] >> word_offset) & ttl_mask;
357 /* set bits are processed a gpio port register at a time */
358 for (i = 0; i < ARRAY_SIZE(ports); i++) {
359 /* gpio offset in bits array */
360 bits_offset = i * gpio_reg_size;
362 /* check if any set bits for current port */
363 gpio_mask = (*mask >> bits_offset) & port_mask;
365 /* no set bits for this port so move on to next port */
369 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
371 /* process output lines */
372 out_state = ioread8(ports[i]) & ~gpio_mask;
373 out_state |= (*bits >> bits_offset) & gpio_mask;
374 iowrite8(out_state, ports[i]);
376 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
379 /* check if setting TTL lines and if they are in output mode */
380 if (!ttl_mask || !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
383 /* handle TTL output */
384 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
386 /* process output lines */
387 out_state = ioread8(&idio24gpio->reg->ttl_out0_7) & ~ttl_mask;
388 out_state |= ttl_bits;
389 iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
391 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
394 static void idio_24_irq_ack(struct irq_data *data)
398 static void idio_24_irq_mask(struct irq_data *data)
400 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
401 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
403 const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
404 unsigned char new_irq_mask;
405 const unsigned long bank_offset = bit_offset / 8;
406 unsigned char cos_enable_state;
408 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
410 idio24gpio->irq_mask &= ~BIT(bit_offset);
411 new_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
414 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
416 /* Disable Rising Edge detection */
417 cos_enable_state &= ~BIT(bank_offset);
418 /* Disable Falling Edge detection */
419 cos_enable_state &= ~BIT(bank_offset + 4);
421 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
424 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
427 static void idio_24_irq_unmask(struct irq_data *data)
429 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
430 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
432 unsigned char prev_irq_mask;
433 const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
434 const unsigned long bank_offset = bit_offset / 8;
435 unsigned char cos_enable_state;
437 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
439 prev_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
440 idio24gpio->irq_mask |= BIT(bit_offset);
442 if (!prev_irq_mask) {
443 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
445 /* Enable Rising Edge detection */
446 cos_enable_state |= BIT(bank_offset);
447 /* Enable Falling Edge detection */
448 cos_enable_state |= BIT(bank_offset + 4);
450 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
453 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
456 static int idio_24_irq_set_type(struct irq_data *data, unsigned int flow_type)
458 /* The only valid irq types are none and both-edges */
459 if (flow_type != IRQ_TYPE_NONE &&
460 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
466 static struct irq_chip idio_24_irqchip = {
467 .name = "pcie-idio-24",
468 .irq_ack = idio_24_irq_ack,
469 .irq_mask = idio_24_irq_mask,
470 .irq_unmask = idio_24_irq_unmask,
471 .irq_set_type = idio_24_irq_set_type
474 static irqreturn_t idio_24_irq_handler(int irq, void *dev_id)
476 struct idio_24_gpio *const idio24gpio = dev_id;
477 unsigned long irq_status;
478 struct gpio_chip *const chip = &idio24gpio->chip;
479 unsigned long irq_mask;
482 raw_spin_lock(&idio24gpio->lock);
484 /* Read Change-Of-State status */
485 irq_status = ioread32(&idio24gpio->reg->cos0_7);
487 raw_spin_unlock(&idio24gpio->lock);
489 /* Make sure our device generated IRQ */
493 /* Handle only unmasked IRQ */
494 irq_mask = idio24gpio->irq_mask & irq_status;
496 for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24)
497 generic_handle_irq(irq_find_mapping(chip->irq.domain,
500 raw_spin_lock(&idio24gpio->lock);
502 /* Clear Change-Of-State status */
503 iowrite32(irq_status, &idio24gpio->reg->cos0_7);
505 raw_spin_unlock(&idio24gpio->lock);
510 #define IDIO_24_NGPIO 56
511 static const char *idio_24_names[IDIO_24_NGPIO] = {
512 "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
513 "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
514 "OUT16", "OUT17", "OUT18", "OUT19", "OUT20", "OUT21", "OUT22", "OUT23",
515 "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
516 "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15",
517 "IIN16", "IIN17", "IIN18", "IIN19", "IIN20", "IIN21", "IIN22", "IIN23",
518 "TTL0", "TTL1", "TTL2", "TTL3", "TTL4", "TTL5", "TTL6", "TTL7"
521 static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
523 struct device *const dev = &pdev->dev;
524 struct idio_24_gpio *idio24gpio;
526 const size_t pci_plx_bar_index = 1;
527 const size_t pci_bar_index = 2;
528 const char *const name = pci_name(pdev);
530 idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
534 err = pcim_enable_device(pdev);
536 dev_err(dev, "Failed to enable PCI device (%d)\n", err);
540 err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name);
542 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
546 idio24gpio->plx = pcim_iomap_table(pdev)[pci_plx_bar_index];
547 idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
549 idio24gpio->chip.label = name;
550 idio24gpio->chip.parent = dev;
551 idio24gpio->chip.owner = THIS_MODULE;
552 idio24gpio->chip.base = -1;
553 idio24gpio->chip.ngpio = IDIO_24_NGPIO;
554 idio24gpio->chip.names = idio_24_names;
555 idio24gpio->chip.get_direction = idio_24_gpio_get_direction;
556 idio24gpio->chip.direction_input = idio_24_gpio_direction_input;
557 idio24gpio->chip.direction_output = idio_24_gpio_direction_output;
558 idio24gpio->chip.get = idio_24_gpio_get;
559 idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple;
560 idio24gpio->chip.set = idio_24_gpio_set;
561 idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple;
563 raw_spin_lock_init(&idio24gpio->lock);
565 /* Software board reset */
566 iowrite8(0, &idio24gpio->reg->soft_reset);
568 * enable PLX PEX8311 internal PCI wire interrupt and local interrupt
571 iowrite8((INTCSR_INTERNAL_PCI_WIRE | INTCSR_LOCAL_INPUT) >> 8,
572 idio24gpio->plx + PLX_PEX8311_PCI_LCS_INTCSR + 1);
574 err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
576 dev_err(dev, "GPIO registering failed (%d)\n", err);
580 err = gpiochip_irqchip_add(&idio24gpio->chip, &idio_24_irqchip, 0,
581 handle_edge_irq, IRQ_TYPE_NONE);
583 dev_err(dev, "Could not add irqchip (%d)\n", err);
587 err = devm_request_irq(dev, pdev->irq, idio_24_irq_handler, IRQF_SHARED,
590 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
597 static const struct pci_device_id idio_24_pci_dev_id[] = {
598 { PCI_DEVICE(0x494F, 0x0FD0) }, { PCI_DEVICE(0x494F, 0x0BD0) },
599 { PCI_DEVICE(0x494F, 0x07D0) }, { PCI_DEVICE(0x494F, 0x0FC0) },
602 MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id);
604 static struct pci_driver idio_24_driver = {
605 .name = "pcie-idio-24",
606 .id_table = idio_24_pci_dev_id,
607 .probe = idio_24_probe
610 module_pci_driver(idio_24_driver);
612 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
613 MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver");
614 MODULE_LICENSE("GPL v2");