/* arch/arm/mach-s5p6440/gpio.c
 *
 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
 * 		http://www.samsung.com/
 *
 * S5P6440 - GPIOlib support
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <mach/map.h>
#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>

/* GPIO bank summary:
*
* Bank	GPIOs	Style	SlpCon	ExtInt Group
* A	6	4Bit	Yes	1
* B	7	4Bit	Yes	1
* C	8	4Bit	Yes	2
* F	2	2Bit	Yes	4 [1]
* G	7	4Bit	Yes	5
* H	10	4Bit[2]	Yes	6
* I	16	2Bit	Yes	None
* J	12	2Bit	Yes	None
* N	16	2Bit	No	IRQ_EINT
* P	8	2Bit	Yes	8
* R	15	4Bit[2]	Yes	8
*
* [1] BANKF pins 14,15 do not form part of the external interrupt sources
* [2] BANK has two control registers, GPxCON0 and GPxCON1
*/

static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
					     unsigned int offset)
{
	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
	void __iomem *base = ourchip->base;
	void __iomem *regcon = base;
	unsigned long con;

	switch (offset) {
	case 6:
		offset += 1;
	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		regcon -= 4;
		break;
	default:
		offset -= 7;
		break;
	}

	con = __raw_readl(regcon);
	con &= ~(0xf << con_4bit_shift(offset));
	__raw_writel(con, regcon);

	return 0;
}

static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
					      unsigned int offset, int value)
{
	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
	void __iomem *base = ourchip->base;
	void __iomem *regcon = base;
	unsigned long con;
	unsigned long dat;
	unsigned con_offset  = offset;

	switch (con_offset) {
	case 6:
		con_offset += 1;
	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		regcon -= 4;
		break;
	default:
		con_offset -= 7;
		break;
	}

	con = __raw_readl(regcon);
	con &= ~(0xf << con_4bit_shift(con_offset));
	con |= 0x1 << con_4bit_shift(con_offset);

	dat = __raw_readl(base + GPIODAT_OFF);
	if (value)
		dat |= 1 << offset;
	else
		dat &= ~(1 << offset);

	__raw_writel(con, regcon);
	__raw_writel(dat, base + GPIODAT_OFF);

	return 0;
}

int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
				   unsigned int off, unsigned int cfg)
{
	void __iomem *reg = chip->base;
	unsigned int shift;
	u32 con;

	switch (off) {
	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		shift = (off & 7) * 4;
		reg -= 4;
		break;
	case 6:
		shift = ((off + 1) & 7) * 4;
		reg -= 4;
	default:
		shift = ((off + 1) & 7) * 4;
		break;
	}

	if (s3c_gpio_is_cfg_special(cfg)) {
		cfg &= 0xf;
		cfg <<= shift;
	}

	con = __raw_readl(reg);
	con &= ~(0xf << shift);
	con |= cfg;
	__raw_writel(con, reg);

	return 0;
}

static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
	{
		.cfg_eint	= 0,
	}, {
		.cfg_eint	= 7,
	}, {
		.cfg_eint	= 3,
		.set_config	= s5p6440_gpio_setcfg_4bit_rbank,
	}, {
		.cfg_eint	= 0,
		.set_config	= s3c_gpio_setcfg_s3c24xx,
	}, {
		.cfg_eint	= 2,
		.set_config	= s3c_gpio_setcfg_s3c24xx,
	}, {
		.cfg_eint	= 3,
		.set_config	= s3c_gpio_setcfg_s3c24xx,
	},
};

static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
	{
		.base	= S5P6440_GPA_BASE,
		.config	= &s5p6440_gpio_cfgs[1],
		.chip	= {
			.base	= S5P6440_GPA(0),
			.ngpio	= S5P6440_GPIO_A_NR,
			.label	= "GPA",
		},
	}, {
		.base	= S5P6440_GPB_BASE,
		.config	= &s5p6440_gpio_cfgs[1],
		.chip	= {
			.base	= S5P6440_GPB(0),
			.ngpio	= S5P6440_GPIO_B_NR,
			.label	= "GPB",
		},
	}, {
		.base	= S5P6440_GPC_BASE,
		.config	= &s5p6440_gpio_cfgs[1],
		.chip	= {
			.base	= S5P6440_GPC(0),
			.ngpio	= S5P6440_GPIO_C_NR,
			.label	= "GPC",
		},
	}, {
		.base	= S5P6440_GPG_BASE,
		.config	= &s5p6440_gpio_cfgs[1],
		.chip	= {
			.base	= S5P6440_GPG(0),
			.ngpio	= S5P6440_GPIO_G_NR,
			.label	= "GPG",
		},
	},
};

