629b987585ded28ca58ec6a9a5b96a823dc3c2f2
[linux-2.6.34-lpc32xx.git] / arch / arm / mach-lpc32xx / gpiolib.c
1 /*
2  * arch/arm/mach-lpc32xx/gpiolib.c
3  *
4  * Author: Kevin Wells <kevin.wells@nxp.com>
5  *
6  * Copyright (C) 2010 NXP Semiconductors
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/io.h>
22 #include <linux/errno.h>
23 #include <linux/gpio.h>
24
25 #include <mach/hardware.h>
26 #include <mach/platform.h>
27 #include "common.h"
28
29 #define LPC32XX_GPIO_P3_INP_STATE               _GPREG(0x000)
30 #define LPC32XX_GPIO_P3_OUTP_SET                _GPREG(0x004)
31 #define LPC32XX_GPIO_P3_OUTP_CLR                _GPREG(0x008)
32 #define LPC32XX_GPIO_P3_OUTP_STATE              _GPREG(0x00C)
33 #define LPC32XX_GPIO_P2_DIR_SET                 _GPREG(0x010)
34 #define LPC32XX_GPIO_P2_DIR_CLR                 _GPREG(0x014)
35 #define LPC32XX_GPIO_P2_DIR_STATE               _GPREG(0x018)
36 #define LPC32XX_GPIO_P2_INP_STATE               _GPREG(0x01C)
37 #define LPC32XX_GPIO_P2_OUTP_SET                _GPREG(0x020)
38 #define LPC32XX_GPIO_P2_OUTP_CLR                _GPREG(0x024)
39 #define LPC32XX_GPIO_P0_INP_STATE               _GPREG(0x040)
40 #define LPC32XX_GPIO_P0_OUTP_SET                _GPREG(0x044)
41 #define LPC32XX_GPIO_P0_OUTP_CLR                _GPREG(0x048)
42 #define LPC32XX_GPIO_P0_OUTP_STATE              _GPREG(0x04C)
43 #define LPC32XX_GPIO_P0_DIR_SET                 _GPREG(0x050)
44 #define LPC32XX_GPIO_P0_DIR_CLR                 _GPREG(0x054)
45 #define LPC32XX_GPIO_P0_DIR_STATE               _GPREG(0x058)
46 #define LPC32XX_GPIO_P1_INP_STATE               _GPREG(0x060)
47 #define LPC32XX_GPIO_P1_OUTP_SET                _GPREG(0x064)
48 #define LPC32XX_GPIO_P1_OUTP_CLR                _GPREG(0x068)
49 #define LPC32XX_GPIO_P1_OUTP_STATE              _GPREG(0x06C)
50 #define LPC32XX_GPIO_P1_DIR_SET                 _GPREG(0x070)
51 #define LPC32XX_GPIO_P1_DIR_CLR                 _GPREG(0x074)
52 #define LPC32XX_GPIO_P1_DIR_STATE               _GPREG(0x078)
53
54 #define GPIO012_PIN_TO_BIT(x)                   (1 << (x))
55 #define GPIO3_PIN_TO_BIT(x)                     (1 << ((x) + 25))
56 #define GPO3_PIN_TO_BIT(x)                      (1 << (x))
57 #define GPIO012_PIN_IN_SEL(x, y)                (((x) >> (y)) & 1)
58 #define GPIO3_PIN_IN_SHIFT(x)                   ((x) == 5 ? 24 : 10 + (x))
59 #define GPIO3_PIN_IN_SEL(x, y)                  (((x) >> GPIO3_PIN_IN_SHIFT(y)) & 1)
60 #define GPIO3_PIN5_IN_SEL(x)                    (((x) >> 24) & 1)
61 #define GPI3_PIN_IN_SEL(x, y)                   (((x) >> (y)) & 1)
62
63 struct gpio_regs {
64         void __iomem *inp_state;
65         void __iomem *outp_set;
66         void __iomem *outp_clr;
67         void __iomem *dir_set;
68         void __iomem *dir_clr;
69 };
70
71 /*
72  * GPIO names
73  */
74 static char *gpio_p0_names[LPC32XX_GPIO_P0_MAX] = {
75         "p0.0", "p0.1", "p0.2", "p0.3",
76         "p0.4", "p0.5", "p0.6", "p0.7"
77 };
78
79 static char *gpio_p1_names[LPC32XX_GPIO_P1_MAX] = {
80         "p1.0", "p1.1", "p1.2", "p1.3",
81         "p1.4", "p1.5", "p1.6", "p1.7",
82         "p1.8", "p1.9", "p1.10", "p1.11",
83         "p1.12", "p1.13", "p1.14", "p1.15",
84         "p1.16", "p1.17", "p1.18", "p1.19",
85         "p1.20", "p1.21", "p1.22", "p1.23",
86 };
87
88 static char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = {
89         "p2.0", "p2.1", "p2.2", "p2.3",
90         "p2.4", "p2.5", "p2.6", "p2.7",
91         "p2.8", "p2.9", "p2.10", "p2.11",
92         "p2.12"
93 };
94
95 static char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = {
96         "gpio00", "gpio01", "gpio02", "gpio03",
97         "gpio04", "gpio05"
98 };
99
100 static char *gpi_p3_names[LPC32XX_GPI_P3_MAX] = {
101         "gpi00", "gpi01", "gpi02", "gpi03",
102         "gpi04", "gpi05", "gpi06", "gpi07",
103         "gpi08", "gpi09",  NULL,    NULL,
104          NULL,    NULL,    NULL,   "gpi15",
105         "gpi16", "gpi17", "gpi18", "gpi19",
106         "gpi20", "gpi21", "gpi22", "gpi23",
107         "gpi24", "gpi25", "gpi26", "gpi27"
108 };
109
110 static char *gpo_p3_names[LPC32XX_GPO_P3_MAX] = {
111         "gpo00", "gpo01", "gpo02", "gpo03",
112         "gpo04", "gpo05", "gpo06", "gpo07",
113         "gpo08", "gpo09", "gpo10", "gpo11",
114         "gpo12", "gpo13", "gpo14", "gpo15",
115         "gpo16", "gpo17", "gpo18", "gpo19",
116         "gpo20", "gpo21", "gpo22", "gpo23"
117 };
118
119 static struct gpio_regs gpio_grp_regs_p0 = {
120         .inp_state      = LPC32XX_GPIO_P0_INP_STATE,
121         .outp_set       = LPC32XX_GPIO_P0_OUTP_SET,
122         .outp_clr       = LPC32XX_GPIO_P0_OUTP_CLR,
123         .dir_set        = LPC32XX_GPIO_P0_DIR_SET,
124         .dir_clr        = LPC32XX_GPIO_P0_DIR_CLR,
125 };
126
127 static struct gpio_regs gpio_grp_regs_p1 = {
128         .inp_state      = LPC32XX_GPIO_P1_INP_STATE,
129         .outp_set       = LPC32XX_GPIO_P1_OUTP_SET,
130         .outp_clr       = LPC32XX_GPIO_P1_OUTP_CLR,
131         .dir_set        = LPC32XX_GPIO_P1_DIR_SET,
132         .dir_clr        = LPC32XX_GPIO_P1_DIR_CLR,
133 };
134
135 static struct gpio_regs gpio_grp_regs_p2 = {
136         .inp_state      = LPC32XX_GPIO_P2_INP_STATE,
137         .outp_set       = LPC32XX_GPIO_P2_OUTP_SET,
138         .outp_clr       = LPC32XX_GPIO_P2_OUTP_CLR,
139         .dir_set        = LPC32XX_GPIO_P2_DIR_SET,
140         .dir_clr        = LPC32XX_GPIO_P2_DIR_CLR,
141 };
142
143 static struct gpio_regs gpio_grp_regs_p3 = {
144         .inp_state      = LPC32XX_GPIO_P3_INP_STATE,
145         .outp_set       = LPC32XX_GPIO_P3_OUTP_SET,
146         .outp_clr       = LPC32XX_GPIO_P3_OUTP_CLR,
147         .dir_set        = LPC32XX_GPIO_P2_DIR_SET,
148         .dir_clr        = LPC32XX_GPIO_P2_DIR_CLR,
149 };
150
151 struct lpc32xx_gpio_chip {
152         struct gpio_chip        chip;
153         struct gpio_regs        *gpio_grp;
154 };
155
156 static inline struct lpc32xx_gpio_chip *to_lpc32xx_gpio(
157         struct gpio_chip *gpc)
158 {
159         return container_of(gpc, struct lpc32xx_gpio_chip, chip);
160 }
161
162 static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group,
163         unsigned pin, int input)
164 {
165         if (input)
166                 __raw_writel(GPIO012_PIN_TO_BIT(pin),
167                         group->gpio_grp->dir_clr);
168         else
169                 __raw_writel(GPIO012_PIN_TO_BIT(pin),
170                         group->gpio_grp->dir_set);
171 }
172
173 static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group,
174         unsigned pin, int input)
175 {
176         u32 u = GPIO3_PIN_TO_BIT(pin);
177
178         if (input)
179                 __raw_writel(u, group->gpio_grp->dir_clr);
180         else
181                 __raw_writel(u, group->gpio_grp->dir_set);
182 }
183
184 static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group,
185         unsigned pin, int high)
186 {
187         if (high)
188                 __raw_writel(GPIO012_PIN_TO_BIT(pin),
189                         group->gpio_grp->outp_set);
190         else
191                 __raw_writel(GPIO012_PIN_TO_BIT(pin),
192                         group->gpio_grp->outp_clr);
193 }
194
195 static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group,
196         unsigned pin, int high)
197 {
198         u32 u = GPIO3_PIN_TO_BIT(pin);
199
200         if (high)
201                 __raw_writel(u, group->gpio_grp->outp_set);
202         else
203                 __raw_writel(u, group->gpio_grp->outp_clr);
204 }
205
206 static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group,
207         unsigned pin, int high)
208 {
209         if (high)
210                 __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set);
211         else
212                 __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr);
213 }
214
215 static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group,
216         unsigned pin)
217 {
218         return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state),
219                 pin);
220 }
221
222 static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group,
223         unsigned pin)
224 {
225         int state = __raw_readl(group->gpio_grp->inp_state);
226
227         /*
228          * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped
229          * to bits 10..14, while GPIOP3-5 is mapped to bit 24.
230          */
231         return GPIO3_PIN_IN_SEL(state, pin);
232 }
233
234 static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group,
235         unsigned pin)
236 {
237         return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin);
238 }
239
240 /*
241  * GENERIC_GPIO primitives.
242  */
243 static int lpc32xx_gpio_dir_input_p012(struct gpio_chip *chip,
244         unsigned pin)
245 {
246         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
247
248         __set_gpio_dir_p012(group, pin, 1);
249
250         return 0;
251 }
252
253 static int lpc32xx_gpio_dir_input_p3(struct gpio_chip *chip,
254         unsigned pin)
255 {
256         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
257
258         __set_gpio_dir_p3(group, pin, 1);
259
260         return 0;
261 }
262
263 static int lpc32xx_gpio_dir_in_always(struct gpio_chip *chip,
264         unsigned pin)
265 {
266         return 0;
267 }
268
269 static int lpc32xx_gpio_get_value_p012(struct gpio_chip *chip, unsigned pin)
270 {
271         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
272
273         return __get_gpio_state_p012(group, pin);
274 }
275
276 static int lpc32xx_gpio_get_value_p3(struct gpio_chip *chip, unsigned pin)
277 {
278         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
279
280         return __get_gpio_state_p3(group, pin);
281 }
282
283 static int lpc32xx_gpi_get_value(struct gpio_chip *chip, unsigned pin)
284 {
285         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
286
287         return __get_gpi_state_p3(group, pin);
288 }
289
290 static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
291         int value)
292 {
293         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
294
295         __set_gpio_dir_p012(group, pin, 0);
296
297         return 0;
298 }
299
300 static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
301         int value)
302 {
303         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
304
305         __set_gpio_dir_p3(group, pin, 0);
306
307         return 0;
308 }
309
310 static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
311         int value)
312 {
313         return 0;
314 }
315
316 static void lpc32xx_gpio_set_value_p012(struct gpio_chip *chip, unsigned pin,
317         int value)
318 {
319         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
320
321         __set_gpio_level_p012(group, pin, value);
322 }
323
324 static void lpc32xx_gpio_set_value_p3(struct gpio_chip *chip, unsigned pin,
325         int value)
326 {
327         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
328
329         __set_gpio_level_p3(group, pin, value);
330 }
331
332 static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin,
333         int value)
334 {
335         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
336
337         __set_gpo_level_p3(group, pin, value);
338 }
339
340 static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin)
341 {
342         if (pin < chip->ngpio)
343                 return 0;
344
345         return -EINVAL;
346 }
347
348 static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
349         {
350                 .chip = {
351                         .label                  = "gpio_p0",
352                         .direction_input        = lpc32xx_gpio_dir_input_p012,
353                         .get                    = lpc32xx_gpio_get_value_p012,
354                         .direction_output       = lpc32xx_gpio_dir_output_p012,
355                         .set                    = lpc32xx_gpio_set_value_p012,
356                         .request                = lpc32xx_gpio_request,
357                         .base                   = LPC32XX_GPIO_P0_GRP,
358                         .ngpio                  = LPC32XX_GPIO_P0_MAX,
359                         .names                  = gpio_p0_names,
360                         .can_sleep              = 0,
361                 },
362                 .gpio_grp = &gpio_grp_regs_p0,
363         },
364         {
365                 .chip = {
366                         .label                  = "gpio_p1",
367                         .direction_input        = lpc32xx_gpio_dir_input_p012,
368                         .get                    = lpc32xx_gpio_get_value_p012,
369                         .direction_output       = lpc32xx_gpio_dir_output_p012,
370                         .set                    = lpc32xx_gpio_set_value_p012,
371                         .request                = lpc32xx_gpio_request,
372                         .base                   = LPC32XX_GPIO_P1_GRP,
373                         .ngpio                  = LPC32XX_GPIO_P1_MAX,
374                         .names                  = gpio_p1_names,
375                         .can_sleep              = 0,
376                 },
377                 .gpio_grp = &gpio_grp_regs_p1,
378         },
379         {
380                 .chip = {
381                         .label                  = "gpio_p2",
382                         .direction_input        = lpc32xx_gpio_dir_input_p012,
383                         .get                    = lpc32xx_gpio_get_value_p012,
384                         .direction_output       = lpc32xx_gpio_dir_output_p012,
385                         .set                    = lpc32xx_gpio_set_value_p012,
386                         .request                = lpc32xx_gpio_request,
387                         .base                   = LPC32XX_GPIO_P2_GRP,
388                         .ngpio                  = LPC32XX_GPIO_P2_MAX,
389                         .names                  = gpio_p2_names,
390                         .can_sleep              = 0,
391                 },
392                 .gpio_grp = &gpio_grp_regs_p2,
393         },
394         {
395                 .chip = {
396                         .label                  = "gpio_p3",
397                         .direction_input        = lpc32xx_gpio_dir_input_p3,
398                         .get                    = lpc32xx_gpio_get_value_p3,
399                         .direction_output       = lpc32xx_gpio_dir_output_p3,
400                         .set                    = lpc32xx_gpio_set_value_p3,
401                         .request                = lpc32xx_gpio_request,
402                         .base                   = LPC32XX_GPIO_P3_GRP,
403                         .ngpio                  = LPC32XX_GPIO_P3_MAX,
404                         .names                  = gpio_p3_names,
405                         .can_sleep              = 0,
406                 },
407                 .gpio_grp = &gpio_grp_regs_p3,
408         },
409         {
410                 .chip = {
411                         .label                  = "gpi_p3",
412                         .direction_input        = lpc32xx_gpio_dir_in_always,
413                         .get                    = lpc32xx_gpi_get_value,
414                         .request                = lpc32xx_gpio_request,
415                         .base                   = LPC32XX_GPI_P3_GRP,
416                         .ngpio                  = LPC32XX_GPI_P3_MAX,
417                         .names                  = gpi_p3_names,
418                         .can_sleep              = 0,
419                 },
420                 .gpio_grp = &gpio_grp_regs_p3,
421         },
422         {
423                 .chip = {
424                         .label                  = "gpo_p3",
425                         .direction_output       = lpc32xx_gpio_dir_out_always,
426                         .set                    = lpc32xx_gpo_set_value,
427                         .request                = lpc32xx_gpio_request,
428                         .base                   = LPC32XX_GPO_P3_GRP,
429                         .ngpio                  = LPC32XX_GPO_P3_MAX,
430                         .names                  = gpo_p3_names,
431                         .can_sleep              = 0,
432                 },
433                 .gpio_grp = &gpio_grp_regs_p3,
434         },
435 };
436
437 void __init lpc32xx_gpio_init(void)
438 {
439         int i;
440
441         for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++)
442                 gpiochip_add(&lpc32xx_gpiochip[i].chip);
443 }