Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.2-rc7 2712 lines 59 kB view raw
1/* 2 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. 3 * http://www.samsung.com/ 4 * 5 * Copyright 2008 Openmoko, Inc. 6 * Copyright 2008 Simtec Electronics 7 * Ben Dooks <ben@simtec.co.uk> 8 * http://armlinux.simtec.co.uk/ 9 * 10 * SAMSUNG - GPIOlib support 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License version 2 as 14 * published by the Free Software Foundation. 15 */ 16 17#include <linux/kernel.h> 18#include <linux/irq.h> 19#include <linux/io.h> 20#include <linux/gpio.h> 21#include <linux/init.h> 22#include <linux/spinlock.h> 23#include <linux/module.h> 24#include <linux/interrupt.h> 25#include <linux/sysdev.h> 26#include <linux/ioport.h> 27 28#include <asm/irq.h> 29 30#include <mach/hardware.h> 31#include <mach/map.h> 32#include <mach/regs-clock.h> 33#include <mach/regs-gpio.h> 34 35#include <plat/cpu.h> 36#include <plat/gpio-core.h> 37#include <plat/gpio-cfg.h> 38#include <plat/gpio-cfg-helpers.h> 39#include <plat/gpio-fns.h> 40#include <plat/pm.h> 41 42#ifndef DEBUG_GPIO 43#define gpio_dbg(x...) do { } while (0) 44#else 45#define gpio_dbg(x...) printk(KERN_DEBUG x) 46#endif 47 48int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, 49 unsigned int off, samsung_gpio_pull_t pull) 50{ 51 void __iomem *reg = chip->base + 0x08; 52 int shift = off * 2; 53 u32 pup; 54 55 pup = __raw_readl(reg); 56 pup &= ~(3 << shift); 57 pup |= pull << shift; 58 __raw_writel(pup, reg); 59 60 return 0; 61} 62 63samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip, 64 unsigned int off) 65{ 66 void __iomem *reg = chip->base + 0x08; 67 int shift = off * 2; 68 u32 pup = __raw_readl(reg); 69 70 pup >>= shift; 71 pup &= 0x3; 72 73 return (__force samsung_gpio_pull_t)pup; 74} 75 76int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip, 77 unsigned int off, samsung_gpio_pull_t pull) 78{ 79 switch (pull) { 80 case S3C_GPIO_PULL_NONE: 81 pull = 0x01; 82 break; 83 case S3C_GPIO_PULL_UP: 84 pull = 0x00; 85 break; 86 case S3C_GPIO_PULL_DOWN: 87 pull = 0x02; 88 break; 89 } 90 return samsung_gpio_setpull_updown(chip, off, pull); 91} 92 93samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip, 94 unsigned int off) 95{ 96 samsung_gpio_pull_t pull; 97 98 pull = samsung_gpio_getpull_updown(chip, off); 99 100 switch (pull) { 101 case 0x00: 102 pull = S3C_GPIO_PULL_UP; 103 break; 104 case 0x01: 105 case 0x03: 106 pull = S3C_GPIO_PULL_NONE; 107 break; 108 case 0x02: 109 pull = S3C_GPIO_PULL_DOWN; 110 break; 111 } 112 113 return pull; 114} 115 116static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip, 117 unsigned int off, samsung_gpio_pull_t pull, 118 samsung_gpio_pull_t updown) 119{ 120 void __iomem *reg = chip->base + 0x08; 121 u32 pup = __raw_readl(reg); 122 123 if (pull == updown) 124 pup &= ~(1 << off); 125 else if (pull == S3C_GPIO_PULL_NONE) 126 pup |= (1 << off); 127 else 128 return -EINVAL; 129 130 __raw_writel(pup, reg); 131 return 0; 132} 133 134static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip, 135 unsigned int off, 136 samsung_gpio_pull_t updown) 137{ 138 void __iomem *reg = chip->base + 0x08; 139 u32 pup = __raw_readl(reg); 140 141 pup &= (1 << off); 142 return pup ? S3C_GPIO_PULL_NONE : updown; 143} 144 145samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip, 146 unsigned int off) 147{ 148 return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP); 149} 150 151int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip, 152 unsigned int off, samsung_gpio_pull_t pull) 153{ 154 return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP); 155} 156 157samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip, 158 unsigned int off) 159{ 160 return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN); 161} 162 163int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip, 164 unsigned int off, samsung_gpio_pull_t pull) 165{ 166 return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); 167} 168 169static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip, 170 unsigned int off, samsung_gpio_pull_t pull) 171{ 172 if (pull == S3C_GPIO_PULL_UP) 173 pull = 3; 174 175 return samsung_gpio_setpull_updown(chip, off, pull); 176} 177 178static samsung_gpio_pull_t exynos4_gpio_getpull(struct samsung_gpio_chip *chip, 179 unsigned int off) 180{ 181 samsung_gpio_pull_t pull; 182 183 pull = samsung_gpio_getpull_updown(chip, off); 184 185 if (pull == 3) 186 pull = S3C_GPIO_PULL_UP; 187 188 return pull; 189} 190 191/* 192 * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration. 193 * @chip: The gpio chip that is being configured. 194 * @off: The offset for the GPIO being configured. 195 * @cfg: The configuration value to set. 196 * 197 * This helper deal with the GPIO cases where the control register 198 * has two bits of configuration per gpio, which have the following 199 * functions: 200 * 00 = input 201 * 01 = output 202 * 1x = special function 203 */ 204 205static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip, 206 unsigned int off, unsigned int cfg) 207{ 208 void __iomem *reg = chip->base; 209 unsigned int shift = off * 2; 210 u32 con; 211 212 if (samsung_gpio_is_cfg_special(cfg)) { 213 cfg &= 0xf; 214 if (cfg > 3) 215 return -EINVAL; 216 217 cfg <<= shift; 218 } 219 220 con = __raw_readl(reg); 221 con &= ~(0x3 << shift); 222 con |= cfg; 223 __raw_writel(con, reg); 224 225 return 0; 226} 227 228/* 229 * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read. 230 * @chip: The gpio chip that is being configured. 231 * @off: The offset for the GPIO being configured. 232 * 233 * The reverse of samsung_gpio_setcfg_2bit(). Will return a value whicg 234 * could be directly passed back to samsung_gpio_setcfg_2bit(), from the 235 * S3C_GPIO_SPECIAL() macro. 236 */ 237 238static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip, 239 unsigned int off) 240{ 241 u32 con; 242 243 con = __raw_readl(chip->base); 244 con >>= off * 2; 245 con &= 3; 246 247 /* this conversion works for IN and OUT as well as special mode */ 248 return S3C_GPIO_SPECIAL(con); 249} 250 251/* 252 * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config. 253 * @chip: The gpio chip that is being configured. 254 * @off: The offset for the GPIO being configured. 255 * @cfg: The configuration value to set. 256 * 257 * This helper deal with the GPIO cases where the control register has 4 bits 258 * of control per GPIO, generally in the form of: 259 * 0000 = Input 260 * 0001 = Output 261 * others = Special functions (dependent on bank) 262 * 263 * Note, since the code to deal with the case where there are two control 264 * registers instead of one, we do not have a separate set of functions for 265 * each case. 266 */ 267 268static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip, 269 unsigned int off, unsigned int cfg) 270{ 271 void __iomem *reg = chip->base; 272 unsigned int shift = (off & 7) * 4; 273 u32 con; 274 275 if (off < 8 && chip->chip.ngpio > 8) 276 reg -= 4; 277 278 if (samsung_gpio_is_cfg_special(cfg)) { 279 cfg &= 0xf; 280 cfg <<= shift; 281 } 282 283 con = __raw_readl(reg); 284 con &= ~(0xf << shift); 285 con |= cfg; 286 __raw_writel(con, reg); 287 288 return 0; 289} 290 291/* 292 * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read. 293 * @chip: The gpio chip that is being configured. 294 * @off: The offset for the GPIO being configured. 295 * 296 * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration 297 * register setting into a value the software can use, such as could be passed 298 * to samsung_gpio_setcfg_4bit(). 299 * 300 * @sa samsung_gpio_getcfg_2bit 301 */ 302 303static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip, 304 unsigned int off) 305{ 306 void __iomem *reg = chip->base; 307 unsigned int shift = (off & 7) * 4; 308 u32 con; 309 310 if (off < 8 && chip->chip.ngpio > 8) 311 reg -= 4; 312 313 con = __raw_readl(reg); 314 con >>= shift; 315 con &= 0xf; 316 317 /* this conversion works for IN and OUT as well as special mode */ 318 return S3C_GPIO_SPECIAL(con); 319} 320 321#ifdef CONFIG_PLAT_S3C24XX 322/* 323 * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A) 324 * @chip: The gpio chip that is being configured. 325 * @off: The offset for the GPIO being configured. 326 * @cfg: The configuration value to set. 327 * 328 * This helper deal with the GPIO cases where the control register 329 * has one bit of configuration for the gpio, where setting the bit 330 * means the pin is in special function mode and unset means output. 331 */ 332 333static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip, 334 unsigned int off, unsigned int cfg) 335{ 336 void __iomem *reg = chip->base; 337 unsigned int shift = off; 338 u32 con; 339 340 if (samsung_gpio_is_cfg_special(cfg)) { 341 cfg &= 0xf; 342 343 /* Map output to 0, and SFN2 to 1 */ 344 cfg -= 1; 345 if (cfg > 1) 346 return -EINVAL; 347 348 cfg <<= shift; 349 } 350 351 con = __raw_readl(reg); 352 con &= ~(0x1 << shift); 353 con |= cfg; 354 __raw_writel(con, reg); 355 356 return 0; 357} 358 359/* 360 * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A) 361 * @chip: The gpio chip that is being configured. 362 * @off: The offset for the GPIO being configured. 363 * 364 * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable 365 * GPIO configuration value. 366 * 367 * @sa samsung_gpio_getcfg_2bit 368 * @sa samsung_gpio_getcfg_4bit 369 */ 370 371static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip, 372 unsigned int off) 373{ 374 u32 con; 375 376 con = __raw_readl(chip->base); 377 con >>= off; 378 con &= 1; 379 con++; 380 381 return S3C_GPIO_SFN(con); 382} 383#endif 384 385#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) 386static int s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip *chip, 387 unsigned int off, unsigned int cfg) 388{ 389 void __iomem *reg = chip->base; 390 unsigned int shift; 391 u32 con; 392 393 switch (off) { 394 case 0: 395 case 1: 396 case 2: 397 case 3: 398 case 4: 399 case 5: 400 shift = (off & 7) * 4; 401 reg -= 4; 402 break; 403 case 6: 404 shift = ((off + 1) & 7) * 4; 405 reg -= 4; 406 default: 407 shift = ((off + 1) & 7) * 4; 408 break; 409 } 410 411 if (samsung_gpio_is_cfg_special(cfg)) { 412 cfg &= 0xf; 413 cfg <<= shift; 414 } 415 416 con = __raw_readl(reg); 417 con &= ~(0xf << shift); 418 con |= cfg; 419 __raw_writel(con, reg); 420 421 return 0; 422} 423#endif 424 425static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg, 426 int nr_chips) 427{ 428 for (; nr_chips > 0; nr_chips--, chipcfg++) { 429 if (!chipcfg->set_config) 430 chipcfg->set_config = samsung_gpio_setcfg_4bit; 431 if (!chipcfg->get_config) 432 chipcfg->get_config = samsung_gpio_getcfg_4bit; 433 if (!chipcfg->set_pull) 434 chipcfg->set_pull = samsung_gpio_setpull_updown; 435 if (!chipcfg->get_pull) 436 chipcfg->get_pull = samsung_gpio_getpull_updown; 437 } 438} 439 440struct samsung_gpio_cfg s3c24xx_gpiocfg_default = { 441 .set_config = samsung_gpio_setcfg_2bit, 442 .get_config = samsung_gpio_getcfg_2bit, 443}; 444 445#ifdef CONFIG_PLAT_S3C24XX 446static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = { 447 .set_config = s3c24xx_gpio_setcfg_abank, 448 .get_config = s3c24xx_gpio_getcfg_abank, 449}; 450#endif 451 452static struct samsung_gpio_cfg exynos4_gpio_cfg = { 453 .set_pull = exynos4_gpio_setpull, 454 .get_pull = exynos4_gpio_getpull, 455 .set_config = samsung_gpio_setcfg_4bit, 456 .get_config = samsung_gpio_getcfg_4bit, 457}; 458 459#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) 460static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = { 461 .cfg_eint = 0x3, 462 .set_config = s5p64x0_gpio_setcfg_rbank, 463 .get_config = samsung_gpio_getcfg_4bit, 464 .set_pull = samsung_gpio_setpull_updown, 465 .get_pull = samsung_gpio_getpull_updown, 466}; 467#endif 468 469static struct samsung_gpio_cfg samsung_gpio_cfgs[] = { 470 { 471 .cfg_eint = 0x0, 472 }, { 473 .cfg_eint = 0x3, 474 }, { 475 .cfg_eint = 0x7, 476 }, { 477 .cfg_eint = 0xF, 478 }, { 479 .cfg_eint = 0x0, 480 .set_config = samsung_gpio_setcfg_2bit, 481 .get_config = samsung_gpio_getcfg_2bit, 482 }, { 483 .cfg_eint = 0x2, 484 .set_config = samsung_gpio_setcfg_2bit, 485 .get_config = samsung_gpio_getcfg_2bit, 486 }, { 487 .cfg_eint = 0x3, 488 .set_config = samsung_gpio_setcfg_2bit, 489 .get_config = samsung_gpio_getcfg_2bit, 490 }, { 491 .set_config = samsung_gpio_setcfg_2bit, 492 .get_config = samsung_gpio_getcfg_2bit, 493 }, { 494 .set_pull = exynos4_gpio_setpull, 495 .get_pull = exynos4_gpio_getpull, 496 }, { 497 .cfg_eint = 0x3, 498 .set_pull = exynos4_gpio_setpull, 499 .get_pull = exynos4_gpio_getpull, 500 } 501}; 502 503/* 504 * Default routines for controlling GPIO, based on the original S3C24XX 505 * GPIO functions which deal with the case where each gpio bank of the 506 * chip is as following: 507 * 508 * base + 0x00: Control register, 2 bits per gpio 509 * gpio n: 2 bits starting at (2*n) 510 * 00 = input, 01 = output, others mean special-function 511 * base + 0x04: Data register, 1 bit per gpio 512 * bit n: data bit n 513*/ 514 515static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset) 516{ 517 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 518 void __iomem *base = ourchip->base; 519 unsigned long flags; 520 unsigned long con; 521 522 samsung_gpio_lock(ourchip, flags); 523 524 con = __raw_readl(base + 0x00); 525 con &= ~(3 << (offset * 2)); 526 527 __raw_writel(con, base + 0x00); 528 529 samsung_gpio_unlock(ourchip, flags); 530 return 0; 531} 532 533static int samsung_gpiolib_2bit_output(struct gpio_chip *chip, 534 unsigned offset, int value) 535{ 536 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 537 void __iomem *base = ourchip->base; 538 unsigned long flags; 539 unsigned long dat; 540 unsigned long con; 541 542 samsung_gpio_lock(ourchip, flags); 543 544 dat = __raw_readl(base + 0x04); 545 dat &= ~(1 << offset); 546 if (value) 547 dat |= 1 << offset; 548 __raw_writel(dat, base + 0x04); 549 550 con = __raw_readl(base + 0x00); 551 con &= ~(3 << (offset * 2)); 552 con |= 1 << (offset * 2); 553 554 __raw_writel(con, base + 0x00); 555 __raw_writel(dat, base + 0x04); 556 557 samsung_gpio_unlock(ourchip, flags); 558 return 0; 559} 560 561/* 562 * The samsung_gpiolib_4bit routines are to control the gpio banks where 563 * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the 564 * following example: 565 * 566 * base + 0x00: Control register, 4 bits per gpio 567 * gpio n: 4 bits starting at (4*n) 568 * 0000 = input, 0001 = output, others mean special-function 569 * base + 0x04: Data register, 1 bit per gpio 570 * bit n: data bit n 571 * 572 * Note, since the data register is one bit per gpio and is at base + 0x4 573 * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the 574 * state of the output. 575 */ 576 577static int samsung_gpiolib_4bit_input(struct gpio_chip *chip, 578 unsigned int offset) 579{ 580 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 581 void __iomem *base = ourchip->base; 582 unsigned long con; 583 584 con = __raw_readl(base + GPIOCON_OFF); 585 con &= ~(0xf << con_4bit_shift(offset)); 586 __raw_writel(con, base + GPIOCON_OFF); 587 588 gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); 589 590 return 0; 591} 592 593static int samsung_gpiolib_4bit_output(struct gpio_chip *chip, 594 unsigned int offset, int value) 595{ 596 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 597 void __iomem *base = ourchip->base; 598 unsigned long con; 599 unsigned long dat; 600 601 con = __raw_readl(base + GPIOCON_OFF); 602 con &= ~(0xf << con_4bit_shift(offset)); 603 con |= 0x1 << con_4bit_shift(offset); 604 605 dat = __raw_readl(base + GPIODAT_OFF); 606 607 if (value) 608 dat |= 1 << offset; 609 else 610 dat &= ~(1 << offset); 611 612 __raw_writel(dat, base + GPIODAT_OFF); 613 __raw_writel(con, base + GPIOCON_OFF); 614 __raw_writel(dat, base + GPIODAT_OFF); 615 616 gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); 617 618 return 0; 619} 620 621/* 622 * The next set of routines are for the case where the GPIO configuration 623 * registers are 4 bits per GPIO but there is more than one register (the 624 * bank has more than 8 GPIOs. 625 * 626 * This case is the similar to the 4 bit case, but the registers are as 627 * follows: 628 * 629 * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs) 630 * gpio n: 4 bits starting at (4*n) 631 * 0000 = input, 0001 = output, others mean special-function 632 * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs) 633 * gpio n: 4 bits starting at (4*n) 634 * 0000 = input, 0001 = output, others mean special-function 635 * base + 0x08: Data register, 1 bit per gpio 636 * bit n: data bit n 637 * 638 * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set 639 * routines we store the 'base + 0x4' address so that these routines see 640 * the data register at ourchip->base + 0x04. 641 */ 642 643static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip, 644 unsigned int offset) 645{ 646 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 647 void __iomem *base = ourchip->base; 648 void __iomem *regcon = base; 649 unsigned long con; 650 651 if (offset > 7) 652 offset -= 8; 653 else 654 regcon -= 4; 655 656 con = __raw_readl(regcon); 657 con &= ~(0xf << con_4bit_shift(offset)); 658 __raw_writel(con, regcon); 659 660 gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con); 661 662 return 0; 663} 664 665static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip, 666 unsigned int offset, int value) 667{ 668 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 669 void __iomem *base = ourchip->base; 670 void __iomem *regcon = base; 671 unsigned long con; 672 unsigned long dat; 673 unsigned con_offset = offset; 674 675 if (con_offset > 7) 676 con_offset -= 8; 677 else 678 regcon -= 4; 679 680 con = __raw_readl(regcon); 681 con &= ~(0xf << con_4bit_shift(con_offset)); 682 con |= 0x1 << con_4bit_shift(con_offset); 683 684 dat = __raw_readl(base + GPIODAT_OFF); 685 686 if (value) 687 dat |= 1 << offset; 688 else 689 dat &= ~(1 << offset); 690 691 __raw_writel(dat, base + GPIODAT_OFF); 692 __raw_writel(con, regcon); 693 __raw_writel(dat, base + GPIODAT_OFF); 694 695 gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); 696 697 return 0; 698} 699 700#ifdef CONFIG_PLAT_S3C24XX 701/* The next set of routines are for the case of s3c24xx bank a */ 702 703static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset) 704{ 705 return -EINVAL; 706} 707 708static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, 709 unsigned offset, int value) 710{ 711 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 712 void __iomem *base = ourchip->base; 713 unsigned long flags; 714 unsigned long dat; 715 unsigned long con; 716 717 local_irq_save(flags); 718 719 con = __raw_readl(base + 0x00); 720 dat = __raw_readl(base + 0x04); 721 722 dat &= ~(1 << offset); 723 if (value) 724 dat |= 1 << offset; 725 726 __raw_writel(dat, base + 0x04); 727 728 con &= ~(1 << offset); 729 730 __raw_writel(con, base + 0x00); 731 __raw_writel(dat, base + 0x04); 732 733 local_irq_restore(flags); 734 return 0; 735} 736#endif 737 738/* The next set of routines are for the case of s5p64x0 bank r */ 739 740static int s5p64x0_gpiolib_rbank_input(struct gpio_chip *chip, 741 unsigned int offset) 742{ 743 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 744 void __iomem *base = ourchip->base; 745 void __iomem *regcon = base; 746 unsigned long con; 747 unsigned long flags; 748 749 switch (offset) { 750 case 6: 751 offset += 1; 752 case 0: 753 case 1: 754 case 2: 755 case 3: 756 case 4: 757 case 5: 758 regcon -= 4; 759 break; 760 default: 761 offset -= 7; 762 break; 763 } 764 765 samsung_gpio_lock(ourchip, flags); 766 767 con = __raw_readl(regcon); 768 con &= ~(0xf << con_4bit_shift(offset)); 769 __raw_writel(con, regcon); 770 771 samsung_gpio_unlock(ourchip, flags); 772 773 return 0; 774} 775 776static int s5p64x0_gpiolib_rbank_output(struct gpio_chip *chip, 777 unsigned int offset, int value) 778{ 779 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 780 void __iomem *base = ourchip->base; 781 void __iomem *regcon = base; 782 unsigned long con; 783 unsigned long dat; 784 unsigned long flags; 785 unsigned con_offset = offset; 786 787 switch (con_offset) { 788 case 6: 789 con_offset += 1; 790 case 0: 791 case 1: 792 case 2: 793 case 3: 794 case 4: 795 case 5: 796 regcon -= 4; 797 break; 798 default: 799 con_offset -= 7; 800 break; 801 } 802 803 samsung_gpio_lock(ourchip, flags); 804 805 con = __raw_readl(regcon); 806 con &= ~(0xf << con_4bit_shift(con_offset)); 807 con |= 0x1 << con_4bit_shift(con_offset); 808 809 dat = __raw_readl(base + GPIODAT_OFF); 810 if (value) 811 dat |= 1 << offset; 812 else 813 dat &= ~(1 << offset); 814 815 __raw_writel(con, regcon); 816 __raw_writel(dat, base + GPIODAT_OFF); 817 818 samsung_gpio_unlock(ourchip, flags); 819 820 return 0; 821} 822 823static void samsung_gpiolib_set(struct gpio_chip *chip, 824 unsigned offset, int value) 825{ 826 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 827 void __iomem *base = ourchip->base; 828 unsigned long flags; 829 unsigned long dat; 830 831 samsung_gpio_lock(ourchip, flags); 832 833 dat = __raw_readl(base + 0x04); 834 dat &= ~(1 << offset); 835 if (value) 836 dat |= 1 << offset; 837 __raw_writel(dat, base + 0x04); 838 839 samsung_gpio_unlock(ourchip, flags); 840} 841 842static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset) 843{ 844 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 845 unsigned long val; 846 847 val = __raw_readl(ourchip->base + 0x04); 848 val >>= offset; 849 val &= 1; 850 851 return val; 852} 853 854/* 855 * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios 856 * for use with the configuration calls, and other parts of the s3c gpiolib 857 * support code. 858 * 859 * Not all s3c support code will need this, as some configurations of cpu 860 * may only support one or two different configuration options and have an 861 * easy gpio to samsung_gpio_chip mapping function. If this is the case, then 862 * the machine support file should provide its own samsung_gpiolib_getchip() 863 * and any other necessary functions. 864 */ 865 866#ifdef CONFIG_S3C_GPIO_TRACK 867struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END]; 868 869static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip) 870{ 871 unsigned int gpn; 872 int i; 873 874 gpn = chip->chip.base; 875 for (i = 0; i < chip->chip.ngpio; i++, gpn++) { 876 BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios)); 877 s3c_gpios[gpn] = chip; 878 } 879} 880#endif /* CONFIG_S3C_GPIO_TRACK */ 881 882/* 883 * samsung_gpiolib_add() - add the Samsung gpio_chip. 884 * @chip: The chip to register 885 * 886 * This is a wrapper to gpiochip_add() that takes our specific gpio chip 887 * information and makes the necessary alterations for the platform and 888 * notes the information for use with the configuration systems and any 889 * other parts of the system. 890 */ 891 892static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) 893{ 894 struct gpio_chip *gc = &chip->chip; 895 int ret; 896 897 BUG_ON(!chip->base); 898 BUG_ON(!gc->label); 899 BUG_ON(!gc->ngpio); 900 901 spin_lock_init(&chip->lock); 902 903 if (!gc->direction_input) 904 gc->direction_input = samsung_gpiolib_2bit_input; 905 if (!gc->direction_output) 906 gc->direction_output = samsung_gpiolib_2bit_output; 907 if (!gc->set) 908 gc->set = samsung_gpiolib_set; 909 if (!gc->get) 910 gc->get = samsung_gpiolib_get; 911 912#ifdef CONFIG_PM 913 if (chip->pm != NULL) { 914 if (!chip->pm->save || !chip->pm->resume) 915 printk(KERN_ERR "gpio: %s has missing PM functions\n", 916 gc->label); 917 } else 918 printk(KERN_ERR "gpio: %s has no PM function\n", gc->label); 919#endif 920 921 /* gpiochip_add() prints own failure message on error. */ 922 ret = gpiochip_add(gc); 923 if (ret >= 0) 924 s3c_gpiolib_track(chip); 925} 926 927static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, 928 int nr_chips, void __iomem *base) 929{ 930 int i; 931 struct gpio_chip *gc = &chip->chip; 932 933 for (i = 0 ; i < nr_chips; i++, chip++) { 934 /* skip banks not present on SoC */ 935 if (chip->chip.base >= S3C_GPIO_END) 936 continue; 937 938 if (!chip->config) 939 chip->config = &s3c24xx_gpiocfg_default; 940 if (!chip->pm) 941 chip->pm = __gpio_pm(&samsung_gpio_pm_2bit); 942 if ((base != NULL) && (chip->base == NULL)) 943 chip->base = base + ((i) * 0x10); 944 945 if (!gc->direction_input) 946 gc->direction_input = samsung_gpiolib_2bit_input; 947 if (!gc->direction_output) 948 gc->direction_output = samsung_gpiolib_2bit_output; 949 950 samsung_gpiolib_add(chip); 951 } 952} 953 954static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip, 955 int nr_chips, void __iomem *base, 956 unsigned int offset) 957{ 958 int i; 959 960 for (i = 0 ; i < nr_chips; i++, chip++) { 961 chip->chip.direction_input = samsung_gpiolib_2bit_input; 962 chip->chip.direction_output = samsung_gpiolib_2bit_output; 963 964 if (!chip->config) 965 chip->config = &samsung_gpio_cfgs[7]; 966 if (!chip->pm) 967 chip->pm = __gpio_pm(&samsung_gpio_pm_2bit); 968 if ((base != NULL) && (chip->base == NULL)) 969 chip->base = base + ((i) * offset); 970 971 samsung_gpiolib_add(chip); 972 } 973} 974 975/* 976 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config. 977 * @chip: The gpio chip that is being configured. 978 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured. 979 * 980 * This helper deal with the GPIO cases where the control register has 4 bits 981 * of control per GPIO, generally in the form of: 982 * 0000 = Input 983 * 0001 = Output 984 * others = Special functions (dependent on bank) 985 * 986 * Note, since the code to deal with the case where there are two control 987 * registers instead of one, we do not have a separate set of function 988 * (samsung_gpiolib_add_4bit2_chips)for each case. 989 */ 990 991static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip, 992 int nr_chips, void __iomem *base) 993{ 994 int i; 995 996 for (i = 0 ; i < nr_chips; i++, chip++) { 997 chip->chip.direction_input = samsung_gpiolib_4bit_input; 998 chip->chip.direction_output = samsung_gpiolib_4bit_output; 999 1000 if (!chip->config) 1001 chip->config = &samsung_gpio_cfgs[2]; 1002 if (!chip->pm) 1003 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); 1004 if ((base != NULL) && (chip->base == NULL)) 1005 chip->base = base + ((i) * 0x20); 1006 1007 samsung_gpiolib_add(chip); 1008 } 1009} 1010 1011static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip, 1012 int nr_chips) 1013{ 1014 for (; nr_chips > 0; nr_chips--, chip++) { 1015 chip->chip.direction_input = samsung_gpiolib_4bit2_input; 1016 chip->chip.direction_output = samsung_gpiolib_4bit2_output; 1017 1018 if (!chip->config) 1019 chip->config = &samsung_gpio_cfgs[2]; 1020 if (!chip->pm) 1021 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); 1022 1023 samsung_gpiolib_add(chip); 1024 } 1025} 1026 1027static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip, 1028 int nr_chips) 1029{ 1030 for (; nr_chips > 0; nr_chips--, chip++) { 1031 chip->chip.direction_input = s5p64x0_gpiolib_rbank_input; 1032 chip->chip.direction_output = s5p64x0_gpiolib_rbank_output; 1033 1034 if (!chip->pm) 1035 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); 1036 1037 samsung_gpiolib_add(chip); 1038 } 1039} 1040 1041int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) 1042{ 1043 struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip); 1044 1045 return samsung_chip->irq_base + offset; 1046} 1047 1048#ifdef CONFIG_PLAT_S3C24XX 1049static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) 1050{ 1051 if (offset < 4) 1052 return IRQ_EINT0 + offset; 1053 1054 if (offset < 8) 1055 return IRQ_EINT4 + offset - 4; 1056 1057 return -EINVAL; 1058} 1059#endif 1060 1061#ifdef CONFIG_PLAT_S3C64XX 1062static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin) 1063{ 1064 return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO; 1065} 1066 1067static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin) 1068{ 1069 return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO; 1070} 1071#endif 1072 1073struct samsung_gpio_chip s3c24xx_gpios[] = { 1074#ifdef CONFIG_PLAT_S3C24XX 1075 { 1076 .config = &s3c24xx_gpiocfg_banka, 1077 .chip = { 1078 .base = S3C2410_GPA(0), 1079 .owner = THIS_MODULE, 1080 .label = "GPIOA", 1081 .ngpio = 24, 1082 .direction_input = s3c24xx_gpiolib_banka_input, 1083 .direction_output = s3c24xx_gpiolib_banka_output, 1084 }, 1085 }, { 1086 .chip = { 1087 .base = S3C2410_GPB(0), 1088 .owner = THIS_MODULE, 1089 .label = "GPIOB", 1090 .ngpio = 16, 1091 }, 1092 }, { 1093 .chip = { 1094 .base = S3C2410_GPC(0), 1095 .owner = THIS_MODULE, 1096 .label = "GPIOC", 1097 .ngpio = 16, 1098 }, 1099 }, { 1100 .chip = { 1101 .base = S3C2410_GPD(0), 1102 .owner = THIS_MODULE, 1103 .label = "GPIOD", 1104 .ngpio = 16, 1105 }, 1106 }, { 1107 .chip = { 1108 .base = S3C2410_GPE(0), 1109 .label = "GPIOE", 1110 .owner = THIS_MODULE, 1111 .ngpio = 16, 1112 }, 1113 }, { 1114 .chip = { 1115 .base = S3C2410_GPF(0), 1116 .owner = THIS_MODULE, 1117 .label = "GPIOF", 1118 .ngpio = 8, 1119 .to_irq = s3c24xx_gpiolib_fbank_to_irq, 1120 }, 1121 }, { 1122 .irq_base = IRQ_EINT8, 1123 .chip = { 1124 .base = S3C2410_GPG(0), 1125 .owner = THIS_MODULE, 1126 .label = "GPIOG", 1127 .ngpio = 16, 1128 .to_irq = samsung_gpiolib_to_irq, 1129 }, 1130 }, { 1131 .chip = { 1132 .base = S3C2410_GPH(0), 1133 .owner = THIS_MODULE, 1134 .label = "GPIOH", 1135 .ngpio = 11, 1136 }, 1137 }, 1138 /* GPIOS for the S3C2443 and later devices. */ 1139 { 1140 .base = S3C2440_GPJCON, 1141 .chip = { 1142 .base = S3C2410_GPJ(0), 1143 .owner = THIS_MODULE, 1144 .label = "GPIOJ", 1145 .ngpio = 16, 1146 }, 1147 }, { 1148 .base = S3C2443_GPKCON, 1149 .chip = { 1150 .base = S3C2410_GPK(0), 1151 .owner = THIS_MODULE, 1152 .label = "GPIOK", 1153 .ngpio = 16, 1154 }, 1155 }, { 1156 .base = S3C2443_GPLCON, 1157 .chip = { 1158 .base = S3C2410_GPL(0), 1159 .owner = THIS_MODULE, 1160 .label = "GPIOL", 1161 .ngpio = 15, 1162 }, 1163 }, { 1164 .base = S3C2443_GPMCON, 1165 .chip = { 1166 .base = S3C2410_GPM(0), 1167 .owner = THIS_MODULE, 1168 .label = "GPIOM", 1169 .ngpio = 2, 1170 }, 1171 }, 1172#endif 1173}; 1174 1175/* 1176 * GPIO bank summary: 1177 * 1178 * Bank GPIOs Style SlpCon ExtInt Group 1179 * A 8 4Bit Yes 1 1180 * B 7 4Bit Yes 1 1181 * C 8 4Bit Yes 2 1182 * D 5 4Bit Yes 3 1183 * E 5 4Bit Yes None 1184 * F 16 2Bit Yes 4 [1] 1185 * G 7 4Bit Yes 5 1186 * H 10 4Bit[2] Yes 6 1187 * I 16 2Bit Yes None 1188 * J 12 2Bit Yes None 1189 * K 16 4Bit[2] No None 1190 * L 15 4Bit[2] No None 1191 * M 6 4Bit No IRQ_EINT 1192 * N 16 2Bit No IRQ_EINT 1193 * O 16 2Bit Yes 7 1194 * P 15 2Bit Yes 8 1195 * Q 9 2Bit Yes 9 1196 * 1197 * [1] BANKF pins 14,15 do not form part of the external interrupt sources 1198 * [2] BANK has two control registers, GPxCON0 and GPxCON1 1199 */ 1200 1201static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = { 1202#ifdef CONFIG_PLAT_S3C64XX 1203 { 1204 .chip = { 1205 .base = S3C64XX_GPA(0), 1206 .ngpio = S3C64XX_GPIO_A_NR, 1207 .label = "GPA", 1208 }, 1209 }, { 1210 .chip = { 1211 .base = S3C64XX_GPB(0), 1212 .ngpio = S3C64XX_GPIO_B_NR, 1213 .label = "GPB", 1214 }, 1215 }, { 1216 .chip = { 1217 .base = S3C64XX_GPC(0), 1218 .ngpio = S3C64XX_GPIO_C_NR, 1219 .label = "GPC", 1220 }, 1221 }, { 1222 .chip = { 1223 .base = S3C64XX_GPD(0), 1224 .ngpio = S3C64XX_GPIO_D_NR, 1225 .label = "GPD", 1226 }, 1227 }, { 1228 .config = &samsung_gpio_cfgs[0], 1229 .chip = { 1230 .base = S3C64XX_GPE(0), 1231 .ngpio = S3C64XX_GPIO_E_NR, 1232 .label = "GPE", 1233 }, 1234 }, { 1235 .base = S3C64XX_GPG_BASE, 1236 .chip = { 1237 .base = S3C64XX_GPG(0), 1238 .ngpio = S3C64XX_GPIO_G_NR, 1239 .label = "GPG", 1240 }, 1241 }, { 1242 .base = S3C64XX_GPM_BASE, 1243 .config = &samsung_gpio_cfgs[1], 1244 .chip = { 1245 .base = S3C64XX_GPM(0), 1246 .ngpio = S3C64XX_GPIO_M_NR, 1247 .label = "GPM", 1248 .to_irq = s3c64xx_gpiolib_mbank_to_irq, 1249 }, 1250 }, 1251#endif 1252}; 1253 1254static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = { 1255#ifdef CONFIG_PLAT_S3C64XX 1256 { 1257 .base = S3C64XX_GPH_BASE + 0x4, 1258 .chip = { 1259 .base = S3C64XX_GPH(0), 1260 .ngpio = S3C64XX_GPIO_H_NR, 1261 .label = "GPH", 1262 }, 1263 }, { 1264 .base = S3C64XX_GPK_BASE + 0x4, 1265 .config = &samsung_gpio_cfgs[0], 1266 .chip = { 1267 .base = S3C64XX_GPK(0), 1268 .ngpio = S3C64XX_GPIO_K_NR, 1269 .label = "GPK", 1270 }, 1271 }, { 1272 .base = S3C64XX_GPL_BASE + 0x4, 1273 .config = &samsung_gpio_cfgs[1], 1274 .chip = { 1275 .base = S3C64XX_GPL(0), 1276 .ngpio = S3C64XX_GPIO_L_NR, 1277 .label = "GPL", 1278 .to_irq = s3c64xx_gpiolib_lbank_to_irq, 1279 }, 1280 }, 1281#endif 1282}; 1283 1284static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = { 1285#ifdef CONFIG_PLAT_S3C64XX 1286 { 1287 .base = S3C64XX_GPF_BASE, 1288 .config = &samsung_gpio_cfgs[6], 1289 .chip = { 1290 .base = S3C64XX_GPF(0), 1291 .ngpio = S3C64XX_GPIO_F_NR, 1292 .label = "GPF", 1293 }, 1294 }, { 1295 .config = &samsung_gpio_cfgs[7], 1296 .chip = { 1297 .base = S3C64XX_GPI(0), 1298 .ngpio = S3C64XX_GPIO_I_NR, 1299 .label = "GPI", 1300 }, 1301 }, { 1302 .config = &samsung_gpio_cfgs[7], 1303 .chip = { 1304 .base = S3C64XX_GPJ(0), 1305 .ngpio = S3C64XX_GPIO_J_NR, 1306 .label = "GPJ", 1307 }, 1308 }, { 1309 .config = &samsung_gpio_cfgs[6], 1310 .chip = { 1311 .base = S3C64XX_GPO(0), 1312 .ngpio = S3C64XX_GPIO_O_NR, 1313 .label = "GPO", 1314 }, 1315 }, { 1316 .config = &samsung_gpio_cfgs[6], 1317 .chip = { 1318 .base = S3C64XX_GPP(0), 1319 .ngpio = S3C64XX_GPIO_P_NR, 1320 .label = "GPP", 1321 }, 1322 }, { 1323 .config = &samsung_gpio_cfgs[6], 1324 .chip = { 1325 .base = S3C64XX_GPQ(0), 1326 .ngpio = S3C64XX_GPIO_Q_NR, 1327 .label = "GPQ", 1328 }, 1329 }, { 1330 .base = S3C64XX_GPN_BASE, 1331 .irq_base = IRQ_EINT(0), 1332 .config = &samsung_gpio_cfgs[5], 1333 .chip = { 1334 .base = S3C64XX_GPN(0), 1335 .ngpio = S3C64XX_GPIO_N_NR, 1336 .label = "GPN", 1337 .to_irq = samsung_gpiolib_to_irq, 1338 }, 1339 }, 1340#endif 1341}; 1342 1343/* 1344 * S5P6440 GPIO bank summary: 1345 * 1346 * Bank GPIOs Style SlpCon ExtInt Group 1347 * A 6 4Bit Yes 1 1348 * B 7 4Bit Yes 1 1349 * C 8 4Bit Yes 2 1350 * F 2 2Bit Yes 4 [1] 1351 * G 7 4Bit Yes 5 1352 * H 10 4Bit[2] Yes 6 1353 * I 16 2Bit Yes None 1354 * J 12 2Bit Yes None 1355 * N 16 2Bit No IRQ_EINT 1356 * P 8 2Bit Yes 8 1357 * R 15 4Bit[2] Yes 8 1358 */ 1359 1360static struct samsung_gpio_chip s5p6440_gpios_4bit[] = { 1361#ifdef CONFIG_CPU_S5P6440 1362 { 1363 .chip = { 1364 .base = S5P6440_GPA(0), 1365 .ngpio = S5P6440_GPIO_A_NR, 1366 .label = "GPA", 1367 }, 1368 }, { 1369 .chip = { 1370 .base = S5P6440_GPB(0), 1371 .ngpio = S5P6440_GPIO_B_NR, 1372 .label = "GPB", 1373 }, 1374 }, { 1375 .chip = { 1376 .base = S5P6440_GPC(0), 1377 .ngpio = S5P6440_GPIO_C_NR, 1378 .label = "GPC", 1379 }, 1380 }, { 1381 .base = S5P64X0_GPG_BASE, 1382 .chip = { 1383 .base = S5P6440_GPG(0), 1384 .ngpio = S5P6440_GPIO_G_NR, 1385 .label = "GPG", 1386 }, 1387 }, 1388#endif 1389}; 1390 1391static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = { 1392#ifdef CONFIG_CPU_S5P6440 1393 { 1394 .base = S5P64X0_GPH_BASE + 0x4, 1395 .chip = { 1396 .base = S5P6440_GPH(0), 1397 .ngpio = S5P6440_GPIO_H_NR, 1398 .label = "GPH", 1399 }, 1400 }, 1401#endif 1402}; 1403 1404static struct samsung_gpio_chip s5p6440_gpios_rbank[] = { 1405#ifdef CONFIG_CPU_S5P6440 1406 { 1407 .base = S5P64X0_GPR_BASE + 0x4, 1408 .config = &s5p64x0_gpio_cfg_rbank, 1409 .chip = { 1410 .base = S5P6440_GPR(0), 1411 .ngpio = S5P6440_GPIO_R_NR, 1412 .label = "GPR", 1413 }, 1414 }, 1415#endif 1416}; 1417 1418static struct samsung_gpio_chip s5p6440_gpios_2bit[] = { 1419#ifdef CONFIG_CPU_S5P6440 1420 { 1421 .base = S5P64X0_GPF_BASE, 1422 .config = &samsung_gpio_cfgs[6], 1423 .chip = { 1424 .base = S5P6440_GPF(0), 1425 .ngpio = S5P6440_GPIO_F_NR, 1426 .label = "GPF", 1427 }, 1428 }, { 1429 .base = S5P64X0_GPI_BASE, 1430 .config = &samsung_gpio_cfgs[4], 1431 .chip = { 1432 .base = S5P6440_GPI(0), 1433 .ngpio = S5P6440_GPIO_I_NR, 1434 .label = "GPI", 1435 }, 1436 }, { 1437 .base = S5P64X0_GPJ_BASE, 1438 .config = &samsung_gpio_cfgs[4], 1439 .chip = { 1440 .base = S5P6440_GPJ(0), 1441 .ngpio = S5P6440_GPIO_J_NR, 1442 .label = "GPJ", 1443 }, 1444 }, { 1445 .base = S5P64X0_GPN_BASE, 1446 .config = &samsung_gpio_cfgs[5], 1447 .chip = { 1448 .base = S5P6440_GPN(0), 1449 .ngpio = S5P6440_GPIO_N_NR, 1450 .label = "GPN", 1451 }, 1452 }, { 1453 .base = S5P64X0_GPP_BASE, 1454 .config = &samsung_gpio_cfgs[6], 1455 .chip = { 1456 .base = S5P6440_GPP(0), 1457 .ngpio = S5P6440_GPIO_P_NR, 1458 .label = "GPP", 1459 }, 1460 }, 1461#endif 1462}; 1463 1464/* 1465 * S5P6450 GPIO bank summary: 1466 * 1467 * Bank GPIOs Style SlpCon ExtInt Group 1468 * A 6 4Bit Yes 1 1469 * B 7 4Bit Yes 1 1470 * C 8 4Bit Yes 2 1471 * D 8 4Bit Yes None 1472 * F 2 2Bit Yes None 1473 * G 14 4Bit[2] Yes 5 1474 * H 10 4Bit[2] Yes 6 1475 * I 16 2Bit Yes None 1476 * J 12 2Bit Yes None 1477 * K 5 4Bit Yes None 1478 * N 16 2Bit No IRQ_EINT 1479 * P 11 2Bit Yes 8 1480 * Q 14 2Bit Yes None 1481 * R 15 4Bit[2] Yes None 1482 * S 8 2Bit Yes None 1483 * 1484 * [1] BANKF pins 14,15 do not form part of the external interrupt sources 1485 * [2] BANK has two control registers, GPxCON0 and GPxCON1 1486 */ 1487 1488static struct samsung_gpio_chip s5p6450_gpios_4bit[] = { 1489#ifdef CONFIG_CPU_S5P6450 1490 { 1491 .chip = { 1492 .base = S5P6450_GPA(0), 1493 .ngpio = S5P6450_GPIO_A_NR, 1494 .label = "GPA", 1495 }, 1496 }, { 1497 .chip = { 1498 .base = S5P6450_GPB(0), 1499 .ngpio = S5P6450_GPIO_B_NR, 1500 .label = "GPB", 1501 }, 1502 }, { 1503 .chip = { 1504 .base = S5P6450_GPC(0), 1505 .ngpio = S5P6450_GPIO_C_NR, 1506 .label = "GPC", 1507 }, 1508 }, { 1509 .chip = { 1510 .base = S5P6450_GPD(0), 1511 .ngpio = S5P6450_GPIO_D_NR, 1512 .label = "GPD", 1513 }, 1514 }, { 1515 .base = S5P6450_GPK_BASE, 1516 .chip = { 1517 .base = S5P6450_GPK(0), 1518 .ngpio = S5P6450_GPIO_K_NR, 1519 .label = "GPK", 1520 }, 1521 }, 1522#endif 1523}; 1524 1525static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = { 1526#ifdef CONFIG_CPU_S5P6450 1527 { 1528 .base = S5P64X0_GPG_BASE + 0x4, 1529 .chip = { 1530 .base = S5P6450_GPG(0), 1531 .ngpio = S5P6450_GPIO_G_NR, 1532 .label = "GPG", 1533 }, 1534 }, { 1535 .base = S5P64X0_GPH_BASE + 0x4, 1536 .chip = { 1537 .base = S5P6450_GPH(0), 1538 .ngpio = S5P6450_GPIO_H_NR, 1539 .label = "GPH", 1540 }, 1541 }, 1542#endif 1543}; 1544 1545static struct samsung_gpio_chip s5p6450_gpios_rbank[] = { 1546#ifdef CONFIG_CPU_S5P6450 1547 { 1548 .base = S5P64X0_GPR_BASE + 0x4, 1549 .config = &s5p64x0_gpio_cfg_rbank, 1550 .chip = { 1551 .base = S5P6450_GPR(0), 1552 .ngpio = S5P6450_GPIO_R_NR, 1553 .label = "GPR", 1554 }, 1555 }, 1556#endif 1557}; 1558 1559static struct samsung_gpio_chip s5p6450_gpios_2bit[] = { 1560#ifdef CONFIG_CPU_S5P6450 1561 { 1562 .base = S5P64X0_GPF_BASE, 1563 .config = &samsung_gpio_cfgs[6], 1564 .chip = { 1565 .base = S5P6450_GPF(0), 1566 .ngpio = S5P6450_GPIO_F_NR, 1567 .label = "GPF", 1568 }, 1569 }, { 1570 .base = S5P64X0_GPI_BASE, 1571 .config = &samsung_gpio_cfgs[4], 1572 .chip = { 1573 .base = S5P6450_GPI(0), 1574 .ngpio = S5P6450_GPIO_I_NR, 1575 .label = "GPI", 1576 }, 1577 }, { 1578 .base = S5P64X0_GPJ_BASE, 1579 .config = &samsung_gpio_cfgs[4], 1580 .chip = { 1581 .base = S5P6450_GPJ(0), 1582 .ngpio = S5P6450_GPIO_J_NR, 1583 .label = "GPJ", 1584 }, 1585 }, { 1586 .base = S5P64X0_GPN_BASE, 1587 .config = &samsung_gpio_cfgs[5], 1588 .chip = { 1589 .base = S5P6450_GPN(0), 1590 .ngpio = S5P6450_GPIO_N_NR, 1591 .label = "GPN", 1592 }, 1593 }, { 1594 .base = S5P64X0_GPP_BASE, 1595 .config = &samsung_gpio_cfgs[6], 1596 .chip = { 1597 .base = S5P6450_GPP(0), 1598 .ngpio = S5P6450_GPIO_P_NR, 1599 .label = "GPP", 1600 }, 1601 }, { 1602 .base = S5P6450_GPQ_BASE, 1603 .config = &samsung_gpio_cfgs[5], 1604 .chip = { 1605 .base = S5P6450_GPQ(0), 1606 .ngpio = S5P6450_GPIO_Q_NR, 1607 .label = "GPQ", 1608 }, 1609 }, { 1610 .base = S5P6450_GPS_BASE, 1611 .config = &samsung_gpio_cfgs[6], 1612 .chip = { 1613 .base = S5P6450_GPS(0), 1614 .ngpio = S5P6450_GPIO_S_NR, 1615 .label = "GPS", 1616 }, 1617 }, 1618#endif 1619}; 1620 1621/* 1622 * S5PC100 GPIO bank summary: 1623 * 1624 * Bank GPIOs Style INT Type 1625 * A0 8 4Bit GPIO_INT0 1626 * A1 5 4Bit GPIO_INT1 1627 * B 8 4Bit GPIO_INT2 1628 * C 5 4Bit GPIO_INT3 1629 * D 7 4Bit GPIO_INT4 1630 * E0 8 4Bit GPIO_INT5 1631 * E1 6 4Bit GPIO_INT6 1632 * F0 8 4Bit GPIO_INT7 1633 * F1 8 4Bit GPIO_INT8 1634 * F2 8 4Bit GPIO_INT9 1635 * F3 4 4Bit GPIO_INT10 1636 * G0 8 4Bit GPIO_INT11 1637 * G1 3 4Bit GPIO_INT12 1638 * G2 7 4Bit GPIO_INT13 1639 * G3 7 4Bit GPIO_INT14 1640 * H0 8 4Bit WKUP_INT 1641 * H1 8 4Bit WKUP_INT 1642 * H2 8 4Bit WKUP_INT 1643 * H3 8 4Bit WKUP_INT 1644 * I 8 4Bit GPIO_INT15 1645 * J0 8 4Bit GPIO_INT16 1646 * J1 5 4Bit GPIO_INT17 1647 * J2 8 4Bit GPIO_INT18 1648 * J3 8 4Bit GPIO_INT19 1649 * J4 4 4Bit GPIO_INT20 1650 * K0 8 4Bit None 1651 * K1 6 4Bit None 1652 * K2 8 4Bit None 1653 * K3 8 4Bit None 1654 * L0 8 4Bit None 1655 * L1 8 4Bit None 1656 * L2 8 4Bit None 1657 * L3 8 4Bit None 1658 */ 1659 1660static struct samsung_gpio_chip s5pc100_gpios_4bit[] = { 1661#ifdef CONFIG_CPU_S5PC100 1662 { 1663 .chip = { 1664 .base = S5PC100_GPA0(0), 1665 .ngpio = S5PC100_GPIO_A0_NR, 1666 .label = "GPA0", 1667 }, 1668 }, { 1669 .chip = { 1670 .base = S5PC100_GPA1(0), 1671 .ngpio = S5PC100_GPIO_A1_NR, 1672 .label = "GPA1", 1673 }, 1674 }, { 1675 .chip = { 1676 .base = S5PC100_GPB(0), 1677 .ngpio = S5PC100_GPIO_B_NR, 1678 .label = "GPB", 1679 }, 1680 }, { 1681 .chip = { 1682 .base = S5PC100_GPC(0), 1683 .ngpio = S5PC100_GPIO_C_NR, 1684 .label = "GPC", 1685 }, 1686 }, { 1687 .chip = { 1688 .base = S5PC100_GPD(0), 1689 .ngpio = S5PC100_GPIO_D_NR, 1690 .label = "GPD", 1691 }, 1692 }, { 1693 .chip = { 1694 .base = S5PC100_GPE0(0), 1695 .ngpio = S5PC100_GPIO_E0_NR, 1696 .label = "GPE0", 1697 }, 1698 }, { 1699 .chip = { 1700 .base = S5PC100_GPE1(0), 1701 .ngpio = S5PC100_GPIO_E1_NR, 1702 .label = "GPE1", 1703 }, 1704 }, { 1705 .chip = { 1706 .base = S5PC100_GPF0(0), 1707 .ngpio = S5PC100_GPIO_F0_NR, 1708 .label = "GPF0", 1709 }, 1710 }, { 1711 .chip = { 1712 .base = S5PC100_GPF1(0), 1713 .ngpio = S5PC100_GPIO_F1_NR, 1714 .label = "GPF1", 1715 }, 1716 }, { 1717 .chip = { 1718 .base = S5PC100_GPF2(0), 1719 .ngpio = S5PC100_GPIO_F2_NR, 1720 .label = "GPF2", 1721 }, 1722 }, { 1723 .chip = { 1724 .base = S5PC100_GPF3(0), 1725 .ngpio = S5PC100_GPIO_F3_NR, 1726 .label = "GPF3", 1727 }, 1728 }, { 1729 .chip = { 1730 .base = S5PC100_GPG0(0), 1731 .ngpio = S5PC100_GPIO_G0_NR, 1732 .label = "GPG0", 1733 }, 1734 }, { 1735 .chip = { 1736 .base = S5PC100_GPG1(0), 1737 .ngpio = S5PC100_GPIO_G1_NR, 1738 .label = "GPG1", 1739 }, 1740 }, { 1741 .chip = { 1742 .base = S5PC100_GPG2(0), 1743 .ngpio = S5PC100_GPIO_G2_NR, 1744 .label = "GPG2", 1745 }, 1746 }, { 1747 .chip = { 1748 .base = S5PC100_GPG3(0), 1749 .ngpio = S5PC100_GPIO_G3_NR, 1750 .label = "GPG3", 1751 }, 1752 }, { 1753 .chip = { 1754 .base = S5PC100_GPI(0), 1755 .ngpio = S5PC100_GPIO_I_NR, 1756 .label = "GPI", 1757 }, 1758 }, { 1759 .chip = { 1760 .base = S5PC100_GPJ0(0), 1761 .ngpio = S5PC100_GPIO_J0_NR, 1762 .label = "GPJ0", 1763 }, 1764 }, { 1765 .chip = { 1766 .base = S5PC100_GPJ1(0), 1767 .ngpio = S5PC100_GPIO_J1_NR, 1768 .label = "GPJ1", 1769 }, 1770 }, { 1771 .chip = { 1772 .base = S5PC100_GPJ2(0), 1773 .ngpio = S5PC100_GPIO_J2_NR, 1774 .label = "GPJ2", 1775 }, 1776 }, { 1777 .chip = { 1778 .base = S5PC100_GPJ3(0), 1779 .ngpio = S5PC100_GPIO_J3_NR, 1780 .label = "GPJ3", 1781 }, 1782 }, { 1783 .chip = { 1784 .base = S5PC100_GPJ4(0), 1785 .ngpio = S5PC100_GPIO_J4_NR, 1786 .label = "GPJ4", 1787 }, 1788 }, { 1789 .chip = { 1790 .base = S5PC100_GPK0(0), 1791 .ngpio = S5PC100_GPIO_K0_NR, 1792 .label = "GPK0", 1793 }, 1794 }, { 1795 .chip = { 1796 .base = S5PC100_GPK1(0), 1797 .ngpio = S5PC100_GPIO_K1_NR, 1798 .label = "GPK1", 1799 }, 1800 }, { 1801 .chip = { 1802 .base = S5PC100_GPK2(0), 1803 .ngpio = S5PC100_GPIO_K2_NR, 1804 .label = "GPK2", 1805 }, 1806 }, { 1807 .chip = { 1808 .base = S5PC100_GPK3(0), 1809 .ngpio = S5PC100_GPIO_K3_NR, 1810 .label = "GPK3", 1811 }, 1812 }, { 1813 .chip = { 1814 .base = S5PC100_GPL0(0), 1815 .ngpio = S5PC100_GPIO_L0_NR, 1816 .label = "GPL0", 1817 }, 1818 }, { 1819 .chip = { 1820 .base = S5PC100_GPL1(0), 1821 .ngpio = S5PC100_GPIO_L1_NR, 1822 .label = "GPL1", 1823 }, 1824 }, { 1825 .chip = { 1826 .base = S5PC100_GPL2(0), 1827 .ngpio = S5PC100_GPIO_L2_NR, 1828 .label = "GPL2", 1829 }, 1830 }, { 1831 .chip = { 1832 .base = S5PC100_GPL3(0), 1833 .ngpio = S5PC100_GPIO_L3_NR, 1834 .label = "GPL3", 1835 }, 1836 }, { 1837 .chip = { 1838 .base = S5PC100_GPL4(0), 1839 .ngpio = S5PC100_GPIO_L4_NR, 1840 .label = "GPL4", 1841 }, 1842 }, { 1843 .base = (S5P_VA_GPIO + 0xC00), 1844 .irq_base = IRQ_EINT(0), 1845 .chip = { 1846 .base = S5PC100_GPH0(0), 1847 .ngpio = S5PC100_GPIO_H0_NR, 1848 .label = "GPH0", 1849 .to_irq = samsung_gpiolib_to_irq, 1850 }, 1851 }, { 1852 .base = (S5P_VA_GPIO + 0xC20), 1853 .irq_base = IRQ_EINT(8), 1854 .chip = { 1855 .base = S5PC100_GPH1(0), 1856 .ngpio = S5PC100_GPIO_H1_NR, 1857 .label = "GPH1", 1858 .to_irq = samsung_gpiolib_to_irq, 1859 }, 1860 }, { 1861 .base = (S5P_VA_GPIO + 0xC40), 1862 .irq_base = IRQ_EINT(16), 1863 .chip = { 1864 .base = S5PC100_GPH2(0), 1865 .ngpio = S5PC100_GPIO_H2_NR, 1866 .label = "GPH2", 1867 .to_irq = samsung_gpiolib_to_irq, 1868 }, 1869 }, { 1870 .base = (S5P_VA_GPIO + 0xC60), 1871 .irq_base = IRQ_EINT(24), 1872 .chip = { 1873 .base = S5PC100_GPH3(0), 1874 .ngpio = S5PC100_GPIO_H3_NR, 1875 .label = "GPH3", 1876 .to_irq = samsung_gpiolib_to_irq, 1877 }, 1878 }, 1879#endif 1880}; 1881 1882/* 1883 * Followings are the gpio banks in S5PV210/S5PC110 1884 * 1885 * The 'config' member when left to NULL, is initialized to the default 1886 * structure samsung_gpio_cfgs[3] in the init function below. 1887 * 1888 * The 'base' member is also initialized in the init function below. 1889 * Note: The initialization of 'base' member of samsung_gpio_chip structure 1890 * uses the above macro and depends on the banks being listed in order here. 1891 */ 1892 1893static struct samsung_gpio_chip s5pv210_gpios_4bit[] = { 1894#ifdef CONFIG_CPU_S5PV210 1895 { 1896 .chip = { 1897 .base = S5PV210_GPA0(0), 1898 .ngpio = S5PV210_GPIO_A0_NR, 1899 .label = "GPA0", 1900 }, 1901 }, { 1902 .chip = { 1903 .base = S5PV210_GPA1(0), 1904 .ngpio = S5PV210_GPIO_A1_NR, 1905 .label = "GPA1", 1906 }, 1907 }, { 1908 .chip = { 1909 .base = S5PV210_GPB(0), 1910 .ngpio = S5PV210_GPIO_B_NR, 1911 .label = "GPB", 1912 }, 1913 }, { 1914 .chip = { 1915 .base = S5PV210_GPC0(0), 1916 .ngpio = S5PV210_GPIO_C0_NR, 1917 .label = "GPC0", 1918 }, 1919 }, { 1920 .chip = { 1921 .base = S5PV210_GPC1(0), 1922 .ngpio = S5PV210_GPIO_C1_NR, 1923 .label = "GPC1", 1924 }, 1925 }, { 1926 .chip = { 1927 .base = S5PV210_GPD0(0), 1928 .ngpio = S5PV210_GPIO_D0_NR, 1929 .label = "GPD0", 1930 }, 1931 }, { 1932 .chip = { 1933 .base = S5PV210_GPD1(0), 1934 .ngpio = S5PV210_GPIO_D1_NR, 1935 .label = "GPD1", 1936 }, 1937 }, { 1938 .chip = { 1939 .base = S5PV210_GPE0(0), 1940 .ngpio = S5PV210_GPIO_E0_NR, 1941 .label = "GPE0", 1942 }, 1943 }, { 1944 .chip = { 1945 .base = S5PV210_GPE1(0), 1946 .ngpio = S5PV210_GPIO_E1_NR, 1947 .label = "GPE1", 1948 }, 1949 }, { 1950 .chip = { 1951 .base = S5PV210_GPF0(0), 1952 .ngpio = S5PV210_GPIO_F0_NR, 1953 .label = "GPF0", 1954 }, 1955 }, { 1956 .chip = { 1957 .base = S5PV210_GPF1(0), 1958 .ngpio = S5PV210_GPIO_F1_NR, 1959 .label = "GPF1", 1960 }, 1961 }, { 1962 .chip = { 1963 .base = S5PV210_GPF2(0), 1964 .ngpio = S5PV210_GPIO_F2_NR, 1965 .label = "GPF2", 1966 }, 1967 }, { 1968 .chip = { 1969 .base = S5PV210_GPF3(0), 1970 .ngpio = S5PV210_GPIO_F3_NR, 1971 .label = "GPF3", 1972 }, 1973 }, { 1974 .chip = { 1975 .base = S5PV210_GPG0(0), 1976 .ngpio = S5PV210_GPIO_G0_NR, 1977 .label = "GPG0", 1978 }, 1979 }, { 1980 .chip = { 1981 .base = S5PV210_GPG1(0), 1982 .ngpio = S5PV210_GPIO_G1_NR, 1983 .label = "GPG1", 1984 }, 1985 }, { 1986 .chip = { 1987 .base = S5PV210_GPG2(0), 1988 .ngpio = S5PV210_GPIO_G2_NR, 1989 .label = "GPG2", 1990 }, 1991 }, { 1992 .chip = { 1993 .base = S5PV210_GPG3(0), 1994 .ngpio = S5PV210_GPIO_G3_NR, 1995 .label = "GPG3", 1996 }, 1997 }, { 1998 .chip = { 1999 .base = S5PV210_GPI(0), 2000 .ngpio = S5PV210_GPIO_I_NR, 2001 .label = "GPI", 2002 }, 2003 }, { 2004 .chip = { 2005 .base = S5PV210_GPJ0(0), 2006 .ngpio = S5PV210_GPIO_J0_NR, 2007 .label = "GPJ0", 2008 }, 2009 }, { 2010 .chip = { 2011 .base = S5PV210_GPJ1(0), 2012 .ngpio = S5PV210_GPIO_J1_NR, 2013 .label = "GPJ1", 2014 }, 2015 }, { 2016 .chip = { 2017 .base = S5PV210_GPJ2(0), 2018 .ngpio = S5PV210_GPIO_J2_NR, 2019 .label = "GPJ2", 2020 }, 2021 }, { 2022 .chip = { 2023 .base = S5PV210_GPJ3(0), 2024 .ngpio = S5PV210_GPIO_J3_NR, 2025 .label = "GPJ3", 2026 }, 2027 }, { 2028 .chip = { 2029 .base = S5PV210_GPJ4(0), 2030 .ngpio = S5PV210_GPIO_J4_NR, 2031 .label = "GPJ4", 2032 }, 2033 }, { 2034 .chip = { 2035 .base = S5PV210_MP01(0), 2036 .ngpio = S5PV210_GPIO_MP01_NR, 2037 .label = "MP01", 2038 }, 2039 }, { 2040 .chip = { 2041 .base = S5PV210_MP02(0), 2042 .ngpio = S5PV210_GPIO_MP02_NR, 2043 .label = "MP02", 2044 }, 2045 }, { 2046 .chip = { 2047 .base = S5PV210_MP03(0), 2048 .ngpio = S5PV210_GPIO_MP03_NR, 2049 .label = "MP03", 2050 }, 2051 }, { 2052 .chip = { 2053 .base = S5PV210_MP04(0), 2054 .ngpio = S5PV210_GPIO_MP04_NR, 2055 .label = "MP04", 2056 }, 2057 }, { 2058 .chip = { 2059 .base = S5PV210_MP05(0), 2060 .ngpio = S5PV210_GPIO_MP05_NR, 2061 .label = "MP05", 2062 }, 2063 }, { 2064 .base = (S5P_VA_GPIO + 0xC00), 2065 .irq_base = IRQ_EINT(0), 2066 .chip = { 2067 .base = S5PV210_GPH0(0), 2068 .ngpio = S5PV210_GPIO_H0_NR, 2069 .label = "GPH0", 2070 .to_irq = samsung_gpiolib_to_irq, 2071 }, 2072 }, { 2073 .base = (S5P_VA_GPIO + 0xC20), 2074 .irq_base = IRQ_EINT(8), 2075 .chip = { 2076 .base = S5PV210_GPH1(0), 2077 .ngpio = S5PV210_GPIO_H1_NR, 2078 .label = "GPH1", 2079 .to_irq = samsung_gpiolib_to_irq, 2080 }, 2081 }, { 2082 .base = (S5P_VA_GPIO + 0xC40), 2083 .irq_base = IRQ_EINT(16), 2084 .chip = { 2085 .base = S5PV210_GPH2(0), 2086 .ngpio = S5PV210_GPIO_H2_NR, 2087 .label = "GPH2", 2088 .to_irq = samsung_gpiolib_to_irq, 2089 }, 2090 }, { 2091 .base = (S5P_VA_GPIO + 0xC60), 2092 .irq_base = IRQ_EINT(24), 2093 .chip = { 2094 .base = S5PV210_GPH3(0), 2095 .ngpio = S5PV210_GPIO_H3_NR, 2096 .label = "GPH3", 2097 .to_irq = samsung_gpiolib_to_irq, 2098 }, 2099 }, 2100#endif 2101}; 2102 2103/* 2104 * Followings are the gpio banks in EXYNOS4210 2105 * 2106 * The 'config' member when left to NULL, is initialized to the default 2107 * structure samsung_gpio_cfgs[3] in the init function below. 2108 * 2109 * The 'base' member is also initialized in the init function below. 2110 * Note: The initialization of 'base' member of samsung_gpio_chip structure 2111 * uses the above macro and depends on the banks being listed in order here. 2112 */ 2113 2114static struct samsung_gpio_chip exynos4_gpios_1[] = { 2115#ifdef CONFIG_ARCH_EXYNOS4 2116 { 2117 .chip = { 2118 .base = EXYNOS4_GPA0(0), 2119 .ngpio = EXYNOS4_GPIO_A0_NR, 2120 .label = "GPA0", 2121 }, 2122 }, { 2123 .chip = { 2124 .base = EXYNOS4_GPA1(0), 2125 .ngpio = EXYNOS4_GPIO_A1_NR, 2126 .label = "GPA1", 2127 }, 2128 }, { 2129 .chip = { 2130 .base = EXYNOS4_GPB(0), 2131 .ngpio = EXYNOS4_GPIO_B_NR, 2132 .label = "GPB", 2133 }, 2134 }, { 2135 .chip = { 2136 .base = EXYNOS4_GPC0(0), 2137 .ngpio = EXYNOS4_GPIO_C0_NR, 2138 .label = "GPC0", 2139 }, 2140 }, { 2141 .chip = { 2142 .base = EXYNOS4_GPC1(0), 2143 .ngpio = EXYNOS4_GPIO_C1_NR, 2144 .label = "GPC1", 2145 }, 2146 }, { 2147 .chip = { 2148 .base = EXYNOS4_GPD0(0), 2149 .ngpio = EXYNOS4_GPIO_D0_NR, 2150 .label = "GPD0", 2151 }, 2152 }, { 2153 .chip = { 2154 .base = EXYNOS4_GPD1(0), 2155 .ngpio = EXYNOS4_GPIO_D1_NR, 2156 .label = "GPD1", 2157 }, 2158 }, { 2159 .chip = { 2160 .base = EXYNOS4_GPE0(0), 2161 .ngpio = EXYNOS4_GPIO_E0_NR, 2162 .label = "GPE0", 2163 }, 2164 }, { 2165 .chip = { 2166 .base = EXYNOS4_GPE1(0), 2167 .ngpio = EXYNOS4_GPIO_E1_NR, 2168 .label = "GPE1", 2169 }, 2170 }, { 2171 .chip = { 2172 .base = EXYNOS4_GPE2(0), 2173 .ngpio = EXYNOS4_GPIO_E2_NR, 2174 .label = "GPE2", 2175 }, 2176 }, { 2177 .chip = { 2178 .base = EXYNOS4_GPE3(0), 2179 .ngpio = EXYNOS4_GPIO_E3_NR, 2180 .label = "GPE3", 2181 }, 2182 }, { 2183 .chip = { 2184 .base = EXYNOS4_GPE4(0), 2185 .ngpio = EXYNOS4_GPIO_E4_NR, 2186 .label = "GPE4", 2187 }, 2188 }, { 2189 .chip = { 2190 .base = EXYNOS4_GPF0(0), 2191 .ngpio = EXYNOS4_GPIO_F0_NR, 2192 .label = "GPF0", 2193 }, 2194 }, { 2195 .chip = { 2196 .base = EXYNOS4_GPF1(0), 2197 .ngpio = EXYNOS4_GPIO_F1_NR, 2198 .label = "GPF1", 2199 }, 2200 }, { 2201 .chip = { 2202 .base = EXYNOS4_GPF2(0), 2203 .ngpio = EXYNOS4_GPIO_F2_NR, 2204 .label = "GPF2", 2205 }, 2206 }, { 2207 .chip = { 2208 .base = EXYNOS4_GPF3(0), 2209 .ngpio = EXYNOS4_GPIO_F3_NR, 2210 .label = "GPF3", 2211 }, 2212 }, 2213#endif 2214}; 2215 2216static struct samsung_gpio_chip exynos4_gpios_2[] = { 2217#ifdef CONFIG_ARCH_EXYNOS4 2218 { 2219 .chip = { 2220 .base = EXYNOS4_GPJ0(0), 2221 .ngpio = EXYNOS4_GPIO_J0_NR, 2222 .label = "GPJ0", 2223 }, 2224 }, { 2225 .chip = { 2226 .base = EXYNOS4_GPJ1(0), 2227 .ngpio = EXYNOS4_GPIO_J1_NR, 2228 .label = "GPJ1", 2229 }, 2230 }, { 2231 .chip = { 2232 .base = EXYNOS4_GPK0(0), 2233 .ngpio = EXYNOS4_GPIO_K0_NR, 2234 .label = "GPK0", 2235 }, 2236 }, { 2237 .chip = { 2238 .base = EXYNOS4_GPK1(0), 2239 .ngpio = EXYNOS4_GPIO_K1_NR, 2240 .label = "GPK1", 2241 }, 2242 }, { 2243 .chip = { 2244 .base = EXYNOS4_GPK2(0), 2245 .ngpio = EXYNOS4_GPIO_K2_NR, 2246 .label = "GPK2", 2247 }, 2248 }, { 2249 .chip = { 2250 .base = EXYNOS4_GPK3(0), 2251 .ngpio = EXYNOS4_GPIO_K3_NR, 2252 .label = "GPK3", 2253 }, 2254 }, { 2255 .chip = { 2256 .base = EXYNOS4_GPL0(0), 2257 .ngpio = EXYNOS4_GPIO_L0_NR, 2258 .label = "GPL0", 2259 }, 2260 }, { 2261 .chip = { 2262 .base = EXYNOS4_GPL1(0), 2263 .ngpio = EXYNOS4_GPIO_L1_NR, 2264 .label = "GPL1", 2265 }, 2266 }, { 2267 .chip = { 2268 .base = EXYNOS4_GPL2(0), 2269 .ngpio = EXYNOS4_GPIO_L2_NR, 2270 .label = "GPL2", 2271 }, 2272 }, { 2273 .config = &samsung_gpio_cfgs[8], 2274 .chip = { 2275 .base = EXYNOS4_GPY0(0), 2276 .ngpio = EXYNOS4_GPIO_Y0_NR, 2277 .label = "GPY0", 2278 }, 2279 }, { 2280 .config = &samsung_gpio_cfgs[8], 2281 .chip = { 2282 .base = EXYNOS4_GPY1(0), 2283 .ngpio = EXYNOS4_GPIO_Y1_NR, 2284 .label = "GPY1", 2285 }, 2286 }, { 2287 .config = &samsung_gpio_cfgs[8], 2288 .chip = { 2289 .base = EXYNOS4_GPY2(0), 2290 .ngpio = EXYNOS4_GPIO_Y2_NR, 2291 .label = "GPY2", 2292 }, 2293 }, { 2294 .config = &samsung_gpio_cfgs[8], 2295 .chip = { 2296 .base = EXYNOS4_GPY3(0), 2297 .ngpio = EXYNOS4_GPIO_Y3_NR, 2298 .label = "GPY3", 2299 }, 2300 }, { 2301 .config = &samsung_gpio_cfgs[8], 2302 .chip = { 2303 .base = EXYNOS4_GPY4(0), 2304 .ngpio = EXYNOS4_GPIO_Y4_NR, 2305 .label = "GPY4", 2306 }, 2307 }, { 2308 .config = &samsung_gpio_cfgs[8], 2309 .chip = { 2310 .base = EXYNOS4_GPY5(0), 2311 .ngpio = EXYNOS4_GPIO_Y5_NR, 2312 .label = "GPY5", 2313 }, 2314 }, { 2315 .config = &samsung_gpio_cfgs[8], 2316 .chip = { 2317 .base = EXYNOS4_GPY6(0), 2318 .ngpio = EXYNOS4_GPIO_Y6_NR, 2319 .label = "GPY6", 2320 }, 2321 }, { 2322 .base = (S5P_VA_GPIO2 + 0xC00), 2323 .config = &samsung_gpio_cfgs[9], 2324 .irq_base = IRQ_EINT(0), 2325 .chip = { 2326 .base = EXYNOS4_GPX0(0), 2327 .ngpio = EXYNOS4_GPIO_X0_NR, 2328 .label = "GPX0", 2329 .to_irq = samsung_gpiolib_to_irq, 2330 }, 2331 }, { 2332 .base = (S5P_VA_GPIO2 + 0xC20), 2333 .config = &samsung_gpio_cfgs[9], 2334 .irq_base = IRQ_EINT(8), 2335 .chip = { 2336 .base = EXYNOS4_GPX1(0), 2337 .ngpio = EXYNOS4_GPIO_X1_NR, 2338 .label = "GPX1", 2339 .to_irq = samsung_gpiolib_to_irq, 2340 }, 2341 }, { 2342 .base = (S5P_VA_GPIO2 + 0xC40), 2343 .config = &samsung_gpio_cfgs[9], 2344 .irq_base = IRQ_EINT(16), 2345 .chip = { 2346 .base = EXYNOS4_GPX2(0), 2347 .ngpio = EXYNOS4_GPIO_X2_NR, 2348 .label = "GPX2", 2349 .to_irq = samsung_gpiolib_to_irq, 2350 }, 2351 }, { 2352 .base = (S5P_VA_GPIO2 + 0xC60), 2353 .config = &samsung_gpio_cfgs[9], 2354 .irq_base = IRQ_EINT(24), 2355 .chip = { 2356 .base = EXYNOS4_GPX3(0), 2357 .ngpio = EXYNOS4_GPIO_X3_NR, 2358 .label = "GPX3", 2359 .to_irq = samsung_gpiolib_to_irq, 2360 }, 2361 }, 2362#endif 2363}; 2364 2365static struct samsung_gpio_chip exynos4_gpios_3[] = { 2366#ifdef CONFIG_ARCH_EXYNOS4 2367 { 2368 .chip = { 2369 .base = EXYNOS4_GPZ(0), 2370 .ngpio = EXYNOS4_GPIO_Z_NR, 2371 .label = "GPZ", 2372 }, 2373 }, 2374#endif 2375}; 2376 2377/* TODO: cleanup soc_is_* */ 2378static __init int samsung_gpiolib_init(void) 2379{ 2380 struct samsung_gpio_chip *chip; 2381 int i, nr_chips; 2382 int group = 0; 2383 2384 samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); 2385 2386 if (soc_is_s3c24xx()) { 2387 s3c24xx_gpiolib_add_chips(s3c24xx_gpios, 2388 ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO); 2389 } else if (soc_is_s3c64xx()) { 2390 samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit, 2391 ARRAY_SIZE(s3c64xx_gpios_2bit), 2392 S3C64XX_VA_GPIO + 0xE0, 0x20); 2393 samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit, 2394 ARRAY_SIZE(s3c64xx_gpios_4bit), 2395 S3C64XX_VA_GPIO); 2396 samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2, 2397 ARRAY_SIZE(s3c64xx_gpios_4bit2)); 2398 } else if (soc_is_s5p6440()) { 2399 samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit, 2400 ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0); 2401 samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit, 2402 ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO); 2403 samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2, 2404 ARRAY_SIZE(s5p6440_gpios_4bit2)); 2405 s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank, 2406 ARRAY_SIZE(s5p6440_gpios_rbank)); 2407 } else if (soc_is_s5p6450()) { 2408 samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit, 2409 ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0); 2410 samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit, 2411 ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO); 2412 samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2, 2413 ARRAY_SIZE(s5p6450_gpios_4bit2)); 2414 s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank, 2415 ARRAY_SIZE(s5p6450_gpios_rbank)); 2416 } else if (soc_is_s5pc100()) { 2417 group = 0; 2418 chip = s5pc100_gpios_4bit; 2419 nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit); 2420 2421 for (i = 0; i < nr_chips; i++, chip++) { 2422 if (!chip->config) { 2423 chip->config = &samsung_gpio_cfgs[3]; 2424 chip->group = group++; 2425 } 2426 } 2427 samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO); 2428#if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT) 2429 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); 2430#endif 2431 } else if (soc_is_s5pv210()) { 2432 group = 0; 2433 chip = s5pv210_gpios_4bit; 2434 nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit); 2435 2436 for (i = 0; i < nr_chips; i++, chip++) { 2437 if (!chip->config) { 2438 chip->config = &samsung_gpio_cfgs[3]; 2439 chip->group = group++; 2440 } 2441 } 2442 samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO); 2443#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT) 2444 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); 2445#endif 2446 } else if (soc_is_exynos4210()) { 2447 group = 0; 2448 2449 /* gpio part1 */ 2450 chip = exynos4_gpios_1; 2451 nr_chips = ARRAY_SIZE(exynos4_gpios_1); 2452 2453 for (i = 0; i < nr_chips; i++, chip++) { 2454 if (!chip->config) { 2455 chip->config = &exynos4_gpio_cfg; 2456 chip->group = group++; 2457 } 2458 } 2459 samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1); 2460 2461 /* gpio part2 */ 2462 chip = exynos4_gpios_2; 2463 nr_chips = ARRAY_SIZE(exynos4_gpios_2); 2464 2465 for (i = 0; i < nr_chips; i++, chip++) { 2466 if (!chip->config) { 2467 chip->config = &exynos4_gpio_cfg; 2468 chip->group = group++; 2469 } 2470 } 2471 samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2); 2472 2473 /* gpio part3 */ 2474 chip = exynos4_gpios_3; 2475 nr_chips = ARRAY_SIZE(exynos4_gpios_3); 2476 2477 for (i = 0; i < nr_chips; i++, chip++) { 2478 if (!chip->config) { 2479 chip->config = &exynos4_gpio_cfg; 2480 chip->group = group++; 2481 } 2482 } 2483 samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3); 2484 2485#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT) 2486 s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); 2487 s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); 2488#endif 2489 } else { 2490 WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n"); 2491 return -ENODEV; 2492 } 2493 2494 return 0; 2495} 2496core_initcall(samsung_gpiolib_init); 2497 2498int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) 2499{ 2500 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 2501 unsigned long flags; 2502 int offset; 2503 int ret; 2504 2505 if (!chip) 2506 return -EINVAL; 2507 2508 offset = pin - chip->chip.base; 2509 2510 samsung_gpio_lock(chip, flags); 2511 ret = samsung_gpio_do_setcfg(chip, offset, config); 2512 samsung_gpio_unlock(chip, flags); 2513 2514 return ret; 2515} 2516EXPORT_SYMBOL(s3c_gpio_cfgpin); 2517 2518int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, 2519 unsigned int cfg) 2520{ 2521 int ret; 2522 2523 for (; nr > 0; nr--, start++) { 2524 ret = s3c_gpio_cfgpin(start, cfg); 2525 if (ret != 0) 2526 return ret; 2527 } 2528 2529 return 0; 2530} 2531EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range); 2532 2533int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, 2534 unsigned int cfg, samsung_gpio_pull_t pull) 2535{ 2536 int ret; 2537 2538 for (; nr > 0; nr--, start++) { 2539 s3c_gpio_setpull(start, pull); 2540 ret = s3c_gpio_cfgpin(start, cfg); 2541 if (ret != 0) 2542 return ret; 2543 } 2544 2545 return 0; 2546} 2547EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range); 2548 2549unsigned s3c_gpio_getcfg(unsigned int pin) 2550{ 2551 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 2552 unsigned long flags; 2553 unsigned ret = 0; 2554 int offset; 2555 2556 if (chip) { 2557 offset = pin - chip->chip.base; 2558 2559 samsung_gpio_lock(chip, flags); 2560 ret = samsung_gpio_do_getcfg(chip, offset); 2561 samsung_gpio_unlock(chip, flags); 2562 } 2563 2564 return ret; 2565} 2566EXPORT_SYMBOL(s3c_gpio_getcfg); 2567 2568int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull) 2569{ 2570 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 2571 unsigned long flags; 2572 int offset, ret; 2573 2574 if (!chip) 2575 return -EINVAL; 2576 2577 offset = pin - chip->chip.base; 2578 2579 samsung_gpio_lock(chip, flags); 2580 ret = samsung_gpio_do_setpull(chip, offset, pull); 2581 samsung_gpio_unlock(chip, flags); 2582 2583 return ret; 2584} 2585EXPORT_SYMBOL(s3c_gpio_setpull); 2586 2587samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin) 2588{ 2589 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 2590 unsigned long flags; 2591 int offset; 2592 u32 pup = 0; 2593 2594 if (chip) { 2595 offset = pin - chip->chip.base; 2596 2597 samsung_gpio_lock(chip, flags); 2598 pup = samsung_gpio_do_getpull(chip, offset); 2599 samsung_gpio_unlock(chip, flags); 2600 } 2601 2602 return (__force samsung_gpio_pull_t)pup; 2603} 2604EXPORT_SYMBOL(s3c_gpio_getpull); 2605 2606/* gpiolib wrappers until these are totally eliminated */ 2607 2608void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) 2609{ 2610 int ret; 2611 2612 WARN_ON(to); /* should be none of these left */ 2613 2614 if (!to) { 2615 /* if pull is enabled, try first with up, and if that 2616 * fails, try using down */ 2617 2618 ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP); 2619 if (ret) 2620 s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN); 2621 } else { 2622 s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); 2623 } 2624} 2625EXPORT_SYMBOL(s3c2410_gpio_pullup); 2626 2627void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) 2628{ 2629 /* do this via gpiolib until all users removed */ 2630 2631 gpio_request(pin, "temporary"); 2632 gpio_set_value(pin, to); 2633 gpio_free(pin); 2634} 2635EXPORT_SYMBOL(s3c2410_gpio_setpin); 2636 2637unsigned int s3c2410_gpio_getpin(unsigned int pin) 2638{ 2639 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 2640 unsigned long offs = pin - chip->chip.base; 2641 2642 return __raw_readl(chip->base + 0x04) & (1 << offs); 2643} 2644EXPORT_SYMBOL(s3c2410_gpio_getpin); 2645 2646#ifdef CONFIG_S5P_GPIO_DRVSTR 2647s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) 2648{ 2649 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 2650 unsigned int off; 2651 void __iomem *reg; 2652 int shift; 2653 u32 drvstr; 2654 2655 if (!chip) 2656 return -EINVAL; 2657 2658 off = pin - chip->chip.base; 2659 shift = off * 2; 2660 reg = chip->base + 0x0C; 2661 2662 drvstr = __raw_readl(reg); 2663 drvstr = drvstr >> shift; 2664 drvstr &= 0x3; 2665 2666 return (__force s5p_gpio_drvstr_t)drvstr; 2667} 2668EXPORT_SYMBOL(s5p_gpio_get_drvstr); 2669 2670int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr) 2671{ 2672 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 2673 unsigned int off; 2674 void __iomem *reg; 2675 int shift; 2676 u32 tmp; 2677 2678 if (!chip) 2679 return -EINVAL; 2680 2681 off = pin - chip->chip.base; 2682 shift = off * 2; 2683 reg = chip->base + 0x0C; 2684 2685 tmp = __raw_readl(reg); 2686 tmp &= ~(0x3 << shift); 2687 tmp |= drvstr << shift; 2688 2689 __raw_writel(tmp, reg); 2690 2691 return 0; 2692} 2693EXPORT_SYMBOL(s5p_gpio_set_drvstr); 2694#endif /* CONFIG_S5P_GPIO_DRVSTR */ 2695 2696#ifdef CONFIG_PLAT_S3C24XX 2697unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) 2698{ 2699 unsigned long flags; 2700 unsigned long misccr; 2701 2702 local_irq_save(flags); 2703 misccr = __raw_readl(S3C24XX_MISCCR); 2704 misccr &= ~clear; 2705 misccr ^= change; 2706 __raw_writel(misccr, S3C24XX_MISCCR); 2707 local_irq_restore(flags); 2708 2709 return misccr; 2710} 2711EXPORT_SYMBOL(s3c2410_modify_misccr); 2712#endif