summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorLei Wen <leiwen@marvell.com>2011-09-30 05:44:12 +0000
committerHeiko Schocher <hs@denx.de>2011-10-03 11:50:09 +0200
commitd308c9d35aee2578d0a69a9ecb8bc7fd7df8fa2d (patch)
treec5fdd8ec8755a96abbfe9bcad001a058be5deb98 /drivers/i2c
parent2be1ed349ca268d3867840fd28960785fd3def0b (diff)
downloadu-boot-imx-d308c9d35aee2578d0a69a9ecb8bc7fd7df8fa2d.zip
u-boot-imx-d308c9d35aee2578d0a69a9ecb8bc7fd7df8fa2d.tar.gz
u-boot-imx-d308c9d35aee2578d0a69a9ecb8bc7fd7df8fa2d.tar.bz2
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>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/mv_i2c.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 8eb30e7..b93922b 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -67,6 +67,27 @@ struct mv_i2c {
};
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
static u32 i2c_regs[CONFIG_MV_I2C_NUM] = CONFIG_MV_I2C_REG;
static unsigned int bus_initialized[CONFIG_MV_I2C_NUM];
@@ -83,7 +104,7 @@ int i2c_set_bus_num(unsigned int bus)
current_bus = 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;
}
@@ -264,28 +285,13 @@ i2c_transfer_finish:
void i2c_init(int speed, int slaveaddr)
{
#ifdef CONFIG_I2C_MULTI_BUS
+ current_bus = 0;
base = (struct mv_i2c *)i2c_regs[current_bus];
#else
base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
#endif
-#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
+ i2c_board_init(base);
}
/*