From 182bf92d19cf007c2d6b9a264107d6996ae9014f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:15 -0600 Subject: [PATCH] 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 --- arch/sandbox/include/asm/test.h | 10 ++++++++++ drivers/i2c/sandbox_i2c.c | 34 +++++++++++++++++++++++----------- include/i2c.h | 1 + test/dm/i2c.c | 8 ++++++++ 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 296589c..06e7301 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -17,6 +17,16 @@ #define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM #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 { SIE_TEST_MODE_NONE, /* Permits read/write of only one byte per I2C transaction */ diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c index 621caec..dd1c7e5 100644 --- a/drivers/i2c/sandbox_i2c.c +++ b/drivers/i2c/sandbox_i2c.c @@ -18,8 +18,8 @@ DECLARE_GLOBAL_DATA_PTR; -struct dm_sandbox_i2c_emul_priv { - struct udevice *emul; +struct sandbox_i2c_priv { + bool test_mode; }; 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; } +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, int nmsgs) { 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 udevice *emul, *dev; bool is_read; int ret; /* 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; 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) return ret; - /* - * 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)) { - debug("%s: Max speed exceeded\n", __func__); - return -EINVAL; + if (priv->test_mode) { + /* + * 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)) { + debug("%s: Max speed exceeded\n", __func__); + return -EINVAL; + } } + return ops->xfer(emul, msg, nmsgs); } @@ -94,4 +105,5 @@ U_BOOT_DRIVER(i2c_sandbox) = { .id = UCLASS_I2C, .of_match = sandbox_i2c_ids, .ops = &sandbox_i2c_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_i2c_priv), }; diff --git a/include/i2c.h b/include/i2c.h index d794057..1e25986 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -54,6 +54,7 @@ struct dm_i2c_chip { uint flags; #ifdef CONFIG_SANDBOX struct udevice *emul; + bool test_mode; #endif }; diff --git a/test/dm/i2c.c b/test/dm/i2c.c index 541b73b..c5939a1 100644 --- a/test/dm/i2c.c +++ b/test/dm/i2c.c @@ -66,6 +66,9 @@ static int dm_test_i2c_speed(struct dm_test_state *dms) uint8_t buf[5]; 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(dm_i2c_set_bus_speed(bus, 100000)); 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_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5)); + sandbox_i2c_set_test_mode(bus, false); return 0; } @@ -100,7 +104,11 @@ static int dm_test_i2c_probe_empty(struct dm_test_state *dms) struct udevice *bus, *dev; 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)); + sandbox_i2c_set_test_mode(bus, false); return 0; }