.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * GPIO driver for LPC32xx SoC |
---|
3 | 4 | * |
---|
4 | 5 | * Author: Kevin Wells <kevin.wells@nxp.com> |
---|
5 | 6 | * |
---|
6 | 7 | * Copyright (C) 2010 NXP Semiconductors |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License as published by |
---|
10 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
11 | | - * (at your option) any later version. |
---|
12 | | - * |
---|
13 | | - * This program is distributed in the hope that it will be useful, |
---|
14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
16 | | - * GNU General Public License for more details. |
---|
17 | 8 | */ |
---|
18 | 9 | |
---|
19 | 10 | #include <linux/kernel.h> |
---|
.. | .. |
---|
25 | 16 | #include <linux/platform_device.h> |
---|
26 | 17 | #include <linux/module.h> |
---|
27 | 18 | |
---|
28 | | -#include <mach/hardware.h> |
---|
29 | | -#include <mach/platform.h> |
---|
30 | | - |
---|
31 | | -#define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) |
---|
32 | | -#define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) |
---|
33 | | -#define LPC32XX_GPIO_P3_OUTP_CLR _GPREG(0x008) |
---|
34 | | -#define LPC32XX_GPIO_P3_OUTP_STATE _GPREG(0x00C) |
---|
35 | | -#define LPC32XX_GPIO_P2_DIR_SET _GPREG(0x010) |
---|
36 | | -#define LPC32XX_GPIO_P2_DIR_CLR _GPREG(0x014) |
---|
37 | | -#define LPC32XX_GPIO_P2_DIR_STATE _GPREG(0x018) |
---|
38 | | -#define LPC32XX_GPIO_P2_INP_STATE _GPREG(0x01C) |
---|
39 | | -#define LPC32XX_GPIO_P2_OUTP_SET _GPREG(0x020) |
---|
40 | | -#define LPC32XX_GPIO_P2_OUTP_CLR _GPREG(0x024) |
---|
41 | | -#define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028) |
---|
42 | | -#define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C) |
---|
43 | | -#define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030) |
---|
44 | | -#define LPC32XX_GPIO_P0_INP_STATE _GPREG(0x040) |
---|
45 | | -#define LPC32XX_GPIO_P0_OUTP_SET _GPREG(0x044) |
---|
46 | | -#define LPC32XX_GPIO_P0_OUTP_CLR _GPREG(0x048) |
---|
47 | | -#define LPC32XX_GPIO_P0_OUTP_STATE _GPREG(0x04C) |
---|
48 | | -#define LPC32XX_GPIO_P0_DIR_SET _GPREG(0x050) |
---|
49 | | -#define LPC32XX_GPIO_P0_DIR_CLR _GPREG(0x054) |
---|
50 | | -#define LPC32XX_GPIO_P0_DIR_STATE _GPREG(0x058) |
---|
51 | | -#define LPC32XX_GPIO_P1_INP_STATE _GPREG(0x060) |
---|
52 | | -#define LPC32XX_GPIO_P1_OUTP_SET _GPREG(0x064) |
---|
53 | | -#define LPC32XX_GPIO_P1_OUTP_CLR _GPREG(0x068) |
---|
54 | | -#define LPC32XX_GPIO_P1_OUTP_STATE _GPREG(0x06C) |
---|
55 | | -#define LPC32XX_GPIO_P1_DIR_SET _GPREG(0x070) |
---|
56 | | -#define LPC32XX_GPIO_P1_DIR_CLR _GPREG(0x074) |
---|
57 | | -#define LPC32XX_GPIO_P1_DIR_STATE _GPREG(0x078) |
---|
| 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) |
---|
58 | 46 | |
---|
59 | 47 | #define GPIO012_PIN_TO_BIT(x) (1 << (x)) |
---|
60 | 48 | #define GPIO3_PIN_TO_BIT(x) (1 << ((x) + 25)) |
---|
.. | .. |
---|
81 | 69 | #define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX) |
---|
82 | 70 | |
---|
83 | 71 | struct gpio_regs { |
---|
84 | | - void __iomem *inp_state; |
---|
85 | | - void __iomem *outp_state; |
---|
86 | | - void __iomem *outp_set; |
---|
87 | | - void __iomem *outp_clr; |
---|
88 | | - void __iomem *dir_set; |
---|
89 | | - void __iomem *dir_clr; |
---|
| 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; |
---|
90 | 78 | }; |
---|
91 | 79 | |
---|
92 | 80 | /* |
---|
.. | .. |
---|
174 | 162 | struct lpc32xx_gpio_chip { |
---|
175 | 163 | struct gpio_chip chip; |
---|
176 | 164 | struct gpio_regs *gpio_grp; |
---|
| 165 | + void __iomem *reg_base; |
---|
177 | 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 | +} |
---|
178 | 177 | |
---|
179 | 178 | static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group, |
---|
180 | 179 | unsigned pin, int input) |
---|
181 | 180 | { |
---|
182 | 181 | if (input) |
---|
183 | | - __raw_writel(GPIO012_PIN_TO_BIT(pin), |
---|
| 182 | + gpreg_write(group, GPIO012_PIN_TO_BIT(pin), |
---|
184 | 183 | group->gpio_grp->dir_clr); |
---|
185 | 184 | else |
---|
186 | | - __raw_writel(GPIO012_PIN_TO_BIT(pin), |
---|
| 185 | + gpreg_write(group, GPIO012_PIN_TO_BIT(pin), |
---|
187 | 186 | group->gpio_grp->dir_set); |
---|
188 | 187 | } |
---|
189 | 188 | |
---|
.. | .. |
---|
193 | 192 | u32 u = GPIO3_PIN_TO_BIT(pin); |
---|
194 | 193 | |
---|
195 | 194 | if (input) |
---|
196 | | - __raw_writel(u, group->gpio_grp->dir_clr); |
---|
| 195 | + gpreg_write(group, u, group->gpio_grp->dir_clr); |
---|
197 | 196 | else |
---|
198 | | - __raw_writel(u, group->gpio_grp->dir_set); |
---|
| 197 | + gpreg_write(group, u, group->gpio_grp->dir_set); |
---|
199 | 198 | } |
---|
200 | 199 | |
---|
201 | 200 | static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group, |
---|
202 | 201 | unsigned pin, int high) |
---|
203 | 202 | { |
---|
204 | 203 | if (high) |
---|
205 | | - __raw_writel(GPIO012_PIN_TO_BIT(pin), |
---|
| 204 | + gpreg_write(group, GPIO012_PIN_TO_BIT(pin), |
---|
206 | 205 | group->gpio_grp->outp_set); |
---|
207 | 206 | else |
---|
208 | | - __raw_writel(GPIO012_PIN_TO_BIT(pin), |
---|
| 207 | + gpreg_write(group, GPIO012_PIN_TO_BIT(pin), |
---|
209 | 208 | group->gpio_grp->outp_clr); |
---|
210 | 209 | } |
---|
211 | 210 | |
---|
.. | .. |
---|
215 | 214 | u32 u = GPIO3_PIN_TO_BIT(pin); |
---|
216 | 215 | |
---|
217 | 216 | if (high) |
---|
218 | | - __raw_writel(u, group->gpio_grp->outp_set); |
---|
| 217 | + gpreg_write(group, u, group->gpio_grp->outp_set); |
---|
219 | 218 | else |
---|
220 | | - __raw_writel(u, group->gpio_grp->outp_clr); |
---|
| 219 | + gpreg_write(group, u, group->gpio_grp->outp_clr); |
---|
221 | 220 | } |
---|
222 | 221 | |
---|
223 | 222 | static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group, |
---|
224 | 223 | unsigned pin, int high) |
---|
225 | 224 | { |
---|
226 | 225 | if (high) |
---|
227 | | - __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set); |
---|
| 226 | + gpreg_write(group, GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set); |
---|
228 | 227 | else |
---|
229 | | - __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr); |
---|
| 228 | + gpreg_write(group, GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr); |
---|
230 | 229 | } |
---|
231 | 230 | |
---|
232 | 231 | static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group, |
---|
233 | 232 | unsigned pin) |
---|
234 | 233 | { |
---|
235 | | - return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), |
---|
| 234 | + return GPIO012_PIN_IN_SEL(gpreg_read(group, group->gpio_grp->inp_state), |
---|
236 | 235 | pin); |
---|
237 | 236 | } |
---|
238 | 237 | |
---|
239 | 238 | static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group, |
---|
240 | 239 | unsigned pin) |
---|
241 | 240 | { |
---|
242 | | - int state = __raw_readl(group->gpio_grp->inp_state); |
---|
| 241 | + int state = gpreg_read(group, group->gpio_grp->inp_state); |
---|
243 | 242 | |
---|
244 | 243 | /* |
---|
245 | 244 | * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped |
---|
.. | .. |
---|
251 | 250 | static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group, |
---|
252 | 251 | unsigned pin) |
---|
253 | 252 | { |
---|
254 | | - return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin); |
---|
| 253 | + return GPI3_PIN_IN_SEL(gpreg_read(group, group->gpio_grp->inp_state), pin); |
---|
255 | 254 | } |
---|
256 | 255 | |
---|
257 | 256 | static int __get_gpo_state_p3(struct lpc32xx_gpio_chip *group, |
---|
258 | 257 | unsigned pin) |
---|
259 | 258 | { |
---|
260 | | - return GPO3_PIN_IN_SEL(__raw_readl(group->gpio_grp->outp_state), pin); |
---|
| 259 | + return GPO3_PIN_IN_SEL(gpreg_read(group, group->gpio_grp->outp_state), pin); |
---|
261 | 260 | } |
---|
262 | 261 | |
---|
263 | 262 | /* |
---|
.. | .. |
---|
506 | 505 | static int lpc32xx_gpio_probe(struct platform_device *pdev) |
---|
507 | 506 | { |
---|
508 | 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); |
---|
509 | 513 | |
---|
510 | 514 | for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) { |
---|
511 | 515 | if (pdev->dev.of_node) { |
---|
512 | 516 | lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate; |
---|
513 | 517 | lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; |
---|
514 | 518 | lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; |
---|
| 519 | + lpc32xx_gpiochip[i].reg_base = reg_base; |
---|
515 | 520 | } |
---|
516 | 521 | devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip, |
---|
517 | 522 | &lpc32xx_gpiochip[i]); |
---|
.. | .. |
---|
536 | 541 | }; |
---|
537 | 542 | |
---|
538 | 543 | module_platform_driver(lpc32xx_gpio_driver); |
---|
| 544 | + |
---|
| 545 | +MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>"); |
---|
| 546 | +MODULE_LICENSE("GPL"); |
---|
| 547 | +MODULE_DESCRIPTION("GPIO driver for LPC32xx SoC"); |
---|