From: kfx <kfx@rock-chips.com>
Date: Mon, 6 Jun 2011 09:02:32 +0000 (+0800)
Subject: update i2c driver: support gpio i2c
X-Git-Tag: firefly_0821_release~10231
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=cd1871b8eb68ef46677f9977ef579cdfc20a3c7e;p=firefly-linux-kernel-4.4.55.git

update i2c driver: support gpio i2c
---

diff --git a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c
index 84fbbec17a03..a723e625b37c 100755
--- a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c
+++ b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c
@@ -50,6 +50,7 @@
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/i2c-gpio.h>
 
 #include "devices.h"
 #include "../../../drivers/input/touchscreen/xpt2046_cbn_ts.h"
@@ -519,31 +520,51 @@ struct bq27510_platform_data bq27510_info = {
 *****************************************************************************************/
 static int rk29_i2c0_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 	rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_I2C0_SCL);
 	rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_I2C0_SDA);
+#else
+	rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_GPIO2B7);
+	rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_GPIO2B6);
+#endif
 	return 0;
 }
 
 static int rk29_i2c1_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 	rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_I2C1_SCL);
 	rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_I2C1_SDA);
+#else
+	rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_GPIO1A7);
+	rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_GPIO1A6);
+#endif
 	return 0;
 }
 static int rk29_i2c2_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 	rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_I2C2_SCL);
 	rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_I2C2_SDA);
+#else
+	rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_GPIO5D4);
+	rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_GPIO5D3);
+#endif
 	return 0;
 }
 
 static int rk29_i2c3_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 	rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_I2C3_SCL);
 	rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_I2C3_SDA);
+#else
+	rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_GPIO2B5);
+	rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_GPIO2B4);
+#endif
 	return 0;
 }
-
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 struct rk29_i2c_platform_data default_i2c0_data = {
 	.bus_num    = 0,
 	.flags      = 0,
@@ -552,7 +573,17 @@ struct rk29_i2c_platform_data default_i2c0_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c0_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c0_data = {
+       .sda_pin = RK29_PIN2_PB6,
+       .scl_pin = RK29_PIN2_PB7,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 0,
+       .io_init = rk29_i2c0_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 struct rk29_i2c_platform_data default_i2c1_data = {
 	.bus_num    = 1,
 	.flags      = 0,
@@ -561,7 +592,17 @@ struct rk29_i2c_platform_data default_i2c1_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c1_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c1_data = {
+       .sda_pin = RK29_PIN1_PA6,
+       .scl_pin = RK29_PIN1_PA7,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 1,
+       .io_init = rk29_i2c1_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 struct rk29_i2c_platform_data default_i2c2_data = {
 	.bus_num    = 2,
 	.flags      = 0,
@@ -570,7 +611,17 @@ struct rk29_i2c_platform_data default_i2c2_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c2_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c2_data = {
+       .sda_pin = RK29_PIN5_PD3,
+       .scl_pin = RK29_PIN5_PD4,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 2,
+       .io_init = rk29_i2c2_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 struct rk29_i2c_platform_data default_i2c3_data = {
 	.bus_num    = 3,
 	.flags      = 0,
@@ -579,7 +630,16 @@ struct rk29_i2c_platform_data default_i2c3_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c3_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c3_data = {
+       .sda_pin = RK29_PIN5_PB5,
+       .scl_pin = RK29_PIN5_PB4,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 3,
+       .io_init = rk29_i2c3_io_init,
+};
+#endif
 #ifdef CONFIG_I2C0_RK29
 static struct i2c_board_info __initdata board_i2c0_devices[] = {
 #if defined (CONFIG_RK1000_CONTROL)
diff --git a/arch/arm/mach-rk29/board-rk29-phonesdk.c b/arch/arm/mach-rk29/board-rk29-phonesdk.c
index ac4faccb9511..ff96ccb625ea 100755
--- a/arch/arm/mach-rk29/board-rk29-phonesdk.c
+++ b/arch/arm/mach-rk29/board-rk29-phonesdk.c
@@ -55,6 +55,7 @@
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/i2c-gpio.h>
 
 #include "devices.h"
 
@@ -1537,31 +1538,51 @@ static struct l3g4200d_platform_data l3g4200d_info = {
 *****************************************************************************************/
 static int rk29_i2c0_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 	rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_I2C0_SCL);
 	rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_I2C0_SDA);
+#else
+	rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_GPIO2B7);
+	rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_GPIO2B6);
+#endif
 	return 0;
 }
 
 static int rk29_i2c1_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 	rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_I2C1_SCL);
 	rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_I2C1_SDA);
+#else
+	rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_GPIO1A7);
+	rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_GPIO1A6);
+#endif
 	return 0;
 }
 static int rk29_i2c2_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 	rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_I2C2_SCL);
 	rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_I2C2_SDA);
