@samitouri / QOSamiQemu / commits / af685633f4

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);