All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] ARM: S5P6440: Add S5P6440 GPIO support
@ 2010-01-14 11:27 Kukjin Kim
  2010-01-14 15:28 ` Niels Langendorff
  0 siblings, 1 reply; 5+ messages in thread
From: Kukjin Kim @ 2010-01-14 11:27 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: ben-linux, Kukjin Kim, Aditya Pratap Sharma, Atul Dahiya

This patch adds Samsung's S5P6440 GPIO support.

Signed-off-by: Aditya Pratap Sharma <adityaps@samsung.com>
Signed-off-by: Atul Dahiya <atul.dahiya@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 arch/arm/mach-s5p6440/include/mach/gpio-core.h |   40 +++
 arch/arm/mach-s5p6440/include/mach/regs-gpio.h |   54 ++++
 arch/arm/mach-s5p6440/s5p6440-gpio.c           |  313 ++++++++++++++++++++++++
 3 files changed, 407 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s5p6440/include/mach/regs-gpio.h
 create mode 100644 arch/arm/mach-s5p6440/s5p6440-gpio.c

diff --git a/arch/arm/mach-s5p6440/include/mach/gpio-core.h b/arch/arm/mach-s5p6440/include/mach/gpio-core.h
index ff7fb30..328c153 100644
--- a/arch/arm/mach-s5p6440/include/mach/gpio-core.h
+++ b/arch/arm/mach-s5p6440/include/mach/gpio-core.h
@@ -16,4 +16,44 @@
 /* currently we just include the platform support */
 #include <plat/gpio-core.h>
 
+#define con_4bit_shift(__off) ((__off) * 4)
+
+/* various helper functions added which are specific to PLAT_S5P platform */
+
+/**
+ * samsung_gpiolib_set_cfg - S5P style GPIO configuration
+ * @chip: The gpio chip that is being configured.
+ * @nr_chips: no of chips (gpio ports) for the GPIO being configured.
+*/
+extern void samsung_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips);
+
+/**
+ * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependant on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a seperate set of function
+ * (samsung_gpiolib_add_4bit2_chips)for each case.
+ */
+extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
+					   int nr_chips);
+extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
+					    int nr_chips);
+
+/**
+ * s5p6440_gpio_setcfg_4bit_rbank - S5P64XX 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured (always R).
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ */
+extern int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
+					  unsigned int off, unsigned int cfg);
 #endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/regs-gpio.h b/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
new file mode 100644
index 0000000..82ff753
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - GPIO register definitions
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+
+/* Base addresses for each of the banks */
+#define S5P6440_GPA_BASE		(S5P_VA_GPIO + 0x0000)
+#define S5P6440_GPB_BASE		(S5P_VA_GPIO + 0x0020)
+#define S5P6440_GPC_BASE		(S5P_VA_GPIO + 0x0040)
+#define S5P6440_GPF_BASE		(S5P_VA_GPIO + 0x00A0)
+#define S5P6440_GPG_BASE		(S5P_VA_GPIO + 0x00C0)
+#define S5P6440_GPH_BASE		(S5P_VA_GPIO + 0x00E0)
+#define S5P6440_GPI_BASE		(S5P_VA_GPIO + 0x0100)
+#define S5P6440_GPJ_BASE		(S5P_VA_GPIO + 0x0120)
+#define S5P6440_GPN_BASE		(S5P_VA_GPIO + 0x0830)
+#define S5P6440_GPP_BASE		(S5P_VA_GPIO + 0x0160)
+#define S5P6440_GPR_BASE		(S5P_VA_GPIO + 0x0290)
+#define S5P6440_EINT0CON0		(S5P_VA_GPIO + 0x900)
+#define S5P6440_EINT0FLTCON0		(S5P_VA_GPIO + 0x910)
+#define S5P6440_EINT0FLTCON1		(S5P_VA_GPIO + 0x914)
+#define S5P6440_EINT0MASK		(S5P_VA_GPIO + 0x920)
+#define S5P6440_EINT0PEND		(S5P_VA_GPIO + 0x924)
+
+/* for LCD */
+#define S5P6440_SPCON_LCD_SEL_RGB	(1 << 0)
+#define S5P6440_SPCON_LCD_SEL_MASK	(3 << 0)
+
+/* These set of macros are not really useful for the
+ * GPF/GPI/GPJ/GPN/GPP,
+ * useful for others set of GPIO's (4 bit)
+ */
+#define S5P6440_GPIO_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+#define S5P6440_GPIO_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S5P6440_GPIO_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+
+/* Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
+ * */
+#define S5P6440_GPIO2_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S5P6440_GPIO2_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
+#define S5P6440_GPIO2_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5p6440/s5p6440-gpio.c b/arch/arm/mach-s5p6440/s5p6440-gpio.c
new file mode 100644
index 0000000..aca73a3
--- /dev/null
+++ b/arch/arm/mach-s5p6440/s5p6440-gpio.c
@@ -0,0 +1,313 @@
+/* arch/arm/mach-s5p6440/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/gpio-core.h>
+#include <mach/regs-gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+#define GPIODAT_OFF	(0x04)
+#define con_4bit_shift(__off) ((__off) * 4)
+
+/* 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",
+		},
+	},
+};
+
+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);
+
+	samsung_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);
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] ARM: S5P6440: Add S5P6440 GPIO support
  2010-01-14 11:27 [PATCH 1/2] ARM: S5P6440: Add S5P6440 GPIO support Kukjin Kim
@ 2010-01-14 15:28 ` Niels Langendorff
  2010-01-15  1:36   ` Ben Dooks
  2010-01-15 11:35   ` Kukjin Kim
  0 siblings, 2 replies; 5+ messages in thread
