The register map is a set of per-model class properties. Pin the values it holds for this part, so a later change cannot alter them unnoticed.
Signed-off-by: Emmanuel Blot <[email protected]> --- tests/qtest/ds1338-test.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/tests/qtest/ds1338-test.c b/tests/qtest/ds1338-test.c index b8d0e65ec44..6066a348465 100644 --- a/tests/qtest/ds1338-test.c +++ b/tests/qtest/ds1338-test.c @@ -24,6 +24,15 @@ #define DS1338_ADDR 0x68 +/* DS1338 register map */ +#define DS1338_SECONDS 0x00 +#define DS1338_CONTROL 0x07 +#define DS1338_NVRAM 0x08 +#define DS1338_NUM_REGS 0x40 + +#define DS1338_CTRL_OSF 0x20 + +/* The clock and calendar come up on the host time. */ static void send_and_receive(void *obj, void *data, QGuestAllocator *alloc) { QI2CDevice *i2cdev = (QI2CDevice *)obj; @@ -32,7 +41,7 @@ static void send_and_receive(void *obj, void *data, QGuestAllocator *alloc) time_t now = time(NULL); struct tm *tm_ptr = gmtime(&now); - i2c_read_block(i2cdev, 0, resp, sizeof(resp)); + i2c_read_block(i2cdev, DS1338_SECONDS, resp, sizeof(resp)); /* check retrieved time against local time */ g_assert_cmpuint(from_bcd(resp[4]), == , tm_ptr->tm_mday); @@ -40,6 +49,56 @@ static void send_and_receive(void *obj, void *data, QGuestAllocator *alloc) g_assert_cmpuint(2000 + from_bcd(resp[6]), == , 1900 + tm_ptr->tm_year); } +/* Writable control bits round-trip; the reserved ones read back zero. */ +static void test_control_register(void *obj, void *data, + QGuestAllocator *alloc) +{ + QI2CDevice *i2cdev = (QI2CDevice *)obj; + + i2c_set8(i2cdev, DS1338_CONTROL, 0x93); + g_assert_cmphex(i2c_get8(i2cdev, DS1338_CONTROL), ==, 0x93); + + i2c_set8(i2cdev, DS1338_CONTROL, 0x4c); + g_assert_cmphex(i2c_get8(i2cdev, DS1338_CONTROL), ==, 0x00); +} + +/* The oscillator-stop flag can only be cleared by a write, never set. */ +static void test_osf_write_protect(void *obj, void *data, + QGuestAllocator *alloc) +{ + QI2CDevice *i2cdev = (QI2CDevice *)obj; + + g_assert_cmphex(i2c_get8(i2cdev, DS1338_CONTROL) & DS1338_CTRL_OSF, + ==, DS1338_CTRL_OSF); + i2c_set8(i2cdev, DS1338_CONTROL, 0x00); + g_assert_cmphex(i2c_get8(i2cdev, DS1338_CONTROL) & DS1338_CTRL_OSF, ==, 0); + i2c_set8(i2cdev, DS1338_CONTROL, DS1338_CTRL_OSF); + g_assert_cmphex(i2c_get8(i2cdev, DS1338_CONTROL) & DS1338_CTRL_OSF, ==, 0); +} + +/* The user RAM returns what the guest wrote to it. */ +static void test_nvram(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *i2cdev = (QI2CDevice *)obj; + + i2c_set8(i2cdev, 0x08, 0xaa); + i2c_set8(i2cdev, 0x20, 0x55); + i2c_set8(i2cdev, 0x3f, 0xc3); + + g_assert_cmphex(i2c_get8(i2cdev, 0x08), ==, 0xaa); + g_assert_cmphex(i2c_get8(i2cdev, 0x20), ==, 0x55); + g_assert_cmphex(i2c_get8(i2cdev, 0x3f), ==, 0xc3); +} + +/* The register pointer wraps at the end of the map. */ +static void test_address_wrap(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *i2cdev = (QI2CDevice *)obj; + + i2c_set8(i2cdev, DS1338_NVRAM, 0x5a); + g_assert_cmphex(i2c_get8(i2cdev, DS1338_NVRAM + DS1338_NUM_REGS), ==, 0x5a); +} + static void ds1338_register_nodes(void) { QOSGraphEdgeOptions opts = { @@ -49,6 +108,12 @@ static void ds1338_register_nodes(void) qos_node_create_driver("ds1338", i2c_device_create); qos_node_consumes("ds1338", "i2c-bus", &opts); + qos_add_test("tx-rx", "ds1338", send_and_receive, NULL); + qos_add_test("control-register", "ds1338", test_control_register, NULL); + qos_add_test("osf-write-protect", "ds1338", test_osf_write_protect, NULL); + qos_add_test("nvram", "ds1338", test_nvram, NULL); + qos_add_test("address-wrap", "ds1338", test_address_wrap, NULL); } + libqos_init(ds1338_register_nodes); -- 2.50.1
