diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/i2c_core.c | 5 | ||||
-rw-r--r-- | drivers/i2c/mxc_i2c.c | 27 | ||||
-rw-r--r-- | drivers/i2c/rk_i2c.c | 6 |
3 files changed, 34 insertions, 4 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/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c index 3fceade61e..63b141838b 100644 --- a/drivers/i2c/rk_i2c.c +++ b/drivers/i2c/rk_i2c.c @@ -29,10 +29,9 @@ DECLARE_GLOBAL_DATA_PTR; #define RK_I2C_FIFO_SIZE 32 struct rk_i2c { - struct udevice *clk; + struct clk clk; struct i2c_regs *regs; unsigned int speed; - int clk_id; }; static inline void rk_i2c_get_div(int div, int *divh, int *divl) @@ -55,7 +54,7 @@ static void rk_i2c_set_clk(struct rk_i2c *i2c, uint32_t scl_rate) int div, divl, divh; /* First get i2c rate from pclk */ - i2c_rate = clk_get_periph_rate(i2c->clk, i2c->clk_id); + i2c_rate = clk_get_rate(&i2c->clk); div = DIV_ROUND_UP(i2c_rate, scl_rate * 8) - 2; divh = 0; @@ -362,7 +361,6 @@ static int rockchip_i2c_ofdata_to_platdata(struct udevice *bus) bus->name, ret); return ret; } - priv->clk_id = ret; return 0; } |