From c27a3856662f69c830b4ebdff0ef0ebe3a117e77 Mon Sep 17 00:00:00 2001
From: kfx <kfx@rock-chips.com>
Date: Fri, 28 Sep 2012 13:07:02 +0800
Subject: [PATCH] gpio_request: add request callback function(rk2928: iomux:
 set gpio mode)

---
 arch/arm/mach-rk2928/iomux.c         | 60 ++++++++++++++++++++++++++--
 arch/arm/plat-rk/include/plat/gpio.h | 14 +------
 drivers/gpio/gpio-rk30.c             | 13 +++++-
 3 files changed, 71 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-rk2928/iomux.c b/arch/arm/mach-rk2928/iomux.c
index 774835541ed5..81da2cb6ffdb 100755
--- a/arch/arm/mach-rk2928/iomux.c
+++ b/arch/arm/mach-rk2928/iomux.c
@@ -21,9 +21,10 @@
 
 #include <mach/io.h>  
 #include <mach/iomux.h>
+#include <mach/gpio.h>
 
 //#define IOMUX_DBG
-
+#define INVALID_MUX     "invalid"
 static struct mux_config rk30_muxs[] = {
 /*
  *	 description				mux  mode   mux	  mux  
@@ -34,6 +35,8 @@ MUX_CFG(GPIO0A0_I2C0_SCL_NAME,                  GPIO0A,    0,    1,    0,    DEF
 MUX_CFG(GPIO0A1_I2C0_SDA_NAME,                  GPIO0A,    2,    1,    0,    DEFAULT)
 MUX_CFG(GPIO0A2_I2C1_SCL_NAME,                  GPIO0A,    4,    1,    0,    DEFAULT)
 MUX_CFG(GPIO0A3_I2C1_SDA_NAME,                  GPIO0A,    6,    1,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
 MUX_CFG(GPIO0A6_I2C3_SCL_HDMI_DDCSCL_NAME,      GPIO0A,    12,    2,    0,    DEFAULT)
 MUX_CFG(GPIO0A7_I2C3_SDA_HDMI_DDCSDA_NAME,      GPIO0A,    14,    2,    0,    DEFAULT)
 
@@ -53,6 +56,8 @@ MUX_CFG(GPIO0C1_UART0_SIN_NAME,                 GPIO0C,    2,    1,    0,    DEF
 MUX_CFG(GPIO0C2_UART0_RTSN_NAME,                GPIO0C,    4,    1,    0,    DEFAULT)
 MUX_CFG(GPIO0C3_UART0_CTSN_NAME,                GPIO0C,    6,    1,    0,    DEFAULT)
 MUX_CFG(GPIO0C4_HDMI_CECSDA_NAME,               GPIO0C,    8,    1,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
 MUX_CFG(GPIO0C7_NAND_CS1_NAME,                  GPIO0C,    14,    1,    0,    DEFAULT)
 
 //gpio0d
@@ -138,11 +143,49 @@ MUX_CFG(GPIO2C7_LCDC0_D21_LCDC1_D21_UART2_SOUT_NAME,GPIO2C,    14,    2,    0,
 //gpio2d
 MUX_CFG(GPIO2D0_LCDC0_D22_LCDC1_D22_NAME,       GPIO2D,    0,    2,    0,    DEFAULT)
 MUX_CFG(GPIO2D1_LCDC0_D23_LCDC1_D23_NAME,       GPIO2D,    2,    2,    0,    DEFAULT)
-
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+
+//gpio3a
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+//gpio3b
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
 //gpio3c
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
 MUX_CFG(GPIO3C1_OTG_DRVVBUS_NAME,               GPIO3C,    2,    1,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
 
 //gpio3d
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
+MUX_CFG(INVALID_MUX,                  GPIO0A,    0,    0,    0,    DEFAULT)
 MUX_CFG(GPIO3D7_TESTCLK_OUT_NAME,               GPIO3D,    14,    1,    0,    DEFAULT)
 };     
 
@@ -151,6 +194,9 @@ void rk30_mux_set(struct mux_config *cfg)
 {
 	int regValue = 0;
 	int mask;
+
+        if(strcmp(cfg->name, INVALID_MUX) == 0)
+                return;
 	
 	mask = (((1<<(cfg->interleave))-1)<<cfg->offset) << 16;
 	regValue |= mask;
@@ -255,7 +301,15 @@ void rk30_mux_api_set(char *name, unsigned int mode)
 	}
 }
 EXPORT_SYMBOL(rk30_mux_api_set);
-
+void gpio_set_iomux(int gpio)
+{
+        struct mux_config *cfg;
+        
+        cfg = &rk30_muxs[(gpio - PIN_BASE)];
+        
+        rk30_mux_set(cfg);
+}
+EXPORT_SYMBOL(gpio_set_iomux);
 
 int rk30_mux_api_get(char *name)
 {
diff --git a/arch/arm/plat-rk/include/plat/gpio.h b/arch/arm/plat-rk/include/plat/gpio.h
index b00c059984d7..0d2fea57589b 100644
--- a/arch/arm/plat-rk/include/plat/gpio.h
+++ b/arch/arm/plat-rk/include/plat/gpio.h
@@ -36,17 +36,6 @@ struct gpio_config{
 #endif	
 };
 
-#if defined(CONFIG_ARCH_RK2928)
-#define PORT_BASE       RK2928_PIN0_PA0
-#elif defined(CONFIG_ARCH_RK30)
-#define PORT_BASE       RK30_PIN0_PA0
-#elif defined(CONFIG_ARCH_RK29)
-#define PORT_BASE       RK29_PIN0_PA0
-#else
-#error	"Arm system type is not support"
-#endif	
-
-
 struct port_config {
         union{
                 struct irq_config irq;
@@ -60,10 +49,11 @@ static inline struct port_config get_port_config(unsigned int value)
         struct port_config port;
 
         port.v = value;
-        port.gpio = PORT_BASE + port.io.bank * 32 + (port.io.goff - 0x0A) * 8 + port.io.off;
+        port.gpio = PIN_BASE + port.io.bank * 32 + (port.io.goff - 0x0A) * 8 + port.io.off;
 
         return port;
 }
+void gpio_set_iomux(int gpio);
 
 typedef enum eGPIOPinLevel
 {
diff --git a/drivers/gpio/gpio-rk30.c b/drivers/gpio/gpio-rk30.c
index 5a4b95174b28..3b742c5fb293 100755
--- a/drivers/gpio/gpio-rk30.c
+++ b/drivers/gpio/gpio-rk30.c
@@ -75,6 +75,7 @@ static int rk30_gpiolib_direction_output(struct gpio_chip *chip,unsigned offset,
 static int rk30_gpiolib_direction_input(struct gpio_chip *chip,unsigned offset);
 static int rk30_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, unsigned enable);
 static int rk30_gpiolib_to_irq(struct gpio_chip *chip,unsigned offset);
+static int rk30_gpiolib_request(struct gpio_chip *chip, unsigned offset);
 
 #define RK30_GPIO_BANK(ID)			\
 	{								\
@@ -84,6 +85,7 @@ static int rk30_gpiolib_to_irq(struct gpio_chip *chip,unsigned offset);
 			.direction_output = rk30_gpiolib_direction_output, \
 			.get              = rk30_gpiolib_get,		\
 			.set              = rk30_gpiolib_set,		\
+			.request          = rk30_gpiolib_request,	\
 			.pull_updown      = rk30_gpiolib_pull_updown,	\
 			.dbg_show         = rk30_gpiolib_dbg_show,	\
 			.to_irq           = rk30_gpiolib_to_irq,	\
@@ -301,7 +303,16 @@ static int rk30_gpiolib_direction_input(struct gpio_chip *chip,unsigned offset)
 	spin_unlock_irqrestore(&bank->lock, flags);
 	return 0;
 }
-
+static int rk30_gpiolib_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct rk30_gpio_bank *bank = to_rk30_gpio_bank(chip);
+        int gpio = offset + PIN_BASE + bank->id * 32;
+        
+#ifdef CONFIG_ARCH_RK2928
+        gpio_set_iomux(gpio); 
+#endif
+        return 0;
+}
 
 static int rk30_gpiolib_get(struct gpio_chip *chip, unsigned offset)
 {
-- 
2.34.1