11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21ceacea2SWilliam Breathitt Gray /*
31ceacea2SWilliam Breathitt Gray  * GPIO driver for the ACCES 104-IDIO-16 family
41ceacea2SWilliam Breathitt Gray  * Copyright (C) 2015 William Breathitt Gray
51ceacea2SWilliam Breathitt Gray  *
686ea8a95SWilliam Breathitt Gray  * This driver supports the following ACCES devices: 104-IDIO-16,
786ea8a95SWilliam Breathitt Gray  * 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8.
81ceacea2SWilliam Breathitt Gray  */
9*cc442e4dSWilliam Breathitt Gray #include <linux/bits.h>
101ceacea2SWilliam Breathitt Gray #include <linux/device.h>
111ceacea2SWilliam Breathitt Gray #include <linux/errno.h>
121ceacea2SWilliam Breathitt Gray #include <linux/gpio/driver.h>
131ceacea2SWilliam Breathitt Gray #include <linux/io.h>
141ceacea2SWilliam Breathitt Gray #include <linux/ioport.h>
15a1184147SWilliam Breathitt Gray #include <linux/interrupt.h>
16a1184147SWilliam Breathitt Gray #include <linux/irqdesc.h>
1786ea8a95SWilliam Breathitt Gray #include <linux/isa.h>
181ceacea2SWilliam Breathitt Gray #include <linux/kernel.h>
191ceacea2SWilliam Breathitt Gray #include <linux/module.h>
201ceacea2SWilliam Breathitt Gray #include <linux/moduleparam.h>
211ceacea2SWilliam Breathitt Gray #include <linux/spinlock.h>
22*cc442e4dSWilliam Breathitt Gray #include <linux/types.h>
231ceacea2SWilliam Breathitt Gray 
2486ea8a95SWilliam Breathitt Gray #define IDIO_16_EXTENT 8
2586ea8a95SWilliam Breathitt Gray #define MAX_NUM_IDIO_16 max_num_isa_dev(IDIO_16_EXTENT)
2686ea8a95SWilliam Breathitt Gray 
2786ea8a95SWilliam Breathitt Gray static unsigned int base[MAX_NUM_IDIO_16];
2886ea8a95SWilliam Breathitt Gray static unsigned int num_idio_16;
29d759f906SDavid Howells module_param_hw_array(base, uint, ioport, &num_idio_16, 0);
3086ea8a95SWilliam Breathitt Gray MODULE_PARM_DESC(base, "ACCES 104-IDIO-16 base addresses");
3186ea8a95SWilliam Breathitt Gray 
3286ea8a95SWilliam Breathitt Gray static unsigned int irq[MAX_NUM_IDIO_16];
33d759f906SDavid Howells module_param_hw_array(irq, uint, irq, NULL, 0);
3486ea8a95SWilliam Breathitt Gray MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers");
351ceacea2SWilliam Breathitt Gray 
361ceacea2SWilliam Breathitt Gray /**
37*cc442e4dSWilliam Breathitt Gray  * struct idio_16_reg - device registers structure
38*cc442e4dSWilliam Breathitt Gray  * @out0_7:	Read: N/A
39*cc442e4dSWilliam Breathitt Gray  *		Write: FET Drive Outputs 0-7
40*cc442e4dSWilliam Breathitt Gray  * @in0_7:	Read: Isolated Inputs 0-7
41*cc442e4dSWilliam Breathitt Gray  *		Write: Clear Interrupt
42*cc442e4dSWilliam Breathitt Gray  * @irq_ctl:	Read: Enable IRQ
43*cc442e4dSWilliam Breathitt Gray  *		Write: Disable IRQ
44*cc442e4dSWilliam Breathitt Gray  * @unused:	N/A
45*cc442e4dSWilliam Breathitt Gray  * @out8_15:	Read: N/A
46*cc442e4dSWilliam Breathitt Gray  *		Write: FET Drive Outputs 8-15
47*cc442e4dSWilliam Breathitt Gray  * @in8_15:	Read: Isolated Inputs 8-15
48*cc442e4dSWilliam Breathitt Gray  *		Write: N/A
49*cc442e4dSWilliam Breathitt Gray  */
50*cc442e4dSWilliam Breathitt Gray struct idio_16_reg {
51*cc442e4dSWilliam Breathitt Gray 	u8 out0_7;
52*cc442e4dSWilliam Breathitt Gray 	u8 in0_7;
53*cc442e4dSWilliam Breathitt Gray 	u8 irq_ctl;
54*cc442e4dSWilliam Breathitt Gray 	u8 unused;
55*cc442e4dSWilliam Breathitt Gray 	u8 out8_15;
56*cc442e4dSWilliam Breathitt Gray 	u8 in8_15;
57*cc442e4dSWilliam Breathitt Gray };
58*cc442e4dSWilliam Breathitt Gray 
59*cc442e4dSWilliam Breathitt Gray /**
601ceacea2SWilliam Breathitt Gray  * struct idio_16_gpio - GPIO device private data structure
611ceacea2SWilliam Breathitt Gray  * @chip:	instance of the gpio_chip
62a1184147SWilliam Breathitt Gray  * @lock:	synchronization lock to prevent I/O race conditions
63a1184147SWilliam Breathitt Gray  * @irq_mask:	I/O bits affected by interrupts
64*cc442e4dSWilliam Breathitt Gray  * @reg:	I/O address offset for the device registers
651ceacea2SWilliam Breathitt Gray  * @out_state:	output bits state
661ceacea2SWilliam Breathitt Gray  */
671ceacea2SWilliam Breathitt Gray struct idio_16_gpio {
681ceacea2SWilliam Breathitt Gray 	struct gpio_chip chip;
693906e808SJulia Cartwright 	raw_spinlock_t lock;
70a1184147SWilliam Breathitt Gray 	unsigned long irq_mask;
71*cc442e4dSWilliam Breathitt Gray 	struct idio_16_reg __iomem *reg;
72cc0f53d2SNavin Sankar Velliangiri 	unsigned int out_state;
731ceacea2SWilliam Breathitt Gray };
741ceacea2SWilliam Breathitt Gray 
75cc0f53d2SNavin Sankar Velliangiri static int idio_16_gpio_get_direction(struct gpio_chip *chip,
76cc0f53d2SNavin Sankar Velliangiri 				      unsigned int offset)
771ceacea2SWilliam Breathitt Gray {
781ceacea2SWilliam Breathitt Gray 	if (offset > 15)
79e42615ecSMatti Vaittinen 		return GPIO_LINE_DIRECTION_IN;
801ceacea2SWilliam Breathitt Gray 
81e42615ecSMatti Vaittinen 	return GPIO_LINE_DIRECTION_OUT;
821ceacea2SWilliam Breathitt Gray }
831ceacea2SWilliam Breathitt Gray 
84cc0f53d2SNavin Sankar Velliangiri static int idio_16_gpio_direction_input(struct gpio_chip *chip,
85cc0f53d2SNavin Sankar Velliangiri 					unsigned int offset)
861ceacea2SWilliam Breathitt Gray {
871ceacea2SWilliam Breathitt Gray 	return 0;
881ceacea2SWilliam Breathitt Gray }
891ceacea2SWilliam Breathitt Gray 
901ceacea2SWilliam Breathitt Gray static int idio_16_gpio_direction_output(struct gpio_chip *chip,
91cc0f53d2SNavin Sankar Velliangiri 	unsigned int offset, int value)
921ceacea2SWilliam Breathitt Gray {
931ceacea2SWilliam Breathitt Gray 	chip->set(chip, offset, value);
941ceacea2SWilliam Breathitt Gray 	return 0;
951ceacea2SWilliam Breathitt Gray }
961ceacea2SWilliam Breathitt Gray 
97cc0f53d2SNavin Sankar Velliangiri static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
981ceacea2SWilliam Breathitt Gray {
99d602ae90SLinus Walleij 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
100cc0f53d2SNavin Sankar Velliangiri 	const unsigned int mask = BIT(offset-16);
1011ceacea2SWilliam Breathitt Gray 
1021ceacea2SWilliam Breathitt Gray 	if (offset < 16)
1031ceacea2SWilliam Breathitt Gray 		return -EINVAL;
1041ceacea2SWilliam Breathitt Gray 
1051ceacea2SWilliam Breathitt Gray 	if (offset < 24)
106*cc442e4dSWilliam Breathitt Gray 		return !!(ioread8(&idio16gpio->reg->in0_7) & mask);
1071ceacea2SWilliam Breathitt Gray 
108*cc442e4dSWilliam Breathitt Gray 	return !!(ioread8(&idio16gpio->reg->in8_15) & (mask>>8));
1091ceacea2SWilliam Breathitt Gray }
1101ceacea2SWilliam Breathitt Gray 
11115f59cffSWilliam Breathitt Gray static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
11215f59cffSWilliam Breathitt Gray 	unsigned long *mask, unsigned long *bits)
11315f59cffSWilliam Breathitt Gray {
11415f59cffSWilliam Breathitt Gray 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
11515f59cffSWilliam Breathitt Gray 
11615f59cffSWilliam Breathitt Gray 	*bits = 0;
11715f59cffSWilliam Breathitt Gray 	if (*mask & GENMASK(23, 16))
118*cc442e4dSWilliam Breathitt Gray 		*bits |= (unsigned long)ioread8(&idio16gpio->reg->in0_7) << 16;
11915f59cffSWilliam Breathitt Gray 	if (*mask & GENMASK(31, 24))
120*cc442e4dSWilliam Breathitt Gray 		*bits |= (unsigned long)ioread8(&idio16gpio->reg->in8_15) << 24;
12115f59cffSWilliam Breathitt Gray 
12215f59cffSWilliam Breathitt Gray 	return 0;
12315f59cffSWilliam Breathitt Gray }
12415f59cffSWilliam Breathitt Gray 
125cc0f53d2SNavin Sankar Velliangiri static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
126cc0f53d2SNavin Sankar Velliangiri 			     int value)
1271ceacea2SWilliam Breathitt Gray {
128d602ae90SLinus Walleij 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
129cc0f53d2SNavin Sankar Velliangiri 	const unsigned int mask = BIT(offset);
1301ceacea2SWilliam Breathitt Gray 	unsigned long flags;
1311ceacea2SWilliam Breathitt Gray 
1321ceacea2SWilliam Breathitt Gray 	if (offset > 15)
1331ceacea2SWilliam Breathitt Gray 		return;
1341ceacea2SWilliam Breathitt Gray 
1353906e808SJulia Cartwright 	raw_spin_lock_irqsave(&idio16gpio->lock, flags);
1361ceacea2SWilliam Breathitt Gray 
1371ceacea2SWilliam Breathitt Gray 	if (value)
1386e0171b4SWilliam Breathitt Gray 		idio16gpio->out_state |= mask;
1391ceacea2SWilliam Breathitt Gray 	else
1406e0171b4SWilliam Breathitt Gray 		idio16gpio->out_state &= ~mask;
1411ceacea2SWilliam Breathitt Gray 
1421ceacea2SWilliam Breathitt Gray 	if (offset > 7)
143*cc442e4dSWilliam Breathitt Gray 		iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15);
1441ceacea2SWilliam Breathitt Gray 	else
145*cc442e4dSWilliam Breathitt Gray 		iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7);
1461ceacea2SWilliam Breathitt Gray 
1473906e808SJulia Cartwright 	raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
1481ceacea2SWilliam Breathitt Gray }
1491ceacea2SWilliam Breathitt Gray 
1509d7ae812SWilliam Breathitt Gray static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
1519d7ae812SWilliam Breathitt Gray 	unsigned long *mask, unsigned long *bits)
1529d7ae812SWilliam Breathitt Gray {
1539d7ae812SWilliam Breathitt Gray 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
1549d7ae812SWilliam Breathitt Gray 	unsigned long flags;
1559d7ae812SWilliam Breathitt Gray 
1563906e808SJulia Cartwright 	raw_spin_lock_irqsave(&idio16gpio->lock, flags);
1579d7ae812SWilliam Breathitt Gray 
1589d7ae812SWilliam Breathitt Gray 	idio16gpio->out_state &= ~*mask;
1599d7ae812SWilliam Breathitt Gray 	idio16gpio->out_state |= *mask & *bits;
1609d7ae812SWilliam Breathitt Gray 
1619d7ae812SWilliam Breathitt Gray 	if (*mask & 0xFF)
162*cc442e4dSWilliam Breathitt Gray 		iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7);
1639d7ae812SWilliam Breathitt Gray 	if ((*mask >> 8) & 0xFF)
164*cc442e4dSWilliam Breathitt Gray 		iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15);
1659d7ae812SWilliam Breathitt Gray 
1663906e808SJulia Cartwright 	raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
1679d7ae812SWilliam Breathitt Gray }
1689d7ae812SWilliam Breathitt Gray 
169a1184147SWilliam Breathitt Gray static void idio_16_irq_ack(struct irq_data *data)
170a1184147SWilliam Breathitt Gray {
171a1184147SWilliam Breathitt Gray }
172a1184147SWilliam Breathitt Gray 
173a1184147SWilliam Breathitt Gray static void idio_16_irq_mask(struct irq_data *data)
174a1184147SWilliam Breathitt Gray {
175a1184147SWilliam Breathitt Gray 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
176d602ae90SLinus Walleij 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
177a1184147SWilliam Breathitt Gray 	const unsigned long mask = BIT(irqd_to_hwirq(data));
178a1184147SWilliam Breathitt Gray 	unsigned long flags;
179a1184147SWilliam Breathitt Gray 
180a1184147SWilliam Breathitt Gray 	idio16gpio->irq_mask &= ~mask;
181a1184147SWilliam Breathitt Gray 
182a1184147SWilliam Breathitt Gray 	if (!idio16gpio->irq_mask) {
1833906e808SJulia Cartwright 		raw_spin_lock_irqsave(&idio16gpio->lock, flags);
184a1184147SWilliam Breathitt Gray 
185*cc442e4dSWilliam Breathitt Gray 		iowrite8(0, &idio16gpio->reg->irq_ctl);
186a1184147SWilliam Breathitt Gray 
1873906e808SJulia Cartwright 		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
188a1184147SWilliam Breathitt Gray 	}
189a1184147SWilliam Breathitt Gray }
190a1184147SWilliam Breathitt Gray 
191a1184147SWilliam Breathitt Gray static void idio_16_irq_unmask(struct irq_data *data)
192a1184147SWilliam Breathitt Gray {
193a1184147SWilliam Breathitt Gray 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
194d602ae90SLinus Walleij 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
195a1184147SWilliam Breathitt Gray 	const unsigned long mask = BIT(irqd_to_hwirq(data));
196a1184147SWilliam Breathitt Gray 	const unsigned long prev_irq_mask = idio16gpio->irq_mask;
197a1184147SWilliam Breathitt Gray 	unsigned long flags;
198a1184147SWilliam Breathitt Gray 
199a1184147SWilliam Breathitt Gray 	idio16gpio->irq_mask |= mask;
200a1184147SWilliam Breathitt Gray 
201a1184147SWilliam Breathitt Gray 	if (!prev_irq_mask) {
2023906e808SJulia Cartwright 		raw_spin_lock_irqsave(&idio16gpio->lock, flags);
203a1184147SWilliam Breathitt Gray 
204*cc442e4dSWilliam Breathitt Gray 		ioread8(&idio16gpio->reg->irq_ctl);
205a1184147SWilliam Breathitt Gray 
2063906e808SJulia Cartwright 		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
207a1184147SWilliam Breathitt Gray 	}
208a1184147SWilliam Breathitt Gray }
209a1184147SWilliam Breathitt Gray 
210cc0f53d2SNavin Sankar Velliangiri static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
211a1184147SWilliam Breathitt Gray {
212a1184147SWilliam Breathitt Gray 	/* The only valid irq types are none and both-edges */
213a1184147SWilliam Breathitt Gray 	if (flow_type != IRQ_TYPE_NONE &&
214a1184147SWilliam Breathitt Gray 		(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
215a1184147SWilliam Breathitt Gray 		return -EINVAL;
216a1184147SWilliam Breathitt Gray 
217a1184147SWilliam Breathitt Gray 	return 0;
218a1184147SWilliam Breathitt Gray }
219a1184147SWilliam Breathitt Gray 
220a1184147SWilliam Breathitt Gray static struct irq_chip idio_16_irqchip = {
221a1184147SWilliam Breathitt Gray 	.name = "104-idio-16",
222a1184147SWilliam Breathitt Gray 	.irq_ack = idio_16_irq_ack,
223a1184147SWilliam Breathitt Gray 	.irq_mask = idio_16_irq_mask,
224a1184147SWilliam Breathitt Gray 	.irq_unmask = idio_16_irq_unmask,
225a1184147SWilliam Breathitt Gray 	.irq_set_type = idio_16_irq_set_type
226a1184147SWilliam Breathitt Gray };
227a1184147SWilliam Breathitt Gray 
228a1184147SWilliam Breathitt Gray static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
229a1184147SWilliam Breathitt Gray {
230a1184147SWilliam Breathitt Gray 	struct idio_16_gpio *const idio16gpio = dev_id;
231a1184147SWilliam Breathitt Gray 	struct gpio_chip *const chip = &idio16gpio->chip;
232a1184147SWilliam Breathitt Gray 	int gpio;
233a1184147SWilliam Breathitt Gray 
234a1184147SWilliam Breathitt Gray 	for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
235dbd1c54fSMarc Zyngier 		generic_handle_domain_irq(chip->irq.domain, gpio);
236a1184147SWilliam Breathitt Gray 
2373906e808SJulia Cartwright 	raw_spin_lock(&idio16gpio->lock);
23812b61c9dSWilliam Breathitt Gray 
239*cc442e4dSWilliam Breathitt Gray 	iowrite8(0, &idio16gpio->reg->in0_7);
24012b61c9dSWilliam Breathitt Gray 
2413906e808SJulia Cartwright 	raw_spin_unlock(&idio16gpio->lock);
24212b61c9dSWilliam Breathitt Gray 
243a1184147SWilliam Breathitt Gray 	return IRQ_HANDLED;
244a1184147SWilliam Breathitt Gray }
245a1184147SWilliam Breathitt Gray 
246e0af4b5eSWilliam Breathitt Gray #define IDIO_16_NGPIO 32
247e0af4b5eSWilliam Breathitt Gray static const char *idio_16_names[IDIO_16_NGPIO] = {
248e0af4b5eSWilliam Breathitt Gray 	"OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
249e0af4b5eSWilliam Breathitt Gray 	"OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
250e0af4b5eSWilliam Breathitt Gray 	"IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
251e0af4b5eSWilliam Breathitt Gray 	"IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
252e0af4b5eSWilliam Breathitt Gray };
253e0af4b5eSWilliam Breathitt Gray 
25482e4613dSLinus Walleij static int idio_16_irq_init_hw(struct gpio_chip *gc)
25582e4613dSLinus Walleij {
25682e4613dSLinus Walleij 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
25782e4613dSLinus Walleij 
25882e4613dSLinus Walleij 	/* Disable IRQ by default */
259*cc442e4dSWilliam Breathitt Gray 	iowrite8(0, &idio16gpio->reg->irq_ctl);
260*cc442e4dSWilliam Breathitt Gray 	iowrite8(0, &idio16gpio->reg->in0_7);
26182e4613dSLinus Walleij 
26282e4613dSLinus Walleij 	return 0;
26382e4613dSLinus Walleij }
26482e4613dSLinus Walleij 
26586ea8a95SWilliam Breathitt Gray static int idio_16_probe(struct device *dev, unsigned int id)
2661ceacea2SWilliam Breathitt Gray {
2671ceacea2SWilliam Breathitt Gray 	struct idio_16_gpio *idio16gpio;
2686e0171b4SWilliam Breathitt Gray 	const char *const name = dev_name(dev);
26982e4613dSLinus Walleij 	struct gpio_irq_chip *girq;
2701ceacea2SWilliam Breathitt Gray 	int err;
2711ceacea2SWilliam Breathitt Gray 
2721ceacea2SWilliam Breathitt Gray 	idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
2731ceacea2SWilliam Breathitt Gray 	if (!idio16gpio)
2741ceacea2SWilliam Breathitt Gray 		return -ENOMEM;
2751ceacea2SWilliam Breathitt Gray 
27686ea8a95SWilliam Breathitt Gray 	if (!devm_request_region(dev, base[id], IDIO_16_EXTENT, name)) {
277cb32389cSWilliam Breathitt Gray 		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
27886ea8a95SWilliam Breathitt Gray 			base[id], base[id] + IDIO_16_EXTENT);
279cb32389cSWilliam Breathitt Gray 		return -EBUSY;
2801ceacea2SWilliam Breathitt Gray 	}
2811ceacea2SWilliam Breathitt Gray 
282*cc442e4dSWilliam Breathitt Gray 	idio16gpio->reg = devm_ioport_map(dev, base[id], IDIO_16_EXTENT);
283*cc442e4dSWilliam Breathitt Gray 	if (!idio16gpio->reg)
284e0a574efSWilliam Breathitt Gray 		return -ENOMEM;
285e0a574efSWilliam Breathitt Gray 
2866e0171b4SWilliam Breathitt Gray 	idio16gpio->chip.label = name;
28758383c78SLinus Walleij 	idio16gpio->chip.parent = dev;
2881ceacea2SWilliam Breathitt Gray 	idio16gpio->chip.owner = THIS_MODULE;
2891ceacea2SWilliam Breathitt Gray 	idio16gpio->chip.base = -1;
290e0af4b5eSWilliam Breathitt Gray 	idio16gpio->chip.ngpio = IDIO_16_NGPIO;
291e0af4b5eSWilliam Breathitt Gray 	idio16gpio->chip.names = idio_16_names;
2921ceacea2SWilliam Breathitt Gray 	idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
2931ceacea2SWilliam Breathitt Gray 	idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
2941ceacea2SWilliam Breathitt Gray 	idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
2951ceacea2SWilliam Breathitt Gray 	idio16gpio->chip.get = idio_16_gpio_get;
29615f59cffSWilliam Breathitt Gray 	idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
2971ceacea2SWilliam Breathitt Gray 	idio16gpio->chip.set = idio_16_gpio_set;
2989d7ae812SWilliam Breathitt Gray 	idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
2991ceacea2SWilliam Breathitt Gray 	idio16gpio->out_state = 0xFFFF;
3001ceacea2SWilliam Breathitt Gray 
30182e4613dSLinus Walleij 	girq = &idio16gpio->chip.irq;
30282e4613dSLinus Walleij 	girq->chip = &idio_16_irqchip;
30382e4613dSLinus Walleij 	/* This will let us handle the parent IRQ in the driver */
30482e4613dSLinus Walleij 	girq->parent_handler = NULL;
30582e4613dSLinus Walleij 	girq->num_parents = 0;
30682e4613dSLinus Walleij 	girq->parents = NULL;
30782e4613dSLinus Walleij 	girq->default_type = IRQ_TYPE_NONE;
30882e4613dSLinus Walleij 	girq->handler = handle_edge_irq;
30982e4613dSLinus Walleij 	girq->init_hw = idio_16_irq_init_hw;
31082e4613dSLinus Walleij 
3113906e808SJulia Cartwright 	raw_spin_lock_init(&idio16gpio->lock);
3121ceacea2SWilliam Breathitt Gray 
313837143d3SWilliam Breathitt Gray 	err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
3141ceacea2SWilliam Breathitt Gray 	if (err) {
3151ceacea2SWilliam Breathitt Gray 		dev_err(dev, "GPIO registering failed (%d)\n", err);
316cb32389cSWilliam Breathitt Gray 		return err;
3171ceacea2SWilliam Breathitt Gray 	}
3181ceacea2SWilliam Breathitt Gray 
319837143d3SWilliam Breathitt Gray 	err = devm_request_irq(dev, irq[id], idio_16_irq_handler, 0, name,
320837143d3SWilliam Breathitt Gray 		idio16gpio);
321837143d3SWilliam Breathitt Gray 	if (err) {
322837143d3SWilliam Breathitt Gray 		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
323837143d3SWilliam Breathitt Gray 		return err;
324837143d3SWilliam Breathitt Gray 	}
3251ceacea2SWilliam Breathitt Gray 
3261ceacea2SWilliam Breathitt Gray 	return 0;
3271ceacea2SWilliam Breathitt Gray }
3281ceacea2SWilliam Breathitt Gray 
32986ea8a95SWilliam Breathitt Gray static struct isa_driver idio_16_driver = {
33086ea8a95SWilliam Breathitt Gray 	.probe = idio_16_probe,
3311ceacea2SWilliam Breathitt Gray 	.driver = {
3321ceacea2SWilliam Breathitt Gray 		.name = "104-idio-16"
3331ceacea2SWilliam Breathitt Gray 	},
3341ceacea2SWilliam Breathitt Gray };
3351ceacea2SWilliam Breathitt Gray 
33686ea8a95SWilliam Breathitt Gray module_isa_driver(idio_16_driver, num_idio_16);
3371ceacea2SWilliam Breathitt Gray 
3381ceacea2SWilliam Breathitt Gray MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
3391ceacea2SWilliam Breathitt Gray MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver");
34022aeddb5SWilliam Breathitt Gray MODULE_LICENSE("GPL v2");
341