1 /* 2 * arch/arm/mach-lpc32xx/gpiolib.c 3 * 4 * Author: Kevin Wells <kevin.wells@nxp.com> 5 * 6 * 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 */ 18 19 #include <linux/kernel.h> 20 #include <linux/init.h> 21 #include <linux/io.h> 22 #include <linux/errno.h> 23 #include <linux/gpio.h> 24 25 #include <mach/hardware.h> 26 #include <mach/platform.h> 27 28 #define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) 29 #define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) 30 #define LPC32XX_GPIO_P3_OUTP_CLR _GPREG(0x008) 31 #define LPC32XX_GPIO_P3_OUTP_STATE _GPREG(0x00C) 32 #define LPC32XX_GPIO_P2_DIR_SET _GPREG(0x010) 33 #define LPC32XX_GPIO_P2_DIR_CLR _GPREG(0x014) 34 #define LPC32XX_GPIO_P2_DIR_STATE _GPREG(0x018) 35 #define LPC32XX_GPIO_P2_INP_STATE _GPREG(0x01C) 36 #define LPC32XX_GPIO_P2_OUTP_SET _GPREG(0x020) 37 #define LPC32XX_GPIO_P2_OUTP_CLR _GPREG(0x024) 38 #define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028) 39 #define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C) 40 #define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030) 41 #define LPC32XX_GPIO_P0_INP_STATE _GPREG(0x040) 42 #define LPC32XX_GPIO_P0_OUTP_SET _GPREG(0x044) 43 #define LPC32XX_GPIO_P0_OUTP_CLR _GPREG(0x048) 44 #define LPC32XX_GPIO_P0_OUTP_STATE _GPREG(0x04C) 45 #define LPC32XX_GPIO_P0_DIR_SET _GPREG(0x050) 46 #define LPC32XX_GPIO_P0_DIR_CLR _GPREG(0x054) 47 #define LPC32XX_GPIO_P0_DIR_STATE _GPREG(0x058) 48 #define LPC32XX_GPIO_P1_INP_STATE _GPREG(0x060) 49 #define LPC32XX_GPIO_P1_OUTP_SET _GPREG(0x064) 50 #define LPC32XX_GPIO_P1_OUTP_CLR _GPREG(0x068) 51 #define LPC32XX_GPIO_P1_OUTP_STATE _GPREG(0x06C) 52 #define LPC32XX_GPIO_P1_DIR_SET _GPREG(0x070) 53 #define LPC32XX_GPIO_P1_DIR_CLR _GPREG(0x074) 54 #define LPC32XX_GPIO_P1_DIR_STATE _GPREG(0x078) 55 56 #define GPIO012_PIN_TO_BIT(x) (1 << (x)) 57 #define GPIO3_PIN_TO_BIT(x) (1 << ((x) + 25)) 58 #define GPO3_PIN_TO_BIT(x) (1 << (x)) 59 #define GPIO012_PIN_IN_SEL(x, y) (((x) >> (y)) & 1) 60 #define GPIO3_PIN_IN_SHIFT(x) ((x) == 5 ? 24 : 10 + (x)) 61 #define GPIO3_PIN_IN_SEL(x, y) ((x) >> GPIO3_PIN_IN_SHIFT(y)) 62 #define GPIO3_PIN5_IN_SEL(x) (((x) >> 24) & 1) 63 #define GPI3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1) 64 65 struct gpio_regs { 66 void __iomem *inp_state; 67 void __iomem *outp_set; 68 void __iomem *outp_clr; 69 void __iomem *dir_set; 70 void __iomem *dir_clr; 71 }; 72 73 /* 74 * GPIO names 75 */ 76 static const char *gpio_p0_names[LPC32XX_GPIO_P0_MAX] = { 77 "p0.0", "p0.1", "p0.2", "p0.3", 78 "p0.4", "p0.5", "p0.6", "p0.7" 79 }; 80 81 static const char *gpio_p1_names[LPC32XX_GPIO_P1_MAX] = { 82 "p1.0", "p1.1", "p1.2", "p1.3", 83 "p1.4", "p1.5", "p1.6", "p1.7", 84 "p1.8", "p1.9", "p1.10", "p1.11", 85 "p1.12", "p1.13", "p1.14", "p1.15", 86 "p1.16", "p1.17", "p1.18", "p1.19", 87 "p1.20", "p1.21", "p1.22", "p1.23", 88 }; 89 90 static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = { 91 "p2.0", "p2.1", "p2.2", "p2.3", 92 "p2.4", "p2.5", "p2.6", "p2.7", 93 "p2.8", "p2.9", "p2.10", "p2.11", 94 "p2.12" 95 }; 96 97 static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = { 98 "gpi000", "gpio01", "gpio02", "gpio03", 99 "gpio04", "gpio05" 100 }; 101 102 static const char *gpi_p3_names[LPC32XX_GPI_P3_MAX] = { 103 "gpi00", "gpi01", "gpi02", "gpi03", 104 "gpi04", "gpi05", "gpi06", "gpi07", 105 "gpi08", "gpi09", NULL, NULL, 106 NULL, NULL, NULL, "gpi15", 107 "gpi16", "gpi17", "gpi18", "gpi19", 108 "gpi20", "gpi21", "gpi22", "gpi23", 109 "gpi24", "gpi25", "gpi26", "gpi27" 110 }; 111 112 static const char *gpo_p3_names[LPC32XX_GPO_P3_MAX] = { 113 "gpo00", "gpo01", "gpo02", "gpo03", 114 "gpo04", "gpo05", "gpo06", "gpo07", 115 "gpo08", "gpo09", "gpo10", "gpo11", 116 "gpo12", "gpo13", "gpo14", "gpo15", 117 "gpo16", "gpo17", "gpo18", "gpo19", 118 "gpo20", "gpo21", "gpo22", "gpo23" 119 }; 120 121 static struct gpio_regs gpio_grp_regs_p0 = { 122 .inp_state = LPC32XX_GPIO_P0_INP_STATE, 123 .outp_set = LPC32XX_GPIO_P0_OUTP_SET, 124 .outp_clr = LPC32XX_GPIO_P0_OUTP_CLR, 125 .dir_set = LPC32XX_GPIO_P0_DIR_SET, 126 .dir_clr = LPC32XX_GPIO_P0_DIR_CLR, 127 }; 128 129 static struct gpio_regs gpio_grp_regs_p1 = { 130 .inp_state = LPC32XX_GPIO_P1_INP_STATE, 131 .outp_set = LPC32XX_GPIO_P1_OUTP_SET, 132 .outp_clr = LPC32XX_GPIO_P1_OUTP_CLR, 133 .dir_set = LPC32XX_GPIO_P1_DIR_SET, 134 .dir_clr = LPC32XX_GPIO_P1_DIR_CLR, 135 }; 136 137 static struct gpio_regs gpio_grp_regs_p2 = { 138 .inp_state = LPC32XX_GPIO_P2_INP_STATE, 139 .outp_set = LPC32XX_GPIO_P2_OUTP_SET, 140 .outp_clr = LPC32XX_GPIO_P2_OUTP_CLR, 141 .dir_set = LPC32XX_GPIO_P2_DIR_SET, 142 .dir_clr = LPC32XX_GPIO_P2_DIR_CLR, 143 }; 144 145 static struct gpio_regs gpio_grp_regs_p3 = { 146 .inp_state = LPC32XX_GPIO_P3_INP_STATE, 147 .outp_set = LPC32XX_GPIO_P3_OUTP_SET, 148 .outp_clr = LPC32XX_GPIO_P3_OUTP_CLR, 149 .dir_set = LPC32XX_GPIO_P2_DIR_SET, 150 .dir_clr = LPC32XX_GPIO_P2_DIR_CLR, 151 }; 152 153 struct lpc32xx_gpio_chip { 154 struct gpio_chip chip; 155 struct gpio_regs *gpio_grp; 156 }; 157 158 static inline struct lpc32xx_gpio_chip *to_lpc32xx_gpio( 159 struct gpio_chip *gpc) 160 { 161 return container_of(gpc, struct lpc32xx_gpio_chip, chip); 162 } 163 164 static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group, 165 unsigned pin, int input) 166 { 167 if (input) 168 __raw_writel(GPIO012_PIN_TO_BIT(pin), 169 group->gpio_grp->dir_clr); 170 else 171 __raw_writel(GPIO012_PIN_TO_BIT(pin), 172 group->gpio_grp->dir_set); 173 } 174 175 static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group, 176 unsigned pin, int input) 177 { 178 u32 u = GPIO3_PIN_TO_BIT(pin); 179 180 if (input) 181 __raw_writel(u, group->gpio_grp->dir_clr); 182 else 183 __raw_writel(u, group->gpio_grp->dir_set); 184 } 185 186 static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group, 187 unsigned pin, int high) 188 { 189 if (high) 190 __raw_writel(GPIO012_PIN_TO_BIT(pin), 191 group->gpio_grp->outp_set); 192 else 193 __raw_writel(GPIO012_PIN_TO_BIT(pin), 194 group->gpio_grp->outp_clr); 195 } 196 197 static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group, 198 unsigned pin, int high) 199 { 200 u32 u = GPIO3_PIN_TO_BIT(pin); 201 202 if (high) 203 __raw_writel(u, group->gpio_grp->outp_set); 204 else 205 __raw_writel(u, group->gpio_grp->outp_clr); 206 } 207 208 static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group, 209 unsigned pin, int high) 210 { 211 if (high) 212 __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set); 213 else 214 __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr); 215 } 216 217 static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group, 218 unsigned pin) 219 { 220 return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), 221 pin); 222 } 223 224 static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group, 225 unsigned pin) 226 { 227 int state = __raw_readl(group->gpio_grp->inp_state); 228 229 /* 230 * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped 231 * to bits 10..14, while GPIOP3-5 is mapped to bit 24. 232 */ 233 return GPIO3_PIN_IN_SEL(state, pin); 234 } 235 236 static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group, 237 unsigned pin) 238 { 239 return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin); 240 } 241 242 /* 243 * GENERIC_GPIO primitives. 244 */ 245 static int lpc32xx_gpio_dir_input_p012(struct gpio_chip *chip, 246 unsigned pin) 247 { 248 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 249 250 __set_gpio_dir_p012(group, pin, 1); 251 252 return 0; 253 } 254 255 static int lpc32xx_gpio_dir_input_p3(struct gpio_chip *chip, 256 unsigned pin) 257 { 258 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 259 260 __set_gpio_dir_p3(group, pin, 1); 261 262 return 0; 263 } 264 265 static int lpc32xx_gpio_dir_in_always(struct gpio_chip *chip, 266 unsigned pin) 267 { 268 return 0; 269 } 270 271 static int lpc32xx_gpio_get_value_p012(struct gpio_chip *chip, unsigned pin) 272 { 273 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 274 275 return __get_gpio_state_p012(group, pin); 276 } 277 278 static int lpc32xx_gpio_get_value_p3(struct gpio_chip *chip, unsigned pin) 279 { 280 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 281 282 return __get_gpio_state_p3(group, pin); 283 } 284 285 static int lpc32xx_gpi_get_value(struct gpio_chip *chip, unsigned pin) 286 { 287 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 288 289 return __get_gpi_state_p3(group, pin); 290 } 291 292 static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin, 293 int value) 294 { 295 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 296 297 __set_gpio_dir_p012(group, pin, 0); 298 299 return 0; 300 } 301 302 static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin, 303 int value) 304 { 305 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 306 307 __set_gpio_dir_p3(group, pin, 0); 308 309 return 0; 310 } 311 312 static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin, 313 int value) 314 { 315 return 0; 316 } 317 318 static void lpc32xx_gpio_set_value_p012(struct gpio_chip *chip, unsigned pin, 319 int value) 320 { 321 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 322 323 __set_gpio_level_p012(group, pin, value); 324 } 325 326 static void lpc32xx_gpio_set_value_p3(struct gpio_chip *chip, unsigned pin, 327 int value) 328 { 329 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 330 331 __set_gpio_level_p3(group, pin, value); 332 } 333 334 static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin, 335 int value) 336 { 337 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); 338 339 __set_gpo_level_p3(group, pin, value); 340 } 341 342 static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin) 343 { 344 if (pin < chip->ngpio) 345 return 0; 346 347 return -EINVAL; 348 } 349 350 static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { 351 { 352 .chip = { 353 .label = "gpio_p0", 354 .direction_input = lpc32xx_gpio_dir_input_p012, 355 .get = lpc32xx_gpio_get_value_p012, 356 .direction_output = lpc32xx_gpio_dir_output_p012, 357 .set = lpc32xx_gpio_set_value_p012, 358 .request = lpc32xx_gpio_request, 359 .base = LPC32XX_GPIO_P0_GRP, 360 .ngpio = LPC32XX_GPIO_P0_MAX, 361 .names = gpio_p0_names, 362 .can_sleep = 0, 363 }, 364 .gpio_grp = &gpio_grp_regs_p0, 365 }, 366 { 367 .chip = { 368 .label = "gpio_p1", 369 .direction_input = lpc32xx_gpio_dir_input_p012, 370 .get = lpc32xx_gpio_get_value_p012, 371 .direction_output = lpc32xx_gpio_dir_output_p012, 372 .set = lpc32xx_gpio_set_value_p012, 373 .request = lpc32xx_gpio_request, 374 .base = LPC32XX_GPIO_P1_GRP, 375 .ngpio = LPC32XX_GPIO_P1_MAX, 376 .names = gpio_p1_names, 377 .can_sleep = 0, 378 }, 379 .gpio_grp = &gpio_grp_regs_p1, 380 }, 381 { 382 .chip = { 383 .label = "gpio_p2", 384 .direction_input = lpc32xx_gpio_dir_input_p012, 385 .get = lpc32xx_gpio_get_value_p012, 386 .direction_output = lpc32xx_gpio_dir_output_p012, 387 .set = lpc32xx_gpio_set_value_p012, 388 .request = lpc32xx_gpio_request, 389 .base = LPC32XX_GPIO_P2_GRP, 390 .ngpio = LPC32XX_GPIO_P2_MAX, 391 .names = gpio_p2_names, 392 .can_sleep = 0, 393 }, 394 .gpio_grp = &gpio_grp_regs_p2, 395 }, 396 { 397 .chip = { 398 .label = "gpio_p3", 399 .direction_input = lpc32xx_gpio_dir_input_p3, 400 .get = lpc32xx_gpio_get_value_p3, 401 .direction_output = lpc32xx_gpio_dir_output_p3, 402 .set = lpc32xx_gpio_set_value_p3, 403 .request = lpc32xx_gpio_request, 404 .base = LPC32XX_GPIO_P3_GRP, 405 .ngpio = LPC32XX_GPIO_P3_MAX, 406 .names = gpio_p3_names, 407 .can_sleep = 0, 408 }, 409 .gpio_grp = &gpio_grp_regs_p3, 410 }, 411 { 412 .chip = { 413 .label = "gpi_p3", 414 .direction_input = lpc32xx_gpio_dir_in_always, 415 .get = lpc32xx_gpi_get_value, 416 .request = lpc32xx_gpio_request, 417 .base = LPC32XX_GPI_P3_GRP, 418 .ngpio = LPC32XX_GPI_P3_MAX, 419 .names = gpi_p3_names, 420 .can_sleep = 0, 421 }, 422 .gpio_grp = &gpio_grp_regs_p3, 423 }, 424 { 425 .chip = { 426 .label = "gpo_p3", 427 .direction_output = lpc32xx_gpio_dir_out_always, 428 .set = lpc32xx_gpo_set_value, 429 .request = lpc32xx_gpio_request, 430 .base = LPC32XX_GPO_P3_GRP, 431 .ngpio = LPC32XX_GPO_P3_MAX, 432 .names = gpo_p3_names, 433 .can_sleep = 0, 434 }, 435 .gpio_grp = &gpio_grp_regs_p3, 436 }, 437 }; 438 439 void __init lpc32xx_gpio_init(void) 440 { 441 int i; 442 443 for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) 444 gpiochip_add(&lpc32xx_gpiochip[i].chip); 445 } 446