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 void lpc18xx_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
36 struct lpc18xx_gpio_chip
*gc
= gpiochip_get_data(chip
);
37 writeb(value
? 1 : 0, gc
->base
+ offset
);
40 static int lpc18xx_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
42 struct lpc18xx_gpio_chip
*gc
= gpiochip_get_data(chip
);
43 return !!readb(gc
->base
+ offset
);
46 static int lpc18xx_gpio_direction(struct gpio_chip
*chip
, unsigned offset
,
49 struct lpc18xx_gpio_chip
*gc
= gpiochip_get_data(chip
);
53 port
= offset
/ LPC18XX_PINS_PER_PORT
;
54 pin
= offset
% LPC18XX_PINS_PER_PORT
;
56 spin_lock_irqsave(&gc
->lock
, flags
);
57 dir
= readl(gc
->base
+ LPC18XX_REG_DIR(port
));
62 writel(dir
, gc
->base
+ LPC18XX_REG_DIR(port
));
63 spin_unlock_irqrestore(&gc
->lock
, flags
);
68 static int lpc18xx_gpio_direction_input(struct gpio_chip
*chip
,
71 return lpc18xx_gpio_direction(chip
, offset
, false);
74 static int lpc18xx_gpio_direction_output(struct gpio_chip
*chip
,
75 unsigned offset
, int value
)
77 lpc18xx_gpio_set(chip
, offset
, value
);
78 return lpc18xx_gpio_direction(chip
, offset
, true);
81 static struct gpio_chip lpc18xx_chip
= {
82 .label
= "lpc18xx/43xx-gpio",
83 .request
= gpiochip_generic_request
,
84 .free
= gpiochip_generic_free
,
85 .direction_input
= lpc18xx_gpio_direction_input
,
86 .direction_output
= lpc18xx_gpio_direction_output
,
87 .set
= lpc18xx_gpio_set
,
88 .get
= lpc18xx_gpio_get
,
89 .ngpio
= LPC18XX_MAX_PORTS
* LPC18XX_PINS_PER_PORT
,
93 static int lpc18xx_gpio_probe(struct platform_device
*pdev
)
95 struct lpc18xx_gpio_chip
*gc
;
99 gc
= devm_kzalloc(&pdev
->dev
, sizeof(*gc
), GFP_KERNEL
);
103 gc
->gpio
= lpc18xx_chip
;
104 platform_set_drvdata(pdev
, gc
);
106 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
107 gc
->base
= devm_ioremap_resource(&pdev
->dev
, res
);
108 if (IS_ERR(gc
->base
))
109 return PTR_ERR(gc
->base
);
111 gc
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
112 if (IS_ERR(gc
->clk
)) {
113 dev_err(&pdev
->dev
, "input clock not found\n");
114 return PTR_ERR(gc
->clk
);
117 ret
= clk_prepare_enable(gc
->clk
);
119 dev_err(&pdev
->dev
, "unable to enable clock\n");
123 spin_lock_init(&gc
->lock
);
125 gc
->gpio
.parent
= &pdev
->dev
;
127 ret
= gpiochip_add_data(&gc
->gpio
, gc
);
129 dev_err(&pdev
->dev
, "failed to add gpio chip\n");
130 clk_disable_unprepare(gc
->clk
);
137 static int lpc18xx_gpio_remove(struct platform_device
*pdev
)
139 struct lpc18xx_gpio_chip
*gc
= platform_get_drvdata(pdev
);
141 gpiochip_remove(&gc
->gpio
);
142 clk_disable_unprepare(gc
->clk
);
147 static const struct of_device_id lpc18xx_gpio_match
[] = {
148 { .compatible
= "nxp,lpc1850-gpio" },
151 MODULE_DEVICE_TABLE(of
, lpc18xx_gpio_match
);
153 static struct platform_driver lpc18xx_gpio_driver
= {
154 .probe
= lpc18xx_gpio_probe
,
155 .remove
= lpc18xx_gpio_remove
,
157 .name
= "lpc18xx-gpio",
158 .of_match_table
= lpc18xx_gpio_match
,
161 module_platform_driver(lpc18xx_gpio_driver
);
163 MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
164 MODULE_DESCRIPTION("GPIO driver for LPC18xx/43xx");
165 MODULE_LICENSE("GPL v2");