1 /* 2 * GPIO driver for the WinSystems WS16C48 3 * Copyright (C) 2016 William Breathitt Gray 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License, version 2, as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 */ 14 #include <linux/bitops.h> 15 #include <linux/device.h> 16 #include <linux/errno.h> 17 #include <linux/gpio/driver.h> 18 #include <linux/io.h> 19 #include <linux/ioport.h> 20 #include <linux/interrupt.h> 21 #include <linux/irqdesc.h> 22 #include <linux/isa.h> 23 #include <linux/kernel.h> 24 #include <linux/module.h> 25 #include <linux/moduleparam.h> 26 #include <linux/spinlock.h> 27 28 #define WS16C48_EXTENT 16 29 #define MAX_NUM_WS16C48 max_num_isa_dev(WS16C48_EXTENT) 30 31 static unsigned int base[MAX_NUM_WS16C48]; 32 static unsigned int num_ws16c48; 33 module_param_hw_array(base, uint, ioport, &num_ws16c48, 0); 34 MODULE_PARM_DESC(base, "WinSystems WS16C48 base addresses"); 35 36 static unsigned int irq[MAX_NUM_WS16C48]; 37 module_param_hw_array(irq, uint, irq, NULL, 0); 38 MODULE_PARM_DESC(irq, "WinSystems WS16C48 interrupt line numbers"); 39 40 /** 41 * struct ws16c48_gpio - GPIO device private data structure 42 * @chip: instance of the gpio_chip 43 * @io_state: bit I/O state (whether bit is set to input or output) 44 * @out_state: output bits state 45 * @lock: synchronization lock to prevent I/O race conditions 46 * @irq_mask: I/O bits affected by interrupts 47 * @flow_mask: IRQ flow type mask for the respective I/O bits 48 * @base: base port address of the GPIO device 49 */ 50 struct ws16c48_gpio { 51 struct gpio_chip chip; 52 unsigned char io_state[6]; 53 unsigned char out_state[6]; 54 raw_spinlock_t lock; 55 unsigned long irq_mask; 56 unsigned long flow_mask; 57 unsigned base; 58 }; 59 60 static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset) 61 { 62 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 63 const unsigned port = offset / 8; 64 const unsigned mask = BIT(offset % 8); 65 66 return !!(ws16c48gpio->io_state[port] & mask); 67 } 68 69 static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 70 { 71 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 72 const unsigned port = offset / 8; 73 const unsigned mask = BIT(offset % 8); 74 unsigned long flags; 75 76 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); 77 78 ws16c48gpio->io_state[port] |= mask; 79 ws16c48gpio->out_state[port] &= ~mask; 80 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); 81 82 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 83 84 return 0; 85 } 86 87 static int ws16c48_gpio_direction_output(struct gpio_chip *chip, 88 unsigned offset, int value) 89 { 90 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 91 const unsigned port = offset / 8; 92 const unsigned mask = BIT(offset % 8); 93 unsigned long flags; 94 95 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); 96 97 ws16c48gpio->io_state[port] &= ~mask; 98 if (value) 99 ws16c48gpio->out_state[port] |= mask; 100 else 101 ws16c48gpio->out_state[port] &= ~mask; 102 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); 103 104 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 105 106 return 0; 107 } 108 109 static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset) 110 { 111 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 112 const unsigned port = offset / 8; 113 const unsigned mask = BIT(offset % 8); 114 unsigned long flags; 115 unsigned port_state; 116 117 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); 118 119 /* ensure that GPIO is set for input */ 120 if (!(ws16c48gpio->io_state[port] & mask)) { 121 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 122 return -EINVAL; 123 } 124 125 port_state = inb(ws16c48gpio->base + port); 126 127 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 128 129 return !!(port_state & mask); 130 } 131 132 static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 133 { 134 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 135 const unsigned port = offset / 8; 136 const unsigned mask = BIT(offset % 8); 137 unsigned long flags; 138 139 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); 140 141 /* ensure that GPIO is set for output */ 142 if (ws16c48gpio->io_state[port] & mask) { 143 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 144 return; 145 } 146 147 if (value) 148 ws16c48gpio->out_state[port] |= mask; 149 else 150 ws16c48gpio->out_state[port] &= ~mask; 151 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); 152 153 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 154 } 155 156 static void ws16c48_gpio_set_multiple(struct gpio_chip *chip, 157 unsigned long *mask, unsigned long *bits) 158 { 159 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 160 unsigned int i; 161 const unsigned int gpio_reg_size = 8; 162 unsigned int port; 163 unsigned int iomask; 164 unsigned int bitmask; 165 unsigned long flags; 166 167 /* set bits are evaluated a gpio register size at a time */ 168 for (i = 0; i < chip->ngpio; i += gpio_reg_size) { 169 /* no more set bits in this mask word; skip to the next word */ 170 if (!mask[BIT_WORD(i)]) { 171 i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size; 172 continue; 173 } 174 175 port = i / gpio_reg_size; 176 177 /* mask out GPIO configured for input */ 178 iomask = mask[BIT_WORD(i)] & ~ws16c48gpio->io_state[port]; 179 bitmask = iomask & bits[BIT_WORD(i)]; 180 181 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); 182 183 /* update output state data and set device gpio register */ 184 ws16c48gpio->out_state[port] &= ~iomask; 185 ws16c48gpio->out_state[port] |= bitmask; 186 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); 187 188 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 189 190 /* prepare for next gpio register set */ 191 mask[BIT_WORD(i)] >>= gpio_reg_size; 192 bits[BIT_WORD(i)] >>= gpio_reg_size; 193 } 194 } 195 196 static void ws16c48_irq_ack(struct irq_data *data) 197 { 198 struct gpio_chip *chip = irq_data_get_irq_chip_data(data); 199 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 200 const unsigned long offset = irqd_to_hwirq(data); 201 const unsigned port = offset / 8; 202 const unsigned mask = BIT(offset % 8); 203 unsigned long flags; 204 unsigned port_state; 205 206 /* only the first 3 ports support interrupts */ 207 if (port > 2) 208 return; 209 210 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); 211 212 port_state = ws16c48gpio->irq_mask >> (8*port); 213 214 outb(0x80, ws16c48gpio->base + 7); 215 outb(port_state & ~mask, ws16c48gpio->base + 8 + port); 216 outb(port_state | mask, ws16c48gpio->base + 8 + port); 217 outb(0xC0, ws16c48gpio->base + 7); 218 219 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 220 } 221 222 static void ws16c48_irq_mask(struct irq_data *data) 223 { 224 struct gpio_chip *chip = irq_data_get_irq_chip_data(data); 225 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 226 const unsigned long offset = irqd_to_hwirq(data); 227 const unsigned long mask = BIT(offset); 228 const unsigned port = offset / 8; 229 unsigned long flags; 230 231 /* only the first 3 ports support interrupts */ 232 if (port > 2) 233 return; 234 235 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); 236 237 ws16c48gpio->irq_mask &= ~mask; 238 239 outb(0x80, ws16c48gpio->base + 7); 240 outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); 241 outb(0xC0, ws16c48gpio->base + 7); 242 243 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 244 } 245 246 static void ws16c48_irq_unmask(struct irq_data *data) 247 { 248 struct gpio_chip *chip = irq_data_get_irq_chip_data(data); 249 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 250 const unsigned long offset = irqd_to_hwirq(data); 251 const unsigned long mask = BIT(offset); 252 const unsigned port = offset / 8; 253 unsigned long flags; 254 255 /* only the first 3 ports support interrupts */ 256 if (port > 2) 257 return; 258 259 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); 260 261 ws16c48gpio->irq_mask |= mask; 262 263 outb(0x80, ws16c48gpio->base + 7); 264 outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); 265 outb(0xC0, ws16c48gpio->base + 7); 266 267 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 268 } 269 270 static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type) 271 { 272 struct gpio_chip *chip = irq_data_get_irq_chip_data(data); 273 struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); 274 const unsigned long offset = irqd_to_hwirq(data); 275 const unsigned long mask = BIT(offset); 276 const unsigned port = offset / 8; 277 unsigned long flags; 278 279 /* only the first 3 ports support interrupts */ 280 if (port > 2) 281 return -EINVAL; 282 283 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); 284 285 switch (flow_type) { 286 case IRQ_TYPE_NONE: 287 break; 288 case IRQ_TYPE_EDGE_RISING: 289 ws16c48gpio->flow_mask |= mask; 290 break; 291 case IRQ_TYPE_EDGE_FALLING: 292 ws16c48gpio->flow_mask &= ~mask; 293 break; 294 default: 295 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 296 return -EINVAL; 297 } 298 299 outb(0x40, ws16c48gpio->base + 7); 300 outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port); 301 outb(0xC0, ws16c48gpio->base + 7); 302 303 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); 304 305 return 0; 306 } 307 308 static struct irq_chip ws16c48_irqchip = { 309 .name = "ws16c48", 310 .irq_ack = ws16c48_irq_ack, 311 .irq_mask = ws16c48_irq_mask, 312 .irq_unmask = ws16c48_irq_unmask, 313 .irq_set_type = ws16c48_irq_set_type 314 }; 315 316 static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id) 317 { 318 struct ws16c48_gpio *const ws16c48gpio = dev_id; 319 struct gpio_chip *const chip = &ws16c48gpio->chip; 320 unsigned long int_pending; 321 unsigned long port; 322 unsigned long int_id; 323 unsigned long gpio; 324 325 int_pending = inb(ws16c48gpio->base + 6) & 0x7; 326 if (!int_pending) 327 return IRQ_NONE; 328 329 /* loop until all pending interrupts are handled */ 330 do { 331 for_each_set_bit(port, &int_pending, 3) { 332 int_id = inb(ws16c48gpio->base + 8 + port); 333 for_each_set_bit(gpio, &int_id, 8) 334 generic_handle_irq(irq_find_mapping( 335 chip->irq.domain, gpio + 8*port)); 336 } 337 338 int_pending = inb(ws16c48gpio->base + 6) & 0x7; 339 } while (int_pending); 340 341 return IRQ_HANDLED; 342 } 343 344 #define WS16C48_NGPIO 48 345 static const char *ws16c48_names[WS16C48_NGPIO] = { 346 "Port 0 Bit 0", "Port 0 Bit 1", "Port 0 Bit 2", "Port 0 Bit 3", 347 "Port 0 Bit 4", "Port 0 Bit 5", "Port 0 Bit 6", "Port 0 Bit 7", 348 "Port 1 Bit 0", "Port 1 Bit 1", "Port 1 Bit 2", "Port 1 Bit 3", 349 "Port 1 Bit 4", "Port 1 Bit 5", "Port 1 Bit 6", "Port 1 Bit 7", 350 "Port 2 Bit 0", "Port 2 Bit 1", "Port 2 Bit 2", "Port 2 Bit 3", 351 "Port 2 Bit 4", "Port 2 Bit 5", "Port 2 Bit 6", "Port 2 Bit 7", 352 "Port 3 Bit 0", "Port 3 Bit 1", "Port 3 Bit 2", "Port 3 Bit 3", 353 "Port 3 Bit 4", "Port 3 Bit 5", "Port 3 Bit 6", "Port 3 Bit 7", 354 "Port 4 Bit 0", "Port 4 Bit 1", "Port 4 Bit 2", "Port 4 Bit 3", 355 "Port 4 Bit 4", "Port 4 Bit 5", "Port 4 Bit 6", "Port 4 Bit 7", 356 "Port 5 Bit 0", "Port 5 Bit 1", "Port 5 Bit 2", "Port 5 Bit 3", 357 "Port 5 Bit 4", "Port 5 Bit 5", "Port 5 Bit 6", "Port 5 Bit 7" 358 }; 359 360 static int ws16c48_probe(struct device *dev, unsigned int id) 361 { 362 struct ws16c48_gpio *ws16c48gpio; 363 const char *const name = dev_name(dev); 364 int err; 365 366 ws16c48gpio = devm_kzalloc(dev, sizeof(*ws16c48gpio), GFP_KERNEL); 367 if (!ws16c48gpio) 368 return -ENOMEM; 369 370 if (!devm_request_region(dev, base[id], WS16C48_EXTENT, name)) { 371 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", 372 base[id], base[id] + WS16C48_EXTENT); 373 return -EBUSY; 374 } 375 376 ws16c48gpio->chip.label = name; 377 ws16c48gpio->chip.parent = dev; 378 ws16c48gpio->chip.owner = THIS_MODULE; 379 ws16c48gpio->chip.base = -1; 380 ws16c48gpio->chip.ngpio = WS16C48_NGPIO; 381 ws16c48gpio->chip.names = ws16c48_names; 382 ws16c48gpio->chip.get_direction = ws16c48_gpio_get_direction; 383 ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input; 384 ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output; 385 ws16c48gpio->chip.get = ws16c48_gpio_get; 386 ws16c48gpio->chip.set = ws16c48_gpio_set; 387 ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple; 388 ws16c48gpio->base = base[id]; 389 390 raw_spin_lock_init(&ws16c48gpio->lock); 391 392 err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio); 393 if (err) { 394 dev_err(dev, "GPIO registering failed (%d)\n", err); 395 return err; 396 } 397 398 /* Disable IRQ by default */ 399 outb(0x80, base[id] + 7); 400 outb(0, base[id] + 8); 401 outb(0, base[id] + 9); 402 outb(0, base[id] + 10); 403 outb(0xC0, base[id] + 7); 404 405 err = gpiochip_irqchip_add(&ws16c48gpio->chip, &ws16c48_irqchip, 0, 406 handle_edge_irq, IRQ_TYPE_NONE); 407 if (err) { 408 dev_err(dev, "Could not add irqchip (%d)\n", err); 409 return err; 410 } 411 412 err = devm_request_irq(dev, irq[id], ws16c48_irq_handler, IRQF_SHARED, 413 name, ws16c48gpio); 414 if (err) { 415 dev_err(dev, "IRQ handler registering failed (%d)\n", err); 416 return err; 417 } 418 419 return 0; 420 } 421 422 static struct isa_driver ws16c48_driver = { 423 .probe = ws16c48_probe, 424 .driver = { 425 .name = "ws16c48" 426 }, 427 }; 428 429 module_isa_driver(ws16c48_driver, num_ws16c48); 430 431 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); 432 MODULE_DESCRIPTION("WinSystems WS16C48 GPIO driver"); 433 MODULE_LICENSE("GPL v2"); 434