1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * GPIO driver for the ACCES PCIe-IDIO-24 family 4 * Copyright (C) 2018 William Breathitt Gray 5 * 6 * This driver supports the following ACCES devices: PCIe-IDIO-24, 7 * PCIe-IDI-24, PCIe-IDO-24, and PCIe-IDIO-12. 8 */ 9 #include <linux/bitmap.h> 10 #include <linux/bitops.h> 11 #include <linux/device.h> 12 #include <linux/errno.h> 13 #include <linux/gpio/driver.h> 14 #include <linux/interrupt.h> 15 #include <linux/irqdesc.h> 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/pci.h> 19 #include <linux/spinlock.h> 20 #include <linux/types.h> 21 22 /* 23 * PLX PEX8311 PCI LCS_INTCSR Interrupt Control/Status 24 * 25 * Bit: Description 26 * 0: Enable Interrupt Sources (Bit 0) 27 * 1: Enable Interrupt Sources (Bit 1) 28 * 2: Generate Internal PCI Bus Internal SERR# Interrupt 29 * 3: Mailbox Interrupt Enable 30 * 4: Power Management Interrupt Enable 31 * 5: Power Management Interrupt 32 * 6: Slave Read Local Data Parity Check Error Enable 33 * 7: Slave Read Local Data Parity Check Error Status 34 * 8: Internal PCI Wire Interrupt Enable 35 * 9: PCI Express Doorbell Interrupt Enable 36 * 10: PCI Abort Interrupt Enable 37 * 11: Local Interrupt Input Enable 38 * 12: Retry Abort Enable 39 * 13: PCI Express Doorbell Interrupt Active 40 * 14: PCI Abort Interrupt Active 41 * 15: Local Interrupt Input Active 42 * 16: Local Interrupt Output Enable 43 * 17: Local Doorbell Interrupt Enable 44 * 18: DMA Channel 0 Interrupt Enable 45 * 19: DMA Channel 1 Interrupt Enable 46 * 20: Local Doorbell Interrupt Active 47 * 21: DMA Channel 0 Interrupt Active 48 * 22: DMA Channel 1 Interrupt Active 49 * 23: Built-In Self-Test (BIST) Interrupt Active 50 * 24: Direct Master was the Bus Master during a Master or Target Abort 51 * 25: DMA Channel 0 was the Bus Master during a Master or Target Abort 52 * 26: DMA Channel 1 was the Bus Master during a Master or Target Abort 53 * 27: Target Abort after internal 256 consecutive Master Retrys 54 * 28: PCI Bus wrote data to LCS_MBOX0 55 * 29: PCI Bus wrote data to LCS_MBOX1 56 * 30: PCI Bus wrote data to LCS_MBOX2 57 * 31: PCI Bus wrote data to LCS_MBOX3 58 */ 59 #define PLX_PEX8311_PCI_LCS_INTCSR 0x68 60 #define INTCSR_INTERNAL_PCI_WIRE BIT(8) 61 #define INTCSR_LOCAL_INPUT BIT(11) 62 63 /** 64 * struct idio_24_gpio_reg - GPIO device registers structure 65 * @out0_7: Read: FET Outputs 0-7 66 * Write: FET Outputs 0-7 67 * @out8_15: Read: FET Outputs 8-15 68 * Write: FET Outputs 8-15 69 * @out16_23: Read: FET Outputs 16-23 70 * Write: FET Outputs 16-23 71 * @ttl_out0_7: Read: TTL/CMOS Outputs 0-7 72 * Write: TTL/CMOS Outputs 0-7 73 * @in0_7: Read: Isolated Inputs 0-7 74 * Write: Reserved 75 * @in8_15: Read: Isolated Inputs 8-15 76 * Write: Reserved 77 * @in16_23: Read: Isolated Inputs 16-23 78 * Write: Reserved 79 * @ttl_in0_7: Read: TTL/CMOS Inputs 0-7 80 * Write: Reserved 81 * @cos0_7: Read: COS Status Inputs 0-7 82 * Write: COS Clear Inputs 0-7 83 * @cos8_15: Read: COS Status Inputs 8-15 84 * Write: COS Clear Inputs 8-15 85 * @cos16_23: Read: COS Status Inputs 16-23 86 * Write: COS Clear Inputs 16-23 87 * @cos_ttl0_7: Read: COS Status TTL/CMOS 0-7 88 * Write: COS Clear TTL/CMOS 0-7 89 * @ctl: Read: Control Register 90 * Write: Control Register 91 * @reserved: Read: Reserved 92 * Write: Reserved 93 * @cos_enable: Read: COS Enable 94 * Write: COS Enable 95 * @soft_reset: Read: IRQ Output Pin Status 96 * Write: Software Board Reset 97 */ 98 struct idio_24_gpio_reg { 99 u8 out0_7; 100 u8 out8_15; 101 u8 out16_23; 102 u8 ttl_out0_7; 103 u8 in0_7; 104 u8 in8_15; 105 u8 in16_23; 106 u8 ttl_in0_7; 107 u8 cos0_7; 108 u8 cos8_15; 109 u8 cos16_23; 110 u8 cos_ttl0_7; 111 u8 ctl; 112 u8 reserved; 113 u8 cos_enable; 114 u8 soft_reset; 115 }; 116 117 /** 118 * struct idio_24_gpio - GPIO device private data structure 119 * @chip: instance of the gpio_chip 120 * @lock: synchronization lock to prevent I/O race conditions 121 * @reg: I/O address offset for the GPIO device registers 122 * @irq_mask: I/O bits affected by interrupts 123 */ 124 struct idio_24_gpio { 125 struct gpio_chip chip; 126 raw_spinlock_t lock; 127 __u8 __iomem *plx; 128 struct idio_24_gpio_reg __iomem *reg; 129 unsigned long irq_mask; 130 }; 131 132 static int idio_24_gpio_get_direction(struct gpio_chip *chip, 133 unsigned int offset) 134 { 135 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 136 const unsigned long out_mode_mask = BIT(1); 137 138 /* FET Outputs */ 139 if (offset < 24) 140 return GPIO_LINE_DIRECTION_OUT; 141 142 /* Isolated Inputs */ 143 if (offset < 48) 144 return GPIO_LINE_DIRECTION_IN; 145 146 /* TTL/CMOS I/O */ 147 /* OUT MODE = 1 when TTL/CMOS Output Mode is set */ 148 if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) 149 return GPIO_LINE_DIRECTION_OUT; 150 151 return GPIO_LINE_DIRECTION_IN; 152 } 153 154 static int idio_24_gpio_direction_input(struct gpio_chip *chip, 155 unsigned int offset) 156 { 157 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 158 unsigned long flags; 159 unsigned int ctl_state; 160 const unsigned long out_mode_mask = BIT(1); 161 162 /* TTL/CMOS I/O */ 163 if (offset > 47) { 164 raw_spin_lock_irqsave(&idio24gpio->lock, flags); 165 166 /* Clear TTL/CMOS Output Mode */ 167 ctl_state = ioread8(&idio24gpio->reg->ctl) & ~out_mode_mask; 168 iowrite8(ctl_state, &idio24gpio->reg->ctl); 169 170 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 171 } 172 173 return 0; 174 } 175 176 static int idio_24_gpio_direction_output(struct gpio_chip *chip, 177 unsigned int offset, int value) 178 { 179 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 180 unsigned long flags; 181 unsigned int ctl_state; 182 const unsigned long out_mode_mask = BIT(1); 183 184 /* TTL/CMOS I/O */ 185 if (offset > 47) { 186 raw_spin_lock_irqsave(&idio24gpio->lock, flags); 187 188 /* Set TTL/CMOS Output Mode */ 189 ctl_state = ioread8(&idio24gpio->reg->ctl) | out_mode_mask; 190 iowrite8(ctl_state, &idio24gpio->reg->ctl); 191 192 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 193 } 194 195 chip->set(chip, offset, value); 196 return 0; 197 } 198 199 static int idio_24_gpio_get(struct gpio_chip *chip, unsigned int offset) 200 { 201 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 202 const unsigned long offset_mask = BIT(offset % 8); 203 const unsigned long out_mode_mask = BIT(1); 204 205 /* FET Outputs */ 206 if (offset < 8) 207 return !!(ioread8(&idio24gpio->reg->out0_7) & offset_mask); 208 209 if (offset < 16) 210 return !!(ioread8(&idio24gpio->reg->out8_15) & offset_mask); 211 212 if (offset < 24) 213 return !!(ioread8(&idio24gpio->reg->out16_23) & offset_mask); 214 215 /* Isolated Inputs */ 216 if (offset < 32) 217 return !!(ioread8(&idio24gpio->reg->in0_7) & offset_mask); 218 219 if (offset < 40) 220 return !!(ioread8(&idio24gpio->reg->in8_15) & offset_mask); 221 222 if (offset < 48) 223 return !!(ioread8(&idio24gpio->reg->in16_23) & offset_mask); 224 225 /* TTL/CMOS Outputs */ 226 if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) 227 return !!(ioread8(&idio24gpio->reg->ttl_out0_7) & offset_mask); 228 229 /* TTL/CMOS Inputs */ 230 return !!(ioread8(&idio24gpio->reg->ttl_in0_7) & offset_mask); 231 } 232 233 static int idio_24_gpio_get_multiple(struct gpio_chip *chip, 234 unsigned long *mask, unsigned long *bits) 235 { 236 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 237 unsigned long offset; 238 unsigned long gpio_mask; 239 void __iomem *ports[] = { 240 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, 241 &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7, 242 &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23, 243 }; 244 size_t index; 245 unsigned long port_state; 246 const unsigned long out_mode_mask = BIT(1); 247 248 /* clear bits array to a clean slate */ 249 bitmap_zero(bits, chip->ngpio); 250 251 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { 252 index = offset / 8; 253 254 /* read bits from current gpio port (port 6 is TTL GPIO) */ 255 if (index < 6) 256 port_state = ioread8(ports[index]); 257 else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) 258 port_state = ioread8(&idio24gpio->reg->ttl_out0_7); 259 else 260 port_state = ioread8(&idio24gpio->reg->ttl_in0_7); 261 262 port_state &= gpio_mask; 263 264 bitmap_set_value8(bits, port_state, offset); 265 } 266 267 return 0; 268 } 269 270 static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset, 271 int value) 272 { 273 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 274 const unsigned long out_mode_mask = BIT(1); 275 void __iomem *base; 276 const unsigned int mask = BIT(offset % 8); 277 unsigned long flags; 278 unsigned int out_state; 279 280 /* Isolated Inputs */ 281 if (offset > 23 && offset < 48) 282 return; 283 284 /* TTL/CMOS Inputs */ 285 if (offset > 47 && !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask)) 286 return; 287 288 /* TTL/CMOS Outputs */ 289 if (offset > 47) 290 base = &idio24gpio->reg->ttl_out0_7; 291 /* FET Outputs */ 292 else if (offset > 15) 293 base = &idio24gpio->reg->out16_23; 294 else if (offset > 7) 295 base = &idio24gpio->reg->out8_15; 296 else 297 base = &idio24gpio->reg->out0_7; 298 299 raw_spin_lock_irqsave(&idio24gpio->lock, flags); 300 301 if (value) 302 out_state = ioread8(base) | mask; 303 else 304 out_state = ioread8(base) & ~mask; 305 306 iowrite8(out_state, base); 307 308 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 309 } 310 311 static void idio_24_gpio_set_multiple(struct gpio_chip *chip, 312 unsigned long *mask, unsigned long *bits) 313 { 314 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 315 unsigned long offset; 316 unsigned long gpio_mask; 317 void __iomem *ports[] = { 318 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, 319 &idio24gpio->reg->out16_23 320 }; 321 size_t index; 322 unsigned long bitmask; 323 unsigned long flags; 324 unsigned long out_state; 325 const unsigned long out_mode_mask = BIT(1); 326 327 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { 328 index = offset / 8; 329 330 bitmask = bitmap_get_value8(bits, offset) & gpio_mask; 331 332 raw_spin_lock_irqsave(&idio24gpio->lock, flags); 333 334 /* read bits from current gpio port (port 6 is TTL GPIO) */ 335 if (index < 6) { 336 out_state = ioread8(ports[index]); 337 } else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) { 338 out_state = ioread8(&idio24gpio->reg->ttl_out0_7); 339 } else { 340 /* skip TTL GPIO if set for input */ 341 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 342 continue; 343 } 344 345 /* set requested bit states */ 346 out_state &= ~gpio_mask; 347 out_state |= bitmask; 348 349 /* write bits for current gpio port (port 6 is TTL GPIO) */ 350 if (index < 6) 351 iowrite8(out_state, ports[index]); 352 else 353 iowrite8(out_state, &idio24gpio->reg->ttl_out0_7); 354 355 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 356 } 357 } 358 359 static void idio_24_irq_ack(struct irq_data *data) 360 { 361 } 362 363 static void idio_24_irq_mask(struct irq_data *data) 364 { 365 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data); 366 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 367 unsigned long flags; 368 const unsigned long bit_offset = irqd_to_hwirq(data) - 24; 369 unsigned char new_irq_mask; 370 const unsigned long bank_offset = bit_offset / 8; 371 unsigned char cos_enable_state; 372 373 raw_spin_lock_irqsave(&idio24gpio->lock, flags); 374 375 idio24gpio->irq_mask &= ~BIT(bit_offset); 376 new_irq_mask = idio24gpio->irq_mask >> bank_offset * 8; 377 378 if (!new_irq_mask) { 379 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable); 380 381 /* Disable Rising Edge detection */ 382 cos_enable_state &= ~BIT(bank_offset); 383 /* Disable Falling Edge detection */ 384 cos_enable_state &= ~BIT(bank_offset + 4); 385 386 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable); 387 } 388 389 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 390 391 gpiochip_disable_irq(chip, irqd_to_hwirq(data)); 392 } 393 394 static void idio_24_irq_unmask(struct irq_data *data) 395 { 396 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data); 397 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 398 unsigned long flags; 399 unsigned char prev_irq_mask; 400 const unsigned long bit_offset = irqd_to_hwirq(data) - 24; 401 const unsigned long bank_offset = bit_offset / 8; 402 unsigned char cos_enable_state; 403 404 gpiochip_enable_irq(chip, irqd_to_hwirq(data)); 405 406 raw_spin_lock_irqsave(&idio24gpio->lock, flags); 407 408 prev_irq_mask = idio24gpio->irq_mask >> bank_offset * 8; 409 idio24gpio->irq_mask |= BIT(bit_offset); 410 411 if (!prev_irq_mask) { 412 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable); 413 414 /* Enable Rising Edge detection */ 415 cos_enable_state |= BIT(bank_offset); 416 /* Enable Falling Edge detection */ 417 cos_enable_state |= BIT(bank_offset + 4); 418 419 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable); 420 } 421 422 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 423 } 424 425 static int idio_24_irq_set_type(struct irq_data *data, unsigned int flow_type) 426 { 427 /* The only valid irq types are none and both-edges */ 428 if (flow_type != IRQ_TYPE_NONE && 429 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH) 430 return -EINVAL; 431 432 return 0; 433 } 434 435 static const struct irq_chip idio_24_irqchip = { 436 .name = "pcie-idio-24", 437 .irq_ack = idio_24_irq_ack, 438 .irq_mask = idio_24_irq_mask, 439 .irq_unmask = idio_24_irq_unmask, 440 .irq_set_type = idio_24_irq_set_type, 441 .flags = IRQCHIP_IMMUTABLE, 442 GPIOCHIP_IRQ_RESOURCE_HELPERS, 443 }; 444 445 static irqreturn_t idio_24_irq_handler(int irq, void *dev_id) 446 { 447 struct idio_24_gpio *const idio24gpio = dev_id; 448 unsigned long irq_status; 449 struct gpio_chip *const chip = &idio24gpio->chip; 450 unsigned long irq_mask; 451 int gpio; 452 453 raw_spin_lock(&idio24gpio->lock); 454 455 /* Read Change-Of-State status */ 456 irq_status = ioread32(&idio24gpio->reg->cos0_7); 457 458 raw_spin_unlock(&idio24gpio->lock); 459 460 /* Make sure our device generated IRQ */ 461 if (!irq_status) 462 return IRQ_NONE; 463 464 /* Handle only unmasked IRQ */ 465 irq_mask = idio24gpio->irq_mask & irq_status; 466 467 for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24) 468 generic_handle_domain_irq(chip->irq.domain, gpio + 24); 469 470 raw_spin_lock(&idio24gpio->lock); 471 472 /* Clear Change-Of-State status */ 473 iowrite32(irq_status, &idio24gpio->reg->cos0_7); 474 475 raw_spin_unlock(&idio24gpio->lock); 476 477 return IRQ_HANDLED; 478 } 479 480 #define IDIO_24_NGPIO 56 481 static const char *idio_24_names[IDIO_24_NGPIO] = { 482 "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7", 483 "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15", 484 "OUT16", "OUT17", "OUT18", "OUT19", "OUT20", "OUT21", "OUT22", "OUT23", 485 "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7", 486 "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15", 487 "IIN16", "IIN17", "IIN18", "IIN19", "IIN20", "IIN21", "IIN22", "IIN23", 488 "TTL0", "TTL1", "TTL2", "TTL3", "TTL4", "TTL5", "TTL6", "TTL7" 489 }; 490 491 static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id) 492 { 493 struct device *const dev = &pdev->dev; 494 struct idio_24_gpio *idio24gpio; 495 int err; 496 const size_t pci_plx_bar_index = 1; 497 const size_t pci_bar_index = 2; 498 const char *const name = pci_name(pdev); 499 struct gpio_irq_chip *girq; 500 501 idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL); 502 if (!idio24gpio) 503 return -ENOMEM; 504 505 err = pcim_enable_device(pdev); 506 if (err) { 507 dev_err(dev, "Failed to enable PCI device (%d)\n", err); 508 return err; 509 } 510 511 err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name); 512 if (err) { 513 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err); 514 return err; 515 } 516 517 idio24gpio->plx = pcim_iomap_table(pdev)[pci_plx_bar_index]; 518 idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index]; 519 520 idio24gpio->chip.label = name; 521 idio24gpio->chip.parent = dev; 522 idio24gpio->chip.owner = THIS_MODULE; 523 idio24gpio->chip.base = -1; 524 idio24gpio->chip.ngpio = IDIO_24_NGPIO; 525 idio24gpio->chip.names = idio_24_names; 526 idio24gpio->chip.get_direction = idio_24_gpio_get_direction; 527 idio24gpio->chip.direction_input = idio_24_gpio_direction_input; 528 idio24gpio->chip.direction_output = idio_24_gpio_direction_output; 529 idio24gpio->chip.get = idio_24_gpio_get; 530 idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple; 531 idio24gpio->chip.set = idio_24_gpio_set; 532 idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple; 533 534 girq = &idio24gpio->chip.irq; 535 gpio_irq_chip_set_chip(girq, &idio_24_irqchip); 536 /* This will let us handle the parent IRQ in the driver */ 537 girq->parent_handler = NULL; 538 girq->num_parents = 0; 539 girq->parents = NULL; 540 girq->default_type = IRQ_TYPE_NONE; 541 girq->handler = handle_edge_irq; 542 543 raw_spin_lock_init(&idio24gpio->lock); 544 545 /* Software board reset */ 546 iowrite8(0, &idio24gpio->reg->soft_reset); 547 /* 548 * enable PLX PEX8311 internal PCI wire interrupt and local interrupt 549 * input 550 */ 551 iowrite8((INTCSR_INTERNAL_PCI_WIRE | INTCSR_LOCAL_INPUT) >> 8, 552 idio24gpio->plx + PLX_PEX8311_PCI_LCS_INTCSR + 1); 553 554 err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio); 555 if (err) { 556 dev_err(dev, "GPIO registering failed (%d)\n", err); 557 return err; 558 } 559 560 err = devm_request_irq(dev, pdev->irq, idio_24_irq_handler, IRQF_SHARED, 561 name, idio24gpio); 562 if (err) { 563 dev_err(dev, "IRQ handler registering failed (%d)\n", err); 564 return err; 565 } 566 567 return 0; 568 } 569 570 static const struct pci_device_id idio_24_pci_dev_id[] = { 571 { PCI_DEVICE(0x494F, 0x0FD0) }, { PCI_DEVICE(0x494F, 0x0BD0) }, 572 { PCI_DEVICE(0x494F, 0x07D0) }, { PCI_DEVICE(0x494F, 0x0FC0) }, 573 { 0 } 574 }; 575 MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id); 576 577 static struct pci_driver idio_24_driver = { 578 .name = "pcie-idio-24", 579 .id_table = idio_24_pci_dev_id, 580 .probe = idio_24_probe 581 }; 582 583 module_pci_driver(idio_24_driver); 584 585 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); 586 MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver"); 587 MODULE_LICENSE("GPL v2"); 588