1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * GPIO driver for the ACCES PCI-IDIO-16
4  * Copyright (C) 2017 William Breathitt Gray
5  */
6 #include <linux/bitmap.h>
7 #include <linux/bitops.h>
8 #include <linux/device.h>
9 #include <linux/errno.h>
10 #include <linux/gpio/driver.h>
11 #include <linux/interrupt.h>
12 #include <linux/irqdesc.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/pci.h>
16 #include <linux/spinlock.h>
17 #include <linux/types.h>
18 
19 /**
20  * struct idio_16_gpio_reg - GPIO device registers structure
21  * @out0_7:	Read: FET Drive Outputs 0-7
22  *		Write: FET Drive Outputs 0-7
23  * @in0_7:	Read: Isolated Inputs 0-7
24  *		Write: Clear Interrupt
25  * @irq_ctl:	Read: Enable IRQ
26  *		Write: Disable IRQ
27  * @filter_ctl:	Read: Activate Input Filters 0-15
28  *		Write: Deactivate Input Filters 0-15
29  * @out8_15:	Read: FET Drive Outputs 8-15
30  *		Write: FET Drive Outputs 8-15
31  * @in8_15:	Read: Isolated Inputs 8-15
32  *		Write: Unused
33  * @irq_status:	Read: Interrupt status
34  *		Write: Unused
35  */
36 struct idio_16_gpio_reg {
37 	u8 out0_7;
38 	u8 in0_7;
39 	u8 irq_ctl;
40 	u8 filter_ctl;
41 	u8 out8_15;
42 	u8 in8_15;
43 	u8 irq_status;
44 };
45 
46 /**
47  * struct idio_16_gpio - GPIO device private data structure
48  * @chip:	instance of the gpio_chip
49  * @lock:	synchronization lock to prevent I/O race conditions
50  * @reg:	I/O address offset for the GPIO device registers
51  * @irq_mask:	I/O bits affected by interrupts
52  */
53 struct idio_16_gpio {
54 	struct gpio_chip chip;
55 	raw_spinlock_t lock;
56 	struct idio_16_gpio_reg __iomem *reg;
57 	unsigned long irq_mask;
58 };
59 
idio_16_gpio_get_direction(struct gpio_chip * chip,unsigned int offset)60 static int idio_16_gpio_get_direction(struct gpio_chip *chip,
61 	unsigned int offset)
62 {
63 	if (offset > 15)
64 		return GPIO_LINE_DIRECTION_IN;
65 
66 	return GPIO_LINE_DIRECTION_OUT;
67 }
68 
idio_16_gpio_direction_input(struct gpio_chip * chip,unsigned int offset)69 static int idio_16_gpio_direction_input(struct gpio_chip *chip,
70 	unsigned int offset)
71 {
72 	return 0;
73 }
74 
idio_16_gpio_direction_output(struct gpio_chip * chip,unsigned int offset,int value)75 static int idio_16_gpio_direction_output(struct gpio_chip *chip,
76 	unsigned int offset, int value)
77 {
78 	chip->set(chip, offset, value);
79 	return 0;
80 }
81 
idio_16_gpio_get(struct gpio_chip * chip,unsigned int offset)82 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
83 {
84 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
85 	unsigned long mask = BIT(offset);
86 
87 	if (offset < 8)
88 		return !!(ioread8(&idio16gpio->reg->out0_7) & mask);
89 
90 	if (offset < 16)
91 		return !!(ioread8(&idio16gpio->reg->out8_15) & (mask >> 8));
92 
93 	if (offset < 24)
94 		return !!(ioread8(&idio16gpio->reg->in0_7) & (mask >> 16));
95 
96 	return !!(ioread8(&idio16gpio->reg->in8_15) & (mask >> 24));
97 }
98 
idio_16_gpio_get_multiple(struct gpio_chip * chip,unsigned long * mask,unsigned long * bits)99 static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
100 	unsigned long *mask, unsigned long *bits)
101 {
102 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
103 	unsigned long offset;
104 	unsigned long gpio_mask;
105 	void __iomem *ports[] = {
106 		&idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
107 		&idio16gpio->reg->in0_7, &idio16gpio->reg->in8_15,
108 	};
109 	void __iomem *port_addr;
110 	unsigned long port_state;
111 
112 	/* clear bits array to a clean slate */
113 	bitmap_zero(bits, chip->ngpio);
114 
115 	for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
116 		port_addr = ports[offset / 8];
117 		port_state = ioread8(port_addr) & gpio_mask;
118 
119 		bitmap_set_value8(bits, port_state, offset);
120 	}
121 
122 	return 0;
123 }
124 
idio_16_gpio_set(struct gpio_chip * chip,unsigned int offset,int value)125 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
126 	int value)
127 {
128 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
129 	unsigned int mask = BIT(offset);
130 	void __iomem *base;
131 	unsigned long flags;
132 	unsigned int out_state;
133 
134 	if (offset > 15)
135 		return;
136 
137 	if (offset > 7) {
138 		mask >>= 8;
139 		base = &idio16gpio->reg->out8_15;
140 	} else
141 		base = &idio16gpio->reg->out0_7;
142 
143 	raw_spin_lock_irqsave(&idio16gpio->lock, flags);
144 
145 	if (value)
146 		out_state = ioread8(base) | mask;
147 	else
148 		out_state = ioread8(base) & ~mask;
149 
150 	iowrite8(out_state, base);
151 
152 	raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
153 }
154 
idio_16_gpio_set_multiple(struct gpio_chip * chip,unsigned long * mask,unsigned long * bits)155 static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
156 	unsigned long *mask, unsigned long *bits)
157 {
158 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
159 	unsigned long offset;
160 	unsigned long gpio_mask;
161 	void __iomem *ports[] = {
162 		&idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
163 	};
164 	size_t index;
165 	void __iomem *port_addr;
166 	unsigned long bitmask;
167 	unsigned long flags;
168 	unsigned long out_state;
169 
170 	for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
171 		index = offset / 8;
172 		port_addr = ports[index];
173 
174 		bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
175 
176 		raw_spin_lock_irqsave(&idio16gpio->lock, flags);
177 
178 		out_state = ioread8(port_addr) & ~gpio_mask;
179 		out_state |= bitmask;
180 		iowrite8(out_state, port_addr);
181 
182 		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
183 	}
184 }
185 
idio_16_irq_ack(struct irq_data * data)186 static void idio_16_irq_ack(struct irq_data *data)
187 {
188 }
189 
idio_16_irq_mask(struct irq_data * data)190 static void idio_16_irq_mask(struct irq_data *data)
191 {
192 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
193 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
194 	const unsigned long mask = BIT(irqd_to_hwirq(data));
195 	unsigned long flags;
196 
197 	idio16gpio->irq_mask &= ~mask;
198 
199 	if (!idio16gpio->irq_mask) {
200 		raw_spin_lock_irqsave(&idio16gpio->lock, flags);
201 
202 		iowrite8(0, &idio16gpio->reg->irq_ctl);
203 
204 		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
205 	}
206 }
207 
idio_16_irq_unmask(struct irq_data * data)208 static void idio_16_irq_unmask(struct irq_data *data)
209 {
210 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
211 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
212 	const unsigned long mask = BIT(irqd_to_hwirq(data));
213 	const unsigned long prev_irq_mask = idio16gpio->irq_mask;
214 	unsigned long flags;
215 
216 	idio16gpio->irq_mask |= mask;
217 
218 	if (!prev_irq_mask) {
219 		raw_spin_lock_irqsave(&idio16gpio->lock, flags);
220 
221 		ioread8(&idio16gpio->reg->irq_ctl);
222 
223 		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
224 	}
225 }
226 
idio_16_irq_set_type(struct irq_data * data,unsigned int flow_type)227 static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
228 {
229 	/* The only valid irq types are none and both-edges */
230 	if (flow_type != IRQ_TYPE_NONE &&
231 		(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
232 		return -EINVAL;
233 
234 	return 0;
235 }
236 
237 static struct irq_chip idio_16_irqchip = {
238 	.name = "pci-idio-16",
239 	.irq_ack = idio_16_irq_ack,
240 	.irq_mask = idio_16_irq_mask,
241 	.irq_unmask = idio_16_irq_unmask,
242 	.irq_set_type = idio_16_irq_set_type
243 };
244 
idio_16_irq_handler(int irq,void * dev_id)245 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
246 {
247 	struct idio_16_gpio *const idio16gpio = dev_id;
248 	unsigned int irq_status;
249 	struct gpio_chip *const chip = &idio16gpio->chip;
250 	int gpio;
251 
252 	raw_spin_lock(&idio16gpio->lock);
253 
254 	irq_status = ioread8(&idio16gpio->reg->irq_status);
255 
256 	raw_spin_unlock(&idio16gpio->lock);
257 
258 	/* Make sure our device generated IRQ */
259 	if (!(irq_status & 0x3) || !(irq_status & 0x4))
260 		return IRQ_NONE;
261 
262 	for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
263 		generic_handle_domain_irq(chip->irq.domain, gpio);
264 
265 	raw_spin_lock(&idio16gpio->lock);
266 
267 	/* Clear interrupt */
268 	iowrite8(0, &idio16gpio->reg->in0_7);
269 
270 	raw_spin_unlock(&idio16gpio->lock);
271 
272 	return IRQ_HANDLED;
273 }
274 
275 #define IDIO_16_NGPIO 32
276 static const char *idio_16_names[IDIO_16_NGPIO] = {
277 	"OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
278 	"OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
279 	"IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
280 	"IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
281 };
282 
idio_16_irq_init_hw(struct gpio_chip * gc)283 static int idio_16_irq_init_hw(struct gpio_chip *gc)
284 {
285 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
286 
287 	/* Disable IRQ by default and clear any pending interrupt */
288 	iowrite8(0, &idio16gpio->reg->irq_ctl);
289 	iowrite8(0, &idio16gpio->reg->in0_7);
290 
291 	return 0;
292 }
293 
idio_16_probe(struct pci_dev * pdev,const struct pci_device_id * id)294 static int idio_16_probe(struct pci_dev *pdev, const struct pci_device_id *id)
295 {
296 	struct device *const dev = &pdev->dev;
297 	struct idio_16_gpio *idio16gpio;
298 	int err;
299 	const size_t pci_bar_index = 2;
300 	const char *const name = pci_name(pdev);
301 	struct gpio_irq_chip *girq;
302 
303 	idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
304 	if (!idio16gpio)
305 		return -ENOMEM;
306 
307 	err = pcim_enable_device(pdev);
308 	if (err) {
309 		dev_err(dev, "Failed to enable PCI device (%d)\n", err);
310 		return err;
311 	}
312 
313 	err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
314 	if (err) {
315 		dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
316 		return err;
317 	}
318 
319 	idio16gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
320 
321 	/* Deactivate input filters */
322 	iowrite8(0, &idio16gpio->reg->filter_ctl);
323 
324 	idio16gpio->chip.label = name;
325 	idio16gpio->chip.parent = dev;
326 	idio16gpio->chip.owner = THIS_MODULE;
327 	idio16gpio->chip.base = -1;
328 	idio16gpio->chip.ngpio = IDIO_16_NGPIO;
329 	idio16gpio->chip.names = idio_16_names;
330 	idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
331 	idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
332 	idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
333 	idio16gpio->chip.get = idio_16_gpio_get;
334 	idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
335 	idio16gpio->chip.set = idio_16_gpio_set;
336 	idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
337 
338 	girq = &idio16gpio->chip.irq;
339 	girq->chip = &idio_16_irqchip;
340 	/* This will let us handle the parent IRQ in the driver */
341 	girq->parent_handler = NULL;
342 	girq->num_parents = 0;
343 	girq->parents = NULL;
344 	girq->default_type = IRQ_TYPE_NONE;
345 	girq->handler = handle_edge_irq;
346 	girq->init_hw = idio_16_irq_init_hw;
347 
348 	raw_spin_lock_init(&idio16gpio->lock);
349 
350 	err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
351 	if (err) {
352 		dev_err(dev, "GPIO registering failed (%d)\n", err);
353 		return err;
354 	}
355 
356 	err = devm_request_irq(dev, pdev->irq, idio_16_irq_handler, IRQF_SHARED,
357 		name, idio16gpio);
358 	if (err) {
359 		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
360 		return err;
361 	}
362 
363 	return 0;
364 }
365 
366 static const struct pci_device_id idio_16_pci_dev_id[] = {
367 	{ PCI_DEVICE(0x494F, 0x0DC8) }, { 0 }
368 };
369 MODULE_DEVICE_TABLE(pci, idio_16_pci_dev_id);
370 
371 static struct pci_driver idio_16_driver = {
372 	.name = "pci-idio-16",
373 	.id_table = idio_16_pci_dev_id,
374 	.probe = idio_16_probe
375 };
376 
377 module_pci_driver(idio_16_driver);
378 
379 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
380 MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver");
381 MODULE_LICENSE("GPL v2");
382