diff options
Diffstat (limited to 'drivers/gpio/gpio-lpc32xx.c')
-rw-r--r-- | drivers/gpio/gpio-lpc32xx.c | 118 |
1 files changed, 68 insertions, 50 deletions
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index 24885b3db3d5..4e626c4235c2 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c | |||
@@ -16,36 +16,33 @@ | |||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | 18 | ||
19 | #include <mach/hardware.h> | 19 | #define LPC32XX_GPIO_P3_INP_STATE (0x000) |
20 | #include <mach/platform.h> | 20 | #define LPC32XX_GPIO_P3_OUTP_SET (0x004) |
21 | 21 | #define LPC32XX_GPIO_P3_OUTP_CLR (0x008) | |
22 | #define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) | 22 | #define LPC32XX_GPIO_P3_OUTP_STATE (0x00C) |
23 | #define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) | 23 | #define LPC32XX_GPIO_P2_DIR_SET (0x010) |
24 | #define LPC32XX_GPIO_P3_OUTP_CLR _GPREG(0x008) | 24 | #define LPC32XX_GPIO_P2_DIR_CLR (0x014) |
25 | #define LPC32XX_GPIO_P3_OUTP_STATE _GPREG(0x00C) | 25 | #define LPC32XX_GPIO_P2_DIR_STATE (0x018) |
26 | #define LPC32XX_GPIO_P2_DIR_SET _GPREG(0x010) | 26 | #define LPC32XX_GPIO_P2_INP_STATE (0x01C) |
27 | #define LPC32XX_GPIO_P2_DIR_CLR _GPREG(0x014) | 27 | #define LPC32XX_GPIO_P2_OUTP_SET (0x020) |
28 | #define LPC32XX_GPIO_P2_DIR_STATE _GPREG(0x018) | 28 | #define LPC32XX_GPIO_P2_OUTP_CLR (0x024) |
29 | #define LPC32XX_GPIO_P2_INP_STATE _GPREG(0x01C) | 29 | #define LPC32XX_GPIO_P2_MUX_SET (0x028) |
30 | #define LPC32XX_GPIO_P2_OUTP_SET _GPREG(0x020) | 30 | #define LPC32XX_GPIO_P2_MUX_CLR (0x02C) |
31 | #define LPC32XX_GPIO_P2_OUTP_CLR _GPREG(0x024) | 31 | #define LPC32XX_GPIO_P2_MUX_STATE (0x030) |
32 | #define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028) | 32 | #define LPC32XX_GPIO_P0_INP_STATE (0x040) |
33 | #define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C) | 33 | #define LPC32XX_GPIO_P0_OUTP_SET (0x044) |
34 | #define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030) | 34 | #define LPC32XX_GPIO_P0_OUTP_CLR (0x048) |
35 | #define LPC32XX_GPIO_P0_INP_STATE _GPREG(0x040) | 35 | #define LPC32XX_GPIO_P0_OUTP_STATE (0x04C) |
36 | #define LPC32XX_GPIO_P0_OUTP_SET _GPREG(0x044) | 36 | #define LPC32XX_GPIO_P0_DIR_SET (0x050) |
37 | #define LPC32XX_GPIO_P0_OUTP_CLR _GPREG(0x048) | 37 | #define LPC32XX_GPIO_P0_DIR_CLR (0x054) |
38 | #define LPC32XX_GPIO_P0_OUTP_STATE _GPREG(0x04C) | 38 | #define LPC32XX_GPIO_P0_DIR_STATE (0x058) |
39 | #define LPC32XX_GPIO_P0_DIR_SET _GPREG(0x050) | 39 | #define LPC32XX_GPIO_P1_INP_STATE (0x060) |
40 | #define LPC32XX_GPIO_P0_DIR_CLR _GPREG(0x054) | 40 | #define LPC32XX_GPIO_P1_OUTP_SET (0x064) |
41 | #define LPC32XX_GPIO_P0_DIR_STATE _GPREG(0x058) | 41 | #define LPC32XX_GPIO_P1_OUTP_CLR (0x068) |
42 | #define LPC32XX_GPIO_P1_INP_STATE _GPREG(0x060) | 42 | #define LPC32XX_GPIO_P1_OUTP_STATE (0x06C) |
43 | #define LPC32XX_GPIO_P1_OUTP_SET _GPREG(0x064) | 43 | #define LPC32XX_GPIO_P1_DIR_SET (0x070) |
44 | #define LPC32XX_GPIO_P1_OUTP_CLR _GPREG(0x068) | 44 | #define LPC32XX_GPIO_P1_DIR_CLR (0x074) |
45 | #define LPC32XX_GPIO_P1_OUTP_STATE _GPREG(0x06C) | 45 | #define LPC32XX_GPIO_P1_DIR_STATE (0x078) |
46 | #define LPC32XX_GPIO_P1_DIR_SET _GPREG(0x070) | ||
47 | #define LPC32XX_GPIO_P1_DIR_CLR _GPREG(0x074) | ||
48 | #define LPC32XX_GPIO_P1_DIR_STATE _GPREG(0x078) | ||
49 | 46 | ||
50 | #define GPIO012_PIN_TO_BIT(x) (1 << (x)) | 47 | #define GPIO012_PIN_TO_BIT(x) (1 << (x)) |
51 | #define GPIO3_PIN_TO_BIT(x) (1 << ((x) + 25)) | 48 | #define GPIO3_PIN_TO_BIT(x) (1 << ((x) + 25)) |
@@ -72,12 +69,12 @@ | |||
72 | #define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX) | 69 | #define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX) |
73 | 70 | ||
74 | struct gpio_regs { | 71 | struct gpio_regs { |
75 | void __iomem *inp_state; | 72 | unsigned long inp_state; |
76 | void __iomem *outp_state; | 73 | unsigned long outp_state; |
77 | void __iomem *outp_set; | 74 | unsigned long outp_set; |
78 | void __iomem *outp_clr; | 75 | unsigned long outp_clr; |
79 | void __iomem *dir_set; | 76 | unsigned long dir_set; |
80 | void __iomem *dir_clr; | 77 | unsigned long dir_clr; |
81 | }; | 78 | }; |
82 | 79 | ||
83 | /* | 80 | /* |
@@ -165,16 +162,27 @@ static struct gpio_regs gpio_grp_regs_p3 = { | |||
165 | struct lpc32xx_gpio_chip { | 162 | struct lpc32xx_gpio_chip { |
166 | struct gpio_chip chip; | 163 | struct gpio_chip chip; |
167 | struct gpio_regs *gpio_grp; | 164 | struct gpio_regs *gpio_grp; |
165 | void __iomem *reg_base; | ||
168 | }; | 166 | }; |
169 | 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 | |||
170 | static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group, | 178 | static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group, |
171 | unsigned pin, int input) | 179 | unsigned pin, int input) |
172 | { | 180 | { |
173 | if (input) | 181 | if (input) |
174 | __raw_writel(GPIO012_PIN_TO_BIT(pin), | 182 | gpreg_write(group, GPIO012_PIN_TO_BIT(pin), |
175 | group->gpio_grp->dir_clr); | 183 | group->gpio_grp->dir_clr); |
176 | else | 184 | else |
177 | __raw_writel(GPIO012_PIN_TO_BIT(pin), | 185 | gpreg_write(group, GPIO012_PIN_TO_BIT(pin), |
178 | group->gpio_grp->dir_set); | 186 | group->gpio_grp->dir_set); |
179 | } | 187 | } |
180 | 188 | ||
@@ -184,19 +192,19 @@ static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group, | |||
184 | u32 u = GPIO3_PIN_TO_BIT(pin); | 192 | u32 u = GPIO3_PIN_TO_BIT(pin); |
185 | 193 | ||
186 | if (input) | 194 | if (input) |
187 | __raw_writel(u, group->gpio_grp->dir_clr); | 195 | gpreg_write(group, u, group->gpio_grp->dir_clr); |
188 | else | 196 | else |
189 | __raw_writel(u, group->gpio_grp->dir_set); | 197 | gpreg_write(group, u, group->gpio_grp->dir_set); |
190 | } | 198 | } |
191 | 199 | ||
192 | static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group, | 200 | static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group, |
193 | unsigned pin, int high) | 201 | unsigned pin, int high) |
194 | { | 202 | { |
195 | if (high) | 203 | if (high) |
196 | __raw_writel(GPIO012_PIN_TO_BIT(pin), | 204 | gpreg_write(group, GPIO012_PIN_TO_BIT(pin), |
197 | group->gpio_grp->outp_set); | 205 | group->gpio_grp->outp_set); |
198 | else | 206 | else |
199 | __raw_writel(GPIO012_PIN_TO_BIT(pin), | 207 | gpreg_write(group, GPIO012_PIN_TO_BIT(pin), |
200 | group->gpio_grp->outp_clr); | 208 | group->gpio_grp->outp_clr); |
201 | } | 209 | } |
202 | 210 | ||
@@ -206,31 +214,31 @@ static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group, | |||
206 | u32 u = GPIO3_PIN_TO_BIT(pin); | 214 | u32 u = GPIO3_PIN_TO_BIT(pin); |
207 | 215 | ||
208 | if (high) | 216 | if (high) |
209 | __raw_writel(u, group->gpio_grp->outp_set); | 217 | gpreg_write(group, u, group->gpio_grp->outp_set); |
210 | else | 218 | else |
211 | __raw_writel(u, group->gpio_grp->outp_clr); | 219 | gpreg_write(group, u, group->gpio_grp->outp_clr); |
212 | } | 220 | } |
213 | 221 | ||
214 | static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group, | 222 | static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group, |
215 | unsigned pin, int high) | 223 | unsigned pin, int high) |
216 | { | 224 | { |
217 | if (high) | 225 | if (high) |
218 | __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); |
219 | else | 227 | else |
220 | __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); |
221 | } | 229 | } |
222 | 230 | ||
223 | static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group, | 231 | static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group, |
224 | unsigned pin) | 232 | unsigned pin) |
225 | { | 233 | { |
226 | 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), |
227 | pin); | 235 | pin); |
228 | } | 236 | } |
229 | 237 | ||
230 | static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group, | 238 | static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group, |
231 | unsigned pin) | 239 | unsigned pin) |
232 | { | 240 | { |
233 | int state = __raw_readl(group->gpio_grp->inp_state); | 241 | int state = gpreg_read(group, group->gpio_grp->inp_state); |
234 | 242 | ||
235 | /* | 243 | /* |
236 | * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped | 244 | * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped |
@@ -242,13 +250,13 @@ static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group, | |||
242 | static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group, | 250 | static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group, |
243 | unsigned pin) | 251 | unsigned pin) |
244 | { | 252 | { |
245 | 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); |
246 | } | 254 | } |
247 | 255 | ||
248 | static int __get_gpo_state_p3(struct lpc32xx_gpio_chip *group, | 256 | static int __get_gpo_state_p3(struct lpc32xx_gpio_chip *group, |
249 | unsigned pin) | 257 | unsigned pin) |
250 | { | 258 | { |
251 | 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); |
252 | } | 260 | } |
253 | 261 | ||
254 | /* | 262 | /* |
@@ -497,12 +505,18 @@ static int lpc32xx_of_xlate(struct gpio_chip *gc, | |||
497 | static int lpc32xx_gpio_probe(struct platform_device *pdev) | 505 | static int lpc32xx_gpio_probe(struct platform_device *pdev) |
498 | { | 506 | { |
499 | int i; | 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); | ||
500 | 513 | ||
501 | for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) { | 514 | for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) { |
502 | if (pdev->dev.of_node) { | 515 | if (pdev->dev.of_node) { |
503 | lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate; | 516 | lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate; |
504 | lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; | 517 | lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; |
505 | lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; | 518 | lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; |
519 | lpc32xx_gpiochip[i].reg_base = reg_base; | ||
506 | } | 520 | } |
507 | devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip, | 521 | devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip, |
508 | &lpc32xx_gpiochip[i]); | 522 | &lpc32xx_gpiochip[i]); |
@@ -527,3 +541,7 @@ static struct platform_driver lpc32xx_gpio_driver = { | |||
527 | }; | 541 | }; |
528 | 542 | ||
529 | module_platform_driver(lpc32xx_gpio_driver); | 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"); | ||