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 <ben@simtec.co.uk>
9 // http://armlinux.simtec.co.uk/
10 //
11 // Samsung - GPIOlib support
12
13 #include <linux/kernel.h>
14 #include <linux/gpio/driver.h>
15 #include <linux/irq.h>
16 #include <linux/io.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
samsung_gpio_setpull_updown(struct samsung_gpio_chip * chip,unsigned int off,samsung_gpio_pull_t pull)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
samsung_gpio_getpull_updown(struct samsung_gpio_chip * chip,unsigned int off)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
samsung_gpio_setcfg_2bit(struct samsung_gpio_chip * chip,unsigned int off,unsigned int cfg)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
samsung_gpio_getcfg_2bit(struct samsung_gpio_chip * chip,unsigned int off)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
samsung_gpio_setcfg_4bit(struct samsung_gpio_chip * chip,unsigned int off,unsigned int cfg)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
samsung_gpio_getcfg_4bit(struct samsung_gpio_chip * chip,unsigned int off)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
samsung_gpiolib_set_cfg(struct samsung_gpio_cfg * chipcfg,int nr_chips)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
samsung_gpiolib_2bit_input(struct gpio_chip * chip,unsigned offset)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
samsung_gpiolib_2bit_output(struct gpio_chip * chip,unsigned offset,int value)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
samsung_gpiolib_4bit_input(struct gpio_chip * chip,unsigned int offset)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
samsung_gpiolib_4bit_output(struct gpio_chip * chip,unsigned int offset,int value)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
samsung_gpiolib_4bit2_input(struct gpio_chip * chip,unsigned int offset)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
samsung_gpiolib_4bit2_output(struct gpio_chip * chip,unsigned int offset,int value)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
samsung_gpiolib_set(struct gpio_chip * chip,unsigned int offset,int value)433 static int samsung_gpiolib_set(struct gpio_chip *chip, unsigned int offset,
434 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 return 0;
452 }
453
samsung_gpiolib_get(struct gpio_chip * chip,unsigned offset)454 static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
455 {
456 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
457 unsigned long val;
458
459 val = __raw_readl(ourchip->base + 0x04);
460 val >>= offset;
461 val &= 1;
462
463 return val;
464 }
465
466 /*
467 * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
468 * for use with the configuration calls, and other parts of the s3c gpiolib
469 * support code.
470 *
471 * Not all s3c support code will need this, as some configurations of cpu
472 * may only support one or two different configuration options and have an
473 * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
474 * the machine support file should provide its own samsung_gpiolib_getchip()
475 * and any other necessary functions.
476 */
477
478 #ifdef CONFIG_S3C_GPIO_TRACK
479 struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
480
s3c_gpiolib_track(struct samsung_gpio_chip * chip)481 static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
482 {
483 unsigned int gpn;
484 int i;
485
486 gpn = chip->chip.base;
487 for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
488 BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
489 s3c_gpios[gpn] = chip;
490 }
491 }
492 #endif /* CONFIG_S3C_GPIO_TRACK */
493
494 /*
495 * samsung_gpiolib_add() - add the Samsung gpio_chip.
496 * @chip: The chip to register
497 *
498 * This is a wrapper to gpiochip_add() that takes our specific gpio chip
499 * information and makes the necessary alterations for the platform and
500 * notes the information for use with the configuration systems and any
501 * other parts of the system.
502 */
503
samsung_gpiolib_add(struct samsung_gpio_chip * chip)504 static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
505 {
506 struct gpio_chip *gc = &chip->chip;
507 int ret;
508
509 BUG_ON(!chip->base);
510 BUG_ON(!gc->label);
511 BUG_ON(!gc->ngpio);
512
513 spin_lock_init(&chip->lock);
514
515 if (!gc->direction_input)
516 gc->direction_input = samsung_gpiolib_2bit_input;
517 if (!gc->direction_output)
518 gc->direction_output = samsung_gpiolib_2bit_output;
519 if (!gc->set)
520 gc->set_rv = samsung_gpiolib_set;
521 if (!gc->get)
522 gc->get = samsung_gpiolib_get;
523
524 #ifdef CONFIG_PM
525 if (chip->pm != NULL) {
526 if (!chip->pm->save || !chip->pm->resume)
527 pr_err("gpio: %s has missing PM functions\n",
528 gc->label);
529 } else
530 pr_err("gpio: %s has no PM function\n", gc->label);
531 #endif
532
533 /* gpiochip_add() prints own failure message on error. */
534 ret = gpiochip_add_data(gc, chip);
535 if (ret >= 0)
536 s3c_gpiolib_track(chip);
537 }
538
samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip * chip,int nr_chips,void __iomem * base,unsigned int offset)539 static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
540 int nr_chips, void __iomem *base,
541 unsigned int offset)
542 {
543 int i;
544
545 for (i = 0 ; i < nr_chips; i++, chip++) {
546 chip->chip.direction_input = samsung_gpiolib_2bit_input;
547 chip->chip.direction_output = samsung_gpiolib_2bit_output;
548
549 if (!chip->config)
550 chip->config = &samsung_gpio_cfgs[7];
551 if (!chip->pm)
552 chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
553 if ((base != NULL) && (chip->base == NULL))
554 chip->base = base + ((i) * offset);
555
556 samsung_gpiolib_add(chip);
557 }
558 }
559
560 /*
561 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
562 * @chip: The gpio chip that is being configured.
563 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
564 *
565 * This helper deal with the GPIO cases where the control register has 4 bits
566 * of control per GPIO, generally in the form of:
567 * 0000 = Input
568 * 0001 = Output
569 * others = Special functions (dependent on bank)
570 *
571 * Note, since the code to deal with the case where there are two control
572 * registers instead of one, we do not have a separate set of function
573 * (samsung_gpiolib_add_4bit2_chips)for each case.
574 */
575
samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip * chip,int nr_chips,void __iomem * base)576 static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
577 int nr_chips, void __iomem *base)
578 {
579 int i;
580
581 for (i = 0 ; i < nr_chips; i++, chip++) {
582 chip->chip.direction_input = samsung_gpiolib_4bit_input;
583 chip->chip.direction_output = samsung_gpiolib_4bit_output;
584
585 if (!chip->config)
586 chip->config = &samsung_gpio_cfgs[2];
587 if (!chip->pm)
588 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
589 if ((base != NULL) && (chip->base == NULL))
590 chip->base = base + ((i) * 0x20);
591
592 chip->bitmap_gpio_int = 0;
593
594 samsung_gpiolib_add(chip);
595 }
596 }
597
samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip * chip,int nr_chips)598 static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
599 int nr_chips)
600 {
601 for (; nr_chips > 0; nr_chips--, chip++) {
602 chip->chip.direction_input = samsung_gpiolib_4bit2_input;
603 chip->chip.direction_output = samsung_gpiolib_4bit2_output;
604
605 if (!chip->config)
606 chip->config = &samsung_gpio_cfgs[2];
607 if (!chip->pm)
608 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
609
610 samsung_gpiolib_add(chip);
611 }
612 }
613
samsung_gpiolib_to_irq(struct gpio_chip * chip,unsigned int offset)614 int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
615 {
616 struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
617
618 return samsung_chip->irq_base + offset;
619 }
620
s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip * chip,unsigned pin)621 static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
622 {
623 return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
624 }
625
s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip * chip,unsigned pin)626 static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
627 {
628 return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
629 }
630
631 /*
632 * GPIO bank summary:
633 *
634 * Bank GPIOs Style SlpCon ExtInt Group
635 * A 8 4Bit Yes 1
636 * B 7 4Bit Yes 1
637 * C 8 4Bit Yes 2
638 * D 5 4Bit Yes 3
639 * E 5 4Bit Yes None
640 * F 16 2Bit Yes 4 [1]
641 * G 7 4Bit Yes 5
642 * H 10 4Bit[2] Yes 6
643 * I 16 2Bit Yes None
644 * J 12 2Bit Yes None
645 * K 16 4Bit[2] No None
646 * L 15 4Bit[2] No None
647 * M 6 4Bit No IRQ_EINT
648 * N 16 2Bit No IRQ_EINT
649 * O 16 2Bit Yes 7
650 * P 15 2Bit Yes 8
651 * Q 9 2Bit Yes 9
652 *
653 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
654 * [2] BANK has two control registers, GPxCON0 and GPxCON1
655 */
656
657 static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
658 {
659 .chip = {
660 .base = S3C64XX_GPA(0),
661 .ngpio = S3C64XX_GPIO_A_NR,
662 .label = "GPA",
663 },
664 }, {
665 .chip = {
666 .base = S3C64XX_GPB(0),
667 .ngpio = S3C64XX_GPIO_B_NR,
668 .label = "GPB",
669 },
670 }, {
671 .chip = {
672 .base = S3C64XX_GPC(0),
673 .ngpio = S3C64XX_GPIO_C_NR,
674 .label = "GPC",
675 },
676 }, {
677 .chip = {
678 .base = S3C64XX_GPD(0),
679 .ngpio = S3C64XX_GPIO_D_NR,
680 .label = "GPD",
681 },
682 }, {
683 .config = &samsung_gpio_cfgs[0],
684 .chip = {
685 .base = S3C64XX_GPE(0),
686 .ngpio = S3C64XX_GPIO_E_NR,
687 .label = "GPE",
688 },
689 }, {
690 .base = S3C64XX_GPG_BASE,
691 .chip = {
692 .base = S3C64XX_GPG(0),
693 .ngpio = S3C64XX_GPIO_G_NR,
694 .label = "GPG",
695 },
696 }, {
697 .base = S3C64XX_GPM_BASE,
698 .config = &samsung_gpio_cfgs[1],
699 .chip = {
700 .base = S3C64XX_GPM(0),
701 .ngpio = S3C64XX_GPIO_M_NR,
702 .label = "GPM",
703 .to_irq = s3c64xx_gpiolib_mbank_to_irq,
704 },
705 },
706 };
707
708 static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
709 {
710 .base = S3C64XX_GPH_BASE + 0x4,
711 .chip = {
712 .base = S3C64XX_GPH(0),
713 .ngpio = S3C64XX_GPIO_H_NR,
714 .label = "GPH",
715 },
716 }, {
717 .base = S3C64XX_GPK_BASE + 0x4,
718 .config = &samsung_gpio_cfgs[0],
719 .chip = {
720 .base = S3C64XX_GPK(0),
721 .ngpio = S3C64XX_GPIO_K_NR,
722 .label = "GPK",
723 },
724 }, {
725 .base = S3C64XX_GPL_BASE + 0x4,
726 .config = &samsung_gpio_cfgs[1],
727 .chip = {
728 .base = S3C64XX_GPL(0),
729 .ngpio = S3C64XX_GPIO_L_NR,
730 .label = "GPL",
731 .to_irq = s3c64xx_gpiolib_lbank_to_irq,
732 },
733 },
734 };
735
736 static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
737 {
738 .base = S3C64XX_GPF_BASE,
739 .config = &samsung_gpio_cfgs[6],
740 .chip = {
741 .base = S3C64XX_GPF(0),
742 .ngpio = S3C64XX_GPIO_F_NR,
743 .label = "GPF",
744 },
745 }, {
746 .config = &samsung_gpio_cfgs[7],
747 .chip = {
748 .base = S3C64XX_GPI(0),
749 .ngpio = S3C64XX_GPIO_I_NR,
750 .label = "GPI",
751 },
752 }, {
753 .config = &samsung_gpio_cfgs[7],
754 .chip = {
755 .base = S3C64XX_GPJ(0),
756 .ngpio = S3C64XX_GPIO_J_NR,
757 .label = "GPJ",
758 },
759 }, {
760 .config = &samsung_gpio_cfgs[6],
761 .chip = {
762 .base = S3C64XX_GPO(0),
763 .ngpio = S3C64XX_GPIO_O_NR,
764 .label = "GPO",
765 },
766 }, {
767 .config = &samsung_gpio_cfgs[6],
768 .chip = {
769 .base = S3C64XX_GPP(0),
770 .ngpio = S3C64XX_GPIO_P_NR,
771 .label = "GPP",
772 },
773 }, {
774 .config = &samsung_gpio_cfgs[6],
775 .chip = {
776 .base = S3C64XX_GPQ(0),
777 .ngpio = S3C64XX_GPIO_Q_NR,
778 .label = "GPQ",
779 },
780 }, {
781 .base = S3C64XX_GPN_BASE,
782 .irq_base = IRQ_EINT(0),
783 .config = &samsung_gpio_cfgs[5],
784 .chip = {
785 .base = S3C64XX_GPN(0),
786 .ngpio = S3C64XX_GPIO_N_NR,
787 .label = "GPN",
788 .to_irq = samsung_gpiolib_to_irq,
789 },
790 },
791 };
792
793 /* TODO: cleanup soc_is_* */
samsung_gpiolib_init(void)794 static __init int samsung_gpiolib_init(void)
795 {
796 /*
797 * Currently there are two drivers that can provide GPIO support for
798 * Samsung SoCs. For device tree enabled platforms, the new
799 * pinctrl-samsung driver is used, providing both GPIO and pin control
800 * interfaces. For legacy (non-DT) platforms this driver is used.
801 */
802 if (of_have_populated_dt())
803 return 0;
804
805 if (soc_is_s3c64xx()) {
806 samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
807 ARRAY_SIZE(samsung_gpio_cfgs));
808 samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
809 ARRAY_SIZE(s3c64xx_gpios_2bit),
810 S3C64XX_VA_GPIO + 0xE0, 0x20);
811 samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
812 ARRAY_SIZE(s3c64xx_gpios_4bit),
813 S3C64XX_VA_GPIO);
814 samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
815 ARRAY_SIZE(s3c64xx_gpios_4bit2));
816 }
817
818 return 0;
819 }
820 core_initcall(samsung_gpiolib_init);
821
s3c_gpio_cfgpin(unsigned int pin,unsigned int config)822 int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
823 {
824 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
825 unsigned long flags;
826 int offset;
827 int ret;
828
829 if (!chip)
830 return -EINVAL;
831
832 offset = pin - chip->chip.base;
833
834 samsung_gpio_lock(chip, flags);
835 ret = samsung_gpio_do_setcfg(chip, offset, config);
836 samsung_gpio_unlock(chip, flags);
837
838 return ret;
839 }
840 EXPORT_SYMBOL(s3c_gpio_cfgpin);
841
s3c_gpio_cfgpin_range(unsigned int start,unsigned int nr,unsigned int cfg)842 int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
843 unsigned int cfg)
844 {
845 int ret;
846
847 for (; nr > 0; nr--, start++) {
848 ret = s3c_gpio_cfgpin(start, cfg);
849 if (ret != 0)
850 return ret;
851 }
852
853 return 0;
854 }
855 EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
856
s3c_gpio_cfgall_range(unsigned int start,unsigned int nr,unsigned int cfg,samsung_gpio_pull_t pull)857 int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
858 unsigned int cfg, samsung_gpio_pull_t pull)
859 {
860 int ret;
861
862 for (; nr > 0; nr--, start++) {
863 s3c_gpio_setpull(start, pull);
864 ret = s3c_gpio_cfgpin(start, cfg);
865 if (ret != 0)
866 return ret;
867 }
868
869 return 0;
870 }
871 EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
872
s3c_gpio_setpull(unsigned int pin,samsung_gpio_pull_t pull)873 int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
874 {
875 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
876 unsigned long flags;
877 int offset, ret;
878
879 if (!chip)
880 return -EINVAL;
881
882 offset = pin - chip->chip.base;
883
884 samsung_gpio_lock(chip, flags);
885 ret = samsung_gpio_do_setpull(chip, offset, pull);
886 samsung_gpio_unlock(chip, flags);
887
888 return ret;
889 }
890 EXPORT_SYMBOL(s3c_gpio_setpull);
891