+#else
+	rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_GPIO5D4);
+	rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_GPIO5D3);
+#endif
 	return 0;
 }
 
 static int rk29_i2c3_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 	rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_I2C3_SCL);
 	rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_I2C3_SDA);
+#else
+	rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_GPIO2B5);
+	rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_GPIO2B4);
+#endif
 	return 0;
 }
-
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 struct rk29_i2c_platform_data default_i2c0_data = {
 	.bus_num    = 0,
 	.flags      = 0,
@@ -1570,7 +1591,17 @@ struct rk29_i2c_platform_data default_i2c0_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c0_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c0_data = {
+       .sda_pin = RK29_PIN2_PB6,
+       .scl_pin = RK29_PIN2_PB7,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 0,
+       .io_init = rk29_i2c0_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 struct rk29_i2c_platform_data default_i2c1_data = {
 	.bus_num    = 1,
 	.flags      = 0,
@@ -1579,7 +1610,17 @@ struct rk29_i2c_platform_data default_i2c1_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c1_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c1_data = {
+       .sda_pin = RK29_PIN1_PA6,
+       .scl_pin = RK29_PIN1_PA7,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 1,
+       .io_init = rk29_i2c1_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 struct rk29_i2c_platform_data default_i2c2_data = {
 	.bus_num    = 2,
 	.flags      = 0,
@@ -1588,7 +1629,17 @@ struct rk29_i2c_platform_data default_i2c2_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c2_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c2_data = {
+       .sda_pin = RK29_PIN5_PD3,
+       .scl_pin = RK29_PIN5_PD4,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 2,
+       .io_init = rk29_i2c2_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 struct rk29_i2c_platform_data default_i2c3_data = {
 	.bus_num    = 3,
 	.flags      = 0,
@@ -1597,7 +1648,16 @@ struct rk29_i2c_platform_data default_i2c3_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c3_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c3_data = {
+       .sda_pin = RK29_PIN5_PB5,
+       .scl_pin = RK29_PIN5_PB4,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 3,
+       .io_init = rk29_i2c3_io_init,
+};
+#endif
 #ifdef CONFIG_I2C0_RK29
 static struct i2c_board_info __initdata board_i2c0_devices[] = {
 #if defined (CONFIG_RK1000_CONTROL)
diff --git a/arch/arm/mach-rk29/board-rk29phonepadsdk.c b/arch/arm/mach-rk29/board-rk29phonepadsdk.c
index 7196627553b7..b33837235e38 100644
--- a/arch/arm/mach-rk29/board-rk29phonepadsdk.c
+++ b/arch/arm/mach-rk29/board-rk29phonepadsdk.c
@@ -50,6 +50,7 @@
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/i2c-gpio.h>
 
 #include "devices.h"
 #if defined(CONFIG_MU509)
@@ -537,31 +538,51 @@ struct bq27510_platform_data bq27510_info = {
 *****************************************************************************************/
 static int rk29_i2c0_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 	rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_I2C0_SCL);
 	rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_I2C0_SDA);
+#else
+	rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_GPIO2B7);
+	rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_GPIO2B6);
+#endif
 	return 0;
 }
 
 static int rk29_i2c1_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 	rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_I2C1_SCL);
 	rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_I2C1_SDA);
+#else
+	rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_GPIO1A7);
+	rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_GPIO1A6);
+#endif
 	return 0;
 }
 static int rk29_i2c2_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 	rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_I2C2_SCL);
 	rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_I2C2_SDA);
