* [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.