linux/drivers/gpio/gpio-104-dio-48e.c
<<
>>
Prefs
   1/*
   2 * GPIO driver for the ACCES 104-DIO-48E series
   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 * This driver supports the following ACCES devices: 104-DIO-48E and
  15 * 104-DIO-24E.
  16 */
  17#include <linux/bitmap.h>
  18#include <linux/bitops.h>
  19#include <linux/device.h>
  20#include <linux/errno.h>
  21#include <linux/gpio/driver.h>
  22#include <linux/io.h>
  23#include <linux/ioport.h>
  24#include <linux/interrupt.h>
  25#include <linux/irqdesc.h>
  26#include <linux/isa.h>
  27#include <linux/kernel.h>
  28#include <linux/module.h>
  29#include <linux/moduleparam.h>
  30#include <linux/spinlock.h>
  31
  32#define DIO48E_EXTENT 16
  33#define MAX_NUM_DIO48E max_num_isa_dev(DIO48E_EXTENT)
  34
  35static unsigned int base[MAX_NUM_DIO48E];
  36static unsigned int num_dio48e;
  37module_param_hw_array(base, uint, ioport, &num_dio48e, 0);
  38MODULE_PARM_DESC(base, "ACCES 104-DIO-48E base addresses");
  39
  40static unsigned int irq[MAX_NUM_DIO48E];
  41module_param_hw_array(irq, uint, irq, NULL, 0);
  42MODULE_PARM_DESC(irq, "ACCES 104-DIO-48E interrupt line numbers");
  43
  44/**
  45 * struct dio48e_gpio - GPIO device private data structure
  46 * @chip:       instance of the gpio_chip
  47 * @io_state:   bit I/O state (whether bit is set to input or output)
  48 * @out_state:  output bits state
  49 * @control:    Control registers state
  50 * @lock:       synchronization lock to prevent I/O race conditions
  51 * @base:       base port address of the GPIO device
  52 * @irq_mask:   I/O bits affected by interrupts
  53 */
  54struct dio48e_gpio {
  55        struct gpio_chip chip;
  56        unsigned char io_state[6];
  57        unsigned char out_state[6];
  58        unsigned char control[2];
  59        raw_spinlock_t lock;
  60        unsigned base;
  61        unsigned char irq_mask;
  62};
  63
  64static int dio48e_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
  65{
  66        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
  67        const unsigned port = offset / 8;
  68        const unsigned mask = BIT(offset % 8);
  69
  70        return !!(dio48egpio->io_state[port] & mask);
  71}
  72
  73static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
  74{
  75        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
  76        const unsigned io_port = offset / 8;
  77        const unsigned int control_port = io_port / 3;
  78        const unsigned control_addr = dio48egpio->base + 3 + control_port*4;
  79        unsigned long flags;
  80        unsigned control;
  81
  82        raw_spin_lock_irqsave(&dio48egpio->lock, flags);
  83
  84        /* Check if configuring Port C */
  85        if (io_port == 2 || io_port == 5) {
  86                /* Port C can be configured by nibble */
  87                if (offset % 8 > 3) {
  88                        dio48egpio->io_state[io_port] |= 0xF0;
  89                        dio48egpio->control[control_port] |= BIT(3);
  90                } else {
  91                        dio48egpio->io_state[io_port] |= 0x0F;
  92                        dio48egpio->control[control_port] |= BIT(0);
  93                }
  94        } else {
  95                dio48egpio->io_state[io_port] |= 0xFF;
  96                if (io_port == 0 || io_port == 3)
  97                        dio48egpio->control[control_port] |= BIT(4);
  98                else
  99                        dio48egpio->control[control_port] |= BIT(1);
 100        }
 101
 102        control = BIT(7) | dio48egpio->control[control_port];
 103        outb(control, control_addr);
 104        control &= ~BIT(7);
 105        outb(control, control_addr);
 106
 107        raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
 108
 109        return 0;
 110}
 111
 112static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 113        int value)
 114{
 115        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
 116        const unsigned io_port = offset / 8;
 117        const unsigned int control_port = io_port / 3;
 118        const unsigned mask = BIT(offset % 8);
 119        const unsigned control_addr = dio48egpio->base + 3 + control_port*4;
 120        const unsigned out_port = (io_port > 2) ? io_port + 1 : io_port;
 121        unsigned long flags;
 122        unsigned control;
 123
 124        raw_spin_lock_irqsave(&dio48egpio->lock, flags);
 125
 126        /* Check if configuring Port C */
 127        if (io_port == 2 || io_port == 5) {
 128                /* Port C can be configured by nibble */
 129                if (offset % 8 > 3) {
 130                        dio48egpio->io_state[io_port] &= 0x0F;
 131                        dio48egpio->control[control_port] &= ~BIT(3);
 132                } else {
 133                        dio48egpio->io_state[io_port] &= 0xF0;
 134                        dio48egpio->control[control_port] &= ~BIT(0);
 135                }
 136        } else {
 137                dio48egpio->io_state[io_port] &= 0x00;
 138                if (io_port == 0 || io_port == 3)
 139                        dio48egpio->control[control_port] &= ~BIT(4);
 140                else
 141                        dio48egpio->control[control_port] &= ~BIT(1);
 142        }
 143
 144        if (value)
 145                dio48egpio->out_state[io_port] |= mask;
 146        else
 147                dio48egpio->out_state[io_port] &= ~mask;
 148
 149        control = BIT(7) | dio48egpio->control[control_port];
 150        outb(control, control_addr);
 151
 152        outb(dio48egpio->out_state[io_port], dio48egpio->base + out_port);
 153
 154        control &= ~BIT(7);
 155        outb(control, control_addr);
 156
 157        raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
 158
 159        return 0;
 160}
 161
 162static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset)
 163{
 164        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
 165        const unsigned port = offset / 8;
 166        const unsigned mask = BIT(offset % 8);
 167        const unsigned in_port = (port > 2) ? port + 1 : port;
 168        unsigned long flags;
 169        unsigned port_state;
 170
 171        raw_spin_lock_irqsave(&dio48egpio->lock, flags);
 172
 173        /* ensure that GPIO is set for input */
 174        if (!(dio48egpio->io_state[port] & mask)) {
 175                raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
 176                return -EINVAL;
 177        }
 178
 179        port_state = inb(dio48egpio->base + in_port);
 180
 181        raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
 182
 183        return !!(port_state & mask);
 184}
 185
 186static int dio48e_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
 187        unsigned long *bits)
 188{
 189        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
 190        size_t i;
 191        static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
 192        const unsigned int gpio_reg_size = 8;
 193        unsigned int bits_offset;
 194        size_t word_index;
 195        unsigned int word_offset;
 196        unsigned long word_mask;
 197        const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
 198        unsigned long port_state;
 199
 200        /* clear bits array to a clean slate */
 201        bitmap_zero(bits, chip->ngpio);
 202
 203        /* get bits are evaluated a gpio port register at a time */
 204        for (i = 0; i < ARRAY_SIZE(ports); i++) {
 205                /* gpio offset in bits array */
 206                bits_offset = i * gpio_reg_size;
 207
 208                /* word index for bits array */
 209                word_index = BIT_WORD(bits_offset);
 210
 211                /* gpio offset within current word of bits array */
 212                word_offset = bits_offset % BITS_PER_LONG;
 213
 214                /* mask of get bits for current gpio within current word */
 215                word_mask = mask[word_index] & (port_mask << word_offset);
 216                if (!word_mask) {
 217                        /* no get bits in this port so skip to next one */
 218                        continue;
 219                }
 220
 221                /* read bits from current gpio port */
 222                port_state = inb(dio48egpio->base + ports[i]);
 223
 224                /* store acquired bits at respective bits array offset */
 225                bits[word_index] |= port_state << word_offset;
 226        }
 227
 228        return 0;
 229}
 230
 231static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 232{
 233        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
 234        const unsigned port = offset / 8;
 235        const unsigned mask = BIT(offset % 8);
 236        const unsigned out_port = (port > 2) ? port + 1 : port;
 237        unsigned long flags;
 238
 239        raw_spin_lock_irqsave(&dio48egpio->lock, flags);
 240
 241        if (value)
 242                dio48egpio->out_state[port] |= mask;
 243        else
 244                dio48egpio->out_state[port] &= ~mask;
 245
 246        outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
 247
 248        raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
 249}
 250
 251static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
 252        unsigned long *mask, unsigned long *bits)
 253{
 254        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
 255        unsigned int i;
 256        const unsigned int gpio_reg_size = 8;
 257        unsigned int port;
 258        unsigned int out_port;
 259        unsigned int bitmask;
 260        unsigned long flags;
 261
 262        /* set bits are evaluated a gpio register size at a time */
 263        for (i = 0; i < chip->ngpio; i += gpio_reg_size) {
 264                /* no more set bits in this mask word; skip to the next word */
 265                if (!mask[BIT_WORD(i)]) {
 266                        i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size;
 267                        continue;
 268                }
 269
 270                port = i / gpio_reg_size;
 271                out_port = (port > 2) ? port + 1 : port;
 272                bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)];
 273
 274                raw_spin_lock_irqsave(&dio48egpio->lock, flags);
 275
 276                /* update output state data and set device gpio register */
 277                dio48egpio->out_state[port] &= ~mask[BIT_WORD(i)];
 278                dio48egpio->out_state[port] |= bitmask;
 279                outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
 280
 281                raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
 282
 283                /* prepare for next gpio register set */
 284                mask[BIT_WORD(i)] >>= gpio_reg_size;
 285                bits[BIT_WORD(i)] >>= gpio_reg_size;
 286        }
 287}
 288
 289static void dio48e_irq_ack(struct irq_data *data)
 290{
 291}
 292
 293static void dio48e_irq_mask(struct irq_data *data)
 294{
 295        struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
 296        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
 297        const unsigned long offset = irqd_to_hwirq(data);
 298        unsigned long flags;
 299
 300        /* only bit 3 on each respective Port C supports interrupts */
 301        if (offset != 19 && offset != 43)
 302                return;
 303
 304        raw_spin_lock_irqsave(&dio48egpio->lock, flags);
 305
 306        if (offset == 19)
 307                dio48egpio->irq_mask &= ~BIT(0);
 308        else
 309                dio48egpio->irq_mask &= ~BIT(1);
 310
 311        if (!dio48egpio->irq_mask)
 312                /* disable interrupts */
 313                inb(dio48egpio->base + 0xB);
 314
 315        raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
 316}
 317
 318static void dio48e_irq_unmask(struct irq_data *data)
 319{
 320        struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
 321        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
 322        const unsigned long offset = irqd_to_hwirq(data);
 323        unsigned long flags;
 324
 325        /* only bit 3 on each respective Port C supports interrupts */
 326        if (offset != 19 && offset != 43)
 327                return;
 328
 329        raw_spin_lock_irqsave(&dio48egpio->lock, flags);
 330
 331        if (!dio48egpio->irq_mask) {
 332                /* enable interrupts */
 333                outb(0x00, dio48egpio->base + 0xF);
 334                outb(0x00, dio48egpio->base + 0xB);
 335        }
 336
 337        if (offset == 19)
 338                dio48egpio->irq_mask |= BIT(0);
 339        else
 340                dio48egpio->irq_mask |= BIT(1);
 341
 342        raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
 343}
 344
 345static int dio48e_irq_set_type(struct irq_data *data, unsigned flow_type)
 346{
 347        const unsigned long offset = irqd_to_hwirq(data);
 348
 349        /* only bit 3 on each respective Port C supports interrupts */
 350        if (offset != 19 && offset != 43)
 351                return -EINVAL;
 352
 353        if (flow_type != IRQ_TYPE_NONE && flow_type != IRQ_TYPE_EDGE_RISING)
 354                return -EINVAL;
 355
 356        return 0;
 357}
 358
 359static struct irq_chip dio48e_irqchip = {
 360        .name = "104-dio-48e",
 361        .irq_ack = dio48e_irq_ack,
 362        .irq_mask = dio48e_irq_mask,
 363        .irq_unmask = dio48e_irq_unmask,
 364        .irq_set_type = dio48e_irq_set_type
 365};
 366
 367static irqreturn_t dio48e_irq_handler(int irq, void *dev_id)
 368{
 369        struct dio48e_gpio *const dio48egpio = dev_id;
 370        struct gpio_chip *const chip = &dio48egpio->chip;
 371        const unsigned long irq_mask = dio48egpio->irq_mask;
 372        unsigned long gpio;
 373
 374        for_each_set_bit(gpio, &irq_mask, 2)
 375                generic_handle_irq(irq_find_mapping(chip->irq.domain,
 376                        19 + gpio*24));
 377
 378        raw_spin_lock(&dio48egpio->lock);
 379
 380        outb(0x00, dio48egpio->base + 0xF);
 381
 382        raw_spin_unlock(&dio48egpio->lock);
 383
 384        return IRQ_HANDLED;
 385}
 386
 387#define DIO48E_NGPIO 48
 388static const char *dio48e_names[DIO48E_NGPIO] = {
 389        "PPI Group 0 Port A 0", "PPI Group 0 Port A 1", "PPI Group 0 Port A 2",
 390        "PPI Group 0 Port A 3", "PPI Group 0 Port A 4", "PPI Group 0 Port A 5",
 391        "PPI Group 0 Port A 6", "PPI Group 0 Port A 7", "PPI Group 0 Port B 0",
 392        "PPI Group 0 Port B 1", "PPI Group 0 Port B 2", "PPI Group 0 Port B 3",
 393        "PPI Group 0 Port B 4", "PPI Group 0 Port B 5", "PPI Group 0 Port B 6",
 394        "PPI Group 0 Port B 7", "PPI Group 0 Port C 0", "PPI Group 0 Port C 1",
 395        "PPI Group 0 Port C 2", "PPI Group 0 Port C 3", "PPI Group 0 Port C 4",
 396        "PPI Group 0 Port C 5", "PPI Group 0 Port C 6", "PPI Group 0 Port C 7",
 397        "PPI Group 1 Port A 0", "PPI Group 1 Port A 1", "PPI Group 1 Port A 2",
 398        "PPI Group 1 Port A 3", "PPI Group 1 Port A 4", "PPI Group 1 Port A 5",
 399        "PPI Group 1 Port A 6", "PPI Group 1 Port A 7", "PPI Group 1 Port B 0",
 400        "PPI Group 1 Port B 1", "PPI Group 1 Port B 2", "PPI Group 1 Port B 3",
 401        "PPI Group 1 Port B 4", "PPI Group 1 Port B 5", "PPI Group 1 Port B 6",
 402        "PPI Group 1 Port B 7", "PPI Group 1 Port C 0", "PPI Group 1 Port C 1",
 403        "PPI Group 1 Port C 2", "PPI Group 1 Port C 3", "PPI Group 1 Port C 4",
 404        "PPI Group 1 Port C 5", "PPI Group 1 Port C 6", "PPI Group 1 Port C 7"
 405};
 406
 407static int dio48e_probe(struct device *dev, unsigned int id)
 408{
 409        struct dio48e_gpio *dio48egpio;
 410        const char *const name = dev_name(dev);
 411        int err;
 412
 413        dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL);
 414        if (!dio48egpio)
 415                return -ENOMEM;
 416
 417        if (!devm_request_region(dev, base[id], DIO48E_EXTENT, name)) {
 418                dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
 419                        base[id], base[id] + DIO48E_EXTENT);
 420                return -EBUSY;
 421        }
 422
 423        dio48egpio->chip.label = name;
 424        dio48egpio->chip.parent = dev;
 425        dio48egpio->chip.owner = THIS_MODULE;
 426        dio48egpio->chip.base = -1;
 427        dio48egpio->chip.ngpio = DIO48E_NGPIO;
 428        dio48egpio->chip.names = dio48e_names;
 429        dio48egpio->chip.get_direction = dio48e_gpio_get_direction;
 430        dio48egpio->chip.direction_input = dio48e_gpio_direction_input;
 431        dio48egpio->chip.direction_output = dio48e_gpio_direction_output;
 432        dio48egpio->chip.get = dio48e_gpio_get;
 433        dio48egpio->chip.get_multiple = dio48e_gpio_get_multiple;
 434        dio48egpio->chip.set = dio48e_gpio_set;
 435        dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple;
 436        dio48egpio->base = base[id];
 437
 438        raw_spin_lock_init(&dio48egpio->lock);
 439
 440        err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio);
 441        if (err) {
 442                dev_err(dev, "GPIO registering failed (%d)\n", err);
 443                return err;
 444        }
 445
 446        /* initialize all GPIO as output */
 447        outb(0x80, base[id] + 3);
 448        outb(0x00, base[id]);
 449        outb(0x00, base[id] + 1);
 450        outb(0x00, base[id] + 2);
 451        outb(0x00, base[id] + 3);
 452        outb(0x80, base[id] + 7);
 453        outb(0x00, base[id] + 4);
 454        outb(0x00, base[id] + 5);
 455        outb(0x00, base[id] + 6);
 456        outb(0x00, base[id] + 7);
 457
 458        /* disable IRQ by default */
 459        inb(base[id] + 0xB);
 460
 461        err = gpiochip_irqchip_add(&dio48egpio->chip, &dio48e_irqchip, 0,
 462                handle_edge_irq, IRQ_TYPE_NONE);
 463        if (err) {
 464                dev_err(dev, "Could not add irqchip (%d)\n", err);
 465                return err;
 466        }
 467
 468        err = devm_request_irq(dev, irq[id], dio48e_irq_handler, 0, name,
 469                dio48egpio);
 470        if (err) {
 471                dev_err(dev, "IRQ handler registering failed (%d)\n", err);
 472                return err;
 473        }
 474
 475        return 0;
 476}
 477
 478static struct isa_driver dio48e_driver = {
 479        .probe = dio48e_probe,
 480        .driver = {
 481                .name = "104-dio-48e"
 482        },
 483};
 484module_isa_driver(dio48e_driver, num_dio48e);
 485
 486MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
 487MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver");
 488MODULE_LICENSE("GPL v2");
 489