static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
	{
		.base	= S5P6440_GPH_BASE + 0x4,
		.config	= &s5p6440_gpio_cfgs[1],
		.chip	= {
			.base	= S5P6440_GPH(0),
			.ngpio	= S5P6440_GPIO_H_NR,
			.label	= "GPH",
		},
	},
};

static struct s3c_gpio_chip gpio_rbank_4bit2[] = {
	{
		.base	= S5P6440_GPR_BASE + 0x4,
		.config	= &s5p6440_gpio_cfgs[2],
		.chip	= {
			.base	= S5P6440_GPR(0),
			.ngpio	= S5P6440_GPIO_R_NR,
			.label	= "GPR",
		},
	},
};

static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
	{
		.base	= S5P6440_GPF_BASE,
		.config	= &s5p6440_gpio_cfgs[5],
		.chip	= {
			.base	= S5P6440_GPF(0),
			.ngpio	= S5P6440_GPIO_F_NR,
			.label	= "GPF",
		},
	}, {
		.base	= S5P6440_GPI_BASE,
		.config	= &s5p6440_gpio_cfgs[3],
		.chip	= {
			.base	= S5P6440_GPI(0),
			.ngpio	= S5P6440_GPIO_I_NR,
			.label	= "GPI",
		},
	}, {
		.base	= S5P6440_GPJ_BASE,
		.config	= &s5p6440_gpio_cfgs[3],
		.chip	= {
			.base	= S5P6440_GPJ(0),
			.ngpio	= S5P6440_GPIO_J_NR,
			.label	= "GPJ",
		},
	}, {
		.base	= S5P6440_GPN_BASE,
		.config	= &s5p6440_gpio_cfgs[4],
		.chip	= {
			.base	= S5P6440_GPN(0),
			.ngpio	= S5P6440_GPIO_N_NR,
			.label	= "GPN",
		},
	}, {
		.base	= S5P6440_GPP_BASE,
		.config	= &s5p6440_gpio_cfgs[5],
		.chip	= {
			.base	= S5P6440_GPP(0),
			.ngpio	= S5P6440_GPIO_P_NR,
			.label	= "GPP",
		},
	},
};

void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
{
	for (; nr_chips > 0; nr_chips--, chipcfg++) {
		if (!chipcfg->set_config)
			chipcfg->set_config	= s3c_gpio_setcfg_s3c64xx_4bit;
		if (!chipcfg->set_pull)
			chipcfg->set_pull	= s3c_gpio_setpull_updown;
		if (!chipcfg->get_pull)
			chipcfg->get_pull	= s3c_gpio_getpull_updown;
	}
}

static void __init s5p6440_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
						int nr_chips)
{
	for (; nr_chips > 0; nr_chips--, chip++) {
		chip->chip.direction_input = s5p6440_gpiolib_rbank_4bit2_input;
		chip->chip.direction_output =
					s5p6440_gpiolib_rbank_4bit2_output;
		s3c_gpiolib_add(chip);
	}
}

static int __init s5p6440_gpiolib_init(void)
{
	struct s3c_gpio_chip *chips = s5p6440_gpio_2bit;
	int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit);

	s5p6440_gpiolib_set_cfg(s5p6440_gpio_cfgs,
				ARRAY_SIZE(s5p6440_gpio_cfgs));

	for (; nr_chips > 0; nr_chips--, chips++)
		s3c_gpiolib_add(chips);

	samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit,
				ARRAY_SIZE(s5p6440_gpio_4bit));

	samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
				ARRAY_SIZE(s5p6440_gpio_4bit2));

	s5p6440_gpio_add_rbank_4bit2(gpio_rbank_4bit2,
				ARRAY_SIZE(gpio_rbank_4bit2));

	return 0;
}
arch_initcall(s5p6440_gpiolib_init);
