xref: /linux/drivers/gpio/gpio-pci-idio-16.c (revision 497e6b37b0099dc415578488287fd84fb74433eb)
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/bits.h>
7 #include <linux/device.h>
8 #include <linux/errno.h>
9 #include <linux/gpio/driver.h>
10 #include <linux/interrupt.h>
11 #include <linux/irqdesc.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/pci.h>
15 #include <linux/spinlock.h>
16 #include <linux/types.h>
17 
18 #include "gpio-idio-16.h"
19 
20 /**
21  * struct idio_16_gpio - GPIO device private data structure
22  * @chip:	instance of the gpio_chip
23  * @lock:	synchronization lock to prevent I/O race conditions
24  * @reg:	I/O address offset for the GPIO device registers
25  * @state:	ACCES IDIO-16 device state
26  * @irq_mask:	I/O bits affected by interrupts
27  */
28 struct idio_16_gpio {
29 	struct gpio_chip chip;
30 	raw_spinlock_t lock;
31 	struct idio_16 __iomem *reg;
32 	struct idio_16_state state;
33 	unsigned long irq_mask;
34 };
35 
36 static int idio_16_gpio_get_direction(struct gpio_chip *chip,
37 	unsigned int offset)
38 {
39 	if (idio_16_get_direction(offset))
40 		return GPIO_LINE_DIRECTION_IN;
41 
42 	return GPIO_LINE_DIRECTION_OUT;
43 }
44 
45 static int idio_16_gpio_direction_input(struct gpio_chip *chip,
46 	unsigned int offset)
47 {
48 	return 0;
49 }
50 
51 static int idio_16_gpio_direction_output(struct gpio_chip *chip,
52 	unsigned int offset, int value)
53 {
54 	chip->set(chip, offset, value);
55 	return 0;
56 }
57 
58 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
59 {
60 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
61 
62 	return idio_16_get(idio16gpio->reg, &idio16gpio->state, offset);
63 }
64 
65 static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
66 	unsigned long *mask, unsigned long *bits)
67 {
68 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
69 
70 	idio_16_get_multiple(idio16gpio->reg, &idio16gpio->state, mask, bits);
71 	return 0;
72 }
73 
74 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
75 	int value)
76 {
77 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
78 
79 	idio_16_set(idio16gpio->reg, &idio16gpio->state, offset, value);
80 }
81 
82 static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
83 	unsigned long *mask, unsigned long *bits)
84 {
85 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
86 
87 	idio_16_set_multiple(idio16gpio->reg, &idio16gpio->state, mask, bits);
88 }
89 
90 static void idio_16_irq_ack(struct irq_data *data)
91 {
92 }
93 
94 static void idio_16_irq_mask(struct irq_data *data)
95 {
96 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
97 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
98 	const unsigned long mask = BIT(irqd_to_hwirq(data));
99 	unsigned long flags;
100 
101 	idio16gpio->irq_mask &= ~mask;
102 
103 	if (!idio16gpio->irq_mask) {
104 		raw_spin_lock_irqsave(&idio16gpio->lock, flags);
105 
106 		iowrite8(0, &idio16gpio->reg->irq_ctl);
107 
108 		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
109 	}
110 }
111 
112 static void idio_16_irq_unmask(struct irq_data *data)
113 {
114 	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
115 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
116 	const unsigned long mask = BIT(irqd_to_hwirq(data));
117 	const unsigned long prev_irq_mask = idio16gpio->irq_mask;
118 	unsigned long flags;
119 
120 	idio16gpio->irq_mask |= mask;
121 
122 	if (!prev_irq_mask) {
123 		raw_spin_lock_irqsave(&idio16gpio->lock, flags);
124 
125 		ioread8(&idio16gpio->reg->irq_ctl);
126 
127 		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
128 	}
129 }
130 
131 static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
132 {
133 	/* The only valid irq types are none and both-edges */
134 	if (flow_type != IRQ_TYPE_NONE &&
135 		(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
136 		return -EINVAL;
137 
138 	return 0;
139 }
140 
141 static struct irq_chip idio_16_irqchip = {
142 	.name = "pci-idio-16",
143 	.irq_ack = idio_16_irq_ack,
144 	.irq_mask = idio_16_irq_mask,
145 	.irq_unmask = idio_16_irq_unmask,
146 	.irq_set_type = idio_16_irq_set_type
147 };
148 
149 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
150 {
151 	struct idio_16_gpio *const idio16gpio = dev_id;
152 	unsigned int irq_status;
153 	struct gpio_chip *const chip = &idio16gpio->chip;
154 	int gpio;
155 
156 	raw_spin_lock(&idio16gpio->lock);
157 
158 	irq_status = ioread8(&idio16gpio->reg->irq_status);
159 
160 	raw_spin_unlock(&idio16gpio->lock);
161 
162 	/* Make sure our device generated IRQ */
163 	if (!(irq_status & 0x3) || !(irq_status & 0x4))
164 		return IRQ_NONE;
165 
166 	for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
167 		generic_handle_domain_irq(chip->irq.domain, gpio);
168 
169 	raw_spin_lock(&idio16gpio->lock);
170 
171 	/* Clear interrupt */
172 	iowrite8(0, &idio16gpio->reg->in0_7);
173 
174 	raw_spin_unlock(&idio16gpio->lock);
175 
176 	return IRQ_HANDLED;
177 }
178 
179 #define IDIO_16_NGPIO 32
180 static const char *idio_16_names[IDIO_16_NGPIO] = {
181 	"OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
182 	"OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
183 	"IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
184 	"IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
185 };
186 
187 static int idio_16_irq_init_hw(struct gpio_chip *gc)
188 {
189 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
190 
191 	/* Disable IRQ by default and clear any pending interrupt */
192 	iowrite8(0, &idio16gpio->reg->irq_ctl);
193 	iowrite8(0, &idio16gpio->reg->in0_7);
194 
195 	return 0;
196 }
197 
198 static int idio_16_probe(struct pci_dev *pdev, const struct pci_device_id *id)
199 {
200 	struct device *const dev = &pdev->dev;
201 	struct idio_16_gpio *idio16gpio;
202 	int err;
203 	const size_t pci_bar_index = 2;
204 	const char *const name = pci_name(pdev);
205 	struct gpio_irq_chip *girq;
206 
207 	idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
208 	if (!idio16gpio)
209 		return -ENOMEM;
210 
211 	err = pcim_enable_device(pdev);
212 	if (err) {
213 		dev_err(dev, "Failed to enable PCI device (%d)\n", err);
214 		return err;
215 	}
216 
217 	err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
218 	if (err) {
219 		dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
220 		return err;
221 	}
222 
223 	idio16gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
224 
225 	/* Deactivate input filters */
226 	iowrite8(0, &idio16gpio->reg->filter_ctl);
227 
228 	idio16gpio->chip.label = name;
229 	idio16gpio->chip.parent = dev;
230 	idio16gpio->chip.owner = THIS_MODULE;
231 	idio16gpio->chip.base = -1;
232 	idio16gpio->chip.ngpio = IDIO_16_NGPIO;
233 	idio16gpio->chip.names = idio_16_names;
234 	idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
235 	idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
236 	idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
237 	idio16gpio->chip.get = idio_16_gpio_get;
238 	idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
239 	idio16gpio->chip.set = idio_16_gpio_set;
240 	idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
241 
242 	idio_16_state_init(&idio16gpio->state);
243 
244 	girq = &idio16gpio->chip.irq;
245 	girq->chip = &idio_16_irqchip;
246 	/* This will let us handle the parent IRQ in the driver */
247 	girq->parent_handler = NULL;
248 	girq->num_parents = 0;
249 	girq->parents = NULL;
250 	girq->default_type = IRQ_TYPE_NONE;
251 	girq->handler = handle_edge_irq;
252 	girq->init_hw = idio_16_irq_init_hw;
253 
254 	raw_spin_lock_init(&idio16gpio->lock);
255 
256 	err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
257 	if (err) {
258 		dev_err(dev, "GPIO registering failed (%d)\n", err);
259 		return err;
260 	}
261 
262 	err = devm_request_irq(dev, pdev->irq, idio_16_irq_handler, IRQF_SHARED,
263 		name, idio16gpio);
264 	if (err) {
265 		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
266 		return err;
267 	}
268 
269 	return 0;
270 }
271 
272 static const struct pci_device_id idio_16_pci_dev_id[] = {
273 	{ PCI_DEVICE(0x494F, 0x0DC8) }, { 0 }
274 };
275 MODULE_DEVICE_TABLE(pci, idio_16_pci_dev_id);
276 
277 static struct pci_driver idio_16_driver = {
278 	.name = "pci-idio-16",
279 	.id_table = idio_16_pci_dev_id,
280 	.probe = idio_16_probe
281 };
282 
283 module_pci_driver(idio_16_driver);
284 
285 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
286 MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver");
287 MODULE_LICENSE("GPL v2");
288 MODULE_IMPORT_NS(GPIO_IDIO_16);
289