From: Niels Langendorff @ 2010-01-14 15:28 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-samsung-soc, ben-linux, Aditya Pratap Sharma, Atul Dahiya

Make sure this patch includes the fixes I supplied in the Samsung CQ 
database APTT00000153

Kukjin Kim wrote:
> This patch adds Samsung's S5P6440 GPIO support.
> 
> Signed-off-by: Aditya Pratap Sharma <adityaps@samsung.com>
> Signed-off-by: Atul Dahiya <atul.dahiya@samsung.com>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
> ---
>  arch/arm/mach-s5p6440/include/mach/gpio-core.h |   40 +++
>  arch/arm/mach-s5p6440/include/mach/regs-gpio.h |   54 ++++
>  arch/arm/mach-s5p6440/s5p6440-gpio.c           |  313 ++++++++++++++++++++++++
>  3 files changed, 407 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-s5p6440/include/mach/regs-gpio.h
>  create mode 100644 arch/arm/mach-s5p6440/s5p6440-gpio.c
> 
> diff --git a/arch/arm/mach-s5p6440/include/mach/gpio-core.h b/arch/arm/mach-s5p6440/include/mach/gpio-core.h
> index ff7fb30..328c153 100644
> --- a/arch/arm/mach-s5p6440/include/mach/gpio-core.h
> +++ b/arch/arm/mach-s5p6440/include/mach/gpio-core.h
> @@ -16,4 +16,44 @@
>  /* currently we just include the platform support */
>  #include <plat/gpio-core.h>
>  
> +#define con_4bit_shift(__off) ((__off) * 4)
> +
> +/* various helper functions added which are specific to PLAT_S5P platform */
> +
> +/**
> + * samsung_gpiolib_set_cfg - S5P style GPIO configuration
> + * @chip: The gpio chip that is being configured.
> + * @nr_chips: no of chips (gpio ports) for the GPIO being configured.
> +*/
> +extern void samsung_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips);
> +
> +/**
> + * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
> + * @chip: The gpio chip that is being configured.
> + * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
> + *
> + * This helper deal with the GPIO cases where the control register has 4 bits
> + * of control per GPIO, generally in the form of:
> + * 0000 = Input
> + * 0001 = Output
> + * others = Special functions (dependant on bank)
> + *
> + * Note, since the code to deal with the case where there are two control
> + * registers instead of one, we do not have a seperate set of function
> + * (samsung_gpiolib_add_4bit2_chips)for each case.
> + */
> +extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
> +					   int nr_chips);
> +extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
> +					    int nr_chips);
> +
> +/**
> + * s5p6440_gpio_setcfg_4bit_rbank - S5P64XX 4bit single register GPIO config.
> + * @chip: The gpio chip that is being configured (always R).
> + * @off: The offset for the GPIO being configured.
> + * @cfg: The configuration value to set.
> + *
> + */
> +extern int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
> +					  unsigned int off, unsigned int cfg);
>  #endif /* __ASM_ARCH_GPIO_CORE_H */
> diff --git a/arch/arm/mach-s5p6440/include/mach/regs-gpio.h b/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
> new file mode 100644
> index 0000000..82ff753
> --- /dev/null
> +++ b/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
> @@ -0,0 +1,54 @@
> +/* linux/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
> + *
> + * Copyright (c) 2009 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com/
> + *
> + * S5P6440 - GPIO register definitions
> + *
> + * 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.
> + */
> +
> +#ifndef __ASM_ARCH_REGS_GPIO_H
> +#define __ASM_ARCH_REGS_GPIO_H __FILE__
> +
> +#include <mach/map.h>
> +
> +/* Base addresses for each of the banks */
> +#define S5P6440_GPA_BASE		(S5P_VA_GPIO + 0x0000)
> +#define S5P6440_GPB_BASE		(S5P_VA_GPIO + 0x0020)
> +#define S5P6440_GPC_BASE		(S5P_VA_GPIO + 0x0040)
> +#define S5P6440_GPF_BASE		(S5P_VA_GPIO + 0x00A0)
> +#define S5P6440_GPG_BASE		(S5P_VA_GPIO + 0x00C0)
> +#define S5P6440_GPH_BASE		(S5P_VA_GPIO + 0x00E0)
> +#define S5P6440_GPI_BASE		(S5P_VA_GPIO + 0x0100)
> +#define S5P6440_GPJ_BASE		(S5P_VA_GPIO + 0x0120)
> +#define S5P6440_GPN_BASE		(S5P_VA_GPIO + 0x0830)
> +#define S5P6440_GPP_BASE		(S5P_VA_GPIO + 0x0160)
> +#define S5P6440_GPR_BASE		(S5P_VA_GPIO + 0x0290)
> +#define S5P6440_EINT0CON0		(S5P_VA_GPIO + 0x900)
> +#define S5P6440_EINT0FLTCON0		(S5P_VA_GPIO + 0x910)
> +#define S5P6440_EINT0FLTCON1		(S5P_VA_GPIO + 0x914)
> +#define S5P6440_EINT0MASK		(S5P_VA_GPIO + 0x920)
> +#define S5P6440_EINT0PEND		(S5P_VA_GPIO + 0x924)
> +
> +/* for LCD */
> +#define S5P6440_SPCON_LCD_SEL_RGB	(1 << 0)
> +#define S5P6440_SPCON_LCD_SEL_MASK	(3 << 0)
> +
> +/* These set of macros are not really useful for the
> + * GPF/GPI/GPJ/GPN/GPP,
> + * useful for others set of GPIO's (4 bit)
> + */
> +#define S5P6440_GPIO_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
> +#define S5P6440_GPIO_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
> +#define S5P6440_GPIO_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
> +
> +/* Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
> + * */
> +#define S5P6440_GPIO2_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
> +#define S5P6440_GPIO2_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
> +#define S5P6440_GPIO2_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
> +
> +#endif /* __ASM_ARCH_REGS_GPIO_H */
> diff --git a/arch/arm/mach-s5p6440/s5p6440-gpio.c b/arch/arm/mach-s5p6440/s5p6440-gpio.c
> new file mode 100644
> index 0000000..aca73a3
> --- /dev/null
> +++ b/arch/arm/mach-s5p6440/s5p6440-gpio.c
> @@ -0,0 +1,313 @@
> +/* arch/arm/mach-s5p6440/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/gpio-core.h>
> +#include <mach/regs-gpio.h>
> +#include <plat/gpio-cfg.h>
> +#include <plat/gpio-cfg-helpers.h>
> +
> +#define GPIODAT_OFF	(0x04)
> +#define con_4bit_shift(__off) ((__off) * 4)
> +
> +/* 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",
> +		},
> +	},
> +};
> +
> +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);
> +
> +	samsung_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);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] ARM: S5P6440: Add S5P6440 GPIO support
  2010-01-14 15:28 ` Niels Langendorff
@ 2010-01-15  1:36   ` Ben Dooks
  2010-01-15  7:33     ` Niels Langendorff
  2010-01-15 11:35   ` Kukjin Kim
  1 sibling, 1 reply; 5+ messages in thread
From: Ben Dooks @ 2010-01-15  1:36 UTC (permalink / raw)
  To: Niels Langendorff
  Cc: Kukjin Kim, linux-samsung-soc, ben-linux, Aditya Pratap Sharma,
	Atul Dahiya

On Thu, Jan 14, 2010 at 04:28:48PM +0100, Niels Langendorff wrote:
> Make sure this patch includes the fixes I supplied in the Samsung CQ  
> database APTT00000153

Which would those be, other mortals don't have access to that information.

[snip]
 
-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] ARM: S5P6440: Add S5P6440 GPIO support
  2010-01-15  1:36   ` Ben Dooks
@ 2010-01-15  7:33     ` Niels Langendorff
  0 siblings, 0 replies; 5+ messages in thread
From: Niels Langendorff @ 2010-01-15  7:33 UTC (permalink / raw)
  To: Ben Dooks
  Cc: Kukjin Kim, linux-samsung-soc, ben-linux, Aditya Pratap Sharma,
	Atul Dahiya

[-- Attachment #1: Type: text/plain, Size: 327 bytes --]

See attached files from Samsungs CQ database

Ben Dooks wrote:
> On Thu, Jan 14, 2010 at 04:28:48PM +0100, Niels Langendorff wrote:
>> Make sure this patch includes the fixes I supplied in the Samsung CQ  
>> database APTT00000153
> 
> Which would those be, other mortals don't have access to that information.
> 
> [snip]
>  

[-- Attachment #2: patch.4bit2_s3c64xx_gpiolib --]
[-- Type: text/plain, Size: 740 bytes --]

diff -Naur linux-base/arch/arm/plat-s3c64xx/gpiolib.c linux/arch/arm/plat-s3c64xx/gpiolib.c
--- linux-base/arch/arm/plat-s3c64xx/gpiolib.c	2009-06-25 17:02:41.000000000 +0200
+++ linux/arch/arm/plat-s3c64xx/gpiolib.c	2009-06-26 11:11:18.000000000 +0200
@@ -168,15 +168,16 @@
 	void __iomem *regcon = base;
 	unsigned long con;
 	unsigned long dat;
+	unsigned con_offset = offset;
 
-	if (offset > 7)
-		offset -= 8;
+	if (con_offset > 7)
+		con_offset -= 8;
 	else
 		regcon -= 4;
 
 	con = __raw_readl(regcon);
-	con &= ~(0xf << con_4bit_shift(offset));
-	con |= 0x1 << con_4bit_shift(offset);
+	con &= ~(0xf << con_4bit_shift(con_offset));
+	con |= 0x1 << con_4bit_shift(con_offset);
 
 	dat = __raw_readl(base + OFF_GPDAT);
 	if (value)

[-- Attachment #3: patch.rbank_patched_based_on_r14 --]
[-- Type: text/plain, Size: 3511 bytes --]

diff -Naur linux-2.6-samsung-base/arch/arm/plat-s3c/gpio-config.c linux-2.6-samsung/arch/arm/plat-s3c/gpio-config.c
--- linux-2.6-samsung-base/arch/arm/plat-s3c/gpio-config.c	2009-06-17 10:54:11.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s3c/gpio-config.c	2009-06-17 10:57:39.000000000 +0200
@@ -132,6 +132,44 @@
 #endif
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
+int s3c_gpio_setcfg_s3c64xx_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;
+}
+
 int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
 				 unsigned int off, unsigned int cfg)
 {
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h linux-2.6-samsung/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h
--- linux-2.6-samsung-base/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	2009-06-17 10:54:11.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	2009-06-17 10:59:12.000000000 +0200
@@ -72,6 +72,28 @@
 				     unsigned int off, unsigned int cfg);
 
 /**
+ * s3c_gpio_setcfg_s3c64xx_4bit_rbank - S3C64XX 4bit single register GPIO R config.
+ * @chip: The gpio chip that is being configured (always R).
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ *	0000 = Input
+ *	0001 = Output
+ *	others = Special functions (dependant on bank)
+ *
+ * A special function is implemented for the R bank because of the GPIO gaps
+ * in this bank
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a seperate set of functions for
+ * each case.
+*/
+extern int s3c_gpio_setcfg_s3c64xx_4bit_rbank(struct s3c_gpio_chip *chip,
+					unsigned int off, unsigned int cfg);
+
+/**
  * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
  * @chip: The gpio chip that is being configured.
  * @off: The offset for the GPIO being configured.
@@ -83,6 +105,8 @@
  *	0001 = Output
  *	others = Special functions (dependant on bank)
  *
+ * Note, do not use this function for register bank R
+ *
  * Note, since the code to deal with the case where there are two control
  * registers instead of one, we do not have a seperate set of functions for
  * each case.
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s5p64xx/gpiolib.c linux-2.6-samsung/arch/arm/plat-s5p64xx/gpiolib.c
--- linux-2.6-samsung-base/arch/arm/plat-s5p64xx/gpiolib.c	2009-06-17 10:54:07.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s5p64xx/gpiolib.c	2009-06-17 11:01:00.000000000 +0200
@@ -210,7 +210,7 @@
 
 static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
 	.cfg_eint	= 3,
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit_rbank,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
 	.set_pin	= s3c_gpio_setpin_updown,

[-- Attachment #4: patch.rbank_s5p6440 --]
[-- Type: text/plain, Size: 6678 bytes --]

diff -Naur linux-2.6-samsung-base/arch/arm/plat-s3c/gpio-config.c linux-2.6-samsung/arch/arm/plat-s3c/gpio-config.c
--- linux-2.6-samsung-base/arch/arm/plat-s3c/gpio-config.c	2009-06-08 09:53:44.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s3c/gpio-config.c	2009-06-26 13:56:14.000000000 +0200
@@ -132,6 +132,44 @@
 #endif
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
+int s3c_gpio_setcfg_s3c64xx_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;
+}
+
 int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
 				 unsigned int off, unsigned int cfg)
 {
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h linux-2.6-samsung/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h
--- linux-2.6-samsung-base/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	2009-06-08 09:53:44.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	2009-06-26 13:55:58.000000000 +0200
@@ -72,6 +72,28 @@
 				     unsigned int off, unsigned int cfg);
 
 /**
+ * s3c_gpio_setcfg_s3c64xx_4bit_rbank - S3C64XX 4bit single register GPIO R config.
+ * @chip: The gpio chip that is being configured (always R).
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ *	0000 = Input
+ *	0001 = Output
+ *	others = Special functions (dependant on bank)
+ *
+ * A special function is implemented for the R bank because of the GPIO gaps
+ * in this bank
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a seperate set of functions for
+ * each case.
+*/
+extern int s3c_gpio_setcfg_s3c64xx_4bit_rbank(struct s3c_gpio_chip *chip,
+					unsigned int off, unsigned int cfg);
+
+/**
  * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
  * @chip: The gpio chip that is being configured.
  * @off: The offset for the GPIO being configured.
@@ -83,6 +105,8 @@
  *	0001 = Output
  *	others = Special functions (dependant on bank)
  *
+ * Note, do not use this function for register bank R
+ *
  * Note, since the code to deal with the case where there are two control
  * registers instead of one, we do not have a seperate set of functions for
  * each case.
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s5p64xx/gpiolib.c linux-2.6-samsung/arch/arm/plat-s5p64xx/gpiolib.c
--- linux-2.6-samsung-base/arch/arm/plat-s5p64xx/gpiolib.c	2009-06-08 09:53:44.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s5p64xx/gpiolib.c	2009-06-26 13:55:41.000000000 +0200
@@ -160,6 +160,38 @@
 
 }
 
+static int s5p64xx_gpiolib_rbank_4bit2_input(struct gpio_chip *chip, unsigned 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);
+
+	gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
+
+	return 0;
+}
+
 static int s5p64xx_gpiolib_4bit2_output(struct gpio_chip *chip,
 				       unsigned offset, int value)
 {
@@ -168,15 +200,61 @@
 	void __iomem *regcon = base;
 	unsigned long con;
 	unsigned long dat;
+	unsigned con_offset = offset;
 
-	if (offset > 7)
-		offset -= 8;
+	if (con_offset > 7)
+		con_offset -= 8;
 	else
 		regcon -= 4;
 
 	con = __raw_readl(regcon);
-	con &= ~(0xf << con_4bit_shift(offset));
-	con |= 0x1 << con_4bit_shift(offset);
+	con &= ~(0xf << con_4bit_shift(con_offset));
+	con |= 0x1 << con_4bit_shift(con_offset);
+
+	dat = __raw_readl(base + OFF_GPDAT);
+	if (value)
+		dat |= 1 << offset;
+	else
+		dat &= ~(1 << offset);
+
+	__raw_writel(dat, base + OFF_GPDAT);
+	__raw_writel(con, regcon);
+	__raw_writel(dat, base + OFF_GPDAT);
+
+	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+	return 0;
+}
+
+static int s5p64xx_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
+				       unsigned 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 + OFF_GPDAT);
 	if (value)
@@ -210,7 +288,7 @@
 
 static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
 	.cfg_eint	= 3,
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit_rbank,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
 	.set_pin	= s3c_gpio_setpin_updown,
@@ -261,7 +339,11 @@
 			.ngpio	= S5P64XX_GPIO_H_NR,
 			.label	= "GPH",
 		},
-	}, {
+	}, 
+};
+
+static struct s3c_gpio_chip gpio_rbank_4bit2[] = {
+	{
 		.base	= S5P64XX_GPR_BASE + 0x4,
 		.config	= &gpio_4bit_cfg_eint0011,
 		.chip	= {
@@ -351,6 +433,12 @@
 	chip->chip.direction_output = s5p64xx_gpiolib_4bit2_output;
 }
 
+static __init void s5p64xx_gpiolib_add_rbank_4bit2(struct s3c_gpio_chip *chip)
+{
+	chip->chip.direction_input = s5p64xx_gpiolib_rbank_4bit2_input;
+	chip->chip.direction_output = s5p64xx_gpiolib_rbank_4bit2_output;
+}
+
 static __init void s5p64xx_gpiolib_add(struct s3c_gpio_chip *chips,
 				       int nr_chips,
 				       void (*fn)(struct s3c_gpio_chip *))
@@ -370,6 +458,9 @@
 	s5p64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
 			    s5p64xx_gpiolib_add_4bit2);
 
+	s5p64xx_gpiolib_add(gpio_rbank_4bit2, ARRAY_SIZE(gpio_rbank_4bit2),
+			    s5p64xx_gpiolib_add_rbank_4bit2);
+
 	s5p64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit), NULL);
 
 	return 0;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH 1/2] ARM: S5P6440: Add S5P6440 GPIO support
  2010-01-14 15:28 ` Niels Langendorff
  2010-01-15  1:36   ` Ben Dooks
@ 2010-01-15 11:35   ` Kukjin Kim
  1 sibling, 0 replies; 5+ messages in thread
From: Kukjin Kim @ 2010-01-15 11:35 UTC (permalink / raw)
  To: 'Niels Langendorff'
  Cc: linux-samsung-soc, ben-linux, 'Aditya Pratap Sharma',
	'Atul Dahiya'

Niels Langendorff wrote:
> Make sure this patch includes the fixes I supplied in the Samsung CQ
> database APTT00000153

Hello Niels,

Yes, the fixes has been included in this gpio patches.

> Kukjin Kim wrote:
> > This patch adds Samsung's S5P6440 GPIO support.
> >


Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
System LSI Division, SAMSUNG ELECTRONICS CO., LTD.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-01-15 11:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-14 11:27 [PATCH 1/2] ARM: S5P6440: Add S5P6440 GPIO support Kukjin Kim
2010-01-14 15:28 ` Niels Langendorff
2010-01-15  1:36   ` Ben Dooks
2010-01-15  7:33     ` Niels Langendorff
2010-01-15 11:35   ` Kukjin Kim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.