diff options
author | Yuan Yao <yao.yuan@nxp.com> | 2016-06-08 18:24:51 +0800 |
---|---|---|
committer | York Sun <york.sun@nxp.com> | 2016-06-10 13:44:58 -0700 |
commit | 9d10c2d3fe6852501a4c43853fe3d2469903a2bb (patch) | |
tree | 11c10d005f12676fdadb55fed1952cf9017814ae | |
parent | 30677deefdf57a8a2d12a766117ea861ca38f52c (diff) |
drivers: i2c: mxc: Add early init
Add early i2c init function with conservative divider when the exact
clock rate is not available.
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
-rw-r--r-- | drivers/i2c/i2c_core.c | 5 | ||||
-rw-r--r-- | drivers/i2c/mxc_i2c.c | 27 | ||||
-rw-r--r-- | include/i2c.h | 3 |
3 files changed, 35 insertions, 0 deletions
diff --git a/drivers/i2c/i2c_core.c b/drivers/i2c/i2c_core.c index 41cc3b8fa4..16b1aba32a 100644 --- a/drivers/i2c/i2c_core.c +++ b/drivers/i2c/i2c_core.c @@ -233,6 +233,11 @@ __weak void i2c_init_board(void) { } +/* implement possible for i2c specific early i2c init */ +__weak void i2c_early_init_f(void) +{ +} + /* * i2c_init_all(): * diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index 445fa21082..f3402089a8 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -32,6 +32,14 @@ DECLARE_GLOBAL_DATA_PTR; #define IMX_I2C_REGSHIFT 2 #define VF610_I2C_REGSHIFT 0 + +#define I2C_EARLY_INIT_INDEX 0 +#ifdef CONFIG_SYS_I2C_IFDR_DIV +#define I2C_IFDR_DIV_CONSERVATIVE CONFIG_SYS_I2C_IFDR_DIV +#else +#define I2C_IFDR_DIV_CONSERVATIVE 0x7e +#endif + /* Register index */ #define IADR 0 #define IFDR 1 @@ -660,6 +668,25 @@ void bus_i2c_init(int index, int speed, int unused, } /* + * Early init I2C for prepare read the clk through I2C. + */ +void i2c_early_init_f(void) +{ + ulong base = mxc_i2c_buses[I2C_EARLY_INIT_INDEX].base; + bool quirk = mxc_i2c_buses[I2C_EARLY_INIT_INDEX].driver_data + & I2C_QUIRK_FLAG ? true : false; + int reg_shift = quirk ? VF610_I2C_REGSHIFT : IMX_I2C_REGSHIFT; + + /* Set I2C divider value */ + writeb(I2C_IFDR_DIV_CONSERVATIVE, base + (IFDR << reg_shift)); + /* Reset module */ + writeb(I2CR_IDIS, base + (I2CR << reg_shift)); + writeb(0, base + (I2SR << reg_shift)); + /* Enable I2C */ + writeb(I2CR_IEN, base + (I2CR << reg_shift)); +} + +/* * Init I2C Bus */ static void mxc_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) diff --git a/include/i2c.h b/include/i2c.h index 1f5ae4538a..d500445aaf 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -701,6 +701,9 @@ extern struct i2c_bus_hose i2c_bus[]; * Initialization, must be called once on start up, may be called * repeatedly to change the speed and slave addresses. */ +#ifdef CONFIG_SYS_I2C_EARLY_INIT +void i2c_early_init_f(void); +#endif void i2c_init(int speed, int slaveaddr); void i2c_init_board(void); #ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT |