tests/qtest: adc128d818: test limit interrupts
Cover per-channel high- and low-limit interrupt status, the INT_CLEAR bit gating the monitoring loop, and the temperature high-limit alarm with hysteresis. Signed-off-by: Emmanuel Blot <emmanuel.blot@free.fr> Link: https://lore.kernel.org/qemu-devel/20260707091609.97759-5-emmanuel.blot@free.fr Signed-off-by: Cédric Le Goater <clg@redhat.com>
Emmanuel Blot committed
Jul 7, 2026 at 11:15 UTC
af685633f45a5ad9ed052cc5e58c7fe62bd0c631
1 file changed
+121
tests/qtest/adc128d818-test.c
+121
@@ -330,6 +330,123 @@ static void test_ext_vref(void *obj, void *data, QGuestAllocator *alloc)
330
g_assert_cmphex(reading, ==, 0x8000);
331
}
332
333
+/* Interrupt status set on limit violation; persists while fault remains */
334
+static void test_interrupt_status(void *obj, void *data, QGuestAllocator *alloc)
335
+{
336
+ QI2CDevice *dev = (QI2CDevice *)obj;
337
+ uint8_t status;
338
+
339
+ i2c_set8(dev, REG_LIMIT_BASE, 0x10);
340
+ g_test_message("Set ch0 high limit = 0x10");
341
+
342
+ qmp_adc128d818_set("ain0", 2560);
343
+ g_test_message("Injected ain0 = 2560 mV (exceeds limit)");
344
+
345
+ i2c_set8(dev, REG_CONFIG, CONFIG_START | CONFIG_INT_ENABLE);
346
+
347
+ status = i2c_get8(dev, REG_INT_STATUS);
348
+ g_test_message("INT_STATUS = 0x%02x (expect bit 0 set)", status);
349
+ g_assert_cmphex(status & 0x01u, ==, 0x01);
350
+
351
+ status = i2c_get8(dev, REG_INT_STATUS);
352
+ g_test_message("INT_STATUS after re-read = 0x%02x (expect bit 0 still set)",
353
+ status);
354
+ g_assert_cmphex(status & 0x01u, ==, 0x01);
355
+
356
+ qmp_adc128d818_set("ain0", 80);
357
+ g_test_message("Injected ain0 = 80 mV (within limit)");
358
+ status = i2c_get8(dev, REG_INT_STATUS);
359
+ g_test_message("INT_STATUS after fault cleared = 0x%02x "
360
+ "(expect bit 0 clear)", status);
361
+ g_assert_cmphex(status & 0x01u, ==, 0x00);
362
+}
363
+
364
+/* INT_CLEAR stops the round-robin monitoring loop */
365
+static void test_int_clear(void *obj, void *data, QGuestAllocator *alloc)
366
+{
367
+ QI2CDevice *dev = (QI2CDevice *)obj;
368
+ uint8_t status;
369
+
370
+ i2c_set8(dev, REG_LIMIT_BASE, 0x10);
371
+ qmp_adc128d818_set("ain0", 2560);
372
+
373
+ i2c_set8(dev, REG_CONFIG,
374
+ CONFIG_START | CONFIG_INT_ENABLE | CONFIG_INT_CLEAR);
375
+ status = i2c_get8(dev, REG_INT_STATUS);
376
+ g_test_message("INT_STATUS with INT_CLEAR set = 0x%02x (expect 0x00)",
377
+ status);
378
+ g_assert_cmphex(status, ==, 0x00);
379
+
380
+ i2c_set8(dev, REG_CONFIG, CONFIG_START | CONFIG_INT_ENABLE);
381
+ status = i2c_get8(dev, REG_INT_STATUS);
382
+ g_test_message("INT_STATUS after INT_CLEAR cleared = 0x%02x (expect bit 0)",
383
+ status);
384
+ g_assert_cmphex(status & 0x01u, ==, 0x01);
385
+}
386
+
387
+/* Low-limit interrupt triggers correctly */
388
+static void test_low_limit(void *obj, void *data, QGuestAllocator *alloc)
389
+{
390
+ QI2CDevice *dev = (QI2CDevice *)obj;
391
+ uint8_t status;
392
+
393
+ i2c_set8(dev, REG_CONFIG, CONFIG_INITIALIZATION);
394
+
395
+ i2c_set8(dev, REG_LIMIT_BASE + 3u, 0x80);
396
+ g_test_message("Set ch1 low limit = 0x80");
397
+
398
+ i2c_set8(dev, REG_LIMIT_BASE + 5u, 0x80);
399
+ g_test_message("Set ch2 low limit = 0x80");
400
+
401
+ qmp_adc128d818_set("ain1", 640);
402
+ qmp_adc128d818_set("ain2", 1280);
403
+ qmp_adc128d818_set("ain0", 1280);
404
+ i2c_set8(dev, REG_CONFIG, CONFIG_START | CONFIG_INT_ENABLE);
405
+
406
+ status = i2c_get8(dev, REG_INT_STATUS);
407
+ g_test_message("INT_STATUS = 0x%02x (expect bits 1 and 2 set)", status);
408
+ g_assert_cmphex(status & 0x02u, ==, 0x02);
409
+ g_assert_cmphex(status & 0x04u, ==, 0x04);
410
+
411
+ g_assert_cmphex(status & 0x01u, ==, 0x00);
412
+}
413
+
414
+/* Temperature high-limit interrupt with hysteresis */
415
+static void test_temp_hysteresis(void *obj, void *data,
416
+ QGuestAllocator *alloc)
417
+{
418
+ QI2CDevice *dev = (QI2CDevice *)obj;
419
+ uint8_t status;
420
+
421
+ i2c_set8(dev, REG_CONFIG, CONFIG_INITIALIZATION);
422
+
423
+ i2c_set8(dev, REG_LIMIT_BASE + 7u * 2u, 0x32);
424
+ i2c_set8(dev, REG_LIMIT_BASE + 7u * 2u + 1u, 0x28);
425
+
426
+ qmp_adc128d818_set("temperature", 25000);
427
+ i2c_set8(dev, REG_CONFIG, CONFIG_START);
428
+
429
+ status = i2c_get8(dev, REG_INT_STATUS);
430
+ g_test_message("25 C: INT_STATUS = 0x%02x (temp bit expect clear)", status);
431
+ g_assert_cmphex(status & 0x80u, ==, 0x00);
432
+
433
+ qmp_adc128d818_set("temperature", 55000);
434
+ status = i2c_get8(dev, REG_INT_STATUS);
435
+ g_test_message("55 C: INT_STATUS = 0x%02x (temp bit expect set)", status);
436
+ g_assert_cmphex(status & 0x80u, ==, 0x80);
437
+
438
+ qmp_adc128d818_set("temperature", 45000);
439
+ status = i2c_get8(dev, REG_INT_STATUS);
440
+ g_test_message("45 C (hysteresis): INT_STATUS = 0x%02x "
441
+ "(temp bit expect set)", status);
442
+ g_assert_cmphex(status & 0x80u, ==, 0x80);
443
+
444
+ qmp_adc128d818_set("temperature", 35000);
445
+ status = i2c_get8(dev, REG_INT_STATUS);
446
+ g_test_message("35 C: INT_STATUS = 0x%02x (temp bit expect clear)", status);
447
+ g_assert_cmphex(status & 0x80u, ==, 0x00);
448
+}
449
+
450
static void adc128d818_register_nodes(void)
451
{
452
QOSGraphEdgeOptions opts = {
@@ -354,5 +471,9 @@ static void adc128d818_register_nodes(void)
471
qos_add_test("temperature-edges", "adc128d818", test_temperature_edges,
472
NULL);
473
qos_add_test("ext-vref", "adc128d818", test_ext_vref, NULL);
474
+ qos_add_test("interrupt-status", "adc128d818", test_interrupt_status, NULL);
475
+ qos_add_test("int-clear", "adc128d818", test_int_clear, NULL);
476
+ qos_add_test("low-limit", "adc128d818", test_low_limit, NULL);
477
+ qos_add_test("temp-hysteresis", "adc128d818", test_temp_hysteresis, NULL);
478
}
479
libqos_init(adc128d818_register_nodes);