gpio: samsung: Remove hardware.h inclusion
[deliverable/linux.git] / drivers / gpio / gpio-samsung.c
CommitLineData
1b39d5f2
KK
1/*
2 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * Copyright 2008 Openmoko, Inc.
6 * Copyright 2008 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 * http://armlinux.simtec.co.uk/
9 *
10 * SAMSUNG - GPIOlib support
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/kernel.h>
18#include <linux/irq.h>
19#include <linux/io.h>
20#include <linux/gpio.h>
21#include <linux/init.h>
22#include <linux/spinlock.h>
23#include <linux/module.h>
24#include <linux/interrupt.h>
edbaa603 25#include <linux/device.h>
1b39d5f2 26#include <linux/ioport.h>
659d73ad
TA
27#include <linux/of.h>
28#include <linux/slab.h>
29#include <linux/of_address.h>
c67d0f29
LW
30#ifdef CONFIG_ARCH_S3C24XX
31#include <linux/platform_data/gpio-samsung-s3c24xx.h>
32#endif
41c3548e
LW
33#ifdef CONFIG_ARCH_S3C64XX
34#include <linux/platform_data/gpio-samsung-s3c64xx.h>
35#endif
1b39d5f2
KK
36
37#include <asm/irq.h>
38
1b39d5f2 39#include <mach/map.h>
1b39d5f2
KK
40#include <mach/regs-gpio.h>
41
42#include <plat/cpu.h>
43#include <plat/gpio-core.h>
44#include <plat/gpio-cfg.h>
45#include <plat/gpio-cfg-helpers.h>
1b39d5f2
KK
46#include <plat/pm.h>
47
1b39d5f2
KK
48int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
49 unsigned int off, samsung_gpio_pull_t pull)
50{
51 void __iomem *reg = chip->base + 0x08;
52 int shift = off * 2;
53 u32 pup;
54
55 pup = __raw_readl(reg);
56 pup &= ~(3 << shift);
57 pup |= pull << shift;
58 __raw_writel(pup, reg);
59
60 return 0;
61}
62
63samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
64 unsigned int off)
65{
66 void __iomem *reg = chip->base + 0x08;
67 int shift = off * 2;
68 u32 pup = __raw_readl(reg);
69
70 pup >>= shift;
71 pup &= 0x3;
72
73 return (__force samsung_gpio_pull_t)pup;
74}
75
76int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
77 unsigned int off, samsung_gpio_pull_t pull)
78{
79 switch (pull) {
80 case S3C_GPIO_PULL_NONE:
81 pull = 0x01;
82 break;
83 case S3C_GPIO_PULL_UP:
84 pull = 0x00;
85 break;
86 case S3C_GPIO_PULL_DOWN:
87 pull = 0x02;
88 break;
89 }
90 return samsung_gpio_setpull_updown(chip, off, pull);
91}
92
93samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
94 unsigned int off)
95{
96 samsung_gpio_pull_t pull;
97
98 pull = samsung_gpio_getpull_updown(chip, off);
99
100 switch (pull) {
101 case 0x00:
102 pull = S3C_GPIO_PULL_UP;
103 break;
104 case 0x01:
105 case 0x03:
106 pull = S3C_GPIO_PULL_NONE;
107 break;
108 case 0x02:
109 pull = S3C_GPIO_PULL_DOWN;
110 break;
111 }
112
113 return pull;
114}
115
116static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
117 unsigned int off, samsung_gpio_pull_t pull,
118 samsung_gpio_pull_t updown)
119{
120 void __iomem *reg = chip->base + 0x08;
121 u32 pup = __raw_readl(reg);
122
123 if (pull == updown)
124 pup &= ~(1 << off);
125 else if (pull == S3C_GPIO_PULL_NONE)
126 pup |= (1 << off);
127 else
128 return -EINVAL;
129
130 __raw_writel(pup, reg);
131 return 0;
132}
133
134static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
135 unsigned int off,
136 samsung_gpio_pull_t updown)
137{
138 void __iomem *reg = chip->base + 0x08;
139 u32 pup = __raw_readl(reg);
140
141 pup &= (1 << off);
142 return pup ? S3C_GPIO_PULL_NONE : updown;
143}
144
145samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
146 unsigned int off)
147{
148 return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
149}
150
151int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
152 unsigned int off, samsung_gpio_pull_t pull)
153{
154 return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
155}
156
157samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
158 unsigned int off)
159{
160 return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
161}
162
163int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
164 unsigned int off, samsung_gpio_pull_t pull)
165{
166 return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
167}
168
1b39d5f2
KK
169/*
170 * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
171 * @chip: The gpio chip that is being configured.
172 * @off: The offset for the GPIO being configured.
173 * @cfg: The configuration value to set.
174 *
175 * This helper deal with the GPIO cases where the control register
176 * has two bits of configuration per gpio, which have the following
177 * functions:
178 * 00 = input
179 * 01 = output
180 * 1x = special function
181 */
182
183static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
184 unsigned int off, unsigned int cfg)
185{
186 void __iomem *reg = chip->base;
187 unsigned int shift = off * 2;
188 u32 con;
189
190 if (samsung_gpio_is_cfg_special(cfg)) {
191 cfg &= 0xf;
192 if (cfg > 3)
193 return -EINVAL;
194
195 cfg <<= shift;
196 }
197
198 con = __raw_readl(reg);
199 con &= ~(0x3 << shift);
200 con |= cfg;
201 __raw_writel(con, reg);
202
203 return 0;
204}
205
206/*
207 * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
208 * @chip: The gpio chip that is being configured.
209 * @off: The offset for the GPIO being configured.
210 *
f1347599 211 * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
1b39d5f2
KK
212 * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
213 * S3C_GPIO_SPECIAL() macro.
214 */
215
216static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
217 unsigned int off)
218{
219 u32 con;
220
221 con = __raw_readl(chip->base);
222 con >>= off * 2;
223 con &= 3;
224
225 /* this conversion works for IN and OUT as well as special mode */
226 return S3C_GPIO_SPECIAL(con);
227}
228
229/*
230 * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
231 * @chip: The gpio chip that is being configured.
232 * @off: The offset for the GPIO being configured.
233 * @cfg: The configuration value to set.
234 *
235 * This helper deal with the GPIO cases where the control register has 4 bits
236 * of control per GPIO, generally in the form of:
237 * 0000 = Input
238 * 0001 = Output
239 * others = Special functions (dependent on bank)
240 *
241 * Note, since the code to deal with the case where there are two control
242 * registers instead of one, we do not have a separate set of functions for
243 * each case.
244 */
245
246static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
247 unsigned int off, unsigned int cfg)
248{
249 void __iomem *reg = chip->base;
250 unsigned int shift = (off & 7) * 4;
251 u32 con;
252
253 if (off < 8 && chip->chip.ngpio > 8)
254 reg -= 4;
255
256 if (samsung_gpio_is_cfg_special(cfg)) {
257 cfg &= 0xf;
258 cfg <<= shift;
259 }
260
261 con = __raw_readl(reg);
262 con &= ~(0xf << shift);
263 con |= cfg;
264 __raw_writel(con, reg);
265
266 return 0;
267}
268
269/*
270 * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
271 * @chip: The gpio chip that is being configured.
272 * @off: The offset for the GPIO being configured.
273 *
274 * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
275 * register setting into a value the software can use, such as could be passed
276 * to samsung_gpio_setcfg_4bit().
277 *
278 * @sa samsung_gpio_getcfg_2bit
279 */
280
281static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
282 unsigned int off)
283{
284 void __iomem *reg = chip->base;
285 unsigned int shift = (off & 7) * 4;
286 u32 con;
287
288 if (off < 8 && chip->chip.ngpio > 8)
289 reg -= 4;
290
291 con = __raw_readl(reg);
292 con >>= shift;
293 con &= 0xf;
294
295 /* this conversion works for IN and OUT as well as special mode */
296 return S3C_GPIO_SPECIAL(con);
297}
298
c034b184 299#ifdef CONFIG_PLAT_S3C24XX
1b39d5f2
KK
300/*
301 * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
302 * @chip: The gpio chip that is being configured.
303 * @off: The offset for the GPIO being configured.
304 * @cfg: The configuration value to set.
305 *
306 * This helper deal with the GPIO cases where the control register
307 * has one bit of configuration for the gpio, where setting the bit
308 * means the pin is in special function mode and unset means output.
309 */
310
311static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
312 unsigned int off, unsigned int cfg)
313{
314 void __iomem *reg = chip->base;
315 unsigned int shift = off;
316 u32 con;
317
318 if (samsung_gpio_is_cfg_special(cfg)) {
319 cfg &= 0xf;
320
321 /* Map output to 0, and SFN2 to 1 */
322 cfg -= 1;
323 if (cfg > 1)
324 return -EINVAL;
325
326 cfg <<= shift;
327 }
328
329 con = __raw_readl(reg);
330 con &= ~(0x1 << shift);
331 con |= cfg;
332 __raw_writel(con, reg);
333
334 return 0;
335}
336
337/*
338 * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
339 * @chip: The gpio chip that is being configured.
340 * @off: The offset for the GPIO being configured.
341 *
342 * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
343 * GPIO configuration value.
344 *
345 * @sa samsung_gpio_getcfg_2bit
346 * @sa samsung_gpio_getcfg_4bit
347 */
348
349static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
350 unsigned int off)
351{
352 u32 con;
353
354 con = __raw_readl(chip->base);
355 con >>= off;
356 con &= 1;
357 con++;
358
359 return S3C_GPIO_SFN(con);
360}
c034b184 361#endif
1b39d5f2 362
c034b184 363#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
1b39d5f2
KK
364static int s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip *chip,
365 unsigned int off, unsigned int cfg)
366{
367 void __iomem *reg = chip->base;
368 unsigned int shift;
369 u32 con;
370
371 switch (off) {
372 case 0:
373 case 1:
374 case 2:
375 case 3:
376 case 4:
377 case 5:
378 shift = (off & 7) * 4;
379 reg -= 4;
380 break;
381 case 6:
382 shift = ((off + 1) & 7) * 4;
383 reg -= 4;
384 default:
385 shift = ((off + 1) & 7) * 4;
386 break;
387 }
388
389 if (samsung_gpio_is_cfg_special(cfg)) {
390 cfg &= 0xf;
391 cfg <<= shift;
392 }
393
394 con = __raw_readl(reg);
395 con &= ~(0xf << shift);
396 con |= cfg;
397 __raw_writel(con, reg);
398
399 return 0;
400}
c034b184 401#endif
1b39d5f2
KK
402
403static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
404 int nr_chips)
405{
406 for (; nr_chips > 0; nr_chips--, chipcfg++) {
407 if (!chipcfg->set_config)
408 chipcfg->set_config = samsung_gpio_setcfg_4bit;
409 if (!chipcfg->get_config)
410 chipcfg->get_config = samsung_gpio_getcfg_4bit;
411 if (!chipcfg->set_pull)
412 chipcfg->set_pull = samsung_gpio_setpull_updown;
413 if (!chipcfg->get_pull)
414 chipcfg->get_pull = samsung_gpio_getpull_updown;
415 }
416}
417
418struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
419 .set_config = samsung_gpio_setcfg_2bit,
420 .get_config = samsung_gpio_getcfg_2bit,
421};
422
c034b184 423#ifdef CONFIG_PLAT_S3C24XX
1b39d5f2
KK
424static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
425 .set_config = s3c24xx_gpio_setcfg_abank,
426 .get_config = s3c24xx_gpio_getcfg_abank,
427};
c034b184 428#endif
1b39d5f2 429
c034b184 430#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
1b39d5f2
KK
431static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = {
432 .cfg_eint = 0x3,
433 .set_config = s5p64x0_gpio_setcfg_rbank,
434 .get_config = samsung_gpio_getcfg_4bit,
435 .set_pull = samsung_gpio_setpull_updown,
436 .get_pull = samsung_gpio_getpull_updown,
437};
c034b184 438#endif
1b39d5f2
KK
439
440static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
2985479f 441 [0] = {
1b39d5f2 442 .cfg_eint = 0x0,
2985479f
MB
443 },
444 [1] = {
1b39d5f2 445 .cfg_eint = 0x3,
2985479f
MB
446 },
447 [2] = {
1b39d5f2 448 .cfg_eint = 0x7,
2985479f
MB
449 },
450 [3] = {
1b39d5f2 451 .cfg_eint = 0xF,
2985479f
MB
452 },
453 [4] = {
1b39d5f2
KK
454 .cfg_eint = 0x0,
455 .set_config = samsung_gpio_setcfg_2bit,
456 .get_config = samsung_gpio_getcfg_2bit,
2985479f
MB
457 },
458 [5] = {
1b39d5f2
KK
459 .cfg_eint = 0x2,
460 .set_config = samsung_gpio_setcfg_2bit,
461 .get_config = samsung_gpio_getcfg_2bit,
2985479f
MB
462 },
463 [6] = {
1b39d5f2
KK
464 .cfg_eint = 0x3,
465 .set_config = samsung_gpio_setcfg_2bit,
466 .get_config = samsung_gpio_getcfg_2bit,
2985479f
MB
467 },
468 [7] = {
1b39d5f2
KK
469 .set_config = samsung_gpio_setcfg_2bit,
470 .get_config = samsung_gpio_getcfg_2bit,
2985479f 471 },
1b39d5f2
KK
472};
473
474/*
475 * Default routines for controlling GPIO, based on the original S3C24XX
476 * GPIO functions which deal with the case where each gpio bank of the
477 * chip is as following:
478 *
479 * base + 0x00: Control register, 2 bits per gpio
480 * gpio n: 2 bits starting at (2*n)
481 * 00 = input, 01 = output, others mean special-function
482 * base + 0x04: Data register, 1 bit per gpio
483 * bit n: data bit n
484*/
485
486static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
487{
488 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
489 void __iomem *base = ourchip->base;
490 unsigned long flags;
491 unsigned long con;
492
493 samsung_gpio_lock(ourchip, flags);
494
495 con = __raw_readl(base + 0x00);
496 con &= ~(3 << (offset * 2));
497
498 __raw_writel(con, base + 0x00);
499
500 samsung_gpio_unlock(ourchip, flags);
501 return 0;
502}
503
504static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
505 unsigned offset, int value)
506{
507 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
508 void __iomem *base = ourchip->base;
509 unsigned long flags;
510 unsigned long dat;
511 unsigned long con;
512
513 samsung_gpio_lock(ourchip, flags);
514
515 dat = __raw_readl(base + 0x04);
516 dat &= ~(1 << offset);
517 if (value)
518 dat |= 1 << offset;
519 __raw_writel(dat, base + 0x04);
520
521 con = __raw_readl(base + 0x00);
522 con &= ~(3 << (offset * 2));
523 con |= 1 << (offset * 2);
524
525 __raw_writel(con, base + 0x00);
526 __raw_writel(dat, base + 0x04);
527
528 samsung_gpio_unlock(ourchip, flags);
529 return 0;
530}
531
532/*
533 * The samsung_gpiolib_4bit routines are to control the gpio banks where
534 * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
535 * following example:
536 *
537 * base + 0x00: Control register, 4 bits per gpio
538 * gpio n: 4 bits starting at (4*n)
539 * 0000 = input, 0001 = output, others mean special-function
540 * base + 0x04: Data register, 1 bit per gpio
541 * bit n: data bit n
542 *
543 * Note, since the data register is one bit per gpio and is at base + 0x4
544 * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
545 * state of the output.
546 */
547
548static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
549 unsigned int offset)
550{
551 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
552 void __iomem *base = ourchip->base;
553 unsigned long con;
554
555 con = __raw_readl(base + GPIOCON_OFF);
2b88ff4a
EK
556 if (ourchip->bitmap_gpio_int & BIT(offset))
557 con |= 0xf << con_4bit_shift(offset);
558 else
559 con &= ~(0xf << con_4bit_shift(offset));
1b39d5f2
KK
560 __raw_writel(con, base + GPIOCON_OFF);
561
343db4bd 562 pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
1b39d5f2
KK
563
564 return 0;
565}
566
567static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
568 unsigned int offset, int value)
569{
570 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
571 void __iomem *base = ourchip->base;
572 unsigned long con;
573 unsigned long dat;
574
575 con = __raw_readl(base + GPIOCON_OFF);
576 con &= ~(0xf << con_4bit_shift(offset));
577 con |= 0x1 << con_4bit_shift(offset);
578
579 dat = __raw_readl(base + GPIODAT_OFF);
580
581 if (value)
582 dat |= 1 << offset;
583 else
584 dat &= ~(1 << offset);
585
586 __raw_writel(dat, base + GPIODAT_OFF);
587 __raw_writel(con, base + GPIOCON_OFF);
588 __raw_writel(dat, base + GPIODAT_OFF);
589
343db4bd 590 pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
1b39d5f2
KK
591
592 return 0;
593}
594
595/*
596 * The next set of routines are for the case where the GPIO configuration
597 * registers are 4 bits per GPIO but there is more than one register (the
598 * bank has more than 8 GPIOs.
599 *
600 * This case is the similar to the 4 bit case, but the registers are as
601 * follows:
602 *
603 * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
604 * gpio n: 4 bits starting at (4*n)
605 * 0000 = input, 0001 = output, others mean special-function
606 * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
607 * gpio n: 4 bits starting at (4*n)
608 * 0000 = input, 0001 = output, others mean special-function
609 * base + 0x08: Data register, 1 bit per gpio
610 * bit n: data bit n
611 *
612 * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
613 * routines we store the 'base + 0x4' address so that these routines see
614 * the data register at ourchip->base + 0x04.
615 */
616
617static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
618 unsigned int offset)
619{
620 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
621 void __iomem *base = ourchip->base;
622 void __iomem *regcon = base;
623 unsigned long con;
624
625 if (offset > 7)
626 offset -= 8;
627 else
628 regcon -= 4;
629
630 con = __raw_readl(regcon);
631 con &= ~(0xf << con_4bit_shift(offset));
632 __raw_writel(con, regcon);
633
343db4bd 634 pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
1b39d5f2
KK
635
636 return 0;
637}
638
639static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
640 unsigned int offset, int value)
641{
642 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
643 void __iomem *base = ourchip->base;
644 void __iomem *regcon = base;
645 unsigned long con;
646 unsigned long dat;
647 unsigned con_offset = offset;
648
649 if (con_offset > 7)
650 con_offset -= 8;
651 else
652 regcon -= 4;
653
654 con = __raw_readl(regcon);
655 con &= ~(0xf << con_4bit_shift(con_offset));
656 con |= 0x1 << con_4bit_shift(con_offset);
657
658 dat = __raw_readl(base + GPIODAT_OFF);
659
660 if (value)
661 dat |= 1 << offset;
662 else
663 dat &= ~(1 << offset);
664
665 __raw_writel(dat, base + GPIODAT_OFF);
666 __raw_writel(con, regcon);
667 __raw_writel(dat, base + GPIODAT_OFF);
668
343db4bd 669 pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
1b39d5f2
KK
670
671 return 0;
672}
673
c034b184 674#ifdef CONFIG_PLAT_S3C24XX
1b39d5f2
KK
675/* The next set of routines are for the case of s3c24xx bank a */
676
677static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
678{
679 return -EINVAL;
680}
681
682static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
683 unsigned offset, int value)
684{
685 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
686 void __iomem *base = ourchip->base;
687 unsigned long flags;
688 unsigned long dat;
689 unsigned long con;
690
691 local_irq_save(flags);
692
693 con = __raw_readl(base + 0x00);
694 dat = __raw_readl(base + 0x04);
695
696 dat &= ~(1 << offset);
697 if (value)
698 dat |= 1 << offset;
699
700 __raw_writel(dat, base + 0x04);
701
702 con &= ~(1 << offset);
703
704 __raw_writel(con, base + 0x00);
705 __raw_writel(dat, base + 0x04);
706
707 local_irq_restore(flags);
708 return 0;
709}
c034b184 710#endif
1b39d5f2
KK
711
712/* The next set of routines are for the case of s5p64x0 bank r */
713
714static int s5p64x0_gpiolib_rbank_input(struct gpio_chip *chip,
715 unsigned int offset)
716{
717 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
718 void __iomem *base = ourchip->base;
719 void __iomem *regcon = base;
720 unsigned long con;
721 unsigned long flags;
722
723 switch (offset) {
724 case 6:
725 offset += 1;
726 case 0:
727 case 1:
728 case 2:
729 case 3:
730 case 4:
731 case 5:
732 regcon -= 4;
733 break;
734 default:
735 offset -= 7;
736 break;
737 }
738
739 samsung_gpio_lock(ourchip, flags);
740
741 con = __raw_readl(regcon);
742 con &= ~(0xf << con_4bit_shift(offset));
743 __raw_writel(con, regcon);
744
745 samsung_gpio_unlock(ourchip, flags);
746
747 return 0;
748}
749
750static int s5p64x0_gpiolib_rbank_output(struct gpio_chip *chip,
751 unsigned int offset, int value)
752{
753 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
754 void __iomem *base = ourchip->base;
755 void __iomem *regcon = base;
756 unsigned long con;
757 unsigned long dat;
758 unsigned long flags;
759 unsigned con_offset = offset;
760
761 switch (con_offset) {
762 case 6:
763 con_offset += 1;
764 case 0:
765 case 1:
766 case 2:
767 case 3:
768 case 4:
769 case 5:
770 regcon -= 4;
771 break;
772 default:
773 con_offset -= 7;
774 break;
775 }
776
777 samsung_gpio_lock(ourchip, flags);
778
779 con = __raw_readl(regcon);
780 con &= ~(0xf << con_4bit_shift(con_offset));
781 con |= 0x1 << con_4bit_shift(con_offset);
782
783 dat = __raw_readl(base + GPIODAT_OFF);
784 if (value)
785 dat |= 1 << offset;
786 else
787 dat &= ~(1 << offset);
788
789 __raw_writel(con, regcon);
790 __raw_writel(dat, base + GPIODAT_OFF);
791
792 samsung_gpio_unlock(ourchip, flags);
793
794 return 0;
795}
796
797static void samsung_gpiolib_set(struct gpio_chip *chip,
798 unsigned offset, int value)
799{
800 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
801 void __iomem *base = ourchip->base;
802 unsigned long flags;
803 unsigned long dat;
804
805 samsung_gpio_lock(ourchip, flags);
806
807 dat = __raw_readl(base + 0x04);
808 dat &= ~(1 << offset);
809 if (value)
810 dat |= 1 << offset;
811 __raw_writel(dat, base + 0x04);
812
813 samsung_gpio_unlock(ourchip, flags);
814}
815
816static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
817{
818 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
819 unsigned long val;
820
821 val = __raw_readl(ourchip->base + 0x04);
822 val >>= offset;
823 val &= 1;
824
825 return val;
826}
827
828/*
829 * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
830 * for use with the configuration calls, and other parts of the s3c gpiolib
831 * support code.
832 *
833 * Not all s3c support code will need this, as some configurations of cpu
834 * may only support one or two different configuration options and have an
835 * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
836 * the machine support file should provide its own samsung_gpiolib_getchip()
837 * and any other necessary functions.
838 */
839
840#ifdef CONFIG_S3C_GPIO_TRACK
841struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
842
843static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
844{
845 unsigned int gpn;
846 int i;
847
848 gpn = chip->chip.base;
849 for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
850 BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
851 s3c_gpios[gpn] = chip;
852 }
853}
854#endif /* CONFIG_S3C_GPIO_TRACK */
855
856/*
857 * samsung_gpiolib_add() - add the Samsung gpio_chip.
858 * @chip: The chip to register
859 *
860 * This is a wrapper to gpiochip_add() that takes our specific gpio chip
861 * information and makes the necessary alterations for the platform and
862 * notes the information for use with the configuration systems and any
863 * other parts of the system.
864 */
865
866static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
867{
868 struct gpio_chip *gc = &chip->chip;
869 int ret;
870
871 BUG_ON(!chip->base);
872 BUG_ON(!gc->label);
873 BUG_ON(!gc->ngpio);
874
875 spin_lock_init(&chip->lock);
876
877 if (!gc->direction_input)
878 gc->direction_input = samsung_gpiolib_2bit_input;
879 if (!gc->direction_output)
880 gc->direction_output = samsung_gpiolib_2bit_output;
881 if (!gc->set)
882 gc->set = samsung_gpiolib_set;
883 if (!gc->get)
884 gc->get = samsung_gpiolib_get;
885
886#ifdef CONFIG_PM
887 if (chip->pm != NULL) {
888 if (!chip->pm->save || !chip->pm->resume)
343db4bd 889 pr_err("gpio: %s has missing PM functions\n",
1b39d5f2
KK
890 gc->label);
891 } else
343db4bd 892 pr_err("gpio: %s has no PM function\n", gc->label);
1b39d5f2
KK
893#endif
894
895 /* gpiochip_add() prints own failure message on error. */
896 ret = gpiochip_add(gc);
897 if (ret >= 0)
898 s3c_gpiolib_track(chip);
899}
900
901static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
902 int nr_chips, void __iomem *base)
903{
904 int i;
905 struct gpio_chip *gc = &chip->chip;
906
907 for (i = 0 ; i < nr_chips; i++, chip++) {
8a8ab2e6
PK
908 /* skip banks not present on SoC */
909 if (chip->chip.base >= S3C_GPIO_END)
910 continue;
911
1b39d5f2
KK
912 if (!chip->config)
913 chip->config = &s3c24xx_gpiocfg_default;
914 if (!chip->pm)
915 chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
916 if ((base != NULL) && (chip->base == NULL))
917 chip->base = base + ((i) * 0x10);
918
919 if (!gc->direction_input)
920 gc->direction_input = samsung_gpiolib_2bit_input;
921 if (!gc->direction_output)
922 gc->direction_output = samsung_gpiolib_2bit_output;
923
924 samsung_gpiolib_add(chip);
925 }
926}
927
928static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
929 int nr_chips, void __iomem *base,
930 unsigned int offset)
931{
932 int i;
933
934 for (i = 0 ; i < nr_chips; i++, chip++) {
935 chip->chip.direction_input = samsung_gpiolib_2bit_input;
936 chip->chip.direction_output = samsung_gpiolib_2bit_output;
937
938 if (!chip->config)
939 chip->config = &samsung_gpio_cfgs[7];
940 if (!chip->pm)
941 chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
942 if ((base != NULL) && (chip->base == NULL))
943 chip->base = base + ((i) * offset);
944
945 samsung_gpiolib_add(chip);
946 }
947}
948
949/*
950 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
951 * @chip: The gpio chip that is being configured.
952 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
953 *
954 * This helper deal with the GPIO cases where the control register has 4 bits
955 * of control per GPIO, generally in the form of:
956 * 0000 = Input
957 * 0001 = Output
958 * others = Special functions (dependent on bank)
959 *
960 * Note, since the code to deal with the case where there are two control
961 * registers instead of one, we do not have a separate set of function
962 * (samsung_gpiolib_add_4bit2_chips)for each case.
963 */
964
965static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
966 int nr_chips, void __iomem *base)
967{
968 int i;
969
970 for (i = 0 ; i < nr_chips; i++, chip++) {
971 chip->chip.direction_input = samsung_gpiolib_4bit_input;
972 chip->chip.direction_output = samsung_gpiolib_4bit_output;
973
974 if (!chip->config)
975 chip->config = &samsung_gpio_cfgs[2];
976 if (!chip->pm)
977 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
978 if ((base != NULL) && (chip->base == NULL))
979 chip->base = base + ((i) * 0x20);
980
2b88ff4a
EK
981 chip->bitmap_gpio_int = 0;
982
1b39d5f2
KK
983 samsung_gpiolib_add(chip);
984 }
985}
986
987static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
988 int nr_chips)
989{
990 for (; nr_chips > 0; nr_chips--, chip++) {
991 chip->chip.direction_input = samsung_gpiolib_4bit2_input;
992 chip->chip.direction_output = samsung_gpiolib_4bit2_output;
993
994 if (!chip->config)
995 chip->config = &samsung_gpio_cfgs[2];
996 if (!chip->pm)
997 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
998
999 samsung_gpiolib_add(chip);
1000 }
1001}
1002
1003static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip,
1004 int nr_chips)
1005{
1006 for (; nr_chips > 0; nr_chips--, chip++) {
1007 chip->chip.direction_input = s5p64x0_gpiolib_rbank_input;
1008 chip->chip.direction_output = s5p64x0_gpiolib_rbank_output;
1009
1010 if (!chip->pm)
1011 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1012
1013 samsung_gpiolib_add(chip);
1014 }
1015}
1016
1017int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
1018{
1019 struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip);
1020
1021 return samsung_chip->irq_base + offset;
1022}
1023
1024#ifdef CONFIG_PLAT_S3C24XX
1025static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
1026{
d97fedef 1027 if (offset < 4) {
1c8408e3
HS
1028 if (soc_is_s3c2412())
1029 return IRQ_EINT0_2412 + offset;
1030 else
1031 return IRQ_EINT0 + offset;
d97fedef 1032 }
1b39d5f2
KK
1033
1034 if (offset < 8)
1035 return IRQ_EINT4 + offset - 4;
1036
1037 return -EINVAL;
1038}
1039#endif
1040
54362e11 1041#ifdef CONFIG_ARCH_S3C64XX
1b39d5f2
KK
1042static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
1043{
1044 return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
1045}
1046
1047static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
1048{
1049 return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
1050}
1051#endif
1052
1053struct samsung_gpio_chip s3c24xx_gpios[] = {
1054#ifdef CONFIG_PLAT_S3C24XX
1055 {
1056 .config = &s3c24xx_gpiocfg_banka,
1057 .chip = {
1058 .base = S3C2410_GPA(0),
1059 .owner = THIS_MODULE,
1060 .label = "GPIOA",
035b2f7c 1061 .ngpio = 27,
1b39d5f2
KK
1062 .direction_input = s3c24xx_gpiolib_banka_input,
1063 .direction_output = s3c24xx_gpiolib_banka_output,
1064 },
1065 }, {
1066 .chip = {
1067 .base = S3C2410_GPB(0),
1068 .owner = THIS_MODULE,
1069 .label = "GPIOB",
035b2f7c 1070 .ngpio = 11,
1b39d5f2
KK
1071 },
1072 }, {
1073 .chip = {
1074 .base = S3C2410_GPC(0),
1075 .owner = THIS_MODULE,
1076 .label = "GPIOC",
1077 .ngpio = 16,
1078 },
1079 }, {
1080 .chip = {
1081 .base = S3C2410_GPD(0),
1082 .owner = THIS_MODULE,
1083 .label = "GPIOD",
1084 .ngpio = 16,
1085 },
1086 }, {
1087 .chip = {
1088 .base = S3C2410_GPE(0),
1089 .label = "GPIOE",
1090 .owner = THIS_MODULE,
1091 .ngpio = 16,
1092 },
1093 }, {
1094 .chip = {
1095 .base = S3C2410_GPF(0),
1096 .owner = THIS_MODULE,
1097 .label = "GPIOF",
1098 .ngpio = 8,
1099 .to_irq = s3c24xx_gpiolib_fbank_to_irq,
1100 },
1101 }, {
1102 .irq_base = IRQ_EINT8,
1103 .chip = {
1104 .base = S3C2410_GPG(0),
1105 .owner = THIS_MODULE,
1106 .label = "GPIOG",
1107 .ngpio = 16,
1108 .to_irq = samsung_gpiolib_to_irq,
1109 },
1110 }, {
1111 .chip = {
1112 .base = S3C2410_GPH(0),
1113 .owner = THIS_MODULE,
1114 .label = "GPIOH",
035b2f7c 1115 .ngpio = 15,
1b39d5f2
KK
1116 },
1117 },
1118 /* GPIOS for the S3C2443 and later devices. */
1119 {
1120 .base = S3C2440_GPJCON,
1121 .chip = {
1122 .base = S3C2410_GPJ(0),
1123 .owner = THIS_MODULE,
1124 .label = "GPIOJ",
1125 .ngpio = 16,
1126 },
1127 }, {
1128 .base = S3C2443_GPKCON,
1129 .chip = {
1130 .base = S3C2410_GPK(0),
1131 .owner = THIS_MODULE,
1132 .label = "GPIOK",
1133 .ngpio = 16,
1134 },
1135 }, {
1136 .base = S3C2443_GPLCON,
1137 .chip = {
1138 .base = S3C2410_GPL(0),
1139 .owner = THIS_MODULE,
1140 .label = "GPIOL",
1141 .ngpio = 15,
1142 },
1143 }, {
1144 .base = S3C2443_GPMCON,
1145 .chip = {
1146 .base = S3C2410_GPM(0),
1147 .owner = THIS_MODULE,
1148 .label = "GPIOM",
1149 .ngpio = 2,
1150 },
1151 },
1152#endif
1153};
1154
1155/*
1156 * GPIO bank summary:
1157 *
1158 * Bank GPIOs Style SlpCon ExtInt Group
1159 * A 8 4Bit Yes 1
1160 * B 7 4Bit Yes 1
1161 * C 8 4Bit Yes 2
1162 * D 5 4Bit Yes 3
1163 * E 5 4Bit Yes None
1164 * F 16 2Bit Yes 4 [1]
1165 * G 7 4Bit Yes 5
1166 * H 10 4Bit[2] Yes 6
1167 * I 16 2Bit Yes None
1168 * J 12 2Bit Yes None
1169 * K 16 4Bit[2] No None
1170 * L 15 4Bit[2] No None
1171 * M 6 4Bit No IRQ_EINT
1172 * N 16 2Bit No IRQ_EINT
1173 * O 16 2Bit Yes 7
1174 * P 15 2Bit Yes 8
1175 * Q 9 2Bit Yes 9
1176 *
1177 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1178 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1179 */
1180
1181static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
54362e11 1182#ifdef CONFIG_ARCH_S3C64XX
1b39d5f2
KK
1183 {
1184 .chip = {
1185 .base = S3C64XX_GPA(0),
1186 .ngpio = S3C64XX_GPIO_A_NR,
1187 .label = "GPA",
1188 },
1189 }, {
1190 .chip = {
1191 .base = S3C64XX_GPB(0),
1192 .ngpio = S3C64XX_GPIO_B_NR,
1193 .label = "GPB",
1194 },
1195 }, {
1196 .chip = {
1197 .base = S3C64XX_GPC(0),
1198 .ngpio = S3C64XX_GPIO_C_NR,
1199 .label = "GPC",
1200 },
1201 }, {
1202 .chip = {
1203 .base = S3C64XX_GPD(0),
1204 .ngpio = S3C64XX_GPIO_D_NR,
1205 .label = "GPD",
1206 },
1207 }, {
1208 .config = &samsung_gpio_cfgs[0],
1209 .chip = {
1210 .base = S3C64XX_GPE(0),
1211 .ngpio = S3C64XX_GPIO_E_NR,
1212 .label = "GPE",
1213 },
1214 }, {
1215 .base = S3C64XX_GPG_BASE,
1216 .chip = {
1217 .base = S3C64XX_GPG(0),
1218 .ngpio = S3C64XX_GPIO_G_NR,
1219 .label = "GPG",
1220 },
1221 }, {
1222 .base = S3C64XX_GPM_BASE,
1223 .config = &samsung_gpio_cfgs[1],
1224 .chip = {
1225 .base = S3C64XX_GPM(0),
1226 .ngpio = S3C64XX_GPIO_M_NR,
1227 .label = "GPM",
1228 .to_irq = s3c64xx_gpiolib_mbank_to_irq,
1229 },
1230 },
1231#endif
1232};
1233
1234static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
54362e11 1235#ifdef CONFIG_ARCH_S3C64XX
1b39d5f2
KK
1236 {
1237 .base = S3C64XX_GPH_BASE + 0x4,
1238 .chip = {
1239 .base = S3C64XX_GPH(0),
1240 .ngpio = S3C64XX_GPIO_H_NR,
1241 .label = "GPH",
1242 },
1243 }, {
1244 .base = S3C64XX_GPK_BASE + 0x4,
1245 .config = &samsung_gpio_cfgs[0],
1246 .chip = {
1247 .base = S3C64XX_GPK(0),
1248 .ngpio = S3C64XX_GPIO_K_NR,
1249 .label = "GPK",
1250 },
1251 }, {
1252 .base = S3C64XX_GPL_BASE + 0x4,
1253 .config = &samsung_gpio_cfgs[1],
1254 .chip = {
1255 .base = S3C64XX_GPL(0),
1256 .ngpio = S3C64XX_GPIO_L_NR,
1257 .label = "GPL",
1258 .to_irq = s3c64xx_gpiolib_lbank_to_irq,
1259 },
1260 },
1261#endif
1262};
1263
1264static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
54362e11 1265#ifdef CONFIG_ARCH_S3C64XX
1b39d5f2
KK
1266 {
1267 .base = S3C64XX_GPF_BASE,
1268 .config = &samsung_gpio_cfgs[6],
1269 .chip = {
1270 .base = S3C64XX_GPF(0),
1271 .ngpio = S3C64XX_GPIO_F_NR,
1272 .label = "GPF",
1273 },
1274 }, {
1275 .config = &samsung_gpio_cfgs[7],
1276 .chip = {
1277 .base = S3C64XX_GPI(0),
1278 .ngpio = S3C64XX_GPIO_I_NR,
1279 .label = "GPI",
1280 },
1281 }, {
1282 .config = &samsung_gpio_cfgs[7],
1283 .chip = {
1284 .base = S3C64XX_GPJ(0),
1285 .ngpio = S3C64XX_GPIO_J_NR,
1286 .label = "GPJ",
1287 },
1288 }, {
1289 .config = &samsung_gpio_cfgs[6],
1290 .chip = {
1291 .base = S3C64XX_GPO(0),
1292 .ngpio = S3C64XX_GPIO_O_NR,
1293 .label = "GPO",
1294 },
1295 }, {
1296 .config = &samsung_gpio_cfgs[6],
1297 .chip = {
1298 .base = S3C64XX_GPP(0),
1299 .ngpio = S3C64XX_GPIO_P_NR,
1300 .label = "GPP",
1301 },
1302 }, {
1303 .config = &samsung_gpio_cfgs[6],
1304 .chip = {
1305 .base = S3C64XX_GPQ(0),
1306 .ngpio = S3C64XX_GPIO_Q_NR,
1307 .label = "GPQ",
1308 },
1309 }, {
1310 .base = S3C64XX_GPN_BASE,
1311 .irq_base = IRQ_EINT(0),
1312 .config = &samsung_gpio_cfgs[5],
1313 .chip = {
1314 .base = S3C64XX_GPN(0),
1315 .ngpio = S3C64XX_GPIO_N_NR,
1316 .label = "GPN",
1317 .to_irq = samsung_gpiolib_to_irq,
1318 },
1319 },
1320#endif
1321};
1322
1323/*
1324 * S5P6440 GPIO bank summary:
1325 *
1326 * Bank GPIOs Style SlpCon ExtInt Group
1327 * A 6 4Bit Yes 1
1328 * B 7 4Bit Yes 1
1329 * C 8 4Bit Yes 2
1330 * F 2 2Bit Yes 4 [1]
1331 * G 7 4Bit Yes 5
1332 * H 10 4Bit[2] Yes 6
1333 * I 16 2Bit Yes None
1334 * J 12 2Bit Yes None
1335 * N 16 2Bit No IRQ_EINT
1336 * P 8 2Bit Yes 8
1337 * R 15 4Bit[2] Yes 8
1338 */
1339
1340static struct samsung_gpio_chip s5p6440_gpios_4bit[] = {
1341#ifdef CONFIG_CPU_S5P6440
1342 {
1343 .chip = {
1344 .base = S5P6440_GPA(0),
1345 .ngpio = S5P6440_GPIO_A_NR,
1346 .label = "GPA",
1347 },
1348 }, {
1349 .chip = {
1350 .base = S5P6440_GPB(0),
1351 .ngpio = S5P6440_GPIO_B_NR,
1352 .label = "GPB",
1353 },
1354 }, {
1355 .chip = {
1356 .base = S5P6440_GPC(0),
1357 .ngpio = S5P6440_GPIO_C_NR,
1358 .label = "GPC",
1359 },
1360 }, {
1361 .base = S5P64X0_GPG_BASE,
1362 .chip = {
1363 .base = S5P6440_GPG(0),
1364 .ngpio = S5P6440_GPIO_G_NR,
1365 .label = "GPG",
1366 },
1367 },
1368#endif
1369};
1370
1371static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = {
1372#ifdef CONFIG_CPU_S5P6440
1373 {
1374 .base = S5P64X0_GPH_BASE + 0x4,
1375 .chip = {
1376 .base = S5P6440_GPH(0),
1377 .ngpio = S5P6440_GPIO_H_NR,
1378 .label = "GPH",
1379 },
1380 },
1381#endif
1382};
1383
1384static struct samsung_gpio_chip s5p6440_gpios_rbank[] = {
1385#ifdef CONFIG_CPU_S5P6440
1386 {
1387 .base = S5P64X0_GPR_BASE + 0x4,
1388 .config = &s5p64x0_gpio_cfg_rbank,
1389 .chip = {
1390 .base = S5P6440_GPR(0),
1391 .ngpio = S5P6440_GPIO_R_NR,
1392 .label = "GPR",
1393 },
1394 },
1395#endif
1396};
1397
1398static struct samsung_gpio_chip s5p6440_gpios_2bit[] = {
1399#ifdef CONFIG_CPU_S5P6440
1400 {
1401 .base = S5P64X0_GPF_BASE,
1402 .config = &samsung_gpio_cfgs[6],
1403 .chip = {
1404 .base = S5P6440_GPF(0),
1405 .ngpio = S5P6440_GPIO_F_NR,
1406 .label = "GPF",
1407 },
1408 }, {
1409 .base = S5P64X0_GPI_BASE,
1410 .config = &samsung_gpio_cfgs[4],
1411 .chip = {
1412 .base = S5P6440_GPI(0),
1413 .ngpio = S5P6440_GPIO_I_NR,
1414 .label = "GPI",
1415 },
1416 }, {
1417 .base = S5P64X0_GPJ_BASE,
1418 .config = &samsung_gpio_cfgs[4],
1419 .chip = {
1420 .base = S5P6440_GPJ(0),
1421 .ngpio = S5P6440_GPIO_J_NR,
1422 .label = "GPJ",
1423 },
1424 }, {
1425 .base = S5P64X0_GPN_BASE,
1426 .config = &samsung_gpio_cfgs[5],
1427 .chip = {
1428 .base = S5P6440_GPN(0),
1429 .ngpio = S5P6440_GPIO_N_NR,
1430 .label = "GPN",
1431 },
1432 }, {
1433 .base = S5P64X0_GPP_BASE,
1434 .config = &samsung_gpio_cfgs[6],
1435 .chip = {
1436 .base = S5P6440_GPP(0),
1437 .ngpio = S5P6440_GPIO_P_NR,
1438 .label = "GPP",
1439 },
1440 },
1441#endif
1442};
1443
1444/*
1445 * S5P6450 GPIO bank summary:
1446 *
1447 * Bank GPIOs Style SlpCon ExtInt Group
1448 * A 6 4Bit Yes 1
1449 * B 7 4Bit Yes 1
1450 * C 8 4Bit Yes 2
1451 * D 8 4Bit Yes None
1452 * F 2 2Bit Yes None
1453 * G 14 4Bit[2] Yes 5
1454 * H 10 4Bit[2] Yes 6
1455 * I 16 2Bit Yes None
1456 * J 12 2Bit Yes None
1457 * K 5 4Bit Yes None
1458 * N 16 2Bit No IRQ_EINT
1459 * P 11 2Bit Yes 8
1460 * Q 14 2Bit Yes None
1461 * R 15 4Bit[2] Yes None
1462 * S 8 2Bit Yes None
1463 *
1464 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1465 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1466 */
1467
1468static struct samsung_gpio_chip s5p6450_gpios_4bit[] = {
1469#ifdef CONFIG_CPU_S5P6450
1470 {
1471 .chip = {
1472 .base = S5P6450_GPA(0),
1473 .ngpio = S5P6450_GPIO_A_NR,
1474 .label = "GPA",
1475 },
1476 }, {
1477 .chip = {
1478 .base = S5P6450_GPB(0),
1479 .ngpio = S5P6450_GPIO_B_NR,
1480 .label = "GPB",
1481 },
1482 }, {
1483 .chip = {
1484 .base = S5P6450_GPC(0),
1485 .ngpio = S5P6450_GPIO_C_NR,
1486 .label = "GPC",
1487 },
1488 }, {
1489 .chip = {
1490 .base = S5P6450_GPD(0),
1491 .ngpio = S5P6450_GPIO_D_NR,
1492 .label = "GPD",
1493 },
1494 }, {
1495 .base = S5P6450_GPK_BASE,
1496 .chip = {
1497 .base = S5P6450_GPK(0),
1498 .ngpio = S5P6450_GPIO_K_NR,
1499 .label = "GPK",
1500 },
1501 },
1502#endif
1503};
1504
1505static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = {
1506#ifdef CONFIG_CPU_S5P6450
1507 {
1508 .base = S5P64X0_GPG_BASE + 0x4,
1509 .chip = {
1510 .base = S5P6450_GPG(0),
1511 .ngpio = S5P6450_GPIO_G_NR,
1512 .label = "GPG",
1513 },
1514 }, {
1515 .base = S5P64X0_GPH_BASE + 0x4,
1516 .chip = {
1517 .base = S5P6450_GPH(0),
1518 .ngpio = S5P6450_GPIO_H_NR,
1519 .label = "GPH",
1520 },
1521 },
1522#endif
1523};
1524
1525static struct samsung_gpio_chip s5p6450_gpios_rbank[] = {
1526#ifdef CONFIG_CPU_S5P6450
1527 {
1528 .base = S5P64X0_GPR_BASE + 0x4,
1529 .config = &s5p64x0_gpio_cfg_rbank,
1530 .chip = {
1531 .base = S5P6450_GPR(0),
1532 .ngpio = S5P6450_GPIO_R_NR,
1533 .label = "GPR",
1534 },
1535 },
1536#endif
1537};
1538
1539static struct samsung_gpio_chip s5p6450_gpios_2bit[] = {
1540#ifdef CONFIG_CPU_S5P6450
1541 {
1542 .base = S5P64X0_GPF_BASE,
1543 .config = &samsung_gpio_cfgs[6],
1544 .chip = {
1545 .base = S5P6450_GPF(0),
1546 .ngpio = S5P6450_GPIO_F_NR,
1547 .label = "GPF",
1548 },
1549 }, {
1550 .base = S5P64X0_GPI_BASE,
1551 .config = &samsung_gpio_cfgs[4],
1552 .chip = {
1553 .base = S5P6450_GPI(0),
1554 .ngpio = S5P6450_GPIO_I_NR,
1555 .label = "GPI",
1556 },
1557 }, {
1558 .base = S5P64X0_GPJ_BASE,
1559 .config = &samsung_gpio_cfgs[4],
1560 .chip = {
1561 .base = S5P6450_GPJ(0),
1562 .ngpio = S5P6450_GPIO_J_NR,
1563 .label = "GPJ",
1564 },
1565 }, {
1566 .base = S5P64X0_GPN_BASE,
1567 .config = &samsung_gpio_cfgs[5],
1568 .chip = {
1569 .base = S5P6450_GPN(0),
1570 .ngpio = S5P6450_GPIO_N_NR,
1571 .label = "GPN",
1572 },
1573 }, {
1574 .base = S5P64X0_GPP_BASE,
1575 .config = &samsung_gpio_cfgs[6],
1576 .chip = {
1577 .base = S5P6450_GPP(0),
1578 .ngpio = S5P6450_GPIO_P_NR,
1579 .label = "GPP",
1580 },
1581 }, {
1582 .base = S5P6450_GPQ_BASE,
1583 .config = &samsung_gpio_cfgs[5],
1584 .chip = {
1585 .base = S5P6450_GPQ(0),
1586 .ngpio = S5P6450_GPIO_Q_NR,
1587 .label = "GPQ",
1588 },
1589 }, {
1590 .base = S5P6450_GPS_BASE,
1591 .config = &samsung_gpio_cfgs[6],
1592 .chip = {
1593 .base = S5P6450_GPS(0),
1594 .ngpio = S5P6450_GPIO_S_NR,
1595 .label = "GPS",
1596 },
1597 },
1598#endif
1599};
1600
1601/*
1602 * S5PC100 GPIO bank summary:
1603 *
1604 * Bank GPIOs Style INT Type
1605 * A0 8 4Bit GPIO_INT0
1606 * A1 5 4Bit GPIO_INT1
1607 * B 8 4Bit GPIO_INT2
1608 * C 5 4Bit GPIO_INT3
1609 * D 7 4Bit GPIO_INT4
1610 * E0 8 4Bit GPIO_INT5
1611 * E1 6 4Bit GPIO_INT6
1612 * F0 8 4Bit GPIO_INT7
1613 * F1 8 4Bit GPIO_INT8
1614 * F2 8 4Bit GPIO_INT9
1615 * F3 4 4Bit GPIO_INT10
1616 * G0 8 4Bit GPIO_INT11
1617 * G1 3 4Bit GPIO_INT12
1618 * G2 7 4Bit GPIO_INT13
1619 * G3 7 4Bit GPIO_INT14
1620 * H0 8 4Bit WKUP_INT
1621 * H1 8 4Bit WKUP_INT
1622 * H2 8 4Bit WKUP_INT
1623 * H3 8 4Bit WKUP_INT
1624 * I 8 4Bit GPIO_INT15
1625 * J0 8 4Bit GPIO_INT16
1626 * J1 5 4Bit GPIO_INT17
1627 * J2 8 4Bit GPIO_INT18
1628 * J3 8 4Bit GPIO_INT19
1629 * J4 4 4Bit GPIO_INT20
1630 * K0 8 4Bit None
1631 * K1 6 4Bit None
1632 * K2 8 4Bit None
1633 * K3 8 4Bit None
1634 * L0 8 4Bit None
1635 * L1 8 4Bit None
1636 * L2 8 4Bit None
1637 * L3 8 4Bit None
1638 */
1639
1640static struct samsung_gpio_chip s5pc100_gpios_4bit[] = {
1641#ifdef CONFIG_CPU_S5PC100
1642 {
1643 .chip = {
1644 .base = S5PC100_GPA0(0),
1645 .ngpio = S5PC100_GPIO_A0_NR,
1646 .label = "GPA0",
1647 },
1648 }, {
1649 .chip = {
1650 .base = S5PC100_GPA1(0),
1651 .ngpio = S5PC100_GPIO_A1_NR,
1652 .label = "GPA1",
1653 },
1654 }, {
1655 .chip = {
1656 .base = S5PC100_GPB(0),
1657 .ngpio = S5PC100_GPIO_B_NR,
1658 .label = "GPB",
1659 },
1660 }, {
1661 .chip = {
1662 .base = S5PC100_GPC(0),
1663 .ngpio = S5PC100_GPIO_C_NR,
1664 .label = "GPC",
1665 },
1666 }, {
1667 .chip = {
1668 .base = S5PC100_GPD(0),
1669 .ngpio = S5PC100_GPIO_D_NR,
1670 .label = "GPD",
1671 },
1672 }, {
1673 .chip = {
1674 .base = S5PC100_GPE0(0),
1675 .ngpio = S5PC100_GPIO_E0_NR,
1676 .label = "GPE0",
1677 },
1678 }, {
1679 .chip = {
1680 .base = S5PC100_GPE1(0),
1681 .ngpio = S5PC100_GPIO_E1_NR,
1682 .label = "GPE1",
1683 },
1684 }, {
1685 .chip = {
1686 .base = S5PC100_GPF0(0),
1687 .ngpio = S5PC100_GPIO_F0_NR,
1688 .label = "GPF0",
1689 },
1690 }, {
1691 .chip = {
1692 .base = S5PC100_GPF1(0),
1693 .ngpio = S5PC100_GPIO_F1_NR,
1694 .label = "GPF1",
1695 },
1696 }, {
1697 .chip = {
1698 .base = S5PC100_GPF2(0),
1699 .ngpio = S5PC100_GPIO_F2_NR,
1700 .label = "GPF2",
1701 },
1702 }, {
1703 .chip = {
1704 .base = S5PC100_GPF3(0),
1705 .ngpio = S5PC100_GPIO_F3_NR,
1706 .label = "GPF3",
1707 },
1708 }, {
1709 .chip = {
1710 .base = S5PC100_GPG0(0),
1711 .ngpio = S5PC100_GPIO_G0_NR,
1712 .label = "GPG0",
1713 },
1714 }, {
1715 .chip = {
1716 .base = S5PC100_GPG1(0),
1717 .ngpio = S5PC100_GPIO_G1_NR,
1718 .label = "GPG1",
1719 },
1720 }, {
1721 .chip = {
1722 .base = S5PC100_GPG2(0),
1723 .ngpio = S5PC100_GPIO_G2_NR,
1724 .label = "GPG2",
1725 },
1726 }, {
1727 .chip = {
1728 .base = S5PC100_GPG3(0),
1729 .ngpio = S5PC100_GPIO_G3_NR,
1730 .label = "GPG3",
1731 },
1732 }, {
1733 .chip = {
1734 .base = S5PC100_GPI(0),
1735 .ngpio = S5PC100_GPIO_I_NR,
1736 .label = "GPI",
1737 },
1738 }, {
1739 .chip = {
1740 .base = S5PC100_GPJ0(0),
1741 .ngpio = S5PC100_GPIO_J0_NR,
1742 .label = "GPJ0",
1743 },
1744 }, {
1745 .chip = {
1746 .base = S5PC100_GPJ1(0),
1747 .ngpio = S5PC100_GPIO_J1_NR,
1748 .label = "GPJ1",
1749 },
1750 }, {
1751 .chip = {
1752 .base = S5PC100_GPJ2(0),
1753 .ngpio = S5PC100_GPIO_J2_NR,
1754 .label = "GPJ2",
1755 },
1756 }, {
1757 .chip = {
1758 .base = S5PC100_GPJ3(0),
1759 .ngpio = S5PC100_GPIO_J3_NR,
1760 .label = "GPJ3",
1761 },
1762 }, {
1763 .chip = {
1764 .base = S5PC100_GPJ4(0),
1765 .ngpio = S5PC100_GPIO_J4_NR,
1766 .label = "GPJ4",
1767 },
1768 }, {
1769 .chip = {
1770 .base = S5PC100_GPK0(0),
1771 .ngpio = S5PC100_GPIO_K0_NR,
1772 .label = "GPK0",
1773 },
1774 }, {
1775 .chip = {
1776 .base = S5PC100_GPK1(0),
1777 .ngpio = S5PC100_GPIO_K1_NR,
1778 .label = "GPK1",
1779 },
1780 }, {
1781 .chip = {
1782 .base = S5PC100_GPK2(0),
1783 .ngpio = S5PC100_GPIO_K2_NR,
1784 .label = "GPK2",
1785 },
1786 }, {
1787 .chip = {
1788 .base = S5PC100_GPK3(0),
1789 .ngpio = S5PC100_GPIO_K3_NR,
1790 .label = "GPK3",
1791 },
1792 }, {
1793 .chip = {
1794 .base = S5PC100_GPL0(0),
1795 .ngpio = S5PC100_GPIO_L0_NR,
1796 .label = "GPL0",
1797 },
1798 }, {
1799 .chip = {
1800 .base = S5PC100_GPL1(0),
1801 .ngpio = S5PC100_GPIO_L1_NR,
1802 .label = "GPL1",
1803 },
1804 }, {
1805 .chip = {
1806 .base = S5PC100_GPL2(0),
1807 .ngpio = S5PC100_GPIO_L2_NR,
1808 .label = "GPL2",
1809 },
1810 }, {
1811 .chip = {
1812 .base = S5PC100_GPL3(0),
1813 .ngpio = S5PC100_GPIO_L3_NR,
1814 .label = "GPL3",
1815 },
1816 }, {
1817 .chip = {
1818 .base = S5PC100_GPL4(0),
1819 .ngpio = S5PC100_GPIO_L4_NR,
1820 .label = "GPL4",
1821 },
1822 }, {
1823 .base = (S5P_VA_GPIO + 0xC00),
1824 .irq_base = IRQ_EINT(0),
1825 .chip = {
1826 .base = S5PC100_GPH0(0),
1827 .ngpio = S5PC100_GPIO_H0_NR,
1828 .label = "GPH0",
1829 .to_irq = samsung_gpiolib_to_irq,
1830 },
1831 }, {
1832 .base = (S5P_VA_GPIO + 0xC20),
1833 .irq_base = IRQ_EINT(8),
1834 .chip = {
1835 .base = S5PC100_GPH1(0),
1836 .ngpio = S5PC100_GPIO_H1_NR,
1837 .label = "GPH1",
1838 .to_irq = samsung_gpiolib_to_irq,
1839 },
1840 }, {
1841 .base = (S5P_VA_GPIO + 0xC40),
1842 .irq_base = IRQ_EINT(16),
1843 .chip = {
1844 .base = S5PC100_GPH2(0),
1845 .ngpio = S5PC100_GPIO_H2_NR,
1846 .label = "GPH2",
1847 .to_irq = samsung_gpiolib_to_irq,
1848 },
1849 }, {
1850 .base = (S5P_VA_GPIO + 0xC60),
1851 .irq_base = IRQ_EINT(24),
1852 .chip = {
1853 .base = S5PC100_GPH3(0),
1854 .ngpio = S5PC100_GPIO_H3_NR,
1855 .label = "GPH3",
1856 .to_irq = samsung_gpiolib_to_irq,
1857 },
1858 },
1859#endif
1860};
1861
1862/*
1863 * Followings are the gpio banks in S5PV210/S5PC110
1864 *
1865 * The 'config' member when left to NULL, is initialized to the default
b391f8cf 1866 * structure samsung_gpio_cfgs[3] in the init function below.
1b39d5f2
KK
1867 *
1868 * The 'base' member is also initialized in the init function below.
1869 * Note: The initialization of 'base' member of samsung_gpio_chip structure
1870 * uses the above macro and depends on the banks being listed in order here.
1871 */
1872
1873static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
1874#ifdef CONFIG_CPU_S5PV210
1875 {
1876 .chip = {
1877 .base = S5PV210_GPA0(0),
1878 .ngpio = S5PV210_GPIO_A0_NR,
1879 .label = "GPA0",
1880 },
1881 }, {
1882 .chip = {
1883 .base = S5PV210_GPA1(0),
1884 .ngpio = S5PV210_GPIO_A1_NR,
1885 .label = "GPA1",
1886 },
1887 }, {
1888 .chip = {
1889 .base = S5PV210_GPB(0),
1890 .ngpio = S5PV210_GPIO_B_NR,
1891 .label = "GPB",
1892 },
1893 }, {
1894 .chip = {
1895 .base = S5PV210_GPC0(0),
1896 .ngpio = S5PV210_GPIO_C0_NR,
1897 .label = "GPC0",
1898 },
1899 }, {
1900 .chip = {
1901 .base = S5PV210_GPC1(0),
1902 .ngpio = S5PV210_GPIO_C1_NR,
1903 .label = "GPC1",
1904 },
1905 }, {
1906 .chip = {
1907 .base = S5PV210_GPD0(0),
1908 .ngpio = S5PV210_GPIO_D0_NR,
1909 .label = "GPD0",
1910 },
1911 }, {
1912 .chip = {
1913 .base = S5PV210_GPD1(0),
1914 .ngpio = S5PV210_GPIO_D1_NR,
1915 .label = "GPD1",
1916 },
1917 }, {
1918 .chip = {
1919 .base = S5PV210_GPE0(0),
1920 .ngpio = S5PV210_GPIO_E0_NR,
1921 .label = "GPE0",
1922 },
1923 }, {
1924 .chip = {
1925 .base = S5PV210_GPE1(0),
1926 .ngpio = S5PV210_GPIO_E1_NR,
1927 .label = "GPE1",
1928 },
1929 }, {
1930 .chip = {
1931 .base = S5PV210_GPF0(0),
1932 .ngpio = S5PV210_GPIO_F0_NR,
1933 .label = "GPF0",
1934 },
1935 }, {
1936 .chip = {
1937 .base = S5PV210_GPF1(0),
1938 .ngpio = S5PV210_GPIO_F1_NR,
1939 .label = "GPF1",
1940 },
1941 }, {
1942 .chip = {
1943 .base = S5PV210_GPF2(0),
1944 .ngpio = S5PV210_GPIO_F2_NR,
1945 .label = "GPF2",
1946 },
1947 }, {
1948 .chip = {
1949 .base = S5PV210_GPF3(0),
1950 .ngpio = S5PV210_GPIO_F3_NR,
1951 .label = "GPF3",
1952 },
1953 }, {
1954 .chip = {
1955 .base = S5PV210_GPG0(0),
1956 .ngpio = S5PV210_GPIO_G0_NR,
1957 .label = "GPG0",
1958 },
1959 }, {
1960 .chip = {
1961 .base = S5PV210_GPG1(0),
1962 .ngpio = S5PV210_GPIO_G1_NR,
1963 .label = "GPG1",
1964 },
1965 }, {
1966 .chip = {
1967 .base = S5PV210_GPG2(0),
1968 .ngpio = S5PV210_GPIO_G2_NR,
1969 .label = "GPG2",
1970 },
1971 }, {
1972 .chip = {
1973 .base = S5PV210_GPG3(0),
1974 .ngpio = S5PV210_GPIO_G3_NR,
1975 .label = "GPG3",
1976 },
1977 }, {
1978 .chip = {
1979 .base = S5PV210_GPI(0),
1980 .ngpio = S5PV210_GPIO_I_NR,
1981 .label = "GPI",
1982 },
1983 }, {
1984 .chip = {
1985 .base = S5PV210_GPJ0(0),
1986 .ngpio = S5PV210_GPIO_J0_NR,
1987 .label = "GPJ0",
1988 },
1989 }, {
1990 .chip = {
1991 .base = S5PV210_GPJ1(0),
1992 .ngpio = S5PV210_GPIO_J1_NR,
1993 .label = "GPJ1",
1994 },
1995 }, {
1996 .chip = {
1997 .base = S5PV210_GPJ2(0),
1998 .ngpio = S5PV210_GPIO_J2_NR,
1999 .label = "GPJ2",
2000 },
2001 }, {
2002 .chip = {
2003 .base = S5PV210_GPJ3(0),
2004 .ngpio = S5PV210_GPIO_J3_NR,
2005 .label = "GPJ3",
2006 },
2007 }, {
2008 .chip = {
2009 .base = S5PV210_GPJ4(0),
2010 .ngpio = S5PV210_GPIO_J4_NR,
2011 .label = "GPJ4",
2012 },
2013 }, {
2014 .chip = {
2015 .base = S5PV210_MP01(0),
2016 .ngpio = S5PV210_GPIO_MP01_NR,
2017 .label = "MP01",
2018 },
2019 }, {
2020 .chip = {
2021 .base = S5PV210_MP02(0),
2022 .ngpio = S5PV210_GPIO_MP02_NR,
2023 .label = "MP02",
2024 },
2025 }, {
2026 .chip = {
2027 .base = S5PV210_MP03(0),
2028 .ngpio = S5PV210_GPIO_MP03_NR,
2029 .label = "MP03",
2030 },
2031 }, {
2032 .chip = {
2033 .base = S5PV210_MP04(0),
2034 .ngpio = S5PV210_GPIO_MP04_NR,
2035 .label = "MP04",
2036 },
2037 }, {
2038 .chip = {
2039 .base = S5PV210_MP05(0),
2040 .ngpio = S5PV210_GPIO_MP05_NR,
2041 .label = "MP05",
2042 },
2043 }, {
2044 .base = (S5P_VA_GPIO + 0xC00),
2045 .irq_base = IRQ_EINT(0),
2046 .chip = {
2047 .base = S5PV210_GPH0(0),
2048 .ngpio = S5PV210_GPIO_H0_NR,
2049 .label = "GPH0",
2050 .to_irq = samsung_gpiolib_to_irq,
2051 },
2052 }, {
2053 .base = (S5P_VA_GPIO + 0xC20),
2054 .irq_base = IRQ_EINT(8),
2055 .chip = {
2056 .base = S5PV210_GPH1(0),
2057 .ngpio = S5PV210_GPIO_H1_NR,
2058 .label = "GPH1",
2059 .to_irq = samsung_gpiolib_to_irq,
2060 },
2061 }, {
2062 .base = (S5P_VA_GPIO + 0xC40),
2063 .irq_base = IRQ_EINT(16),
2064 .chip = {
2065 .base = S5PV210_GPH2(0),
2066 .ngpio = S5PV210_GPIO_H2_NR,
2067 .label = "GPH2",
2068 .to_irq = samsung_gpiolib_to_irq,
2069 },
2070 }, {
2071 .base = (S5P_VA_GPIO + 0xC60),
2072 .irq_base = IRQ_EINT(24),
2073 .chip = {
2074 .base = S5PV210_GPH3(0),
2075 .ngpio = S5PV210_GPIO_H3_NR,
2076 .label = "GPH3",
2077 .to_irq = samsung_gpiolib_to_irq,
2078 },
2079 },
2080#endif
2081};
2082
1b39d5f2
KK
2083/* TODO: cleanup soc_is_* */
2084static __init int samsung_gpiolib_init(void)
2085{
2086 struct samsung_gpio_chip *chip;
2087 int i, nr_chips;
2088 int group = 0;
2089
ba51bdd3 2090 /*
608f9737
TF
2091 * Currently there are two drivers that can provide GPIO support for
2092 * Samsung SoCs. For device tree enabled platforms, the new
2093 * pinctrl-samsung driver is used, providing both GPIO and pin control
2094 * interfaces. For legacy (non-DT) platforms this driver is used.
2095 */
2096 if (of_have_populated_dt())
2097 return -ENODEV;
ba51bdd3 2098
1b39d5f2
KK
2099 samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
2100
2101 if (soc_is_s3c24xx()) {
2102 s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
2103 ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
2104 } else if (soc_is_s3c64xx()) {
2105 samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
2106 ARRAY_SIZE(s3c64xx_gpios_2bit),
2107 S3C64XX_VA_GPIO + 0xE0, 0x20);
2108 samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
2109 ARRAY_SIZE(s3c64xx_gpios_4bit),
2110 S3C64XX_VA_GPIO);
2111 samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
2112 ARRAY_SIZE(s3c64xx_gpios_4bit2));
2113 } else if (soc_is_s5p6440()) {
2114 samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
2115 ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
2116 samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
2117 ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
2118 samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
2119 ARRAY_SIZE(s5p6440_gpios_4bit2));
2120 s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
2121 ARRAY_SIZE(s5p6440_gpios_rbank));
2122 } else if (soc_is_s5p6450()) {
2123 samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
2124 ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
2125 samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
2126 ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
2127 samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
2128 ARRAY_SIZE(s5p6450_gpios_4bit2));
2129 s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
2130 ARRAY_SIZE(s5p6450_gpios_rbank));
2131 } else if (soc_is_s5pc100()) {
2132 group = 0;
2133 chip = s5pc100_gpios_4bit;
2134 nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
2135
2136 for (i = 0; i < nr_chips; i++, chip++) {
2137 if (!chip->config) {
b391f8cf 2138 chip->config = &samsung_gpio_cfgs[3];
1b39d5f2
KK
2139 chip->group = group++;
2140 }
2141 }
2142 samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
2143#if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
2144 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
2145#endif
2146 } else if (soc_is_s5pv210()) {
2147 group = 0;
2148 chip = s5pv210_gpios_4bit;
2149 nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
2150
2151 for (i = 0; i < nr_chips; i++, chip++) {
2152 if (!chip->config) {
b391f8cf 2153 chip->config = &samsung_gpio_cfgs[3];
1b39d5f2
KK
2154 chip->group = group++;
2155 }
2156 }
2157 samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
2158#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
2159 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
2160#endif
fbe92fcc
MB
2161 } else {
2162 WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
2163 return -ENODEV;
1b39d5f2
KK
2164 }
2165
2166 return 0;
2167}
2168core_initcall(samsung_gpiolib_init);
2169
2170int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
2171{
2172 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2173 unsigned long flags;
2174 int offset;
2175 int ret;
2176
2177 if (!chip)
2178 return -EINVAL;
2179
2180 offset = pin - chip->chip.base;
2181
2182 samsung_gpio_lock(chip, flags);
2183 ret = samsung_gpio_do_setcfg(chip, offset, config);
2184 samsung_gpio_unlock(chip, flags);
2185
2186 return ret;
2187}
2188EXPORT_SYMBOL(s3c_gpio_cfgpin);
2189
2190int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
2191 unsigned int cfg)
2192{
2193 int ret;
2194
2195 for (; nr > 0; nr--, start++) {
2196 ret = s3c_gpio_cfgpin(start, cfg);
2197 if (ret != 0)
2198 return ret;
2199 }
2200
2201 return 0;
2202}
2203EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
2204
2205int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
2206 unsigned int cfg, samsung_gpio_pull_t pull)
2207{
2208 int ret;
2209
2210 for (; nr > 0; nr--, start++) {
2211 s3c_gpio_setpull(start, pull);
2212 ret = s3c_gpio_cfgpin(start, cfg);
2213 if (ret != 0)
2214 return ret;
2215 }
2216
2217 return 0;
2218}
2219EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
2220
2221unsigned s3c_gpio_getcfg(unsigned int pin)
2222{
2223 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2224 unsigned long flags;
2225 unsigned ret = 0;
2226 int offset;
2227
2228 if (chip) {
2229 offset = pin - chip->chip.base;
2230
2231 samsung_gpio_lock(chip, flags);
2232 ret = samsung_gpio_do_getcfg(chip, offset);
2233 samsung_gpio_unlock(chip, flags);
2234 }
2235
2236 return ret;
2237}
2238EXPORT_SYMBOL(s3c_gpio_getcfg);
2239
2240int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
2241{
2242 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2243 unsigned long flags;
2244 int offset, ret;
2245
2246 if (!chip)
2247 return -EINVAL;
2248
2249 offset = pin - chip->chip.base;
2250
2251 samsung_gpio_lock(chip, flags);
2252 ret = samsung_gpio_do_setpull(chip, offset, pull);
2253 samsung_gpio_unlock(chip, flags);
2254
2255 return ret;
2256}
2257EXPORT_SYMBOL(s3c_gpio_setpull);
2258
2259samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
2260{
2261 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2262 unsigned long flags;
2263 int offset;
2264 u32 pup = 0;
2265
2266 if (chip) {
2267 offset = pin - chip->chip.base;
2268
2269 samsung_gpio_lock(chip, flags);
2270 pup = samsung_gpio_do_getpull(chip, offset);
2271 samsung_gpio_unlock(chip, flags);
2272 }
2273
2274 return (__force samsung_gpio_pull_t)pup;
2275}
2276EXPORT_SYMBOL(s3c_gpio_getpull);
2277
1b39d5f2
KK
2278#ifdef CONFIG_S5P_GPIO_DRVSTR
2279s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
2280{
2281 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2282 unsigned int off;
2283 void __iomem *reg;
2284 int shift;
2285 u32 drvstr;
2286
2287 if (!chip)
2288 return -EINVAL;
2289
2290 off = pin - chip->chip.base;
2291 shift = off * 2;
2292 reg = chip->base + 0x0C;
2293
2294 drvstr = __raw_readl(reg);
2295 drvstr = drvstr >> shift;
2296 drvstr &= 0x3;
2297
2298 return (__force s5p_gpio_drvstr_t)drvstr;
2299}
2300EXPORT_SYMBOL(s5p_gpio_get_drvstr);
2301
2302int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
2303{
2304 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2305 unsigned int off;
2306 void __iomem *reg;
2307 int shift;
2308 u32 tmp;
2309
2310 if (!chip)
2311 return -EINVAL;
2312
2313 off = pin - chip->chip.base;
2314 shift = off * 2;
2315 reg = chip->base + 0x0C;
2316
2317 tmp = __raw_readl(reg);
2318 tmp &= ~(0x3 << shift);
2319 tmp |= drvstr << shift;
2320
2321 __raw_writel(tmp, reg);
2322
2323 return 0;
2324}
2325EXPORT_SYMBOL(s5p_gpio_set_drvstr);
2326#endif /* CONFIG_S5P_GPIO_DRVSTR */
2327
2328#ifdef CONFIG_PLAT_S3C24XX
2329unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
2330{
2331 unsigned long flags;
2332 unsigned long misccr;
2333
2334 local_irq_save(flags);
2335 misccr = __raw_readl(S3C24XX_MISCCR);
2336 misccr &= ~clear;
2337 misccr ^= change;
2338 __raw_writel(misccr, S3C24XX_MISCCR);
2339 local_irq_restore(flags);
2340
2341 return misccr;
2342}
2343EXPORT_SYMBOL(s3c2410_modify_misccr);
2344#endif
This page took 0.193388 seconds and 5 git commands to generate.