2 * GPIO driver for NXP LPC18xx/43xx.
4 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
12 #include <linux/clk.h>
13 #include <linux/gpio/driver.h>
15 #include <linux/module.h>
17 #include <linux/of_gpio.h>
18 #include <linux/pinctrl/consumer.h>
19 #include <linux/platform_device.h>
21 /* LPC18xx GPIO register offsets */
22 #define LPC18XX_REG_DIR(n) (0x2000 + n * sizeof(u32))
24 #define LPC18XX_MAX_PORTS 8
25 #define LPC18XX_PINS_PER_PORT 32
27 struct lpc18xx_gpio_chip
{
28 struct gpio_chip gpio
;
34 static inline struct lpc18xx_gpio_chip
*to_lpc18xx_gpio(struct gpio_chip
*chip
)
36 return container_of(chip
, struct lpc18xx_gpio_chip
, gpio
);
39 static int lpc18xx_gpio_request(struct gpio_chip
*chip
, unsigned offset
)
41 return pinctrl_request_gpio(offset
);
44 static void lpc18xx_gpio_free(struct gpio_chip
*chip
, unsigned offset
)
46 pinctrl_free_gpio(offset
);
49 static void lpc18xx_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
51 struct lpc18xx_gpio_chip
*gc
= to_lpc18xx_gpio(chip
);
52 writeb(value
? 1 : 0, gc
->base
+ offset
);
55 static int lpc18xx_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
57 struct lpc18xx_gpio_chip
*gc
= to_lpc18xx_gpio(chip
);
58 return !!readb(gc
->base
+ offset
);
61 static int lpc18xx_gpio_direction(struct gpio_chip
*chip
, unsigned offset
,
64 struct lpc18xx_gpio_chip
*gc
= to_lpc18xx_gpio(chip
);
68 port
= offset
/ LPC18XX_PINS_PER_PORT
;
69 pin
= offset
% LPC18XX_PINS_PER_PORT
;
71 spin_lock_irqsave(&gc
->lock
, flags
);
72 dir
= readl(gc
->base
+ LPC18XX_REG_DIR(port
));
77 writel(dir
, gc
->base
+ LPC18XX_REG_DIR(port
));
78 spin_unlock_irqrestore(&gc
->lock
, flags
);
83 static int lpc18xx_gpio_direction_input(struct gpio_chip
*chip
,
86 return lpc18xx_gpio_direction(chip
, offset
, false);
89 static int lpc18xx_gpio_direction_output(struct gpio_chip
*chip
,
90 unsigned offset
, int value
)
92 lpc18xx_gpio_set(chip
, offset
, value
);
93 return lpc18xx_gpio_direction(chip
, offset
, true);
96 static struct gpio_chip lpc18xx_chip
= {
97 .label
= "lpc18xx/43xx-gpio",
98 .request
= lpc18xx_gpio_request
,
99 .free
= lpc18xx_gpio_free
,
100 .direction_input
= lpc18xx_gpio_direction_input
,
101 .direction_output
= lpc18xx_gpio_direction_output
,
102 .set
= lpc18xx_gpio_set
,
103 .get
= lpc18xx_gpio_get
,
104 .ngpio
= LPC18XX_MAX_PORTS
* LPC18XX_PINS_PER_PORT
,
105 .owner
= THIS_MODULE
,
108 static int lpc18xx_gpio_probe(struct platform_device
*pdev
)
110 struct lpc18xx_gpio_chip
*gc
;
111 struct resource
*res
;
114 gc
= devm_kzalloc(&pdev
->dev
, sizeof(*gc
), GFP_KERNEL
);
118 gc
->gpio
= lpc18xx_chip
;
119 platform_set_drvdata(pdev
, gc
);
121 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
122 gc
->base
= devm_ioremap_resource(&pdev
->dev
, res
);
123 if (IS_ERR(gc
->base
))
124 return PTR_ERR(gc
->base
);
126 gc
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
127 if (IS_ERR(gc
->clk
)) {
128 dev_err(&pdev
->dev
, "input clock not found\n");
129 return PTR_ERR(gc
->clk
);
132 ret
= clk_prepare_enable(gc
->clk
);
134 dev_err(&pdev
->dev
, "unable to enable clock\n");
138 spin_lock_init(&gc
->lock
);
140 gc
->gpio
.dev
= &pdev
->dev
;
142 ret
= gpiochip_add(&gc
->gpio
);
144 dev_err(&pdev
->dev
, "failed to add gpio chip\n");
145 clk_disable_unprepare(gc
->clk
);
152 static int lpc18xx_gpio_remove(struct platform_device
*pdev
)
154 struct lpc18xx_gpio_chip
*gc
= platform_get_drvdata(pdev
);
156 gpiochip_remove(&gc
->gpio
);
157 clk_disable_unprepare(gc
->clk
);
162 static const struct of_device_id lpc18xx_gpio_match
[] = {
163 { .compatible
= "nxp,lpc1850-gpio" },
166 MODULE_DEVICE_TABLE(of
, lpc18xx_gpio_match
);
168 static struct platform_driver lpc18xx_gpio_driver
= {
169 .probe
= lpc18xx_gpio_probe
,
170 .remove
= lpc18xx_gpio_remove
,
172 .name
= "lpc18xx-gpio",
173 .of_match_table
= lpc18xx_gpio_match
,
176 module_platform_driver(lpc18xx_gpio_driver
);
178 MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
179 MODULE_DESCRIPTION("GPIO driver for LPC18xx/43xx");
180 MODULE_LICENSE("GPL v2");