GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / gpio / gpio-vr41xx.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Driver for NEC VR4100 series General-purpose I/O Unit.
4  *
5  *  Copyright (C) 2002 MontaVista Software Inc.
6  *      Author: Yoichi Yuasa <source@mvista.com>
7  *  Copyright (C) 2003-2009  Yoichi Yuasa <yuasa@linux-mips.org>
8  */
9 #include <linux/errno.h>
10 #include <linux/fs.h>
11 #include <linux/gpio/driver.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/io.h>
15 #include <linux/irq.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/platform_device.h>
19 #include <linux/spinlock.h>
20 #include <linux/types.h>
21
22 #include <asm/vr41xx/giu.h>
23 #include <asm/vr41xx/irq.h>
24 #include <asm/vr41xx/vr41xx.h>
25
26 MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>");
27 MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver");
28 MODULE_LICENSE("GPL");
29
30 #define GIUIOSELL       0x00
31 #define GIUIOSELH       0x02
32 #define GIUPIODL        0x04
33 #define GIUPIODH        0x06
34 #define GIUINTSTATL     0x08
35 #define GIUINTSTATH     0x0a
36 #define GIUINTENL       0x0c
37 #define GIUINTENH       0x0e
38 #define GIUINTTYPL      0x10
39 #define GIUINTTYPH      0x12
40 #define GIUINTALSELL    0x14
41 #define GIUINTALSELH    0x16
42 #define GIUINTHTSELL    0x18
43 #define GIUINTHTSELH    0x1a
44 #define GIUPODATL       0x1c
45 #define GIUPODATEN      0x1c
46 #define GIUPODATH       0x1e
47  #define PIOEN0         0x0100
48  #define PIOEN1         0x0200
49 #define GIUPODAT        0x1e
50 #define GIUFEDGEINHL    0x20
51 #define GIUFEDGEINHH    0x22
52 #define GIUREDGEINHL    0x24
53 #define GIUREDGEINHH    0x26
54
55 #define GIUUSEUPDN      0x1e0
56 #define GIUTERMUPDN     0x1e2
57
58 #define GPIO_HAS_PULLUPDOWN_IO          0x0001
59 #define GPIO_HAS_OUTPUT_ENABLE          0x0002
60 #define GPIO_HAS_INTERRUPT_EDGE_SELECT  0x0100
61
62 enum {
63         GPIO_INPUT,
64         GPIO_OUTPUT,
65 };
66
67 static DEFINE_SPINLOCK(giu_lock);
68 static unsigned long giu_flags;
69
70 static void __iomem *giu_base;
71 static struct gpio_chip vr41xx_gpio_chip;
72
73 #define giu_read(offset)                readw(giu_base + (offset))
74 #define giu_write(offset, value)        writew((value), giu_base + (offset))
75
76 #define GPIO_PIN_OF_IRQ(irq)    ((irq) - GIU_IRQ_BASE)
77 #define GIUINT_HIGH_OFFSET      16
78 #define GIUINT_HIGH_MAX         32
79
80 static inline u16 giu_set(u16 offset, u16 set)
81 {
82         u16 data;
83
84         data = giu_read(offset);
85         data |= set;
86         giu_write(offset, data);
87
88         return data;
89 }
90
91 static inline u16 giu_clear(u16 offset, u16 clear)
92 {
93         u16 data;
94
95         data = giu_read(offset);
96         data &= ~clear;
97         giu_write(offset, data);
98
99         return data;
100 }
101
102 static void ack_giuint_low(struct irq_data *d)
103 {
104         giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(d->irq));
105 }
106
107 static void mask_giuint_low(struct irq_data *d)
108 {
109         giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq));
110 }
111
112 static void mask_ack_giuint_low(struct irq_data *d)
113 {
114         unsigned int pin;
115
116         pin = GPIO_PIN_OF_IRQ(d->irq);
117         giu_clear(GIUINTENL, 1 << pin);
118         giu_write(GIUINTSTATL, 1 << pin);
119 }
120
121 static void unmask_giuint_low(struct irq_data *d)
122 {
123         giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq));
124 }
125
126 static unsigned int startup_giuint(struct irq_data *data)
127 {
128         int ret;
129
130         ret = gpiochip_lock_as_irq(&vr41xx_gpio_chip, irqd_to_hwirq(data));
131         if (ret) {
132                 dev_err(vr41xx_gpio_chip.parent,
133                         "unable to lock HW IRQ %lu for IRQ\n",
134                         data->hwirq);
135                 return ret;
136         }
137
138         /* Satisfy the .enable semantics by unmasking the line */
139         unmask_giuint_low(data);
140         return 0;
141 }
142
143 static void shutdown_giuint(struct irq_data *data)
144 {
145         mask_giuint_low(data);
146         gpiochip_unlock_as_irq(&vr41xx_gpio_chip, data->hwirq);
147 }
148
149 static struct irq_chip giuint_low_irq_chip = {
150         .name           = "GIUINTL",
151         .irq_ack        = ack_giuint_low,
152         .irq_mask       = mask_giuint_low,
153         .irq_mask_ack   = mask_ack_giuint_low,
154         .irq_unmask     = unmask_giuint_low,
155         .irq_startup    = startup_giuint,
156         .irq_shutdown   = shutdown_giuint,
157 };
158
159 static void ack_giuint_high(struct irq_data *d)
160 {
161         giu_write(GIUINTSTATH,
162                   1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
163 }
164
165 static void mask_giuint_high(struct irq_data *d)
166 {
167         giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
168 }
169
170 static void mask_ack_giuint_high(struct irq_data *d)
171 {
172         unsigned int pin;
173
174         pin = GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET;
175         giu_clear(GIUINTENH, 1 << pin);
176         giu_write(GIUINTSTATH, 1 << pin);
177 }
178
179 static void unmask_giuint_high(struct irq_data *d)
180 {
181         giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
182 }
183
184 static struct irq_chip giuint_high_irq_chip = {
185         .name           = "GIUINTH",
186         .irq_ack        = ack_giuint_high,
187         .irq_mask       = mask_giuint_high,
188         .irq_mask_ack   = mask_ack_giuint_high,
189         .irq_unmask     = unmask_giuint_high,
190 };
191
192 static int giu_get_irq(unsigned int irq)
193 {
194         u16 pendl, pendh, maskl, maskh;
195         int i;
196
197         pendl = giu_read(GIUINTSTATL);
198         pendh = giu_read(GIUINTSTATH);
199         maskl = giu_read(GIUINTENL);
200         maskh = giu_read(GIUINTENH);
201
202         maskl &= pendl;
203         maskh &= pendh;
204
205         if (maskl) {
206                 for (i = 0; i < 16; i++) {
207                         if (maskl & (1 << i))
208                                 return GIU_IRQ(i);
209                 }
210         } else if (maskh) {
211                 for (i = 0; i < 16; i++) {
212                         if (maskh & (1 << i))
213                                 return GIU_IRQ(i + GIUINT_HIGH_OFFSET);
214                 }
215         }
216
217         printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n",
218                maskl, pendl, maskh, pendh);
219
220         return -EINVAL;
221 }
222
223 void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger,
224                             irq_signal_t signal)
225 {
226         u16 mask;
227
228         if (pin < GIUINT_HIGH_OFFSET) {
229                 mask = 1 << pin;
230                 if (trigger != IRQ_TRIGGER_LEVEL) {
231                         giu_set(GIUINTTYPL, mask);
232                         if (signal == IRQ_SIGNAL_HOLD)
233                                 giu_set(GIUINTHTSELL, mask);
234                         else
235                                 giu_clear(GIUINTHTSELL, mask);
236                         if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
237                                 switch (trigger) {
238                                 case IRQ_TRIGGER_EDGE_FALLING:
239                                         giu_set(GIUFEDGEINHL, mask);
240                                         giu_clear(GIUREDGEINHL, mask);
241                                         break;
242                                 case IRQ_TRIGGER_EDGE_RISING:
243                                         giu_clear(GIUFEDGEINHL, mask);
244                                         giu_set(GIUREDGEINHL, mask);
245                                         break;
246                                 default:
247                                         giu_set(GIUFEDGEINHL, mask);
248                                         giu_set(GIUREDGEINHL, mask);
249                                         break;
250                                 }
251                         }
252                         irq_set_chip_and_handler(GIU_IRQ(pin),
253                                                  &giuint_low_irq_chip,
254                                                  handle_edge_irq);
255                 } else {
256                         giu_clear(GIUINTTYPL, mask);
257                         giu_clear(GIUINTHTSELL, mask);
258                         irq_set_chip_and_handler(GIU_IRQ(pin),
259                                                  &giuint_low_irq_chip,
260                                                  handle_level_irq);
261                 }
262                 giu_write(GIUINTSTATL, mask);
263         } else if (pin < GIUINT_HIGH_MAX) {
264                 mask = 1 << (pin - GIUINT_HIGH_OFFSET);
265                 if (trigger != IRQ_TRIGGER_LEVEL) {
266                         giu_set(GIUINTTYPH, mask);
267                         if (signal == IRQ_SIGNAL_HOLD)
268                                 giu_set(GIUINTHTSELH, mask);
269                         else
270                                 giu_clear(GIUINTHTSELH, mask);
271                         if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
272                                 switch (trigger) {
273                                 case IRQ_TRIGGER_EDGE_FALLING:
274                                         giu_set(GIUFEDGEINHH, mask);
275                                         giu_clear(GIUREDGEINHH, mask);
276                                         break;
277                                 case IRQ_TRIGGER_EDGE_RISING:
278                                         giu_clear(GIUFEDGEINHH, mask);
279                                         giu_set(GIUREDGEINHH, mask);
280                                         break;
281                                 default:
282                                         giu_set(GIUFEDGEINHH, mask);
283                                         giu_set(GIUREDGEINHH, mask);
284                                         break;
285                                 }
286                         }
287                         irq_set_chip_and_handler(GIU_IRQ(pin),
288                                                  &giuint_high_irq_chip,
289                                                  handle_edge_irq);
290                 } else {
291                         giu_clear(GIUINTTYPH, mask);
292                         giu_clear(GIUINTHTSELH, mask);
293                         irq_set_chip_and_handler(GIU_IRQ(pin),
294                                                  &giuint_high_irq_chip,
295                                                  handle_level_irq);
296                 }
297                 giu_write(GIUINTSTATH, mask);
298         }
299 }
300 EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger);
301
302 void vr41xx_set_irq_level(unsigned int pin, irq_level_t level)
303 {
304         u16 mask;
305
306         if (pin < GIUINT_HIGH_OFFSET) {
307                 mask = 1 << pin;
308                 if (level == IRQ_LEVEL_HIGH)
309                         giu_set(GIUINTALSELL, mask);
310                 else
311                         giu_clear(GIUINTALSELL, mask);
312                 giu_write(GIUINTSTATL, mask);
313         } else if (pin < GIUINT_HIGH_MAX) {
314                 mask = 1 << (pin - GIUINT_HIGH_OFFSET);
315                 if (level == IRQ_LEVEL_HIGH)
316                         giu_set(GIUINTALSELH, mask);
317                 else
318                         giu_clear(GIUINTALSELH, mask);
319                 giu_write(GIUINTSTATH, mask);
320         }
321 }
322 EXPORT_SYMBOL_GPL(vr41xx_set_irq_level);
323
324 static int giu_set_direction(struct gpio_chip *chip, unsigned pin, int dir)
325 {
326         u16 offset, mask, reg;
327         unsigned long flags;
328
329         if (pin >= chip->ngpio)
330                 return -EINVAL;
331
332         if (pin < 16) {
333                 offset = GIUIOSELL;
334                 mask = 1 << pin;
335         } else if (pin < 32) {
336                 offset = GIUIOSELH;
337                 mask = 1 << (pin - 16);
338         } else {
339                 if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) {
340                         offset = GIUPODATEN;
341                         mask = 1 << (pin - 32);
342                 } else {
343                         switch (pin) {
344                         case 48:
345                                 offset = GIUPODATH;
346                                 mask = PIOEN0;
347                                 break;
348                         case 49:
349                                 offset = GIUPODATH;
350                                 mask = PIOEN1;
351                                 break;
352                         default:
353                                 return -EINVAL;
354                         }
355                 }
356         }
357
358         spin_lock_irqsave(&giu_lock, flags);
359
360         reg = giu_read(offset);
361         if (dir == GPIO_OUTPUT)
362                 reg |= mask;
363         else
364                 reg &= ~mask;
365         giu_write(offset, reg);
366
367         spin_unlock_irqrestore(&giu_lock, flags);
368
369         return 0;
370 }
371
372 static int vr41xx_gpio_get(struct gpio_chip *chip, unsigned pin)
373 {
374         u16 reg, mask;
375
376         if (pin >= chip->ngpio)
377                 return -EINVAL;
378
379         if (pin < 16) {
380                 reg = giu_read(GIUPIODL);
381                 mask = 1 << pin;
382         } else if (pin < 32) {
383                 reg = giu_read(GIUPIODH);
384                 mask = 1 << (pin - 16);
385         } else if (pin < 48) {
386                 reg = giu_read(GIUPODATL);
387                 mask = 1 << (pin - 32);
388         } else {
389                 reg = giu_read(GIUPODATH);
390                 mask = 1 << (pin - 48);
391         }
392
393         if (reg & mask)
394                 return 1;
395
396         return 0;
397 }
398
399 static void vr41xx_gpio_set(struct gpio_chip *chip, unsigned pin,
400                             int value)
401 {
402         u16 offset, mask, reg;
403         unsigned long flags;
404
405         if (pin >= chip->ngpio)
406                 return;
407
408         if (pin < 16) {
409                 offset = GIUPIODL;
410                 mask = 1 << pin;
411         } else if (pin < 32) {
412                 offset = GIUPIODH;
413                 mask = 1 << (pin - 16);
414         } else if (pin < 48) {
415                 offset = GIUPODATL;
416                 mask = 1 << (pin - 32);
417         } else {
418                 offset = GIUPODATH;
419                 mask = 1 << (pin - 48);
420         }
421
422         spin_lock_irqsave(&giu_lock, flags);
423
424         reg = giu_read(offset);
425         if (value)
426                 reg |= mask;
427         else
428                 reg &= ~mask;
429         giu_write(offset, reg);
430
431         spin_unlock_irqrestore(&giu_lock, flags);
432 }
433
434
435 static int vr41xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
436 {
437         return giu_set_direction(chip, offset, GPIO_INPUT);
438 }
439
440 static int vr41xx_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
441                                 int value)
442 {
443         vr41xx_gpio_set(chip, offset, value);
444
445         return giu_set_direction(chip, offset, GPIO_OUTPUT);
446 }
447
448 static int vr41xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
449 {
450         if (offset >= chip->ngpio)
451                 return -EINVAL;
452
453         return GIU_IRQ_BASE + offset;
454 }
455
456 static struct gpio_chip vr41xx_gpio_chip = {
457         .label                  = "vr41xx",
458         .owner                  = THIS_MODULE,
459         .direction_input        = vr41xx_gpio_direction_input,
460         .get                    = vr41xx_gpio_get,
461         .direction_output       = vr41xx_gpio_direction_output,
462         .set                    = vr41xx_gpio_set,
463         .to_irq                 = vr41xx_gpio_to_irq,
464 };
465
466 static int giu_probe(struct platform_device *pdev)
467 {
468         unsigned int trigger, i, pin;
469         struct irq_chip *chip;
470         int irq;
471
472         switch (pdev->id) {
473         case GPIO_50PINS_PULLUPDOWN:
474                 giu_flags = GPIO_HAS_PULLUPDOWN_IO;
475                 vr41xx_gpio_chip.ngpio = 50;
476                 break;
477         case GPIO_36PINS:
478                 vr41xx_gpio_chip.ngpio = 36;
479                 break;
480         case GPIO_48PINS_EDGE_SELECT:
481                 giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
482                 vr41xx_gpio_chip.ngpio = 48;
483                 break;
484         default:
485                 dev_err(&pdev->dev, "GIU: unknown ID %d\n", pdev->id);
486                 return -ENODEV;
487         }
488
489         giu_base = devm_platform_ioremap_resource(pdev, 0);
490         if (IS_ERR(giu_base))
491                 return PTR_ERR(giu_base);
492
493         vr41xx_gpio_chip.parent = &pdev->dev;
494
495         if (gpiochip_add_data(&vr41xx_gpio_chip, NULL))
496                 return -ENODEV;
497
498         giu_write(GIUINTENL, 0);
499         giu_write(GIUINTENH, 0);
500
501         trigger = giu_read(GIUINTTYPH) << 16;
502         trigger |= giu_read(GIUINTTYPL);
503         for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
504                 pin = GPIO_PIN_OF_IRQ(i);
505                 if (pin < GIUINT_HIGH_OFFSET)
506                         chip = &giuint_low_irq_chip;
507                 else
508                         chip = &giuint_high_irq_chip;
509
510                 if (trigger & (1 << pin))
511                         irq_set_chip_and_handler(i, chip, handle_edge_irq);
512                 else
513                         irq_set_chip_and_handler(i, chip, handle_level_irq);
514
515         }
516
517         irq = platform_get_irq(pdev, 0);
518         if (irq < 0 || irq >= nr_irqs)
519                 return -EBUSY;
520
521         return cascade_irq(irq, giu_get_irq);
522 }
523
524 static int giu_remove(struct platform_device *pdev)
525 {
526         if (giu_base) {
527                 giu_base = NULL;
528         }
529
530         return 0;
531 }
532
533 static struct platform_driver giu_device_driver = {
534         .probe          = giu_probe,
535         .remove         = giu_remove,
536         .driver         = {
537                 .name   = "GIU",
538         },
539 };
540
541 module_platform_driver(giu_device_driver);