xref: /openbmc/linux/drivers/gpio/gpio-lpc32xx.c (revision 320a6480)
1f80cb526SLinus Walleij /*
2da03d740SRoland Stigge  * GPIO driver for LPC32xx SoC
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>
24831cbd7aSSachin Kamat #include <linux/of.h>
25e92935e1SRoland Stigge #include <linux/of_gpio.h>
26e92935e1SRoland Stigge #include <linux/platform_device.h>
27e92935e1SRoland Stigge #include <linux/module.h>
28eef80f33SLinus Walleij #include <linux/platform_data/gpio-lpc32xx.h>
29f80cb526SLinus Walleij 
30f80cb526SLinus Walleij #include <mach/hardware.h>
31f80cb526SLinus Walleij #include <mach/platform.h>
32f80cb526SLinus Walleij 
33f80cb526SLinus Walleij #define LPC32XX_GPIO_P3_INP_STATE		_GPREG(0x000)
34f80cb526SLinus Walleij #define LPC32XX_GPIO_P3_OUTP_SET		_GPREG(0x004)
35f80cb526SLinus Walleij #define LPC32XX_GPIO_P3_OUTP_CLR		_GPREG(0x008)
36f80cb526SLinus Walleij #define LPC32XX_GPIO_P3_OUTP_STATE		_GPREG(0x00C)
37f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_DIR_SET			_GPREG(0x010)
38f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_DIR_CLR			_GPREG(0x014)
39f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_DIR_STATE		_GPREG(0x018)
40f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_INP_STATE		_GPREG(0x01C)
41f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_OUTP_SET		_GPREG(0x020)
42f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_OUTP_CLR		_GPREG(0x024)
43f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_MUX_SET			_GPREG(0x028)
44f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_MUX_CLR			_GPREG(0x02C)
45f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_MUX_STATE		_GPREG(0x030)
46f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_INP_STATE		_GPREG(0x040)
47f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_OUTP_SET		_GPREG(0x044)
48f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_OUTP_CLR		_GPREG(0x048)
49f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_OUTP_STATE		_GPREG(0x04C)
50f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_DIR_SET			_GPREG(0x050)
51f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_DIR_CLR			_GPREG(0x054)
52f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_DIR_STATE		_GPREG(0x058)
53f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_INP_STATE		_GPREG(0x060)
54f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_OUTP_SET		_GPREG(0x064)
55f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_OUTP_CLR		_GPREG(0x068)
56f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_OUTP_STATE		_GPREG(0x06C)
57f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_DIR_SET			_GPREG(0x070)
58f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_DIR_CLR			_GPREG(0x074)
59f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_DIR_STATE		_GPREG(0x078)
60f80cb526SLinus Walleij 
61f80cb526SLinus Walleij #define GPIO012_PIN_TO_BIT(x)			(1 << (x))
62f80cb526SLinus Walleij #define GPIO3_PIN_TO_BIT(x)			(1 << ((x) + 25))
63f80cb526SLinus Walleij #define GPO3_PIN_TO_BIT(x)			(1 << (x))
64f80cb526SLinus Walleij #define GPIO012_PIN_IN_SEL(x, y)		(((x) >> (y)) & 1)
65f80cb526SLinus Walleij #define GPIO3_PIN_IN_SHIFT(x)			((x) == 5 ? 24 : 10 + (x))
668e5fb37bSRoland Stigge #define GPIO3_PIN_IN_SEL(x, y)			(((x) >> GPIO3_PIN_IN_SHIFT(y)) & 1)
67f80cb526SLinus Walleij #define GPIO3_PIN5_IN_SEL(x)			(((x) >> 24) & 1)
68f80cb526SLinus Walleij #define GPI3_PIN_IN_SEL(x, y)			(((x) >> (y)) & 1)
6946158aadSRoland Stigge #define GPO3_PIN_IN_SEL(x, y)			(((x) >> (y)) & 1)
70f80cb526SLinus Walleij 
71f80cb526SLinus Walleij struct gpio_regs {
72f80cb526SLinus Walleij 	void __iomem *inp_state;
7346158aadSRoland Stigge 	void __iomem *outp_state;
74f80cb526SLinus Walleij 	void __iomem *outp_set;
75f80cb526SLinus Walleij 	void __iomem *outp_clr;
76f80cb526SLinus Walleij 	void __iomem *dir_set;
77f80cb526SLinus Walleij 	void __iomem *dir_clr;
78f80cb526SLinus Walleij };
79f80cb526SLinus Walleij 
80f80cb526SLinus Walleij /*
81f80cb526SLinus Walleij  * GPIO names
82f80cb526SLinus Walleij  */
83f80cb526SLinus Walleij static const char *gpio_p0_names[LPC32XX_GPIO_P0_MAX] = {
84f80cb526SLinus Walleij 	"p0.0", "p0.1", "p0.2", "p0.3",
85f80cb526SLinus Walleij 	"p0.4", "p0.5", "p0.6", "p0.7"
86f80cb526SLinus Walleij };
87f80cb526SLinus Walleij 
88f80cb526SLinus Walleij static const char *gpio_p1_names[LPC32XX_GPIO_P1_MAX] = {
89f80cb526SLinus Walleij 	"p1.0", "p1.1", "p1.2", "p1.3",
90f80cb526SLinus Walleij 	"p1.4", "p1.5", "p1.6", "p1.7",
91f80cb526SLinus Walleij 	"p1.8", "p1.9", "p1.10", "p1.11",
92f80cb526SLinus Walleij 	"p1.12", "p1.13", "p1.14", "p1.15",
93f80cb526SLinus Walleij 	"p1.16", "p1.17", "p1.18", "p1.19",
94f80cb526SLinus Walleij 	"p1.20", "p1.21", "p1.22", "p1.23",
95f80cb526SLinus Walleij };
96f80cb526SLinus Walleij 
97f80cb526SLinus Walleij static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = {
98f80cb526SLinus Walleij 	"p2.0", "p2.1", "p2.2", "p2.3",
99f80cb526SLinus Walleij 	"p2.4", "p2.5", "p2.6", "p2.7",
100f80cb526SLinus Walleij 	"p2.8", "p2.9", "p2.10", "p2.11",
101f80cb526SLinus Walleij 	"p2.12"
102f80cb526SLinus Walleij };
103f80cb526SLinus Walleij 
104f80cb526SLinus Walleij static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = {
10595120d5dSRoland Stigge 	"gpio00", "gpio01", "gpio02", "gpio03",
106f80cb526SLinus Walleij 	"gpio04", "gpio05"
107f80cb526SLinus Walleij };
108f80cb526SLinus Walleij 
109f80cb526SLinus Walleij static const char *gpi_p3_names[LPC32XX_GPI_P3_MAX] = {
110f80cb526SLinus Walleij 	"gpi00", "gpi01", "gpi02", "gpi03",
111f80cb526SLinus Walleij 	"gpi04", "gpi05", "gpi06", "gpi07",
112f80cb526SLinus Walleij 	"gpi08", "gpi09",  NULL,    NULL,
113f80cb526SLinus Walleij 	 NULL,    NULL,    NULL,   "gpi15",
114f80cb526SLinus Walleij 	"gpi16", "gpi17", "gpi18", "gpi19",
115f80cb526SLinus Walleij 	"gpi20", "gpi21", "gpi22", "gpi23",
11671fde000SRoland Stigge 	"gpi24", "gpi25", "gpi26", "gpi27",
11771fde000SRoland Stigge 	"gpi28"
118f80cb526SLinus Walleij };
119f80cb526SLinus Walleij 
120f80cb526SLinus Walleij static const char *gpo_p3_names[LPC32XX_GPO_P3_MAX] = {
121f80cb526SLinus Walleij 	"gpo00", "gpo01", "gpo02", "gpo03",
122f80cb526SLinus Walleij 	"gpo04", "gpo05", "gpo06", "gpo07",
123f80cb526SLinus Walleij 	"gpo08", "gpo09", "gpo10", "gpo11",
124f80cb526SLinus Walleij 	"gpo12", "gpo13", "gpo14", "gpo15",
125f80cb526SLinus Walleij 	"gpo16", "gpo17", "gpo18", "gpo19",
126f80cb526SLinus Walleij 	"gpo20", "gpo21", "gpo22", "gpo23"
127f80cb526SLinus Walleij };
128f80cb526SLinus Walleij 
129f80cb526SLinus Walleij static struct gpio_regs gpio_grp_regs_p0 = {
130f80cb526SLinus Walleij 	.inp_state	= LPC32XX_GPIO_P0_INP_STATE,
131f80cb526SLinus Walleij 	.outp_set	= LPC32XX_GPIO_P0_OUTP_SET,
132f80cb526SLinus Walleij 	.outp_clr	= LPC32XX_GPIO_P0_OUTP_CLR,
133f80cb526SLinus Walleij 	.dir_set	= LPC32XX_GPIO_P0_DIR_SET,
134f80cb526SLinus Walleij 	.dir_clr	= LPC32XX_GPIO_P0_DIR_CLR,
135f80cb526SLinus Walleij };
136f80cb526SLinus Walleij 
137f80cb526SLinus Walleij static struct gpio_regs gpio_grp_regs_p1 = {
138f80cb526SLinus Walleij 	.inp_state	= LPC32XX_GPIO_P1_INP_STATE,
139f80cb526SLinus Walleij 	.outp_set	= LPC32XX_GPIO_P1_OUTP_SET,
140f80cb526SLinus Walleij 	.outp_clr	= LPC32XX_GPIO_P1_OUTP_CLR,
141f80cb526SLinus Walleij 	.dir_set	= LPC32XX_GPIO_P1_DIR_SET,
142f80cb526SLinus Walleij 	.dir_clr	= LPC32XX_GPIO_P1_DIR_CLR,
143f80cb526SLinus Walleij };
144f80cb526SLinus Walleij 
145f80cb526SLinus Walleij static struct gpio_regs gpio_grp_regs_p2 = {
146f80cb526SLinus Walleij 	.inp_state	= LPC32XX_GPIO_P2_INP_STATE,
147f80cb526SLinus Walleij 	.outp_set	= LPC32XX_GPIO_P2_OUTP_SET,
148f80cb526SLinus Walleij 	.outp_clr	= LPC32XX_GPIO_P2_OUTP_CLR,
149f80cb526SLinus Walleij 	.dir_set	= LPC32XX_GPIO_P2_DIR_SET,
150f80cb526SLinus Walleij 	.dir_clr	= LPC32XX_GPIO_P2_DIR_CLR,
151f80cb526SLinus Walleij };
152f80cb526SLinus Walleij 
153f80cb526SLinus Walleij static struct gpio_regs gpio_grp_regs_p3 = {
154f80cb526SLinus Walleij 	.inp_state	= LPC32XX_GPIO_P3_INP_STATE,
15546158aadSRoland Stigge 	.outp_state	= LPC32XX_GPIO_P3_OUTP_STATE,
156f80cb526SLinus Walleij 	.outp_set	= LPC32XX_GPIO_P3_OUTP_SET,
157f80cb526SLinus Walleij 	.outp_clr	= LPC32XX_GPIO_P3_OUTP_CLR,
158f80cb526SLinus Walleij 	.dir_set	= LPC32XX_GPIO_P2_DIR_SET,
159f80cb526SLinus Walleij 	.dir_clr	= LPC32XX_GPIO_P2_DIR_CLR,
160f80cb526SLinus Walleij };
161f80cb526SLinus Walleij 
162f80cb526SLinus Walleij struct lpc32xx_gpio_chip {
163f80cb526SLinus Walleij 	struct gpio_chip	chip;
164f80cb526SLinus Walleij 	struct gpio_regs	*gpio_grp;
165f80cb526SLinus Walleij };
166f80cb526SLinus Walleij 
167f80cb526SLinus Walleij static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group,
168f80cb526SLinus Walleij 	unsigned pin, int input)
169f80cb526SLinus Walleij {
170f80cb526SLinus Walleij 	if (input)
171f80cb526SLinus Walleij 		__raw_writel(GPIO012_PIN_TO_BIT(pin),
172f80cb526SLinus Walleij 			group->gpio_grp->dir_clr);
173f80cb526SLinus Walleij 	else
174f80cb526SLinus Walleij 		__raw_writel(GPIO012_PIN_TO_BIT(pin),
175f80cb526SLinus Walleij 			group->gpio_grp->dir_set);
176f80cb526SLinus Walleij }
177f80cb526SLinus Walleij 
178f80cb526SLinus Walleij static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group,
179f80cb526SLinus Walleij 	unsigned pin, int input)
180f80cb526SLinus Walleij {
181f80cb526SLinus Walleij 	u32 u = GPIO3_PIN_TO_BIT(pin);
182f80cb526SLinus Walleij 
183f80cb526SLinus Walleij 	if (input)
184f80cb526SLinus Walleij 		__raw_writel(u, group->gpio_grp->dir_clr);
185f80cb526SLinus Walleij 	else
186f80cb526SLinus Walleij 		__raw_writel(u, group->gpio_grp->dir_set);
187f80cb526SLinus Walleij }
188f80cb526SLinus Walleij 
189f80cb526SLinus Walleij static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group,
190f80cb526SLinus Walleij 	unsigned pin, int high)
191f80cb526SLinus Walleij {
192f80cb526SLinus Walleij 	if (high)
193f80cb526SLinus Walleij 		__raw_writel(GPIO012_PIN_TO_BIT(pin),
194f80cb526SLinus Walleij 			group->gpio_grp->outp_set);
195f80cb526SLinus Walleij 	else
196f80cb526SLinus Walleij 		__raw_writel(GPIO012_PIN_TO_BIT(pin),
197f80cb526SLinus Walleij 			group->gpio_grp->outp_clr);
198f80cb526SLinus Walleij }
199f80cb526SLinus Walleij 
200f80cb526SLinus Walleij static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group,
201f80cb526SLinus Walleij 	unsigned pin, int high)
202f80cb526SLinus Walleij {
203f80cb526SLinus Walleij 	u32 u = GPIO3_PIN_TO_BIT(pin);
204f80cb526SLinus Walleij 
205f80cb526SLinus Walleij 	if (high)
206f80cb526SLinus Walleij 		__raw_writel(u, group->gpio_grp->outp_set);
207f80cb526SLinus Walleij 	else
208f80cb526SLinus Walleij 		__raw_writel(u, group->gpio_grp->outp_clr);
209f80cb526SLinus Walleij }
210f80cb526SLinus Walleij 
211f80cb526SLinus Walleij static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group,
212f80cb526SLinus Walleij 	unsigned pin, int high)
213f80cb526SLinus Walleij {
214f80cb526SLinus Walleij 	if (high)
215f80cb526SLinus Walleij 		__raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set);
216f80cb526SLinus Walleij 	else
217f80cb526SLinus Walleij 		__raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr);
218f80cb526SLinus Walleij }
219f80cb526SLinus Walleij 
220f80cb526SLinus Walleij static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group,
221f80cb526SLinus Walleij 	unsigned pin)
222f80cb526SLinus Walleij {
223f80cb526SLinus Walleij 	return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state),
224f80cb526SLinus Walleij 		pin);
225f80cb526SLinus Walleij }
226f80cb526SLinus Walleij 
227f80cb526SLinus Walleij static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group,
228f80cb526SLinus Walleij 	unsigned pin)
229f80cb526SLinus Walleij {
230f80cb526SLinus Walleij 	int state = __raw_readl(group->gpio_grp->inp_state);
231f80cb526SLinus Walleij 
232f80cb526SLinus Walleij 	/*
233f80cb526SLinus Walleij 	 * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped
234f80cb526SLinus Walleij 	 * to bits 10..14, while GPIOP3-5 is mapped to bit 24.
235f80cb526SLinus Walleij 	 */
236f80cb526SLinus Walleij 	return GPIO3_PIN_IN_SEL(state, pin);
237f80cb526SLinus Walleij }
238f80cb526SLinus Walleij 
239f80cb526SLinus Walleij static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group,
240f80cb526SLinus Walleij 	unsigned pin)
241f80cb526SLinus Walleij {
242f80cb526SLinus Walleij 	return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin);
243f80cb526SLinus Walleij }
244f80cb526SLinus Walleij 
24546158aadSRoland Stigge static int __get_gpo_state_p3(struct lpc32xx_gpio_chip *group,
24646158aadSRoland Stigge 	unsigned pin)
24746158aadSRoland Stigge {
24846158aadSRoland Stigge 	return GPO3_PIN_IN_SEL(__raw_readl(group->gpio_grp->outp_state), pin);
24946158aadSRoland Stigge }
25046158aadSRoland Stigge 
251f80cb526SLinus Walleij /*
2527fd2bf3dSAlexandre Courbot  * GPIO primitives.
253f80cb526SLinus Walleij  */
254f80cb526SLinus Walleij static int lpc32xx_gpio_dir_input_p012(struct gpio_chip *chip,
255f80cb526SLinus Walleij 	unsigned pin)
256f80cb526SLinus Walleij {
257a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
258f80cb526SLinus Walleij 
259f80cb526SLinus Walleij 	__set_gpio_dir_p012(group, pin, 1);
260f80cb526SLinus Walleij 
261f80cb526SLinus Walleij 	return 0;
262f80cb526SLinus Walleij }
263f80cb526SLinus Walleij 
264f80cb526SLinus Walleij static int lpc32xx_gpio_dir_input_p3(struct gpio_chip *chip,
265f80cb526SLinus Walleij 	unsigned pin)
266f80cb526SLinus Walleij {
267a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
268f80cb526SLinus Walleij 
269f80cb526SLinus Walleij 	__set_gpio_dir_p3(group, pin, 1);
270f80cb526SLinus Walleij 
271f80cb526SLinus Walleij 	return 0;
272f80cb526SLinus Walleij }
273f80cb526SLinus Walleij 
274f80cb526SLinus Walleij static int lpc32xx_gpio_dir_in_always(struct gpio_chip *chip,
275f80cb526SLinus Walleij 	unsigned pin)
276f80cb526SLinus Walleij {
277f80cb526SLinus Walleij 	return 0;
278f80cb526SLinus Walleij }
279f80cb526SLinus Walleij 
280f80cb526SLinus Walleij static int lpc32xx_gpio_get_value_p012(struct gpio_chip *chip, unsigned pin)
281f80cb526SLinus Walleij {
282a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
283f80cb526SLinus Walleij 
2842e6d8456SLinus Walleij 	return !!__get_gpio_state_p012(group, pin);
285f80cb526SLinus Walleij }
286f80cb526SLinus Walleij 
287f80cb526SLinus Walleij static int lpc32xx_gpio_get_value_p3(struct gpio_chip *chip, unsigned pin)
288f80cb526SLinus Walleij {
289a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
290f80cb526SLinus Walleij 
2912e6d8456SLinus Walleij 	return !!__get_gpio_state_p3(group, pin);
292f80cb526SLinus Walleij }
293f80cb526SLinus Walleij 
294f80cb526SLinus Walleij static int lpc32xx_gpi_get_value(struct gpio_chip *chip, unsigned pin)
295f80cb526SLinus Walleij {
296a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
297f80cb526SLinus Walleij 
2982e6d8456SLinus Walleij 	return !!__get_gpi_state_p3(group, pin);
299f80cb526SLinus Walleij }
300f80cb526SLinus Walleij 
301f80cb526SLinus Walleij static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
302f80cb526SLinus Walleij 	int value)
303f80cb526SLinus Walleij {
304a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
305f80cb526SLinus Walleij 
306b1268d37SRoland Stigge 	__set_gpio_level_p012(group, pin, value);
307f80cb526SLinus Walleij 	__set_gpio_dir_p012(group, pin, 0);
308f80cb526SLinus Walleij 
309f80cb526SLinus Walleij 	return 0;
310f80cb526SLinus Walleij }
311f80cb526SLinus Walleij 
312f80cb526SLinus Walleij static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
313f80cb526SLinus Walleij 	int value)
314f80cb526SLinus Walleij {
315a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
316f80cb526SLinus Walleij 
317b1268d37SRoland Stigge 	__set_gpio_level_p3(group, pin, value);
318f80cb526SLinus Walleij 	__set_gpio_dir_p3(group, pin, 0);
319f80cb526SLinus Walleij 
320f80cb526SLinus Walleij 	return 0;
321f80cb526SLinus Walleij }
322f80cb526SLinus Walleij 
323f80cb526SLinus Walleij static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
324f80cb526SLinus Walleij 	int value)
325f80cb526SLinus Walleij {
326a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
327b1268d37SRoland Stigge 
328b1268d37SRoland Stigge 	__set_gpo_level_p3(group, pin, value);
329f80cb526SLinus Walleij 	return 0;
330f80cb526SLinus Walleij }
331f80cb526SLinus Walleij 
332f80cb526SLinus Walleij static void lpc32xx_gpio_set_value_p012(struct gpio_chip *chip, unsigned pin,
333f80cb526SLinus Walleij 	int value)
334f80cb526SLinus Walleij {
335a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
336f80cb526SLinus Walleij 
337f80cb526SLinus Walleij 	__set_gpio_level_p012(group, pin, value);
338f80cb526SLinus Walleij }
339f80cb526SLinus Walleij 
340f80cb526SLinus Walleij static void lpc32xx_gpio_set_value_p3(struct gpio_chip *chip, unsigned pin,
341f80cb526SLinus Walleij 	int value)
342f80cb526SLinus Walleij {
343a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
344f80cb526SLinus Walleij 
345f80cb526SLinus Walleij 	__set_gpio_level_p3(group, pin, value);
346f80cb526SLinus Walleij }
347f80cb526SLinus Walleij 
348f80cb526SLinus Walleij static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin,
349f80cb526SLinus Walleij 	int value)
350f80cb526SLinus Walleij {
351a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
352f80cb526SLinus Walleij 
353f80cb526SLinus Walleij 	__set_gpo_level_p3(group, pin, value);
354f80cb526SLinus Walleij }
355f80cb526SLinus Walleij 
35646158aadSRoland Stigge static int lpc32xx_gpo_get_value(struct gpio_chip *chip, unsigned pin)
35746158aadSRoland Stigge {
358a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
35946158aadSRoland Stigge 
3602e6d8456SLinus Walleij 	return !!__get_gpo_state_p3(group, pin);
36146158aadSRoland Stigge }
36246158aadSRoland Stigge 
363f80cb526SLinus Walleij static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin)
364f80cb526SLinus Walleij {
365f80cb526SLinus Walleij 	if (pin < chip->ngpio)
366f80cb526SLinus Walleij 		return 0;
367f80cb526SLinus Walleij 
368f80cb526SLinus Walleij 	return -EINVAL;
369f80cb526SLinus Walleij }
370f80cb526SLinus Walleij 
3710bdfeddcSRoland Stigge static int lpc32xx_gpio_to_irq_p01(struct gpio_chip *chip, unsigned offset)
3720bdfeddcSRoland Stigge {
3730bdfeddcSRoland Stigge 	return -ENXIO;
3740bdfeddcSRoland Stigge }
3750bdfeddcSRoland Stigge 
376320a6480SSylvain Lemieux static int lpc32xx_gpio_to_irq_gpio_p3(struct gpio_chip *chip, unsigned offset)
377320a6480SSylvain Lemieux {
378320a6480SSylvain Lemieux 	return -ENXIO;
379320a6480SSylvain Lemieux }
3800bdfeddcSRoland Stigge 
3810bdfeddcSRoland Stigge static int lpc32xx_gpio_to_irq_gpi_p3(struct gpio_chip *chip, unsigned offset)
3820bdfeddcSRoland Stigge {
3830bdfeddcSRoland Stigge 	return -ENXIO;
3840bdfeddcSRoland Stigge }
3850bdfeddcSRoland Stigge 
386f80cb526SLinus Walleij static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
387f80cb526SLinus Walleij 	{
388f80cb526SLinus Walleij 		.chip = {
389f80cb526SLinus Walleij 			.label			= "gpio_p0",
390f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_input_p012,
391f80cb526SLinus Walleij 			.get			= lpc32xx_gpio_get_value_p012,
392f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_output_p012,
393f80cb526SLinus Walleij 			.set			= lpc32xx_gpio_set_value_p012,
394f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
3950bdfeddcSRoland Stigge 			.to_irq			= lpc32xx_gpio_to_irq_p01,
396f80cb526SLinus Walleij 			.base			= LPC32XX_GPIO_P0_GRP,
397f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPIO_P0_MAX,
398f80cb526SLinus Walleij 			.names			= gpio_p0_names,
3999fb1f39eSLinus Walleij 			.can_sleep		= false,
400f80cb526SLinus Walleij 		},
401f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p0,
402f80cb526SLinus Walleij 	},
403f80cb526SLinus Walleij 	{
404f80cb526SLinus Walleij 		.chip = {
405f80cb526SLinus Walleij 			.label			= "gpio_p1",
406f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_input_p012,
407f80cb526SLinus Walleij 			.get			= lpc32xx_gpio_get_value_p012,
408f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_output_p012,
409f80cb526SLinus Walleij 			.set			= lpc32xx_gpio_set_value_p012,
410f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
4110bdfeddcSRoland Stigge 			.to_irq			= lpc32xx_gpio_to_irq_p01,
412f80cb526SLinus Walleij 			.base			= LPC32XX_GPIO_P1_GRP,
413f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPIO_P1_MAX,
414f80cb526SLinus Walleij 			.names			= gpio_p1_names,
4159fb1f39eSLinus Walleij 			.can_sleep		= false,
416f80cb526SLinus Walleij 		},
417f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p1,
418f80cb526SLinus Walleij 	},
419f80cb526SLinus Walleij 	{
420f80cb526SLinus Walleij 		.chip = {
421f80cb526SLinus Walleij 			.label			= "gpio_p2",
422f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_input_p012,
423f80cb526SLinus Walleij 			.get			= lpc32xx_gpio_get_value_p012,
424f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_output_p012,
425f80cb526SLinus Walleij 			.set			= lpc32xx_gpio_set_value_p012,
426f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
427f80cb526SLinus Walleij 			.base			= LPC32XX_GPIO_P2_GRP,
428f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPIO_P2_MAX,
429f80cb526SLinus Walleij 			.names			= gpio_p2_names,
4309fb1f39eSLinus Walleij 			.can_sleep		= false,
431f80cb526SLinus Walleij 		},
432f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p2,
433f80cb526SLinus Walleij 	},
434f80cb526SLinus Walleij 	{
435f80cb526SLinus Walleij 		.chip = {
436f80cb526SLinus Walleij 			.label			= "gpio_p3",
437f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_input_p3,
438f80cb526SLinus Walleij 			.get			= lpc32xx_gpio_get_value_p3,
439f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_output_p3,
440f80cb526SLinus Walleij 			.set			= lpc32xx_gpio_set_value_p3,
441f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
4420bdfeddcSRoland Stigge 			.to_irq			= lpc32xx_gpio_to_irq_gpio_p3,
443f80cb526SLinus Walleij 			.base			= LPC32XX_GPIO_P3_GRP,
444f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPIO_P3_MAX,
445f80cb526SLinus Walleij 			.names			= gpio_p3_names,
4469fb1f39eSLinus Walleij 			.can_sleep		= false,
447f80cb526SLinus Walleij 		},
448f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p3,
449f80cb526SLinus Walleij 	},
450f80cb526SLinus Walleij 	{
451f80cb526SLinus Walleij 		.chip = {
452f80cb526SLinus Walleij 			.label			= "gpi_p3",
453f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_in_always,
454f80cb526SLinus Walleij 			.get			= lpc32xx_gpi_get_value,
455f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
4560bdfeddcSRoland Stigge 			.to_irq			= lpc32xx_gpio_to_irq_gpi_p3,
457f80cb526SLinus Walleij 			.base			= LPC32XX_GPI_P3_GRP,
458f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPI_P3_MAX,
459f80cb526SLinus Walleij 			.names			= gpi_p3_names,
4609fb1f39eSLinus Walleij 			.can_sleep		= false,
461f80cb526SLinus Walleij 		},
462f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p3,
463f80cb526SLinus Walleij 	},
464f80cb526SLinus Walleij 	{
465f80cb526SLinus Walleij 		.chip = {
466f80cb526SLinus Walleij 			.label			= "gpo_p3",
467f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_out_always,
468f80cb526SLinus Walleij 			.set			= lpc32xx_gpo_set_value,
46946158aadSRoland Stigge 			.get			= lpc32xx_gpo_get_value,
470f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
471f80cb526SLinus Walleij 			.base			= LPC32XX_GPO_P3_GRP,
472f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPO_P3_MAX,
473f80cb526SLinus Walleij 			.names			= gpo_p3_names,
4749fb1f39eSLinus Walleij 			.can_sleep		= false,
475f80cb526SLinus Walleij 		},
476f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p3,
477f80cb526SLinus Walleij 	},
478f80cb526SLinus Walleij };
479f80cb526SLinus Walleij 
480e92935e1SRoland Stigge static int lpc32xx_of_xlate(struct gpio_chip *gc,
481e92935e1SRoland Stigge 			    const struct of_phandle_args *gpiospec, u32 *flags)
482e92935e1SRoland Stigge {
483e92935e1SRoland Stigge 	/* Is this the correct bank? */
484e92935e1SRoland Stigge 	u32 bank = gpiospec->args[0];
485fdc7a9f8SAxel Lin 	if ((bank >= ARRAY_SIZE(lpc32xx_gpiochip) ||
486e92935e1SRoland Stigge 	    (gc != &lpc32xx_gpiochip[bank].chip)))
487e92935e1SRoland Stigge 		return -EINVAL;
488e92935e1SRoland Stigge 
489e92935e1SRoland Stigge 	if (flags)
490e92935e1SRoland Stigge 		*flags = gpiospec->args[2];
491e92935e1SRoland Stigge 	return gpiospec->args[1];
492e92935e1SRoland Stigge }
493e92935e1SRoland Stigge 
4943836309dSBill Pemberton static int lpc32xx_gpio_probe(struct platform_device *pdev)
495e92935e1SRoland Stigge {
496f80cb526SLinus Walleij 	int i;
497f80cb526SLinus Walleij 
498e92935e1SRoland Stigge 	for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) {
499e92935e1SRoland Stigge 		if (pdev->dev.of_node) {
500e92935e1SRoland Stigge 			lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate;
501e92935e1SRoland Stigge 			lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3;
502e92935e1SRoland Stigge 			lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node;
503e92935e1SRoland Stigge 		}
50469c0a0a5SLaxman Dewangan 		devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip,
505a9bc97e4SLinus Walleij 				  &lpc32xx_gpiochip[i]);
506f80cb526SLinus Walleij 	}
507e92935e1SRoland Stigge 
508e92935e1SRoland Stigge 	return 0;
509e92935e1SRoland Stigge }
510e92935e1SRoland Stigge 
511e92935e1SRoland Stigge #ifdef CONFIG_OF
512e95c7c45SJingoo Han static const struct of_device_id lpc32xx_gpio_of_match[] = {
513e92935e1SRoland Stigge 	{ .compatible = "nxp,lpc3220-gpio", },
514e92935e1SRoland Stigge 	{ },
515e92935e1SRoland Stigge };
516e92935e1SRoland Stigge #endif
517e92935e1SRoland Stigge 
518e92935e1SRoland Stigge static struct platform_driver lpc32xx_gpio_driver = {
519e92935e1SRoland Stigge 	.driver		= {
520e92935e1SRoland Stigge 		.name	= "lpc32xx-gpio",
521e92935e1SRoland Stigge 		.of_match_table = of_match_ptr(lpc32xx_gpio_of_match),
522e92935e1SRoland Stigge 	},
523e92935e1SRoland Stigge 	.probe		= lpc32xx_gpio_probe,
524e92935e1SRoland Stigge };
525e92935e1SRoland Stigge 
526e92935e1SRoland Stigge module_platform_driver(lpc32xx_gpio_driver);
527