[ARM] S3C: Add new GPIO configuration calls
authorBen Dooks <ben-linux@fluff.org>
Fri, 31 Oct 2008 16:14:34 +0000 (16:14 +0000)
committerBen Dooks <ben-linux@fluff.org>
Mon, 15 Dec 2008 23:34:15 +0000 (23:34 +0000)
Add new GPIO configuration calls that mesh with the
new gpiolib support.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
arch/arm/mach-s3c2410/include/mach/gpio-core.h [new file with mode: 0644]
arch/arm/mach-s3c6400/include/mach/gpio-core.h [new file with mode: 0644]
arch/arm/plat-s3c/Kconfig
arch/arm/plat-s3c/Makefile
arch/arm/plat-s3c/gpio-config.c [new file with mode: 0644]
arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h [new file with mode: 0644]
arch/arm/plat-s3c/include/plat/gpio-cfg.h [new file with mode: 0644]
arch/arm/plat-s3c/include/plat/gpio-core.h
arch/arm/plat-s3c24xx/gpiolib.c
arch/arm/plat-s3c64xx/Kconfig
arch/arm/plat-s3c64xx/gpiolib.c

diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-core.h b/arch/arm/mach-s3c2410/include/mach/gpio-core.h
new file mode 100644 (file)
index 0000000..6c9fbb9
--- /dev/null
@@ -0,0 +1,34 @@
+/* arch/arm/mach-s3c24100/include/mach/gpio-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C2410 - GPIO core 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.
+*/
+
+#ifndef __ASM_ARCH_GPIO_CORE_H
+#define __ASM_ARCH_GPIO_CORE_H __FILE__
+
+#include <plat/gpio-core.h>
+#include <mach/regs-gpio.h>
+
+extern struct s3c_gpio_chip s3c24xx_gpios[];
+
+static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
+{
+       struct s3c_gpio_chip *chip;
+
+       if (pin > S3C2410_GPG10)
+               return NULL;
+
+       chip = &s3c24xx_gpios[pin/32];
+       return (S3C2410_GPIO_OFFSET(pin) > chip->chip.ngpio) ? chip : NULL;
+}
+
+#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/gpio-core.h b/arch/arm/mach-s3c6400/include/mach/gpio-core.h
new file mode 100644 (file)
index 0000000..d89aae6
--- /dev/null
@@ -0,0 +1,21 @@
+/* arch/arm/mach-s3c6400/include/mach/gpio-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIO core 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.
+*/
+
+#ifndef __ASM_ARCH_GPIO_CORE_H
+#define __ASM_ARCH_GPIO_CORE_H __FILE__
+
+/* currently we just include the platform support */
+#include <plat/gpio-core.h>
+
+#endif /* __ASM_ARCH_GPIO_CORE_H */
index 77fc38f51874754ac7168ac71edb5fea76ab4950..45e62cba595c94244cc661e3e4685814313d7ec1 100644 (file)
@@ -120,6 +120,33 @@ config S3C_GPIO_TRACK
          Internal configuration option to enable the s3c specific gpio
          chip tracking if the platform requires it.
 
+config S3C_GPIO_PULL_UPDOWN
+       bool
+       help
+         Internal configuration to enable the correct GPIO pull helper
+
+config S3C_GPIO_PULL_DOWN
+       bool
+       help
+         Internal configuration to enable the correct GPIO pull helper
+
+config S3C_GPIO_PULL_UP
+       bool
+       help
+         Internal configuration to enable the correct GPIO pull helper
+
+config S3C_GPIO_CFG_S3C24XX
+       bool
+       help
+         Internal configuration to enable S3C24XX style GPIO configuration
+         functions.
+
+config S3C_GPIO_CFG_S3C64XX
+       bool
+       help
+         Internal configuration to enable S3C64XX style GPIO configuration
+         functions.
+
 # device definitions to compile in
 
 config S3C_DEV_HSMMC
index 4d0299aef7ca5cc151e1bb21690a5771ae276cb4..68a3451a2d9dbf4088cb7d806636dbe4c26a857a 100644 (file)
@@ -16,6 +16,7 @@ obj-y                         += time.o
 obj-y                          += clock.o
 obj-y                          += pwm-clock.o
 obj-y                          += gpio.o
