0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/bitmap.h>
0019 #include <linux/bitops.h>
0020 #include <linux/device.h>
0021 #include <linux/errno.h>
0022 #include <linux/gpio/driver.h>
0023 #include <linux/interrupt.h>
0024 #include <linux/irqdesc.h>
0025 #include <linux/kernel.h>
0026 #include <linux/module.h>
0027 #include <linux/pci.h>
0028 #include <linux/spinlock.h>
0029 #include <linux/types.h>
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 #define PLX_PEX8311_PCI_LCS_INTCSR 0x68
0069 #define INTCSR_INTERNAL_PCI_WIRE BIT(8)
0070 #define INTCSR_LOCAL_INPUT BIT(11)
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 struct idio_24_gpio_reg {
0108 u8 out0_7;
0109 u8 out8_15;
0110 u8 out16_23;
0111 u8 ttl_out0_7;
0112 u8 in0_7;
0113 u8 in8_15;
0114 u8 in16_23;
0115 u8 ttl_in0_7;
0116 u8 cos0_7;
0117 u8 cos8_15;
0118 u8 cos16_23;
0119 u8 cos_ttl0_7;
0120 u8 ctl;
0121 u8 reserved;
0122 u8 cos_enable;
0123 u8 soft_reset;
0124 };
0125
0126
0127
0128
0129
0130
0131
0132
0133 struct idio_24_gpio {
0134 struct gpio_chip chip;
0135 raw_spinlock_t lock;
0136 __u8 __iomem *plx;
0137 struct idio_24_gpio_reg __iomem *reg;
0138 unsigned long irq_mask;
0139 };
0140
0141 static int idio_24_gpio_get_direction(struct gpio_chip *chip,
0142 unsigned int offset)
0143 {
0144 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0145 const unsigned long out_mode_mask = BIT(1);
0146
0147
0148 if (offset < 24)
0149 return GPIO_LINE_DIRECTION_OUT;
0150
0151
0152 if (offset < 48)
0153 return GPIO_LINE_DIRECTION_IN;
0154
0155
0156
0157 if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
0158 return GPIO_LINE_DIRECTION_OUT;
0159
0160 return GPIO_LINE_DIRECTION_IN;
0161 }
0162
0163 static int idio_24_gpio_direction_input(struct gpio_chip *chip,
0164 unsigned int offset)
0165 {
0166 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0167 unsigned long flags;
0168 unsigned int ctl_state;
0169 const unsigned long out_mode_mask = BIT(1);
0170
0171
0172 if (offset > 47) {
0173 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0174
0175
0176 ctl_state = ioread8(&idio24gpio->reg->ctl) & ~out_mode_mask;
0177 iowrite8(ctl_state, &idio24gpio->reg->ctl);
0178
0179 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0180 }
0181
0182 return 0;
0183 }
0184
0185 static int idio_24_gpio_direction_output(struct gpio_chip *chip,
0186 unsigned int offset, int value)
0187 {
0188 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0189 unsigned long flags;
0190 unsigned int ctl_state;
0191 const unsigned long out_mode_mask = BIT(1);
0192
0193
0194 if (offset > 47) {
0195 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0196
0197
0198 ctl_state = ioread8(&idio24gpio->reg->ctl) | out_mode_mask;
0199 iowrite8(ctl_state, &idio24gpio->reg->ctl);
0200
0201 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0202 }
0203
0204 chip->set(chip, offset, value);
0205 return 0;
0206 }
0207
0208 static int idio_24_gpio_get(struct gpio_chip *chip, unsigned int offset)
0209 {
0210 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0211 const unsigned long offset_mask = BIT(offset % 8);
0212 const unsigned long out_mode_mask = BIT(1);
0213
0214
0215 if (offset < 8)
0216 return !!(ioread8(&idio24gpio->reg->out0_7) & offset_mask);
0217
0218 if (offset < 16)
0219 return !!(ioread8(&idio24gpio->reg->out8_15) & offset_mask);
0220
0221 if (offset < 24)
0222 return !!(ioread8(&idio24gpio->reg->out16_23) & offset_mask);
0223
0224
0225 if (offset < 32)
0226 return !!(ioread8(&idio24gpio->reg->in0_7) & offset_mask);
0227
0228 if (offset < 40)
0229 return !!(ioread8(&idio24gpio->reg->in8_15) & offset_mask);
0230
0231 if (offset < 48)
0232 return !!(ioread8(&idio24gpio->reg->in16_23) & offset_mask);
0233
0234
0235 if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
0236 return !!(ioread8(&idio24gpio->reg->ttl_out0_7) & offset_mask);
0237
0238
0239 return !!(ioread8(&idio24gpio->reg->ttl_in0_7) & offset_mask);
0240 }
0241
0242 static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
0243 unsigned long *mask, unsigned long *bits)
0244 {
0245 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0246 unsigned long offset;
0247 unsigned long gpio_mask;
0248 void __iomem *ports[] = {
0249 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
0250 &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
0251 &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
0252 };
0253 size_t index;
0254 unsigned long port_state;
0255 const unsigned long out_mode_mask = BIT(1);
0256
0257
0258 bitmap_zero(bits, chip->ngpio);
0259
0260 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
0261 index = offset / 8;
0262
0263
0264 if (index < 6)
0265 port_state = ioread8(ports[index]);
0266 else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
0267 port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
0268 else
0269 port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
0270
0271 port_state &= gpio_mask;
0272
0273 bitmap_set_value8(bits, port_state, offset);
0274 }
0275
0276 return 0;
0277 }
0278
0279 static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
0280 int value)
0281 {
0282 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0283 const unsigned long out_mode_mask = BIT(1);
0284 void __iomem *base;
0285 const unsigned int mask = BIT(offset % 8);
0286 unsigned long flags;
0287 unsigned int out_state;
0288
0289
0290 if (offset > 23 && offset < 48)
0291 return;
0292
0293
0294 if (offset > 47 && !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
0295 return;
0296
0297
0298 if (offset > 47)
0299 base = &idio24gpio->reg->ttl_out0_7;
0300
0301 else if (offset > 15)
0302 base = &idio24gpio->reg->out16_23;
0303 else if (offset > 7)
0304 base = &idio24gpio->reg->out8_15;
0305 else
0306 base = &idio24gpio->reg->out0_7;
0307
0308 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0309
0310 if (value)
0311 out_state = ioread8(base) | mask;
0312 else
0313 out_state = ioread8(base) & ~mask;
0314
0315 iowrite8(out_state, base);
0316
0317 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0318 }
0319
0320 static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
0321 unsigned long *mask, unsigned long *bits)
0322 {
0323 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0324 unsigned long offset;
0325 unsigned long gpio_mask;
0326 void __iomem *ports[] = {
0327 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
0328 &idio24gpio->reg->out16_23
0329 };
0330 size_t index;
0331 unsigned long bitmask;
0332 unsigned long flags;
0333 unsigned long out_state;
0334 const unsigned long out_mode_mask = BIT(1);
0335
0336 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
0337 index = offset / 8;
0338
0339 bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
0340
0341 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0342
0343
0344 if (index < 6) {
0345 out_state = ioread8(ports[index]);
0346 } else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) {
0347 out_state = ioread8(&idio24gpio->reg->ttl_out0_7);
0348 } else {
0349
0350 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0351 continue;
0352 }
0353
0354
0355 out_state &= ~gpio_mask;
0356 out_state |= bitmask;
0357
0358
0359 if (index < 6)
0360 iowrite8(out_state, ports[index]);
0361 else
0362 iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
0363
0364 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0365 }
0366 }
0367
0368 static void idio_24_irq_ack(struct irq_data *data)
0369 {
0370 }
0371
0372 static void idio_24_irq_mask(struct irq_data *data)
0373 {
0374 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
0375 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0376 unsigned long flags;
0377 const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
0378 unsigned char new_irq_mask;
0379 const unsigned long bank_offset = bit_offset / 8;
0380 unsigned char cos_enable_state;
0381
0382 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0383
0384 idio24gpio->irq_mask &= ~BIT(bit_offset);
0385 new_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
0386
0387 if (!new_irq_mask) {
0388 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
0389
0390
0391 cos_enable_state &= ~BIT(bank_offset);
0392
0393 cos_enable_state &= ~BIT(bank_offset + 4);
0394
0395 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
0396 }
0397
0398 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0399 }
0400
0401 static void idio_24_irq_unmask(struct irq_data *data)
0402 {
0403 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
0404 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0405 unsigned long flags;
0406 unsigned char prev_irq_mask;
0407 const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
0408 const unsigned long bank_offset = bit_offset / 8;
0409 unsigned char cos_enable_state;
0410
0411 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0412
0413 prev_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
0414 idio24gpio->irq_mask |= BIT(bit_offset);
0415
0416 if (!prev_irq_mask) {
0417 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
0418
0419
0420 cos_enable_state |= BIT(bank_offset);
0421
0422 cos_enable_state |= BIT(bank_offset + 4);
0423
0424 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
0425 }
0426
0427 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0428 }
0429
0430 static int idio_24_irq_set_type(struct irq_data *data, unsigned int flow_type)
0431 {
0432
0433 if (flow_type != IRQ_TYPE_NONE &&
0434 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
0435 return -EINVAL;
0436
0437 return 0;
0438 }
0439
0440 static struct irq_chip idio_24_irqchip = {
0441 .name = "pcie-idio-24",
0442 .irq_ack = idio_24_irq_ack,
0443 .irq_mask = idio_24_irq_mask,
0444 .irq_unmask = idio_24_irq_unmask,
0445 .irq_set_type = idio_24_irq_set_type
0446 };
0447
0448 static irqreturn_t idio_24_irq_handler(int irq, void *dev_id)
0449 {
0450 struct idio_24_gpio *const idio24gpio = dev_id;
0451 unsigned long irq_status;
0452 struct gpio_chip *const chip = &idio24gpio->chip;
0453 unsigned long irq_mask;
0454 int gpio;
0455
0456 raw_spin_lock(&idio24gpio->lock);
0457
0458
0459 irq_status = ioread32(&idio24gpio->reg->cos0_7);
0460
0461 raw_spin_unlock(&idio24gpio->lock);
0462
0463
0464 if (!irq_status)
0465 return IRQ_NONE;
0466
0467
0468 irq_mask = idio24gpio->irq_mask & irq_status;
0469
0470 for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24)
0471 generic_handle_domain_irq(chip->irq.domain, gpio + 24);
0472
0473 raw_spin_lock(&idio24gpio->lock);
0474
0475
0476 iowrite32(irq_status, &idio24gpio->reg->cos0_7);
0477
0478 raw_spin_unlock(&idio24gpio->lock);
0479
0480 return IRQ_HANDLED;
0481 }
0482
0483 #define IDIO_24_NGPIO 56
0484 static const char *idio_24_names[IDIO_24_NGPIO] = {
0485 "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
0486 "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
0487 "OUT16", "OUT17", "OUT18", "OUT19", "OUT20", "OUT21", "OUT22", "OUT23",
0488 "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
0489 "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15",
0490 "IIN16", "IIN17", "IIN18", "IIN19", "IIN20", "IIN21", "IIN22", "IIN23",
0491 "TTL0", "TTL1", "TTL2", "TTL3", "TTL4", "TTL5", "TTL6", "TTL7"
0492 };
0493
0494 static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
0495 {
0496 struct device *const dev = &pdev->dev;
0497 struct idio_24_gpio *idio24gpio;
0498 int err;
0499 const size_t pci_plx_bar_index = 1;
0500 const size_t pci_bar_index = 2;
0501 const char *const name = pci_name(pdev);
0502 struct gpio_irq_chip *girq;
0503
0504 idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
0505 if (!idio24gpio)
0506 return -ENOMEM;
0507
0508 err = pcim_enable_device(pdev);
0509 if (err) {
0510 dev_err(dev, "Failed to enable PCI device (%d)\n", err);
0511 return err;
0512 }
0513
0514 err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name);
0515 if (err) {
0516 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
0517 return err;
0518 }
0519
0520 idio24gpio->plx = pcim_iomap_table(pdev)[pci_plx_bar_index];
0521 idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
0522
0523 idio24gpio->chip.label = name;
0524 idio24gpio->chip.parent = dev;
0525 idio24gpio->chip.owner = THIS_MODULE;
0526 idio24gpio->chip.base = -1;
0527 idio24gpio->chip.ngpio = IDIO_24_NGPIO;
0528 idio24gpio->chip.names = idio_24_names;
0529 idio24gpio->chip.get_direction = idio_24_gpio_get_direction;
0530 idio24gpio->chip.direction_input = idio_24_gpio_direction_input;
0531 idio24gpio->chip.direction_output = idio_24_gpio_direction_output;
0532 idio24gpio->chip.get = idio_24_gpio_get;
0533 idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple;
0534 idio24gpio->chip.set = idio_24_gpio_set;
0535 idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple;
0536
0537 girq = &idio24gpio->chip.irq;
0538 girq->chip = &idio_24_irqchip;
0539
0540 girq->parent_handler = NULL;
0541 girq->num_parents = 0;
0542 girq->parents = NULL;
0543 girq->default_type = IRQ_TYPE_NONE;
0544 girq->handler = handle_edge_irq;
0545
0546 raw_spin_lock_init(&idio24gpio->lock);
0547
0548
0549 iowrite8(0, &idio24gpio->reg->soft_reset);
0550
0551
0552
0553
0554 iowrite8((INTCSR_INTERNAL_PCI_WIRE | INTCSR_LOCAL_INPUT) >> 8,
0555 idio24gpio->plx + PLX_PEX8311_PCI_LCS_INTCSR + 1);
0556
0557 err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
0558 if (err) {
0559 dev_err(dev, "GPIO registering failed (%d)\n", err);
0560 return err;
0561 }
0562
0563 err = devm_request_irq(dev, pdev->irq, idio_24_irq_handler, IRQF_SHARED,
0564 name, idio24gpio);
0565 if (err) {
0566 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
0567 return err;
0568 }
0569
0570 return 0;
0571 }
0572
0573 static const struct pci_device_id idio_24_pci_dev_id[] = {
0574 { PCI_DEVICE(0x494F, 0x0FD0) }, { PCI_DEVICE(0x494F, 0x0BD0) },
0575 { PCI_DEVICE(0x494F, 0x07D0) }, { PCI_DEVICE(0x494F, 0x0FC0) },
0576 { 0 }
0577 };
0578 MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id);
0579
0580 static struct pci_driver idio_24_driver = {
0581 .name = "pcie-idio-24",
0582 .id_table = idio_24_pci_dev_id,
0583 .probe = idio_24_probe
0584 };
0585
0586 module_pci_driver(idio_24_driver);
0587
0588 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
0589 MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver");
0590 MODULE_LICENSE("GPL v2");