Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * GPIO driver for the ACCES PCI-IDIO-16
0004  * Copyright (C) 2017 William Breathitt Gray
0005  */
0006 #include <linux/bitmap.h>
0007 #include <linux/bitops.h>
0008 #include <linux/device.h>
0009 #include <linux/errno.h>
0010 #include <linux/gpio/driver.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/irqdesc.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/pci.h>
0016 #include <linux/spinlock.h>
0017 #include <linux/types.h>
0018 
0019 /**
0020  * struct idio_16_gpio_reg - GPIO device registers structure
0021  * @out0_7: Read: FET Drive Outputs 0-7
0022  *      Write: FET Drive Outputs 0-7
0023  * @in0_7:  Read: Isolated Inputs 0-7
0024  *      Write: Clear Interrupt
0025  * @irq_ctl:    Read: Enable IRQ
0026  *      Write: Disable IRQ
0027  * @filter_ctl: Read: Activate Input Filters 0-15
0028  *      Write: Deactivate Input Filters 0-15
0029  * @out8_15:    Read: FET Drive Outputs 8-15
0030  *      Write: FET Drive Outputs 8-15
0031  * @in8_15: Read: Isolated Inputs 8-15
0032  *      Write: Unused
0033  * @irq_status: Read: Interrupt status
0034  *      Write: Unused
0035  */
0036 struct idio_16_gpio_reg {
0037     u8 out0_7;
0038     u8 in0_7;
0039     u8 irq_ctl;
0040     u8 filter_ctl;
0041     u8 out8_15;
0042     u8 in8_15;
0043     u8 irq_status;
0044 };
0045 
0046 /**
0047  * struct idio_16_gpio - GPIO device private data structure
0048  * @chip:   instance of the gpio_chip
0049  * @lock:   synchronization lock to prevent I/O race conditions
0050  * @reg:    I/O address offset for the GPIO device registers
0051  * @irq_mask:   I/O bits affected by interrupts
0052  */
0053 struct idio_16_gpio {
0054     struct gpio_chip chip;
0055     raw_spinlock_t lock;
0056     struct idio_16_gpio_reg __iomem *reg;
0057     unsigned long irq_mask;
0058 };
0059 
0060 static int idio_16_gpio_get_direction(struct gpio_chip *chip,
0061     unsigned int offset)
0062 {
0063     if (offset > 15)
0064         return GPIO_LINE_DIRECTION_IN;
0065 
0066     return GPIO_LINE_DIRECTION_OUT;
0067 }
0068 
0069 static int idio_16_gpio_direction_input(struct gpio_chip *chip,
0070     unsigned int offset)
0071 {
0072     return 0;
0073 }
0074 
0075 static int idio_16_gpio_direction_output(struct gpio_chip *chip,
0076     unsigned int offset, int value)
0077 {
0078     chip->set(chip, offset, value);
0079     return 0;
0080 }
0081 
0082 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
0083 {
0084     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0085     unsigned long mask = BIT(offset);
0086 
0087     if (offset < 8)
0088         return !!(ioread8(&idio16gpio->reg->out0_7) & mask);
0089 
0090     if (offset < 16)
0091         return !!(ioread8(&idio16gpio->reg->out8_15) & (mask >> 8));
0092 
0093     if (offset < 24)
0094         return !!(ioread8(&idio16gpio->reg->in0_7) & (mask >> 16));
0095 
0096     return !!(ioread8(&idio16gpio->reg->in8_15) & (mask >> 24));
0097 }
0098 
0099 static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
0100     unsigned long *mask, unsigned long *bits)
0101 {
0102     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0103     unsigned long offset;
0104     unsigned long gpio_mask;
0105     void __iomem *ports[] = {
0106         &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
0107         &idio16gpio->reg->in0_7, &idio16gpio->reg->in8_15,
0108     };
0109     void __iomem *port_addr;
0110     unsigned long port_state;
0111 
0112     /* clear bits array to a clean slate */
0113     bitmap_zero(bits, chip->ngpio);
0114 
0115     for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
0116         port_addr = ports[offset / 8];
0117         port_state = ioread8(port_addr) & gpio_mask;
0118 
0119         bitmap_set_value8(bits, port_state, offset);
0120     }
0121 
0122     return 0;
0123 }
0124 
0125 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
0126     int value)
0127 {
0128     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0129     unsigned int mask = BIT(offset);
0130     void __iomem *base;
0131     unsigned long flags;
0132     unsigned int out_state;
0133 
0134     if (offset > 15)
0135         return;
0136 
0137     if (offset > 7) {
0138         mask >>= 8;
0139         base = &idio16gpio->reg->out8_15;
0140     } else
0141         base = &idio16gpio->reg->out0_7;
0142 
0143     raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0144 
0145     if (value)
0146         out_state = ioread8(base) | mask;
0147     else
0148         out_state = ioread8(base) & ~mask;
0149 
0150     iowrite8(out_state, base);
0151 
0152     raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0153 }
0154 
0155 static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
0156     unsigned long *mask, unsigned long *bits)
0157 {
0158     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0159     unsigned long offset;
0160     unsigned long gpio_mask;
0161     void __iomem *ports[] = {
0162         &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
0163     };
0164     size_t index;
0165     void __iomem *port_addr;
0166     unsigned long bitmask;
0167     unsigned long flags;
0168     unsigned long out_state;
0169 
0170     for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
0171         index = offset / 8;
0172         port_addr = ports[index];
0173 
0174         bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
0175 
0176         raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0177 
0178         out_state = ioread8(port_addr) & ~gpio_mask;
0179         out_state |= bitmask;
0180         iowrite8(out_state, port_addr);
0181 
0182         raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0183     }
0184 }
0185 
0186 static void idio_16_irq_ack(struct irq_data *data)
0187 {
0188 }
0189 
0190 static void idio_16_irq_mask(struct irq_data *data)
0191 {
0192     struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0193     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0194     const unsigned long mask = BIT(irqd_to_hwirq(data));
0195     unsigned long flags;
0196 
0197     idio16gpio->irq_mask &= ~mask;
0198 
0199     if (!idio16gpio->irq_mask) {
0200         raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0201 
0202         iowrite8(0, &idio16gpio->reg->irq_ctl);
0203 
0204         raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0205     }
0206 }
0207 
0208 static void idio_16_irq_unmask(struct irq_data *data)
0209 {
0210     struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0211     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0212     const unsigned long mask = BIT(irqd_to_hwirq(data));
0213     const unsigned long prev_irq_mask = idio16gpio->irq_mask;
0214     unsigned long flags;
0215 
0216     idio16gpio->irq_mask |= mask;
0217 
0218     if (!prev_irq_mask) {
0219         raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0220 
0221         ioread8(&idio16gpio->reg->irq_ctl);
0222 
0223         raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0224     }
0225 }
0226 
0227 static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
0228 {
0229     /* The only valid irq types are none and both-edges */
0230     if (flow_type != IRQ_TYPE_NONE &&
0231         (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
0232         return -EINVAL;
0233 
0234     return 0;
0235 }
0236 
0237 static struct irq_chip idio_16_irqchip = {
0238     .name = "pci-idio-16",
0239     .irq_ack = idio_16_irq_ack,
0240     .irq_mask = idio_16_irq_mask,
0241     .irq_unmask = idio_16_irq_unmask,
0242     .irq_set_type = idio_16_irq_set_type
0243 };
0244 
0245 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
0246 {
0247     struct idio_16_gpio *const idio16gpio = dev_id;
0248     unsigned int irq_status;
0249     struct gpio_chip *const chip = &idio16gpio->chip;
0250     int gpio;
0251 
0252     raw_spin_lock(&idio16gpio->lock);
0253 
0254     irq_status = ioread8(&idio16gpio->reg->irq_status);
0255 
0256     raw_spin_unlock(&idio16gpio->lock);
0257 
0258     /* Make sure our device generated IRQ */
0259     if (!(irq_status & 0x3) || !(irq_status & 0x4))
0260         return IRQ_NONE;
0261 
0262     for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
0263         generic_handle_domain_irq(chip->irq.domain, gpio);
0264 
0265     raw_spin_lock(&idio16gpio->lock);
0266 
0267     /* Clear interrupt */
0268     iowrite8(0, &idio16gpio->reg->in0_7);
0269 
0270     raw_spin_unlock(&idio16gpio->lock);
0271 
0272     return IRQ_HANDLED;
0273 }
0274 
0275 #define IDIO_16_NGPIO 32
0276 static const char *idio_16_names[IDIO_16_NGPIO] = {
0277     "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
0278     "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
0279     "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
0280     "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
0281 };
0282 
0283 static int idio_16_irq_init_hw(struct gpio_chip *gc)
0284 {
0285     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
0286 
0287     /* Disable IRQ by default and clear any pending interrupt */
0288     iowrite8(0, &idio16gpio->reg->irq_ctl);
0289     iowrite8(0, &idio16gpio->reg->in0_7);
0290 
0291     return 0;
0292 }
0293 
0294 static int idio_16_probe(struct pci_dev *pdev, const struct pci_device_id *id)
0295 {
0296     struct device *const dev = &pdev->dev;
0297     struct idio_16_gpio *idio16gpio;
0298     int err;
0299     const size_t pci_bar_index = 2;
0300     const char *const name = pci_name(pdev);
0301     struct gpio_irq_chip *girq;
0302 
0303     idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
0304     if (!idio16gpio)
0305         return -ENOMEM;
0306 
0307     err = pcim_enable_device(pdev);
0308     if (err) {
0309         dev_err(dev, "Failed to enable PCI device (%d)\n", err);
0310         return err;
0311     }
0312 
0313     err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
0314     if (err) {
0315         dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
0316         return err;
0317     }
0318 
0319     idio16gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
0320 
0321     /* Deactivate input filters */
0322     iowrite8(0, &idio16gpio->reg->filter_ctl);
0323 
0324     idio16gpio->chip.label = name;
0325     idio16gpio->chip.parent = dev;
0326     idio16gpio->chip.owner = THIS_MODULE;
0327     idio16gpio->chip.base = -1;
0328     idio16gpio->chip.ngpio = IDIO_16_NGPIO;
0329     idio16gpio->chip.names = idio_16_names;
0330     idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
0331     idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
0332     idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
0333     idio16gpio->chip.get = idio_16_gpio_get;
0334     idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
0335     idio16gpio->chip.set = idio_16_gpio_set;
0336     idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
0337 
0338     girq = &idio16gpio->chip.irq;
0339     girq->chip = &idio_16_irqchip;
0340     /* This will let us handle the parent IRQ in the driver */
0341     girq->parent_handler = NULL;
0342     girq->num_parents = 0;
0343     girq->parents = NULL;
0344     girq->default_type = IRQ_TYPE_NONE;
0345     girq->handler = handle_edge_irq;
0346     girq->init_hw = idio_16_irq_init_hw;
0347 
0348     raw_spin_lock_init(&idio16gpio->lock);
0349 
0350     err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
0351     if (err) {
0352         dev_err(dev, "GPIO registering failed (%d)\n", err);
0353         return err;
0354     }
0355 
0356     err = devm_request_irq(dev, pdev->irq, idio_16_irq_handler, IRQF_SHARED,
0357         name, idio16gpio);
0358     if (err) {
0359         dev_err(dev, "IRQ handler registering failed (%d)\n", err);
0360         return err;
0361     }
0362 
0363     return 0;
0364 }
0365 
0366 static const struct pci_device_id idio_16_pci_dev_id[] = {
0367     { PCI_DEVICE(0x494F, 0x0DC8) }, { 0 }
0368 };
0369 MODULE_DEVICE_TABLE(pci, idio_16_pci_dev_id);
0370 
0371 static struct pci_driver idio_16_driver = {
0372     .name = "pci-idio-16",
0373     .id_table = idio_16_pci_dev_id,
0374     .probe = idio_16_probe
0375 };
0376 
0377 module_pci_driver(idio_16_driver);
0378 
0379 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
0380 MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver");
0381 MODULE_LICENSE("GPL v2");