1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * GPIO driver for the ACCES 104-IDIO-16 family
4  * Copyright (C) 2015 William Breathitt Gray
5  *
6  * This driver supports the following ACCES devices: 104-IDIO-16,
7  * 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8.
8  */
9 #include <linux/bits.h>
10 #include <linux/device.h>
11 #include <linux/errno.h>
12 #include <linux/gpio/driver.h>
13 #include <linux/io.h>
14 #include <linux/ioport.h>
15 #include <linux/interrupt.h>
16 #include <linux/irqdesc.h>
17 #include <linux/isa.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/moduleparam.h>
21 #include <linux/spinlock.h>
22 #include <linux/types.h>
23 
24 #define IDIO_16_EXTENT 8
25 #define MAX_NUM_IDIO_16 max_num_isa_dev(IDIO_16_EXTENT)
26 
27 static unsigned int base[MAX_NUM_IDIO_16];
28 static unsigned int num_idio_16;
29 module_param_hw_array(base, uint, ioport, &num_idio_16, 0);
30 MODULE_PARM_DESC(base, "ACCES 104-IDIO-16 base addresses");
31 
32 static unsigned int irq[MAX_NUM_IDIO_16];
33 module_param_hw_array(irq, uint, irq, NULL, 0);
34 MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers");
35 
36 /**
37  * struct idio_16_reg - device registers structure
38  * @out0_7:	Read: N/A
39  *		Write: FET Drive Outputs 0-7
40  * @in0_7:	Read: Isolated Inputs 0-7
41  *		Write: Clear Interrupt
42  * @irq_ctl:	Read: Enable IRQ
43  *		Write: Disable IRQ
44  * @unused:	N/A
45  * @out8_15:	Read: N/A
46  *		Write: FET Drive Outputs 8-15
47  * @in8_15:	Read: Isolated Inputs 8-15
48  *		Write: N/A
49  */
50 struct idio_16_reg {
51 	u8 out0_7;
52 	u8 in0_7;
53 	u8 irq_ctl;
54 	u8 unused;
55 	u8 out8_15;
56 	u8 in8_15;
57 };
58 
59 /**
60  * struct idio_16_gpio - GPIO device private data structure
61  * @chip:	instance of the gpio_chip
62  * @lock:	synchronization lock to prevent I/O race conditions
63  * @irq_mask:	I/O bits affected by interrupts
64  * @reg:	I/O address offset for the device registers
65  * @out_state:	output bits state
66  */
67 struct idio_16_gpio {
68 	struct gpio_chip chip;
69 	raw_spinlock_t lock;
70 	unsigned long irq_mask;
71 	struct idio_16_reg __iomem *reg;
72 	unsigned int out_state;
73 };
74 
75 static int idio_16_gpio_get_direction(struct gpio_chip *chip,
76 				      unsigned int offset)
77 {
78 	if (offset > 15)
79 		return GPIO_LINE_DIRECTION_IN;
80 
81 	return GPIO_LINE_DIRECTION_OUT;
82 }
83 
84 static int idio_16_gpio_direction_input(struct gpio_chip *chip,
85 					unsigned int offset)
86 {
87 	return 0;
88 }
89 
90 static int idio_16_gpio_direction_output(struct gpio_chip *chip,
91 	unsigned int offset, int value)
92 {
93 	chip->set(chip, offset, value);
94 	return 0;
95 }
96 
97 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
98 {
99 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
100 	const unsigned int mask = BIT(offset-16);
101 
102 	if (offset < 16)
103 		return -EINVAL;
104 
105 	if (offset < 24)
106 		return !!(ioread8(&idio16gpio->reg->in0_7) & mask);
107 
108 	return !!(ioread8(&idio16gpio->reg->in8_15) & (mask>>8));
109 }
110 
111 static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
112 	unsigned long *mask, unsigned long *bits)
113 {
114 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
115 
116 	*bits = 0;
117 	if (*mask & GENMASK(23, 16))
118 		*bits |= (unsigned long)ioread8(&idio16gpio->reg->in0_7) << 16;
119 	if (*mask & GENMASK(31, 24))
120 		*bits |= (unsigned long)ioread8(&idio16gpio->reg->in8_15) << 24;
121 
122 	return 0;
123 }
124 
125 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
126 			     int value)
127 {
128 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
129 	const unsigned int mask = BIT(offset);
130 	unsigned long flags;
131 
132 	if (offset > 15)
133 		return;
134 
135 	raw_spin_lock_irqsave(&idio16gpio->lock, flags);
136 
137 	if (value)
138 		idio16gpio->out_state |= mask;
139 	else
140 		idio16gpio->out_state &= ~mask;
141 
142 	if (offset > 7)
143 		iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15);
144 	else
145 		iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7);
146 
147 	raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
148 }
149 
150 static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
151 	unsigned long *mask, unsigned long *bits)
152 {
153 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
154 	unsigned long flags;
155 
156 	raw_spin_lock_irqsave(&idio16gpio->lock, flags);
157 
158 	idio16gpio->out_state &= ~*mask;
159 	idio16gpio->out_state |= *mask & *bits;
160 
161 	if (*mask & 0xFF)
162 		iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7);
163 	if ((*mask >> 8) & 0xFF)
164 		iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15);
165 
166 	raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
167 }
168 
169 static void idio_16_irq_ack(struct irq_data *data)
170 {
171 }
172 
173 static void idio_16_irq_mask(struct irq_data *data)
174 {
175 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
176 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
177 	const unsigned long offset = irqd_to_hwirq(data);
178 	unsigned long flags;
179 
180 	idio16gpio->irq_mask &= ~BIT(offset);
181 	gpiochip_disable_irq(chip, offset);
182 
183 	if (!idio16gpio->irq_mask) {
184 		raw_spin_lock_irqsave(&idio16gpio->lock, flags);
185 
186 		iowrite8(0, &idio16gpio->reg->irq_ctl);
187 
188 		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
189 	}
190 }
191 
192 static void idio_16_irq_unmask(struct irq_data *data)
193 {
194 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
195 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
196 	const unsigned long offset = irqd_to_hwirq(data);
197 	const unsigned long prev_irq_mask = idio16gpio->irq_mask;
198 	unsigned long flags;
199 
200 	gpiochip_enable_irq(chip, offset);
201 	idio16gpio->irq_mask |= BIT(offset);
202 
203 	if (!prev_irq_mask) {
204 		raw_spin_lock_irqsave(&idio16gpio->lock, flags);
205 
206 		ioread8(&idio16gpio->reg->irq_ctl);
207 
208 		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
209 	}
210 }
211 
212 static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
213 {
214 	/* The only valid irq types are none and both-edges */
215 	if (flow_type != IRQ_TYPE_NONE &&
216 		(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
217 		return -EINVAL;
218 
219 	return 0;
220 }
221 
222 static const struct irq_chip idio_16_irqchip = {
223 	.name = "104-idio-16",
224 	.irq_ack = idio_16_irq_ack,
225 	.irq_mask = idio_16_irq_mask,
226 	.irq_unmask = idio_16_irq_unmask,
227 	.irq_set_type = idio_16_irq_set_type,
228 	.flags = IRQCHIP_IMMUTABLE,
229 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
230 };
231 
232 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
233 {
234 	struct idio_16_gpio *const idio16gpio = dev_id;
235 	struct gpio_chip *const chip = &idio16gpio->chip;
236 	int gpio;
237 
238 	for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
239 		generic_handle_domain_irq(chip->irq.domain, gpio);
240 
241 	raw_spin_lock(&idio16gpio->lock);
242 
243 	iowrite8(0, &idio16gpio->reg->in0_7);
244 
245 	raw_spin_unlock(&idio16gpio->lock);
246 
247 	return IRQ_HANDLED;
248 }
249 
250 #define IDIO_16_NGPIO 32
251 static const char *idio_16_names[IDIO_16_NGPIO] = {
252 	"OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
253 	"OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
254 	"IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
255 	"IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
256 };
257 
258 static int idio_16_irq_init_hw(struct gpio_chip *gc)
259 {
260 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
261 
262 	/* Disable IRQ by default */
263 	iowrite8(0, &idio16gpio->reg->irq_ctl);
264 	iowrite8(0, &idio16gpio->reg->in0_7);
265 
266 	return 0;
267 }
268 
269 static int idio_16_probe(struct device *dev, unsigned int id)
270 {
271 	struct idio_16_gpio *idio16gpio;
272 	const char *const name = dev_name(dev);
273 	struct gpio_irq_chip *girq;
274 	int err;
275 
276 	idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
277 	if (!idio16gpio)
278 		return -ENOMEM;
279 
280 	if (!devm_request_region(dev, base[id], IDIO_16_EXTENT, name)) {
281 		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
282 			base[id], base[id] + IDIO_16_EXTENT);
283 		return -EBUSY;
284 	}
285 
286 	idio16gpio->reg = devm_ioport_map(dev, base[id], IDIO_16_EXTENT);
287 	if (!idio16gpio->reg)
288 		return -ENOMEM;
289 
290 	idio16gpio->chip.label = name;
291 	idio16gpio->chip.parent = dev;
292 	idio16gpio->chip.owner = THIS_MODULE;
293 	idio16gpio->chip.base = -1;
294 	idio16gpio->chip.ngpio = IDIO_16_NGPIO;
295 	idio16gpio->chip.names = idio_16_names;
296 	idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
297 	idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
298 	idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
299 	idio16gpio->chip.get = idio_16_gpio_get;
300 	idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
301 	idio16gpio->chip.set = idio_16_gpio_set;
302 	idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
303 	idio16gpio->out_state = 0xFFFF;
304 
305 	girq = &idio16gpio->chip.irq;
306 	gpio_irq_chip_set_chip(girq, &idio_16_irqchip);
307 	/* This will let us handle the parent IRQ in the driver */
308 	girq->parent_handler = NULL;
309 	girq->num_parents = 0;
310 	girq->parents = NULL;
311 	girq->default_type = IRQ_TYPE_NONE;
312 	girq->handler = handle_edge_irq;
313 	girq->init_hw = idio_16_irq_init_hw;
314 
315 	raw_spin_lock_init(&idio16gpio->lock);
316 
317 	err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
318 	if (err) {
319 		dev_err(dev, "GPIO registering failed (%d)\n", err);
320 		return err;
321 	}
322 
323 	err = devm_request_irq(dev, irq[id], idio_16_irq_handler, 0, name,
324 		idio16gpio);
325 	if (err) {
326 		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
327 		return err;
328 	}
329 
330 	return 0;
331 }
332 
333 static struct isa_driver idio_16_driver = {
334 	.probe = idio_16_probe,
335 	.driver = {
336 		.name = "104-idio-16"
337 	},
338 };
339 
340 module_isa_driver(idio_16_driver, num_idio_16);
341 
342 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
343 MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver");
344 MODULE_LICENSE("GPL v2");
345