]> Git Repo - linux.git/blob - arch/arm/mach-s3c/gpio-samsung.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[linux.git] / arch / arm / mach-s3c / gpio-samsung.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
4 //              http://www.samsung.com/
5 //
6 // Copyright 2008 Openmoko, Inc.
7 // Copyright 2008 Simtec Electronics
8 //      Ben Dooks <[email protected]>
9 //      http://armlinux.simtec.co.uk/
10 //
11 // Samsung - GPIOlib support
12
13 #include <linux/kernel.h>
14 #include <linux/irq.h>
15 #include <linux/io.h>
16 #include <linux/gpio.h>
17 #include <linux/init.h>
18 #include <linux/spinlock.h>
19 #include <linux/module.h>
20 #include <linux/interrupt.h>
21 #include <linux/device.h>
22 #include <linux/ioport.h>
23 #include <linux/of.h>
24 #include <linux/slab.h>
25 #include <linux/of_address.h>
26
27 #include <asm/irq.h>
28
29 #include "irqs.h"
30 #include "map.h"
31 #include "regs-gpio.h"
32 #include "gpio-samsung.h"
33
34 #include "cpu.h"
35 #include "gpio-core.h"
36 #include "gpio-cfg.h"
37 #include "gpio-cfg-helpers.h"
38 #include "pm.h"
39
40 static int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
41                                 unsigned int off, samsung_gpio_pull_t pull)
42 {
43         void __iomem *reg = chip->base + 0x08;
44         int shift = off * 2;
45         u32 pup;
46
47         pup = __raw_readl(reg);
48         pup &= ~(3 << shift);
49         pup |= pull << shift;
50         __raw_writel(pup, reg);
51
52         return 0;
53 }
54
55 static samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
56                                                 unsigned int off)
57 {
58         void __iomem *reg = chip->base + 0x08;
59         int shift = off * 2;
60         u32 pup = __raw_readl(reg);
61
62         pup >>= shift;
63         pup &= 0x3;
64
65         return (__force samsung_gpio_pull_t)pup;
66 }
67
68 static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
69                                     unsigned int off, unsigned int cfg)
70 {
71         void __iomem *reg = chip->base;
72         unsigned int shift = off * 2;
73         u32 con;
74
75         if (samsung_gpio_is_cfg_special(cfg)) {
76                 cfg &= 0xf;
77                 if (cfg > 3)
78                         return -EINVAL;
79
80                 cfg <<= shift;
81         }
82
83         con = __raw_readl(reg);
84         con &= ~(0x3 << shift);
85         con |= cfg;
86         __raw_writel(con, reg);
87
88         return 0;
89 }
90
91 /*
92  * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
93  * @chip: The gpio chip that is being configured.
94  * @off: The offset for the GPIO being configured.
95  *
96  * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
97  * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
98  * S3C_GPIO_SPECIAL() macro.
99  */
100
101 static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
102                                              unsigned int off)
103 {
104         u32 con;
105
106         con = __raw_readl(chip->base);
107         con >>= off * 2;
108         con &= 3;
109
110         /* this conversion works for IN and OUT as well as special mode */
111         return S3C_GPIO_SPECIAL(con);
112 }
113
114 /*
115  * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
116  * @chip: The gpio chip that is being configured.
117  * @off: The offset for the GPIO being configured.
118  * @cfg: The configuration value to set.
119  *
120  * This helper deal with the GPIO cases where the control register has 4 bits
121  * of control per GPIO, generally in the form of:
122  *      0000 = Input
123  *      0001 = Output
124  *      others = Special functions (dependent on bank)
125  *
126  * Note, since the code to deal with the case where there are two control
127  * registers instead of one, we do not have a separate set of functions for
128  * each case.
129  */
130
131 static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
132                                     unsigned int off, unsigned int cfg)
133 {
134         void __iomem *reg = chip->base;
135         unsigned int shift = (off & 7) * 4;
136         u32 con;
137
138         if (off < 8 && chip->chip.ngpio > 8)
139                 reg -= 4;
140
141         if (samsung_gpio_is_cfg_special(cfg)) {
142                 cfg &= 0xf;
143                 cfg <<= shift;
144         }
145
146         con = __raw_readl(reg);
147         con &= ~(0xf << shift);
148         con |= cfg;
149         __raw_writel(con, reg);
150
151         return 0;
152 }
153
154 /*
155  * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
156  * @chip: The gpio chip that is being configured.
157  * @off: The offset for the GPIO being configured.
158  *
159  * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
160  * register setting into a value the software can use, such as could be passed
161  * to samsung_gpio_setcfg_4bit().
162  *
163  * @sa samsung_gpio_getcfg_2bit
164  */
165
166 static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
167                                          unsigned int off)
168 {
169         void __iomem *reg = chip->base;
170         unsigned int shift = (off & 7) * 4;
171         u32 con;
172
173         if (off < 8 && chip->chip.ngpio > 8)
174                 reg -= 4;
175
176         con = __raw_readl(reg);
177         con >>= shift;
178         con &= 0xf;
179
180         /* this conversion works for IN and OUT as well as special mode */
181         return S3C_GPIO_SPECIAL(con);
182 }
183
184 static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
185                                            int nr_chips)
186 {
187         for (; nr_chips > 0; nr_chips--, chipcfg++) {
188                 if (!chipcfg->set_config)
189                         chipcfg->set_config = samsung_gpio_setcfg_4bit;
190                 if (!chipcfg->get_config)
191                         chipcfg->get_config = samsung_gpio_getcfg_4bit;
192                 if (!chipcfg->set_pull)
193                         chipcfg->set_pull = samsung_gpio_setpull_updown;
194                 if (!chipcfg->get_pull)
195                         chipcfg->get_pull = samsung_gpio_getpull_updown;
196         }
197 }
198
199 static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
200         [0] = {
201                 .cfg_eint       = 0x0,
202         },
203         [1] = {
204                 .cfg_eint       = 0x3,
205         },
206         [2] = {
207                 .cfg_eint       = 0x7,
208         },
209         [3] = {
210                 .cfg_eint       = 0xF,
211         },
212         [4] = {
213                 .cfg_eint       = 0x0,
214                 .set_config     = samsung_gpio_setcfg_2bit,
215                 .get_config     = samsung_gpio_getcfg_2bit,
216         },
217         [5] = {
218                 .cfg_eint       = 0x2,
219                 .set_config     = samsung_gpio_setcfg_2bit,
220                 .get_config     = samsung_gpio_getcfg_2bit,
221         },
222         [6] = {
223                 .cfg_eint       = 0x3,
224                 .set_config     = samsung_gpio_setcfg_2bit,
225                 .get_config     = samsung_gpio_getcfg_2bit,
226         },
227         [7] = {
228                 .set_config     = samsung_gpio_setcfg_2bit,
229                 .get_config     = samsung_gpio_getcfg_2bit,
230         },
231 };
232
233 /*
234  * Default routines for controlling GPIO, based on the original S3C24XX
235  * GPIO functions which deal with the case where each gpio bank of the
236  * chip is as following:
237  *
238  * base + 0x00: Control register, 2 bits per gpio
239  *              gpio n: 2 bits starting at (2*n)
240  *              00 = input, 01 = output, others mean special-function
241  * base + 0x04: Data register, 1 bit per gpio
242  *              bit n: data bit n
243 */
244
245 static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
246 {
247         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
248         void __iomem *base = ourchip->base;
249         unsigned long flags;
250         unsigned long con;
251
252         samsung_gpio_lock(ourchip, flags);
253
254         con = __raw_readl(base + 0x00);
255         con &= ~(3 << (offset * 2));
256
257         __raw_writel(con, base + 0x00);
258
259         samsung_gpio_unlock(ourchip, flags);
260         return 0;
261 }
262
263 static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
264                                        unsigned offset, int value)
265 {
266         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
267         void __iomem *base = ourchip->base;
268         unsigned long flags;
269         unsigned long dat;
270         unsigned long con;
271
272         samsung_gpio_lock(ourchip, flags);
273
274         dat = __raw_readl(base + 0x04);
275         dat &= ~(1 << offset);
276         if (value)
277                 dat |= 1 << offset;
278         __raw_writel(dat, base + 0x04);
279
280         con = __raw_readl(base + 0x00);
281         con &= ~(3 << (offset * 2));
282         con |= 1 << (offset * 2);
283
284         __raw_writel(con, base + 0x00);
285         __raw_writel(dat, base + 0x04);
286
287         samsung_gpio_unlock(ourchip, flags);
288         return 0;
289 }
290
291 /*
292  * The samsung_gpiolib_4bit routines are to control the gpio banks where
293  * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
294  * following example:
295  *
296  * base + 0x00: Control register, 4 bits per gpio
297  *              gpio n: 4 bits starting at (4*n)
298  *              0000 = input, 0001 = output, others mean special-function
299  * base + 0x04: Data register, 1 bit per gpio
300  *              bit n: data bit n
301  *
302  * Note, since the data register is one bit per gpio and is at base + 0x4
303  * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
304  * state of the output.
305  */
306
307 static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
308                                       unsigned int offset)
309 {
310         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
311         void __iomem *base = ourchip->base;
312         unsigned long con;
313
314         con = __raw_readl(base + GPIOCON_OFF);
315         if (ourchip->bitmap_gpio_int & BIT(offset))
316                 con |= 0xf << con_4bit_shift(offset);
317         else
318                 con &= ~(0xf << con_4bit_shift(offset));
319         __raw_writel(con, base + GPIOCON_OFF);
320
321         pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
322
323         return 0;
324 }
325
326 static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
327                                        unsigned int offset, int value)
328 {
329         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
330         void __iomem *base = ourchip->base;
331         unsigned long con;
332         unsigned long dat;
333
334         con = __raw_readl(base + GPIOCON_OFF);
335         con &= ~(0xf << con_4bit_shift(offset));
336         con |= 0x1 << con_4bit_shift(offset);
337
338         dat = __raw_readl(base + GPIODAT_OFF);
339
340         if (value)
341                 dat |= 1 << offset;
342         else
343                 dat &= ~(1 << offset);
344
345         __raw_writel(dat, base + GPIODAT_OFF);
346         __raw_writel(con, base + GPIOCON_OFF);
347         __raw_writel(dat, base + GPIODAT_OFF);
348
349         pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
350
351         return 0;
352 }
353
354 /*
355  * The next set of routines are for the case where the GPIO configuration
356  * registers are 4 bits per GPIO but there is more than one register (the
357  * bank has more than 8 GPIOs.
358  *
359  * This case is the similar to the 4 bit case, but the registers are as
360  * follows:
361  *
362  * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
363  *              gpio n: 4 bits starting at (4*n)
364  *              0000 = input, 0001 = output, others mean special-function
365  * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
366  *              gpio n: 4 bits starting at (4*n)
367  *              0000 = input, 0001 = output, others mean special-function
368  * base + 0x08: Data register, 1 bit per gpio
369  *              bit n: data bit n
370  *
371  * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
372  * routines we store the 'base + 0x4' address so that these routines see
373  * the data register at ourchip->base + 0x04.
374  */
375
376 static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
377                                        unsigned int offset)
378 {
379         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
380         void __iomem *base = ourchip->base;
381         void __iomem *regcon = base;
382         unsigned long con;
383
384         if (offset > 7)
385                 offset -= 8;
386         else
387                 regcon -= 4;
388
389         con = __raw_readl(regcon);
390         con &= ~(0xf << con_4bit_shift(offset));
391         __raw_writel(con, regcon);
392
393         pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
394
395         return 0;
396 }
397
398 static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
399                                         unsigned int offset, int value)
400 {
401         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
402         void __iomem *base = ourchip->base;
403         void __iomem *regcon = base;
404         unsigned long con;
405         unsigned long dat;
406         unsigned con_offset = offset;
407
408         if (con_offset > 7)
409                 con_offset -= 8;
410         else
411                 regcon -= 4;
412
413         con = __raw_readl(regcon);
414         con &= ~(0xf << con_4bit_shift(con_offset));
415         con |= 0x1 << con_4bit_shift(con_offset);
416
417         dat = __raw_readl(base + GPIODAT_OFF);
418
419         if (value)
420                 dat |= 1 << offset;
421         else
422                 dat &= ~(1 << offset);
423
424         __raw_writel(dat, base + GPIODAT_OFF);
425         __raw_writel(con, regcon);
426         __raw_writel(dat, base + GPIODAT_OFF);
427
428         pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
429
430         return 0;
431 }
432
433 static void samsung_gpiolib_set(struct gpio_chip *chip,
434                                 unsigned offset, int value)
435 {
436         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
437         void __iomem *base = ourchip->base;
438         unsigned long flags;
439         unsigned long dat;
440
441         samsung_gpio_lock(ourchip, flags);
442
443         dat = __raw_readl(base + 0x04);
444         dat &= ~(1 << offset);
445         if (value)
446                 dat |= 1 << offset;
447         __raw_writel(dat, base + 0x04);
448
449         samsung_gpio_unlock(ourchip, flags);
450 }
451
452 static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
453 {
454         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
455         unsigned long val;
456
457         val = __raw_readl(ourchip->base + 0x04);
458         val >>= offset;
459         val &= 1;
460
461         return val;
462 }
463
464 /*
465  * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
466  * for use with the configuration calls, and other parts of the s3c gpiolib
467  * support code.
468  *
469  * Not all s3c support code will need this, as some configurations of cpu
470  * may only support one or two different configuration options and have an
471  * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
472  * the machine support file should provide its own samsung_gpiolib_getchip()
473  * and any other necessary functions.
474  */
475
476 #ifdef CONFIG_S3C_GPIO_TRACK
477 struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
478
479 static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
480 {
481         unsigned int gpn;
482         int i;
483
484         gpn = chip->chip.base;
485         for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
486                 BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
487                 s3c_gpios[gpn] = chip;
488         }
489 }
490 #endif /* CONFIG_S3C_GPIO_TRACK */
491
492 /*
493  * samsung_gpiolib_add() - add the Samsung gpio_chip.
494  * @chip: The chip to register
495  *
496  * This is a wrapper to gpiochip_add() that takes our specific gpio chip
497  * information and makes the necessary alterations for the platform and
498  * notes the information for use with the configuration systems and any
499  * other parts of the system.
500  */
501
502 static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
503 {
504         struct gpio_chip *gc = &chip->chip;
505         int ret;
506
507         BUG_ON(!chip->base);
508         BUG_ON(!gc->label);
509         BUG_ON(!gc->ngpio);
510
511         spin_lock_init(&chip->lock);
512
513         if (!gc->direction_input)
514                 gc->direction_input = samsung_gpiolib_2bit_input;
515         if (!gc->direction_output)
516                 gc->direction_output = samsung_gpiolib_2bit_output;
517         if (!gc->set)
518                 gc->set = samsung_gpiolib_set;
519         if (!gc->get)
520                 gc->get = samsung_gpiolib_get;
521
522 #ifdef CONFIG_PM
523         if (chip->pm != NULL) {
524                 if (!chip->pm->save || !chip->pm->resume)
525                         pr_err("gpio: %s has missing PM functions\n",
526                                gc->label);
527         } else
528                 pr_err("gpio: %s has no PM function\n", gc->label);
529 #endif
530
531         /* gpiochip_add() prints own failure message on error. */
532         ret = gpiochip_add_data(gc, chip);
533         if (ret >= 0)
534                 s3c_gpiolib_track(chip);
535 }
536
537 static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
538                                                   int nr_chips, void __iomem *base,
539                                                   unsigned int offset)
540 {
541         int i;
542
543         for (i = 0 ; i < nr_chips; i++, chip++) {
544                 chip->chip.direction_input = samsung_gpiolib_2bit_input;
545                 chip->chip.direction_output = samsung_gpiolib_2bit_output;
546
547                 if (!chip->config)
548                         chip->config = &samsung_gpio_cfgs[7];
549                 if (!chip->pm)
550                         chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
551                 if ((base != NULL) && (chip->base == NULL))
552                         chip->base = base + ((i) * offset);
553
554                 samsung_gpiolib_add(chip);
555         }
556 }
557
558 /*
559  * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
560  * @chip: The gpio chip that is being configured.
561  * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
562  *
563  * This helper deal with the GPIO cases where the control register has 4 bits
564  * of control per GPIO, generally in the form of:
565  * 0000 = Input
566  * 0001 = Output
567  * others = Special functions (dependent on bank)
568  *
569  * Note, since the code to deal with the case where there are two control
570  * registers instead of one, we do not have a separate set of function
571  * (samsung_gpiolib_add_4bit2_chips)for each case.
572  */
573
574 static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
575                                                   int nr_chips, void __iomem *base)
576 {
577         int i;
578
579         for (i = 0 ; i < nr_chips; i++, chip++) {
580                 chip->chip.direction_input = samsung_gpiolib_4bit_input;
581                 chip->chip.direction_output = samsung_gpiolib_4bit_output;
582
583                 if (!chip->config)
584                         chip->config = &samsung_gpio_cfgs[2];
585                 if (!chip->pm)
586                         chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
587                 if ((base != NULL) && (chip->base == NULL))
588                         chip->base = base + ((i) * 0x20);
589
590                 chip->bitmap_gpio_int = 0;
591
592                 samsung_gpiolib_add(chip);
593         }
594 }
595
596 static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
597                                                    int nr_chips)
598 {
599         for (; nr_chips > 0; nr_chips--, chip++) {
600                 chip->chip.direction_input = samsung_gpiolib_4bit2_input;
601                 chip->chip.direction_output = samsung_gpiolib_4bit2_output;
602
603                 if (!chip->config)
604                         chip->config = &samsung_gpio_cfgs[2];
605                 if (!chip->pm)
606                         chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
607
608                 samsung_gpiolib_add(chip);
609         }
610 }
611
612 int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
613 {
614         struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
615
616         return samsung_chip->irq_base + offset;
617 }
618
619 static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
620 {
621         return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
622 }
623
624 static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
625 {
626         return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
627 }
628
629 /*
630  * GPIO bank summary:
631  *
632  * Bank GPIOs   Style   SlpCon  ExtInt Group
633  * A    8       4Bit    Yes     1
634  * B    7       4Bit    Yes     1
635  * C    8       4Bit    Yes     2
636  * D    5       4Bit    Yes     3
637  * E    5       4Bit    Yes     None
638  * F    16      2Bit    Yes     4 [1]
639  * G    7       4Bit    Yes     5
640  * H    10      4Bit[2] Yes     6
641  * I    16      2Bit    Yes     None
642  * J    12      2Bit    Yes     None
643  * K    16      4Bit[2] No      None
644  * L    15      4Bit[2] No      None
645  * M    6       4Bit    No      IRQ_EINT
646  * N    16      2Bit    No      IRQ_EINT
647  * O    16      2Bit    Yes     7
648  * P    15      2Bit    Yes     8
649  * Q    9       2Bit    Yes     9
650  *
651  * [1] BANKF pins 14,15 do not form part of the external interrupt sources
652  * [2] BANK has two control registers, GPxCON0 and GPxCON1
653  */
654
655 static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
656         {
657                 .chip   = {
658                         .base   = S3C64XX_GPA(0),
659                         .ngpio  = S3C64XX_GPIO_A_NR,
660                         .label  = "GPA",
661                 },
662         }, {
663                 .chip   = {
664                         .base   = S3C64XX_GPB(0),
665                         .ngpio  = S3C64XX_GPIO_B_NR,
666                         .label  = "GPB",
667                 },
668         }, {
669                 .chip   = {
670                         .base   = S3C64XX_GPC(0),
671                         .ngpio  = S3C64XX_GPIO_C_NR,
672                         .label  = "GPC",
673                 },
674         }, {
675                 .chip   = {
676                         .base   = S3C64XX_GPD(0),
677                         .ngpio  = S3C64XX_GPIO_D_NR,
678                         .label  = "GPD",
679                 },
680         }, {
681                 .config = &samsung_gpio_cfgs[0],
682                 .chip   = {
683                         .base   = S3C64XX_GPE(0),
684                         .ngpio  = S3C64XX_GPIO_E_NR,
685                         .label  = "GPE",
686                 },
687         }, {
688                 .base   = S3C64XX_GPG_BASE,
689                 .chip   = {
690                         .base   = S3C64XX_GPG(0),
691                         .ngpio  = S3C64XX_GPIO_G_NR,
692                         .label  = "GPG",
693                 },
694         }, {
695                 .base   = S3C64XX_GPM_BASE,
696                 .config = &samsung_gpio_cfgs[1],
697                 .chip   = {
698                         .base   = S3C64XX_GPM(0),
699                         .ngpio  = S3C64XX_GPIO_M_NR,
700                         .label  = "GPM",
701                         .to_irq = s3c64xx_gpiolib_mbank_to_irq,
702                 },
703         },
704 };
705
706 static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
707         {
708                 .base   = S3C64XX_GPH_BASE + 0x4,
709                 .chip   = {
710                         .base   = S3C64XX_GPH(0),
711                         .ngpio  = S3C64XX_GPIO_H_NR,
712                         .label  = "GPH",
713                 },
714         }, {
715                 .base   = S3C64XX_GPK_BASE + 0x4,
716                 .config = &samsung_gpio_cfgs[0],
717                 .chip   = {
718                         .base   = S3C64XX_GPK(0),
719                         .ngpio  = S3C64XX_GPIO_K_NR,
720                         .label  = "GPK",
721                 },
722         }, {
723                 .base   = S3C64XX_GPL_BASE + 0x4,
724                 .config = &samsung_gpio_cfgs[1],
725                 .chip   = {
726                         .base   = S3C64XX_GPL(0),
727                         .ngpio  = S3C64XX_GPIO_L_NR,
728                         .label  = "GPL",
729                         .to_irq = s3c64xx_gpiolib_lbank_to_irq,
730                 },
731         },
732 };
733
734 static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
735         {
736                 .base   = S3C64XX_GPF_BASE,
737                 .config = &samsung_gpio_cfgs[6],
738                 .chip   = {
739                         .base   = S3C64XX_GPF(0),
740                         .ngpio  = S3C64XX_GPIO_F_NR,
741                         .label  = "GPF",
742                 },
743         }, {
744                 .config = &samsung_gpio_cfgs[7],
745                 .chip   = {
746                         .base   = S3C64XX_GPI(0),
747                         .ngpio  = S3C64XX_GPIO_I_NR,
748                         .label  = "GPI",
749                 },
750         }, {
751                 .config = &samsung_gpio_cfgs[7],
752                 .chip   = {
753                         .base   = S3C64XX_GPJ(0),
754                         .ngpio  = S3C64XX_GPIO_J_NR,
755                         .label  = "GPJ",
756                 },
757         }, {
758                 .config = &samsung_gpio_cfgs[6],
759                 .chip   = {
760                         .base   = S3C64XX_GPO(0),
761                         .ngpio  = S3C64XX_GPIO_O_NR,
762                         .label  = "GPO",
763                 },
764         }, {
765                 .config = &samsung_gpio_cfgs[6],
766                 .chip   = {
767                         .base   = S3C64XX_GPP(0),
768                         .ngpio  = S3C64XX_GPIO_P_NR,
769                         .label  = "GPP",
770                 },
771         }, {
772                 .config = &samsung_gpio_cfgs[6],
773                 .chip   = {
774                         .base   = S3C64XX_GPQ(0),
775                         .ngpio  = S3C64XX_GPIO_Q_NR,
776                         .label  = "GPQ",
777                 },
778         }, {
779                 .base   = S3C64XX_GPN_BASE,
780                 .irq_base = IRQ_EINT(0),
781                 .config = &samsung_gpio_cfgs[5],
782                 .chip   = {
783                         .base   = S3C64XX_GPN(0),
784                         .ngpio  = S3C64XX_GPIO_N_NR,
785                         .label  = "GPN",
786                         .to_irq = samsung_gpiolib_to_irq,
787                 },
788         },
789 };
790
791 /* TODO: cleanup soc_is_* */
792 static __init int samsung_gpiolib_init(void)
793 {
794         /*
795          * Currently there are two drivers that can provide GPIO support for
796          * Samsung SoCs. For device tree enabled platforms, the new
797          * pinctrl-samsung driver is used, providing both GPIO and pin control
798          * interfaces. For legacy (non-DT) platforms this driver is used.
799          */
800         if (of_have_populated_dt())
801                 return 0;
802
803         if (soc_is_s3c64xx()) {
804                 samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
805                                 ARRAY_SIZE(samsung_gpio_cfgs));
806                 samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
807                                 ARRAY_SIZE(s3c64xx_gpios_2bit),
808                                 S3C64XX_VA_GPIO + 0xE0, 0x20);
809                 samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
810                                 ARRAY_SIZE(s3c64xx_gpios_4bit),
811                                 S3C64XX_VA_GPIO);
812                 samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
813                                 ARRAY_SIZE(s3c64xx_gpios_4bit2));
814         }
815
816         return 0;
817 }
818 core_initcall(samsung_gpiolib_init);
819
820 int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
821 {
822         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
823         unsigned long flags;
824         int offset;
825         int ret;
826
827         if (!chip)
828                 return -EINVAL;
829
830         offset = pin - chip->chip.base;
831
832         samsung_gpio_lock(chip, flags);
833         ret = samsung_gpio_do_setcfg(chip, offset, config);
834         samsung_gpio_unlock(chip, flags);
835
836         return ret;
837 }
838 EXPORT_SYMBOL(s3c_gpio_cfgpin);
839
840 int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
841                           unsigned int cfg)
842 {
843         int ret;
844
845         for (; nr > 0; nr--, start++) {
846                 ret = s3c_gpio_cfgpin(start, cfg);
847                 if (ret != 0)
848                         return ret;
849         }
850
851         return 0;
852 }
853 EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
854
855 int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
856                           unsigned int cfg, samsung_gpio_pull_t pull)
857 {
858         int ret;
859
860         for (; nr > 0; nr--, start++) {
861                 s3c_gpio_setpull(start, pull);
862                 ret = s3c_gpio_cfgpin(start, cfg);
863                 if (ret != 0)
864                         return ret;
865         }
866
867         return 0;
868 }
869 EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
870
871 int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
872 {
873         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
874         unsigned long flags;
875         int offset, ret;
876
877         if (!chip)
878                 return -EINVAL;
879
880         offset = pin - chip->chip.base;
881
882         samsung_gpio_lock(chip, flags);
883         ret = samsung_gpio_do_setpull(chip, offset, pull);
884         samsung_gpio_unlock(chip, flags);
885
886         return ret;
887 }
888 EXPORT_SYMBOL(s3c_gpio_setpull);
This page took 0.08789 seconds and 4 git commands to generate.