diff options
-rw-r--r-- | cmd/i2c.c | 14 | ||||
-rw-r--r-- | drivers/i2c/Kconfig | 7 | ||||
-rw-r--r-- | drivers/i2c/at91_i2c.c | 24 | ||||
-rw-r--r-- | drivers/i2c/meson_i2c.c | 31 |
4 files changed, 42 insertions, 34 deletions
diff --git a/cmd/i2c.c b/cmd/i2c.c index 3dd7c6ba4de..bfddf8be1b9 100644 --- a/cmd/i2c.c +++ b/cmd/i2c.c @@ -1156,7 +1156,10 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) uint chip; u_char data[128]; u_char cksum; - int j; + int j, ret; +#ifdef CONFIG_DM_I2C + struct udevice *dev; +#endif static const char *decode_CAS_DDR2[] = { " TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD" @@ -1210,7 +1213,14 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) */ chip = simple_strtoul (argv[1], NULL, 16); - if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) { +#ifdef CONFIG_DM_I2C + ret = i2c_get_cur_bus_chip(chip, &dev); + if (!ret) + ret = dm_i2c_read(dev, 0, data, sizeof(data)); +#else + ret = i2c_read(chip, 0, 1, data, sizeof(data)); +#endif + if (ret) { puts ("No SDRAM Serial Presence Detect found.\n"); return 1; } diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index cc370b9c57c..0630712e4a4 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -141,7 +141,12 @@ config SYS_I2C_MESON bool "Amlogic Meson I2C driver" depends on DM_I2C && ARCH_MESON help - Add support for the Amlogic Meson I2C driver. + Add support for the I2C controller available in Amlogic Meson + SoCs. The controller supports programmable bus speed including + standard (100kbits/s) and fast (400kbit/s) speed and allows the + software to define a flexible format of the bit streams. It has an + internal buffer holding up to 8 bytes for transfers and supports + both 7-bit and 10-bit addresses. config SYS_I2C_MXC bool "NXP i.MX I2C driver" diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c index d394044f80d..7917ca12312 100644 --- a/drivers/i2c/at91_i2c.c +++ b/drivers/i2c/at91_i2c.c @@ -72,6 +72,8 @@ static int at91_i2c_xfer_msg(struct at91_i2c_bus *bus, struct i2c_msg *msg) } else { writel(msg->buf[0], ®->thr); + ret = at91_wait_for_xfer(bus, TWI_SR_TXRDY); + for (i = 1; !ret && (i < msg->len); i++) { writel(msg->buf[i], ®->thr); ret = at91_wait_for_xfer(bus, TWI_SR_TXRDY); @@ -199,27 +201,6 @@ static int at91_i2c_enable_clk(struct udevice *dev) return 0; } -static int at91_i2c_probe_chip(struct udevice *dev, uint chip, uint chip_flags) -{ - struct at91_i2c_bus *bus = dev_get_priv(dev); - struct at91_i2c_regs *reg = bus->regs; - int ret; - - ret = at91_i2c_enable_clk(dev); - if (ret) - return ret; - - writel(TWI_CR_SWRST, ®->cr); - - at91_calc_i2c_clock(dev, bus->clock_frequency); - - writel(bus->cwgr_val, ®->cwgr); - writel(TWI_CR_MSEN, ®->cr); - writel(TWI_CR_SVDIS, ®->cr); - - return 0; -} - static int at91_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) { struct at91_i2c_bus *bus = dev_get_priv(dev); @@ -254,7 +235,6 @@ static int at91_i2c_ofdata_to_platdata(struct udevice *dev) static const struct dm_i2c_ops at91_i2c_ops = { .xfer = at91_i2c_xfer, - .probe_chip = at91_i2c_probe_chip, .set_bus_speed = at91_i2c_set_bus_speed, .get_bus_speed = at91_i2c_get_bus_speed, }; diff --git a/drivers/i2c/meson_i2c.c b/drivers/i2c/meson_i2c.c index 2434d9ed538..4f37d2f3168 100644 --- a/drivers/i2c/meson_i2c.c +++ b/drivers/i2c/meson_i2c.c @@ -9,7 +9,7 @@ #include <dm.h> #include <i2c.h> -#define I2C_TIMEOUT_MS 500 +#define I2C_TIMEOUT_MS 100 /* Control register fields */ #define REG_CTRL_START BIT(0) @@ -44,12 +44,12 @@ struct i2c_regs { struct meson_i2c { struct i2c_regs *regs; - struct i2c_msg *msg; - bool last; - uint count; - uint pos; - u32 tokens[2]; - uint num_tokens; + struct i2c_msg *msg; /* Current I2C message */ + bool last; /* Whether the message is the last */ + uint count; /* Number of bytes in the current transfer */ + uint pos; /* Position of current transfer in message */ + u32 tokens[2]; /* Sequence of tokens to be written */ + uint num_tokens; /* Number of tokens to be written */ }; static void meson_i2c_reset_tokens(struct meson_i2c *i2c) @@ -69,6 +69,10 @@ static void meson_i2c_add_token(struct meson_i2c *i2c, int token) i2c->num_tokens++; } +/* + * Retrieve data for the current transfer (which can be at most 8 + * bytes) from the device internal buffer. + */ static void meson_i2c_get_data(struct meson_i2c *i2c, u8 *buf, int len) { u32 rdata0, rdata1; @@ -86,6 +90,10 @@ static void meson_i2c_get_data(struct meson_i2c *i2c, u8 *buf, int len) *buf++ = (rdata1 >> (i - 4) * 8) & 0xff; } +/* + * Write data for the current transfer (which can be at most 8 bytes) + * to the device internal buffer. + */ static void meson_i2c_put_data(struct meson_i2c *i2c, u8 *buf, int len) { u32 wdata0 = 0, wdata1 = 0; @@ -103,6 +111,11 @@ static void meson_i2c_put_data(struct meson_i2c *i2c, u8 *buf, int len) debug("meson i2c: write data %08x %08x len %d\n", wdata0, wdata1, len); } +/* + * Prepare the next transfer: pick the next 8 bytes in the remaining + * part of message and write tokens and data (if needed) to the + * device. + */ static void meson_i2c_prepare_xfer(struct meson_i2c *i2c) { bool write = !(i2c->msg->flags & I2C_M_RD); @@ -178,7 +191,7 @@ static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg, if (readl(&i2c->regs->ctrl) & REG_CTRL_ERROR) { debug("meson i2c: error\n"); - return -ENXIO; + return -EREMOTEIO; } if ((msg->flags & I2C_M_RD) && i2c->count) { @@ -200,7 +213,7 @@ static int meson_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, for (i = 0; i < nmsgs; i++) { ret = meson_i2c_xfer_msg(i2c, msg + i, i == nmsgs - 1); if (ret) - return -EREMOTEIO; + return ret; } return 0; |