Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.9.4.
   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