0001
0002
0003
0004
0005
0006 #include <linux/bitmap.h>
0007 #include <linux/bitops.h>
0008 #include <linux/device.h>
0009 #include <linux/errno.h>
0010 #include <linux/gpio/driver.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/irqdesc.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/pci.h>
0016 #include <linux/spinlock.h>
0017 #include <linux/types.h>
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 struct idio_16_gpio_reg {
0037 u8 out0_7;
0038 u8 in0_7;
0039 u8 irq_ctl;
0040 u8 filter_ctl;
0041 u8 out8_15;
0042 u8 in8_15;
0043 u8 irq_status;
0044 };
0045
0046
0047
0048
0049
0050
0051
0052
0053 struct idio_16_gpio {
0054 struct gpio_chip chip;
0055 raw_spinlock_t lock;
0056 struct idio_16_gpio_reg __iomem *reg;
0057 unsigned long irq_mask;
0058 };
0059
0060 static int idio_16_gpio_get_direction(struct gpio_chip *chip,
0061 unsigned int offset)
0062 {
0063 if (offset > 15)
0064 return GPIO_LINE_DIRECTION_IN;
0065
0066 return GPIO_LINE_DIRECTION_OUT;
0067 }
0068
0069 static int idio_16_gpio_direction_input(struct gpio_chip *chip,
0070 unsigned int offset)
0071 {
0072 return 0;
0073 }
0074
0075 static int idio_16_gpio_direction_output(struct gpio_chip *chip,
0076 unsigned int offset, int value)
0077 {
0078 chip->set(chip, offset, value);
0079 return 0;
0080 }
0081
0082 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
0083 {
0084 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0085 unsigned long mask = BIT(offset);
0086
0087 if (offset < 8)
0088 return !!(ioread8(&idio16gpio->reg->out0_7) & mask);
0089
0090 if (offset < 16)
0091 return !!(ioread8(&idio16gpio->reg->out8_15) & (mask >> 8));
0092
0093 if (offset < 24)
0094 return !!(ioread8(&idio16gpio->reg->in0_7) & (mask >> 16));
0095
0096 return !!(ioread8(&idio16gpio->reg->in8_15) & (mask >> 24));
0097 }
0098
0099 static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
0100 unsigned long *mask, unsigned long *bits)
0101 {
0102 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0103 unsigned long offset;
0104 unsigned long gpio_mask;
0105 void __iomem *ports[] = {
0106 &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
0107 &idio16gpio->reg->in0_7, &idio16gpio->reg->in8_15,
0108 };
0109 void __iomem *port_addr;
0110 unsigned long port_state;
0111
0112
0113 bitmap_zero(bits, chip->ngpio);
0114
0115 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
0116 port_addr = ports[offset / 8];
0117 port_state = ioread8(port_addr) & gpio_mask;
0118
0119 bitmap_set_value8(bits, port_state, offset);
0120 }
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 unsigned int mask = BIT(offset);
0130 void __iomem *base;
0131 unsigned long flags;
0132 unsigned int out_state;
0133
0134 if (offset > 15)
0135 return;
0136
0137 if (offset > 7) {
0138 mask >>= 8;
0139 base = &idio16gpio->reg->out8_15;
0140 } else
0141 base = &idio16gpio->reg->out0_7;
0142
0143 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0144
0145 if (value)
0146 out_state = ioread8(base) | mask;
0147 else
0148 out_state = ioread8(base) & ~mask;
0149
0150 iowrite8(out_state, base);
0151
0152 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0153 }
0154
0155 static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
0156 unsigned long *mask, unsigned long *bits)
0157 {
0158 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0159 unsigned long offset;
0160 unsigned long gpio_mask;
0161 void __iomem *ports[] = {
0162 &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
0163 };
0164 size_t index;
0165 void __iomem *port_addr;
0166 unsigned long bitmask;
0167 unsigned long flags;
0168 unsigned long out_state;
0169
0170 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
0171 index = offset / 8;
0172 port_addr = ports[index];
0173
0174 bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
0175
0176 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0177
0178 out_state = ioread8(port_addr) & ~gpio_mask;
0179 out_state |= bitmask;
0180 iowrite8(out_state, port_addr);
0181
0182 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0183 }
0184 }
0185
0186 static void idio_16_irq_ack(struct irq_data *data)
0187 {
0188 }
0189
0190 static void idio_16_irq_mask(struct irq_data *data)
0191 {
0192 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0193 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0194 const unsigned long mask = BIT(irqd_to_hwirq(data));
0195 unsigned long flags;
0196
0197 idio16gpio->irq_mask &= ~mask;
0198
0199 if (!idio16gpio->irq_mask) {
0200 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0201
0202 iowrite8(0, &idio16gpio->reg->irq_ctl);
0203
0204 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0205 }
0206 }
0207
0208 static void idio_16_irq_unmask(struct irq_data *data)
0209 {
0210 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
0211 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
0212 const unsigned long mask = BIT(irqd_to_hwirq(data));
0213 const unsigned long prev_irq_mask = idio16gpio->irq_mask;
0214 unsigned long flags;
0215
0216 idio16gpio->irq_mask |= mask;
0217
0218 if (!prev_irq_mask) {
0219 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
0220
0221 ioread8(&idio16gpio->reg->irq_ctl);
0222
0223 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
0224 }
0225 }
0226
0227 static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
0228 {
0229
0230 if (flow_type != IRQ_TYPE_NONE &&
0231 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
0232 return -EINVAL;
0233
0234 return 0;
0235 }
0236
0237 static struct irq_chip idio_16_irqchip = {
0238 .name = "pci-idio-16",
0239 .irq_ack = idio_16_irq_ack,
0240 .irq_mask = idio_16_irq_mask,
0241 .irq_unmask = idio_16_irq_unmask,
0242 .irq_set_type = idio_16_irq_set_type
0243 };
0244
0245 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
0246 {
0247 struct idio_16_gpio *const idio16gpio = dev_id;
0248 unsigned int irq_status;
0249 struct gpio_chip *const chip = &idio16gpio->chip;
0250 int gpio;
0251
0252 raw_spin_lock(&idio16gpio->lock);
0253
0254 irq_status = ioread8(&idio16gpio->reg->irq_status);
0255
0256 raw_spin_unlock(&idio16gpio->lock);
0257
0258
0259 if (!(irq_status & 0x3) || !(irq_status & 0x4))
0260 return IRQ_NONE;
0261
0262 for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
0263 generic_handle_domain_irq(chip->irq.domain, gpio);
0264
0265 raw_spin_lock(&idio16gpio->lock);
0266
0267
0268 iowrite8(0, &idio16gpio->reg->in0_7);
0269
0270 raw_spin_unlock(&idio16gpio->lock);
0271
0272 return IRQ_HANDLED;
0273 }
0274
0275 #define IDIO_16_NGPIO 32
0276 static const char *idio_16_names[IDIO_16_NGPIO] = {
0277 "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
0278 "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
0279 "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
0280 "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
0281 };
0282
0283 static int idio_16_irq_init_hw(struct gpio_chip *gc)
0284 {
0285 struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
0286
0287
0288 iowrite8(0, &idio16gpio->reg->irq_ctl);
0289 iowrite8(0, &idio16gpio->reg->in0_7);
0290
0291 return 0;
0292 }
0293
0294 static int idio_16_probe(struct pci_dev *pdev, const struct pci_device_id *id)
0295 {
0296 struct device *const dev = &pdev->dev;
0297 struct idio_16_gpio *idio16gpio;
0298 int err;
0299 const size_t pci_bar_index = 2;
0300 const char *const name = pci_name(pdev);
0301 struct gpio_irq_chip *girq;
0302
0303 idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
0304 if (!idio16gpio)
0305 return -ENOMEM;
0306
0307 err = pcim_enable_device(pdev);
0308 if (err) {
0309 dev_err(dev, "Failed to enable PCI device (%d)\n", err);
0310 return err;
0311 }
0312
0313 err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
0314 if (err) {
0315 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
0316 return err;
0317 }
0318
0319 idio16gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
0320
0321
0322 iowrite8(0, &idio16gpio->reg->filter_ctl);
0323
0324 idio16gpio->chip.label = name;
0325 idio16gpio->chip.parent = dev;
0326 idio16gpio->chip.owner = THIS_MODULE;
0327 idio16gpio->chip.base = -1;
0328 idio16gpio->chip.ngpio = IDIO_16_NGPIO;
0329 idio16gpio->chip.names = idio_16_names;
0330 idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
0331 idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
0332 idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
0333 idio16gpio->chip.get = idio_16_gpio_get;
0334 idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
0335 idio16gpio->chip.set = idio_16_gpio_set;
0336 idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
0337
0338 girq = &idio16gpio->chip.irq;
0339 girq->chip = &idio_16_irqchip;
0340
0341 girq->parent_handler = NULL;
0342 girq->num_parents = 0;
0343 girq->parents = NULL;
0344 girq->default_type = IRQ_TYPE_NONE;
0345 girq->handler = handle_edge_irq;
0346 girq->init_hw = idio_16_irq_init_hw;
0347
0348 raw_spin_lock_init(&idio16gpio->lock);
0349
0350 err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
0351 if (err) {
0352 dev_err(dev, "GPIO registering failed (%d)\n", err);
0353 return err;
0354 }
0355
0356 err = devm_request_irq(dev, pdev->irq, idio_16_irq_handler, IRQF_SHARED,
0357 name, idio16gpio);
0358 if (err) {
0359 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
0360 return err;
0361 }
0362
0363 return 0;
0364 }
0365
0366 static const struct pci_device_id idio_16_pci_dev_id[] = {
0367 { PCI_DEVICE(0x494F, 0x0DC8) }, { 0 }
0368 };
0369 MODULE_DEVICE_TABLE(pci, idio_16_pci_dev_id);
0370
0371 static struct pci_driver idio_16_driver = {
0372 .name = "pci-idio-16",
0373 .id_table = idio_16_pci_dev_id,
0374 .probe = idio_16_probe
0375 };
0376
0377 module_pci_driver(idio_16_driver);
0378
0379 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
0380 MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver");
0381 MODULE_LICENSE("GPL v2");