xref: /openbmc/linux/drivers/gpio/gpio-lpc32xx.c (revision c942fddf)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2f80cb526SLinus Walleij /*
3da03d740SRoland Stigge  * GPIO driver for LPC32xx SoC
4f80cb526SLinus Walleij  *
5f80cb526SLinus Walleij  * Author: Kevin Wells <kevin.wells@nxp.com>
6f80cb526SLinus Walleij  *
7f80cb526SLinus Walleij  * Copyright (C) 2010 NXP Semiconductors
8f80cb526SLinus Walleij  */
9f80cb526SLinus Walleij 
10f80cb526SLinus Walleij #include <linux/kernel.h>
11f80cb526SLinus Walleij #include <linux/init.h>
12f80cb526SLinus Walleij #include <linux/io.h>
13f80cb526SLinus Walleij #include <linux/errno.h>
1411975f9eSLinus Walleij #include <linux/gpio/driver.h>
15831cbd7aSSachin Kamat #include <linux/of.h>
16e92935e1SRoland Stigge #include <linux/platform_device.h>
17e92935e1SRoland Stigge #include <linux/module.h>
18f80cb526SLinus Walleij 
19f80cb526SLinus Walleij #include <mach/hardware.h>
20f80cb526SLinus Walleij #include <mach/platform.h>
21f80cb526SLinus Walleij 
22f80cb526SLinus Walleij #define LPC32XX_GPIO_P3_INP_STATE		_GPREG(0x000)
23f80cb526SLinus Walleij #define LPC32XX_GPIO_P3_OUTP_SET		_GPREG(0x004)
24f80cb526SLinus Walleij #define LPC32XX_GPIO_P3_OUTP_CLR		_GPREG(0x008)
25f80cb526SLinus Walleij #define LPC32XX_GPIO_P3_OUTP_STATE		_GPREG(0x00C)
26f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_DIR_SET			_GPREG(0x010)
27f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_DIR_CLR			_GPREG(0x014)
28f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_DIR_STATE		_GPREG(0x018)
29f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_INP_STATE		_GPREG(0x01C)
30f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_OUTP_SET		_GPREG(0x020)
31f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_OUTP_CLR		_GPREG(0x024)
32f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_MUX_SET			_GPREG(0x028)
33f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_MUX_CLR			_GPREG(0x02C)
34f80cb526SLinus Walleij #define LPC32XX_GPIO_P2_MUX_STATE		_GPREG(0x030)
35f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_INP_STATE		_GPREG(0x040)
36f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_OUTP_SET		_GPREG(0x044)
37f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_OUTP_CLR		_GPREG(0x048)
38f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_OUTP_STATE		_GPREG(0x04C)
39f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_DIR_SET			_GPREG(0x050)
40f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_DIR_CLR			_GPREG(0x054)
41f80cb526SLinus Walleij #define LPC32XX_GPIO_P0_DIR_STATE		_GPREG(0x058)
42f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_INP_STATE		_GPREG(0x060)
43f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_OUTP_SET		_GPREG(0x064)
44f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_OUTP_CLR		_GPREG(0x068)
45f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_OUTP_STATE		_GPREG(0x06C)
46f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_DIR_SET			_GPREG(0x070)
47f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_DIR_CLR			_GPREG(0x074)
48f80cb526SLinus Walleij #define LPC32XX_GPIO_P1_DIR_STATE		_GPREG(0x078)
49f80cb526SLinus Walleij 
50f80cb526SLinus Walleij #define GPIO012_PIN_TO_BIT(x)			(1 << (x))
51f80cb526SLinus Walleij #define GPIO3_PIN_TO_BIT(x)			(1 << ((x) + 25))
52f80cb526SLinus Walleij #define GPO3_PIN_TO_BIT(x)			(1 << (x))
53f80cb526SLinus Walleij #define GPIO012_PIN_IN_SEL(x, y)		(((x) >> (y)) & 1)
54f80cb526SLinus Walleij #define GPIO3_PIN_IN_SHIFT(x)			((x) == 5 ? 24 : 10 + (x))
558e5fb37bSRoland Stigge #define GPIO3_PIN_IN_SEL(x, y)			(((x) >> GPIO3_PIN_IN_SHIFT(y)) & 1)
56f80cb526SLinus Walleij #define GPIO3_PIN5_IN_SEL(x)			(((x) >> 24) & 1)
57f80cb526SLinus Walleij #define GPI3_PIN_IN_SEL(x, y)			(((x) >> (y)) & 1)
5846158aadSRoland Stigge #define GPO3_PIN_IN_SEL(x, y)			(((x) >> (y)) & 1)
59f80cb526SLinus Walleij 
6014bf873eSVladimir Zapolskiy #define LPC32XX_GPIO_P0_MAX	8
6114bf873eSVladimir Zapolskiy #define LPC32XX_GPIO_P1_MAX	24
6214bf873eSVladimir Zapolskiy #define LPC32XX_GPIO_P2_MAX	13
6314bf873eSVladimir Zapolskiy #define LPC32XX_GPIO_P3_MAX	6
6414bf873eSVladimir Zapolskiy #define LPC32XX_GPI_P3_MAX	29
6514bf873eSVladimir Zapolskiy #define LPC32XX_GPO_P3_MAX	24
6614bf873eSVladimir Zapolskiy 
6714bf873eSVladimir Zapolskiy #define LPC32XX_GPIO_P0_GRP	0
6814bf873eSVladimir Zapolskiy #define LPC32XX_GPIO_P1_GRP	(LPC32XX_GPIO_P0_GRP + LPC32XX_GPIO_P0_MAX)
6914bf873eSVladimir Zapolskiy #define LPC32XX_GPIO_P2_GRP	(LPC32XX_GPIO_P1_GRP + LPC32XX_GPIO_P1_MAX)
7014bf873eSVladimir Zapolskiy #define LPC32XX_GPIO_P3_GRP	(LPC32XX_GPIO_P2_GRP + LPC32XX_GPIO_P2_MAX)
7114bf873eSVladimir Zapolskiy #define LPC32XX_GPI_P3_GRP	(LPC32XX_GPIO_P3_GRP + LPC32XX_GPIO_P3_MAX)
7214bf873eSVladimir Zapolskiy #define LPC32XX_GPO_P3_GRP	(LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX)
7314bf873eSVladimir Zapolskiy 
74f80cb526SLinus Walleij struct gpio_regs {
75f80cb526SLinus Walleij 	void __iomem *inp_state;
7646158aadSRoland Stigge 	void __iomem *outp_state;
77f80cb526SLinus Walleij 	void __iomem *outp_set;
78f80cb526SLinus Walleij 	void __iomem *outp_clr;
79f80cb526SLinus Walleij 	void __iomem *dir_set;
80f80cb526SLinus Walleij 	void __iomem *dir_clr;
81f80cb526SLinus Walleij };
82f80cb526SLinus Walleij 
83f80cb526SLinus Walleij /*
84f80cb526SLinus Walleij  * GPIO names
85f80cb526SLinus Walleij  */
86f80cb526SLinus Walleij static const char *gpio_p0_names[LPC32XX_GPIO_P0_MAX] = {
87f80cb526SLinus Walleij 	"p0.0", "p0.1", "p0.2", "p0.3",
88f80cb526SLinus Walleij 	"p0.4", "p0.5", "p0.6", "p0.7"
89f80cb526SLinus Walleij };
90f80cb526SLinus Walleij 
91f80cb526SLinus Walleij static const char *gpio_p1_names[LPC32XX_GPIO_P1_MAX] = {
92f80cb526SLinus Walleij 	"p1.0", "p1.1", "p1.2", "p1.3",
93f80cb526SLinus Walleij 	"p1.4", "p1.5", "p1.6", "p1.7",
94f80cb526SLinus Walleij 	"p1.8", "p1.9", "p1.10", "p1.11",
95f80cb526SLinus Walleij 	"p1.12", "p1.13", "p1.14", "p1.15",
96f80cb526SLinus Walleij 	"p1.16", "p1.17", "p1.18", "p1.19",
97f80cb526SLinus Walleij 	"p1.20", "p1.21", "p1.22", "p1.23",
98f80cb526SLinus Walleij };
99f80cb526SLinus Walleij 
100f80cb526SLinus Walleij static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = {
101f80cb526SLinus Walleij 	"p2.0", "p2.1", "p2.2", "p2.3",
102f80cb526SLinus Walleij 	"p2.4", "p2.5", "p2.6", "p2.7",
103f80cb526SLinus Walleij 	"p2.8", "p2.9", "p2.10", "p2.11",
104f80cb526SLinus Walleij 	"p2.12"
105f80cb526SLinus Walleij };
106f80cb526SLinus Walleij 
107f80cb526SLinus Walleij static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = {
10895120d5dSRoland Stigge 	"gpio00", "gpio01", "gpio02", "gpio03",
109f80cb526SLinus Walleij 	"gpio04", "gpio05"
110f80cb526SLinus Walleij };
111f80cb526SLinus Walleij 
112f80cb526SLinus Walleij static const char *gpi_p3_names[LPC32XX_GPI_P3_MAX] = {
113f80cb526SLinus Walleij 	"gpi00", "gpi01", "gpi02", "gpi03",
114f80cb526SLinus Walleij 	"gpi04", "gpi05", "gpi06", "gpi07",
115f80cb526SLinus Walleij 	"gpi08", "gpi09",  NULL,    NULL,
116f80cb526SLinus Walleij 	 NULL,    NULL,    NULL,   "gpi15",
117f80cb526SLinus Walleij 	"gpi16", "gpi17", "gpi18", "gpi19",
118f80cb526SLinus Walleij 	"gpi20", "gpi21", "gpi22", "gpi23",
11971fde000SRoland Stigge 	"gpi24", "gpi25", "gpi26", "gpi27",
12071fde000SRoland Stigge 	"gpi28"
121f80cb526SLinus Walleij };
122f80cb526SLinus Walleij 
123f80cb526SLinus Walleij static const char *gpo_p3_names[LPC32XX_GPO_P3_MAX] = {
124f80cb526SLinus Walleij 	"gpo00", "gpo01", "gpo02", "gpo03",
125f80cb526SLinus Walleij 	"gpo04", "gpo05", "gpo06", "gpo07",
126f80cb526SLinus Walleij 	"gpo08", "gpo09", "gpo10", "gpo11",
127f80cb526SLinus Walleij 	"gpo12", "gpo13", "gpo14", "gpo15",
128f80cb526SLinus Walleij 	"gpo16", "gpo17", "gpo18", "gpo19",
129f80cb526SLinus Walleij 	"gpo20", "gpo21", "gpo22", "gpo23"
130f80cb526SLinus Walleij };
131f80cb526SLinus Walleij 
132f80cb526SLinus Walleij static struct gpio_regs gpio_grp_regs_p0 = {
133f80cb526SLinus Walleij 	.inp_state	= LPC32XX_GPIO_P0_INP_STATE,
134f80cb526SLinus Walleij 	.outp_set	= LPC32XX_GPIO_P0_OUTP_SET,
135f80cb526SLinus Walleij 	.outp_clr	= LPC32XX_GPIO_P0_OUTP_CLR,
136f80cb526SLinus Walleij 	.dir_set	= LPC32XX_GPIO_P0_DIR_SET,
137f80cb526SLinus Walleij 	.dir_clr	= LPC32XX_GPIO_P0_DIR_CLR,
138f80cb526SLinus Walleij };
139f80cb526SLinus Walleij 
140f80cb526SLinus Walleij static struct gpio_regs gpio_grp_regs_p1 = {
141f80cb526SLinus Walleij 	.inp_state	= LPC32XX_GPIO_P1_INP_STATE,
142f80cb526SLinus Walleij 	.outp_set	= LPC32XX_GPIO_P1_OUTP_SET,
143f80cb526SLinus Walleij 	.outp_clr	= LPC32XX_GPIO_P1_OUTP_CLR,
144f80cb526SLinus Walleij 	.dir_set	= LPC32XX_GPIO_P1_DIR_SET,
145f80cb526SLinus Walleij 	.dir_clr	= LPC32XX_GPIO_P1_DIR_CLR,
146f80cb526SLinus Walleij };
147f80cb526SLinus Walleij 
148f80cb526SLinus Walleij static struct gpio_regs gpio_grp_regs_p2 = {
149f80cb526SLinus Walleij 	.inp_state	= LPC32XX_GPIO_P2_INP_STATE,
150f80cb526SLinus Walleij 	.outp_set	= LPC32XX_GPIO_P2_OUTP_SET,
151f80cb526SLinus Walleij 	.outp_clr	= LPC32XX_GPIO_P2_OUTP_CLR,
152f80cb526SLinus Walleij 	.dir_set	= LPC32XX_GPIO_P2_DIR_SET,
153f80cb526SLinus Walleij 	.dir_clr	= LPC32XX_GPIO_P2_DIR_CLR,
154f80cb526SLinus Walleij };
155f80cb526SLinus Walleij 
156f80cb526SLinus Walleij static struct gpio_regs gpio_grp_regs_p3 = {
157f80cb526SLinus Walleij 	.inp_state	= LPC32XX_GPIO_P3_INP_STATE,
15846158aadSRoland Stigge 	.outp_state	= LPC32XX_GPIO_P3_OUTP_STATE,
159f80cb526SLinus Walleij 	.outp_set	= LPC32XX_GPIO_P3_OUTP_SET,
160f80cb526SLinus Walleij 	.outp_clr	= LPC32XX_GPIO_P3_OUTP_CLR,
161f80cb526SLinus Walleij 	.dir_set	= LPC32XX_GPIO_P2_DIR_SET,
162f80cb526SLinus Walleij 	.dir_clr	= LPC32XX_GPIO_P2_DIR_CLR,
163f80cb526SLinus Walleij };
164f80cb526SLinus Walleij 
165f80cb526SLinus Walleij struct lpc32xx_gpio_chip {
166f80cb526SLinus Walleij 	struct gpio_chip	chip;
167f80cb526SLinus Walleij 	struct gpio_regs	*gpio_grp;
168f80cb526SLinus Walleij };
169f80cb526SLinus Walleij 
170f80cb526SLinus Walleij static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group,
171f80cb526SLinus Walleij 	unsigned pin, int input)
172f80cb526SLinus Walleij {
173f80cb526SLinus Walleij 	if (input)
174f80cb526SLinus Walleij 		__raw_writel(GPIO012_PIN_TO_BIT(pin),
175f80cb526SLinus Walleij 			group->gpio_grp->dir_clr);
176f80cb526SLinus Walleij 	else
177f80cb526SLinus Walleij 		__raw_writel(GPIO012_PIN_TO_BIT(pin),
178f80cb526SLinus Walleij 			group->gpio_grp->dir_set);
179f80cb526SLinus Walleij }
180f80cb526SLinus Walleij 
181f80cb526SLinus Walleij static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group,
182f80cb526SLinus Walleij 	unsigned pin, int input)
183f80cb526SLinus Walleij {
184f80cb526SLinus Walleij 	u32 u = GPIO3_PIN_TO_BIT(pin);
185f80cb526SLinus Walleij 
186f80cb526SLinus Walleij 	if (input)
187f80cb526SLinus Walleij 		__raw_writel(u, group->gpio_grp->dir_clr);
188f80cb526SLinus Walleij 	else
189f80cb526SLinus Walleij 		__raw_writel(u, group->gpio_grp->dir_set);
190f80cb526SLinus Walleij }
191f80cb526SLinus Walleij 
192f80cb526SLinus Walleij static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group,
193f80cb526SLinus Walleij 	unsigned pin, int high)
194f80cb526SLinus Walleij {
195f80cb526SLinus Walleij 	if (high)
196f80cb526SLinus Walleij 		__raw_writel(GPIO012_PIN_TO_BIT(pin),
197f80cb526SLinus Walleij 			group->gpio_grp->outp_set);
198f80cb526SLinus Walleij 	else
199f80cb526SLinus Walleij 		__raw_writel(GPIO012_PIN_TO_BIT(pin),
200f80cb526SLinus Walleij 			group->gpio_grp->outp_clr);
201f80cb526SLinus Walleij }
202f80cb526SLinus Walleij 
203f80cb526SLinus Walleij static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group,
204f80cb526SLinus Walleij 	unsigned pin, int high)
205f80cb526SLinus Walleij {
206f80cb526SLinus Walleij 	u32 u = GPIO3_PIN_TO_BIT(pin);
207f80cb526SLinus Walleij 
208f80cb526SLinus Walleij 	if (high)
209f80cb526SLinus Walleij 		__raw_writel(u, group->gpio_grp->outp_set);
210f80cb526SLinus Walleij 	else
211f80cb526SLinus Walleij 		__raw_writel(u, group->gpio_grp->outp_clr);
212f80cb526SLinus Walleij }
213f80cb526SLinus Walleij 
214f80cb526SLinus Walleij static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group,
215f80cb526SLinus Walleij 	unsigned pin, int high)
216f80cb526SLinus Walleij {
217f80cb526SLinus Walleij 	if (high)
218f80cb526SLinus Walleij 		__raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set);
219f80cb526SLinus Walleij 	else
220f80cb526SLinus Walleij 		__raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr);
221f80cb526SLinus Walleij }
222f80cb526SLinus Walleij 
223f80cb526SLinus Walleij static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group,
224f80cb526SLinus Walleij 	unsigned pin)
225f80cb526SLinus Walleij {
226f80cb526SLinus Walleij 	return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state),
227f80cb526SLinus Walleij 		pin);
228f80cb526SLinus Walleij }
229f80cb526SLinus Walleij 
230f80cb526SLinus Walleij static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group,
231f80cb526SLinus Walleij 	unsigned pin)
232f80cb526SLinus Walleij {
233f80cb526SLinus Walleij 	int state = __raw_readl(group->gpio_grp->inp_state);
234f80cb526SLinus Walleij 
235f80cb526SLinus Walleij 	/*
236f80cb526SLinus Walleij 	 * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped
237f80cb526SLinus Walleij 	 * to bits 10..14, while GPIOP3-5 is mapped to bit 24.
238f80cb526SLinus Walleij 	 */
239f80cb526SLinus Walleij 	return GPIO3_PIN_IN_SEL(state, pin);
240f80cb526SLinus Walleij }
241f80cb526SLinus Walleij 
242f80cb526SLinus Walleij static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group,
243f80cb526SLinus Walleij 	unsigned pin)
244f80cb526SLinus Walleij {
245f80cb526SLinus Walleij 	return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin);
246f80cb526SLinus Walleij }
247f80cb526SLinus Walleij 
24846158aadSRoland Stigge static int __get_gpo_state_p3(struct lpc32xx_gpio_chip *group,
24946158aadSRoland Stigge 	unsigned pin)
25046158aadSRoland Stigge {
25146158aadSRoland Stigge 	return GPO3_PIN_IN_SEL(__raw_readl(group->gpio_grp->outp_state), pin);
25246158aadSRoland Stigge }
25346158aadSRoland Stigge 
254f80cb526SLinus Walleij /*
2557fd2bf3dSAlexandre Courbot  * GPIO primitives.
256f80cb526SLinus Walleij  */
257f80cb526SLinus Walleij static int lpc32xx_gpio_dir_input_p012(struct gpio_chip *chip,
258f80cb526SLinus Walleij 	unsigned pin)
259f80cb526SLinus Walleij {
260a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
261f80cb526SLinus Walleij 
262f80cb526SLinus Walleij 	__set_gpio_dir_p012(group, pin, 1);
263f80cb526SLinus Walleij 
264f80cb526SLinus Walleij 	return 0;
265f80cb526SLinus Walleij }
266f80cb526SLinus Walleij 
267f80cb526SLinus Walleij static int lpc32xx_gpio_dir_input_p3(struct gpio_chip *chip,
268f80cb526SLinus Walleij 	unsigned pin)
269f80cb526SLinus Walleij {
270a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
271f80cb526SLinus Walleij 
272f80cb526SLinus Walleij 	__set_gpio_dir_p3(group, pin, 1);
273f80cb526SLinus Walleij 
274f80cb526SLinus Walleij 	return 0;
275f80cb526SLinus Walleij }
276f80cb526SLinus Walleij 
277f80cb526SLinus Walleij static int lpc32xx_gpio_dir_in_always(struct gpio_chip *chip,
278f80cb526SLinus Walleij 	unsigned pin)
279f80cb526SLinus Walleij {
280f80cb526SLinus Walleij 	return 0;
281f80cb526SLinus Walleij }
282f80cb526SLinus Walleij 
283f80cb526SLinus Walleij static int lpc32xx_gpio_get_value_p012(struct gpio_chip *chip, unsigned pin)
284f80cb526SLinus Walleij {
285a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
286f80cb526SLinus Walleij 
2872e6d8456SLinus Walleij 	return !!__get_gpio_state_p012(group, pin);
288f80cb526SLinus Walleij }
289f80cb526SLinus Walleij 
290f80cb526SLinus Walleij static int lpc32xx_gpio_get_value_p3(struct gpio_chip *chip, unsigned pin)
291f80cb526SLinus Walleij {
292a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
293f80cb526SLinus Walleij 
2942e6d8456SLinus Walleij 	return !!__get_gpio_state_p3(group, pin);
295f80cb526SLinus Walleij }
296f80cb526SLinus Walleij 
297f80cb526SLinus Walleij static int lpc32xx_gpi_get_value(struct gpio_chip *chip, unsigned pin)
298f80cb526SLinus Walleij {
299a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
300f80cb526SLinus Walleij 
3012e6d8456SLinus Walleij 	return !!__get_gpi_state_p3(group, pin);
302f80cb526SLinus Walleij }
303f80cb526SLinus Walleij 
304f80cb526SLinus Walleij static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
305f80cb526SLinus Walleij 	int value)
306f80cb526SLinus Walleij {
307a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
308f80cb526SLinus Walleij 
309b1268d37SRoland Stigge 	__set_gpio_level_p012(group, pin, value);
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 {
318a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
319f80cb526SLinus Walleij 
320b1268d37SRoland Stigge 	__set_gpio_level_p3(group, pin, value);
321f80cb526SLinus Walleij 	__set_gpio_dir_p3(group, pin, 0);
322f80cb526SLinus Walleij 
323f80cb526SLinus Walleij 	return 0;
324f80cb526SLinus Walleij }
325f80cb526SLinus Walleij 
326f80cb526SLinus Walleij static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
327f80cb526SLinus Walleij 	int value)
328f80cb526SLinus Walleij {
329a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
330b1268d37SRoland Stigge 
331b1268d37SRoland Stigge 	__set_gpo_level_p3(group, pin, value);
332f80cb526SLinus Walleij 	return 0;
333f80cb526SLinus Walleij }
334f80cb526SLinus Walleij 
335f80cb526SLinus Walleij static void lpc32xx_gpio_set_value_p012(struct gpio_chip *chip, unsigned pin,
336f80cb526SLinus Walleij 	int value)
337f80cb526SLinus Walleij {
338a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
339f80cb526SLinus Walleij 
340f80cb526SLinus Walleij 	__set_gpio_level_p012(group, pin, value);
341f80cb526SLinus Walleij }
342f80cb526SLinus Walleij 
343f80cb526SLinus Walleij static void lpc32xx_gpio_set_value_p3(struct gpio_chip *chip, unsigned pin,
344f80cb526SLinus Walleij 	int value)
345f80cb526SLinus Walleij {
346a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
347f80cb526SLinus Walleij 
348f80cb526SLinus Walleij 	__set_gpio_level_p3(group, pin, value);
349f80cb526SLinus Walleij }
350f80cb526SLinus Walleij 
351f80cb526SLinus Walleij static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin,
352f80cb526SLinus Walleij 	int value)
353f80cb526SLinus Walleij {
354a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
355f80cb526SLinus Walleij 
356f80cb526SLinus Walleij 	__set_gpo_level_p3(group, pin, value);
357f80cb526SLinus Walleij }
358f80cb526SLinus Walleij 
35946158aadSRoland Stigge static int lpc32xx_gpo_get_value(struct gpio_chip *chip, unsigned pin)
36046158aadSRoland Stigge {
361a9bc97e4SLinus Walleij 	struct lpc32xx_gpio_chip *group = gpiochip_get_data(chip);
36246158aadSRoland Stigge 
3632e6d8456SLinus Walleij 	return !!__get_gpo_state_p3(group, pin);
36446158aadSRoland Stigge }
36546158aadSRoland Stigge 
366f80cb526SLinus Walleij static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin)
367f80cb526SLinus Walleij {
368f80cb526SLinus Walleij 	if (pin < chip->ngpio)
369f80cb526SLinus Walleij 		return 0;
370f80cb526SLinus Walleij 
371f80cb526SLinus Walleij 	return -EINVAL;
372f80cb526SLinus Walleij }
373f80cb526SLinus Walleij 
3740bdfeddcSRoland Stigge static int lpc32xx_gpio_to_irq_p01(struct gpio_chip *chip, unsigned offset)
3750bdfeddcSRoland Stigge {
3760bdfeddcSRoland Stigge 	return -ENXIO;
3770bdfeddcSRoland Stigge }
3780bdfeddcSRoland Stigge 
379320a6480SSylvain Lemieux static int lpc32xx_gpio_to_irq_gpio_p3(struct gpio_chip *chip, unsigned offset)
380320a6480SSylvain Lemieux {
381320a6480SSylvain Lemieux 	return -ENXIO;
382320a6480SSylvain Lemieux }
3830bdfeddcSRoland Stigge 
3840bdfeddcSRoland Stigge static int lpc32xx_gpio_to_irq_gpi_p3(struct gpio_chip *chip, unsigned offset)
3850bdfeddcSRoland Stigge {
3860bdfeddcSRoland Stigge 	return -ENXIO;
3870bdfeddcSRoland Stigge }
3880bdfeddcSRoland Stigge 
389f80cb526SLinus Walleij static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
390f80cb526SLinus Walleij 	{
391f80cb526SLinus Walleij 		.chip = {
392f80cb526SLinus Walleij 			.label			= "gpio_p0",
393f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_input_p012,
394f80cb526SLinus Walleij 			.get			= lpc32xx_gpio_get_value_p012,
395f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_output_p012,
396f80cb526SLinus Walleij 			.set			= lpc32xx_gpio_set_value_p012,
397f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
3980bdfeddcSRoland Stigge 			.to_irq			= lpc32xx_gpio_to_irq_p01,
399f80cb526SLinus Walleij 			.base			= LPC32XX_GPIO_P0_GRP,
400f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPIO_P0_MAX,
401f80cb526SLinus Walleij 			.names			= gpio_p0_names,
4029fb1f39eSLinus Walleij 			.can_sleep		= false,
403f80cb526SLinus Walleij 		},
404f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p0,
405f80cb526SLinus Walleij 	},
406f80cb526SLinus Walleij 	{
407f80cb526SLinus Walleij 		.chip = {
408f80cb526SLinus Walleij 			.label			= "gpio_p1",
409f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_input_p012,
410f80cb526SLinus Walleij 			.get			= lpc32xx_gpio_get_value_p012,
411f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_output_p012,
412f80cb526SLinus Walleij 			.set			= lpc32xx_gpio_set_value_p012,
413f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
4140bdfeddcSRoland Stigge 			.to_irq			= lpc32xx_gpio_to_irq_p01,
415f80cb526SLinus Walleij 			.base			= LPC32XX_GPIO_P1_GRP,
416f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPIO_P1_MAX,
417f80cb526SLinus Walleij 			.names			= gpio_p1_names,
4189fb1f39eSLinus Walleij 			.can_sleep		= false,
419f80cb526SLinus Walleij 		},
420f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p1,
421f80cb526SLinus Walleij 	},
422f80cb526SLinus Walleij 	{
423f80cb526SLinus Walleij 		.chip = {
424f80cb526SLinus Walleij 			.label			= "gpio_p2",
425f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_input_p012,
426f80cb526SLinus Walleij 			.get			= lpc32xx_gpio_get_value_p012,
427f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_output_p012,
428f80cb526SLinus Walleij 			.set			= lpc32xx_gpio_set_value_p012,
429f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
430f80cb526SLinus Walleij 			.base			= LPC32XX_GPIO_P2_GRP,
431f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPIO_P2_MAX,
432f80cb526SLinus Walleij 			.names			= gpio_p2_names,
4339fb1f39eSLinus Walleij 			.can_sleep		= false,
434f80cb526SLinus Walleij 		},
435f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p2,
436f80cb526SLinus Walleij 	},
437f80cb526SLinus Walleij 	{
438f80cb526SLinus Walleij 		.chip = {
439f80cb526SLinus Walleij 			.label			= "gpio_p3",
440f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_input_p3,
441f80cb526SLinus Walleij 			.get			= lpc32xx_gpio_get_value_p3,
442f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_output_p3,
443f80cb526SLinus Walleij 			.set			= lpc32xx_gpio_set_value_p3,
444f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
4450bdfeddcSRoland Stigge 			.to_irq			= lpc32xx_gpio_to_irq_gpio_p3,
446f80cb526SLinus Walleij 			.base			= LPC32XX_GPIO_P3_GRP,
447f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPIO_P3_MAX,
448f80cb526SLinus Walleij 			.names			= gpio_p3_names,
4499fb1f39eSLinus Walleij 			.can_sleep		= false,
450f80cb526SLinus Walleij 		},
451f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p3,
452f80cb526SLinus Walleij 	},
453f80cb526SLinus Walleij 	{
454f80cb526SLinus Walleij 		.chip = {
455f80cb526SLinus Walleij 			.label			= "gpi_p3",
456f80cb526SLinus Walleij 			.direction_input	= lpc32xx_gpio_dir_in_always,
457f80cb526SLinus Walleij 			.get			= lpc32xx_gpi_get_value,
458f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
4590bdfeddcSRoland Stigge 			.to_irq			= lpc32xx_gpio_to_irq_gpi_p3,
460f80cb526SLinus Walleij 			.base			= LPC32XX_GPI_P3_GRP,
461f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPI_P3_MAX,
462f80cb526SLinus Walleij 			.names			= gpi_p3_names,
4639fb1f39eSLinus Walleij 			.can_sleep		= false,
464f80cb526SLinus Walleij 		},
465f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p3,
466f80cb526SLinus Walleij 	},
467f80cb526SLinus Walleij 	{
468f80cb526SLinus Walleij 		.chip = {
469f80cb526SLinus Walleij 			.label			= "gpo_p3",
470f80cb526SLinus Walleij 			.direction_output	= lpc32xx_gpio_dir_out_always,
471f80cb526SLinus Walleij 			.set			= lpc32xx_gpo_set_value,
47246158aadSRoland Stigge 			.get			= lpc32xx_gpo_get_value,
473f80cb526SLinus Walleij 			.request		= lpc32xx_gpio_request,
474f80cb526SLinus Walleij 			.base			= LPC32XX_GPO_P3_GRP,
475f80cb526SLinus Walleij 			.ngpio			= LPC32XX_GPO_P3_MAX,
476f80cb526SLinus Walleij 			.names			= gpo_p3_names,
4779fb1f39eSLinus Walleij 			.can_sleep		= false,
478f80cb526SLinus Walleij 		},
479f80cb526SLinus Walleij 		.gpio_grp = &gpio_grp_regs_p3,
480f80cb526SLinus Walleij 	},
481f80cb526SLinus Walleij };
482f80cb526SLinus Walleij 
483e92935e1SRoland Stigge static int lpc32xx_of_xlate(struct gpio_chip *gc,
484e92935e1SRoland Stigge 			    const struct of_phandle_args *gpiospec, u32 *flags)
485e92935e1SRoland Stigge {
486e92935e1SRoland Stigge 	/* Is this the correct bank? */
487e92935e1SRoland Stigge 	u32 bank = gpiospec->args[0];
488fdc7a9f8SAxel Lin 	if ((bank >= ARRAY_SIZE(lpc32xx_gpiochip) ||
489e92935e1SRoland Stigge 	    (gc != &lpc32xx_gpiochip[bank].chip)))
490e92935e1SRoland Stigge 		return -EINVAL;
491e92935e1SRoland Stigge 
492e92935e1SRoland Stigge 	if (flags)
493e92935e1SRoland Stigge 		*flags = gpiospec->args[2];
494e92935e1SRoland Stigge 	return gpiospec->args[1];
495e92935e1SRoland Stigge }
496e92935e1SRoland Stigge 
4973836309dSBill Pemberton static int lpc32xx_gpio_probe(struct platform_device *pdev)
498e92935e1SRoland Stigge {
499f80cb526SLinus Walleij 	int i;
500f80cb526SLinus Walleij 
501e92935e1SRoland Stigge 	for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) {
502e92935e1SRoland Stigge 		if (pdev->dev.of_node) {
503e92935e1SRoland Stigge 			lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate;
504e92935e1SRoland Stigge 			lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3;
505e92935e1SRoland Stigge 			lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node;
506e92935e1SRoland Stigge 		}
50769c0a0a5SLaxman Dewangan 		devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip,
508a9bc97e4SLinus Walleij 				  &lpc32xx_gpiochip[i]);
509f80cb526SLinus Walleij 	}
510e92935e1SRoland Stigge 
511e92935e1SRoland Stigge 	return 0;
512e92935e1SRoland Stigge }
513e92935e1SRoland Stigge 
514e92935e1SRoland Stigge #ifdef CONFIG_OF
515e95c7c45SJingoo Han static const struct of_device_id lpc32xx_gpio_of_match[] = {
516e92935e1SRoland Stigge 	{ .compatible = "nxp,lpc3220-gpio", },
517e92935e1SRoland Stigge 	{ },
518e92935e1SRoland Stigge };
519e92935e1SRoland Stigge #endif
520e92935e1SRoland Stigge 
521e92935e1SRoland Stigge static struct platform_driver lpc32xx_gpio_driver = {
522e92935e1SRoland Stigge 	.driver		= {
523e92935e1SRoland Stigge 		.name	= "lpc32xx-gpio",
524e92935e1SRoland Stigge 		.of_match_table = of_match_ptr(lpc32xx_gpio_of_match),
525e92935e1SRoland Stigge 	},
526e92935e1SRoland Stigge 	.probe		= lpc32xx_gpio_probe,
527e92935e1SRoland Stigge };
528e92935e1SRoland Stigge 
529e92935e1SRoland Stigge module_platform_driver(lpc32xx_gpio_driver);
530