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