mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-20 22:21:41 +00:00
I2C: mv_i2c: fix multi-bus init issue
When enable the multi-bus, the current_bus is not inited in the original implementation, which make the i2c operation unpredicatable. Signed-off-by: Lei Wen <leiwen@marvell.com>
This commit is contained in:
parent
2be1ed349c
commit
d308c9d35a
1 changed files with 24 additions and 18 deletions
|
@ -67,6 +67,27 @@ struct mv_i2c {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mv_i2c *base;
|
static struct mv_i2c *base;
|
||||||
|
static void i2c_board_init(struct mv_i2c *base)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SYS_I2C_INIT_BOARD
|
||||||
|
u32 icr;
|
||||||
|
/*
|
||||||
|
* call board specific i2c bus reset routine before accessing the
|
||||||
|
* environment, which might be in a chip on that bus. For details
|
||||||
|
* about this problem see doc/I2C_Edge_Conditions.
|
||||||
|
*
|
||||||
|
* disable I2C controller first, otherwhise it thinks we want to
|
||||||
|
* talk to the slave port...
|
||||||
|
*/
|
||||||
|
icr = readl(&base->icr);
|
||||||
|
writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
|
||||||
|
|
||||||
|
i2c_init_board();
|
||||||
|
|
||||||
|
writel(icr, &base->icr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_I2C_MULTI_BUS
|
#ifdef CONFIG_I2C_MULTI_BUS
|
||||||
static u32 i2c_regs[CONFIG_MV_I2C_NUM] = CONFIG_MV_I2C_REG;
|
static u32 i2c_regs[CONFIG_MV_I2C_NUM] = CONFIG_MV_I2C_REG;
|
||||||
static unsigned int bus_initialized[CONFIG_MV_I2C_NUM];
|
static unsigned int bus_initialized[CONFIG_MV_I2C_NUM];
|
||||||
|
@ -83,7 +104,7 @@ int i2c_set_bus_num(unsigned int bus)
|
||||||
current_bus = bus;
|
current_bus = bus;
|
||||||
|
|
||||||
if (!bus_initialized[current_bus]) {
|
if (!bus_initialized[current_bus]) {
|
||||||
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
i2c_board_init(base);
|
||||||
bus_initialized[current_bus] = 1;
|
bus_initialized[current_bus] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,28 +285,13 @@ i2c_transfer_finish:
|
||||||
void i2c_init(int speed, int slaveaddr)
|
void i2c_init(int speed, int slaveaddr)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_I2C_MULTI_BUS
|
#ifdef CONFIG_I2C_MULTI_BUS
|
||||||
|
current_bus = 0;
|
||||||
base = (struct mv_i2c *)i2c_regs[current_bus];
|
base = (struct mv_i2c *)i2c_regs[current_bus];
|
||||||
#else
|
#else
|
||||||
base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
|
base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_I2C_INIT_BOARD
|
i2c_board_init(base);
|
||||||
u32 icr;
|
|
||||||
/*
|
|
||||||
* call board specific i2c bus reset routine before accessing the
|
|
||||||
* environment, which might be in a chip on that bus. For details
|
|
||||||
* about this problem see doc/I2C_Edge_Conditions.
|
|
||||||
*
|
|
||||||
* disable I2C controller first, otherwhise it thinks we want to
|
|
||||||
* talk to the slave port...
|
|
||||||
*/
|
|
||||||
icr = readl(&base->icr);
|
|
||||||
writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
|
|
||||||
|
|
||||||
i2c_init_board();
|
|
||||||
|
|
||||||
writel(icr, &base->icr);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue