xref: /openbmc/u-boot/drivers/gpio/lpc32xx_gpio.c (revision da60fb79)
1 /*
2  * LPC32xxGPIO driver
3  *
4  * (C) Copyright 2014  DENX Software Engineering GmbH
5  * Written-by: Albert ARIBAUD <albert.aribaud@3adev.fr>
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <asm/io.h>
11 #include <asm/arch-lpc32xx/cpu.h>
12 #include <asm/arch-lpc32xx/gpio.h>
13 #include <asm-generic/gpio.h>
14 #include <dm.h>
15 
16 /**
17  * LPC32xx GPIOs work in banks but are non-homogeneous:
18  * - each bank holds a different number of GPIOs
19  * - some GPIOs are input/ouput, some input only, some output only;
20  * - some GPIOs have different meanings as an input and as an output;
21  * - some GPIOs are controlled on a given port and bit index, but
22  *   read on another one.
23 *
24  * In order to keep this code simple, GPIOS are considered here as
25  * homogeneous and linear, from 0 to 127.
26  *
27  *	** WARNING #1 **
28  *
29  * Client code is responsible for properly using valid GPIO numbers,
30  * including cases where a single physical GPIO has differing numbers
31  * for setting its direction, reading it and/or writing to it.
32  *
33  *	** WARNING #2 **
34  *
35  * Please read NOTE in description of lpc32xx_gpio_get_function().
36  */
37 
38 #define LPC32XX_GPIOS 128
39 
40 struct lpc32xx_gpio_priv {
41 	struct gpio_regs *regs;
42 	/* GPIO FUNCTION: SEE WARNING #2 */
43 	signed char function[LPC32XX_GPIOS];
44 };
45 
46 /**
47  * We have 4 GPIO ports of 32 bits each
48  */
49 
50 #define MAX_GPIO 128
51 
52 #define GPIO_TO_PORT(gpio) ((gpio / 32) & 3)
53 #define GPIO_TO_RANK(gpio) (gpio % 32)
54 #define GPIO_TO_MASK(gpio) (1 << (gpio % 32))
55 
56 /**
57  * Configure a GPIO number 'offset' as input
58  */
59 
60 static int lpc32xx_gpio_direction_input(struct udevice *dev, unsigned offset)
61 {
62 	int port, mask;
63 	struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev);
64 	struct gpio_regs *regs = gpio_priv->regs;
65 
66 	port = GPIO_TO_PORT(offset);
67 	mask = GPIO_TO_MASK(offset);
68 
69 	switch (port) {
70 	case 0:
71 		writel(mask, &regs->p0_dir_clr);
72 		break;
73 	case 1:
74 		writel(mask, &regs->p1_dir_clr);
75 		break;
76 	case 2:
77 		/* ports 2 and 3 share a common direction */
78 	case 3:
79 		writel(mask, &regs->p2_p3_dir_clr);
80 		break;
81 	default:
82 		return -1;
83 	}
84 
85 	/* GPIO FUNCTION: SEE WARNING #2 */
86 	gpio_priv->function[offset] = GPIOF_INPUT;
87 
88 	return 0;
89 }
90 
91 /**
92  * Get the value of a GPIO
93  */
94 
95 static int lpc32xx_gpio_get_value(struct udevice *dev, unsigned offset)
96 {
97 	int port, rank, mask, value;
98 	struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev);
99 	struct gpio_regs *regs = gpio_priv->regs;
100 
101 	port = GPIO_TO_PORT(offset);
102 
103 	switch (port) {
104 	case 0:
105 		value = readl(&regs->p0_inp_state);
106 		break;
107 	case 1:
108 		value = readl(&regs->p1_inp_state);
109 		break;
110 	case 2:
111 		value = readl(&regs->p2_inp_state);
112 		break;
113 	case 3:
114 		value = readl(&regs->p3_inp_state);
115 		break;
116 	default:
117 		return -1;
118 	}
119 
120 	rank = GPIO_TO_RANK(offset);
121 	mask = GPIO_TO_MASK(offset);
122 
123 	return (value & mask) >> rank;
124 }
125 
126 /**
127  * Set a GPIO
128  */
129 
130 static int gpio_set(struct udevice *dev, unsigned gpio)
131 {
132 	int port, mask;
133 	struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev);
134 	struct gpio_regs *regs = gpio_priv->regs;
135 
136 	port = GPIO_TO_PORT(gpio);
137 	mask = GPIO_TO_MASK(gpio);
138 
139 	switch (port) {
140 	case 0:
141 		writel(mask, &regs->p0_outp_set);
142 		break;
143 	case 1:
144 		writel(mask, &regs->p1_outp_set);
145 		break;
146 	case 2:
147 		writel(mask, &regs->p2_outp_set);
148 		break;
149 	case 3:
150 		writel(mask, &regs->p3_outp_set);
151 		break;
152 	default:
153 		return -1;
154 	}
155 	return 0;
156 }
157 
158 /**
159  * Clear a GPIO
160  */
161 
162 static int gpio_clr(struct udevice *dev, unsigned gpio)
163 {
164 	int port, mask;
165 	struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev);
166 	struct gpio_regs *regs = gpio_priv->regs;
167 
168 	port = GPIO_TO_PORT(gpio);
169 	mask = GPIO_TO_MASK(gpio);
170 
171 	switch (port) {
172 	case 0:
173 		writel(mask, &regs->p0_outp_clr);
174 		break;
175 	case 1:
176 		writel(mask, &regs->p1_outp_clr);
177 		break;
178 	case 2:
179 		writel(mask, &regs->p2_outp_clr);
180 		break;
181 	case 3:
182 		writel(mask, &regs->p3_outp_clr);
183 		break;
184 	default:
185 		return -1;
186 	}
187 	return 0;
188 }
189 
190 /**
191  * Set the value of a GPIO
192  */
193 
194 static int lpc32xx_gpio_set_value(struct udevice *dev, unsigned offset,
195 				 int value)
196 {
197 	if (value)
198 		return gpio_set(dev, offset);
199 	else
200 		return gpio_clr(dev, offset);
201 }
202 
203 /**
204  * Configure a GPIO number 'offset' as output with given initial value.
205  */
206 
207 static int lpc32xx_gpio_direction_output(struct udevice *dev, unsigned offset,
208 				       int value)
209 {
210 	int port, mask;
211 	struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev);
212 	struct gpio_regs *regs = gpio_priv->regs;
213 
214 	port = GPIO_TO_PORT(offset);
215 	mask = GPIO_TO_MASK(offset);
216 
217 	switch (port) {
218 	case 0:
219 		writel(mask, &regs->p0_dir_set);
220 		break;
221 	case 1:
222 		writel(mask, &regs->p1_dir_set);
223 		break;
224 	case 2:
225 		/* ports 2 and 3 share a common direction */
226 	case 3:
227 		writel(mask, &regs->p2_p3_dir_set);
228 		break;
229 	default:
230 		return -1;
231 	}
232 
233 	/* GPIO FUNCTION: SEE WARNING #2 */
234 	gpio_priv->function[offset] = GPIOF_OUTPUT;
235 
236 	return lpc32xx_gpio_set_value(dev, offset, value);
237 }
238 
239 /**
240  * GPIO functions are supposed to be computed from their current
241  * configuration, but that's way too complicated in LPC32XX. A simpler
242  * approach is used, where the GPIO functions are cached in an array.
243  * When the GPIO is in use, its function is either "input" or "output"
244  * depending on its direction, otherwise its function is "unknown".
245  *
246  *	** NOTE **
247  *
248  * THIS APPROACH WAS CHOSEN DU TO THE COMPLEX NATURE OF THE LPC32XX
249  * GPIOS; DO NOT TAKE THIS AS AN EXAMPLE FOR NEW CODE.
250  */
251 
252 static int lpc32xx_gpio_get_function(struct udevice *dev, unsigned offset)
253 {
254 	struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev);
255 	return gpio_priv->function[offset];
256 }
257 
258 static const struct dm_gpio_ops gpio_lpc32xx_ops = {
259 	.direction_input	= lpc32xx_gpio_direction_input,
260 	.direction_output	= lpc32xx_gpio_direction_output,
261 	.get_value		= lpc32xx_gpio_get_value,
262 	.set_value		= lpc32xx_gpio_set_value,
263 	.get_function		= lpc32xx_gpio_get_function,
264 };
265 
266 static int lpc32xx_gpio_probe(struct udevice *dev)
267 {
268 	struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev);
269 	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
270 
271 	if (dev->of_offset == -1) {
272 		/* Tell the uclass how many GPIOs we have */
273 		uc_priv->gpio_count = LPC32XX_GPIOS;
274 	}
275 
276 	/* set base address for GPIO registers */
277 	gpio_priv->regs = (struct gpio_regs *)GPIO_BASE;
278 
279 	/* all GPIO functions are unknown until requested */
280 	/* GPIO FUNCTION: SEE WARNING #2 */
281 	memset(gpio_priv->function, GPIOF_UNKNOWN, sizeof(gpio_priv->function));
282 
283 	return 0;
284 }
285 
286 U_BOOT_DRIVER(gpio_lpc32xx) = {
287 	.name	= "gpio_lpc32xx",
288 	.id	= UCLASS_GPIO,
289 	.ops	= &gpio_lpc32xx_ops,
290 	.probe	= lpc32xx_gpio_probe,
291 	.priv_auto_alloc_size = sizeof(struct lpc32xx_gpio_priv),
292 };
293