Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

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