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_array(base, uint, &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_array(irq, uint, 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 	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 				spin_lock_irqsave(&idi48gpio->lock, flags);
116 
117 				outb(idi48gpio->cos_enb, idi48gpio->base + 7);
118 
119 				spin_unlock_irqrestore(&idi48gpio->lock, flags);
120 			}
121 
122 			return;
123 		}
124 }
125 
126 static void idi_48_irq_unmask(struct irq_data *data)
127 {
128 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
129 	struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
130 	const unsigned offset = irqd_to_hwirq(data);
131 	unsigned i;
132 	unsigned mask;
133 	unsigned boundary;
134 	unsigned prev_irq_mask;
135 	unsigned long flags;
136 
137 	for (i = 0; i < 48; i += 8)
138 		if (offset < i + 8) {
139 			mask = BIT(offset - i);
140 			boundary = i / 8;
141 			prev_irq_mask = idi48gpio->irq_mask[boundary];
142 
143 			idi48gpio->irq_mask[boundary] |= mask;
144 
145 			if (!prev_irq_mask) {
146 				idi48gpio->cos_enb |= BIT(boundary);
147 
148 				spin_lock_irqsave(&idi48gpio->lock, flags);
149 
150 				outb(idi48gpio->cos_enb, idi48gpio->base + 7);
151 
152 				spin_unlock_irqrestore(&idi48gpio->lock, flags);
153 			}
154 
155 			return;
156 		}
157 }
158 
159 static int idi_48_irq_set_type(struct irq_data *data, unsigned flow_type)
160 {
161 	/* The only valid irq types are none and both-edges */
162 	if (flow_type != IRQ_TYPE_NONE &&
163 		(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
164 		return -EINVAL;
165 
166 	return 0;
167 }
168 
169 static struct irq_chip idi_48_irqchip = {
170 	.name = "104-idi-48",
171 	.irq_ack = idi_48_irq_ack,
172 	.irq_mask = idi_48_irq_mask,
173 	.irq_unmask = idi_48_irq_unmask,
174 	.irq_set_type = idi_48_irq_set_type
175 };
176 
177 static irqreturn_t idi_48_irq_handler(int irq, void *dev_id)
178 {
179 	struct idi_48_gpio *const idi48gpio = dev_id;
180 	unsigned long cos_status;
181 	unsigned long boundary;
182 	unsigned long irq_mask;
183 	unsigned long bit_num;
184 	unsigned long gpio;
185 	struct gpio_chip *const chip = &idi48gpio->chip;
186 
187 	spin_lock(&idi48gpio->ack_lock);
188 
189 	spin_lock(&idi48gpio->lock);
190 
191 	cos_status = inb(idi48gpio->base + 7);
192 
193 	spin_unlock(&idi48gpio->lock);
194 
195 	/* IRQ Status (bit 6) is active low (0 = IRQ generated by device) */
196 	if (cos_status & BIT(6)) {
197 		spin_unlock(&idi48gpio->ack_lock);
198 		return IRQ_NONE;
199 	}
200 
201 	/* Bit 0-5 indicate which Change-Of-State boundary triggered the IRQ */
202 	cos_status &= 0x3F;
203 
204 	for_each_set_bit(boundary, &cos_status, 6) {
205 		irq_mask = idi48gpio->irq_mask[boundary];
206 
207 		for_each_set_bit(bit_num, &irq_mask, 8) {
208 			gpio = bit_num + boundary * 8;
209 
210 			generic_handle_irq(irq_find_mapping(chip->irqdomain,
211 				gpio));
212 		}
213 	}
214 
215 	spin_unlock(&idi48gpio->ack_lock);
216 
217 	return IRQ_HANDLED;
218 }
219 
220 #define IDI48_NGPIO 48
221 static const char *idi48_names[IDI48_NGPIO] = {
222 	"Bit 0 A", "Bit 1 A", "Bit 2 A", "Bit 3 A", "Bit 4 A", "Bit 5 A",
223 	"Bit 6 A", "Bit 7 A", "Bit 8 A", "Bit 9 A", "Bit 10 A", "Bit 11 A",
224 	"Bit 12 A", "Bit 13 A", "Bit 14 A", "Bit 15 A",	"Bit 16 A", "Bit 17 A",
225 	"Bit 18 A", "Bit 19 A", "Bit 20 A", "Bit 21 A", "Bit 22 A", "Bit 23 A",
226 	"Bit 0 B", "Bit 1 B", "Bit 2 B", "Bit 3 B", "Bit 4 B", "Bit 5 B",
227 	"Bit 6 B", "Bit 7 B", "Bit 8 B", "Bit 9 B", "Bit 10 B", "Bit 11 B",
228 	"Bit 12 B", "Bit 13 B", "Bit 14 B", "Bit 15 B",	"Bit 16 B", "Bit 17 B",
229 	"Bit 18 B", "Bit 19 B", "Bit 20 B", "Bit 21 B", "Bit 22 B", "Bit 23 B"
230 };
231 
232 static int idi_48_probe(struct device *dev, unsigned int id)
233 {
234 	struct idi_48_gpio *idi48gpio;
235 	const char *const name = dev_name(dev);
236 	int err;
237 
238 	idi48gpio = devm_kzalloc(dev, sizeof(*idi48gpio), GFP_KERNEL);
239 	if (!idi48gpio)
240 		return -ENOMEM;
241 
242 	if (!devm_request_region(dev, base[id], IDI_48_EXTENT, name)) {
243 		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
244 			base[id], base[id] + IDI_48_EXTENT);
245 		return -EBUSY;
246 	}
247 
248 	idi48gpio->chip.label = name;
249 	idi48gpio->chip.parent = dev;
250 	idi48gpio->chip.owner = THIS_MODULE;
251 	idi48gpio->chip.base = -1;
252 	idi48gpio->chip.ngpio = IDI48_NGPIO;
253 	idi48gpio->chip.names = idi48_names;
254 	idi48gpio->chip.get_direction = idi_48_gpio_get_direction;
255 	idi48gpio->chip.direction_input = idi_48_gpio_direction_input;
256 	idi48gpio->chip.get = idi_48_gpio_get;
257 	idi48gpio->base = base[id];
258 
259 	spin_lock_init(&idi48gpio->lock);
260 	spin_lock_init(&idi48gpio->ack_lock);
261 
262 	err = devm_gpiochip_add_data(dev, &idi48gpio->chip, idi48gpio);
263 	if (err) {
264 		dev_err(dev, "GPIO registering failed (%d)\n", err);
265 		return err;
266 	}
267 
268 	/* Disable IRQ by default */
269 	outb(0, base[id] + 7);
270 	inb(base[id] + 7);
271 
272 	err = gpiochip_irqchip_add(&idi48gpio->chip, &idi_48_irqchip, 0,
273 		handle_edge_irq, IRQ_TYPE_NONE);
274 	if (err) {
275 		dev_err(dev, "Could not add irqchip (%d)\n", err);
276 		return err;
277 	}
278 
279 	err = devm_request_irq(dev, irq[id], idi_48_irq_handler, IRQF_SHARED,
280 		name, idi48gpio);
281 	if (err) {
282 		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
283 		return err;
284 	}
285 
286 	return 0;
287 }
288 
289 static struct isa_driver idi_48_driver = {
290 	.probe = idi_48_probe,
291 	.driver = {
292 		.name = "104-idi-48"
293 	},
294 };
295 module_isa_driver(idi_48_driver, num_idi_48);
296 
297 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
298 MODULE_DESCRIPTION("ACCES 104-IDI-48 GPIO driver");
299 MODULE_LICENSE("GPL v2");
300