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