+obj-y                          += gpio-config.o
 
 # devices
 
diff --git a/arch/arm/plat-s3c/gpio-config.c b/arch/arm/plat-s3c/gpio-config.c
new file mode 100644 (file)
index 0000000..7642b97
--- /dev/null
@@ -0,0 +1,163 @@
+/* linux/arch/arm/plat-s3c/gpio-config.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO configuration core
+ *
+ * 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/gpio.h>
+#include <linux/io.h>
+
+#include <mach/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
+{
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned long flags;
+       int offset;
+       int ret;
+
+       if (!chip)
+               return -EINVAL;
+
+       offset = pin - chip->chip.base;
+
+       local_irq_save(flags);
+       ret = s3c_gpio_do_setcfg(chip, offset, config);
+       local_irq_restore(flags);
+
+       return ret;
+}
+
+int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
+{
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned long flags;
+       int offset, ret;
+
+       if (!chip)
+               return -EINVAL;
+
+       offset = pin - chip->chip.base;
+
+       local_irq_save(flags);
+       ret = s3c_gpio_do_setpull(chip, offset, pull);
+       local_irq_restore(flags);
+
+       return ret;
+}
+
+#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
+int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
+                                 unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = off;
+       u32 con;
+
+       if (s3c_gpio_is_cfg_special(cfg)) {
+               cfg &= 0xf;
+
+               /* Map output to 0, and SFN2 to 1 */
+               cfg -= 1;
+               if (cfg > 1)
+                       return -EINVAL;
+
+               cfg <<= shift;
+       }
+
+       con = __raw_readl(reg);
+       con &= ~(0x1 << shift);
+       con |= cfg;
+       __raw_writel(con, reg);
+
+       return 0;
+}
+
+int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
+                           unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = off * 2;
+       u32 con;
+
+       if (s3c_gpio_is_cfg_special(cfg)) {
+               cfg &= 0xf;
+               if (cfg > 3)
+                       return -EINVAL;
+
+               cfg <<= shift;
+       }
+
+       con = __raw_readl(reg);
+       con &= ~(0x3 << shift);
+       con |= cfg;
+       __raw_writel(con, reg);
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
+int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+                                unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = (off & 7) * 4;
+       u32 con;
+
+       if (off < 8 && chip->chip.ngpio >= 8)
+               reg -= 4;
+
+       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;
+}
+#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
+
+#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
+int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
+                           unsigned int off, s3c_gpio_pull_t pull)
+{
+       void __iomem *reg = chip->base + 0x08;
+       int shift = off * 2;
+       u32 pup;
+
+       pup = __raw_readl(reg);
+       pup &= ~(3 << shift);
+       pup |= pull << shift;
+       __raw_writel(pup, reg);
+
+       return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
+                                       unsigned int off)
+{
+       void __iomem *reg = chip->base + 0x08;
+       int shift = off * 2;
+       u32 pup = __raw_readl(reg);
+
+       pup >>= shift;
+       pup &= 0x3;
+       return (__force s3c_gpio_pull_t)pup;
+}
+#endif
diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h
new file mode 100644 (file)
index 0000000..652e2bb
--- /dev/null
@@ -0,0 +1,176 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO pin configuration helper 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.
+*/
+
+/* This is meant for core cpu support, machine or other driver files
+ * should not be including this header.
+ */
+
+#ifndef __PLAT_GPIO_CFG_HELPERS_H
+#define __PLAT_GPIO_CFG_HELPERS_H __FILE__
+
+/* As a note, all gpio configuration functions are entered exclusively, either
+ * with the relevant lock held or the system prevented from doing anything else
+ * by disabling interrupts.
+*/
+
+static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
+                                    unsigned int off, unsigned int config)
+{
+       return (chip->config->set_config)(chip, off, config);
+}
+
+static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
+                                     unsigned int off, s3c_gpio_pull_t pull)
+{
+       return (chip->config->set_pull)(chip, off, pull);
+}
+
+/**
+ * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
+ * @chip: The gpio chip that is being configured.
+ * @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 two bits of configuration per gpio, which have the following
+ * functions:
+ *     00 = input
+ *     01 = output
+ *     1x = special function
+*/
+extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
+                                  unsigned int off, unsigned int cfg);
+
+/**
+ * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @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 one bit of configuration for the gpio, where setting the bit
+ * means the pin is in special function mode and unset means output.
+*/
+extern int s3c_gpio_setcfg_s3c24xx_a(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.
+ * @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)
+ *
+ * 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(struct s3c_gpio_chip *chip,
+                                       unsigned int off, unsigned int cfg);
+
+
+/* Pull-{up,down} resistor controls.
+ *
+ * S3C2410,S3C2440,S3C24A0 = Pull-UP,
+ * S3C2412,S3C2413 = Pull-Down
+ * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef]
+ * S3C2443 = Pull-Both [not same as S3C6400]
+ */
+
+/**
+ * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with one
+ * bit configuring the presence of a pull-up resistor.
+ */
+extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+                               unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none
+ * @chip: The gpio chip that is being configured
+ * @off: The offset for the GPIO being configured
+ * @param: pull: The pull mode being requested
+ *
+ * This is a helper function for the case where we have GPIOs with one
+ * bit configuring the presence of a pull-down resistor.
+ */
+extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
+                                 unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with two
+ * bits configuring the presence of a pull resistor, in the following
+ * order:
+ *     00 = No pull resistor connected
+ *     01 = Pull-up resistor connected
+ *     10 = Pull-down resistor connected
+ */
+extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
+                                  unsigned int off, s3c_gpio_pull_t pull);
+
+
+/**
+ * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-{up,down} resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_upown.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
+                                              unsigned int off);
+
+/**
+ * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with two
+ * bits configuring the presence of a pull resistor, in the following
+ * order:
+ *     00 = Pull-up resistor connected
+ *     10 = Pull-down resistor connected
+ *     x1 = No pull up resistor
+ */
+extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
+                                   unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors
+ * @chip: The gpio chip that the GPIO pin belongs to.
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-{up,down} resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_upown.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_s3c24xx(struct s3c_gpio_chip *chip,
+                                               unsigned int off);
+
+#endif /* __PLAT_GPIO_CFG_HELPERS_H */
+
diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg.h b/arch/arm/plat-s3c/include/plat/gpio-cfg.h
new file mode 100644 (file)
index 0000000..29cd6a8
--- /dev/null
@@ -0,0 +1,110 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO pin configuration
+ *
+ * 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.
+*/
+
+/* This file contains the necessary definitions to get the basic gpio
+ * pin configuration done such as setting a pin to input or output or
+ * changing the pull-{up,down} configurations.
+ */
+
+/* Note, this interface is being added to the s3c64xx arch first and will
+ * be added to the s3c24xx systems later.
+ */
+
+#ifndef __PLAT_GPIO_CFG_H
+#define __PLAT_GPIO_CFG_H __FILE__
+
+typedef unsigned int __bitwise__ s3c_gpio_pull_t;
+
+/* forward declaration if gpio-core.h hasn't been included */
+struct s3c_gpio_chip;
+
+/**
+ * struct s3c_gpio_cfg GPIO configuration
+ * @cfg_eint: Configuration setting when used for external interrupt source
+ * @get_pull: Read the current pull configuration for the GPIO
+ * @set_pull: Set the current pull configuraiton for the GPIO
+ * @set_config: Set the current configuration for the GPIO
+ * @get_config: Read the current configuration for the GPIO
+ *
+ * Each chip can have more than one type of GPIO bank available and some
+ * have different capabilites even when they have the same control register
+ * layouts. Provide an point to vector control routine and provide any
+ * per-bank configuration information that other systems such as the
+ * external interrupt code will need.
+ */
+struct s3c_gpio_cfg {
+       unsigned int    cfg_eint;
+
+       s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs);
+       int             (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,
+                                   s3c_gpio_pull_t pull);
+
+       unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);
+       int      (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,
+                              unsigned config);
+};
+
+#define S3C_GPIO_SPECIAL_MARK  (0xfffffff0)
+#define S3C_GPIO_SPECIAL(x)    (S3C_GPIO_SPECIAL_MARK | (x))
+
+/* Defines for generic pin configurations */
+#define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0))
+#define S3C_GPIO_OUTPUT        (S3C_GPIO_SPECIAL(1))
+#define S3C_GPIO_SFN(x)        (S3C_GPIO_SPECIAL(x))
+
+#define s3c_gpio_is_cfg_special(_cfg) \
+       (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
+
+/**
+ * s3c_gpio_cfgpin() - Change the GPIO function of a pin.
+ * @pin pin The pin number to configure.
+ * @pin to The configuration for the pin's function.
+ *
+ * Configure which function is actually connected to the external
+ * pin, such as an gpio input, output or some form of special function
+ * connected to an internal peripheral block.
+ */
+extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
+
+/* Define values for the pull-{up,down} available for each gpio pin.
+ *
+ * These values control the state of the weak pull-{up,down} resistors
+ * available on most pins on the S3C series. Not all chips support both
+ * up or down settings, and it may be dependant on the chip that is being
+ * used to whether the particular mode is available.
+ */
+#define S3C_GPIO_PULL_NONE     ((__force s3c_gpio_pull_t)0x00)
+#define S3C_GPIO_PULL_DOWN     ((__force s3c_gpio_pull_t)0x01)
+#define S3C_GPIO_PULL_UP       ((__force s3c_gpio_pull_t)0x02)
+
+/**
+ * s3c_gpio_setpull() - set the state of a gpio pin pull resistor
+ * @pin: The pin number to configure the pull resistor.
+ * @pull: The configuration for the pull resistor.
+ *
+ * This function sets the state of the pull-{up,down} resistor for the
+ * specified pin. It will return 0 if successfull, or a negative error
+ * code if the pin cannot support the requested pull setting.
+*/
+extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_getpull() - get the pull resistor state of a gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the pull resistor value for the specified pin.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
+
+#endif /* __PLAT_GPIO_CFG_H */
index ad68b32a7f9d7646a7e65e66ac3f92613ca0a8b5..2fc60a580ac89241428678f9e8dbdea57c4a4fa6 100644 (file)
  * specific code.
 */
 
+struct s3c_gpio_cfg;
+
 /**
  * struct s3c_gpio_chip - wrapper for specific implementation of gpio
  * @chip: The chip structure to be exported via gpiolib.
  * @base: The base pointer to the gpio configuration registers.
+ * @config: special function and pull-resistor control information.
  *
  * This wrapper provides the necessary information for the Samsung
  * specific gpios being registered with gpiolib.
  */
 struct s3c_gpio_chip {
        struct gpio_chip        chip;
+       struct s3c_gpio_cfg     *config;
        void __iomem            *base;
 };
 
@@ -48,7 +52,6 @@ static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc)
  */
 extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
 
