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