This source file includes following definitions.
- idio_24_gpio_get_direction
- idio_24_gpio_direction_input
- idio_24_gpio_direction_output
- idio_24_gpio_get
- idio_24_gpio_get_multiple
- idio_24_gpio_set
- idio_24_gpio_set_multiple
- idio_24_irq_ack
- idio_24_irq_mask
- idio_24_irq_unmask
- idio_24_irq_set_type
- idio_24_irq_handler
- idio_24_probe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
87
88
89
90
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
106 if (offset < 24)
107 return 0;
108
109
110 if (offset < 48)
111 return 1;
112
113
114
115 return !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask);
116 }
117
118 static int idio_24_gpio_direction_input(struct gpio_chip *chip,
119 unsigned int offset)
120 {
121 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
122 unsigned long flags;
123 unsigned int ctl_state;
124 const unsigned long out_mode_mask = BIT(1);
125
126
127 if (offset > 47) {
128 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
129
130
131 ctl_state = ioread8(&idio24gpio->reg->ctl) & ~out_mode_mask;
132 iowrite8(ctl_state, &idio24gpio->reg->ctl);
133
134 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
135 }
136
137 return 0;
138 }
139
140 static int idio_24_gpio_direction_output(struct gpio_chip *chip,
141 unsigned int offset, int value)
142 {
143 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
144 unsigned long flags;
145 unsigned int ctl_state;
146 const unsigned long out_mode_mask = BIT(1);
147
148
149 if (offset > 47) {
150 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
151
152
153 ctl_state = ioread8(&idio24gpio->reg->ctl) | out_mode_mask;
154 iowrite8(ctl_state, &idio24gpio->reg->ctl);
155
156 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
157 }
158
159 chip->set(chip, offset, value);
160 return 0;
161 }
162
163 static int idio_24_gpio_get(struct gpio_chip *chip, unsigned int offset)
164 {
165 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
166 const unsigned long offset_mask = BIT(offset % 8);
167 const unsigned long out_mode_mask = BIT(1);
168
169
170 if (offset < 8)
171 return !!(ioread8(&idio24gpio->reg->out0_7) & offset_mask);
172
173 if (offset < 16)
174 return !!(ioread8(&idio24gpio->reg->out8_15) & offset_mask);
175
176 if (offset < 24)
177 return !!(ioread8(&idio24gpio->reg->out16_23) & offset_mask);
178
179
180 if (offset < 32)
181 return !!(ioread8(&idio24gpio->reg->in0_7) & offset_mask);
182
183 if (offset < 40)
184 return !!(ioread8(&idio24gpio->reg->in8_15) & offset_mask);
185
186 if (offset < 48)
187 return !!(ioread8(&idio24gpio->reg->in16_23) & offset_mask);
188
189
190 if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
191 return !!(ioread8(&idio24gpio->reg->ttl_out0_7) & offset_mask);
192
193
194 return !!(ioread8(&idio24gpio->reg->ttl_in0_7) & offset_mask);
195 }
196
197 static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
198 unsigned long *mask, unsigned long *bits)
199 {
200 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
201 size_t i;
202 const unsigned int gpio_reg_size = 8;
203 unsigned int bits_offset;
204 size_t word_index;
205 unsigned int word_offset;
206 unsigned long word_mask;
207 const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
208 unsigned long port_state;
209 void __iomem *ports[] = {
210 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
211 &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
212 &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
213 };
214 const unsigned long out_mode_mask = BIT(1);
215
216
217 bitmap_zero(bits, chip->ngpio);
218
219
220 for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) {
221
222 bits_offset = i * gpio_reg_size;
223
224
225 word_index = BIT_WORD(bits_offset);
226
227
228 word_offset = bits_offset % BITS_PER_LONG;
229
230
231 word_mask = mask[word_index] & (port_mask << word_offset);
232 if (!word_mask) {
233
234 continue;
235 }
236
237
238 if (i < 6)
239 port_state = ioread8(ports[i]);
240 else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
241 port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
242 else
243 port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
244
245
246 bits[word_index] |= (port_state << word_offset) & word_mask;
247 }
248
249 return 0;
250 }
251
252 static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
253 int value)
254 {
255 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
256 const unsigned long out_mode_mask = BIT(1);
257 void __iomem *base;
258 const unsigned int mask = BIT(offset % 8);
259 unsigned long flags;
260 unsigned int out_state;
261
262
263 if (offset > 23 && offset < 48)
264 return;
265
266
267 if (offset > 47 && !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
268 return;
269
270
271 if (offset > 47)
272 base = &idio24gpio->reg->ttl_out0_7;
273
274 else if (offset > 15)
275 base = &idio24gpio->reg->out16_23;
276 else if (offset > 7)
277 base = &idio24gpio->reg->out8_15;
278 else
279 base = &idio24gpio->reg->out0_7;
280
281 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
282
283 if (value)
284 out_state = ioread8(base) | mask;
285 else
286 out_state = ioread8(base) & ~mask;
287
288 iowrite8(out_state, base);
289
290 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
291 }
292
293 static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
294 unsigned long *mask, unsigned long *bits)
295 {
296 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
297 size_t i;
298 unsigned long bits_offset;
299 unsigned long gpio_mask;
300 const unsigned int gpio_reg_size = 8;
301 const unsigned long port_mask = GENMASK(gpio_reg_size, 0);
302 unsigned long flags;
303 unsigned int out_state;
304 void __iomem *ports[] = {
305 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
306 &idio24gpio->reg->out16_23
307 };
308 const unsigned long out_mode_mask = BIT(1);
309 const unsigned int ttl_offset = 48;
310 const size_t ttl_i = BIT_WORD(ttl_offset);
311 const unsigned int word_offset = ttl_offset % BITS_PER_LONG;
312 const unsigned long ttl_mask = (mask[ttl_i] >> word_offset) & port_mask;
313 const unsigned long ttl_bits = (bits[ttl_i] >> word_offset) & ttl_mask;
314
315
316 for (i = 0; i < ARRAY_SIZE(ports); i++) {
317
318 bits_offset = i * gpio_reg_size;
319
320
321 gpio_mask = (*mask >> bits_offset) & port_mask;
322 if (!gpio_mask) {
323
324 continue;
325 }
326
327 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
328
329
330 out_state = ioread8(ports[i]) & ~gpio_mask;
331 out_state |= (*bits >> bits_offset) & gpio_mask;
332 iowrite8(out_state, ports[i]);
333
334 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
335 }
336
337
338 if (!ttl_mask || !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
339 return;
340
341
342 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
343
344
345 out_state = ioread8(&idio24gpio->reg->ttl_out0_7) & ~ttl_mask;
346 out_state |= ttl_bits;
347 iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
348
349 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
350 }
351
352 static void idio_24_irq_ack(struct irq_data *data)
353 {
354 }
355
356 static void idio_24_irq_mask(struct irq_data *data)
357 {
358 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
359 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
360 unsigned long flags;
361 const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
362 unsigned char new_irq_mask;
363 const unsigned long bank_offset = bit_offset/8 * 8;
364 unsigned char cos_enable_state;
365
366 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
367
368 idio24gpio->irq_mask &= BIT(bit_offset);
369 new_irq_mask = idio24gpio->irq_mask >> bank_offset;
370
371 if (!new_irq_mask) {
372 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
373
374
375 cos_enable_state &= ~BIT(bank_offset);
376
377 cos_enable_state &= ~BIT(bank_offset + 4);
378
379 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
380 }
381
382 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
383 }
384
385 static void idio_24_irq_unmask(struct irq_data *data)
386 {
387 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
388 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
389 unsigned long flags;
390 unsigned char prev_irq_mask;
391 const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
392 const unsigned long bank_offset = bit_offset/8 * 8;
393 unsigned char cos_enable_state;
394
395 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
396
397 prev_irq_mask = idio24gpio->irq_mask >> bank_offset;
398 idio24gpio->irq_mask |= BIT(bit_offset);
399
400 if (!prev_irq_mask) {
401 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
402
403
404 cos_enable_state |= BIT(bank_offset);
405
406 cos_enable_state |= BIT(bank_offset + 4);
407
408 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
409 }
410
411 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
412 }
413
414 static int idio_24_irq_set_type(struct irq_data *data, unsigned int flow_type)
415 {
416
417 if (flow_type != IRQ_TYPE_NONE &&
418 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
419 return -EINVAL;
420
421 return 0;
422 }
423
424 static struct irq_chip idio_24_irqchip = {
425 .name = "pcie-idio-24",
426 .irq_ack = idio_24_irq_ack,
427 .irq_mask = idio_24_irq_mask,
428 .irq_unmask = idio_24_irq_unmask,
429 .irq_set_type = idio_24_irq_set_type
430 };
431
432 static irqreturn_t idio_24_irq_handler(int irq, void *dev_id)
433 {
434 struct idio_24_gpio *const idio24gpio = dev_id;
435 unsigned long irq_status;
436 struct gpio_chip *const chip = &idio24gpio->chip;
437 unsigned long irq_mask;
438 int gpio;
439
440 raw_spin_lock(&idio24gpio->lock);
441
442
443 irq_status = ioread32(&idio24gpio->reg->cos0_7);
444
445 raw_spin_unlock(&idio24gpio->lock);
446
447
448 if (!irq_status)
449 return IRQ_NONE;
450
451
452 irq_mask = idio24gpio->irq_mask & irq_status;
453
454 for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24)
455 generic_handle_irq(irq_find_mapping(chip->irq.domain,
456 gpio + 24));
457
458 raw_spin_lock(&idio24gpio->lock);
459
460
461 iowrite32(irq_status, &idio24gpio->reg->cos0_7);
462
463 raw_spin_unlock(&idio24gpio->lock);
464
465 return IRQ_HANDLED;
466 }
467
468 #define IDIO_24_NGPIO 56
469 static const char *idio_24_names[IDIO_24_NGPIO] = {
470 "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
471 "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
472 "OUT16", "OUT17", "OUT18", "OUT19", "OUT20", "OUT21", "OUT22", "OUT23",
473 "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
474 "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15",
475 "IIN16", "IIN17", "IIN18", "IIN19", "IIN20", "IIN21", "IIN22", "IIN23",
476 "TTL0", "TTL1", "TTL2", "TTL3", "TTL4", "TTL5", "TTL6", "TTL7"
477 };
478
479 static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
480 {
481 struct device *const dev = &pdev->dev;
482 struct idio_24_gpio *idio24gpio;
483 int err;
484 const size_t pci_bar_index = 2;
485 const char *const name = pci_name(pdev);
486
487 idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
488 if (!idio24gpio)
489 return -ENOMEM;
490
491 err = pcim_enable_device(pdev);
492 if (err) {
493 dev_err(dev, "Failed to enable PCI device (%d)\n", err);
494 return err;
495 }
496
497 err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
498 if (err) {
499 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
500 return err;
501 }
502
503 idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
504
505 idio24gpio->chip.label = name;
506 idio24gpio->chip.parent = dev;
507 idio24gpio->chip.owner = THIS_MODULE;
508 idio24gpio->chip.base = -1;
509 idio24gpio->chip.ngpio = IDIO_24_NGPIO;
510 idio24gpio->chip.names = idio_24_names;
511 idio24gpio->chip.get_direction = idio_24_gpio_get_direction;
512 idio24gpio->chip.direction_input = idio_24_gpio_direction_input;
513 idio24gpio->chip.direction_output = idio_24_gpio_direction_output;
514 idio24gpio->chip.get = idio_24_gpio_get;
515 idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple;
516 idio24gpio->chip.set = idio_24_gpio_set;
517 idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple;
518
519 raw_spin_lock_init(&idio24gpio->lock);
520
521
522 iowrite8(0, &idio24gpio->reg->soft_reset);
523
524 err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
525 if (err) {
526 dev_err(dev, "GPIO registering failed (%d)\n", err);
527 return err;
528 }
529
530 err = gpiochip_irqchip_add(&idio24gpio->chip, &idio_24_irqchip, 0,
531 handle_edge_irq, IRQ_TYPE_NONE);
532 if (err) {
533 dev_err(dev, "Could not add irqchip (%d)\n", err);
534 return err;
535 }
536
537 err = devm_request_irq(dev, pdev->irq, idio_24_irq_handler, IRQF_SHARED,
538 name, idio24gpio);
539 if (err) {
540 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
541 return err;
542 }
543
544 return 0;
545 }
546
547 static const struct pci_device_id idio_24_pci_dev_id[] = {
548 { PCI_DEVICE(0x494F, 0x0FD0) }, { PCI_DEVICE(0x494F, 0x0BD0) },
549 { PCI_DEVICE(0x494F, 0x07D0) }, { PCI_DEVICE(0x494F, 0x0FC0) },
550 { 0 }
551 };
552 MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id);
553
554 static struct pci_driver idio_24_driver = {
555 .name = "pcie-idio-24",
556 .id_table = idio_24_pci_dev_id,
557 .probe = idio_24_probe
558 };
559
560 module_pci_driver(idio_24_driver);
561
562 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
563 MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver");
564 MODULE_LICENSE("GPL v2");