From 1d5b1aa60c938419e3d73723b0102c59bb809e37 Mon Sep 17 00:00:00 2001 From: kfx Date: Tue, 8 Jan 2013 17:05:59 +0800 Subject: [PATCH] i2c: use new iomux api --- arch/arm/mach-rk2928/devices.c | 110 ++-------------- arch/arm/mach-rk30/devices.c | 182 ++------------------------ arch/arm/plat-rk/include/plat/board.h | 3 +- drivers/i2c/busses/i2c-rk30-adapter.c | 41 +++++- drivers/i2c/busses/i2c-rk30.c | 6 +- drivers/i2c/busses/i2c-rk30.h | 3 + 6 files changed, 68 insertions(+), 277 deletions(-) diff --git a/arch/arm/mach-rk2928/devices.c b/arch/arm/mach-rk2928/devices.c index fabd582cc4fa..8c6a9536d13c 100755 --- a/arch/arm/mach-rk2928/devices.c +++ b/arch/arm/mach-rk2928/devices.c @@ -274,107 +274,14 @@ static void __init rk2928_init_uart(void) #define I2C3_END RK2928_RKI2C3_PHYS + RK2928_RKI2C3_SIZE - 1 #endif -struct i2c_iomux{ - int scl_pin; - char *scl_name; - unsigned int scl_i2c_mode; - unsigned int scl_gpio_mode; - - int sda_pin; - char *sda_name; - unsigned int sda_i2c_mode; - unsigned int sda_gpio_mode; - - char *req_name; -}; -static struct i2c_iomux iomux[] = { - { - .scl_pin = RK2928_PIN0_PA0, - .scl_name = GPIO0A0_I2C0_SCL_NAME, - .scl_i2c_mode = GPIO0A_I2C0_SCL, - .scl_gpio_mode = 0, - .sda_pin = RK2928_PIN0_PA1, - .sda_name = GPIO0A1_I2C0_SDA_NAME, - .sda_i2c_mode = GPIO0A_I2C0_SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.0", - }, - { - .scl_pin = RK2928_PIN0_PA2, - .scl_name = GPIO0A2_I2C1_SCL_NAME, - .scl_i2c_mode = GPIO0A_I2C1_SCL, - .scl_gpio_mode = 0, - .sda_pin = RK2928_PIN0_PA3, - .sda_name = GPIO0A3_I2C1_SDA_NAME, - .sda_i2c_mode = GPIO0A_I2C1_SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.1", - }, - { - .scl_pin = RK2928_PIN2_PC5, - .scl_name = GPIO2C5_LCDC0_D19_LCDC1_D19_I2C2_SCL_NAME, - .scl_i2c_mode = GPIO2C_I2C2_SCL, - .scl_gpio_mode = 0, - .sda_pin = RK2928_PIN2_PC4, - .sda_name = GPIO2C4_LCDC0_D18_LCDC1_D18_I2C2_SDA_NAME, - .sda_i2c_mode = GPIO2C_I2C2_SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.2", - }, - { - .scl_pin = RK2928_PIN0_PA6, - .scl_name = GPIO0A6_I2C3_SCL_HDMI_DDCSCL_NAME, - .scl_i2c_mode = GPIO0A_I2C3_SCL, - .scl_gpio_mode = 0, - .sda_pin = RK2928_PIN0_PA7, - .sda_name = GPIO0A7_I2C3_SDA_HDMI_DDCSDA_NAME, - .sda_i2c_mode = GPIO0A_I2C3_SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.3", - }, -}; -static int i2c_check_idle(int id) -{ - int sda_level, scl_level; - - if(id < 0 || id > 3){ - printk("Error: id: %d\n", id); - } - - rk30_mux_api_set(iomux[id].scl_name, iomux[id].scl_gpio_mode); - rk30_mux_api_set(iomux[id].sda_name, iomux[id].sda_gpio_mode); - - gpio_request(iomux[id].scl_pin, iomux[id].req_name); - gpio_request(iomux[id].sda_pin, iomux[id].req_name); - - gpio_direction_input(iomux[id].scl_pin); - gpio_direction_input(iomux[id].sda_pin); - - scl_level = gpio_get_value(iomux[id].scl_pin); - sda_level = gpio_get_value(iomux[id].sda_pin); - - gpio_free(iomux[id].scl_pin); - gpio_free(iomux[id].sda_pin); - - rk30_mux_api_set(iomux[id].scl_name, iomux[id].scl_i2c_mode); - rk30_mux_api_set(iomux[id].sda_name, iomux[id].sda_i2c_mode); - - if(sda_level == 1 && scl_level == 1) - return I2C_IDLE; - else if(sda_level == 0 && scl_level == 1) - return I2C_SDA_LOW; - else if(sda_level == 1 && scl_level == 0) - return I2C_SCL_LOW; - else - return BOTH_LOW; -} - -#ifdef CONFIG_I2C2_RK30 +#ifdef CONFIG_I2C0_RK30 static struct rk30_i2c_platform_data default_i2c0_data = { .bus_num = 0, .is_div_from_arm = 1, .adap_type = I2C0_ADAP_TYPE, - .check_idle = &i2c_check_idle, + .sda_mode = I2C0_SDA, + .scl_mode = I2C0_SCL, + }; static struct resource resources_i2c0[] = { @@ -406,7 +313,8 @@ static struct rk30_i2c_platform_data default_i2c1_data = { .bus_num = 1, .is_div_from_arm = 1, .adap_type = I2C1_ADAP_TYPE, - .check_idle = &i2c_check_idle, + .sda_mode = I2C1_SDA, + .scl_mode = I2C1_SCL, }; static struct resource resources_i2c1[] = { @@ -438,7 +346,8 @@ static struct rk30_i2c_platform_data default_i2c2_data = { .bus_num = 2, .is_div_from_arm = 0, .adap_type = I2C2_ADAP_TYPE, - .check_idle = &i2c_check_idle, + .sda_mode = I2C2_SDA, + .scl_mode = I2C2_SCL, }; static struct resource resources_i2c2[] = { @@ -470,7 +379,8 @@ static struct rk30_i2c_platform_data default_i2c3_data = { .bus_num = 3, .is_div_from_arm = 0, .adap_type = I2C3_ADAP_TYPE, - .check_idle = &i2c_check_idle, + .sda_mode = I2C3_SDA, + .scl_mode = I2C3_SCL, }; static struct resource resources_i2c3[] = { diff --git a/arch/arm/mach-rk30/devices.c b/arch/arm/mach-rk30/devices.c index 837dbb79ddde..c5e6aee6b981 100755 --- a/arch/arm/mach-rk30/devices.c +++ b/arch/arm/mach-rk30/devices.c @@ -421,173 +421,6 @@ static void __init rk30_init_uart(void) #define I2C4_END RK30_I2C4_PHYS + SZ_16K - 1 #endif -struct i2c_iomux{ - int scl_pin; - char *scl_name; - unsigned int scl_i2c_mode; - unsigned int scl_gpio_mode; - - int sda_pin; - char *sda_name; - unsigned int sda_i2c_mode; - unsigned int sda_gpio_mode; - - char *req_name; -}; -#ifdef CONFIG_ARCH_RK3066B -static struct i2c_iomux iomux[] = { - { - .scl_pin = RK30_PIN1_PD1, - .scl_name = GPIO1D1_I2C0SCL_NAME, - .scl_i2c_mode = GPIO1D_I2C0SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN1_PD0, - .sda_name = GPIO1D0_I2C0SDA_NAME, - .sda_i2c_mode = GPIO1D_I2C0SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.0", - }, - { - .scl_pin = RK30_PIN1_PD3, - .scl_name = GPIO1D3_I2C1SCL_NAME, - .scl_i2c_mode = GPIO1D_I2C1SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN1_PD2, - .sda_name = GPIO1D2_I2C1SDA_NAME, - .sda_i2c_mode = GPIO1D_I2C1SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.1", - }, - { - .scl_pin = RK30_PIN1_PD5, - .scl_name = GPIO1D5_I2C2SCL_NAME, - .scl_i2c_mode = GPIO1D_I2C2SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN1_PD4, - .sda_name = GPIO1D4_I2C2SDA_NAME, - .sda_i2c_mode = GPIO1D_I2C2SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.2", - }, - { - .scl_pin = RK30_PIN3_PB7, - .scl_name = GPIO3B7_CIFDATA11_I2C3SCL_NAME, - .scl_i2c_mode = GPIO3B_I2C3SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN3_PB6, - .sda_name = GPIO3B6_CIFDATA10_I2C3SDA_NAME, - .sda_i2c_mode = GPIO3B_I2C3SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.3", - }, - { - .scl_pin = RK30_PIN1_PD7, - .scl_name = GPIO1D7_I2C4SCL_NAME, - .scl_i2c_mode = GPIO1D_I2C4SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN1_PD6, - .sda_name = GPIO1D6_I2C4SDA_NAME, - .sda_i2c_mode = GPIO1D_I2C4SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.4", - }, -}; -#else -static struct i2c_iomux iomux[] = { - { - .scl_pin = RK30_PIN2_PD5, - .scl_name = GPIO2D5_I2C0SCL_NAME, - .scl_i2c_mode = GPIO2D_I2C0_SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN2_PD4, - .sda_name = GPIO2D4_I2C0SDA_NAME, - .sda_i2c_mode = GPIO2D_I2C0_SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.0", - }, - { - .scl_pin = RK30_PIN2_PD7, - .scl_name = GPIO2D7_I2C1SCL_NAME, - .scl_i2c_mode = GPIO2D_I2C1_SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN2_PD6, - .sda_name = GPIO2D6_I2C1SDA_NAME, - .sda_i2c_mode = GPIO2D_I2C1_SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.1", - }, - { - .scl_pin = RK30_PIN3_PA1, - .scl_name = GPIO3A1_I2C2SCL_NAME, - .scl_i2c_mode = GPIO3A_I2C2_SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN3_PA0, - .sda_name = GPIO3A0_I2C2SDA_NAME, - .sda_i2c_mode = GPIO3A_I2C2_SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.2", - }, - { - .scl_pin = RK30_PIN3_PA3, - .scl_name = GPIO3A3_I2C3SCL_NAME, - .scl_i2c_mode = GPIO3A_I2C3_SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN3_PA2, - .sda_name = GPIO3A2_I2C3SDA_NAME, - .sda_i2c_mode = GPIO3A_I2C3_SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.3", - }, - { - .scl_pin = RK30_PIN3_PA5, - .scl_name = GPIO3A5_I2C4SCL_NAME, - .scl_i2c_mode = GPIO3A_I2C4_SCL, - .scl_gpio_mode = 0, - .sda_pin = RK30_PIN3_PA4, - .sda_name = GPIO3A4_I2C4SDA_NAME, - .sda_i2c_mode = GPIO3A_I2C4_SDA, - .sda_gpio_mode = 0, - .req_name = "i2c.4", - }, -}; -#endif -static int i2c_check_idle(int id) -{ - int sda_level, scl_level; - - if(id < 0 || id > 4){ - printk("Error: id: %d\n", id); - return -1; - } - - rk30_mux_api_set(iomux[id].scl_name, iomux[id].scl_gpio_mode); - rk30_mux_api_set(iomux[id].sda_name, iomux[id].sda_gpio_mode); - - gpio_request(iomux[id].scl_pin, iomux[id].req_name); - gpio_request(iomux[id].sda_pin, iomux[id].req_name); - - gpio_direction_input(iomux[id].scl_pin); - gpio_direction_input(iomux[id].sda_pin); - - scl_level = gpio_get_value(iomux[id].scl_pin); - sda_level = gpio_get_value(iomux[id].sda_pin); - - gpio_free(iomux[id].scl_pin); - gpio_free(iomux[id].sda_pin); - - rk30_mux_api_set(iomux[id].scl_name, iomux[id].scl_i2c_mode); - rk30_mux_api_set(iomux[id].sda_name, iomux[id].sda_i2c_mode); - - if(sda_level == 1 && scl_level == 1) - return I2C_IDLE; - else if(sda_level == 0 && scl_level == 1) - return I2C_SDA_LOW; - else if(sda_level == 1 && scl_level == 0) - return I2C_SCL_LOW; - else - return BOTH_LOW; -} - #ifdef CONFIG_I2C0_RK30 static struct rk30_i2c_platform_data default_i2c0_data = { .bus_num = 0, @@ -597,7 +430,8 @@ static struct rk30_i2c_platform_data default_i2c0_data = { .is_div_from_arm = 1, #endif .adap_type = I2C0_ADAP_TYPE, - .check_idle = &i2c_check_idle, + .sda_mode = I2C0_SDA, + .scl_mode = I2C0_SCL, }; static struct resource resources_i2c0[] = { @@ -633,7 +467,8 @@ static struct rk30_i2c_platform_data default_i2c1_data = { .is_div_from_arm = 1, #endif .adap_type = I2C1_ADAP_TYPE, - .check_idle = &i2c_check_idle, + .sda_mode = I2C1_SDA, + .scl_mode = I2C1_SCL, }; static struct resource resources_i2c1[] = { @@ -665,7 +500,8 @@ static struct rk30_i2c_platform_data default_i2c2_data = { .bus_num = 2, .is_div_from_arm = 0, .adap_type = I2C2_ADAP_TYPE, - .check_idle = &i2c_check_idle, + .sda_mode = I2C2_SDA, + .scl_mode = I2C2_SCL, }; static struct resource resources_i2c2[] = { @@ -697,7 +533,8 @@ static struct rk30_i2c_platform_data default_i2c3_data = { .bus_num = 3, .is_div_from_arm = 0, .adap_type = I2C3_ADAP_TYPE, - .check_idle = &i2c_check_idle, + .sda_mode = I2C3_SDA, + .scl_mode = I2C3_SCL, }; static struct resource resources_i2c3[] = { @@ -729,7 +566,8 @@ static struct rk30_i2c_platform_data default_i2c4_data = { .bus_num = 4, .is_div_from_arm = 0, .adap_type = I2C4_ADAP_TYPE, - .check_idle = &i2c_check_idle, + .sda_mode = I2C4_SDA, + .scl_mode = I2C4_SCL, }; static struct resource resources_i2c4[] = { diff --git a/arch/arm/plat-rk/include/plat/board.h b/arch/arm/plat-rk/include/plat/board.h index d111cf6f6808..072a94361402 100755 --- a/arch/arm/plat-rk/include/plat/board.h +++ b/arch/arm/plat-rk/include/plat/board.h @@ -26,9 +26,10 @@ struct rk30_i2c_platform_data { int adap_type; int is_div_from_arm; u32 flags; + int scl_mode; + int sda_mode; int (*io_init)(void); int (*io_deinit)(void); - int (*check_idle)(int); }; struct spi_cs_gpio { diff --git a/drivers/i2c/busses/i2c-rk30-adapter.c b/drivers/i2c/busses/i2c-rk30-adapter.c index 468a0b1b57c1..88e1ea62aa1c 100755 --- a/drivers/i2c/busses/i2c-rk30-adapter.c +++ b/drivers/i2c/busses/i2c-rk30-adapter.c @@ -107,6 +107,45 @@ static void rk30_show_regs(struct rk30_i2c *i2c) for( i = 0; i < 8; i ++) dev_info(i2c->dev, "I2C_RXDATA%d: 0x%08x\n", i, i2c_readl(i2c->regs + I2C_RXDATA_BASE + i * 4)); } + +static int rk30_i2c_check_idle(struct rk30_i2c *i2c) +{ + int ret = 0; + int sda_io, scl_io; + int sda_lev, scl_lev; + + sda_io = iomux_mode_to_gpio(i2c->sda_mode); + scl_io = iomux_mode_to_gpio(i2c->scl_mode); + + ret = gpio_request(sda_io, NULL); + if(unlikely(ret < 0)){ + dev_err(i2c->dev, "Failed to request gpio: SDA_GPIO\n"); + return ret; + } + ret = gpio_request(scl_io, NULL); + if(unlikely(ret < 0)){ + dev_err(i2c->dev, "Failed to request gpio: SCL_GPIO\n"); + gpio_free(sda_io); + return ret; + } + gpio_direction_input(sda_io); + gpio_direction_input(scl_io); + + sda_lev = gpio_get_value(sda_io); + scl_lev = gpio_get_value(scl_io); + + iomux_set(i2c->sda_mode); + iomux_set(i2c->scl_mode); + + if(sda_lev == 1 && scl_lev == 1) + return I2C_IDLE; + else if(sda_lev == 0 && scl_lev == 1) + return I2C_SDA_LOW; + else if(sda_lev == 1 && scl_lev == 0) + return I2C_SCL_LOW; + else + return BOTH_LOW; +} static inline void rk30_i2c_enable(struct rk30_i2c *i2c, unsigned int lastnak) { unsigned int con = 0; @@ -543,7 +582,7 @@ static int rk30_i2c_xfer(struct i2c_adapter *adap, clk_enable(i2c->clk); #ifdef I2C_CHECK_IDLE - while(retry-- && ((state = i2c->check_idle(i2c->adap.nr)) != I2C_IDLE)){ + while(retry-- && ((state = rk30_i2c_check_idle(i2c)) != I2C_IDLE)){ msleep(10); } if(retry == 0){ diff --git a/drivers/i2c/busses/i2c-rk30.c b/drivers/i2c/busses/i2c-rk30.c index 1383cca221c8..eb26047d2543 100755 --- a/drivers/i2c/busses/i2c-rk30.c +++ b/drivers/i2c/busses/i2c-rk30.c @@ -101,9 +101,9 @@ static int rk30_i2c_probe(struct platform_device *pdev) if(pdata->io_init) pdata->io_init(); - if(pdata->check_idle){ - i2c->check_idle = pdata->check_idle; - } + + i2c->sda_mode = pdata->sda_mode; + i2c->scl_mode = pdata->scl_mode; strlcpy(i2c->adap.name, "rk30_i2c", sizeof(i2c->adap.name)); i2c->adap.owner = THIS_MODULE; diff --git a/drivers/i2c/busses/i2c-rk30.h b/drivers/i2c/busses/i2c-rk30.h index 5e4e48fac2e3..573703bc3fda 100755 --- a/drivers/i2c/busses/i2c-rk30.h +++ b/drivers/i2c/busses/i2c-rk30.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #if 0 @@ -98,6 +99,8 @@ struct rk30_i2c { unsigned int mode; unsigned int count; + int sda_mode, scl_mode; + struct wake_lock idlelock[5]; int is_div_from_arm[5]; -- 2.34.1