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