Merge git://git.denx.de/u-boot-i2c

This commit is contained in:
Tom Rini 2017-12-07 07:28:20 -05:00
commit bd1e3bcc0b
4 changed files with 42 additions and 34 deletions

View file

@ -1156,7 +1156,10 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
uint chip; uint chip;
u_char data[128]; u_char data[128];
u_char cksum; u_char cksum;
int j; int j, ret;
#ifdef CONFIG_DM_I2C
struct udevice *dev;
#endif
static const char *decode_CAS_DDR2[] = { static const char *decode_CAS_DDR2[] = {
" TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD" " 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); 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"); puts ("No SDRAM Serial Presence Detect found.\n");
return 1; return 1;
} }

View file

@ -141,7 +141,12 @@ config SYS_I2C_MESON
bool "Amlogic Meson I2C driver" bool "Amlogic Meson I2C driver"
depends on DM_I2C && ARCH_MESON depends on DM_I2C && ARCH_MESON
help 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 config SYS_I2C_MXC
bool "NXP i.MX I2C driver" bool "NXP i.MX I2C driver"

View file

@ -72,6 +72,8 @@ static int at91_i2c_xfer_msg(struct at91_i2c_bus *bus, struct i2c_msg *msg)
} else { } else {
writel(msg->buf[0], &reg->thr); writel(msg->buf[0], &reg->thr);
ret = at91_wait_for_xfer(bus, TWI_SR_TXRDY);
for (i = 1; !ret && (i < msg->len); i++) { for (i = 1; !ret && (i < msg->len); i++) {
writel(msg->buf[i], &reg->thr); writel(msg->buf[i], &reg->thr);
ret = at91_wait_for_xfer(bus, TWI_SR_TXRDY); ret = at91_wait_for_xfer(bus, TWI_SR_TXRDY);
@ -199,27 +201,6 @@ static int at91_i2c_enable_clk(struct udevice *dev)
return 0; 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, &reg->cr);
at91_calc_i2c_clock(dev, bus->clock_frequency);
writel(bus->cwgr_val, &reg->cwgr);
writel(TWI_CR_MSEN, &reg->cr);
writel(TWI_CR_SVDIS, &reg->cr);
return 0;
}
static int at91_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) static int at91_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
{ {
struct at91_i2c_bus *bus = dev_get_priv(dev); 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 = { static const struct dm_i2c_ops at91_i2c_ops = {
.xfer = at91_i2c_xfer, .xfer = at91_i2c_xfer,
.probe_chip = at91_i2c_probe_chip,
.set_bus_speed = at91_i2c_set_bus_speed, .set_bus_speed = at91_i2c_set_bus_speed,
.get_bus_speed = at91_i2c_get_bus_speed, .get_bus_speed = at91_i2c_get_bus_speed,
}; };

View file

@ -9,7 +9,7 @@
#include <dm.h> #include <dm.h>
#include <i2c.h> #include <i2c.h>
#define I2C_TIMEOUT_MS 500 #define I2C_TIMEOUT_MS 100
/* Control register fields */ /* Control register fields */
#define REG_CTRL_START BIT(0) #define REG_CTRL_START BIT(0)
@ -44,12 +44,12 @@ struct i2c_regs {
struct meson_i2c { struct meson_i2c {
struct i2c_regs *regs; struct i2c_regs *regs;
struct i2c_msg *msg; struct i2c_msg *msg; /* Current I2C message */
bool last; bool last; /* Whether the message is the last */
uint count; uint count; /* Number of bytes in the current transfer */
uint pos; uint pos; /* Position of current transfer in message */
u32 tokens[2]; u32 tokens[2]; /* Sequence of tokens to be written */
uint num_tokens; uint num_tokens; /* Number of tokens to be written */
}; };
static void meson_i2c_reset_tokens(struct meson_i2c *i2c) 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++; 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) static void meson_i2c_get_data(struct meson_i2c *i2c, u8 *buf, int len)
{ {
u32 rdata0, rdata1; 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; *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) static void meson_i2c_put_data(struct meson_i2c *i2c, u8 *buf, int len)
{ {
u32 wdata0 = 0, wdata1 = 0; 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); 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) static void meson_i2c_prepare_xfer(struct meson_i2c *i2c)
{ {
bool write = !(i2c->msg->flags & I2C_M_RD); 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) { if (readl(&i2c->regs->ctrl) & REG_CTRL_ERROR) {
debug("meson i2c: error\n"); debug("meson i2c: error\n");
return -ENXIO; return -EREMOTEIO;
} }
if ((msg->flags & I2C_M_RD) && i2c->count) { 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++) { for (i = 0; i < nmsgs; i++) {
ret = meson_i2c_xfer_msg(i2c, msg + i, i == nmsgs - 1); ret = meson_i2c_xfer_msg(i2c, msg + i, i == nmsgs - 1);
if (ret) if (ret)
return -EREMOTEIO; return ret;
} }
return 0; return 0;