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