Reviewed-by: Glenn Miles <[email protected]> Thanks,
Glenn On Mon, 2026-10-12 at 16:32 +0200, Emmanuel Blot via qemu development wrote: > Add coverage for the DIAG_ALRT flag-clearing rules: which of a read and > a write clears CNVRF and the limit flags in each alert mode, and that a > conversion only re-evaluates the flags of the channels it converted. > > Signed-off-by: Emmanuel Blot <[email protected]> > --- > tests/qtest/ina238-test.c | 127 > ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 127 insertions(+) > > diff --git a/tests/qtest/ina238-test.c b/tests/qtest/ina238-test.c > index fb7bcc265c..e7dd50a822 100644 > --- a/tests/qtest/ina238-test.c > +++ b/tests/qtest/ina238-test.c > @@ -494,6 +494,106 @@ static void test_alert_latch(void *obj, void *data, > QGuestAllocator *alloc) > g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, 0); > } > > +/* In latch mode a read releases the flag even while the fault persists. */ > +static void test_alert_latch_persist(void *obj, void *data, > + QGuestAllocator *alloc) > +{ > + QI2CDevice *dev = (QI2CDevice *)obj; > + > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + i2c_set16(dev, REG_SOVL, 0x1000); > + i2c_set16(dev, REG_DIAG_ALRT, DIAG_ALATCH); > + > + qmp_ina238_set("shunt-voltage", 97200000); > + > + /* First read shows the latched flag and clears it */ > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, > + DIAG_SHNTOL); > + > + /* Fault still present but no new conversion: the flag stays cleared */ > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, 0); > + > + qmp_ina238_set("shunt-voltage", 97200000); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, > + DIAG_SHNTOL); > +} > + > +/* > + * In transparent mode a limit flag follows the live condition: a read leaves > + * it set while the fault persists. > + */ > +static void test_alert_transparent_persist(void *obj, void *data, > + QGuestAllocator *alloc) > +{ > + QI2CDevice *dev = (QI2CDevice *)obj; > + > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + i2c_set16(dev, REG_SOVL, 0x1000); > + > + qmp_ina238_set("shunt-voltage", 97200000); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, > + DIAG_SHNTOL); > + > + /* Repeated reads do not clear the flag while the fault is still > present. */ > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, > + DIAG_SHNTOL); > + > + /* A conversion with the fault gone clears it. */ > + qmp_ina238_set("shunt-voltage", 5000000); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, 0); > +} > + > +/* A DIAG_ALRT write releases a latched limit flag as a read does. */ > +static void test_alert_latch_write_clears(void *obj, void *data, > + QGuestAllocator *alloc) > +{ > + QI2CDevice *dev = (QI2CDevice *)obj; > + > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + i2c_set16(dev, REG_SOVL, 0x1000); > + i2c_set16(dev, REG_DIAG_ALRT, DIAG_ALATCH); > + > + qmp_ina238_set("shunt-voltage", 97200000); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, > + DIAG_SHNTOL); > + > + /* The read above cleared it; re-latch it with another conversion. */ > + qmp_ina238_set("shunt-voltage", 97200000); > + > + /* A write (keeping latch mode) clears the flag while the fault > persists. */ > + i2c_set16(dev, REG_DIAG_ALRT, DIAG_ALATCH); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, 0); > + > + /* The next conversion re-asserts the still-present fault. */ > + qmp_ina238_set("shunt-voltage", 97200000); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, > + DIAG_SHNTOL); > +} > + > +/* > + * A conversion only re-evaluates the flags of the channels it converted: the > + * shunt register a bus-only conversion left stale must not resurrect one. > + */ > +static void test_alert_channel(void *obj, void *data, QGuestAllocator *alloc) > +{ > + QI2CDevice *dev = (QI2CDevice *)obj; > + > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + i2c_set16(dev, REG_SOVL, 0x1000); > + i2c_set16(dev, REG_DIAG_ALRT, DIAG_ALATCH); > + > + qmp_ina238_set("shunt-voltage", 97200000); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, > + DIAG_SHNTOL); > + > + /* Continuous bus-only mode */ > + i2c_set16(dev, REG_ADC_CONFIG, 0x9000); > + qmp_ina238_set("bus-voltage", 12000000); > + > + g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x4BF0); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_SHNTOL, ==, 0); > +} > + > /* DIAG_ALRT control bits are writable; status bits are read-only */ > static void test_diag_control(void *obj, void *data, QGuestAllocator *alloc) > { > @@ -529,6 +629,25 @@ static void test_cnvrf(void *obj, void *data, > QGuestAllocator *alloc) > g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_CNVRF, ==, 0); > } > > +/* A DIAG_ALRT write clears CNVRF only in latch mode. */ > +static void test_cnvrf_write(void *obj, void *data, QGuestAllocator *alloc) > +{ > + QI2CDevice *dev = (QI2CDevice *)obj; > + > + /* Latch mode: a write clears CNVRF. */ > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + i2c_set16(dev, REG_DIAG_ALRT, DIAG_ALATCH); > + qmp_ina238_set("shunt-voltage", 20000000); > + i2c_set16(dev, REG_DIAG_ALRT, DIAG_ALATCH); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_CNVRF, ==, 0); > + > + /* Transparent mode: a write does not clear CNVRF. */ > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + qmp_ina238_set("shunt-voltage", 20000000); > + i2c_set16(dev, REG_DIAG_ALRT, 0x0000); > + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_CNVRF, ==, > DIAG_CNVRF); > +} > + > /* Shunt-voltage injection limits */ > static void test_shunt_limits(void *obj, void *data, QGuestAllocator *alloc) > { > @@ -625,7 +744,15 @@ static void ina238_register_nodes(void) > qos_add_test("alert-power", "ina238", test_alert_power, NULL); > qos_add_test("alert-multi", "ina238", test_alert_multi, NULL); > qos_add_test("alert-latch", "ina238", test_alert_latch, NULL); > + qos_add_test("alert-latch-persist", "ina238", test_alert_latch_persist, > + NULL); > + qos_add_test("alert-transparent-persist", "ina238", > + test_alert_transparent_persist, NULL); > + qos_add_test("alert-latch-write-clears", "ina238", > + test_alert_latch_write_clears, NULL); > + qos_add_test("alert-channel", "ina238", test_alert_channel, NULL); > qos_add_test("diag-control", "ina238", test_diag_control, NULL); > qos_add_test("cnvrf", "ina238", test_cnvrf, NULL); > + qos_add_test("cnvrf-write", "ina238", test_cnvrf_write, NULL); > } > libqos_init(ina238_register_nodes); >
