Introduce the INA230 qtest: the qgraph node and the register map. Cover the power-on-reset defaults and Die ID, the software reset, and the Configuration register write mask. The QMP voltage-injection helpers arrive with the following commit that exercises them.
Signed-off-by: Emmanuel Blot <[email protected]> --- tests/qtest/ina230-test.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 1 + 2 files changed, 116 insertions(+) diff --git a/tests/qtest/ina230-test.c b/tests/qtest/ina230-test.c new file mode 100644 index 0000000000..f7aefd2d97 --- /dev/null +++ b/tests/qtest/ina230-test.c @@ -0,0 +1,115 @@ +/* + * QTest testcase for the INA230 current/voltage/power monitor + * + * Copyright (c) 2026 Meta Platforms, Inc. and affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "libqos/i2c.h" +#include "libqos/qgraph.h" +#include "libqtest-single.h" +#include "qobject/qdict.h" + +#define INA230_TEST_ID "ina230-test" +#define INA230_TEST_ADDR 0x40 + +/* Register pointer addresses */ +#define REG_CONFIG 0x00 +#define REG_SHUNT 0x01 +#define REG_BUS 0x02 +#define REG_POWER 0x03 +#define REG_CURRENT 0x04 +#define REG_CALIBRATION 0x05 +#define REG_MASK_ENABLE 0x06 +#define REG_ALERT_LIMIT 0x07 +#define REG_DIE_ID 0xFF + +/* Configuration register bits */ +#define CONFIG_POR 0x4127 +#define CONFIG_RST 0x8000 + +/* Mask/Enable register bits */ +#define ME_LEN 0x0001 +#define ME_APOL 0x0002 +#define ME_OVF 0x0004 +#define ME_CVRF 0x0008 +#define ME_AFF 0x0010 +#define ME_CNVR 0x0400 +#define ME_POL 0x0800 +#define ME_BUL 0x1000 +#define ME_BOL 0x2000 +#define ME_SUL 0x4000 +#define ME_SOL 0x8000 + +/* Injected-input scaling (datasheet fixed LSBs) */ +#define SHUNT_LSB_NV 2500 +#define BUS_LSB_UV 1250 + +#define DIE_ID_VAL 0x2310 + +/* Power-on-reset default values and the Die ID */ +static void test_defaults(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + g_assert_cmphex(i2c_get16(dev, REG_CONFIG), ==, CONFIG_POR); + g_assert_cmphex(i2c_get16(dev, REG_SHUNT), ==, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_BUS), ==, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_POWER), ==, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_CALIBRATION), ==, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE), ==, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_ALERT_LIMIT), ==, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_DIE_ID), ==, DIE_ID_VAL); +} + +/* Software reset via the Configuration RST bit */ +static void test_soft_reset(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + i2c_set16(dev, REG_CALIBRATION, 0x1234); + i2c_set16(dev, REG_MASK_ENABLE, ME_SOL); + i2c_set16(dev, REG_ALERT_LIMIT, 0x0500); + + g_assert_cmphex(i2c_get16(dev, REG_CALIBRATION), ==, 0x1234); + g_assert_cmphex(i2c_get16(dev, REG_ALERT_LIMIT), ==, 0x0500); + + i2c_set16(dev, REG_CONFIG, CONFIG_RST); + + g_assert_cmphex(i2c_get16(dev, REG_CONFIG), ==, CONFIG_POR); + g_assert_cmphex(i2c_get16(dev, REG_CALIBRATION), ==, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE), ==, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_ALERT_LIMIT), ==, 0x0000); +} + +/* Every bit except the self-clearing RST is writable and reads back */ +static void test_config_wmask(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + /* Reserved bits are not forced: the guest value is retained */ + i2c_set16(dev, REG_CONFIG, 0x0007); + g_assert_cmphex(i2c_get16(dev, REG_CONFIG), ==, 0x0007); + + i2c_set16(dev, REG_CONFIG, 0x7FFF); + g_assert_cmphex(i2c_get16(dev, REG_CONFIG), ==, 0x7FFF); +} + +static void ina230_register_nodes(void) +{ + QOSGraphEdgeOptions opts = { + .extra_device_opts = "id=" INA230_TEST_ID ",address=0x40" + }; + add_qi2c_address(&opts, &(QI2CAddress) { INA230_TEST_ADDR }); + + qos_node_create_driver("ina230", i2c_device_create); + qos_node_consumes("ina230", "i2c-bus", &opts); + + qos_add_test("defaults", "ina230", test_defaults, NULL); + qos_add_test("soft-reset", "ina230", test_soft_reset, NULL); + qos_add_test("config-wmask", "ina230", test_config_wmask, NULL); +} +libqos_init(ina230_register_nodes); diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 2bf3f5555b..97480d92aa 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -324,6 +324,7 @@ qos_test_ss.add( 'e1000-test.c', 'eepro100-test.c', 'es1370-test.c', + 'ina230-test.c', 'lsm303dlhc-mag-test.c', 'isl_pmbus_vr-test.c', 'max34451-test.c', -- 2.50.1