-
 /* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
  * for use with the configuration calls, and other parts of the s3c gpiolib
  * support code.
@@ -65,8 +68,10 @@ extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
 
 static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
 {
-       return s3c_gpios[chip];
+       return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
 }
 #else
+/* machine specific code should provide s3c_gpiolib_getchip */
+
 static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
 #endif
index 9785a8fb4809532cfd0175b586a933cef8a3e59f..f95c6c9d9f1a95ad93d64bc17ca8f7f9b894b59f 100644 (file)
@@ -59,7 +59,7 @@ static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
        return 0;
 }
 
-static struct s3c_gpio_chip gpios[] = {
+struct s3c_gpio_chip s3c24xx_gpios[] = {
        [0] = {
                .base   = S3C24XX_GPIO_BASE(S3C2410_GPA0),
                .chip   = {
@@ -129,10 +129,10 @@ static struct s3c_gpio_chip gpios[] = {
 
 static __init int s3c24xx_gpiolib_init(void)
 {
-       struct s3c_gpio_chip *chip = gpios;
+       struct s3c_gpio_chip *chip = s3c24xx_gpios;
        int gpn;
 
-       for (gpn = 0; gpn < ARRAY_SIZE(gpios); gpn++, chip++)
+       for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++)
                s3c_gpiolib_add(chip);
 
        return 0;
index 3df2ec19d08a6933cac9b1ec3e8576fa7cb8e994..842200abeb3668da5b31665bef4411a7394fd5da 100644 (file)
@@ -15,6 +15,9 @@ config PLAT_S3C64XX
        select NO_IOPORT
        select ARCH_REQUIRE_GPIOLIB
        select S3C_GPIO_TRACK
+       select S3C_GPIO_PULL_UPDOWN
+       select S3C_GPIO_CFG_S3C24XX
+       select S3C_GPIO_CFG_S3C64XX
        help
          Base platform code for any Samsung S3C64XX device
 
index 28ba23502bce4e7cb00710435d373de4928782c0..cc62941d7b5c53f1721be0671abd35286c29639b 100644 (file)
 
 #include <mach/map.h>
 #include <mach/gpio.h>
+#include <mach/gpio-core.h>
 
-#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
 #include <plat/regs-gpio.h>
 
 /* GPIO bank summary:
 
 #define con_4bit_shift(__off) ((__off) * 4)
 
+#if 1
+#define gpio_dbg(x...) do { } while(0)
+#else
+#define gpio_dbg(x...) printk(KERN_DEBUG ## x)
+#endif
+
 /* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where
  * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
  * following example:
@@ -77,6 +85,8 @@ static int s3c64xx_gpiolib_4bit_input(struct gpio_chip *chip, unsigned offset)
        con &= ~(0xf << con_4bit_shift(offset));
        __raw_writel(con, base + OFF_GPCON);
 
+       gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
+
        return 0;
 }
 
@@ -102,6 +112,8 @@ static int s3c64xx_gpiolib_4bit_output(struct gpio_chip *chip,
        __raw_writel(con, base + OFF_GPCON);
        __raw_writel(dat, base + OFF_GPDAT);
 
+       gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
        return 0;
 }
 
@@ -142,6 +154,8 @@ static int s3c64xx_gpiolib_4bit2_input(struct gpio_chip *chip, unsigned offset)
        con &= ~(0xf << con_4bit_shift(offset));
        __raw_writel(con, regcon);
 
+       gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
+
        return 0;
 
 }
@@ -174,12 +188,35 @@ static int s3c64xx_gpiolib_4bit2_output(struct gpio_chip *chip,
        __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 struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
+       .cfg_eint       = 7,
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
+       .cfg_eint       = 3,
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
 static struct s3c_gpio_chip gpio_4bit[] = {
        {
                .base   = S3C64XX_GPA_BASE,
+               .config = &gpio_4bit_cfg_eint0111,
                .chip   = {
                        .base   = S3C64XX_GPA(0),
                        .ngpio  = S3C64XX_GPIO_A_NR,
@@ -187,6 +224,7 @@ static struct s3c_gpio_chip gpio_4bit[] = {
                },
        }, {
                .base   = S3C64XX_GPB_BASE,
+               .config = &gpio_4bit_cfg_eint0111,
                .chip   = {
                        .base   = S3C64XX_GPB(0),
                        .ngpio  = S3C64XX_GPIO_B_NR,
@@ -194,6 +232,7 @@ static struct s3c_gpio_chip gpio_4bit[] = {
                },
        }, {
                .base   = S3C64XX_GPC_BASE,
+               .config = &gpio_4bit_cfg_eint0111,
                .chip   = {
                        .base   = S3C64XX_GPC(0),
                        .ngpio  = S3C64XX_GPIO_C_NR,
@@ -201,6 +240,7 @@ static struct s3c_gpio_chip gpio_4bit[] = {
                },
        }, {
                .base   = S3C64XX_GPD_BASE,
+               .config = &gpio_4bit_cfg_eint0111,
                .chip   = {
                        .base   = S3C64XX_GPD(0),
                        .ngpio  = S3C64XX_GPIO_D_NR,
@@ -208,6 +248,7 @@ static struct s3c_gpio_chip gpio_4bit[] = {
                },
        }, {
                .base   = S3C64XX_GPE_BASE,
+               .config = &gpio_4bit_cfg_noint,
                .chip   = {
                        .base   = S3C64XX_GPE(0),
                        .ngpio  = S3C64XX_GPIO_E_NR,
@@ -215,6 +256,7 @@ static struct s3c_gpio_chip gpio_4bit[] = {
                },
        }, {
                .base   = S3C64XX_GPG_BASE,
+               .config = &gpio_4bit_cfg_eint0111,
                .chip   = {
                        .base   = S3C64XX_GPG(0),
                        .ngpio  = S3C64XX_GPIO_G_NR,
@@ -222,6 +264,7 @@ static struct s3c_gpio_chip gpio_4bit[] = {
                },
        }, {
                .base   = S3C64XX_GPM_BASE,
+               .config = &gpio_4bit_cfg_eint0011,
                .chip   = {
                        .base   = S3C64XX_GPM(0),
                        .ngpio  = S3C64XX_GPIO_M_NR,
@@ -233,6 +276,7 @@ static struct s3c_gpio_chip gpio_4bit[] = {
 static struct s3c_gpio_chip gpio_4bit2[] = {
        {
                .base   = S3C64XX_GPH_BASE + 0x4,
+               .config = &gpio_4bit_cfg_eint0111,
                .chip   = {
                        .base   = S3C64XX_GPH(0),
                        .ngpio  = S3C64XX_GPIO_H_NR,
@@ -240,6 +284,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = {
                },
        }, {
                .base   = S3C64XX_GPK_BASE + 0x4,
+               .config = &gpio_4bit_cfg_noint,
                .chip   = {
                        .base   = S3C64XX_GPK(0),
                        .ngpio  = S3C64XX_GPIO_K_NR,
@@ -247,6 +292,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = {
                },
        }, {
                .base   = S3C64XX_GPL_BASE + 0x4,
+               .config = &gpio_4bit_cfg_eint0011,
                .chip   = {
                        .base   = S3C64XX_GPL(0),
                        .ngpio  = S3C64XX_GPIO_L_NR,
@@ -255,9 +301,30 @@ static struct s3c_gpio_chip gpio_4bit2[] = {
        },
 };
 
+static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
+       .set_config     = s3c_gpio_setcfg_s3c24xx,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
+       .cfg_eint       = 2,
+       .set_config     = s3c_gpio_setcfg_s3c24xx,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
+       .cfg_eint       = 3,
+       .set_config     = s3c_gpio_setcfg_s3c24xx,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
 static struct s3c_gpio_chip gpio_2bit[] = {
        {
                .base   = S3C64XX_GPF_BASE,
+               .config = &gpio_2bit_cfg_eint11,
                .chip   = {
                        .base   = S3C64XX_GPF(0),
                        .ngpio  = S3C64XX_GPIO_F_NR,
@@ -265,6 +332,7 @@ static struct s3c_gpio_chip gpio_2bit[] = {
                },
        }, {
                .base   = S3C64XX_GPI_BASE,
+               .config = &gpio_2bit_cfg_noint,
                .chip   = {
                        .base   = S3C64XX_GPI(0),
                        .ngpio  = S3C64XX_GPIO_I_NR,
@@ -272,6 +340,7 @@ static struct s3c_gpio_chip gpio_2bit[] = {
                },
        }, {
                .base   = S3C64XX_GPJ_BASE,
+               .config = &gpio_2bit_cfg_noint,
                .chip   = {
                        .base   = S3C64XX_GPJ(0),
                        .ngpio  = S3C64XX_GPIO_J_NR,
@@ -279,6 +348,7 @@ static struct s3c_gpio_chip gpio_2bit[] = {
                },
        }, {
                .base   = S3C64XX_GPN_BASE,
+               .config = &gpio_2bit_cfg_eint10,
                .chip   = {
                        .base   = S3C64XX_GPN(0),
                        .ngpio  = S3C64XX_GPIO_N_NR,
@@ -286,6 +356,7 @@ static struct s3c_gpio_chip gpio_2bit[] = {
                },
        }, {
                .base   = S3C64XX_GPO_BASE,
+               .config = &gpio_2bit_cfg_eint11,
                .chip   = {
                        .base   = S3C64XX_GPO(0),
                        .ngpio  = S3C64XX_GPIO_O_NR,
@@ -293,6 +364,7 @@ static struct s3c_gpio_chip gpio_2bit[] = {
                },
        }, {
                .base   = S3C64XX_GPP_BASE,
+               .config = &gpio_2bit_cfg_eint11,
                .chip   = {
                        .base   = S3C64XX_GPP(0),
                        .ngpio  = S3C64XX_GPIO_P_NR,
@@ -300,6 +372,7 @@ static struct s3c_gpio_chip gpio_2bit[] = {
                },
        }, {
                .base   = S3C64XX_GPQ_BASE,
+               .config = &gpio_2bit_cfg_eint11,
                .chip   = {
                        .base   = S3C64XX_GPQ(0),
                        .ngpio  = S3C64XX_GPIO_Q_NR,