1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * GPIO driver for the ACCES PCI-IDIO-16 4 * Copyright (C) 2017 William Breathitt Gray 5 */ 6 #include <linux/bits.h> 7 #include <linux/device.h> 8 #include <linux/errno.h> 9 #include <linux/gpio/driver.h> 10 #include <linux/interrupt.h> 11 #include <linux/irqdesc.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/pci.h> 15 #include <linux/spinlock.h> 16 #include <linux/types.h> 17 18 #include "gpio-idio-16.h" 19 20 /** 21 * struct idio_16_gpio - GPIO device private data structure 22 * @chip: instance of the gpio_chip 23 * @lock: synchronization lock to prevent I/O race conditions 24 * @reg: I/O address offset for the GPIO device registers 25 * @state: ACCES IDIO-16 device state 26 * @irq_mask: I/O bits affected by interrupts 27 */ 28 struct idio_16_gpio { 29 struct gpio_chip chip; 30 raw_spinlock_t lock; 31 struct idio_16 __iomem *reg; 32 struct idio_16_state state; 33 unsigned long irq_mask; 34 }; 35 36 static int idio_16_gpio_get_direction(struct gpio_chip *chip, 37 unsigned int offset) 38 { 39 if (idio_16_get_direction(offset)) 40 return GPIO_LINE_DIRECTION_IN; 41 42 return GPIO_LINE_DIRECTION_OUT; 43 } 44 45 static int idio_16_gpio_direction_input(struct gpio_chip *chip, 46 unsigned int offset) 47 { 48 return 0; 49 } 50 51 static int idio_16_gpio_direction_output(struct gpio_chip *chip, 52 unsigned int offset, int value) 53 { 54 chip->set(chip, offset, value); 55 return 0; 56 } 57 58 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset) 59 { 60 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 61 62 return idio_16_get(idio16gpio->reg, &idio16gpio->state, offset); 63 } 64 65 static int idio_16_gpio_get_multiple(struct gpio_chip *chip, 66 unsigned long *mask, unsigned long *bits) 67 { 68 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 69 70 idio_16_get_multiple(idio16gpio->reg, &idio16gpio->state, mask, bits); 71 return 0; 72 } 73 74 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset, 75 int value) 76 { 77 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 78 79 idio_16_set(idio16gpio->reg, &idio16gpio->state, offset, value); 80 } 81 82 static void idio_16_gpio_set_multiple(struct gpio_chip *chip, 83 unsigned long *mask, unsigned long *bits) 84 { 85 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 86 87 idio_16_set_multiple(idio16gpio->reg, &idio16gpio->state, mask, bits); 88 } 89 90 static void idio_16_irq_ack(struct irq_data *data) 91 { 92 } 93 94 static void idio_16_irq_mask(struct irq_data *data) 95 { 96 struct gpio_chip *chip = irq_data_get_irq_chip_data(data); 97 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 98 const unsigned long mask = BIT(irqd_to_hwirq(data)); 99 unsigned long flags; 100 101 idio16gpio->irq_mask &= ~mask; 102 103 if (!idio16gpio->irq_mask) { 104 raw_spin_lock_irqsave(&idio16gpio->lock, flags); 105 106 iowrite8(0, &idio16gpio->reg->irq_ctl); 107 108 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 109 } 110 111 gpiochip_disable_irq(chip, irqd_to_hwirq(data)); 112 } 113 114 static void idio_16_irq_unmask(struct irq_data *data) 115 { 116 struct gpio_chip *chip = irq_data_get_irq_chip_data(data); 117 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 118 const unsigned long mask = BIT(irqd_to_hwirq(data)); 119 const unsigned long prev_irq_mask = idio16gpio->irq_mask; 120 unsigned long flags; 121 122 gpiochip_enable_irq(chip, irqd_to_hwirq(data)); 123 124 idio16gpio->irq_mask |= mask; 125 126 if (!prev_irq_mask) { 127 raw_spin_lock_irqsave(&idio16gpio->lock, flags); 128 129 ioread8(&idio16gpio->reg->irq_ctl); 130 131 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 132 } 133 } 134 135 static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type) 136 { 137 /* The only valid irq types are none and both-edges */ 138 if (flow_type != IRQ_TYPE_NONE && 139 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH) 140 return -EINVAL; 141 142 return 0; 143 } 144 145 static const struct irq_chip idio_16_irqchip = { 146 .name = "pci-idio-16", 147 .irq_ack = idio_16_irq_ack, 148 .irq_mask = idio_16_irq_mask, 149 .irq_unmask = idio_16_irq_unmask, 150 .irq_set_type = idio_16_irq_set_type, 151 .flags = IRQCHIP_IMMUTABLE, 152 GPIOCHIP_IRQ_RESOURCE_HELPERS, 153 }; 154 155 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) 156 { 157 struct idio_16_gpio *const idio16gpio = dev_id; 158 unsigned int irq_status; 159 struct gpio_chip *const chip = &idio16gpio->chip; 160 int gpio; 161 162 raw_spin_lock(&idio16gpio->lock); 163 164 irq_status = ioread8(&idio16gpio->reg->irq_status); 165 166 raw_spin_unlock(&idio16gpio->lock); 167 168 /* Make sure our device generated IRQ */ 169 if (!(irq_status & 0x3) || !(irq_status & 0x4)) 170 return IRQ_NONE; 171 172 for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) 173 generic_handle_domain_irq(chip->irq.domain, gpio); 174 175 raw_spin_lock(&idio16gpio->lock); 176 177 /* Clear interrupt */ 178 iowrite8(0, &idio16gpio->reg->in0_7); 179 180 raw_spin_unlock(&idio16gpio->lock); 181 182 return IRQ_HANDLED; 183 } 184 185 #define IDIO_16_NGPIO 32 186 static const char *idio_16_names[IDIO_16_NGPIO] = { 187 "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7", 188 "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15", 189 "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7", 190 "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15" 191 }; 192 193 static int idio_16_irq_init_hw(struct gpio_chip *gc) 194 { 195 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc); 196 197 /* Disable IRQ by default and clear any pending interrupt */ 198 iowrite8(0, &idio16gpio->reg->irq_ctl); 199 iowrite8(0, &idio16gpio->reg->in0_7); 200 201 return 0; 202 } 203 204 static int idio_16_probe(struct pci_dev *pdev, const struct pci_device_id *id) 205 { 206 struct device *const dev = &pdev->dev; 207 struct idio_16_gpio *idio16gpio; 208 int err; 209 const size_t pci_bar_index = 2; 210 const char *const name = pci_name(pdev); 211 struct gpio_irq_chip *girq; 212 213 idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL); 214 if (!idio16gpio) 215 return -ENOMEM; 216 217 err = pcim_enable_device(pdev); 218 if (err) { 219 dev_err(dev, "Failed to enable PCI device (%d)\n", err); 220 return err; 221 } 222 223 err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name); 224 if (err) { 225 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err); 226 return err; 227 } 228 229 idio16gpio->reg = pcim_iomap_table(pdev)[pci_bar_index]; 230 231 /* Deactivate input filters */ 232 iowrite8(0, &idio16gpio->reg->filter_ctl); 233 234 idio16gpio->chip.label = name; 235 idio16gpio->chip.parent = dev; 236 idio16gpio->chip.owner = THIS_MODULE; 237 idio16gpio->chip.base = -1; 238 idio16gpio->chip.ngpio = IDIO_16_NGPIO; 239 idio16gpio->chip.names = idio_16_names; 240 idio16gpio->chip.get_direction = idio_16_gpio_get_direction; 241 idio16gpio->chip.direction_input = idio_16_gpio_direction_input; 242 idio16gpio->chip.direction_output = idio_16_gpio_direction_output; 243 idio16gpio->chip.get = idio_16_gpio_get; 244 idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple; 245 idio16gpio->chip.set = idio_16_gpio_set; 246 idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; 247 248 idio_16_state_init(&idio16gpio->state); 249 250 girq = &idio16gpio->chip.irq; 251 gpio_irq_chip_set_chip(girq, &idio_16_irqchip); 252 /* This will let us handle the parent IRQ in the driver */ 253 girq->parent_handler = NULL; 254 girq->num_parents = 0; 255 girq->parents = NULL; 256 girq->default_type = IRQ_TYPE_NONE; 257 girq->handler = handle_edge_irq; 258 girq->init_hw = idio_16_irq_init_hw; 259 260 raw_spin_lock_init(&idio16gpio->lock); 261 262 err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); 263 if (err) { 264 dev_err(dev, "GPIO registering failed (%d)\n", err); 265 return err; 266 } 267 268 err = devm_request_irq(dev, pdev->irq, idio_16_irq_handler, IRQF_SHARED, 269 name, idio16gpio); 270 if (err) { 271 dev_err(dev, "IRQ handler registering failed (%d)\n", err); 272 return err; 273 } 274 275 return 0; 276 } 277 278 static const struct pci_device_id idio_16_pci_dev_id[] = { 279 { PCI_DEVICE(0x494F, 0x0DC8) }, { 0 } 280 }; 281 MODULE_DEVICE_TABLE(pci, idio_16_pci_dev_id); 282 283 static struct pci_driver idio_16_driver = { 284 .name = "pci-idio-16", 285 .id_table = idio_16_pci_dev_id, 286 .probe = idio_16_probe 287 }; 288 289 module_pci_driver(idio_16_driver); 290 291 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); 292 MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver"); 293 MODULE_LICENSE("GPL v2"); 294 MODULE_IMPORT_NS(GPIO_IDIO_16); 295