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