xref: /openbmc/linux/drivers/gpio/gpio-ws16c48.c (revision 1b39eacd)
1 /*
2  * GPIO driver for the WinSystems WS16C48
3  * Copyright (C) 2016 William Breathitt Gray
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License, version 2, as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14 #include <linux/bitops.h>
15 #include <linux/device.h>
16 #include <linux/errno.h>
17 #include <linux/gpio/driver.h>
18 #include <linux/io.h>
19 #include <linux/ioport.h>
20 #include <linux/interrupt.h>
21 #include <linux/irqdesc.h>
22 #include <linux/isa.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/moduleparam.h>
26 #include <linux/spinlock.h>
27 
28 #define WS16C48_EXTENT 16
29 #define MAX_NUM_WS16C48 max_num_isa_dev(WS16C48_EXTENT)
30 
31 static unsigned int base[MAX_NUM_WS16C48];
32 static unsigned int num_ws16c48;
33 module_param_hw_array(base, uint, ioport, &num_ws16c48, 0);
34 MODULE_PARM_DESC(base, "WinSystems WS16C48 base addresses");
35 
36 static unsigned int irq[MAX_NUM_WS16C48];
37 module_param_hw_array(irq, uint, irq, NULL, 0);
38 MODULE_PARM_DESC(irq, "WinSystems WS16C48 interrupt line numbers");
39 
40 /**
41  * struct ws16c48_gpio - GPIO device private data structure
42  * @chip:	instance of the gpio_chip
43  * @io_state:	bit I/O state (whether bit is set to input or output)
44  * @out_state:	output bits state
45  * @lock:	synchronization lock to prevent I/O race conditions
46  * @irq_mask:	I/O bits affected by interrupts
47  * @flow_mask:	IRQ flow type mask for the respective I/O bits
48  * @base:	base port address of the GPIO device
49  */
50 struct ws16c48_gpio {
51 	struct gpio_chip chip;
52 	unsigned char io_state[6];
53 	unsigned char out_state[6];
54 	raw_spinlock_t lock;
55 	unsigned long irq_mask;
56 	unsigned long flow_mask;
57 	unsigned base;
58 };
59 
60 static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
61 {
62 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
63 	const unsigned port = offset / 8;
64 	const unsigned mask = BIT(offset % 8);
65 
66 	return !!(ws16c48gpio->io_state[port] & mask);
67 }
68 
69 static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
70 {
71 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
72 	const unsigned port = offset / 8;
73 	const unsigned mask = BIT(offset % 8);
74 	unsigned long flags;
75 
76 	raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
77 
78 	ws16c48gpio->io_state[port] |= mask;
79 	ws16c48gpio->out_state[port] &= ~mask;
80 	outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
81 
82 	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
83 
84 	return 0;
85 }
86 
87 static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
88 	unsigned offset, int value)
89 {
90 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
91 	const unsigned port = offset / 8;
92 	const unsigned mask = BIT(offset % 8);
93 	unsigned long flags;
94 
95 	raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
96 
97 	ws16c48gpio->io_state[port] &= ~mask;
98 	if (value)
99 		ws16c48gpio->out_state[port] |= mask;
100 	else
101 		ws16c48gpio->out_state[port] &= ~mask;
102 	outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
103 
104 	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
105 
106 	return 0;
107 }
108 
109 static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)
110 {
111 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
112 	const unsigned port = offset / 8;
113 	const unsigned mask = BIT(offset % 8);
114 	unsigned long flags;
115 	unsigned port_state;
116 
117 	raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
118 
119 	/* ensure that GPIO is set for input */
120 	if (!(ws16c48gpio->io_state[port] & mask)) {
121 		raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
122 		return -EINVAL;
123 	}
124 
125 	port_state = inb(ws16c48gpio->base + port);
126 
127 	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
128 
129 	return !!(port_state & mask);
130 }
131 
132 static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
133 {
134 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
135 	const unsigned port = offset / 8;
136 	const unsigned mask = BIT(offset % 8);
137 	unsigned long flags;
138 
139 	raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
140 
141 	/* ensure that GPIO is set for output */
142 	if (ws16c48gpio->io_state[port] & mask) {
143 		raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
144 		return;
145 	}
146 
147 	if (value)
148 		ws16c48gpio->out_state[port] |= mask;
149 	else
150 		ws16c48gpio->out_state[port] &= ~mask;
151 	outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
152 
153 	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
154 }
155 
156 static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
157 	unsigned long *mask, unsigned long *bits)
158 {
159 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
160 	unsigned int i;
161 	const unsigned int gpio_reg_size = 8;
162 	unsigned int port;
163 	unsigned int iomask;
164 	unsigned int bitmask;
165 	unsigned long flags;
166 
167 	/* set bits are evaluated a gpio register size at a time */
168 	for (i = 0; i < chip->ngpio; i += gpio_reg_size) {
169 		/* no more set bits in this mask word; skip to the next word */
170 		if (!mask[BIT_WORD(i)]) {
171 			i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size;
172 			continue;
173 		}
174 
175 		port = i / gpio_reg_size;
176 
177 		/* mask out GPIO configured for input */
178 		iomask = mask[BIT_WORD(i)] & ~ws16c48gpio->io_state[port];
179 		bitmask = iomask & bits[BIT_WORD(i)];
180 
181 		raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
182 
183 		/* update output state data and set device gpio register */
184 		ws16c48gpio->out_state[port] &= ~iomask;
185 		ws16c48gpio->out_state[port] |= bitmask;
186 		outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
187 
188 		raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
189 
190 		/* prepare for next gpio register set */
191 		mask[BIT_WORD(i)] >>= gpio_reg_size;
192 		bits[BIT_WORD(i)] >>= gpio_reg_size;
193 	}
194 }
195 
196 static void ws16c48_irq_ack(struct irq_data *data)
197 {
198 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
199 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
200 	const unsigned long offset = irqd_to_hwirq(data);
201 	const unsigned port = offset / 8;
202 	const unsigned mask = BIT(offset % 8);
203 	unsigned long flags;
204 	unsigned port_state;
205 
206 	/* only the first 3 ports support interrupts */
207 	if (port > 2)
208 		return;
209 
210 	raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
211 
212 	port_state = ws16c48gpio->irq_mask >> (8*port);
213 
214 	outb(0x80, ws16c48gpio->base + 7);
215 	outb(port_state & ~mask, ws16c48gpio->base + 8 + port);
216 	outb(port_state | mask, ws16c48gpio->base + 8 + port);
217 	outb(0xC0, ws16c48gpio->base + 7);
218 
219 	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
220 }
221 
222 static void ws16c48_irq_mask(struct irq_data *data)
223 {
224 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
225 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
226 	const unsigned long offset = irqd_to_hwirq(data);
227 	const unsigned long mask = BIT(offset);
228 	const unsigned port = offset / 8;
229 	unsigned long flags;
230 
231 	/* only the first 3 ports support interrupts */
232 	if (port > 2)
233 		return;
234 
235 	raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
236 
237 	ws16c48gpio->irq_mask &= ~mask;
238 
239 	outb(0x80, ws16c48gpio->base + 7);
240 	outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
241 	outb(0xC0, ws16c48gpio->base + 7);
242 
243 	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
244 }
245 
246 static void ws16c48_irq_unmask(struct irq_data *data)
247 {
248 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
249 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
250 	const unsigned long offset = irqd_to_hwirq(data);
251 	const unsigned long mask = BIT(offset);
252 	const unsigned port = offset / 8;
253 	unsigned long flags;
254 
255 	/* only the first 3 ports support interrupts */
256 	if (port > 2)
257 		return;
258 
259 	raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
260 
261 	ws16c48gpio->irq_mask |= mask;
262 
263 	outb(0x80, ws16c48gpio->base + 7);
264 	outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
265 	outb(0xC0, ws16c48gpio->base + 7);
266 
267 	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
268 }
269 
270 static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
271 {
272 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
273 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
274 	const unsigned long offset = irqd_to_hwirq(data);
275 	const unsigned long mask = BIT(offset);
276 	const unsigned port = offset / 8;
277 	unsigned long flags;
278 
279 	/* only the first 3 ports support interrupts */
280 	if (port > 2)
281 		return -EINVAL;
282 
283 	raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
284 
285 	switch (flow_type) {
286 	case IRQ_TYPE_NONE:
287 		break;
288 	case IRQ_TYPE_EDGE_RISING:
289 		ws16c48gpio->flow_mask |= mask;
290 		break;
291 	case IRQ_TYPE_EDGE_FALLING:
292 		ws16c48gpio->flow_mask &= ~mask;
293 		break;
294 	default:
295 		raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
296 		return -EINVAL;
297 	}
298 
299 	outb(0x40, ws16c48gpio->base + 7);
300 	outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port);
301 	outb(0xC0, ws16c48gpio->base + 7);
302 
303 	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
304 
305 	return 0;
306 }
307 
308 static struct irq_chip ws16c48_irqchip = {
309 	.name = "ws16c48",
310 	.irq_ack = ws16c48_irq_ack,
311 	.irq_mask = ws16c48_irq_mask,
312 	.irq_unmask = ws16c48_irq_unmask,
313 	.irq_set_type = ws16c48_irq_set_type
314 };
315 
316 static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id)
317 {
318 	struct ws16c48_gpio *const ws16c48gpio = dev_id;
319 	struct gpio_chip *const chip = &ws16c48gpio->chip;
320 	unsigned long int_pending;
321 	unsigned long port;
322 	unsigned long int_id;
323 	unsigned long gpio;
324 
325 	int_pending = inb(ws16c48gpio->base + 6) & 0x7;
326 	if (!int_pending)
327 		return IRQ_NONE;
328 
329 	/* loop until all pending interrupts are handled */
330 	do {
331 		for_each_set_bit(port, &int_pending, 3) {
332 			int_id = inb(ws16c48gpio->base + 8 + port);
333 			for_each_set_bit(gpio, &int_id, 8)
334 				generic_handle_irq(irq_find_mapping(
335 					chip->irq.domain, gpio + 8*port));
336 		}
337 
338 		int_pending = inb(ws16c48gpio->base + 6) & 0x7;
339 	} while (int_pending);
340 
341 	return IRQ_HANDLED;
342 }
343 
344 #define WS16C48_NGPIO 48
345 static const char *ws16c48_names[WS16C48_NGPIO] = {
346 	"Port 0 Bit 0", "Port 0 Bit 1", "Port 0 Bit 2", "Port 0 Bit 3",
347 	"Port 0 Bit 4", "Port 0 Bit 5", "Port 0 Bit 6", "Port 0 Bit 7",
348 	"Port 1 Bit 0", "Port 1 Bit 1", "Port 1 Bit 2", "Port 1 Bit 3",
349 	"Port 1 Bit 4", "Port 1 Bit 5", "Port 1 Bit 6", "Port 1 Bit 7",
350 	"Port 2 Bit 0", "Port 2 Bit 1", "Port 2 Bit 2", "Port 2 Bit 3",
351 	"Port 2 Bit 4", "Port 2 Bit 5", "Port 2 Bit 6", "Port 2 Bit 7",
352 	"Port 3 Bit 0", "Port 3 Bit 1", "Port 3 Bit 2", "Port 3 Bit 3",
353 	"Port 3 Bit 4", "Port 3 Bit 5", "Port 3 Bit 6", "Port 3 Bit 7",
354 	"Port 4 Bit 0", "Port 4 Bit 1", "Port 4 Bit 2", "Port 4 Bit 3",
355 	"Port 4 Bit 4", "Port 4 Bit 5", "Port 4 Bit 6", "Port 4 Bit 7",
356 	"Port 5 Bit 0", "Port 5 Bit 1", "Port 5 Bit 2", "Port 5 Bit 3",
357 	"Port 5 Bit 4", "Port 5 Bit 5", "Port 5 Bit 6", "Port 5 Bit 7"
358 };
359 
360 static int ws16c48_probe(struct device *dev, unsigned int id)
361 {
362 	struct ws16c48_gpio *ws16c48gpio;
363 	const char *const name = dev_name(dev);
364 	int err;
365 
366 	ws16c48gpio = devm_kzalloc(dev, sizeof(*ws16c48gpio), GFP_KERNEL);
367 	if (!ws16c48gpio)
368 		return -ENOMEM;
369 
370 	if (!devm_request_region(dev, base[id], WS16C48_EXTENT, name)) {
371 		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
372 			base[id], base[id] + WS16C48_EXTENT);
373 		return -EBUSY;
374 	}
375 
376 	ws16c48gpio->chip.label = name;
377 	ws16c48gpio->chip.parent = dev;
378 	ws16c48gpio->chip.owner = THIS_MODULE;
379 	ws16c48gpio->chip.base = -1;
380 	ws16c48gpio->chip.ngpio = WS16C48_NGPIO;
381 	ws16c48gpio->chip.names = ws16c48_names;
382 	ws16c48gpio->chip.get_direction = ws16c48_gpio_get_direction;
383 	ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input;
384 	ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output;
385 	ws16c48gpio->chip.get = ws16c48_gpio_get;
386 	ws16c48gpio->chip.set = ws16c48_gpio_set;
387 	ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple;
388 	ws16c48gpio->base = base[id];
389 
390 	raw_spin_lock_init(&ws16c48gpio->lock);
391 
392 	err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio);
393 	if (err) {
394 		dev_err(dev, "GPIO registering failed (%d)\n", err);
395 		return err;
396 	}
397 
398 	/* Disable IRQ by default */
399 	outb(0x80, base[id] + 7);
400 	outb(0, base[id] + 8);
401 	outb(0, base[id] + 9);
402 	outb(0, base[id] + 10);
403 	outb(0xC0, base[id] + 7);
404 
405 	err = gpiochip_irqchip_add(&ws16c48gpio->chip, &ws16c48_irqchip, 0,
406 		handle_edge_irq, IRQ_TYPE_NONE);
407 	if (err) {
408 		dev_err(dev, "Could not add irqchip (%d)\n", err);
409 		return err;
410 	}
411 
412 	err = devm_request_irq(dev, irq[id], ws16c48_irq_handler, IRQF_SHARED,
413 		name, ws16c48gpio);
414 	if (err) {
415 		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
416 		return err;
417 	}
418 
419 	return 0;
420 }
421 
422 static struct isa_driver ws16c48_driver = {
423 	.probe = ws16c48_probe,
424 	.driver = {
425 		.name = "ws16c48"
426 	},
427 };
428 
429 module_isa_driver(ws16c48_driver, num_ws16c48);
430 
431 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
432 MODULE_DESCRIPTION("WinSystems WS16C48 GPIO driver");
433 MODULE_LICENSE("GPL v2");
434