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