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