+#else
+	rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_GPIO5D4);
+	rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_GPIO5D3);
+#endif
 	return 0;
 }
 
 static int rk29_i2c3_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 	rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_I2C3_SCL);
 	rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_I2C3_SDA);
+#else
+	rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_GPIO2B5);
+	rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_GPIO2B4);
+#endif
 	return 0;
 }
-
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 struct rk29_i2c_platform_data default_i2c0_data = {
 	.bus_num    = 0,
 	.flags      = 0,
@@ -570,7 +591,17 @@ struct rk29_i2c_platform_data default_i2c0_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c0_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c0_data = {
+       .sda_pin = RK29_PIN2_PB6,
+       .scl_pin = RK29_PIN2_PB7,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 0,
+       .io_init = rk29_i2c0_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 struct rk29_i2c_platform_data default_i2c1_data = {
 	.bus_num    = 1,
 	.flags      = 0,
@@ -579,7 +610,17 @@ struct rk29_i2c_platform_data default_i2c1_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c1_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c1_data = {
+       .sda_pin = RK29_PIN1_PA6,
+       .scl_pin = RK29_PIN1_PA7,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 1,
+       .io_init = rk29_i2c1_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 struct rk29_i2c_platform_data default_i2c2_data = {
 	.bus_num    = 2,
 	.flags      = 0,
@@ -588,7 +629,17 @@ struct rk29_i2c_platform_data default_i2c2_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c2_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c2_data = {
+       .sda_pin = RK29_PIN5_PD3,
+       .scl_pin = RK29_PIN5_PD4,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 2,
+       .io_init = rk29_i2c2_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 struct rk29_i2c_platform_data default_i2c3_data = {
 	.bus_num    = 3,
 	.flags      = 0,
@@ -597,7 +648,16 @@ struct rk29_i2c_platform_data default_i2c3_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c3_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c3_data = {
+       .sda_pin = RK29_PIN5_PB5,
+       .scl_pin = RK29_PIN5_PB4,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 3,
+       .io_init = rk29_i2c3_io_init,
+};
+#endif
 #ifdef CONFIG_I2C0_RK29
 static struct i2c_board_info __initdata board_i2c0_devices[] = {
 #if defined (CONFIG_RK1000_CONTROL)
diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c
index 37d7e6222bdc..57bd90123990 100755
--- a/arch/arm/mach-rk29/board-rk29sdk.c
+++ b/arch/arm/mach-rk29/board-rk29sdk.c
@@ -50,6 +50,7 @@
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/i2c-gpio.h>
 
 #include "devices.h"
 #include "../../../drivers/input/touchscreen/xpt2046_cbn_ts.h"
@@ -525,31 +526,51 @@ struct bq27510_platform_data bq27510_info = {
 *****************************************************************************************/
 static int rk29_i2c0_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 	rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_I2C0_SCL);
 	rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_I2C0_SDA);
+#else
+	rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_GPIO2B7);
+	rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_GPIO2B6);
+#endif
 	return 0;
 }
 
 static int rk29_i2c1_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 	rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_I2C1_SCL);
 	rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_I2C1_SDA);
+#else
+	rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_GPIO1A7);
+	rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_GPIO1A6);
+#endif
 	return 0;
 }
 static int rk29_i2c2_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 	rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_I2C2_SCL);
 	rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_I2C2_SDA);
+#else
+	rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_GPIO5D4);
+	rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_GPIO5D3);
+#endif
 	return 0;
 }
 
 static int rk29_i2c3_io_init(void)
 {
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 	rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_I2C3_SCL);
 	rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_I2C3_SDA);
+#else
+	rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_GPIO2B5);
+	rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_GPIO2B4);
+#endif
 	return 0;
 }
