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