xref: /linux/drivers/gpio/gpio-pcie-idio-24.c (revision 9a6b55ac)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * GPIO driver for the ACCES PCIe-IDIO-24 family
4  * Copyright (C) 2018 William Breathitt Gray
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License, version 2, as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * This driver supports the following ACCES devices: PCIe-IDIO-24,
16  * PCIe-IDI-24, PCIe-IDO-24, and PCIe-IDIO-12.
17  */
18 #include <linux/bitmap.h>
19 #include <linux/bitops.h>
20 #include <linux/device.h>
21 #include <linux/errno.h>
22 #include <linux/gpio/driver.h>
23 #include <linux/interrupt.h>
24 #include <linux/irqdesc.h>
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/pci.h>
28 #include <linux/spinlock.h>
29 #include <linux/types.h>
30 
31 /**
32  * struct idio_24_gpio_reg - GPIO device registers structure
33  * @out0_7:	Read: FET Outputs 0-7
34  *		Write: FET Outputs 0-7
35  * @out8_15:	Read: FET Outputs 8-15
36  *		Write: FET Outputs 8-15
37  * @out16_23:	Read: FET Outputs 16-23
38  *		Write: FET Outputs 16-23
39  * @ttl_out0_7:	Read: TTL/CMOS Outputs 0-7
40  *		Write: TTL/CMOS Outputs 0-7
41  * @in0_7:	Read: Isolated Inputs 0-7
42  *		Write: Reserved
43  * @in8_15:	Read: Isolated Inputs 8-15
44  *		Write: Reserved
45  * @in16_23:	Read: Isolated Inputs 16-23
46  *		Write: Reserved
47  * @ttl_in0_7:	Read: TTL/CMOS Inputs 0-7
48  *		Write: Reserved
49  * @cos0_7:	Read: COS Status Inputs 0-7
50  *		Write: COS Clear Inputs 0-7
51  * @cos8_15:	Read: COS Status Inputs 8-15
52  *		Write: COS Clear Inputs 8-15
53  * @cos16_23:	Read: COS Status Inputs 16-23
54  *		Write: COS Clear Inputs 16-23
55  * @cos_ttl0_7:	Read: COS Status TTL/CMOS 0-7
56  *		Write: COS Clear TTL/CMOS 0-7
57  * @ctl:	Read: Control Register
58  *		Write: Control Register
59  * @reserved:	Read: Reserved
60  *		Write: Reserved
61  * @cos_enable:	Read: COS Enable
62  *		Write: COS Enable
63  * @soft_reset:	Read: IRQ Output Pin Status
64  *		Write: Software Board Reset
65  */
66 struct idio_24_gpio_reg {
67 	u8 out0_7;
68 	u8 out8_15;
69 	u8 out16_23;
70 	u8 ttl_out0_7;
71 	u8 in0_7;
72 	u8 in8_15;
73 	u8 in16_23;
74 	u8 ttl_in0_7;
75 	u8 cos0_7;
76 	u8 cos8_15;
77 	u8 cos16_23;
78 	u8 cos_ttl0_7;
79 	u8 ctl;
80 	u8 reserved;
81 	u8 cos_enable;
82 	u8 soft_reset;
83 };
84 
85 /**
86  * struct idio_24_gpio - GPIO device private data structure
87  * @chip:	instance of the gpio_chip
88  * @lock:	synchronization lock to prevent I/O race conditions
89  * @reg:	I/O address offset for the GPIO device registers
90  * @irq_mask:	I/O bits affected by interrupts
91  */
92 struct idio_24_gpio {
93 	struct gpio_chip chip;
94 	raw_spinlock_t lock;
95 	struct idio_24_gpio_reg __iomem *reg;
96 	unsigned long irq_mask;
97 };
98 
99 static int idio_24_gpio_get_direction(struct gpio_chip *chip,
100 	unsigned int offset)
101 {
102 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
103 	const unsigned long out_mode_mask = BIT(1);
104 
105 	/* FET Outputs */
106 	if (offset < 24)
107 		return GPIO_LINE_DIRECTION_OUT;
108 
109 	/* Isolated Inputs */
110 	if (offset < 48)
111 		return GPIO_LINE_DIRECTION_IN;
112 
113 	/* TTL/CMOS I/O */
114 	/* OUT MODE = 1 when TTL/CMOS Output Mode is set */
115 	if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
116 		return GPIO_LINE_DIRECTION_OUT;
117 
118 	return GPIO_LINE_DIRECTION_IN;
119 }
120 
121 static int idio_24_gpio_direction_input(struct gpio_chip *chip,
122 	unsigned int offset)
123 {
124 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
125 	unsigned long flags;
126 	unsigned int ctl_state;
127 	const unsigned long out_mode_mask = BIT(1);
128 
129 	/* TTL/CMOS I/O */
130 	if (offset > 47) {
131 		raw_spin_lock_irqsave(&idio24gpio->lock, flags);
132 
133 		/* Clear TTL/CMOS Output Mode */
134 		ctl_state = ioread8(&idio24gpio->reg->ctl) & ~out_mode_mask;
135 		iowrite8(ctl_state, &idio24gpio->reg->ctl);
136 
137 		raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
138 	}
139 
140 	return 0;
141 }
142 
143 static int idio_24_gpio_direction_output(struct gpio_chip *chip,
144 	unsigned int offset, int value)
145 {
146 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
147 	unsigned long flags;
148 	unsigned int ctl_state;
149 	const unsigned long out_mode_mask = BIT(1);
150 
151 	/* TTL/CMOS I/O */
152 	if (offset > 47) {
153 		raw_spin_lock_irqsave(&idio24gpio->lock, flags);
154 
155 		/* Set TTL/CMOS Output Mode */
156 		ctl_state = ioread8(&idio24gpio->reg->ctl) | out_mode_mask;
157 		iowrite8(ctl_state, &idio24gpio->reg->ctl);
158 
159 		raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
160 	}
161 
162 	chip->set(chip, offset, value);
163 	return 0;
164 }
165 
166 static int idio_24_gpio_get(struct gpio_chip *chip, unsigned int offset)
167 {
168 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
169 	const unsigned long offset_mask = BIT(offset % 8);
170 	const unsigned long out_mode_mask = BIT(1);
171 
172 	/* FET Outputs */
173 	if (offset < 8)
174 		return !!(ioread8(&idio24gpio->reg->out0_7) & offset_mask);
175 
176 	if (offset < 16)
177 		return !!(ioread8(&idio24gpio->reg->out8_15) & offset_mask);
178 
179 	if (offset < 24)
180 		return !!(ioread8(&idio24gpio->reg->out16_23) & offset_mask);
181 
182 	/* Isolated Inputs */
183 	if (offset < 32)
184 		return !!(ioread8(&idio24gpio->reg->in0_7) & offset_mask);
185 
186 	if (offset < 40)
187 		return !!(ioread8(&idio24gpio->reg->in8_15) & offset_mask);
188 
189 	if (offset < 48)
190 		return !!(ioread8(&idio24gpio->reg->in16_23) & offset_mask);
191 
192 	/* TTL/CMOS Outputs */
193 	if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
194 		return !!(ioread8(&idio24gpio->reg->ttl_out0_7) & offset_mask);
195 
196 	/* TTL/CMOS Inputs */
197 	return !!(ioread8(&idio24gpio->reg->ttl_in0_7) & offset_mask);
198 }
199 
200 static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
201 	unsigned long *mask, unsigned long *bits)
202 {
203 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
204 	unsigned long offset;
205 	unsigned long gpio_mask;
206 	void __iomem *ports[] = {
207 		&idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
208 		&idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
209 		&idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
210 	};
211 	size_t index;
212 	unsigned long port_state;
213 	const unsigned long out_mode_mask = BIT(1);
214 
215 	/* clear bits array to a clean slate */
216 	bitmap_zero(bits, chip->ngpio);
217 
218 	for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
219 		index = offset / 8;
220 
221 		/* read bits from current gpio port (port 6 is TTL GPIO) */
222 		if (index < 6)
223 			port_state = ioread8(ports[index]);
224 		else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
225 			port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
226 		else
227 			port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
228 
229 		port_state &= gpio_mask;
230 
231 		bitmap_set_value8(bits, port_state, offset);
232 	}
233 
234 	return 0;
235 }
236 
237 static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
238 	int value)
239 {
240 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
241 	const unsigned long out_mode_mask = BIT(1);
242 	void __iomem *base;
243 	const unsigned int mask = BIT(offset % 8);
244 	unsigned long flags;
245 	unsigned int out_state;
246 
247 	/* Isolated Inputs */
248 	if (offset > 23 && offset < 48)
249 		return;
250 
251 	/* TTL/CMOS Inputs */
252 	if (offset > 47 && !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
253 		return;
254 
255 	/* TTL/CMOS Outputs */
256 	if (offset > 47)
257 		base = &idio24gpio->reg->ttl_out0_7;
258 	/* FET Outputs */
259 	else if (offset > 15)
260 		base = &idio24gpio->reg->out16_23;
261 	else if (offset > 7)
262 		base = &idio24gpio->reg->out8_15;
263 	else
264 		base = &idio24gpio->reg->out0_7;
265 
266 	raw_spin_lock_irqsave(&idio24gpio->lock, flags);
267 
268 	if (value)
269 		out_state = ioread8(base) | mask;
270 	else
271 		out_state = ioread8(base) & ~mask;
272 
273 	iowrite8(out_state, base);
274 
275 	raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
276 }
277 
278 static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
279 	unsigned long *mask, unsigned long *bits)
280 {
281 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
282 	unsigned long offset;
283 	unsigned long gpio_mask;
284 	void __iomem *ports[] = {
285 		&idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
286 		&idio24gpio->reg->out16_23
287 	};
288 	size_t index;
289 	unsigned long bitmask;
290 	unsigned long flags;
291 	unsigned long out_state;
292 	const unsigned long out_mode_mask = BIT(1);
293 
294 	for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
295 		index = offset / 8;
296 
297 		bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
298 
299 		raw_spin_lock_irqsave(&idio24gpio->lock, flags);
300 
301 		/* read bits from current gpio port (port 6 is TTL GPIO) */
302 		if (index < 6) {
303 			out_state = ioread8(ports[index]);
304 		} else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) {
305 			out_state = ioread8(&idio24gpio->reg->ttl_out0_7);
306 		} else {
307 			/* skip TTL GPIO if set for input */
308 			raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
309 			continue;
310 		}
311 
312 		/* set requested bit states */
313 		out_state &= ~gpio_mask;
314 		out_state |= bitmask;
315 
316 		/* write bits for current gpio port (port 6 is TTL GPIO) */
317 		if (index < 6)
318 			iowrite8(out_state, ports[index]);
319 		else
320 			iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
321 
322 		raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
323 	}
324 }
325 
326 static void idio_24_irq_ack(struct irq_data *data)
327 {
328 }
329 
330 static void idio_24_irq_mask(struct irq_data *data)
331 {
332 	struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
333 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
334 	unsigned long flags;
335 	const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
336 	unsigned char new_irq_mask;
337 	const unsigned long bank_offset = bit_offset/8 * 8;
338 	unsigned char cos_enable_state;
339 
340 	raw_spin_lock_irqsave(&idio24gpio->lock, flags);
341 
342 	idio24gpio->irq_mask &= BIT(bit_offset);
343 	new_irq_mask = idio24gpio->irq_mask >> bank_offset;
344 
345 	if (!new_irq_mask) {
346 		cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
347 
348 		/* Disable Rising Edge detection */
349 		cos_enable_state &= ~BIT(bank_offset);
350 		/* Disable Falling Edge detection */
351 		cos_enable_state &= ~BIT(bank_offset + 4);
352 
353 		iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
354 	}
355 
356 	raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
357 }
358 
359 static void idio_24_irq_unmask(struct irq_data *data)
360 {
361 	struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
362 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
363 	unsigned long flags;
364 	unsigned char prev_irq_mask;
365 	const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
366 	const unsigned long bank_offset = bit_offset/8 * 8;
367 	unsigned char cos_enable_state;
368 
369 	raw_spin_lock_irqsave(&idio24gpio->lock, flags);
370 
371 	prev_irq_mask = idio24gpio->irq_mask >> bank_offset;
372 	idio24gpio->irq_mask |= BIT(bit_offset);
373 
374 	if (!prev_irq_mask) {
375 		cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
376 
377 		/* Enable Rising Edge detection */
378 		cos_enable_state |= BIT(bank_offset);
379 		/* Enable Falling Edge detection */
380 		cos_enable_state |= BIT(bank_offset + 4);
381 
382 		iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
383 	}
384 
385 	raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
386 }
387 
388 static int idio_24_irq_set_type(struct irq_data *data, unsigned int flow_type)
389 {
390 	/* The only valid irq types are none and both-edges */
391 	if (flow_type != IRQ_TYPE_NONE &&
392 		(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
393 		return -EINVAL;
394 
395 	return 0;
396 }
397 
398 static struct irq_chip idio_24_irqchip = {
399 	.name = "pcie-idio-24",
400 	.irq_ack = idio_24_irq_ack,
401 	.irq_mask = idio_24_irq_mask,
402 	.irq_unmask = idio_24_irq_unmask,
403 	.irq_set_type = idio_24_irq_set_type
404 };
405 
406 static irqreturn_t idio_24_irq_handler(int irq, void *dev_id)
407 {
408 	struct idio_24_gpio *const idio24gpio = dev_id;
409 	unsigned long irq_status;
410 	struct gpio_chip *const chip = &idio24gpio->chip;
411 	unsigned long irq_mask;
412 	int gpio;
413 
414 	raw_spin_lock(&idio24gpio->lock);
415 
416 	/* Read Change-Of-State status */
417 	irq_status = ioread32(&idio24gpio->reg->cos0_7);
418 
419 	raw_spin_unlock(&idio24gpio->lock);
420 
421 	/* Make sure our device generated IRQ */
422 	if (!irq_status)
423 		return IRQ_NONE;
424 
425 	/* Handle only unmasked IRQ */
426 	irq_mask = idio24gpio->irq_mask & irq_status;
427 
428 	for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24)
429 		generic_handle_irq(irq_find_mapping(chip->irq.domain,
430 			gpio + 24));
431 
432 	raw_spin_lock(&idio24gpio->lock);
433 
434 	/* Clear Change-Of-State status */
435 	iowrite32(irq_status, &idio24gpio->reg->cos0_7);
436 
437 	raw_spin_unlock(&idio24gpio->lock);
438 
439 	return IRQ_HANDLED;
440 }
441 
442 #define IDIO_24_NGPIO 56
443 static const char *idio_24_names[IDIO_24_NGPIO] = {
444 	"OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
445 	"OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
446 	"OUT16", "OUT17", "OUT18", "OUT19", "OUT20", "OUT21", "OUT22", "OUT23",
447 	"IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
448 	"IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15",
449 	"IIN16", "IIN17", "IIN18", "IIN19", "IIN20", "IIN21", "IIN22", "IIN23",
450 	"TTL0", "TTL1", "TTL2", "TTL3", "TTL4", "TTL5", "TTL6", "TTL7"
451 };
452 
453 static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
454 {
455 	struct device *const dev = &pdev->dev;
456 	struct idio_24_gpio *idio24gpio;
457 	int err;
458 	const size_t pci_bar_index = 2;
459 	const char *const name = pci_name(pdev);
460 
461 	idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
462 	if (!idio24gpio)
463 		return -ENOMEM;
464 
465 	err = pcim_enable_device(pdev);
466 	if (err) {
467 		dev_err(dev, "Failed to enable PCI device (%d)\n", err);
468 		return err;
469 	}
470 
471 	err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
472 	if (err) {
473 		dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
474 		return err;
475 	}
476 
477 	idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
478 
479 	idio24gpio->chip.label = name;
480 	idio24gpio->chip.parent = dev;
481 	idio24gpio->chip.owner = THIS_MODULE;
482 	idio24gpio->chip.base = -1;
483 	idio24gpio->chip.ngpio = IDIO_24_NGPIO;
484 	idio24gpio->chip.names = idio_24_names;
485 	idio24gpio->chip.get_direction = idio_24_gpio_get_direction;
486 	idio24gpio->chip.direction_input = idio_24_gpio_direction_input;
487 	idio24gpio->chip.direction_output = idio_24_gpio_direction_output;
488 	idio24gpio->chip.get = idio_24_gpio_get;
489 	idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple;
490 	idio24gpio->chip.set = idio_24_gpio_set;
491 	idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple;
492 
493 	raw_spin_lock_init(&idio24gpio->lock);
494 
495 	/* Software board reset */
496 	iowrite8(0, &idio24gpio->reg->soft_reset);
497 
498 	err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
499 	if (err) {
500 		dev_err(dev, "GPIO registering failed (%d)\n", err);
501 		return err;
502 	}
503 
504 	err = gpiochip_irqchip_add(&idio24gpio->chip, &idio_24_irqchip, 0,
505 		handle_edge_irq, IRQ_TYPE_NONE);
506 	if (err) {
507 		dev_err(dev, "Could not add irqchip (%d)\n", err);
508 		return err;
509 	}
510 
511 	err = devm_request_irq(dev, pdev->irq, idio_24_irq_handler, IRQF_SHARED,
512 		name, idio24gpio);
513 	if (err) {
514 		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
515 		return err;
516 	}
517 
518 	return 0;
519 }
520 
521 static const struct pci_device_id idio_24_pci_dev_id[] = {
522 	{ PCI_DEVICE(0x494F, 0x0FD0) }, { PCI_DEVICE(0x494F, 0x0BD0) },
523 	{ PCI_DEVICE(0x494F, 0x07D0) }, { PCI_DEVICE(0x494F, 0x0FC0) },
524 	{ 0 }
525 };
526 MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id);
527 
528 static struct pci_driver idio_24_driver = {
529 	.name = "pcie-idio-24",
530 	.id_table = idio_24_pci_dev_id,
531 	.probe = idio_24_probe
532 };
533 
534 module_pci_driver(idio_24_driver);
535 
536 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
537 MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver");
538 MODULE_LICENSE("GPL v2");
539