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 	size_t i;
205 	const unsigned int gpio_reg_size = 8;
206 	unsigned int bits_offset;
207 	size_t word_index;
208 	unsigned int word_offset;
209 	unsigned long word_mask;
210 	const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
211 	unsigned long port_state;
212 	void __iomem *ports[] = {
213 		&idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
214 		&idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
215 		&idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
216 	};
217 	const unsigned long out_mode_mask = BIT(1);
218 
219 	/* clear bits array to a clean slate */
220 	bitmap_zero(bits, chip->ngpio);
221 
222 	/* get bits are evaluated a gpio port register at a time */
223 	for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) {
224 		/* gpio offset in bits array */
225 		bits_offset = i * gpio_reg_size;
226 
227 		/* word index for bits array */
228 		word_index = BIT_WORD(bits_offset);
229 
230 		/* gpio offset within current word of bits array */
231 		word_offset = bits_offset % BITS_PER_LONG;
232 
233 		/* mask of get bits for current gpio within current word */
234 		word_mask = mask[word_index] & (port_mask << word_offset);
235 		if (!word_mask) {
236 			/* no get bits in this port so skip to next one */
237 			continue;
238 		}
239 
240 		/* read bits from current gpio port (port 6 is TTL GPIO) */
241 		if (i < 6)
242 			port_state = ioread8(ports[i]);
243 		else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
244 			port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
245 		else
246 			port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
247 
248 		/* store acquired bits at respective bits array offset */
249 		bits[word_index] |= (port_state << word_offset) & word_mask;
250 	}
251 
252 	return 0;
253 }
254 
255 static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
256 	int value)
257 {
258 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
259 	const unsigned long out_mode_mask = BIT(1);
260 	void __iomem *base;
261 	const unsigned int mask = BIT(offset % 8);
262 	unsigned long flags;
263 	unsigned int out_state;
264 
265 	/* Isolated Inputs */
266 	if (offset > 23 && offset < 48)
267 		return;
268 
269 	/* TTL/CMOS Inputs */
270 	if (offset > 47 && !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
271 		return;
272 
273 	/* TTL/CMOS Outputs */
274 	if (offset > 47)
275 		base = &idio24gpio->reg->ttl_out0_7;
276 	/* FET Outputs */
277 	else if (offset > 15)
278 		base = &idio24gpio->reg->out16_23;
279 	else if (offset > 7)
280 		base = &idio24gpio->reg->out8_15;
281 	else
282 		base = &idio24gpio->reg->out0_7;
283 
284 	raw_spin_lock_irqsave(&idio24gpio->lock, flags);
285 
286 	if (value)
287 		out_state = ioread8(base) | mask;
288 	else
289 		out_state = ioread8(base) & ~mask;
290 
291 	iowrite8(out_state, base);
292 
293 	raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
294 }
295 
296 static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
297 	unsigned long *mask, unsigned long *bits)
298 {
299 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
300 	size_t i;
301 	unsigned long bits_offset;
302 	unsigned long gpio_mask;
303 	const unsigned int gpio_reg_size = 8;
304 	const unsigned long port_mask = GENMASK(gpio_reg_size, 0);
305 	unsigned long flags;
306 	unsigned int out_state;
307 	void __iomem *ports[] = {
308 		&idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
309 		&idio24gpio->reg->out16_23
310 	};
311 	const unsigned long out_mode_mask = BIT(1);
312 	const unsigned int ttl_offset = 48;
313 	const size_t ttl_i = BIT_WORD(ttl_offset);
314 	const unsigned int word_offset = ttl_offset % BITS_PER_LONG;
315 	const unsigned long ttl_mask = (mask[ttl_i] >> word_offset) & port_mask;
316 	const unsigned long ttl_bits = (bits[ttl_i] >> word_offset) & ttl_mask;
317 
318 	/* set bits are processed a gpio port register at a time */
319 	for (i = 0; i < ARRAY_SIZE(ports); i++) {
320 		/* gpio offset in bits array */
321 		bits_offset = i * gpio_reg_size;
322 
323 		/* check if any set bits for current port */
324 		gpio_mask = (*mask >> bits_offset) & port_mask;
325 		if (!gpio_mask) {
326 			/* no set bits for this port so move on to next port */
327 			continue;
328 		}
329 
330 		raw_spin_lock_irqsave(&idio24gpio->lock, flags);
331 
332 		/* process output lines */
333 		out_state = ioread8(ports[i]) & ~gpio_mask;
334 		out_state |= (*bits >> bits_offset) & gpio_mask;
335 		iowrite8(out_state, ports[i]);
336 
337 		raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
338 	}
339 
340 	/* check if setting TTL lines and if they are in output mode */
341 	if (!ttl_mask || !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
342 		return;
343 
344 	/* handle TTL output */
345 	raw_spin_lock_irqsave(&idio24gpio->lock, flags);
346 
347 	/* process output lines */
348 	out_state = ioread8(&idio24gpio->reg->ttl_out0_7) & ~ttl_mask;
349 	out_state |= ttl_bits;
350 	iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
351 
352 	raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
353 }
354 
355 static void idio_24_irq_ack(struct irq_data *data)
356 {
357 }
358 
359 static void idio_24_irq_mask(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 	const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
365 	unsigned char new_irq_mask;
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 	idio24gpio->irq_mask &= BIT(bit_offset);
372 	new_irq_mask = idio24gpio->irq_mask >> bank_offset;
373 
374 	if (!new_irq_mask) {
375 		cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
376 
377 		/* Disable Rising Edge detection */
378 		cos_enable_state &= ~BIT(bank_offset);
379 		/* Disable 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 void idio_24_irq_unmask(struct irq_data *data)
389 {
390 	struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
391 	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
392 	unsigned long flags;
393 	unsigned char prev_irq_mask;
394 	const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
395 	const unsigned long bank_offset = bit_offset/8 * 8;
396 	unsigned char cos_enable_state;
397 
398 	raw_spin_lock_irqsave(&idio24gpio->lock, flags);
399 
400 	prev_irq_mask = idio24gpio->irq_mask >> bank_offset;
401 	idio24gpio->irq_mask |= BIT(bit_offset);
402 
403 	if (!prev_irq_mask) {
404 		cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
405 
406 		/* Enable Rising Edge detection */
407 		cos_enable_state |= BIT(bank_offset);
408 		/* Enable Falling Edge detection */
409 		cos_enable_state |= BIT(bank_offset + 4);
410 
411 		iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
412 	}
413 
414 	raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
415 }
416 
417 static int idio_24_irq_set_type(struct irq_data *data, unsigned int flow_type)
418 {
419 	/* The only valid irq types are none and both-edges */
420 	if (flow_type != IRQ_TYPE_NONE &&
421 		(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
422 		return -EINVAL;
423 
424 	return 0;
425 }
426 
427 static struct irq_chip idio_24_irqchip = {
428 	.name = "pcie-idio-24",
429 	.irq_ack = idio_24_irq_ack,
430 	.irq_mask = idio_24_irq_mask,
431 	.irq_unmask = idio_24_irq_unmask,
432 	.irq_set_type = idio_24_irq_set_type
433 };
434 
435 static irqreturn_t idio_24_irq_handler(int irq, void *dev_id)
436 {
437 	struct idio_24_gpio *const idio24gpio = dev_id;
438 	unsigned long irq_status;
439 	struct gpio_chip *const chip = &idio24gpio->chip;
440 	unsigned long irq_mask;
441 	int gpio;
442 
443 	raw_spin_lock(&idio24gpio->lock);
444 
445 	/* Read Change-Of-State status */
446 	irq_status = ioread32(&idio24gpio->reg->cos0_7);
447 
448 	raw_spin_unlock(&idio24gpio->lock);
449 
450 	/* Make sure our device generated IRQ */
451 	if (!irq_status)
452 		return IRQ_NONE;
453 
454 	/* Handle only unmasked IRQ */
455 	irq_mask = idio24gpio->irq_mask & irq_status;
456 
457 	for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24)
458 		generic_handle_irq(irq_find_mapping(chip->irq.domain,
459 			gpio + 24));
460 
461 	raw_spin_lock(&idio24gpio->lock);
462 
463 	/* Clear Change-Of-State status */
464 	iowrite32(irq_status, &idio24gpio->reg->cos0_7);
465 
466 	raw_spin_unlock(&idio24gpio->lock);
467 
468 	return IRQ_HANDLED;
469 }
470 
471 #define IDIO_24_NGPIO 56
472 static const char *idio_24_names[IDIO_24_NGPIO] = {
473 	"OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
474 	"OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
475 	"OUT16", "OUT17", "OUT18", "OUT19", "OUT20", "OUT21", "OUT22", "OUT23",
476 	"IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
477 	"IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15",
478 	"IIN16", "IIN17", "IIN18", "IIN19", "IIN20", "IIN21", "IIN22", "IIN23",
479 	"TTL0", "TTL1", "TTL2", "TTL3", "TTL4", "TTL5", "TTL6", "TTL7"
480 };
481 
482 static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
483 {
484 	struct device *const dev = &pdev->dev;
485 	struct idio_24_gpio *idio24gpio;
486 	int err;
487 	const size_t pci_bar_index = 2;
488 	const char *const name = pci_name(pdev);
489 
490 	idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
491 	if (!idio24gpio)
492 		return -ENOMEM;
493 
494 	err = pcim_enable_device(pdev);
495 	if (err) {
496 		dev_err(dev, "Failed to enable PCI device (%d)\n", err);
497 		return err;
498 	}
499 
500 	err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
501 	if (err) {
502 		dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
503 		return err;
504 	}
505 
506 	idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
507 
508 	idio24gpio->chip.label = name;
509 	idio24gpio->chip.parent = dev;
510 	idio24gpio->chip.owner = THIS_MODULE;
511 	idio24gpio->chip.base = -1;
512 	idio24gpio->chip.ngpio = IDIO_24_NGPIO;
513 	idio24gpio->chip.names = idio_24_names;
514 	idio24gpio->chip.get_direction = idio_24_gpio_get_direction;
515 	idio24gpio->chip.direction_input = idio_24_gpio_direction_input;
516 	idio24gpio->chip.direction_output = idio_24_gpio_direction_output;
517 	idio24gpio->chip.get = idio_24_gpio_get;
518 	idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple;
519 	idio24gpio->chip.set = idio_24_gpio_set;
520 	idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple;
521 
522 	raw_spin_lock_init(&idio24gpio->lock);
523 
524 	/* Software board reset */
525 	iowrite8(0, &idio24gpio->reg->soft_reset);
526 
527 	err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
528 	if (err) {
529 		dev_err(dev, "GPIO registering failed (%d)\n", err);
530 		return err;
531 	}
532 
533 	err = gpiochip_irqchip_add(&idio24gpio->chip, &idio_24_irqchip, 0,
534 		handle_edge_irq, IRQ_TYPE_NONE);
535 	if (err) {
536 		dev_err(dev, "Could not add irqchip (%d)\n", err);
537 		return err;
538 	}
539 
540 	err = devm_request_irq(dev, pdev->irq, idio_24_irq_handler, IRQF_SHARED,
541 		name, idio24gpio);
542 	if (err) {
543 		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
544 		return err;
545 	}
546 
547 	return 0;
548 }
549 
550 static const struct pci_device_id idio_24_pci_dev_id[] = {
551 	{ PCI_DEVICE(0x494F, 0x0FD0) }, { PCI_DEVICE(0x494F, 0x0BD0) },
552 	{ PCI_DEVICE(0x494F, 0x07D0) }, { PCI_DEVICE(0x494F, 0x0FC0) },
553 	{ 0 }
554 };
555 MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id);
556 
557 static struct pci_driver idio_24_driver = {
558 	.name = "pcie-idio-24",
559 	.id_table = idio_24_pci_dev_id,
560 	.probe = idio_24_probe
561 };
562 
563 module_pci_driver(idio_24_driver);
564 
565 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
566 MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver");
567 MODULE_LICENSE("GPL v2");
568