Reviewed-by: Glenn Miles <[email protected]>

Thanks,

Glenn

On Mon, 2026-10-12 at 16:32 +0200, Emmanuel Blot via qemu development
wrote:
> Cover the shunt-, bus- and die-temperature injection properties and the
> current and power values derived through the Shunt Calibration register,
> including the zero-calibration case, the ADCRANGE rescaling and the
> clamp/overflow edges.
> 
> Signed-off-by: Emmanuel Blot <[email protected]>
> ---
>  tests/qtest/ina238-test.c | 156 
> ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 156 insertions(+)
> 
> diff --git a/tests/qtest/ina238-test.c b/tests/qtest/ina238-test.c
> index 6e59ed30b5..693139f988 100644
> --- a/tests/qtest/ina238-test.c
> +++ b/tests/qtest/ina238-test.c
> @@ -89,6 +89,20 @@ static void qmp_ina238_set(const char *property, int value)
>      qobject_unref(resp);
>  }
>  
> +static int qmp_ina238_get(const char *property)
> +{
> +    QDict *resp;
> +    int ret;
> +
> +    resp = qmp("{ 'execute': 'qom-get', 'arguments':"
> +               " { 'path': %s, 'property': %s } }",
> +               INA238_TEST_ID, property);
> +    g_assert(qdict_haskey(resp, "return"));
> +    ret = qdict_get_int(resp, "return");
> +    qobject_unref(resp);
> +    return ret;
> +}
> +
>  /* Power-on-reset default values and the ID registers */
>  static void test_defaults(void *obj, void *data, QGuestAllocator *alloc)
>  {
> @@ -160,6 +174,139 @@ static void test_config_wmask(void *obj, void *data, 
> QGuestAllocator *alloc)
>      g_assert_cmphex(i2c_get16(dev, REG_CONFIG), ==, CONFIG_POR);
>  }
>  
> +/* Shunt voltage register */
> +static void test_shunt_injection(void *obj, void *data, QGuestAllocator 
> *alloc)
> +{
> +    QI2CDevice *dev = (QI2CDevice *)obj;
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_RST);
> +
> +    qmp_ina238_set("shunt-voltage", 97200000);
> +    g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x4BF0);
> +
> +    qmp_ina238_set("shunt-voltage", -80000000);
> +    g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0xC180);
> +
> +    g_assert_cmpint(qmp_ina238_get("shunt-voltage"), ==, -80000000);
> +}
> +
> +/* Bus voltage register */
> +static void test_bus_injection(void *obj, void *data, QGuestAllocator *alloc)
> +{
> +    QI2CDevice *dev = (QI2CDevice *)obj;
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_RST);
> +
> +    qmp_ina238_set("bus-voltage", 48000000);
> +    g_assert_cmphex(i2c_get16(dev, REG_VBUS), ==, 0x3C00);
> +
> +    qmp_ina238_set("bus-voltage", 12000000);
> +    g_assert_cmphex(i2c_get16(dev, REG_VBUS), ==, 0x0F00);
> +}
> +
> +/* Die temperature register */
> +static void test_temp_injection(void *obj, void *data, QGuestAllocator 
> *alloc)
> +{
> +    QI2CDevice *dev = (QI2CDevice *)obj;
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_RST);
> +
> +    qmp_ina238_set("die-temperature", 25000);
> +    g_assert_cmphex(i2c_get16(dev, REG_DIETEMP), ==, 0x0C80);
> +
> +    qmp_ina238_set("die-temperature", -25000);
> +    g_assert_cmphex(i2c_get16(dev, REG_DIETEMP), ==, 0xF380);
> +
> +    g_assert_cmpint(qmp_ina238_get("die-temperature"), ==, -25000);
> +}
> +
> +/* Calibration-derived current */
> +static void test_calibration_current(void *obj, void *data,
> +                                     QGuestAllocator *alloc)
> +{
> +    QI2CDevice *dev = (QI2CDevice *)obj;
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_RST);
> +    qmp_ina238_set("shunt-voltage", 97200000);
> +
> +    i2c_set16(dev, REG_SHUNT_CAL, 0x0000);
> +    g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x0000);
> +
> +    i2c_set16(dev, REG_SHUNT_CAL, 0x0FD2);
> +    g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x4CCC);
> +}
> +
> +/* Calibration-derived power */
> +static void test_power(void *obj, void *data, QGuestAllocator *alloc)
> +{
> +    QI2CDevice *dev = (QI2CDevice *)obj;
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_RST);
> +    qmp_ina238_set("shunt-voltage", 97200000);
> +    qmp_ina238_set("bus-voltage", 48000000);
> +    i2c_set16(dev, REG_SHUNT_CAL, 0x0FD2);
> +
> +    g_assert_cmpuint(i2c_get24(dev, REG_POWER), ==, 4718400);
> +}
> +
> +/* With SHUNT_CAL == 0 the current and power registers stay zero */
> +static void test_zero_cal(void *obj, void *data, QGuestAllocator *alloc)
> +{
> +    QI2CDevice *dev = (QI2CDevice *)obj;
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_RST);
> +    i2c_set16(dev, REG_SHUNT_CAL, 0x0000);
> +    qmp_ina238_set("shunt-voltage", 97200000);
> +    qmp_ina238_set("bus-voltage", 48000000);
> +
> +    g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x0000);
> +    g_assert_cmpuint(i2c_get24(dev, REG_POWER), ==, 0);
> +}
> +
> +/* ADCRANGE changes the shunt LSB, not the current divisor. */
> +static void test_adcrange(void *obj, void *data, QGuestAllocator *alloc)
> +{
> +    QI2CDevice *dev = (QI2CDevice *)obj;
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_RST);
> +
> +    qmp_ina238_set("shunt-voltage", 20000000);
> +    g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x0FA0);
> +
> +    i2c_set16(dev, REG_SHUNT_CAL, 0x0800);
> +    g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x1F40);
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_ADCRANGE);
> +    g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x3E80);
> +
> +    g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x7D00);
> +
> +    i2c_set16(dev, REG_SHUNT_CAL, 0x2000);
> +    g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x1F40);
> +}
> +
> +/* Clamping at full scale and the MATHOF flag */
> +static void test_overflow(void *obj, void *data, QGuestAllocator *alloc)
> +{
> +    QI2CDevice *dev = (QI2CDevice *)obj;
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_RST);
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_ADCRANGE);
> +    qmp_ina238_set("shunt-voltage", 97200000);
> +    g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x7FFF);
> +    qmp_ina238_set("shunt-voltage", -97200000);
> +    g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x8000);
> +
> +    i2c_set16(dev, REG_CONFIG, CONFIG_POR);
> +    qmp_ina238_set("shunt-voltage", 163835000);
> +    i2c_set16(dev, REG_SHUNT_CAL, 0x0001);
> +    g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x7FFF);
> +    g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_MATHOF, ==,
> +                    DIAG_MATHOF);
> +}
> +
> +/* Shunt over-limit alert (transparent mode) */
>  static void ina238_register_nodes(void)
>  {
>      QOSGraphEdgeOptions opts = {
> @@ -173,5 +320,14 @@ static void ina238_register_nodes(void)
>      qos_add_test("defaults", "ina238", test_defaults, NULL);
>      qos_add_test("soft-reset", "ina238", test_soft_reset, NULL);
>      qos_add_test("config-wmask", "ina238", test_config_wmask, NULL);
> +    qos_add_test("shunt-injection", "ina238", test_shunt_injection, NULL);
> +    qos_add_test("bus-injection", "ina238", test_bus_injection, NULL);
> +    qos_add_test("temp-injection", "ina238", test_temp_injection, NULL);
> +    qos_add_test("calibration-current", "ina238", test_calibration_current,
> +                 NULL);
> +    qos_add_test("power", "ina238", test_power, NULL);
> +    qos_add_test("zero-cal", "ina238", test_zero_cal, NULL);
> +    qos_add_test("adcrange", "ina238", test_adcrange, NULL);
> +    qos_add_test("overflow", "ina238", test_overflow, NULL);
>  }
>  libqos_init(ina238_register_nodes);
> 


Reply via email to