Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * GPIO driver for the WinSystems WS16C48
0004  * Copyright (C) 2016 William Breathitt Gray
0005  */
0006 #include <linux/bitmap.h>
0007 #include <linux/device.h>
0008 #include <linux/errno.h>
0009 #include <linux/gpio/driver.h>
0010 #include <linux/io.h>
0011 #include <linux/ioport.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/irqdesc.h>
0014 #include <linux/isa.h>
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/moduleparam.h>
0018 #include <linux/spinlock.h>
0019 #include <linux/types.h>
0020 
0021 #define WS16C48_EXTENT 10
0022 #define MAX_NUM_WS16C48 max_num_isa_dev(WS16C48_EXTENT)
0023 
0024 static unsigned int base[MAX_NUM_WS16C48];
0025 static unsigned int num_ws16c48;
0026 module_param_hw_array(base, uint, ioport, &num_ws16c48, 0);
0027 MODULE_PARM_DESC(base, "WinSystems WS16C48 base addresses");
0028 
0029 static unsigned int irq[MAX_NUM_WS16C48];
0030 module_param_hw_array(irq, uint, irq, NULL, 0);
0031 MODULE_PARM_DESC(irq, "WinSystems WS16C48 interrupt line numbers");
0032 
0033 /**
0034  * struct ws16c48_reg - device register structure
0035  * @port:       Port 0 through 5 I/O
0036  * @int_pending:    Interrupt Pending
0037  * @page_lock:      Register page (Bits 7-6) and I/O port lock (Bits 5-0)
0038  * @pol_enab_int_id:    Interrupt polarity, enable, and ID
0039  */
0040 struct ws16c48_reg {
0041     u8 port[6];
0042     u8 int_pending;
0043     u8 page_lock;
0044     u8 pol_enab_int_id[3];
0045 };
0046 
0047 /**
0048  * struct ws16c48_gpio - GPIO device private data structure
0049  * @chip:   instance of the gpio_chip
0050  * @io_state:   bit I/O state (whether bit is set to input or output)
0051  * @out_state:  output bits state
0052  * @lock:   synchronization lock to prevent I/O race conditions
0053  * @irq_mask:   I/O bits affected by interrupts
0054  * @flow_mask:  IRQ flow type mask for the respective I/O bits
0055  * @reg:    I/O address offset for the device registers
0056  */
0057 struct ws16c48_gpio {
0058     struct gpio_chip chip;
0059     unsigned char io_state[6];
0060     unsigned char out_state[6];
0061     raw_spinlock_t lock;
0062     unsigned long irq_mask;
0063     unsigned long flow_mask;
0064     struct ws16c48_reg __iomem *reg;
0065 };
0066 
0067 static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
0068 {
0069     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0070     const unsigned port = offset / 8;
0071     const unsigned mask = BIT(offset % 8);
0072 
0073     if (ws16c48gpio->io_state[port] & mask)
0074         return GPIO_LINE_DIRECTION_IN;
0075 
0076     return GPIO_LINE_DIRECTION_OUT;
0077 }
0078 
0079 static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
0080 {
0081     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0082     const unsigned port = offset / 8;
0083     const unsigned mask = BIT(offset % 8);
0084     unsigned long flags;
0085 
0086     raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
0087 
0088     ws16c48gpio->io_state[port] |= mask;
0089     ws16c48gpio->out_state[port] &= ~mask;
0090     iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->reg->port + port);
0091 
0092     raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0093 
0094     return 0;
0095 }
0096 
0097 static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
0098     unsigned offset, int value)
0099 {
0100     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0101     const unsigned port = offset / 8;
0102     const unsigned mask = BIT(offset % 8);
0103     unsigned long flags;
0104 
0105     raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
0106 
0107     ws16c48gpio->io_state[port] &= ~mask;
0108     if (value)
0109         ws16c48gpio->out_state[port] |= mask;
0110     else
0111         ws16c48gpio->out_state[port] &= ~mask;
0112     iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->reg->port + port);
0113 
0114     raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0115 
0116     return 0;
0117 }
0118 
0119 static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)
0120 {
0121     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0122     const unsigned port = offset / 8;
0123     const unsigned mask = BIT(offset % 8);
0124     unsigned long flags;
0125     unsigned port_state;
0126 
0127     raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
0128 
0129     /* ensure that GPIO is set for input */
0130     if (!(ws16c48gpio->io_state[port] & mask)) {
0131         raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0132         return -EINVAL;
0133     }
0134 
0135     port_state = ioread8(ws16c48gpio->reg->port + port);
0136 
0137     raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0138 
0139     return !!(port_state & mask);
0140 }
0141 
0142 static int ws16c48_gpio_get_multiple(struct gpio_chip *chip,
0143     unsigned long *mask, unsigned long *bits)
0144 {
0145     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0146     unsigned long offset;
0147     unsigned long gpio_mask;
0148     size_t index;
0149     u8 __iomem *port_addr;
0150     unsigned long port_state;
0151 
0152     /* clear bits array to a clean slate */
0153     bitmap_zero(bits, chip->ngpio);
0154 
0155     for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {
0156         index = offset / 8;
0157         port_addr = ws16c48gpio->reg->port + index;
0158         port_state = ioread8(port_addr) & gpio_mask;
0159 
0160         bitmap_set_value8(bits, port_state, offset);
0161     }
0162 
0163     return 0;
0164 }
0165 
0166 static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
0167 {
0168     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0169     const unsigned port = offset / 8;
0170     const unsigned mask = BIT(offset % 8);
0171     unsigned long flags;
0172 
0173     raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
0174 
0175     /* ensure that GPIO is set for output */
0176     if (ws16c48gpio->io_state[port] & mask) {
0177         raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0178         return;
0179     }
0180 
0181     if (value)
0182         ws16c48gpio->out_state[port] |= mask;
0183     else
0184         ws16c48gpio->out_state[port] &= ~mask;
0185     iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->reg->port + port);
0186 
0187     raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0188 }
0189 
0190 static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
0191     unsigned long *mask, unsigned long *bits)
0192 {
0193     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0194     unsigned long offset;
0195     unsigned long gpio_mask;
0196     size_t index;
0197     u8 __iomem *port_addr;
0198     unsigned long bitmask;
0199     unsigned long flags;
0200 
0201     for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {
0202         index = offset / 8;
0203         port_addr = ws16c48gpio->reg->port + index;
0204 
0205         /* mask out GPIO configured for input */
0206         gpio_mask &= ~ws16c48gpio->io_state[index];
0207         bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
0208 
0209         raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
0210 
0211         /* update output state data and set device gpio register */
0212         ws16c48gpio->out_state[index] &= ~gpio_mask;
0213         ws16c48gpio->out_state[index] |= bitmask;
0214         iowrite8(ws16c48gpio->out_state[index], port_addr);
0215 
0216         raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0217     }
0218 }
0219 
0220 static void ws16c48_irq_ack(struct irq_data *data)
0221 {
0222     struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0223     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0224     const unsigned long offset = irqd_to_hwirq(data);
0225     const unsigned port = offset / 8;
0226     const unsigned mask = BIT(offset % 8);
0227     unsigned long flags;
0228     unsigned port_state;
0229 
0230     /* only the first 3 ports support interrupts */
0231     if (port > 2)
0232         return;
0233 
0234     raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
0235 
0236     port_state = ws16c48gpio->irq_mask >> (8*port);
0237 
0238     /* Select Register Page 2; Unlock all I/O ports */
0239     iowrite8(0x80, &ws16c48gpio->reg->page_lock);
0240 
0241     /* Clear pending interrupt */
0242     iowrite8(port_state & ~mask, ws16c48gpio->reg->pol_enab_int_id + port);
0243     iowrite8(port_state | mask, ws16c48gpio->reg->pol_enab_int_id + port);
0244 
0245     /* Select Register Page 3; Unlock all I/O ports */
0246     iowrite8(0xC0, &ws16c48gpio->reg->page_lock);
0247 
0248     raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0249 }
0250 
0251 static void ws16c48_irq_mask(struct irq_data *data)
0252 {
0253     struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0254     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0255     const unsigned long offset = irqd_to_hwirq(data);
0256     const unsigned long mask = BIT(offset);
0257     const unsigned port = offset / 8;
0258     unsigned long flags;
0259     unsigned long port_state;
0260 
0261     /* only the first 3 ports support interrupts */
0262     if (port > 2)
0263         return;
0264 
0265     raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
0266 
0267     ws16c48gpio->irq_mask &= ~mask;
0268     gpiochip_disable_irq(chip, offset);
0269     port_state = ws16c48gpio->irq_mask >> (8 * port);
0270 
0271     /* Select Register Page 2; Unlock all I/O ports */
0272     iowrite8(0x80, &ws16c48gpio->reg->page_lock);
0273 
0274     /* Disable interrupt */
0275     iowrite8(port_state, ws16c48gpio->reg->pol_enab_int_id + port);
0276 
0277     /* Select Register Page 3; Unlock all I/O ports */
0278     iowrite8(0xC0, &ws16c48gpio->reg->page_lock);
0279 
0280     raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0281 }
0282 
0283 static void ws16c48_irq_unmask(struct irq_data *data)
0284 {
0285     struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0286     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0287     const unsigned long offset = irqd_to_hwirq(data);
0288     const unsigned long mask = BIT(offset);
0289     const unsigned port = offset / 8;
0290     unsigned long flags;
0291     unsigned long port_state;
0292 
0293     /* only the first 3 ports support interrupts */
0294     if (port > 2)
0295         return;
0296 
0297     raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
0298 
0299     gpiochip_enable_irq(chip, offset);
0300     ws16c48gpio->irq_mask |= mask;
0301     port_state = ws16c48gpio->irq_mask >> (8 * port);
0302 
0303     /* Select Register Page 2; Unlock all I/O ports */
0304     iowrite8(0x80, &ws16c48gpio->reg->page_lock);
0305 
0306     /* Enable interrupt */
0307     iowrite8(port_state, ws16c48gpio->reg->pol_enab_int_id + port);
0308 
0309     /* Select Register Page 3; Unlock all I/O ports */
0310     iowrite8(0xC0, &ws16c48gpio->reg->page_lock);
0311 
0312     raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0313 }
0314 
0315 static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
0316 {
0317     struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0318     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
0319     const unsigned long offset = irqd_to_hwirq(data);
0320     const unsigned long mask = BIT(offset);
0321     const unsigned port = offset / 8;
0322     unsigned long flags;
0323     unsigned long port_state;
0324 
0325     /* only the first 3 ports support interrupts */
0326     if (port > 2)
0327         return -EINVAL;
0328 
0329     raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
0330 
0331     switch (flow_type) {
0332     case IRQ_TYPE_NONE:
0333         break;
0334     case IRQ_TYPE_EDGE_RISING:
0335         ws16c48gpio->flow_mask |= mask;
0336         break;
0337     case IRQ_TYPE_EDGE_FALLING:
0338         ws16c48gpio->flow_mask &= ~mask;
0339         break;
0340     default:
0341         raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0342         return -EINVAL;
0343     }
0344 
0345     port_state = ws16c48gpio->flow_mask >> (8 * port);
0346 
0347     /* Select Register Page 1; Unlock all I/O ports */
0348     iowrite8(0x40, &ws16c48gpio->reg->page_lock);
0349 
0350     /* Set interrupt polarity */
0351     iowrite8(port_state, ws16c48gpio->reg->pol_enab_int_id + port);
0352 
0353     /* Select Register Page 3; Unlock all I/O ports */
0354     iowrite8(0xC0, &ws16c48gpio->reg->page_lock);
0355 
0356     raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
0357 
0358     return 0;
0359 }
0360 
0361 static const struct irq_chip ws16c48_irqchip = {
0362     .name = "ws16c48",
0363     .irq_ack = ws16c48_irq_ack,
0364     .irq_mask = ws16c48_irq_mask,
0365     .irq_unmask = ws16c48_irq_unmask,
0366     .irq_set_type = ws16c48_irq_set_type,
0367     .flags = IRQCHIP_IMMUTABLE,
0368     GPIOCHIP_IRQ_RESOURCE_HELPERS,
0369 };
0370 
0371 static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id)
0372 {
0373     struct ws16c48_gpio *const ws16c48gpio = dev_id;
0374     struct gpio_chip *const chip = &ws16c48gpio->chip;
0375     struct ws16c48_reg __iomem *const reg = ws16c48gpio->reg;
0376     unsigned long int_pending;
0377     unsigned long port;
0378     unsigned long int_id;
0379     unsigned long gpio;
0380 
0381     int_pending = ioread8(&reg->int_pending) & 0x7;
0382     if (!int_pending)
0383         return IRQ_NONE;
0384 
0385     /* loop until all pending interrupts are handled */
0386     do {
0387         for_each_set_bit(port, &int_pending, 3) {
0388             int_id = ioread8(reg->pol_enab_int_id + port);
0389             for_each_set_bit(gpio, &int_id, 8)
0390                 generic_handle_domain_irq(chip->irq.domain,
0391                               gpio + 8*port);
0392         }
0393 
0394         int_pending = ioread8(&reg->int_pending) & 0x7;
0395     } while (int_pending);
0396 
0397     return IRQ_HANDLED;
0398 }
0399 
0400 #define WS16C48_NGPIO 48
0401 static const char *ws16c48_names[WS16C48_NGPIO] = {
0402     "Port 0 Bit 0", "Port 0 Bit 1", "Port 0 Bit 2", "Port 0 Bit 3",
0403     "Port 0 Bit 4", "Port 0 Bit 5", "Port 0 Bit 6", "Port 0 Bit 7",
0404     "Port 1 Bit 0", "Port 1 Bit 1", "Port 1 Bit 2", "Port 1 Bit 3",
0405     "Port 1 Bit 4", "Port 1 Bit 5", "Port 1 Bit 6", "Port 1 Bit 7",
0406     "Port 2 Bit 0", "Port 2 Bit 1", "Port 2 Bit 2", "Port 2 Bit 3",
0407     "Port 2 Bit 4", "Port 2 Bit 5", "Port 2 Bit 6", "Port 2 Bit 7",
0408     "Port 3 Bit 0", "Port 3 Bit 1", "Port 3 Bit 2", "Port 3 Bit 3",
0409     "Port 3 Bit 4", "Port 3 Bit 5", "Port 3 Bit 6", "Port 3 Bit 7",
0410     "Port 4 Bit 0", "Port 4 Bit 1", "Port 4 Bit 2", "Port 4 Bit 3",
0411     "Port 4 Bit 4", "Port 4 Bit 5", "Port 4 Bit 6", "Port 4 Bit 7",
0412     "Port 5 Bit 0", "Port 5 Bit 1", "Port 5 Bit 2", "Port 5 Bit 3",
0413     "Port 5 Bit 4", "Port 5 Bit 5", "Port 5 Bit 6", "Port 5 Bit 7"
0414 };
0415 
0416 static int ws16c48_irq_init_hw(struct gpio_chip *gc)
0417 {
0418     struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(gc);
0419 
0420     /* Select Register Page 2; Unlock all I/O ports */
0421     iowrite8(0x80, &ws16c48gpio->reg->page_lock);
0422 
0423     /* Disable interrupts for all lines */
0424     iowrite8(0, &ws16c48gpio->reg->pol_enab_int_id[0]);
0425     iowrite8(0, &ws16c48gpio->reg->pol_enab_int_id[1]);
0426     iowrite8(0, &ws16c48gpio->reg->pol_enab_int_id[2]);
0427 
0428     /* Select Register Page 3; Unlock all I/O ports */
0429     iowrite8(0xC0, &ws16c48gpio->reg->page_lock);
0430 
0431     return 0;
0432 }
0433 
0434 static int ws16c48_probe(struct device *dev, unsigned int id)
0435 {
0436     struct ws16c48_gpio *ws16c48gpio;
0437     const char *const name = dev_name(dev);
0438     struct gpio_irq_chip *girq;
0439     int err;
0440 
0441     ws16c48gpio = devm_kzalloc(dev, sizeof(*ws16c48gpio), GFP_KERNEL);
0442     if (!ws16c48gpio)
0443         return -ENOMEM;
0444 
0445     if (!devm_request_region(dev, base[id], WS16C48_EXTENT, name)) {
0446         dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
0447             base[id], base[id] + WS16C48_EXTENT);
0448         return -EBUSY;
0449     }
0450 
0451     ws16c48gpio->reg = devm_ioport_map(dev, base[id], WS16C48_EXTENT);
0452     if (!ws16c48gpio->reg)
0453         return -ENOMEM;
0454 
0455     ws16c48gpio->chip.label = name;
0456     ws16c48gpio->chip.parent = dev;
0457     ws16c48gpio->chip.owner = THIS_MODULE;
0458     ws16c48gpio->chip.base = -1;
0459     ws16c48gpio->chip.ngpio = WS16C48_NGPIO;
0460     ws16c48gpio->chip.names = ws16c48_names;
0461     ws16c48gpio->chip.get_direction = ws16c48_gpio_get_direction;
0462     ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input;
0463     ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output;
0464     ws16c48gpio->chip.get = ws16c48_gpio_get;
0465     ws16c48gpio->chip.get_multiple = ws16c48_gpio_get_multiple;
0466     ws16c48gpio->chip.set = ws16c48_gpio_set;
0467     ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple;
0468 
0469     girq = &ws16c48gpio->chip.irq;
0470     gpio_irq_chip_set_chip(girq, &ws16c48_irqchip);
0471     /* This will let us handle the parent IRQ in the driver */
0472     girq->parent_handler = NULL;
0473     girq->num_parents = 0;
0474     girq->parents = NULL;
0475     girq->default_type = IRQ_TYPE_NONE;
0476     girq->handler = handle_edge_irq;
0477     girq->init_hw = ws16c48_irq_init_hw;
0478 
0479     raw_spin_lock_init(&ws16c48gpio->lock);
0480 
0481     err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio);
0482     if (err) {
0483         dev_err(dev, "GPIO registering failed (%d)\n", err);
0484         return err;
0485     }
0486 
0487     err = devm_request_irq(dev, irq[id], ws16c48_irq_handler, IRQF_SHARED,
0488         name, ws16c48gpio);
0489     if (err) {
0490         dev_err(dev, "IRQ handler registering failed (%d)\n", err);
0491         return err;
0492     }
0493 
0494     return 0;
0495 }
0496 
0497 static struct isa_driver ws16c48_driver = {
0498     .probe = ws16c48_probe,
0499     .driver = {
0500         .name = "ws16c48"
0501     },
0502 };
0503 
0504 module_isa_driver(ws16c48_driver, num_ws16c48);
0505 
0506 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
0507 MODULE_DESCRIPTION("WinSystems WS16C48 GPIO driver");
0508 MODULE_LICENSE("GPL v2");