1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2011-2012 Avionic Design GmbH |
4 | */ |
5 | |
6 | #include <linux/gpio/driver.h> |
7 | #include <linux/i2c.h> |
8 | #include <linux/interrupt.h> |
9 | #include <linux/mod_devicetable.h> |
10 | #include <linux/module.h> |
11 | #include <linux/property.h> |
12 | #include <linux/seq_file.h> |
13 | #include <linux/slab.h> |
14 | |
15 | #define GPIO_DDR(gpio) (0x00 << (gpio)->reg_shift) |
16 | #define GPIO_PLR(gpio) (0x01 << (gpio)->reg_shift) |
17 | #define GPIO_IER(gpio) (0x02 << (gpio)->reg_shift) |
18 | #define GPIO_ISR(gpio) (0x03 << (gpio)->reg_shift) |
19 | #define GPIO_PTR(gpio) (0x04 << (gpio)->reg_shift) |
20 | |
21 | struct adnp { |
22 | struct i2c_client *client; |
23 | struct gpio_chip gpio; |
24 | unsigned int reg_shift; |
25 | |
26 | struct mutex i2c_lock; |
27 | struct mutex irq_lock; |
28 | |
29 | u8 *irq_enable; |
30 | u8 *irq_level; |
31 | u8 *irq_rise; |
32 | u8 *irq_fall; |
33 | u8 *irq_high; |
34 | u8 *irq_low; |
35 | }; |
36 | |
37 | static int adnp_read(struct adnp *adnp, unsigned offset, uint8_t *value) |
38 | { |
39 | int err; |
40 | |
41 | err = i2c_smbus_read_byte_data(client: adnp->client, command: offset); |
42 | if (err < 0) { |
43 | dev_err(adnp->gpio.parent, "%s failed: %d\n" , |
44 | "i2c_smbus_read_byte_data()" , err); |
45 | return err; |
46 | } |
47 | |
48 | *value = err; |
49 | return 0; |
50 | } |
51 | |
52 | static int adnp_write(struct adnp *adnp, unsigned offset, uint8_t value) |
53 | { |
54 | int err; |
55 | |
56 | err = i2c_smbus_write_byte_data(client: adnp->client, command: offset, value); |
57 | if (err < 0) { |
58 | dev_err(adnp->gpio.parent, "%s failed: %d\n" , |
59 | "i2c_smbus_write_byte_data()" , err); |
60 | return err; |
61 | } |
62 | |
63 | return 0; |
64 | } |
65 | |
66 | static int adnp_gpio_get(struct gpio_chip *chip, unsigned offset) |
67 | { |
68 | struct adnp *adnp = gpiochip_get_data(gc: chip); |
69 | unsigned int reg = offset >> adnp->reg_shift; |
70 | unsigned int pos = offset & 7; |
71 | u8 value; |
72 | int err; |
73 | |
74 | err = adnp_read(adnp, GPIO_PLR(adnp) + reg, value: &value); |
75 | if (err < 0) |
76 | return err; |
77 | |
78 | return (value & BIT(pos)) ? 1 : 0; |
79 | } |
80 | |
81 | static void __adnp_gpio_set(struct adnp *adnp, unsigned offset, int value) |
82 | { |
83 | unsigned int reg = offset >> adnp->reg_shift; |
84 | unsigned int pos = offset & 7; |
85 | int err; |
86 | u8 val; |
87 | |
88 | err = adnp_read(adnp, GPIO_PLR(adnp) + reg, value: &val); |
89 | if (err < 0) |
90 | return; |
91 | |
92 | if (value) |
93 | val |= BIT(pos); |
94 | else |
95 | val &= ~BIT(pos); |
96 | |
97 | adnp_write(adnp, GPIO_PLR(adnp) + reg, value: val); |
98 | } |
99 | |
100 | static void adnp_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
101 | { |
102 | struct adnp *adnp = gpiochip_get_data(gc: chip); |
103 | |
104 | mutex_lock(&adnp->i2c_lock); |
105 | __adnp_gpio_set(adnp, offset, value); |
106 | mutex_unlock(lock: &adnp->i2c_lock); |
107 | } |
108 | |
109 | static int adnp_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
110 | { |
111 | struct adnp *adnp = gpiochip_get_data(gc: chip); |
112 | unsigned int reg = offset >> adnp->reg_shift; |
113 | unsigned int pos = offset & 7; |
114 | u8 value; |
115 | int err; |
116 | |
117 | mutex_lock(&adnp->i2c_lock); |
118 | |
119 | err = adnp_read(adnp, GPIO_DDR(adnp) + reg, value: &value); |
120 | if (err < 0) |
121 | goto out; |
122 | |
123 | value &= ~BIT(pos); |
124 | |
125 | err = adnp_write(adnp, GPIO_DDR(adnp) + reg, value); |
126 | if (err < 0) |
127 | goto out; |
128 | |
129 | err = adnp_read(adnp, GPIO_DDR(adnp) + reg, value: &value); |
130 | if (err < 0) |
131 | goto out; |
132 | |
133 | if (value & BIT(pos)) { |
134 | err = -EPERM; |
135 | goto out; |
136 | } |
137 | |
138 | err = 0; |
139 | |
140 | out: |
141 | mutex_unlock(lock: &adnp->i2c_lock); |
142 | return err; |
143 | } |
144 | |
145 | static int adnp_gpio_direction_output(struct gpio_chip *chip, unsigned offset, |
146 | int value) |
147 | { |
148 | struct adnp *adnp = gpiochip_get_data(gc: chip); |
149 | unsigned int reg = offset >> adnp->reg_shift; |
150 | unsigned int pos = offset & 7; |
151 | int err; |
152 | u8 val; |
153 | |
154 | mutex_lock(&adnp->i2c_lock); |
155 | |
156 | err = adnp_read(adnp, GPIO_DDR(adnp) + reg, value: &val); |
157 | if (err < 0) |
158 | goto out; |
159 | |
160 | val |= BIT(pos); |
161 | |
162 | err = adnp_write(adnp, GPIO_DDR(adnp) + reg, value: val); |
163 | if (err < 0) |
164 | goto out; |
165 | |
166 | err = adnp_read(adnp, GPIO_DDR(adnp) + reg, value: &val); |
167 | if (err < 0) |
168 | goto out; |
169 | |
170 | if (!(val & BIT(pos))) { |
171 | err = -EPERM; |
172 | goto out; |
173 | } |
174 | |
175 | __adnp_gpio_set(adnp, offset, value); |
176 | err = 0; |
177 | |
178 | out: |
179 | mutex_unlock(lock: &adnp->i2c_lock); |
180 | return err; |
181 | } |
182 | |
183 | static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) |
184 | { |
185 | struct adnp *adnp = gpiochip_get_data(gc: chip); |
186 | unsigned int num_regs = 1 << adnp->reg_shift, i, j; |
187 | int err; |
188 | |
189 | for (i = 0; i < num_regs; i++) { |
190 | u8 ddr, plr, ier, isr; |
191 | |
192 | mutex_lock(&adnp->i2c_lock); |
193 | |
194 | err = adnp_read(adnp, GPIO_DDR(adnp) + i, value: &ddr); |
195 | if (err < 0) |
196 | goto unlock; |
197 | |
198 | err = adnp_read(adnp, GPIO_PLR(adnp) + i, value: &plr); |
199 | if (err < 0) |
200 | goto unlock; |
201 | |
202 | err = adnp_read(adnp, GPIO_IER(adnp) + i, value: &ier); |
203 | if (err < 0) |
204 | goto unlock; |
205 | |
206 | err = adnp_read(adnp, GPIO_ISR(adnp) + i, value: &isr); |
207 | if (err < 0) |
208 | goto unlock; |
209 | |
210 | mutex_unlock(lock: &adnp->i2c_lock); |
211 | |
212 | for (j = 0; j < 8; j++) { |
213 | unsigned int bit = (i << adnp->reg_shift) + j; |
214 | const char *direction = "input " ; |
215 | const char *level = "low " ; |
216 | const char *interrupt = "disabled" ; |
217 | const char *pending = "" ; |
218 | |
219 | if (ddr & BIT(j)) |
220 | direction = "output" ; |
221 | |
222 | if (plr & BIT(j)) |
223 | level = "high" ; |
224 | |
225 | if (ier & BIT(j)) |
226 | interrupt = "enabled " ; |
227 | |
228 | if (isr & BIT(j)) |
229 | pending = "pending" ; |
230 | |
231 | seq_printf(m: s, fmt: "%2u: %s %s IRQ %s %s\n" , bit, |
232 | direction, level, interrupt, pending); |
233 | } |
234 | } |
235 | |
236 | return; |
237 | |
238 | unlock: |
239 | mutex_unlock(lock: &adnp->i2c_lock); |
240 | } |
241 | |
242 | static irqreturn_t adnp_irq(int irq, void *data) |
243 | { |
244 | struct adnp *adnp = data; |
245 | unsigned int num_regs, i; |
246 | |
247 | num_regs = 1 << adnp->reg_shift; |
248 | |
249 | for (i = 0; i < num_regs; i++) { |
250 | unsigned int base = i << adnp->reg_shift, bit; |
251 | u8 changed, level, isr, ier; |
252 | unsigned long pending; |
253 | int err; |
254 | |
255 | mutex_lock(&adnp->i2c_lock); |
256 | |
257 | err = adnp_read(adnp, GPIO_PLR(adnp) + i, value: &level); |
258 | if (err < 0) { |
259 | mutex_unlock(lock: &adnp->i2c_lock); |
260 | continue; |
261 | } |
262 | |
263 | err = adnp_read(adnp, GPIO_ISR(adnp) + i, value: &isr); |
264 | if (err < 0) { |
265 | mutex_unlock(lock: &adnp->i2c_lock); |
266 | continue; |
267 | } |
268 | |
269 | err = adnp_read(adnp, GPIO_IER(adnp) + i, value: &ier); |
270 | if (err < 0) { |
271 | mutex_unlock(lock: &adnp->i2c_lock); |
272 | continue; |
273 | } |
274 | |
275 | mutex_unlock(lock: &adnp->i2c_lock); |
276 | |
277 | /* determine pins that changed levels */ |
278 | changed = level ^ adnp->irq_level[i]; |
279 | |
280 | /* compute edge-triggered interrupts */ |
281 | pending = changed & ((adnp->irq_fall[i] & ~level) | |
282 | (adnp->irq_rise[i] & level)); |
283 | |
284 | /* add in level-triggered interrupts */ |
285 | pending |= (adnp->irq_high[i] & level) | |
286 | (adnp->irq_low[i] & ~level); |
287 | |
288 | /* mask out non-pending and disabled interrupts */ |
289 | pending &= isr & ier; |
290 | |
291 | for_each_set_bit(bit, &pending, 8) { |
292 | unsigned int child_irq; |
293 | child_irq = irq_find_mapping(domain: adnp->gpio.irq.domain, |
294 | hwirq: base + bit); |
295 | handle_nested_irq(irq: child_irq); |
296 | } |
297 | } |
298 | |
299 | return IRQ_HANDLED; |
300 | } |
301 | |
302 | static void adnp_irq_mask(struct irq_data *d) |
303 | { |
304 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
305 | struct adnp *adnp = gpiochip_get_data(gc); |
306 | unsigned int reg = d->hwirq >> adnp->reg_shift; |
307 | unsigned int pos = d->hwirq & 7; |
308 | |
309 | adnp->irq_enable[reg] &= ~BIT(pos); |
310 | gpiochip_disable_irq(gc, offset: irqd_to_hwirq(d)); |
311 | } |
312 | |
313 | static void adnp_irq_unmask(struct irq_data *d) |
314 | { |
315 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
316 | struct adnp *adnp = gpiochip_get_data(gc); |
317 | unsigned int reg = d->hwirq >> adnp->reg_shift; |
318 | unsigned int pos = d->hwirq & 7; |
319 | |
320 | gpiochip_enable_irq(gc, offset: irqd_to_hwirq(d)); |
321 | adnp->irq_enable[reg] |= BIT(pos); |
322 | } |
323 | |
324 | static int adnp_irq_set_type(struct irq_data *d, unsigned int type) |
325 | { |
326 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
327 | struct adnp *adnp = gpiochip_get_data(gc); |
328 | unsigned int reg = d->hwirq >> adnp->reg_shift; |
329 | unsigned int pos = d->hwirq & 7; |
330 | |
331 | if (type & IRQ_TYPE_EDGE_RISING) |
332 | adnp->irq_rise[reg] |= BIT(pos); |
333 | else |
334 | adnp->irq_rise[reg] &= ~BIT(pos); |
335 | |
336 | if (type & IRQ_TYPE_EDGE_FALLING) |
337 | adnp->irq_fall[reg] |= BIT(pos); |
338 | else |
339 | adnp->irq_fall[reg] &= ~BIT(pos); |
340 | |
341 | if (type & IRQ_TYPE_LEVEL_HIGH) |
342 | adnp->irq_high[reg] |= BIT(pos); |
343 | else |
344 | adnp->irq_high[reg] &= ~BIT(pos); |
345 | |
346 | if (type & IRQ_TYPE_LEVEL_LOW) |
347 | adnp->irq_low[reg] |= BIT(pos); |
348 | else |
349 | adnp->irq_low[reg] &= ~BIT(pos); |
350 | |
351 | return 0; |
352 | } |
353 | |
354 | static void adnp_irq_bus_lock(struct irq_data *d) |
355 | { |
356 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
357 | struct adnp *adnp = gpiochip_get_data(gc); |
358 | |
359 | mutex_lock(&adnp->irq_lock); |
360 | } |
361 | |
362 | static void adnp_irq_bus_unlock(struct irq_data *d) |
363 | { |
364 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
365 | struct adnp *adnp = gpiochip_get_data(gc); |
366 | unsigned int num_regs = 1 << adnp->reg_shift, i; |
367 | |
368 | mutex_lock(&adnp->i2c_lock); |
369 | |
370 | for (i = 0; i < num_regs; i++) |
371 | adnp_write(adnp, GPIO_IER(adnp) + i, value: adnp->irq_enable[i]); |
372 | |
373 | mutex_unlock(lock: &adnp->i2c_lock); |
374 | mutex_unlock(lock: &adnp->irq_lock); |
375 | } |
376 | |
377 | static const struct irq_chip adnp_irq_chip = { |
378 | .name = "gpio-adnp" , |
379 | .irq_mask = adnp_irq_mask, |
380 | .irq_unmask = adnp_irq_unmask, |
381 | .irq_set_type = adnp_irq_set_type, |
382 | .irq_bus_lock = adnp_irq_bus_lock, |
383 | .irq_bus_sync_unlock = adnp_irq_bus_unlock, |
384 | .flags = IRQCHIP_IMMUTABLE, |
385 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
386 | }; |
387 | |
388 | static int adnp_irq_setup(struct adnp *adnp) |
389 | { |
390 | unsigned int num_regs = 1 << adnp->reg_shift, i; |
391 | struct gpio_chip *chip = &adnp->gpio; |
392 | int err; |
393 | |
394 | mutex_init(&adnp->irq_lock); |
395 | |
396 | /* |
397 | * Allocate memory to keep track of the current level and trigger |
398 | * modes of the interrupts. To avoid multiple allocations, a single |
399 | * large buffer is allocated and pointers are setup to point at the |
400 | * corresponding offsets. For consistency, the layout of the buffer |
401 | * is chosen to match the register layout of the hardware in that |
402 | * each segment contains the corresponding bits for all interrupts. |
403 | */ |
404 | adnp->irq_enable = devm_kcalloc(dev: chip->parent, n: num_regs, size: 6, |
405 | GFP_KERNEL); |
406 | if (!adnp->irq_enable) |
407 | return -ENOMEM; |
408 | |
409 | adnp->irq_level = adnp->irq_enable + (num_regs * 1); |
410 | adnp->irq_rise = adnp->irq_enable + (num_regs * 2); |
411 | adnp->irq_fall = adnp->irq_enable + (num_regs * 3); |
412 | adnp->irq_high = adnp->irq_enable + (num_regs * 4); |
413 | adnp->irq_low = adnp->irq_enable + (num_regs * 5); |
414 | |
415 | for (i = 0; i < num_regs; i++) { |
416 | /* |
417 | * Read the initial level of all pins to allow the emulation |
418 | * of edge triggered interrupts. |
419 | */ |
420 | err = adnp_read(adnp, GPIO_PLR(adnp) + i, value: &adnp->irq_level[i]); |
421 | if (err < 0) |
422 | return err; |
423 | |
424 | /* disable all interrupts */ |
425 | err = adnp_write(adnp, GPIO_IER(adnp) + i, value: 0); |
426 | if (err < 0) |
427 | return err; |
428 | |
429 | adnp->irq_enable[i] = 0x00; |
430 | } |
431 | |
432 | err = devm_request_threaded_irq(dev: chip->parent, irq: adnp->client->irq, |
433 | NULL, thread_fn: adnp_irq, |
434 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
435 | devname: dev_name(dev: chip->parent), dev_id: adnp); |
436 | if (err != 0) { |
437 | dev_err(chip->parent, "can't request IRQ#%d: %d\n" , |
438 | adnp->client->irq, err); |
439 | return err; |
440 | } |
441 | |
442 | return 0; |
443 | } |
444 | |
445 | static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios, |
446 | bool is_irq_controller) |
447 | { |
448 | struct gpio_chip *chip = &adnp->gpio; |
449 | int err; |
450 | |
451 | adnp->reg_shift = get_count_order(count: num_gpios) - 3; |
452 | |
453 | chip->direction_input = adnp_gpio_direction_input; |
454 | chip->direction_output = adnp_gpio_direction_output; |
455 | chip->get = adnp_gpio_get; |
456 | chip->set = adnp_gpio_set; |
457 | chip->can_sleep = true; |
458 | |
459 | if (IS_ENABLED(CONFIG_DEBUG_FS)) |
460 | chip->dbg_show = adnp_gpio_dbg_show; |
461 | |
462 | chip->base = -1; |
463 | chip->ngpio = num_gpios; |
464 | chip->label = adnp->client->name; |
465 | chip->parent = &adnp->client->dev; |
466 | chip->owner = THIS_MODULE; |
467 | |
468 | if (is_irq_controller) { |
469 | struct gpio_irq_chip *girq; |
470 | |
471 | err = adnp_irq_setup(adnp); |
472 | if (err) |
473 | return err; |
474 | |
475 | girq = &chip->irq; |
476 | gpio_irq_chip_set_chip(girq, chip: &adnp_irq_chip); |
477 | |
478 | /* This will let us handle the parent IRQ in the driver */ |
479 | girq->parent_handler = NULL; |
480 | girq->num_parents = 0; |
481 | girq->parents = NULL; |
482 | girq->default_type = IRQ_TYPE_NONE; |
483 | girq->handler = handle_simple_irq; |
484 | girq->threaded = true; |
485 | } |
486 | |
487 | err = devm_gpiochip_add_data(&adnp->client->dev, chip, adnp); |
488 | if (err) |
489 | return err; |
490 | |
491 | return 0; |
492 | } |
493 | |
494 | static int adnp_i2c_probe(struct i2c_client *client) |
495 | { |
496 | struct device *dev = &client->dev; |
497 | struct adnp *adnp; |
498 | u32 num_gpios; |
499 | int err; |
500 | |
501 | err = device_property_read_u32(dev, propname: "nr-gpios" , val: &num_gpios); |
502 | if (err < 0) |
503 | return err; |
504 | |
505 | adnp = devm_kzalloc(dev: &client->dev, size: sizeof(*adnp), GFP_KERNEL); |
506 | if (!adnp) |
507 | return -ENOMEM; |
508 | |
509 | mutex_init(&adnp->i2c_lock); |
510 | adnp->client = client; |
511 | |
512 | err = adnp_gpio_setup(adnp, num_gpios, is_irq_controller: device_property_read_bool(dev, propname: "interrupt-controller" )); |
513 | if (err) |
514 | return err; |
515 | |
516 | i2c_set_clientdata(client, data: adnp); |
517 | |
518 | return 0; |
519 | } |
520 | |
521 | static const struct i2c_device_id adnp_i2c_id[] = { |
522 | { "gpio-adnp" }, |
523 | { }, |
524 | }; |
525 | MODULE_DEVICE_TABLE(i2c, adnp_i2c_id); |
526 | |
527 | static const struct of_device_id adnp_of_match[] = { |
528 | { .compatible = "ad,gpio-adnp" , }, |
529 | { }, |
530 | }; |
531 | MODULE_DEVICE_TABLE(of, adnp_of_match); |
532 | |
533 | static struct i2c_driver adnp_i2c_driver = { |
534 | .driver = { |
535 | .name = "gpio-adnp" , |
536 | .of_match_table = adnp_of_match, |
537 | }, |
538 | .probe = adnp_i2c_probe, |
539 | .id_table = adnp_i2c_id, |
540 | }; |
541 | module_i2c_driver(adnp_i2c_driver); |
542 | |
543 | MODULE_DESCRIPTION("Avionic Design N-bit GPIO expander" ); |
544 | MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>" ); |
545 | MODULE_LICENSE("GPL" ); |
546 | |