Merge branch 'l2x0-pull-rmk' of git://dev.omapzoom.org/pub/scm/santosh/kernel-omap4...
[pandora-kernel.git] / arch / arm / mach-s5pc100 / gpiolib.c
1 /* linux/arch/arm/mach-s5pc100/gpiolib.c
2  *
3  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com
5  *
6  *  Copyright 2009 Samsung Electronics Co
7  *  Kyungmin Park <kyungmin.park@samsung.com>
8  *
9  * S5PC100 - GPIOlib support
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/irq.h>
18 #include <linux/io.h>
19 #include <linux/gpio.h>
20
21 #include <mach/map.h>
22 #include <mach/regs-gpio.h>
23
24 #include <plat/gpio-core.h>
25 #include <plat/gpio-cfg.h>
26 #include <plat/gpio-cfg-helpers.h>
27
28 /* S5PC100 GPIO bank summary:
29  *
30  * Bank GPIOs   Style   INT Type
31  * A0   8       4Bit    GPIO_INT0
32  * A1   5       4Bit    GPIO_INT1
33  * B    8       4Bit    GPIO_INT2
34  * C    5       4Bit    GPIO_INT3
35  * D    7       4Bit    GPIO_INT4
36  * E0   8       4Bit    GPIO_INT5
37  * E1   6       4Bit    GPIO_INT6
38  * F0   8       4Bit    GPIO_INT7
39  * F1   8       4Bit    GPIO_INT8
40  * F2   8       4Bit    GPIO_INT9
41  * F3   4       4Bit    GPIO_INT10
42  * G0   8       4Bit    GPIO_INT11
43  * G1   3       4Bit    GPIO_INT12
44  * G2   7       4Bit    GPIO_INT13
45  * G3   7       4Bit    GPIO_INT14
46  * H0   8       4Bit    WKUP_INT
47  * H1   8       4Bit    WKUP_INT
48  * H2   8       4Bit    WKUP_INT
49  * H3   8       4Bit    WKUP_INT
50  * I    8       4Bit    GPIO_INT15
51  * J0   8       4Bit    GPIO_INT16
52  * J1   5       4Bit    GPIO_INT17
53  * J2   8       4Bit    GPIO_INT18
54  * J3   8       4Bit    GPIO_INT19
55  * J4   4       4Bit    GPIO_INT20
56  * K0   8       4Bit    None
57  * K1   6       4Bit    None
58  * K2   8       4Bit    None
59  * K3   8       4Bit    None
60  * L0   8       4Bit    None
61  * L1   8       4Bit    None
62  * L2   8       4Bit    None
63  * L3   8       4Bit    None
64  */
65
66 static struct s3c_gpio_cfg gpio_cfg = {
67         .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
68         .set_pull       = s3c_gpio_setpull_updown,
69         .get_pull       = s3c_gpio_getpull_updown,
70 };
71
72 static struct s3c_gpio_cfg gpio_cfg_eint = {
73         .cfg_eint       = 0xf,
74         .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
75         .set_pull       = s3c_gpio_setpull_updown,
76         .get_pull       = s3c_gpio_getpull_updown,
77 };
78
79 static struct s3c_gpio_cfg gpio_cfg_noint = {
80         .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
81         .set_pull       = s3c_gpio_setpull_updown,
82         .get_pull       = s3c_gpio_getpull_updown,
83 };
84
85 /*
86  * GPIO bank's base address given the index of the bank in the
87  * list of all gpio banks.
88  */
89 #define S5PC100_BANK_BASE(bank_nr)      (S5P_VA_GPIO + ((bank_nr) * 0x20))
90
91 /*
92  * Following are the gpio banks in S5PC100.
93  *
94  * The 'config' member when left to NULL, is initialized to the default
95  * structure gpio_cfg in the init function below.
96  *
97  * The 'base' member is also initialized in the init function below.
98  * Note: The initialization of 'base' member of s3c_gpio_chip structure
99  * uses the above macro and depends on the banks being listed in order here.
100  */
101 static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
102         {
103                 .chip   = {
104                         .base   = S5PC100_GPA0(0),
105                         .ngpio  = S5PC100_GPIO_A0_NR,
106                         .label  = "GPA0",
107                 },
108         }, {
109                 .chip   = {
110                         .base   = S5PC100_GPA1(0),
111                         .ngpio  = S5PC100_GPIO_A1_NR,
112                         .label  = "GPA1",
113                 },
114         }, {
115                 .chip   = {
116                         .base   = S5PC100_GPB(0),
117                         .ngpio  = S5PC100_GPIO_B_NR,
118                         .label  = "GPB",
119                 },
120         }, {
121                 .chip   = {
122                         .base   = S5PC100_GPC(0),
123                         .ngpio  = S5PC100_GPIO_C_NR,
124                         .label  = "GPC",
125                 },
126         }, {
127                 .chip   = {
128                         .base   = S5PC100_GPD(0),
129                         .ngpio  = S5PC100_GPIO_D_NR,
130                         .label  = "GPD",
131                 },
132         }, {
133                 .chip   = {
134                         .base   = S5PC100_GPE0(0),
135                         .ngpio  = S5PC100_GPIO_E0_NR,
136                         .label  = "GPE0",
137                 },
138         }, {
139                 .chip   = {
140                         .base   = S5PC100_GPE1(0),
141                         .ngpio  = S5PC100_GPIO_E1_NR,
142                         .label  = "GPE1",
143                 },
144         }, {
145                 .chip   = {
146                         .base   = S5PC100_GPF0(0),
147                         .ngpio  = S5PC100_GPIO_F0_NR,
148                         .label  = "GPF0",
149                 },
150         }, {
151                 .chip   = {
152                         .base   = S5PC100_GPF1(0),
153                         .ngpio  = S5PC100_GPIO_F1_NR,
154                         .label  = "GPF1",
155                 },
156         }, {
157                 .chip   = {
158                         .base   = S5PC100_GPF2(0),
159                         .ngpio  = S5PC100_GPIO_F2_NR,
160                         .label  = "GPF2",
161                 },
162         }, {
163                 .chip   = {
164                         .base   = S5PC100_GPF3(0),
165                         .ngpio  = S5PC100_GPIO_F3_NR,
166                         .label  = "GPF3",
167                 },
168         }, {
169                 .chip   = {
170                         .base   = S5PC100_GPG0(0),
171                         .ngpio  = S5PC100_GPIO_G0_NR,
172                         .label  = "GPG0",
173                 },
174         }, {
175                 .chip   = {
176                         .base   = S5PC100_GPG1(0),
177                         .ngpio  = S5PC100_GPIO_G1_NR,
178                         .label  = "GPG1",
179                 },
180         }, {
181                 .chip   = {
182                         .base   = S5PC100_GPG2(0),
183                         .ngpio  = S5PC100_GPIO_G2_NR,
184                         .label  = "GPG2",
185                 },
186         }, {
187                 .chip   = {
188                         .base   = S5PC100_GPG3(0),
189                         .ngpio  = S5PC100_GPIO_G3_NR,
190                         .label  = "GPG3",
191                 },
192         }, {
193                 .chip   = {
194                         .base   = S5PC100_GPI(0),
195                         .ngpio  = S5PC100_GPIO_I_NR,
196                         .label  = "GPI",
197                 },
198         }, {
199                 .chip   = {
200                         .base   = S5PC100_GPJ0(0),
201                         .ngpio  = S5PC100_GPIO_J0_NR,
202                         .label  = "GPJ0",
203                 },
204         }, {
205                 .chip   = {
206                         .base   = S5PC100_GPJ1(0),
207                         .ngpio  = S5PC100_GPIO_J1_NR,
208                         .label  = "GPJ1",
209                 },
210         }, {
211                 .chip   = {
212                         .base   = S5PC100_GPJ2(0),
213                         .ngpio  = S5PC100_GPIO_J2_NR,
214                         .label  = "GPJ2",
215                 },
216         }, {
217                 .chip   = {
218                         .base   = S5PC100_GPJ3(0),
219                         .ngpio  = S5PC100_GPIO_J3_NR,
220                         .label  = "GPJ3",
221                 },
222         }, {
223                 .chip   = {
224                         .base   = S5PC100_GPJ4(0),
225                         .ngpio  = S5PC100_GPIO_J4_NR,
226                         .label  = "GPJ4",
227                 },
228         }, {
229                 .config = &gpio_cfg_noint,
230                 .chip   = {
231                         .base   = S5PC100_GPK0(0),
232                         .ngpio  = S5PC100_GPIO_K0_NR,
233                         .label  = "GPK0",
234                 },
235         }, {
236                 .config = &gpio_cfg_noint,
237                 .chip   = {
238                         .base   = S5PC100_GPK1(0),
239                         .ngpio  = S5PC100_GPIO_K1_NR,
240                         .label  = "GPK1",
241                 },
242         }, {
243                 .config = &gpio_cfg_noint,
244                 .chip   = {
245                         .base   = S5PC100_GPK2(0),
246                         .ngpio  = S5PC100_GPIO_K2_NR,
247                         .label  = "GPK2",
248                 },
249         }, {
250                 .config = &gpio_cfg_noint,
251                 .chip   = {
252                         .base   = S5PC100_GPK3(0),
253                         .ngpio  = S5PC100_GPIO_K3_NR,
254                         .label  = "GPK3",
255                 },
256         }, {
257                 .config = &gpio_cfg_noint,
258                 .chip   = {
259                         .base   = S5PC100_GPL0(0),
260                         .ngpio  = S5PC100_GPIO_L0_NR,
261                         .label  = "GPL0",
262                 },
263         }, {
264                 .config = &gpio_cfg_noint,
265                 .chip   = {
266                         .base   = S5PC100_GPL1(0),
267                         .ngpio  = S5PC100_GPIO_L1_NR,
268                         .label  = "GPL1",
269                 },
270         }, {
271                 .config = &gpio_cfg_noint,
272                 .chip   = {
273                         .base   = S5PC100_GPL2(0),
274                         .ngpio  = S5PC100_GPIO_L2_NR,
275                         .label  = "GPL2",
276                 },
277         }, {
278                 .config = &gpio_cfg_noint,
279                 .chip   = {
280                         .base   = S5PC100_GPL3(0),
281                         .ngpio  = S5PC100_GPIO_L3_NR,
282                         .label  = "GPL3",
283                 },
284         }, {
285                 .config = &gpio_cfg_noint,
286                 .chip   = {
287                         .base   = S5PC100_GPL4(0),
288                         .ngpio  = S5PC100_GPIO_L4_NR,
289                         .label  = "GPL4",
290                 },
291         }, {
292                 .base   = (S5P_VA_GPIO + 0xC00),
293                 .config = &gpio_cfg_eint,
294                 .irq_base = IRQ_EINT(0),
295                 .chip   = {
296                         .base   = S5PC100_GPH0(0),
297                         .ngpio  = S5PC100_GPIO_H0_NR,
298                         .label  = "GPH0",
299                         .to_irq = samsung_gpiolib_to_irq,
300                 },
301         }, {
302                 .base   = (S5P_VA_GPIO + 0xC20),
303                 .config = &gpio_cfg_eint,
304                 .irq_base = IRQ_EINT(8),
305                 .chip   = {
306                         .base   = S5PC100_GPH1(0),
307                         .ngpio  = S5PC100_GPIO_H1_NR,
308                         .label  = "GPH1",
309                         .to_irq = samsung_gpiolib_to_irq,
310                 },
311         }, {
312                 .base   = (S5P_VA_GPIO + 0xC40),
313                 .config = &gpio_cfg_eint,
314                 .irq_base = IRQ_EINT(16),
315                 .chip   = {
316                         .base   = S5PC100_GPH2(0),
317                         .ngpio  = S5PC100_GPIO_H2_NR,
318                         .label  = "GPH2",
319                         .to_irq = samsung_gpiolib_to_irq,
320                 },
321         }, {
322                 .base   = (S5P_VA_GPIO + 0xC60),
323                 .config = &gpio_cfg_eint,
324                 .irq_base = IRQ_EINT(24),
325                 .chip   = {
326                         .base   = S5PC100_GPH3(0),
327                         .ngpio  = S5PC100_GPIO_H3_NR,
328                         .label  = "GPH3",
329                         .to_irq = samsung_gpiolib_to_irq,
330                 },
331         },
332 };
333
334 static __init int s5pc100_gpiolib_init(void)
335 {
336         struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
337         int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
338         int gpioint_group = 0;
339         int i;
340
341         for (i = 0; i < nr_chips; i++, chip++) {
342                 if (chip->config == NULL) {
343                         chip->config = &gpio_cfg;
344                         chip->group = gpioint_group++;
345                 }
346                 if (chip->base == NULL)
347                         chip->base = S5PC100_BANK_BASE(i);
348         }
349
350         samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
351
352         return 0;
353 }
354 core_initcall(s5pc100_gpiolib_init);