ARM: S5PC100: Move gpio support from plat-s5pc1xx to mach-s5pc100
[linux-2.6-microblaze.git] / arch / arm / mach-s5pc100 / gpiolib.c
1 /*
2  * arch/arm/plat-s5pc1xx/gpiolib.c
3  *
4  *  Copyright 2009 Samsung Electronics Co
5  *  Kyungmin Park <kyungmin.park@samsung.com>
6  *
7  * S5PC1XX - GPIOlib support
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/irq.h>
16 #include <linux/io.h>
17 #include <linux/gpio.h>
18
19 #include <mach/map.h>
20 #include <mach/regs-gpio.h>
21
22 #include <plat/gpio-core.h>
23 #include <plat/gpio-cfg.h>
24 #include <plat/gpio-cfg-helpers.h>
25
26 /* S5PC100 GPIO bank summary:
27  *
28  * Bank GPIOs   Style   INT Type
29  * A0   8       4Bit    GPIO_INT0
30  * A1   5       4Bit    GPIO_INT1
31  * B    8       4Bit    GPIO_INT2
32  * C    5       4Bit    GPIO_INT3
33  * D    7       4Bit    GPIO_INT4
34  * E0   8       4Bit    GPIO_INT5
35  * E1   6       4Bit    GPIO_INT6
36  * F0   8       4Bit    GPIO_INT7
37  * F1   8       4Bit    GPIO_INT8
38  * F2   8       4Bit    GPIO_INT9
39  * F3   4       4Bit    GPIO_INT10
40  * G0   8       4Bit    GPIO_INT11
41  * G1   3       4Bit    GPIO_INT12
42  * G2   7       4Bit    GPIO_INT13
43  * G3   7       4Bit    GPIO_INT14
44  * H0   8       4Bit    WKUP_INT
45  * H1   8       4Bit    WKUP_INT
46  * H2   8       4Bit    WKUP_INT
47  * H3   8       4Bit    WKUP_INT
48  * I    8       4Bit    GPIO_INT15
49  * J0   8       4Bit    GPIO_INT16
50  * J1   5       4Bit    GPIO_INT17
51  * J2   8       4Bit    GPIO_INT18
52  * J3   8       4Bit    GPIO_INT19
53  * J4   4       4Bit    GPIO_INT20
54  * K0   8       4Bit    None
55  * K1   6       4Bit    None
56  * K2   8       4Bit    None
57  * K3   8       4Bit    None
58  * L0   8       4Bit    None
59  * L1   8       4Bit    None
60  * L2   8       4Bit    None
61  * L3   8       4Bit    None
62  */
63
64 #if 0
65 static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
66 {
67         return S3C_IRQ_GPIO(chip->base + offset);
68 }
69
70 static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
71 {
72         int base;
73
74         base = chip->base - S5PC100_GPH0(0);
75         if (base == 0)
76                 return IRQ_EINT(offset);
77         base = chip->base - S5PC100_GPH1(0);
78         if (base == 0)
79                 return IRQ_EINT(8 + offset);
80         base = chip->base - S5PC100_GPH2(0);
81         if (base == 0)
82                 return IRQ_EINT(16 + offset);
83         base = chip->base - S5PC100_GPH3(0);
84         if (base == 0)
85                 return IRQ_EINT(24 + offset);
86         return -EINVAL;
87 }
88 #endif
89 static struct s3c_gpio_cfg gpio_cfg = {
90         .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
91         .set_pull       = s3c_gpio_setpull_updown,
92         .get_pull       = s3c_gpio_getpull_updown,
93 };
94
95 static struct s3c_gpio_cfg gpio_cfg_eint = {
96         .cfg_eint       = 0xf,
97         .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
98         .set_pull       = s3c_gpio_setpull_updown,
99         .get_pull       = s3c_gpio_getpull_updown,
100 };
101
102 static struct s3c_gpio_cfg gpio_cfg_noint = {
103         .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
104         .set_pull       = s3c_gpio_setpull_updown,
105         .get_pull       = s3c_gpio_getpull_updown,
106 };
107
108 static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
109         {
110                 .base   = S5PC100_GPA0_BASE,
111                 .config = &gpio_cfg,
112                 .chip   = {
113                         .base   = S5PC100_GPA0(0),
114                         .ngpio  = S5PC100_GPIO_A0_NR,
115                         .label  = "GPA0",
116                 },
117         }, {
118                 .base   = S5PC100_GPA1_BASE,
119                 .config = &gpio_cfg,
120                 .chip   = {
121                         .base   = S5PC100_GPA1(0),
122                         .ngpio  = S5PC100_GPIO_A1_NR,
123                         .label  = "GPA1",
124                 },
125         }, {
126                 .base   = S5PC100_GPB_BASE,
127                 .config = &gpio_cfg,
128                 .chip   = {
129                         .base   = S5PC100_GPB(0),
130                         .ngpio  = S5PC100_GPIO_B_NR,
131                         .label  = "GPB",
132                 },
133         }, {
134                 .base   = S5PC100_GPC_BASE,
135                 .config = &gpio_cfg,
136                 .chip   = {
137                         .base   = S5PC100_GPC(0),
138                         .ngpio  = S5PC100_GPIO_C_NR,
139                         .label  = "GPC",
140                 },
141         }, {
142                 .base   = S5PC100_GPD_BASE,
143                 .config = &gpio_cfg,
144                 .chip   = {
145                         .base   = S5PC100_GPD(0),
146                         .ngpio  = S5PC100_GPIO_D_NR,
147                         .label  = "GPD",
148                 },
149         }, {
150                 .base   = S5PC100_GPE0_BASE,
151                 .config = &gpio_cfg,
152                 .chip   = {
153                         .base   = S5PC100_GPE0(0),
154                         .ngpio  = S5PC100_GPIO_E0_NR,
155                         .label  = "GPE0",
156                 },
157         }, {
158                 .base   = S5PC100_GPE1_BASE,
159                 .config = &gpio_cfg,
160                 .chip   = {
161                         .base   = S5PC100_GPE1(0),
162                         .ngpio  = S5PC100_GPIO_E1_NR,
163                         .label  = "GPE1",
164                 },
165         }, {
166                 .base   = S5PC100_GPF0_BASE,
167                 .config = &gpio_cfg,
168                 .chip   = {
169                         .base   = S5PC100_GPF0(0),
170                         .ngpio  = S5PC100_GPIO_F0_NR,
171                         .label  = "GPF0",
172                 },
173         }, {
174                 .base   = S5PC100_GPF1_BASE,
175                 .config = &gpio_cfg,
176                 .chip   = {
177                         .base   = S5PC100_GPF1(0),
178                         .ngpio  = S5PC100_GPIO_F1_NR,
179                         .label  = "GPF1",
180                 },
181         }, {
182                 .base   = S5PC100_GPF2_BASE,
183                 .config = &gpio_cfg,
184                 .chip   = {
185                         .base   = S5PC100_GPF2(0),
186                         .ngpio  = S5PC100_GPIO_F2_NR,
187                         .label  = "GPF2",
188                 },
189         }, {
190                 .base   = S5PC100_GPF3_BASE,
191                 .config = &gpio_cfg,
192                 .chip   = {
193                         .base   = S5PC100_GPF3(0),
194                         .ngpio  = S5PC100_GPIO_F3_NR,
195                         .label  = "GPF3",
196                 },
197         }, {
198                 .base   = S5PC100_GPG0_BASE,
199                 .config = &gpio_cfg,
200                 .chip   = {
201                         .base   = S5PC100_GPG0(0),
202                         .ngpio  = S5PC100_GPIO_G0_NR,
203                         .label  = "GPG0",
204                 },
205         }, {
206                 .base   = S5PC100_GPG1_BASE,
207                 .config = &gpio_cfg,
208                 .chip   = {
209                         .base   = S5PC100_GPG1(0),
210                         .ngpio  = S5PC100_GPIO_G1_NR,
211                         .label  = "GPG1",
212                 },
213         }, {
214                 .base   = S5PC100_GPG2_BASE,
215                 .config = &gpio_cfg,
216                 .chip   = {
217                         .base   = S5PC100_GPG2(0),
218                         .ngpio  = S5PC100_GPIO_G2_NR,
219                         .label  = "GPG2",
220                 },
221         }, {
222                 .base   = S5PC100_GPG3_BASE,
223                 .config = &gpio_cfg,
224                 .chip   = {
225                         .base   = S5PC100_GPG3(0),
226                         .ngpio  = S5PC100_GPIO_G3_NR,
227                         .label  = "GPG3",
228                 },
229         }, {
230                 .base   = S5PC100_GPH0_BASE,
231                 .config = &gpio_cfg_eint,
232                 .chip   = {
233                         .base   = S5PC100_GPH0(0),
234                         .ngpio  = S5PC100_GPIO_H0_NR,
235                         .label  = "GPH0",
236                 },
237         }, {
238                 .base   = S5PC100_GPH1_BASE,
239                 .config = &gpio_cfg_eint,
240                 .chip   = {
241                         .base   = S5PC100_GPH1(0),
242                         .ngpio  = S5PC100_GPIO_H1_NR,
243                         .label  = "GPH1",
244                 },
245         }, {
246                 .base   = S5PC100_GPH2_BASE,
247                 .config = &gpio_cfg_eint,
248                 .chip   = {
249                         .base   = S5PC100_GPH2(0),
250                         .ngpio  = S5PC100_GPIO_H2_NR,
251                         .label  = "GPH2",
252                 },
253         }, {
254                 .base   = S5PC100_GPH3_BASE,
255                 .config = &gpio_cfg_eint,
256                 .chip   = {
257                         .base   = S5PC100_GPH3(0),
258                         .ngpio  = S5PC100_GPIO_H3_NR,
259                         .label  = "GPH3",
260                 },
261         }, {
262                 .base   = S5PC100_GPI_BASE,
263                 .config = &gpio_cfg,
264                 .chip   = {
265                         .base   = S5PC100_GPI(0),
266                         .ngpio  = S5PC100_GPIO_I_NR,
267                         .label  = "GPI",
268                 },
269         }, {
270                 .base   = S5PC100_GPJ0_BASE,
271                 .config = &gpio_cfg,
272                 .chip   = {
273                         .base   = S5PC100_GPJ0(0),
274                         .ngpio  = S5PC100_GPIO_J0_NR,
275                         .label  = "GPJ0",
276                 },
277         }, {
278                 .base   = S5PC100_GPJ1_BASE,
279                 .config = &gpio_cfg,
280                 .chip   = {
281                         .base   = S5PC100_GPJ1(0),
282                         .ngpio  = S5PC100_GPIO_J1_NR,
283                         .label  = "GPJ1",
284                 },
285         }, {
286                 .base   = S5PC100_GPJ2_BASE,
287                 .config = &gpio_cfg,
288                 .chip   = {
289                         .base   = S5PC100_GPJ2(0),
290                         .ngpio  = S5PC100_GPIO_J2_NR,
291                         .label  = "GPJ2",
292                 },
293         }, {
294                 .base   = S5PC100_GPJ3_BASE,
295                 .config = &gpio_cfg,
296                 .chip   = {
297                         .base   = S5PC100_GPJ3(0),
298                         .ngpio  = S5PC100_GPIO_J3_NR,
299                         .label  = "GPJ3",
300                 },
301         }, {
302                 .base   = S5PC100_GPJ4_BASE,
303                 .config = &gpio_cfg,
304                 .chip   = {
305                         .base   = S5PC100_GPJ4(0),
306                         .ngpio  = S5PC100_GPIO_J4_NR,
307                         .label  = "GPJ4",
308                 },
309         }, {
310                 .base   = S5PC100_GPK0_BASE,
311                 .config = &gpio_cfg_noint,
312                 .chip   = {
313                         .base   = S5PC100_GPK0(0),
314                         .ngpio  = S5PC100_GPIO_K0_NR,
315                         .label  = "GPK0",
316                 },
317         }, {
318                 .base   = S5PC100_GPK1_BASE,
319                 .config = &gpio_cfg_noint,
320                 .chip   = {
321                         .base   = S5PC100_GPK1(0),
322                         .ngpio  = S5PC100_GPIO_K1_NR,
323                         .label  = "GPK1",
324                 },
325         }, {
326                 .base   = S5PC100_GPK2_BASE,
327                 .config = &gpio_cfg_noint,
328                 .chip   = {
329                         .base   = S5PC100_GPK2(0),
330                         .ngpio  = S5PC100_GPIO_K2_NR,
331                         .label  = "GPK2",
332                 },
333         }, {
334                 .base   = S5PC100_GPK3_BASE,
335                 .config = &gpio_cfg_noint,
336                 .chip   = {
337                         .base   = S5PC100_GPK3(0),
338                         .ngpio  = S5PC100_GPIO_K3_NR,
339                         .label  = "GPK3",
340                 },
341         }, {
342                 .base   = S5PC100_GPL0_BASE,
343                 .config = &gpio_cfg_noint,
344                 .chip   = {
345                         .base   = S5PC100_GPL0(0),
346                         .ngpio  = S5PC100_GPIO_L0_NR,
347                         .label  = "GPL0",
348                 },
349         }, {
350                 .base   = S5PC100_GPL1_BASE,
351                 .config = &gpio_cfg_noint,
352                 .chip   = {
353                         .base   = S5PC100_GPL1(0),
354                         .ngpio  = S5PC100_GPIO_L1_NR,
355                         .label  = "GPL1",
356                 },
357         }, {
358                 .base   = S5PC100_GPL2_BASE,
359                 .config = &gpio_cfg_noint,
360                 .chip   = {
361                         .base   = S5PC100_GPL2(0),
362                         .ngpio  = S5PC100_GPIO_L2_NR,
363                         .label  = "GPL2",
364                 },
365         }, {
366                 .base   = S5PC100_GPL3_BASE,
367                 .config = &gpio_cfg_noint,
368                 .chip   = {
369                         .base   = S5PC100_GPL3(0),
370                         .ngpio  = S5PC100_GPIO_L3_NR,
371                         .label  = "GPL3",
372                 },
373         }, {
374                 .base   = S5PC100_GPL4_BASE,
375                 .config = &gpio_cfg_noint,
376                 .chip   = {
377                         .base   = S5PC100_GPL4(0),
378                         .ngpio  = S5PC100_GPIO_L4_NR,
379                         .label  = "GPL4",
380                 },
381         },
382 };
383
384 /* FIXME move from irq-gpio.c */
385 extern struct irq_chip s5pc1xx_gpioint;
386 extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
387
388 static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip)
389 {
390 #if 0
391         /* Interrupt */
392         if (chip->config == &gpio_cfg) {
393                 int i, irq;
394
395                 chip->chip.to_irq = s5pc1xx_gpiolib_to_irq;
396
397                 for (i = 0;  i < chip->chip.ngpio; i++) {
398                         irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
399                         set_irq_chip(irq, &s5pc1xx_gpioint);
400                         set_irq_data(irq, &chip->chip);
401                         set_irq_handler(irq, handle_level_irq);
402                         set_irq_flags(irq, IRQF_VALID);
403                 }
404         } else if (chip->config == &gpio_cfg_eint)
405                 chip->chip.to_irq = s5pc1xx_gpiolib_to_eint;
406 #endif
407 }
408
409 static __init int s5pc1xx_gpiolib_init(void)
410 {
411         struct s3c_gpio_chip *chip;
412         int nr_chips;
413
414         chip = s5pc100_gpio_chips;
415         nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
416
417         for (; nr_chips > 0; nr_chips--, chip++)
418                 s5pc100_gpiolib_link(chip);
419
420         samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips,
421                                        ARRAY_SIZE(s5pc100_gpio_chips));
422 #if 0
423         /* Interrupt */
424         set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler);
425 #endif
426         return 0;
427 }
428 core_initcall(s5pc1xx_gpiolib_init);