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