Re: [U-Boot] [PATCH V2] i2c: mxc: refactor i2c driver and support dm
Please ignore this version, since bus_i2c_init is not good for DM, I'll implement a weak function for this. On 4/25/2015 9:04 PM, Peng Fan wrote: 1. Introduce a new structure `struct mxc_i2c_bus`, this structure will used for non-DM and DM. 1. Remove `struct mxc_i2c_regs` structure, but use register offset to access registers based on `base` entry of `struct mxc_i2c_bus`. 2. Remove most `#ifdef I2C_QUIRK_REG`. Using driver_data to contain platform flags. A new flag is introduced, I2C_QUIRK_FLAG. 3. Most functions use `struct mxc_i2c_bus` as one of the parameters. 4. Support DM 5. Make most functions common to DM and non-DM, try to avoid duplicated code. 6. struct i2c_parms and struct sram_data are removed, since we move to use struct mxc_i2c_regs. 7. Remove bus_i2c_read bus_i2c_write prototype in header file 8. The frist paramter of bus_i2c_init is modified to i2c index, since bus_i2c_init is a must now, so it is also implemented for DM part. Signed-off-by: Peng Fan peng@freescale.com --- Changes v2: This patch is a big change from v1 patch. 1. Refactor driver, remove register access based on structure, but use 'base + offset' 2. Introduce mxc_i2c_bus structure 3. Introduce I2C_QUIRK_FLAG and remove most I2C_QUIRK_REG and use driver_data to contain the flags for different platforms 4. Avoid duplicated code between DM and non-DM part 5. The function name i2c_init_transfer is not changed. 6. Remove bus_i2c_read/write prototype from header file 7. change bus_i2c_init's first parameter to i2c index 8. Rename patch name, since refactor non-DM part. arch/arm/imx-common/i2c-mxv7.c| 3 +- arch/arm/include/asm/imx-common/mxc_i2c.h | 6 +- drivers/i2c/mxc_i2c.c | 585 -- 3 files changed, 402 insertions(+), 192 deletions(-) diff --git a/arch/arm/imx-common/i2c-mxv7.c b/arch/arm/imx-common/i2c-mxv7.c index 1a632e7..3c793ef 100644 --- a/arch/arm/imx-common/i2c-mxv7.c +++ b/arch/arm/imx-common/i2c-mxv7.c @@ -99,8 +99,7 @@ int setup_i2c(unsigned i2c_index, int speed, int slave_addr, if (ret) goto err_idle; - bus_i2c_init(i2c_bases[i2c_index], speed, slave_addr, - force_idle_bus, p); + bus_i2c_init(i2c_index, speed, slave_addr, force_idle_bus, p); return 0; diff --git a/arch/arm/include/asm/imx-common/mxc_i2c.h b/arch/arm/include/asm/imx-common/mxc_i2c.h index af86163..94b085f 100644 --- a/arch/arm/include/asm/imx-common/mxc_i2c.h +++ b/arch/arm/include/asm/imx-common/mxc_i2c.h @@ -54,10 +54,6 @@ struct i2c_pads_info { int setup_i2c(unsigned i2c_index, int speed, int slave_addr, struct i2c_pads_info *p); -void bus_i2c_init(void *base, int speed, int slave_addr, +void bus_i2c_init(int index, int speed, int slave_addr, int (*idle_bus_fn)(void *p), void *p); -int bus_i2c_read(void *base, uchar chip, uint addr, int alen, uchar *buf, - int len); -int bus_i2c_write(void *base, uchar chip, uint addr, int alen, - const uchar *buf, int len); #endif diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index fc5ee35..9894f3e 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -21,26 +21,21 @@ #include asm/io.h #include i2c.h #include watchdog.h +#include dm.h +#include fdtdec.h DECLARE_GLOBAL_DATA_PTR; -#ifdef I2C_QUIRK_REG -struct mxc_i2c_regs { - uint8_t iadr; - uint8_t ifdr; - uint8_t i2cr; - uint8_t i2sr; - uint8_t i2dr; -}; -#else -struct mxc_i2c_regs { - uint32_tiadr; - uint32_tifdr; - uint32_ti2cr; - uint32_ti2sr; - uint32_ti2dr; -}; -#endif +#define I2C_QUIRK_FLAG (1 0) + +#define IMX_I2C_REGSHIFT 2 +#define VF610_I2C_REGSHIFT 0 +/* Register index */ +#define IADR 0 +#define IFDR 1 +#define I2CR 2 +#define I2SR 3 +#define I2DR 4 #define I2CR_IIEN (1 6) #define I2CR_MSTA (1 5) @@ -68,6 +63,23 @@ struct mxc_i2c_regs { #error define CONFIG_SYS_I2C_BASE to use the mxc_i2c driver #endif +/* + * Information about i2c controller + * struct mxc_i2c_bus - information about the i2c[x] bus + * @base: Address of I2C bus controller + * @speed: Speed of I2C bus + * @driver_data: Flags for different platforms, such as I2C_QUIRK_FLAG. + * @idle_bus_fn: function to force bus idle + * @idle_bus_data: parameter for idle_bus_fun + */ +struct mxc_i2c_bus { + ulong base; + ulong driver_data; + int speed; + int (*idle_bus_fn)(void *p); + void *idle_bus_data; +}; + #ifdef I2C_QUIRK_REG static u16 i2c_clk_div[60][2] = { { 20, 0x00 }, { 22, 0x01 }, { 24, 0x02 }, { 26, 0x03 }, @@ -104,7 +116,6 @@ static u16 i2c_clk_div[50][2] = { }; #endif - #ifndef CONFIG_SYS_MXC_I2C1_SPEED #define CONFIG_SYS_MXC_I2C1_SPEED
[U-Boot] [PATCH V2] i2c: mxc: refactor i2c driver and support dm
1. Introduce a new structure `struct mxc_i2c_bus`, this structure will used for non-DM and DM. 1. Remove `struct mxc_i2c_regs` structure, but use register offset to access registers based on `base` entry of `struct mxc_i2c_bus`. 2. Remove most `#ifdef I2C_QUIRK_REG`. Using driver_data to contain platform flags. A new flag is introduced, I2C_QUIRK_FLAG. 3. Most functions use `struct mxc_i2c_bus` as one of the parameters. 4. Support DM 5. Make most functions common to DM and non-DM, try to avoid duplicated code. 6. struct i2c_parms and struct sram_data are removed, since we move to use struct mxc_i2c_regs. 7. Remove bus_i2c_read bus_i2c_write prototype in header file 8. The frist paramter of bus_i2c_init is modified to i2c index, since bus_i2c_init is a must now, so it is also implemented for DM part. Signed-off-by: Peng Fan peng@freescale.com --- Changes v2: This patch is a big change from v1 patch. 1. Refactor driver, remove register access based on structure, but use 'base + offset' 2. Introduce mxc_i2c_bus structure 3. Introduce I2C_QUIRK_FLAG and remove most I2C_QUIRK_REG and use driver_data to contain the flags for different platforms 4. Avoid duplicated code between DM and non-DM part 5. The function name i2c_init_transfer is not changed. 6. Remove bus_i2c_read/write prototype from header file 7. change bus_i2c_init's first parameter to i2c index 8. Rename patch name, since refactor non-DM part. arch/arm/imx-common/i2c-mxv7.c| 3 +- arch/arm/include/asm/imx-common/mxc_i2c.h | 6 +- drivers/i2c/mxc_i2c.c | 585 -- 3 files changed, 402 insertions(+), 192 deletions(-) diff --git a/arch/arm/imx-common/i2c-mxv7.c b/arch/arm/imx-common/i2c-mxv7.c index 1a632e7..3c793ef 100644 --- a/arch/arm/imx-common/i2c-mxv7.c +++ b/arch/arm/imx-common/i2c-mxv7.c @@ -99,8 +99,7 @@ int setup_i2c(unsigned i2c_index, int speed, int slave_addr, if (ret) goto err_idle; - bus_i2c_init(i2c_bases[i2c_index], speed, slave_addr, - force_idle_bus, p); + bus_i2c_init(i2c_index, speed, slave_addr, force_idle_bus, p); return 0; diff --git a/arch/arm/include/asm/imx-common/mxc_i2c.h b/arch/arm/include/asm/imx-common/mxc_i2c.h index af86163..94b085f 100644 --- a/arch/arm/include/asm/imx-common/mxc_i2c.h +++ b/arch/arm/include/asm/imx-common/mxc_i2c.h @@ -54,10 +54,6 @@ struct i2c_pads_info { int setup_i2c(unsigned i2c_index, int speed, int slave_addr, struct i2c_pads_info *p); -void bus_i2c_init(void *base, int speed, int slave_addr, +void bus_i2c_init(int index, int speed, int slave_addr, int (*idle_bus_fn)(void *p), void *p); -int bus_i2c_read(void *base, uchar chip, uint addr, int alen, uchar *buf, - int len); -int bus_i2c_write(void *base, uchar chip, uint addr, int alen, - const uchar *buf, int len); #endif diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index fc5ee35..9894f3e 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -21,26 +21,21 @@ #include asm/io.h #include i2c.h #include watchdog.h +#include dm.h +#include fdtdec.h DECLARE_GLOBAL_DATA_PTR; -#ifdef I2C_QUIRK_REG -struct mxc_i2c_regs { - uint8_t iadr; - uint8_t ifdr; - uint8_t i2cr; - uint8_t i2sr; - uint8_t i2dr; -}; -#else -struct mxc_i2c_regs { - uint32_tiadr; - uint32_tifdr; - uint32_ti2cr; - uint32_ti2sr; - uint32_ti2dr; -}; -#endif +#define I2C_QUIRK_FLAG (1 0) + +#define IMX_I2C_REGSHIFT 2 +#define VF610_I2C_REGSHIFT 0 +/* Register index */ +#define IADR 0 +#define IFDR 1 +#define I2CR 2 +#define I2SR 3 +#define I2DR 4 #define I2CR_IIEN (1 6) #define I2CR_MSTA (1 5) @@ -68,6 +63,23 @@ struct mxc_i2c_regs { #error define CONFIG_SYS_I2C_BASE to use the mxc_i2c driver #endif +/* + * Information about i2c controller + * struct mxc_i2c_bus - information about the i2c[x] bus + * @base: Address of I2C bus controller + * @speed: Speed of I2C bus + * @driver_data: Flags for different platforms, such as I2C_QUIRK_FLAG. + * @idle_bus_fn: function to force bus idle + * @idle_bus_data: parameter for idle_bus_fun + */ +struct mxc_i2c_bus { + ulong base; + ulong driver_data; + int speed; + int (*idle_bus_fn)(void *p); + void *idle_bus_data; +}; + #ifdef I2C_QUIRK_REG static u16 i2c_clk_div[60][2] = { { 20, 0x00 }, { 22, 0x01 }, { 24, 0x02 }, { 26, 0x03 }, @@ -104,7 +116,6 @@ static u16 i2c_clk_div[50][2] = { }; #endif - #ifndef CONFIG_SYS_MXC_I2C1_SPEED #define CONFIG_SYS_MXC_I2C1_SPEED 10 #endif @@ -125,11 +136,10 @@ static u16 i2c_clk_div[50][2] = { #define CONFIG_SYS_MXC_I2C3_SLAVE 0 #endif - /* * Calculate and set proper clock divider */ -static uint8_t