1 /*
2  * GPIO driver for the ACCES 104-IDI-48 family
3  * Copyright (C) 2015 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  * This driver supports the following ACCES devices: 104-IDI-48A,
15  * 104-IDI-48AC, 104-IDI-48B, and 104-IDI-48BC.
16  */
17 #include <linux/bitops.h>
18 #include <linux/device.h>
19 #include <linux/errno.h>
20 #include <linux/gpio/driver.h>
21 #include <linux/io.h>
22 #include <linux/ioport.h>
23 #include <linux/interrupt.h>
24 #include <linux/irqdesc.h>
25 #include <linux/isa.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/spinlock.h>
30 
31 #define IDI_48_EXTENT 8
32 #define MAX_NUM_IDI_48 max_num_isa_dev(IDI_48_EXTENT)
33 
34 static unsigned int base[MAX_NUM_IDI_48];
35 static unsigned int num_idi_48;
36 module_param_hw_array(base, uint, ioport, &num_idi_48, 0);
37 MODULE_PARM_DESC(base, "ACCES 104-IDI-48 base addresses");
38 
39 static unsigned int irq[MAX_NUM_IDI_48];
40 module_param_hw_array(irq, uint, irq, NULL, 0);
41 MODULE_PARM_DESC(irq, "ACCES 104-IDI-48 interrupt line numbers");
42 
43 /**
44  * struct idi_48_gpio - GPIO device private data structure
45  * @chip:	instance of the gpio_chip
46  * @lock:	synchronization lock to prevent I/O race conditions
47  * @ack_lock:	synchronization lock to prevent IRQ handler race conditions
48  * @irq_mask:	input bits affected by interrupts
49  * @base:	base port address of the GPIO device
50  * @cos_enb:	Change-Of-State IRQ enable boundaries mask
51  */
52 struct idi_48_gpio {
53 	struct gpio_chip chip;
54 	raw_spinlock_t lock;
55 	spinlock_t ack_lock;
56 	unsigned char irq_mask[6];
57 	unsigned base;
58 	unsigned char cos_enb;
59 };
60 
61 static int idi_48_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
62 {
63 	return 1;
64 }
65 
66 static int idi_48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
67 {
68 	return 0;
69 }
70 
71 static int idi_48_gpio_get(struct gpio_chip *chip, unsigned offset)
72 {
73 	struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
74 	unsigned i;
75 	const unsigned register_offset[6] = { 0, 1, 2, 4, 5, 6 };
76 	unsigned base_offset;
77 	unsigned mask;
78 
79 	for (i = 0; i < 48; i += 8)
80 		if (offset < i + 8) {
81 			base_offset = register_offset[i / 8];
82 			mask = BIT(offset - i);
83 
84 			return !!(inb(idi48gpio->base + base_offset) & mask);
85 		}
86 
87 	/* The following line should never execute since offset < 48 */
88 	return 0;
89 }
90 
91 static void idi_48_irq_ack(struct irq_data *data)
92 {
93 }
94 
95 static void idi_48_irq_mask(struct irq_data *data)
96 {
97 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
98 	struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
99 	const unsigned offset = irqd_to_hwirq(data);
100 	unsigned i;
101 	unsigned mask;
102 	unsigned boundary;
103 	unsigned long flags;
104 
105 	for (i = 0; i < 48; i += 8)
106 		if (offset < i + 8) {
107 			mask = BIT(offset - i);
108 			boundary = i / 8;
109 
110 			idi48gpio->irq_mask[boundary] &= ~mask;
111 
112 			if (!idi48gpio->irq_mask[boundary]) {
113 				idi48gpio->cos_enb &= ~BIT(boundary);
114 
115 				raw_spin_lock_irqsave(&idi48gpio->lock, flags);
116 
117 				outb(idi48gpio->cos_enb, idi48gpio->base + 7);
118 
119 				raw_spin_unlock_irqrestore(&idi48gpio->lock,
120 						           flags);
121 			}
122 
123 			return;
124 		}
125 }
126 
127 static void idi_48_irq_unmask(struct irq_data *data)
128 {
129 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
130 	struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
131 	const unsigned offset = irqd_to_hwirq(data);
132 	unsigned i;
133 	unsigned mask;
134 	unsigned boundary;
135 	unsigned prev_irq_mask;
136 	unsigned long flags;
137 
138 	for (i = 0; i < 48; i += 8)
139 		if (offset < i + 8) {
140 			mask = BIT(offset - i);
141 			boundary = i / 8;
142 			prev_irq_mask = idi48gpio->irq_mask[boundary];
143 
144 			idi48gpio->irq_mask[boundary] |= mask;
145 
146 			if (!prev_irq_mask) {
147 				idi48gpio->cos_enb |= BIT(boundary);
148 
149 				raw_spin_lock_irqsave(&idi48gpio->lock, flags);
150 
151 				outb(idi48gpio->cos_enb, idi48gpio->base + 7);
152 
153 				raw_spin_unlock_irqrestore(&idi48gpio->lock,
154 						           flags);
155 			}
156 
157 			return;
158 		}
159 }
160 
161 static int idi_48_irq_set_type(struct irq_data *data, unsigned flow_type)
162 {
163 	/* The only valid irq types are none and both-edges */
164 	if (flow_type != IRQ_TYPE_NONE &&
165 		(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
166 		return -EINVAL;
167 
168 	return 0;
169 }
170 
171 static struct irq_chip idi_48_irqchip = {
172 	.name = "104-idi-48",
173 	.irq_ack = idi_48_irq_ack,
174 	.irq_mask = idi_48_irq_mask,
175 	.irq_unmask = idi_48_irq_unmask,
176 	.irq_set_type = idi_48_irq_set_type
177 };
178 
179 static irqreturn_t idi_48_irq_handler(int irq, void *dev_id)
180 {
181 	struct idi_48_gpio *const idi48gpio = dev_id;
182 	unsigned long cos_status;
183 	unsigned long boundary;
184 	unsigned long irq_mask;
185 	unsigned long bit_num;
186 	unsigned long gpio;
187 	struct gpio_chip *const chip = &idi48gpio->chip;
188 
189 	spin_lock(&idi48gpio->ack_lock);
190 
191 	raw_spin_lock(&idi48gpio->lock);
192 
193 	cos_status = inb(idi48gpio->base + 7);
194 
195 	raw_spin_unlock(&idi48gpio->lock);
196 
197 	/* IRQ Status (bit 6) is active low (0 = IRQ generated by device) */
198 	if (cos_status & BIT(6)) {
199 		spin_unlock(&idi48gpio->ack_lock);
200 		return IRQ_NONE;
201 	}
202 
203 	/* Bit 0-5 indicate which Change-Of-State boundary triggered the IRQ */
204 	cos_status &= 0x3F;
205 
206 	for_each_set_bit(boundary, &cos_status, 6) {
207 		irq_mask = idi48gpio->irq_mask[boundary];
208 
209 		for_each_set_bit(bit_num, &irq_mask, 8) {
210 			gpio = bit_num + boundary * 8;
211 
212 			generic_handle_irq(irq_find_mapping(chip->irqdomain,
213 				gpio));
214 		}
215 	}
216 
217 	spin_unlock(&idi48gpio->ack_lock);
218 
219 	return IRQ_HANDLED;
220 }
221 
222 #define IDI48_NGPIO 48
223 static const char *idi48_names[IDI48_NGPIO] = {
224 	"Bit 0 A", "Bit 1 A", "Bit 2 A", "Bit 3 A", "Bit 4 A", "Bit 5 A",
225 	"Bit 6 A", "Bit 7 A", "Bit 8 A", "Bit 9 A", "Bit 10 A", "Bit 11 A",
226 	"Bit 12 A", "Bit 13 A", "Bit 14 A", "Bit 15 A",	"Bit 16 A", "Bit 17 A",
227 	"Bit 18 A", "Bit 19 A", "Bit 20 A", "Bit 21 A", "Bit 22 A", "Bit 23 A",
228 	"Bit 0 B", "Bit 1 B", "Bit 2 B", "Bit 3 B", "Bit 4 B", "Bit 5 B",
229 	"Bit 6 B", "Bit 7 B", "Bit 8 B", "Bit 9 B", "Bit 10 B", "Bit 11 B",
230 	"Bit 12 B", "Bit 13 B", "Bit 14 B", "Bit 15 B",	"Bit 16 B", "Bit 17 B",
231 	"Bit 18 B", "Bit 19 B", "Bit 20 B", "Bit 21 B", "Bit 22 B", "Bit 23 B"
232 };
233 
234 static int idi_48_probe(struct device *dev, unsigned int id)
235 {
236 	struct idi_48_gpio *idi48gpio;
237 	const char *const name = dev_name(dev);
238 	int err;
239 
240 	idi48gpio = devm_kzalloc(dev, sizeof(*idi48gpio), GFP_KERNEL);
241 	if (!idi48gpio)
242 		return -ENOMEM;
243 
244 	if (!devm_request_region(dev, base[id], IDI_48_EXTENT, name)) {
245 		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
246 			base[id], base[id] + IDI_48_EXTENT);
247 		return -EBUSY;
248 	}
249 
250 	idi48gpio->chip.label = name;
251 	idi48gpio->chip.parent = dev;
252 	idi48gpio->chip.owner = THIS_MODULE;
253 	idi48gpio->chip.base = -1;
254 	idi48gpio->chip.ngpio = IDI48_NGPIO;
255 	idi48gpio->chip.names = idi48_names;
256 	idi48gpio->chip.get_direction = idi_48_gpio_get_direction;
257 	idi48gpio->chip.direction_input = idi_48_gpio_direction_input;
258 	idi48gpio->chip.get = idi_48_gpio_get;
259 	idi48gpio->base = base[id];
260 
261 	raw_spin_lock_init(&idi48gpio->lock);
262 	spin_lock_init(&idi48gpio->ack_lock);
263 
264 	err = devm_gpiochip_add_data(dev, &idi48gpio->chip, idi48gpio);
265 	if (err) {
266 		dev_err(dev, "GPIO registering failed (%d)\n", err);
267 		return err;
268 	}
269 
270 	/* Disable IRQ by default */
271 	outb(0, base[id] + 7);
272 	inb(base[id] + 7);
273 
274 	err = gpiochip_irqchip_add(&idi48gpio->chip, &idi_48_irqchip, 0,
275 		handle_edge_irq, IRQ_TYPE_NONE);
276 	if (err) {
277 		dev_err(dev, "Could not add irqchip (%d)\n", err);
278 		return err;
279 	}
280 
281 	err = devm_request_irq(dev, irq[id], idi_48_irq_handler, IRQF_SHARED,
282 		name, idi48gpio);
283 	if (err) {
284 		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
285 		return err;
286 	}
287 
288 	return 0;
289 }
290 
291 static struct isa_driver idi_48_driver = {
292 	.probe = idi_48_probe,
293 	.driver = {
294 		.name = "104-idi-48"
295 	},
296 };
297 module_isa_driver(idi_48_driver, num_idi_48);
298 
299 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
300 MODULE_DESCRIPTION("ACCES 104-IDI-48 GPIO driver");
301 MODULE_LICENSE("GPL v2");
302