Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * GPIO driver for the ACCES 104-IDIO-16 family
0004  * Copyright (C) 2015 William Breathitt Gray
0005  *
0006  * This driver supports the following ACCES devices: 104-IDIO-16,
0007  * 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8.
0008  */
0009 #include <linux/bits.h>
0010 #include <linux/device.h>
0011 #include <linux/errno.h>
0012 #include <linux/gpio/driver.h>
0013 #include <linux/io.h>
0014 #include <linux/ioport.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/irqdesc.h>
0017 #include <linux/isa.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/moduleparam.h>
0021 #include <linux/spinlock.h>
0022 #include <linux/types.h>
0023 
0024 #define IDIO_16_EXTENT 8
0025 #define MAX_NUM_IDIO_16 max_num_isa_dev(IDIO_16_EXTENT)
0026 
0027 static unsigned int base[MAX_NUM_IDIO_16];
0028 static unsigned int num_idio_16;
0029 module_param_hw_array(base, uint, ioport, &num_idio_16, 0);
0030 MODULE_PARM_DESC(base, "ACCES 104-IDIO-16 base addresses");
0031 
0032 static unsigned int irq[MAX_NUM_IDIO_16];
0033 module_param_hw_array(irq, uint, irq, NULL, 0);
0034 MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers");
0035 
0036 /**
0037  * struct idio_16_reg - device registers structure
0038  * @out0_7: Read: N/A
0039  *      Write: FET Drive Outputs 0-7
0040  * @in0_7:  Read: Isolated Inputs 0-7
0041  *      Write: Clear Interrupt
0042  * @irq_ctl:    Read: Enable IRQ
0043  *      Write: Disable IRQ
0044  * @unused: N/A
0045  * @out8_15:    Read: N/A
0046  *      Write: FET Drive Outputs 8-15
0047  * @in8_15: Read: Isolated Inputs 8-15
0048  *      Write: N/A
0049  */
0050 struct idio_16_reg {
0051     u8 out0_7;
0052     u8 in0_7;
0053     u8 irq_ctl;
0054     u8 unused;
0055     u8 out8_15;
0056     u8 in8_15;
0057 };
0058 
0059 /**
0060  * struct idio_16_gpio - GPIO device private data structure
0061  * @chip:   instance of the gpio_chip
0062  * @lock:   synchronization lock to prevent I/O race conditions
0063  * @irq_mask:   I/O bits affected by interrupts
0064  * @reg:    I/O address offset for the device registers
0065  * @out_state:  output bits state
0066  */
0067 struct idio_16_gpio {
0068     struct gpio_chip chip;
0069     raw_spinlock_t lock;
0070     unsigned long irq_mask;
0071     struct idio_16_reg __iomem *reg;
0072     unsigned int out_state;
0073 };
0074 
0075 static int idio_16_gpio_get_direction(struct gpio_chip *chip,
0076                       unsigned int offset)
0077 {
0078     if (offset > 15)
0079         return GPIO_LINE_DIRECTION_IN;
0080 
0081     return GPIO_LINE_DIRECTION_OUT;
0082 }
0083 
0084 static int idio_16_gpio_direction_input(struct gpio_chip *chip,
0085                     unsigned int offset)
0086 {
0087     return 0;
0088 }
0089 
0090 static int idio_16_gpio_direction_output(struct gpio_chip *chip,
0091     unsigned int offset, int value)
0092 {
0093     chip->set(chip, offset, value);
0094     return 0;
0095 }
0096 
0097 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
0098 {
0099     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0100     const unsigned int mask = BIT(offset-16);
0101 
0102     if (offset < 16)
0103         return -EINVAL;
0104 
0105     if (offset < 24)
0106         return !!(ioread8(&idio16gpio->reg->in0_7) & mask);
0107 
0108     return !!(ioread8(&idio16gpio->reg->in8_15) & (mask>>8));
0109 }
0110 
0111 static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
0112     unsigned long *mask, unsigned long *bits)
0113 {
0114     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0115 
0116     *bits = 0;
0117     if (*mask & GENMASK(23, 16))
0118         *bits |= (unsigned long)ioread8(&idio16gpio->reg->in0_7) << 16;
0119     if (*mask & GENMASK(31, 24))
0120         *bits |= (unsigned long)ioread8(&idio16gpio->reg->in8_15) << 24;
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     const unsigned int mask = BIT(offset);
0130     unsigned long flags;
0131 
0132     if (offset > 15)
0133         return;
0134 
0135     raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0136 
0137     if (value)
0138         idio16gpio->out_state |= mask;
0139     else
0140         idio16gpio->out_state &= ~mask;
0141 
0142     if (offset > 7)
0143         iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15);
0144     else
0145         iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7);
0146 
0147     raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0148 }
0149 
0150 static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
0151     unsigned long *mask, unsigned long *bits)
0152 {
0153     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0154     unsigned long flags;
0155 
0156     raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0157 
0158     idio16gpio->out_state &= ~*mask;
0159     idio16gpio->out_state |= *mask & *bits;
0160 
0161     if (*mask & 0xFF)
0162         iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7);
0163     if ((*mask >> 8) & 0xFF)
0164         iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15);
0165 
0166     raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0167 }
0168 
0169 static void idio_16_irq_ack(struct irq_data *data)
0170 {
0171 }
0172 
0173 static void idio_16_irq_mask(struct irq_data *data)
0174 {
0175     struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0176     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0177     const unsigned long offset = irqd_to_hwirq(data);
0178     unsigned long flags;
0179 
0180     idio16gpio->irq_mask &= ~BIT(offset);
0181     gpiochip_disable_irq(chip, offset);
0182 
0183     if (!idio16gpio->irq_mask) {
0184         raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0185 
0186         iowrite8(0, &idio16gpio->reg->irq_ctl);
0187 
0188         raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0189     }
0190 }
0191 
0192 static void idio_16_irq_unmask(struct irq_data *data)
0193 {
0194     struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0195     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0196     const unsigned long offset = irqd_to_hwirq(data);
0197     const unsigned long prev_irq_mask = idio16gpio->irq_mask;
0198     unsigned long flags;
0199 
0200     gpiochip_enable_irq(chip, offset);
0201     idio16gpio->irq_mask |= BIT(offset);
0202 
0203     if (!prev_irq_mask) {
0204         raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0205 
0206         ioread8(&idio16gpio->reg->irq_ctl);
0207 
0208         raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0209     }
0210 }
0211 
0212 static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
0213 {
0214     /* The only valid irq types are none and both-edges */
0215     if (flow_type != IRQ_TYPE_NONE &&
0216         (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
0217         return -EINVAL;
0218 
0219     return 0;
0220 }
0221 
0222 static const struct irq_chip idio_16_irqchip = {
0223     .name = "104-idio-16",
0224     .irq_ack = idio_16_irq_ack,
0225     .irq_mask = idio_16_irq_mask,
0226     .irq_unmask = idio_16_irq_unmask,
0227     .irq_set_type = idio_16_irq_set_type,
0228     .flags = IRQCHIP_IMMUTABLE,
0229     GPIOCHIP_IRQ_RESOURCE_HELPERS,
0230 };
0231 
0232 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
0233 {
0234     struct idio_16_gpio *const idio16gpio = dev_id;
0235     struct gpio_chip *const chip = &idio16gpio->chip;
0236     int gpio;
0237 
0238     for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
0239         generic_handle_domain_irq(chip->irq.domain, gpio);
0240 
0241     raw_spin_lock(&idio16gpio->lock);
0242 
0243     iowrite8(0, &idio16gpio->reg->in0_7);
0244 
0245     raw_spin_unlock(&idio16gpio->lock);
0246 
0247     return IRQ_HANDLED;
0248 }
0249 
0250 #define IDIO_16_NGPIO 32
0251 static const char *idio_16_names[IDIO_16_NGPIO] = {
0252     "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
0253     "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
0254     "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
0255     "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
0256 };
0257 
0258 static int idio_16_irq_init_hw(struct gpio_chip *gc)
0259 {
0260     struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
0261 
0262     /* Disable IRQ by default */
0263     iowrite8(0, &idio16gpio->reg->irq_ctl);
0264     iowrite8(0, &idio16gpio->reg->in0_7);
0265 
0266     return 0;
0267 }
0268 
0269 static int idio_16_probe(struct device *dev, unsigned int id)
0270 {
0271     struct idio_16_gpio *idio16gpio;
0272     const char *const name = dev_name(dev);
0273     struct gpio_irq_chip *girq;
0274     int err;
0275 
0276     idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
0277     if (!idio16gpio)
0278         return -ENOMEM;
0279 
0280     if (!devm_request_region(dev, base[id], IDIO_16_EXTENT, name)) {
0281         dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
0282             base[id], base[id] + IDIO_16_EXTENT);
0283         return -EBUSY;
0284     }
0285 
0286     idio16gpio->reg = devm_ioport_map(dev, base[id], IDIO_16_EXTENT);
0287     if (!idio16gpio->reg)
0288         return -ENOMEM;
0289 
0290     idio16gpio->chip.label = name;
0291     idio16gpio->chip.parent = dev;
0292     idio16gpio->chip.owner = THIS_MODULE;
0293     idio16gpio->chip.base = -1;
0294     idio16gpio->chip.ngpio = IDIO_16_NGPIO;
0295     idio16gpio->chip.names = idio_16_names;
0296     idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
0297     idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
0298     idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
0299     idio16gpio->chip.get = idio_16_gpio_get;
0300     idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
0301     idio16gpio->chip.set = idio_16_gpio_set;
0302     idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
0303     idio16gpio->out_state = 0xFFFF;
0304 
0305     girq = &idio16gpio->chip.irq;
0306     gpio_irq_chip_set_chip(girq, &idio_16_irqchip);
0307     /* This will let us handle the parent IRQ in the driver */
0308     girq->parent_handler = NULL;
0309     girq->num_parents = 0;
0310     girq->parents = NULL;
0311     girq->default_type = IRQ_TYPE_NONE;
0312     girq->handler = handle_edge_irq;
0313     girq->init_hw = idio_16_irq_init_hw;
0314 
0315     raw_spin_lock_init(&idio16gpio->lock);
0316 
0317     err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
0318     if (err) {
0319         dev_err(dev, "GPIO registering failed (%d)\n", err);
0320         return err;
0321     }
0322 
0323     err = devm_request_irq(dev, irq[id], idio_16_irq_handler, 0, name,
0324         idio16gpio);
0325     if (err) {
0326         dev_err(dev, "IRQ handler registering failed (%d)\n", err);
0327         return err;
0328     }
0329 
0330     return 0;
0331 }
0332 
0333 static struct isa_driver idio_16_driver = {
0334     .probe = idio_16_probe,
0335     .driver = {
0336         .name = "104-idio-16"
0337     },
0338 };
0339 
0340 module_isa_driver(idio_16_driver, num_idio_16);
0341 
0342 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
0343 MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver");
0344 MODULE_LICENSE("GPL v2");