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