arm:lpc32xx:Fix for missing GPI_28
[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         "gpi28"
109 };
110
111 static char *gpo_p3_names[LPC32XX_GPO_P3_MAX] = {
112         "gpo00", "gpo01", "gpo02", "gpo03",
113         "gpo04", "gpo05", "gpo06", "gpo07",
114         "gpo08", "gpo09", "gpo10", "gpo11",
115         "gpo12", "gpo13", "gpo14", "gpo15",
116         "gpo16", "gpo17", "gpo18", "gpo19",
117         "gpo20", "gpo21", "gpo22", "gpo23"
118 };
119
120 static struct gpio_regs gpio_grp_regs_p0 = {
121         .inp_state      = LPC32XX_GPIO_P0_INP_STATE,
122         .outp_set       = LPC32XX_GPIO_P0_OUTP_SET,
123         .outp_clr       = LPC32XX_GPIO_P0_OUTP_CLR,
124         .dir_set        = LPC32XX_GPIO_P0_DIR_SET,
125         .dir_clr        = LPC32XX_GPIO_P0_DIR_CLR,
126 };
127
128 static struct gpio_regs gpio_grp_regs_p1 = {
129         .inp_state      = LPC32XX_GPIO_P1_INP_STATE,
130         .outp_set       = LPC32XX_GPIO_P1_OUTP_SET,
131         .outp_clr       = LPC32XX_GPIO_P1_OUTP_CLR,
132         .dir_set        = LPC32XX_GPIO_P1_DIR_SET,
133         .dir_clr        = LPC32XX_GPIO_P1_DIR_CLR,
134 };
135
136 static struct gpio_regs gpio_grp_regs_p2 = {
137         .inp_state      = LPC32XX_GPIO_P2_INP_STATE,
138         .outp_set       = LPC32XX_GPIO_P2_OUTP_SET,
139         .outp_clr       = LPC32XX_GPIO_P2_OUTP_CLR,
140         .dir_set        = LPC32XX_GPIO_P2_DIR_SET,
141         .dir_clr        = LPC32XX_GPIO_P2_DIR_CLR,
142 };
143
144 static struct gpio_regs gpio_grp_regs_p3 = {
145         .inp_state      = LPC32XX_GPIO_P3_INP_STATE,
146         .outp_set       = LPC32XX_GPIO_P3_OUTP_SET,
147         .outp_clr       = LPC32XX_GPIO_P3_OUTP_CLR,
148         .dir_set        = LPC32XX_GPIO_P2_DIR_SET,
149         .dir_clr        = LPC32XX_GPIO_P2_DIR_CLR,
150 };
151
152 struct lpc32xx_gpio_chip {
153         struct gpio_chip        chip;
154         struct gpio_regs        *gpio_grp;
155 };
156
157 static inline struct lpc32xx_gpio_chip *to_lpc32xx_gpio(
158         struct gpio_chip *gpc)
159 {
160         return container_of(gpc, struct lpc32xx_gpio_chip, chip);
161 }
162
163 static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group,
164         unsigned pin, int input)
165 {
166         if (input)
167                 __raw_writel(GPIO012_PIN_TO_BIT(pin),
168                         group->gpio_grp->dir_clr);
169         else
170                 __raw_writel(GPIO012_PIN_TO_BIT(pin),
171                         group->gpio_grp->dir_set);
172 }
173
174 static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group,
175         unsigned pin, int input)
176 {
177         u32 u = GPIO3_PIN_TO_BIT(pin);
178
179         if (input)
180                 __raw_writel(u, group->gpio_grp->dir_clr);
181         else
182                 __raw_writel(u, group->gpio_grp->dir_set);
183 }
184
185 static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group,
186         unsigned pin, int high)
187 {
188         if (high)
189                 __raw_writel(GPIO012_PIN_TO_BIT(pin),
190                         group->gpio_grp->outp_set);
191         else
192                 __raw_writel(GPIO012_PIN_TO_BIT(pin),
193                         group->gpio_grp->outp_clr);
194 }
195
196 static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group,
197         unsigned pin, int high)
198 {
199         u32 u = GPIO3_PIN_TO_BIT(pin);
200
201         if (high)
202                 __raw_writel(u, group->gpio_grp->outp_set);
203         else
204                 __raw_writel(u, group->gpio_grp->outp_clr);
205 }
206
207 static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group,
208         unsigned pin, int high)
209 {
210         if (high)
211                 __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set);
212         else
213                 __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr);
214 }
215
216 static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group,
217         unsigned pin)
218 {
219         return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state),
220                 pin);
221 }
222
223 static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group,
224         unsigned pin)
225 {
226         int state = __raw_readl(group->gpio_grp->inp_state);
227
228         /*
229          * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped
230          * to bits 10..14, while GPIOP3-5 is mapped to bit 24.
231          */
232         return GPIO3_PIN_IN_SEL(state, pin);
233 }
234
235 static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group,
236         unsigned pin)
237 {
238         return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin);
239 }
240
241 /*
242  * GENERIC_GPIO primitives.
243  */
244 static int lpc32xx_gpio_dir_input_p012(struct gpio_chip *chip,
245         unsigned pin)
246 {
247         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
248
249         __set_gpio_dir_p012(group, pin, 1);
250
251         return 0;
252 }
253
254 static int lpc32xx_gpio_dir_input_p3(struct gpio_chip *chip,
255         unsigned pin)
256 {
257         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
258
259         __set_gpio_dir_p3(group, pin, 1);
260
261         return 0;
262 }
263
264 static int lpc32xx_gpio_dir_in_always(struct gpio_chip *chip,
265         unsigned pin)
266 {
267         return 0;
268 }
269
270 static int lpc32xx_gpio_get_value_p012(struct gpio_chip *chip, unsigned pin)
271 {
272         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
273
274         return __get_gpio_state_p012(group, pin);
275 }
276
277 static int lpc32xx_gpio_get_value_p3(struct gpio_chip *chip, unsigned pin)
278 {
279         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
280
281         return __get_gpio_state_p3(group, pin);
282 }
283
284 static int lpc32xx_gpi_get_value(struct gpio_chip *chip, unsigned pin)
285 {
286         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
287
288         return __get_gpi_state_p3(group, pin);
289 }
290
291 static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
292         int value)
293 {
294         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
295
296         __set_gpio_dir_p012(group, pin, 0);
297
298         return 0;
299 }
300
301 static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
302         int value)
303 {
304         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
305
306         __set_gpio_dir_p3(group, pin, 0);
307
308         return 0;
309 }
310
311 static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
312         int value)
313 {
314         return 0;
315 }
316
317 static void lpc32xx_gpio_set_value_p012(struct gpio_chip *chip, unsigned pin,
318         int value)
319 {
320         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
321
322         __set_gpio_level_p012(group, pin, value);
323 }
324
325 static void lpc32xx_gpio_set_value_p3(struct gpio_chip *chip, unsigned pin,
326         int value)
327 {
328         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
329
330         __set_gpio_level_p3(group, pin, value);
331 }
332
333 static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin,
334         int value)
335 {
336         struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
337
338         __set_gpo_level_p3(group, pin, value);
339 }
340
341 static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin)
342 {
343         if (pin < chip->ngpio)
344                 return 0;
345
346         return -EINVAL;
347 }
348
349 static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
350         {
351                 .chip = {
352                         .label                  = "gpio_p0",
353                         .direction_input        = lpc32xx_gpio_dir_input_p012,
354                         .get                    = lpc32xx_gpio_get_value_p012,
355                         .direction_output       = lpc32xx_gpio_dir_output_p012,
356                         .set                    = lpc32xx_gpio_set_value_p012,
357                         .request                = lpc32xx_gpio_request,
358                         .base                   = LPC32XX_GPIO_P0_GRP,
359                         .ngpio                  = LPC32XX_GPIO_P0_MAX,
360                         .names                  = gpio_p0_names,
361                         .can_sleep              = 0,
362                 },
363                 .gpio_grp = &gpio_grp_regs_p0,
364         },
365         {
366                 .chip = {
367                         .label                  = "gpio_p1",
368                         .direction_input        = lpc32xx_gpio_dir_input_p012,
369                         .get                    = lpc32xx_gpio_get_value_p012,
370                         .direction_output       = lpc32xx_gpio_dir_output_p012,
371                         .set                    = lpc32xx_gpio_set_value_p012,
372                         .request                = lpc32xx_gpio_request,
373                         .base                   = LPC32XX_GPIO_P1_GRP,
374                         .ngpio                  = LPC32XX_GPIO_P1_MAX,
375                         .names                  = gpio_p1_names,
376                         .can_sleep              = 0,
377                 },
378                 .gpio_grp = &gpio_grp_regs_p1,
379         },
380         {
381                 .chip = {
382                         .label                  = "gpio_p2",
383                         .direction_input        = lpc32xx_gpio_dir_input_p012,
384                         .get                    = lpc32xx_gpio_get_value_p012,
385                         .direction_output       = lpc32xx_gpio_dir_output_p012,
386                         .set                    = lpc32xx_gpio_set_value_p012,
387                         .request                = lpc32xx_gpio_request,
388                         .base                   = LPC32XX_GPIO_P2_GRP,
389                         .ngpio                  = LPC32XX_GPIO_P2_MAX,
390                         .names                  = gpio_p2_names,
391                         .can_sleep              = 0,
392                 },
393                 .gpio_grp = &gpio_grp_regs_p2,
394         },
395         {
396                 .chip = {
397                         .label                  = "gpio_p3",
398                         .direction_input        = lpc32xx_gpio_dir_input_p3,
399                         .get                    = lpc32xx_gpio_get_value_p3,
400                         .direction_output       = lpc32xx_gpio_dir_output_p3,
401                         .set                    = lpc32xx_gpio_set_value_p3,
402                         .request                = lpc32xx_gpio_request,
403                         .base                   = LPC32XX_GPIO_P3_GRP,
404                         .ngpio                  = LPC32XX_GPIO_P3_MAX,
405                         .names                  = gpio_p3_names,
406                         .can_sleep              = 0,
407                 },
408                 .gpio_grp = &gpio_grp_regs_p3,
409         },
410         {
411                 .chip = {
412                         .label                  = "gpi_p3",
413                         .direction_input        = lpc32xx_gpio_dir_in_always,
414                         .get                    = lpc32xx_gpi_get_value,
415                         .request                = lpc32xx_gpio_request,
416                         .base                   = LPC32XX_GPI_P3_GRP,
417                         .ngpio                  = LPC32XX_GPI_P3_MAX,
418                         .names                  = gpi_p3_names,
419                         .can_sleep              = 0,
420                 },
421                 .gpio_grp = &gpio_grp_regs_p3,
422         },
423         {
424                 .chip = {
425                         .label                  = "gpo_p3",
426                         .direction_output       = lpc32xx_gpio_dir_out_always,
427                         .set                    = lpc32xx_gpo_set_value,
428                         .request                = lpc32xx_gpio_request,
429                         .base                   = LPC32XX_GPO_P3_GRP,
430                         .ngpio                  = LPC32XX_GPO_P3_MAX,
431                         .names                  = gpo_p3_names,
432                         .can_sleep              = 0,
433                 },
434                 .gpio_grp = &gpio_grp_regs_p3,
435         },
436 };
437
438 void __init lpc32xx_gpio_init(void)
439 {
440         int i;
441
442         for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++)
443                 gpiochip_add(&lpc32xx_gpiochip[i].chip);
444 }