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#include <mach/gpio-samsung.h> 36 37#include <plat/cpu.h> 38#include <plat/gpio-core.h> 39#include <plat/gpio-cfg.h> 40#include <plat/gpio-cfg-helpers.h> 41#include <plat/pm.h> 42 43int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, 44 unsigned int off, samsung_gpio_pull_t pull) 45{ 46 void __iomem *reg = chip->base + 0x08; 47 int shift = off * 2; 48 u32 pup; 49 50 pup = __raw_readl(reg); 51 pup &= ~(3 << shift); 52 pup |= pull << shift; 53 __raw_writel(pup, reg); 54 55 return 0; 56} 57 58samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip, 59 unsigned int off) 60{ 61 void __iomem *reg = chip->base + 0x08; 62 int shift = off * 2; 63 u32 pup = __raw_readl(reg); 64 65 pup >>= shift; 66 pup &= 0x3; 67 68 return (__force samsung_gpio_pull_t)pup; 69} 70 71int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip, 72 unsigned int off, samsung_gpio_pull_t pull) 73{ 74 switch (pull) { 75 case S3C_GPIO_PULL_NONE: 76 pull = 0x01; 77 break; 78 case S3C_GPIO_PULL_UP: 79 pull = 0x00; 80 break; 81 case S3C_GPIO_PULL_DOWN: 82 pull = 0x02; 83 break; 84 } 85 return samsung_gpio_setpull_updown(chip, off, pull); 86} 87 88samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip, 89 unsigned int off) 90{ 91 samsung_gpio_pull_t pull; 92 93 pull = samsung_gpio_getpull_updown(chip, off); 94 95 switch (pull) { 96 case 0x00: 97 pull = S3C_GPIO_PULL_UP; 98 break; 99 case 0x01: 100 case 0x03: 101 pull = S3C_GPIO_PULL_NONE; 102 break; 103 case 0x02: 104 pull = S3C_GPIO_PULL_DOWN; 105 break; 106 } 107 108 return pull; 109} 110 111static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip, 112 unsigned int off, samsung_gpio_pull_t pull, 113 samsung_gpio_pull_t updown) 114{ 115 void __iomem *reg = chip->base + 0x08; 116 u32 pup = __raw_readl(reg); 117 118 if (pull == updown) 119 pup &= ~(1 << off); 120 else if (pull == S3C_GPIO_PULL_NONE) 121 pup |= (1 << off); 122 else 123 return -EINVAL; 124 125 __raw_writel(pup, reg); 126 return 0; 127} 128 129static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip, 130 unsigned int off, 131 samsung_gpio_pull_t updown) 132{ 133 void __iomem *reg = chip->base + 0x08; 134 u32 pup = __raw_readl(reg); 135 136 pup &= (1 << off); 137 return pup ? S3C_GPIO_PULL_NONE : updown; 138} 139 140samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip, 141 unsigned int off) 142{ 143 return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP); 144} 145 146int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip, 147 unsigned int off, samsung_gpio_pull_t pull) 148{ 149 return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP); 150} 151 152samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip, 153 unsigned int off) 154{ 155 return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN); 156} 157 158int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip, 159 unsigned int off, samsung_gpio_pull_t pull) 160{ 161 return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); 162} 163 164/* 165 * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration. 166 * @chip: The gpio chip that is being configured. 167 * @off: The offset for the GPIO being configured. 168 * @cfg: The configuration value to set. 169 * 170 * This helper deal with the GPIO cases where the control register 171 * has two bits of configuration per gpio, which have the following 172 * functions: 173 * 00 = input 174 * 01 = output 175 * 1x = special function 176 */ 177 178static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip, 179 unsigned int off, unsigned int cfg) 180{ 181 void __iomem *reg = chip->base; 182 unsigned int shift = off * 2; 183 u32 con; 184 185 if (samsung_gpio_is_cfg_special(cfg)) { 186 cfg &= 0xf; 187 if (cfg > 3) 188 return -EINVAL; 189 190 cfg <<= shift; 191 } 192 193 con = __raw_readl(reg); 194 con &= ~(0x3 << shift); 195 con |= cfg; 196 __raw_writel(con, reg); 197 198 return 0; 199} 200 201/* 202 * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read. 203 * @chip: The gpio chip that is being configured. 204 * @off: The offset for the GPIO being configured. 205 * 206 * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which 207 * could be directly passed back to samsung_gpio_setcfg_2bit(), from the 208 * S3C_GPIO_SPECIAL() macro. 209 */ 210 211static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip, 212 unsigned int off) 213{ 214 u32 con; 215 216 con = __raw_readl(chip->base); 217 con >>= off * 2; 218 con &= 3; 219 220 /* this conversion works for IN and OUT as well as special mode */ 221 return S3C_GPIO_SPECIAL(con); 222} 223 224/* 225 * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config. 226 * @chip: The gpio chip that is being configured. 227 * @off: The offset for the GPIO being configured. 228 * @cfg: The configuration value to set. 229 * 230 * This helper deal with the GPIO cases where the control register has 4 bits 231 * of control per GPIO, generally in the form of: 232 * 0000 = Input 233 * 0001 = Output 234 * others = Special functions (dependent on bank) 235 * 236 * Note, since the code to deal with the case where there are two control 237 * registers instead of one, we do not have a separate set of functions for 238 * each case. 239 */ 240 241static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip, 242 unsigned int off, unsigned int cfg) 243{ 244 void __iomem *reg = chip->base; 245 unsigned int shift = (off & 7) * 4; 246 u32 con; 247 248 if (off < 8 && chip->chip.ngpio > 8) 249 reg -= 4; 250 251 if (samsung_gpio_is_cfg_special(cfg)) { 252 cfg &= 0xf; 253 cfg <<= shift; 254 } 255 256 con = __raw_readl(reg); 257 con &= ~(0xf << shift); 258 con |= cfg; 259 __raw_writel(con, reg); 260 261 return 0; 262} 263 264/* 265 * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read. 266 * @chip: The gpio chip that is being configured. 267 * @off: The offset for the GPIO being configured. 268 * 269 * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration 270 * register setting into a value the software can use, such as could be passed 271 * to samsung_gpio_setcfg_4bit(). 272 * 273 * @sa samsung_gpio_getcfg_2bit 274 */ 275 276static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip, 277 unsigned int off) 278{ 279 void __iomem *reg = chip->base; 280 unsigned int shift = (off & 7) * 4; 281 u32 con; 282 283 if (off < 8 && chip->chip.ngpio > 8) 284 reg -= 4; 285 286 con = __raw_readl(reg); 287 con >>= shift; 288 con &= 0xf; 289 290 /* this conversion works for IN and OUT as well as special mode */ 291 return S3C_GPIO_SPECIAL(con); 292} 293 294#ifdef CONFIG_PLAT_S3C24XX 295/* 296 * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A) 297 * @chip: The gpio chip that is being configured. 298 * @off: The offset for the GPIO being configured. 299 * @cfg: The configuration value to set. 300 * 301 * This helper deal with the GPIO cases where the control register 302 * has one bit of configuration for the gpio, where setting the bit 303 * means the pin is in special function mode and unset means output. 304 */ 305 306static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip, 307 unsigned int off, unsigned int cfg) 308{ 309 void __iomem *reg = chip->base; 310 unsigned int shift = off; 311 u32 con; 312 313 if (samsung_gpio_is_cfg_special(cfg)) { 314 cfg &= 0xf; 315 316 /* Map output to 0, and SFN2 to 1 */ 317 cfg -= 1; 318 if (cfg > 1) 319 return -EINVAL; 320 321 cfg <<= shift; 322 } 323 324 con = __raw_readl(reg); 325 con &= ~(0x1 << shift); 326 con |= cfg; 327 __raw_writel(con, reg); 328 329 return 0; 330} 331 332/* 333 * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A) 334 * @chip: The gpio chip that is being configured. 335 * @off: The offset for the GPIO being configured. 336 * 337 * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable 338 * GPIO configuration value. 339 * 340 * @sa samsung_gpio_getcfg_2bit 341 * @sa samsung_gpio_getcfg_4bit 342 */ 343 344static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip, 345 unsigned int off) 346{ 347 u32 con; 348 349 con = __raw_readl(chip->base); 350 con >>= off; 351 con &= 1; 352 con++; 353 354 return S3C_GPIO_SFN(con); 355} 356#endif 357 358static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg, 359 int nr_chips) 360{ 361 for (; nr_chips > 0; nr_chips--, chipcfg++) { 362 if (!chipcfg->set_config) 363 chipcfg->set_config = samsung_gpio_setcfg_4bit; 364 if (!chipcfg->get_config) 365 chipcfg->get_config = samsung_gpio_getcfg_4bit; 366 if (!chipcfg->set_pull) 367 chipcfg->set_pull = samsung_gpio_setpull_updown; 368 if (!chipcfg->get_pull) 369 chipcfg->get_pull = samsung_gpio_getpull_updown; 370 } 371} 372 373struct samsung_gpio_cfg s3c24xx_gpiocfg_default = { 374 .set_config = samsung_gpio_setcfg_2bit, 375 .get_config = samsung_gpio_getcfg_2bit, 376}; 377 378#ifdef CONFIG_PLAT_S3C24XX 379static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = { 380 .set_config = s3c24xx_gpio_setcfg_abank, 381 .get_config = s3c24xx_gpio_getcfg_abank, 382}; 383#endif 384 385static struct samsung_gpio_cfg samsung_gpio_cfgs[] = { 386 [0] = { 387 .cfg_eint = 0x0, 388 }, 389 [1] = { 390 .cfg_eint = 0x3, 391 }, 392 [2] = { 393 .cfg_eint = 0x7, 394 }, 395 [3] = { 396 .cfg_eint = 0xF, 397 }, 398 [4] = { 399 .cfg_eint = 0x0, 400 .set_config = samsung_gpio_setcfg_2bit, 401 .get_config = samsung_gpio_getcfg_2bit, 402 }, 403 [5] = { 404 .cfg_eint = 0x2, 405 .set_config = samsung_gpio_setcfg_2bit, 406 .get_config = samsung_gpio_getcfg_2bit, 407 }, 408 [6] = { 409 .cfg_eint = 0x3, 410 .set_config = samsung_gpio_setcfg_2bit, 411 .get_config = samsung_gpio_getcfg_2bit, 412 }, 413 [7] = { 414 .set_config = samsung_gpio_setcfg_2bit, 415 .get_config = samsung_gpio_getcfg_2bit, 416 }, 417}; 418 419/* 420 * Default routines for controlling GPIO, based on the original S3C24XX 421 * GPIO functions which deal with the case where each gpio bank of the 422 * chip is as following: 423 * 424 * base + 0x00: Control register, 2 bits per gpio 425 * gpio n: 2 bits starting at (2*n) 426 * 00 = input, 01 = output, others mean special-function 427 * base + 0x04: Data register, 1 bit per gpio 428 * bit n: data bit n 429*/ 430 431static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset) 432{ 433 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 434 void __iomem *base = ourchip->base; 435 unsigned long flags; 436 unsigned long con; 437 438 samsung_gpio_lock(ourchip, flags); 439 440 con = __raw_readl(base + 0x00); 441 con &= ~(3 << (offset * 2)); 442 443 __raw_writel(con, base + 0x00); 444 445 samsung_gpio_unlock(ourchip, flags); 446 return 0; 447} 448 449static int samsung_gpiolib_2bit_output(struct gpio_chip *chip, 450 unsigned offset, int value) 451{ 452 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 453 void __iomem *base = ourchip->base; 454 unsigned long flags; 455 unsigned long dat; 456 unsigned long con; 457 458 samsung_gpio_lock(ourchip, flags); 459 460 dat = __raw_readl(base + 0x04); 461 dat &= ~(1 << offset); 462 if (value) 463 dat |= 1 << offset; 464 __raw_writel(dat, base + 0x04); 465 466 con = __raw_readl(base + 0x00); 467 con &= ~(3 << (offset * 2)); 468 con |= 1 << (offset * 2); 469 470 __raw_writel(con, base + 0x00); 471 __raw_writel(dat, base + 0x04); 472 473 samsung_gpio_unlock(ourchip, flags); 474 return 0; 475} 476 477/* 478 * The samsung_gpiolib_4bit routines are to control the gpio banks where 479 * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the 480 * following example: 481 * 482 * base + 0x00: Control register, 4 bits per gpio 483 * gpio n: 4 bits starting at (4*n) 484 * 0000 = input, 0001 = output, others mean special-function 485 * base + 0x04: Data register, 1 bit per gpio 486 * bit n: data bit n 487 * 488 * Note, since the data register is one bit per gpio and is at base + 0x4 489 * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the 490 * state of the output. 491 */ 492 493static int samsung_gpiolib_4bit_input(struct gpio_chip *chip, 494 unsigned int offset) 495{ 496 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 497 void __iomem *base = ourchip->base; 498 unsigned long con; 499 500 con = __raw_readl(base + GPIOCON_OFF); 501 if (ourchip->bitmap_gpio_int & BIT(offset)) 502 con |= 0xf << con_4bit_shift(offset); 503 else 504 con &= ~(0xf << con_4bit_shift(offset)); 505 __raw_writel(con, base + GPIOCON_OFF); 506 507 pr_debug("%s: %p: CON now %08lx\n", __func__, base, con); 508 509 return 0; 510} 511 512static int samsung_gpiolib_4bit_output(struct gpio_chip *chip, 513 unsigned int offset, int value) 514{ 515 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 516 void __iomem *base = ourchip->base; 517 unsigned long con; 518 unsigned long dat; 519 520 con = __raw_readl(base + GPIOCON_OFF); 521 con &= ~(0xf << con_4bit_shift(offset)); 522 con |= 0x1 << con_4bit_shift(offset); 523 524 dat = __raw_readl(base + GPIODAT_OFF); 525 526 if (value) 527 dat |= 1 << offset; 528 else 529 dat &= ~(1 << offset); 530 531 __raw_writel(dat, base + GPIODAT_OFF); 532 __raw_writel(con, base + GPIOCON_OFF); 533 __raw_writel(dat, base + GPIODAT_OFF); 534 535 pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); 536 537 return 0; 538} 539 540/* 541 * The next set of routines are for the case where the GPIO configuration 542 * registers are 4 bits per GPIO but there is more than one register (the 543 * bank has more than 8 GPIOs. 544 * 545 * This case is the similar to the 4 bit case, but the registers are as 546 * follows: 547 * 548 * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs) 549 * gpio n: 4 bits starting at (4*n) 550 * 0000 = input, 0001 = output, others mean special-function 551 * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs) 552 * gpio n: 4 bits starting at (4*n) 553 * 0000 = input, 0001 = output, others mean special-function 554 * base + 0x08: Data register, 1 bit per gpio 555 * bit n: data bit n 556 * 557 * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set 558 * routines we store the 'base + 0x4' address so that these routines see 559 * the data register at ourchip->base + 0x04. 560 */ 561 562static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip, 563 unsigned int offset) 564{ 565 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 566 void __iomem *base = ourchip->base; 567 void __iomem *regcon = base; 568 unsigned long con; 569 570 if (offset > 7) 571 offset -= 8; 572 else 573 regcon -= 4; 574 575 con = __raw_readl(regcon); 576 con &= ~(0xf << con_4bit_shift(offset)); 577 __raw_writel(con, regcon); 578 579 pr_debug("%s: %p: CON %08lx\n", __func__, base, con); 580 581 return 0; 582} 583 584static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip, 585 unsigned int offset, int value) 586{ 587 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 588 void __iomem *base = ourchip->base; 589 void __iomem *regcon = base; 590 unsigned long con; 591 unsigned long dat; 592 unsigned con_offset = offset; 593 594 if (con_offset > 7) 595 con_offset -= 8; 596 else 597 regcon -= 4; 598 599 con = __raw_readl(regcon); 600 con &= ~(0xf << con_4bit_shift(con_offset)); 601 con |= 0x1 << con_4bit_shift(con_offset); 602 603 dat = __raw_readl(base + GPIODAT_OFF); 604 605 if (value) 606 dat |= 1 << offset; 607 else 608 dat &= ~(1 << offset); 609 610 __raw_writel(dat, base + GPIODAT_OFF); 611 __raw_writel(con, regcon); 612 __raw_writel(dat, base + GPIODAT_OFF); 613 614 pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); 615 616 return 0; 617} 618 619#ifdef CONFIG_PLAT_S3C24XX 620/* The next set of routines are for the case of s3c24xx bank a */ 621 622static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset) 623{ 624 return -EINVAL; 625} 626 627static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, 628 unsigned offset, int value) 629{ 630 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 631 void __iomem *base = ourchip->base; 632 unsigned long flags; 633 unsigned long dat; 634 unsigned long con; 635 636 local_irq_save(flags); 637 638 con = __raw_readl(base + 0x00); 639 dat = __raw_readl(base + 0x04); 640 641 dat &= ~(1 << offset); 642 if (value) 643 dat |= 1 << offset; 644 645 __raw_writel(dat, base + 0x04); 646 647 con &= ~(1 << offset); 648 649 __raw_writel(con, base + 0x00); 650 __raw_writel(dat, base + 0x04); 651 652 local_irq_restore(flags); 653 return 0; 654} 655#endif 656 657static void samsung_gpiolib_set(struct gpio_chip *chip, 658 unsigned offset, int value) 659{ 660 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 661 void __iomem *base = ourchip->base; 662 unsigned long flags; 663 unsigned long dat; 664 665 samsung_gpio_lock(ourchip, flags); 666 667 dat = __raw_readl(base + 0x04); 668 dat &= ~(1 << offset); 669 if (value) 670 dat |= 1 << offset; 671 __raw_writel(dat, base + 0x04); 672 673 samsung_gpio_unlock(ourchip, flags); 674} 675 676static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset) 677{ 678 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); 679 unsigned long val; 680 681 val = __raw_readl(ourchip->base + 0x04); 682 val >>= offset; 683 val &= 1; 684 685 return val; 686} 687 688/* 689 * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios 690 * for use with the configuration calls, and other parts of the s3c gpiolib 691 * support code. 692 * 693 * Not all s3c support code will need this, as some configurations of cpu 694 * may only support one or two different configuration options and have an 695 * easy gpio to samsung_gpio_chip mapping function. If this is the case, then 696 * the machine support file should provide its own samsung_gpiolib_getchip() 697 * and any other necessary functions. 698 */ 699 700#ifdef CONFIG_S3C_GPIO_TRACK 701struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END]; 702 703static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip) 704{ 705 unsigned int gpn; 706 int i; 707 708 gpn = chip->chip.base; 709 for (i = 0; i < chip->chip.ngpio; i++, gpn++) { 710 BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios)); 711 s3c_gpios[gpn] = chip; 712 } 713} 714#endif /* CONFIG_S3C_GPIO_TRACK */ 715 716/* 717 * samsung_gpiolib_add() - add the Samsung gpio_chip. 718 * @chip: The chip to register 719 * 720 * This is a wrapper to gpiochip_add() that takes our specific gpio chip 721 * information and makes the necessary alterations for the platform and 722 * notes the information for use with the configuration systems and any 723 * other parts of the system. 724 */ 725 726static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) 727{ 728 struct gpio_chip *gc = &chip->chip; 729 int ret; 730 731 BUG_ON(!chip->base); 732 BUG_ON(!gc->label); 733 BUG_ON(!gc->ngpio); 734 735 spin_lock_init(&chip->lock); 736 737 if (!gc->direction_input) 738 gc->direction_input = samsung_gpiolib_2bit_input; 739 if (!gc->direction_output) 740 gc->direction_output = samsung_gpiolib_2bit_output; 741 if (!gc->set) 742 gc->set = samsung_gpiolib_set; 743 if (!gc->get) 744 gc->get = samsung_gpiolib_get; 745 746#ifdef CONFIG_PM 747 if (chip->pm != NULL) { 748 if (!chip->pm->save || !chip->pm->resume) 749 pr_err("gpio: %s has missing PM functions\n", 750 gc->label); 751 } else 752 pr_err("gpio: %s has no PM function\n", gc->label); 753#endif 754 755 /* gpiochip_add() prints own failure message on error. */ 756 ret = gpiochip_add(gc); 757 if (ret >= 0) 758 s3c_gpiolib_track(chip); 759} 760 761static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, 762 int nr_chips, void __iomem *base) 763{ 764 int i; 765 struct gpio_chip *gc = &chip->chip; 766 767 for (i = 0 ; i < nr_chips; i++, chip++) { 768 /* skip banks not present on SoC */ 769 if (chip->chip.base >= S3C_GPIO_END) 770 continue; 771 772 if (!chip->config) 773 chip->config = &s3c24xx_gpiocfg_default; 774 if (!chip->pm) 775 chip->pm = __gpio_pm(&samsung_gpio_pm_2bit); 776 if ((base != NULL) && (chip->base == NULL)) 777 chip->base = base + ((i) * 0x10); 778 779 if (!gc->direction_input) 780 gc->direction_input = samsung_gpiolib_2bit_input; 781 if (!gc->direction_output) 782 gc->direction_output = samsung_gpiolib_2bit_output; 783 784 samsung_gpiolib_add(chip); 785 } 786} 787 788static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip, 789 int nr_chips, void __iomem *base, 790 unsigned int offset) 791{ 792 int i; 793 794 for (i = 0 ; i < nr_chips; i++, chip++) { 795 chip->chip.direction_input = samsung_gpiolib_2bit_input; 796 chip->chip.direction_output = samsung_gpiolib_2bit_output; 797 798 if (!chip->config) 799 chip->config = &samsung_gpio_cfgs[7]; 800 if (!chip->pm) 801 chip->pm = __gpio_pm(&samsung_gpio_pm_2bit); 802 if ((base != NULL) && (chip->base == NULL)) 803 chip->base = base + ((i) * offset); 804 805 samsung_gpiolib_add(chip); 806 } 807} 808 809/* 810 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config. 811 * @chip: The gpio chip that is being configured. 812 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured. 813 * 814 * This helper deal with the GPIO cases where the control register has 4 bits 815 * of control per GPIO, generally in the form of: 816 * 0000 = Input 817 * 0001 = Output 818 * others = Special functions (dependent on bank) 819 * 820 * Note, since the code to deal with the case where there are two control 821 * registers instead of one, we do not have a separate set of function 822 * (samsung_gpiolib_add_4bit2_chips)for each case. 823 */ 824 825static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip, 826 int nr_chips, void __iomem *base) 827{ 828 int i; 829 830 for (i = 0 ; i < nr_chips; i++, chip++) { 831 chip->chip.direction_input = samsung_gpiolib_4bit_input; 832 chip->chip.direction_output = samsung_gpiolib_4bit_output; 833 834 if (!chip->config) 835 chip->config = &samsung_gpio_cfgs[2]; 836 if (!chip->pm) 837 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); 838 if ((base != NULL) && (chip->base == NULL)) 839 chip->base = base + ((i) * 0x20); 840 841 chip->bitmap_gpio_int = 0; 842 843 samsung_gpiolib_add(chip); 844 } 845} 846 847static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip, 848 int nr_chips) 849{ 850 for (; nr_chips > 0; nr_chips--, chip++) { 851 chip->chip.direction_input = samsung_gpiolib_4bit2_input; 852 chip->chip.direction_output = samsung_gpiolib_4bit2_output; 853 854 if (!chip->config) 855 chip->config = &samsung_gpio_cfgs[2]; 856 if (!chip->pm) 857 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); 858 859 samsung_gpiolib_add(chip); 860 } 861} 862 863int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) 864{ 865 struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip); 866 867 return samsung_chip->irq_base + offset; 868} 869 870#ifdef CONFIG_PLAT_S3C24XX 871static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) 872{ 873 if (offset < 4) { 874 if (soc_is_s3c2412()) 875 return IRQ_EINT0_2412 + offset; 876 else 877 return IRQ_EINT0 + offset; 878 } 879 880 if (offset < 8) 881 return IRQ_EINT4 + offset - 4; 882 883 return -EINVAL; 884} 885#endif 886 887#ifdef CONFIG_ARCH_S3C64XX 888static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin) 889{ 890 return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO; 891} 892 893static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin) 894{ 895 return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO; 896} 897#endif 898 899struct samsung_gpio_chip s3c24xx_gpios[] = { 900#ifdef CONFIG_PLAT_S3C24XX 901 { 902 .config = &s3c24xx_gpiocfg_banka, 903 .chip = { 904 .base = S3C2410_GPA(0), 905 .owner = THIS_MODULE, 906 .label = "GPIOA", 907 .ngpio = 27, 908 .direction_input = s3c24xx_gpiolib_banka_input, 909 .direction_output = s3c24xx_gpiolib_banka_output, 910 }, 911 }, { 912 .chip = { 913 .base = S3C2410_GPB(0), 914 .owner = THIS_MODULE, 915 .label = "GPIOB", 916 .ngpio = 11, 917 }, 918 }, { 919 .chip = { 920 .base = S3C2410_GPC(0), 921 .owner = THIS_MODULE, 922 .label = "GPIOC", 923 .ngpio = 16, 924 }, 925 }, { 926 .chip = { 927 .base = S3C2410_GPD(0), 928 .owner = THIS_MODULE, 929 .label = "GPIOD", 930 .ngpio = 16, 931 }, 932 }, { 933 .chip = { 934 .base = S3C2410_GPE(0), 935 .label = "GPIOE", 936 .owner = THIS_MODULE, 937 .ngpio = 16, 938 }, 939 }, { 940 .chip = { 941 .base = S3C2410_GPF(0), 942 .owner = THIS_MODULE, 943 .label = "GPIOF", 944 .ngpio = 8, 945 .to_irq = s3c24xx_gpiolib_fbank_to_irq, 946 }, 947 }, { 948 .irq_base = IRQ_EINT8, 949 .chip = { 950 .base = S3C2410_GPG(0), 951 .owner = THIS_MODULE, 952 .label = "GPIOG", 953 .ngpio = 16, 954 .to_irq = samsung_gpiolib_to_irq, 955 }, 956 }, { 957 .chip = { 958 .base = S3C2410_GPH(0), 959 .owner = THIS_MODULE, 960 .label = "GPIOH", 961 .ngpio = 15, 962 }, 963 }, 964 /* GPIOS for the S3C2443 and later devices. */ 965 { 966 .base = S3C2440_GPJCON, 967 .chip = { 968 .base = S3C2410_GPJ(0), 969 .owner = THIS_MODULE, 970 .label = "GPIOJ", 971 .ngpio = 16, 972 }, 973 }, { 974 .base = S3C2443_GPKCON, 975 .chip = { 976 .base = S3C2410_GPK(0), 977 .owner = THIS_MODULE, 978 .label = "GPIOK", 979 .ngpio = 16, 980 }, 981 }, { 982 .base = S3C2443_GPLCON, 983 .chip = { 984 .base = S3C2410_GPL(0), 985 .owner = THIS_MODULE, 986 .label = "GPIOL", 987 .ngpio = 15, 988 }, 989 }, { 990 .base = S3C2443_GPMCON, 991 .chip = { 992 .base = S3C2410_GPM(0), 993 .owner = THIS_MODULE, 994 .label = "GPIOM", 995 .ngpio = 2, 996 }, 997 }, 998#endif 999}; 1000 1001/* 1002 * GPIO bank summary: 1003 * 1004 * Bank GPIOs Style SlpCon ExtInt Group 1005 * A 8 4Bit Yes 1 1006 * B 7 4Bit Yes 1 1007 * C 8 4Bit Yes 2 1008 * D 5 4Bit Yes 3 1009 * E 5 4Bit Yes None 1010 * F 16 2Bit Yes 4 [1] 1011 * G 7 4Bit Yes 5 1012 * H 10 4Bit[2] Yes 6 1013 * I 16 2Bit Yes None 1014 * J 12 2Bit Yes None 1015 * K 16 4Bit[2] No None 1016 * L 15 4Bit[2] No None 1017 * M 6 4Bit No IRQ_EINT 1018 * N 16 2Bit No IRQ_EINT 1019 * O 16 2Bit Yes 7 1020 * P 15 2Bit Yes 8 1021 * Q 9 2Bit Yes 9 1022 * 1023 * [1] BANKF pins 14,15 do not form part of the external interrupt sources 1024 * [2] BANK has two control registers, GPxCON0 and GPxCON1 1025 */ 1026 1027static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = { 1028#ifdef CONFIG_ARCH_S3C64XX 1029 { 1030 .chip = { 1031 .base = S3C64XX_GPA(0), 1032 .ngpio = S3C64XX_GPIO_A_NR, 1033 .label = "GPA", 1034 }, 1035 }, { 1036 .chip = { 1037 .base = S3C64XX_GPB(0), 1038 .ngpio = S3C64XX_GPIO_B_NR, 1039 .label = "GPB", 1040 }, 1041 }, { 1042 .chip = { 1043 .base = S3C64XX_GPC(0), 1044 .ngpio = S3C64XX_GPIO_C_NR, 1045 .label = "GPC", 1046 }, 1047 }, { 1048 .chip = { 1049 .base = S3C64XX_GPD(0), 1050 .ngpio = S3C64XX_GPIO_D_NR, 1051 .label = "GPD", 1052 }, 1053 }, { 1054 .config = &samsung_gpio_cfgs[0], 1055 .chip = { 1056 .base = S3C64XX_GPE(0), 1057 .ngpio = S3C64XX_GPIO_E_NR, 1058 .label = "GPE", 1059 }, 1060 }, { 1061 .base = S3C64XX_GPG_BASE, 1062 .chip = { 1063 .base = S3C64XX_GPG(0), 1064 .ngpio = S3C64XX_GPIO_G_NR, 1065 .label = "GPG", 1066 }, 1067 }, { 1068 .base = S3C64XX_GPM_BASE, 1069 .config = &samsung_gpio_cfgs[1], 1070 .chip = { 1071 .base = S3C64XX_GPM(0), 1072 .ngpio = S3C64XX_GPIO_M_NR, 1073 .label = "GPM", 1074 .to_irq = s3c64xx_gpiolib_mbank_to_irq, 1075 }, 1076 }, 1077#endif 1078}; 1079 1080static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = { 1081#ifdef CONFIG_ARCH_S3C64XX 1082 { 1083 .base = S3C64XX_GPH_BASE + 0x4, 1084 .chip = { 1085 .base = S3C64XX_GPH(0), 1086 .ngpio = S3C64XX_GPIO_H_NR, 1087 .label = "GPH", 1088 }, 1089 }, { 1090 .base = S3C64XX_GPK_BASE + 0x4, 1091 .config = &samsung_gpio_cfgs[0], 1092 .chip = { 1093 .base = S3C64XX_GPK(0), 1094 .ngpio = S3C64XX_GPIO_K_NR, 1095 .label = "GPK", 1096 }, 1097 }, { 1098 .base = S3C64XX_GPL_BASE + 0x4, 1099 .config = &samsung_gpio_cfgs[1], 1100 .chip = { 1101 .base = S3C64XX_GPL(0), 1102 .ngpio = S3C64XX_GPIO_L_NR, 1103 .label = "GPL", 1104 .to_irq = s3c64xx_gpiolib_lbank_to_irq, 1105 }, 1106 }, 1107#endif 1108}; 1109 1110static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = { 1111#ifdef CONFIG_ARCH_S3C64XX 1112 { 1113 .base = S3C64XX_GPF_BASE, 1114 .config = &samsung_gpio_cfgs[6], 1115 .chip = { 1116 .base = S3C64XX_GPF(0), 1117 .ngpio = S3C64XX_GPIO_F_NR, 1118 .label = "GPF", 1119 }, 1120 }, { 1121 .config = &samsung_gpio_cfgs[7], 1122 .chip = { 1123 .base = S3C64XX_GPI(0), 1124 .ngpio = S3C64XX_GPIO_I_NR, 1125 .label = "GPI", 1126 }, 1127 }, { 1128 .config = &samsung_gpio_cfgs[7], 1129 .chip = { 1130 .base = S3C64XX_GPJ(0), 1131 .ngpio = S3C64XX_GPIO_J_NR, 1132 .label = "GPJ", 1133 }, 1134 }, { 1135 .config = &samsung_gpio_cfgs[6], 1136 .chip = { 1137 .base = S3C64XX_GPO(0), 1138 .ngpio = S3C64XX_GPIO_O_NR, 1139 .label = "GPO", 1140 }, 1141 }, { 1142 .config = &samsung_gpio_cfgs[6], 1143 .chip = { 1144 .base = S3C64XX_GPP(0), 1145 .ngpio = S3C64XX_GPIO_P_NR, 1146 .label = "GPP", 1147 }, 1148 }, { 1149 .config = &samsung_gpio_cfgs[6], 1150 .chip = { 1151 .base = S3C64XX_GPQ(0), 1152 .ngpio = S3C64XX_GPIO_Q_NR, 1153 .label = "GPQ", 1154 }, 1155 }, { 1156 .base = S3C64XX_GPN_BASE, 1157 .irq_base = IRQ_EINT(0), 1158 .config = &samsung_gpio_cfgs[5], 1159 .chip = { 1160 .base = S3C64XX_GPN(0), 1161 .ngpio = S3C64XX_GPIO_N_NR, 1162 .label = "GPN", 1163 .to_irq = samsung_gpiolib_to_irq, 1164 }, 1165 }, 1166#endif 1167}; 1168 1169/* TODO: cleanup soc_is_* */ 1170static __init int samsung_gpiolib_init(void) 1171{ 1172 /* 1173 * Currently there are two drivers that can provide GPIO support for 1174 * Samsung SoCs. For device tree enabled platforms, the new 1175 * pinctrl-samsung driver is used, providing both GPIO and pin control 1176 * interfaces. For legacy (non-DT) platforms this driver is used. 1177 */ 1178 if (of_have_populated_dt()) 1179 return -ENODEV; 1180 1181 samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); 1182 1183 if (soc_is_s3c24xx()) { 1184 s3c24xx_gpiolib_add_chips(s3c24xx_gpios, 1185 ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO); 1186 } else if (soc_is_s3c64xx()) { 1187 samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit, 1188 ARRAY_SIZE(s3c64xx_gpios_2bit), 1189 S3C64XX_VA_GPIO + 0xE0, 0x20); 1190 samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit, 1191 ARRAY_SIZE(s3c64xx_gpios_4bit), 1192 S3C64XX_VA_GPIO); 1193 samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2, 1194 ARRAY_SIZE(s3c64xx_gpios_4bit2)); 1195 } else { 1196 WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n"); 1197 return -ENODEV; 1198 } 1199 1200 return 0; 1201} 1202core_initcall(samsung_gpiolib_init); 1203 1204int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) 1205{ 1206 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 1207 unsigned long flags; 1208 int offset; 1209 int ret; 1210 1211 if (!chip) 1212 return -EINVAL; 1213 1214 offset = pin - chip->chip.base; 1215 1216 samsung_gpio_lock(chip, flags); 1217 ret = samsung_gpio_do_setcfg(chip, offset, config); 1218 samsung_gpio_unlock(chip, flags); 1219 1220 return ret; 1221} 1222EXPORT_SYMBOL(s3c_gpio_cfgpin); 1223 1224int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, 1225 unsigned int cfg) 1226{ 1227 int ret; 1228 1229 for (; nr > 0; nr--, start++) { 1230 ret = s3c_gpio_cfgpin(start, cfg); 1231 if (ret != 0) 1232 return ret; 1233 } 1234 1235 return 0; 1236} 1237EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range); 1238 1239int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, 1240 unsigned int cfg, samsung_gpio_pull_t pull) 1241{ 1242 int ret; 1243 1244 for (; nr > 0; nr--, start++) { 1245 s3c_gpio_setpull(start, pull); 1246 ret = s3c_gpio_cfgpin(start, cfg); 1247 if (ret != 0) 1248 return ret; 1249 } 1250 1251 return 0; 1252} 1253EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range); 1254 1255unsigned s3c_gpio_getcfg(unsigned int pin) 1256{ 1257 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 1258 unsigned long flags; 1259 unsigned ret = 0; 1260 int offset; 1261 1262 if (chip) { 1263 offset = pin - chip->chip.base; 1264 1265 samsung_gpio_lock(chip, flags); 1266 ret = samsung_gpio_do_getcfg(chip, offset); 1267 samsung_gpio_unlock(chip, flags); 1268 } 1269 1270 return ret; 1271} 1272EXPORT_SYMBOL(s3c_gpio_getcfg); 1273 1274int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull) 1275{ 1276 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 1277 unsigned long flags; 1278 int offset, ret; 1279 1280 if (!chip) 1281 return -EINVAL; 1282 1283 offset = pin - chip->chip.base; 1284 1285 samsung_gpio_lock(chip, flags); 1286 ret = samsung_gpio_do_setpull(chip, offset, pull); 1287 samsung_gpio_unlock(chip, flags); 1288 1289 return ret; 1290} 1291EXPORT_SYMBOL(s3c_gpio_setpull); 1292 1293samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin) 1294{ 1295 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); 1296 unsigned long flags; 1297 int offset; 1298 u32 pup = 0; 1299 1300 if (chip) { 1301 offset = pin - chip->chip.base; 1302 1303 samsung_gpio_lock(chip, flags); 1304 pup = samsung_gpio_do_getpull(chip, offset); 1305 samsung_gpio_unlock(chip, flags); 1306 } 1307 1308 return (__force samsung_gpio_pull_t)pup; 1309} 1310EXPORT_SYMBOL(s3c_gpio_getpull); 1311 1312#ifdef CONFIG_PLAT_S3C24XX 1313unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) 1314{ 1315 unsigned long flags; 1316 unsigned long misccr; 1317 1318 local_irq_save(flags); 1319 misccr = __raw_readl(S3C24XX_MISCCR); 1320 misccr &= ~clear; 1321 misccr ^= change; 1322 __raw_writel(misccr, S3C24XX_MISCCR); 1323 local_irq_restore(flags); 1324 1325 return misccr; 1326} 1327EXPORT_SYMBOL(s3c2410_modify_misccr); 1328#endif 1329