-
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 struct rk29_i2c_platform_data default_i2c0_data = {
 	.bus_num    = 0,
 	.flags      = 0,
@@ -558,7 +579,17 @@ struct rk29_i2c_platform_data default_i2c0_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c0_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c0_data = {
+       .sda_pin = RK29_PIN2_PB6,
+       .scl_pin = RK29_PIN2_PB7,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 0,
+       .io_init = rk29_i2c0_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 struct rk29_i2c_platform_data default_i2c1_data = {
 	.bus_num    = 1,
 	.flags      = 0,
@@ -567,7 +598,17 @@ struct rk29_i2c_platform_data default_i2c1_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c1_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c1_data = {
+       .sda_pin = RK29_PIN1_PA6,
+       .scl_pin = RK29_PIN1_PA7,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 1,
+       .io_init = rk29_i2c1_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 struct rk29_i2c_platform_data default_i2c2_data = {
 	.bus_num    = 2,
 	.flags      = 0,
@@ -576,7 +617,17 @@ struct rk29_i2c_platform_data default_i2c2_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c2_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c2_data = {
+       .sda_pin = RK29_PIN5_PD3,
+       .scl_pin = RK29_PIN5_PD4,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 2,
+       .io_init = rk29_i2c2_io_init,
+};
+#endif
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 struct rk29_i2c_platform_data default_i2c3_data = {
 	.bus_num    = 3,
 	.flags      = 0,
@@ -585,7 +636,16 @@ struct rk29_i2c_platform_data default_i2c3_data = {
 	.mode 		= I2C_MODE_IRQ,
 	.io_init = rk29_i2c3_io_init,
 };
-
+#else
+struct i2c_gpio_platform_data default_i2c3_data = {
+       .sda_pin = RK29_PIN5_PB5,
+       .scl_pin = RK29_PIN5_PB4,
+       .udelay = 5, // clk = 500/udelay = 100Khz
+       .timeout = 100,//msecs_to_jiffies(200),
+       .bus_num    = 3,
+       .io_init = rk29_i2c3_io_init,
+};
+#endif
 #ifdef CONFIG_I2C0_RK29
 static struct i2c_board_info __initdata board_i2c0_devices[] = {
 #if defined (CONFIG_RK1000_CONTROL)
diff --git a/arch/arm/mach-rk29/devices.c b/arch/arm/mach-rk29/devices.c
index fc2258670367..365faf78660e 100755
--- a/arch/arm/mach-rk29/devices.c
+++ b/arch/arm/mach-rk29/devices.c
@@ -79,6 +79,7 @@ struct platform_device rk29_device_vmac = {
 #endif
 
 #ifdef CONFIG_I2C_RK29
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 static struct resource resources_i2c0[] = {
 	{
 		.start	= IRQ_I2C0,
@@ -91,6 +92,8 @@ static struct resource resources_i2c0[] = {
 		.flags	= IORESOURCE_MEM,
 	},
 };
+#endif
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 static struct resource resources_i2c1[] = {
 	{
 		.start	= IRQ_I2C1,
@@ -103,6 +106,8 @@ static struct resource resources_i2c1[] = {
 		.flags	= IORESOURCE_MEM,
 	},
 };
+#endif
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 static struct resource resources_i2c2[] = {
 	{
 		.start	= IRQ_I2C2,
@@ -115,6 +120,8 @@ static struct resource resources_i2c2[] = {
 		.flags	= IORESOURCE_MEM,
 	},
 };
+#endif
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 static struct resource resources_i2c3[] = {
 	{
 		.start	= IRQ_I2C3,
@@ -127,8 +134,9 @@ static struct resource resources_i2c3[] = {
 		.flags	= IORESOURCE_MEM,
 	},
 };
-
+#endif
 struct platform_device rk29_device_i2c0 = {
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 	.name	= "rk29_i2c",
 	.id	= 0,
 	.num_resources	= ARRAY_SIZE(resources_i2c0),
@@ -136,8 +144,16 @@ struct platform_device rk29_device_i2c0 = {
 	.dev 			= {
 		.platform_data = &default_i2c0_data,
 	},
+#else
+	.name	= "i2c-gpio",
+	.id = 0,
+	.dev 			= {
+		.platform_data = &default_i2c0_data,
+	},
+#endif
 };
 struct platform_device rk29_device_i2c1 = {
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 	.name	= "rk29_i2c",
 	.id	= 1,
 	.num_resources	= ARRAY_SIZE(resources_i2c1),
@@ -145,8 +161,16 @@ struct platform_device rk29_device_i2c1 = {
 	.dev 			= {
 		.platform_data = &default_i2c1_data,
 	},
+#else
+	.name	= "i2c-gpio",
+	.id = 1,
+	.dev 			= {
+		.platform_data = &default_i2c1_data,
+	},
+#endif
 };
 struct platform_device rk29_device_i2c2 = {
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 	.name	= "rk29_i2c",
 	.id	= 2,
 	.num_resources	= ARRAY_SIZE(resources_i2c2),
@@ -154,8 +178,16 @@ struct platform_device rk29_device_i2c2 = {
 	.dev 			= {
 		.platform_data = &default_i2c2_data,
 	},
+#else
+	.name	= "i2c-gpio",
+	.id = 2,
+	.dev 			= {
+		.platform_data = &default_i2c2_data,
+	},
+#endif
 };
 struct platform_device rk29_device_i2c3 = {
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 	.name	= "rk29_i2c",
 	.id	= 3,
 	.num_resources	= ARRAY_SIZE(resources_i2c3),
@@ -163,6 +195,13 @@ struct platform_device rk29_device_i2c3 = {
 	.dev 			= {
 		.platform_data = &default_i2c3_data,
 	},
+#else
+	.name	= "i2c-gpio",
+	.id = 3,
+	.dev 			= {
+		.platform_data = &default_i2c3_data,
+	},
+#endif
 };
 #endif
 
diff --git a/arch/arm/mach-rk29/devices.h b/arch/arm/mach-rk29/devices.h
index 1c538077cbe0..2a27e72a2b4a 100755
--- a/arch/arm/mach-rk29/devices.h
+++ b/arch/arm/mach-rk29/devices.h
@@ -17,11 +17,26 @@
 #define __ARCH_ARM_MACH_RK29_DEVICES_H
 
 extern struct rk29_nand_platform_data rk29_nand_data;
-
+#ifdef CONFIG_RK29_I2C0_CONTROLLER
 extern struct rk29_i2c_platform_data default_i2c0_data;
+#else
+extern struct i2c_gpio_platform_data default_i2c0_data;
+#endif
+#ifdef CONFIG_RK29_I2C1_CONTROLLER
 extern struct rk29_i2c_platform_data default_i2c1_data;
+#else
+extern struct i2c_gpio_platform_data default_i2c1_data;
+#endif
+#ifdef CONFIG_RK29_I2C2_CONTROLLER
 extern struct rk29_i2c_platform_data default_i2c2_data;
+#else
+extern struct i2c_gpio_platform_data default_i2c2_data;
+#endif
+#ifdef CONFIG_RK29_I2C3_CONTROLLER
 extern struct rk29_i2c_platform_data default_i2c3_data;
+#else
+extern struct i2c_gpio_platform_data default_i2c3_data;
+#endif
 
 extern struct platform_device rk29_device_i2c0;
 extern struct platform_device rk29_device_i2c1;
diff --git a/drivers/i2c/algos/Makefile b/drivers/i2c/algos/Makefile
index 18b3e962ec09..8445ba362bc0 100644
--- a/drivers/i2c/algos/Makefile
+++ b/drivers/i2c/algos/Makefile
@@ -2,7 +2,8 @@
 # Makefile for the i2c algorithms
 #
 
-obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
+#obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
+obj-y						+= i2c-algo-bit.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ALGOPCA)	+= i2c-algo-pca.o
 
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
old mode 100644
new mode 100755
index e25e13980af3..e7cae5d355a5
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -363,7 +363,7 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
 		 * the SMBus PEC was wrong.
 		 */
 		} else if (retval == 0) {
-			dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n");
+			dev_err(&i2c_adap->dev, "sendbytes: NAK bailout, addr is 0x%x.\n", msg->addr);
 			return -EIO;
 
 		/* Timeout; or (someday) lost arbitration
@@ -374,8 +374,8 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
 		 * to know or care about this ... it is *NOT* an error.
 		 */
 		} else {
-			dev_err(&i2c_adap->dev, "sendbytes: error %d\n",
-					retval);
+			dev_err(&i2c_adap->dev, "sendbytes: error %d, addr is 0x%x.\n",
+					retval, msg->addr);
 			return retval;
 		}
 	}
@@ -523,6 +523,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
 	unsigned short nak_ok;
 
 	bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
+	adap->udelay = 500 * 1000/msgs[0].scl_rate + 1;
 	i2c_start(adap);
 	for (i = 0; i < num; i++) {
 		pmsg = &msgs[i];
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index eb6df5f1a6de..5a664c3ad756 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -307,13 +307,30 @@ if I2C_RK29
 		depends on ARCH_RK29
 		help
 			This supports the use of the I2C0 interface on rk29 processors.
-
+		if I2C0_RK29
+			choice
+				prompt "I2C transfer mode select"
+				config RK29_I2C0_CONTROLLER
+					bool "With i2c controller"
+				config RK29_I2C0_GPIO
+					bool "Simulation with GPIO"
+			endchoice
+		endif
 	config I2C1_RK29
 		bool "RK29 I2C1 interface support"
 		default y
 		depends on ARCH_RK29
 		help
 			This supports the use of the I2C1 interface on rk29 processors.
+		if I2C1_RK29
+			choice
+				prompt "I2C transfer mode select"
+				config RK29_I2C1_CONTROLLER
+					bool "With i2c controller"
+				config RK29_I2C1_GPIO
+					bool "Simulation with GPIO"
+			endchoice
+		endif
 
 	config I2C2_RK29
 		bool "RK29 I2C2 interface support"
@@ -321,6 +338,15 @@ if I2C_RK29
 		depends on ARCH_RK29
 		help
 			This supports the use of the I2C2 interface on rk29 processors.
+		if I2C2_RK29
+			choice
+				prompt "I2C transfer mode select"
+				config RK29_I2C2_CONTROLLER
+					bool "With i2c controller"
+				config RK29_I2C2_GPIO
+					bool "Simulation with GPIO"
+			endchoice
+		endif
 
 	config I2C3_RK29
 		bool "RK29 I2C3 interface support"
@@ -328,6 +354,15 @@ if I2C_RK29
 		depends on ARCH_RK29 && !UART3_CTS_RTS_RK29
 		help
 			This supports the use of the I2C3 interface on rk29 processors.
+		if I2C3_RK29
+			choice
+				prompt "I2C transfer mode select"
+				config RK29_I2C3_CONTROLLER
+					bool "With i2c controller"
+				config RK29_I2C3_GPIO
+					bool "Simulation with GPIO"
+			endchoice
+		endif
 endif
 config I2C_DEV_RK29
 	tristate "RK29 I2C device interface support"
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 231d1aadacb7..69703292fe10 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -4,7 +4,7 @@
 obj-$(CONFIG_I2C_RK2818)	+= i2c-rk2818.o
 obj-$(CONFIG_I2C_RK29)		+= i2c-rk29.o
 obj-$(CONFIG_I2C_DEV_RK29)		+= i2c-dev-rk29.o
-
+obj-y						+= i2c-gpio.o
 
 ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
old mode 100644
new mode 100755
index 32104eac8d3d..e8fa62a50e8f
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -87,7 +87,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	pdata = pdev->dev.platform_data;
 	if (!pdata)
 		return -ENXIO;
-
+	if(pdata->io_init)
+		pdata->io_init();
 	ret = -ENOMEM;
 	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
 	if (!adap)
@@ -210,7 +211,7 @@ static int __init i2c_gpio_init(void)
 
 	return ret;
 }
-module_init(i2c_gpio_init);
+subsys_initcall(i2c_gpio_init);
 
 static void __exit i2c_gpio_exit(void)
 {
diff --git a/include/linux/i2c-gpio.h b/include/linux/i2c-gpio.h
old mode 100644
new mode 100755
index c1bcb1f1d73b..1b4ac408db7c
--- a/include/linux/i2c-gpio.h
+++ b/include/linux/i2c-gpio.h
@@ -33,6 +33,8 @@ struct i2c_gpio_platform_data {
 	unsigned int	sda_is_open_drain:1;
 	unsigned int	scl_is_open_drain:1;
 	unsigned int	scl_is_output_only:1;
+	int bus_num;
+	int (*io_init)(void);
 };
 
 #endif /* _LINUX_I2C_GPIO_H */