dm: i2c: Add an explicit test mode to the sandbox I2C driver

At present this driver has a few test features. They are needed for running
the driver model unit tests but are confusing and unnecessary if using
sandbox at the command line. Add a flag to enable the test mode, and don't
enable it by default.

Signed-off-by: Simon Glass <sjg@chromium.org>
master
Simon Glass 9 years ago
parent ba3864f803
commit 182bf92d19
  1. 10
      arch/sandbox/include/asm/test.h
  2. 34
      drivers/i2c/sandbox_i2c.c
  3. 1
      include/i2c.h
  4. 8
      test/dm/i2c.c

@ -17,6 +17,16 @@
#define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM #define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM
#define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL #define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
/**
* sandbox_i2c_set_test_mode() - set test mode for running unit tests
*
* See sandbox_i2c_xfer() for the behaviour changes.
*
* @bus: sandbox I2C bus to adjust
* @test_mode: true to select test mode, false to run normally
*/
void sandbox_i2c_set_test_mode(struct udevice *bus, bool test_mode);
enum sandbox_i2c_eeprom_test_mode { enum sandbox_i2c_eeprom_test_mode {
SIE_TEST_MODE_NONE, SIE_TEST_MODE_NONE,
/* Permits read/write of only one byte per I2C transaction */ /* Permits read/write of only one byte per I2C transaction */

@ -18,8 +18,8 @@
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
struct dm_sandbox_i2c_emul_priv { struct sandbox_i2c_priv {
struct udevice *emul; bool test_mode;
}; };
static int get_emul(struct udevice *dev, struct udevice **devp, static int get_emul(struct udevice *dev, struct udevice **devp,
@ -47,17 +47,25 @@ static int get_emul(struct udevice *dev, struct udevice **devp,
return 0; return 0;
} }
void sandbox_i2c_set_test_mode(struct udevice *bus, bool test_mode)
{
struct sandbox_i2c_priv *priv = dev_get_priv(bus);
priv->test_mode = test_mode;
}
static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
int nmsgs) int nmsgs)
{ {
struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
struct sandbox_i2c_priv *priv = dev_get_priv(bus);
struct dm_i2c_ops *ops; struct dm_i2c_ops *ops;
struct udevice *emul, *dev; struct udevice *emul, *dev;
bool is_read; bool is_read;
int ret; int ret;
/* Special test code to return success but with no emulation */ /* Special test code to return success but with no emulation */
if (msg->addr == SANDBOX_I2C_TEST_ADDR) if (priv->test_mode && msg->addr == SANDBOX_I2C_TEST_ADDR)
return 0; return 0;
ret = i2c_get_chip(bus, msg->addr, 1, &dev); ret = i2c_get_chip(bus, msg->addr, 1, &dev);
@ -68,15 +76,18 @@ static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
if (ret) if (ret)
return ret; return ret;
/* if (priv->test_mode) {
* For testing, don't allow writing above 100KHz for writes and /*
* 400KHz for reads * For testing, don't allow writing above 100KHz for writes and
*/ * 400KHz for reads.
is_read = nmsgs > 1; */
if (i2c->speed_hz > (is_read ? 400000 : 100000)) { is_read = nmsgs > 1;
debug("%s: Max speed exceeded\n", __func__); if (i2c->speed_hz > (is_read ? 400000 : 100000)) {
return -EINVAL; debug("%s: Max speed exceeded\n", __func__);
return -EINVAL;
}
} }
return ops->xfer(emul, msg, nmsgs); return ops->xfer(emul, msg, nmsgs);
} }
@ -94,4 +105,5 @@ U_BOOT_DRIVER(i2c_sandbox) = {
.id = UCLASS_I2C, .id = UCLASS_I2C,
.of_match = sandbox_i2c_ids, .of_match = sandbox_i2c_ids,
.ops = &sandbox_i2c_ops, .ops = &sandbox_i2c_ops,
.priv_auto_alloc_size = sizeof(struct sandbox_i2c_priv),
}; };

@ -54,6 +54,7 @@ struct dm_i2c_chip {
uint flags; uint flags;
#ifdef CONFIG_SANDBOX #ifdef CONFIG_SANDBOX
struct udevice *emul; struct udevice *emul;
bool test_mode;
#endif #endif
}; };

@ -66,6 +66,9 @@ static int dm_test_i2c_speed(struct dm_test_state *dms)
uint8_t buf[5]; uint8_t buf[5];
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
/* Use test mode so we create the required errors for invalid speeds */
sandbox_i2c_set_test_mode(bus, true);
ut_assertok(i2c_get_chip(bus, chip, 1, &dev)); ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
ut_assertok(dm_i2c_set_bus_speed(bus, 100000)); ut_assertok(dm_i2c_set_bus_speed(bus, 100000));
ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(dm_i2c_read(dev, 0, buf, 5));
@ -73,6 +76,7 @@ static int dm_test_i2c_speed(struct dm_test_state *dms)
ut_asserteq(400000, dm_i2c_get_bus_speed(bus)); ut_asserteq(400000, dm_i2c_get_bus_speed(bus));
ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(dm_i2c_read(dev, 0, buf, 5));
ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5)); ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5));
sandbox_i2c_set_test_mode(bus, false);
return 0; return 0;
} }
@ -100,7 +104,11 @@ static int dm_test_i2c_probe_empty(struct dm_test_state *dms)
struct udevice *bus, *dev; struct udevice *bus, *dev;
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
/* Use test mode so that this chip address will always probe */
sandbox_i2c_set_test_mode(bus, true);
ut_assertok(dm_i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev)); ut_assertok(dm_i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev));
sandbox_i2c_set_test_mode(bus, false);
return 0; return 0;
} }

Loading…
Cancel
Save