xref: /openbmc/qemu/tests/qtest/max34451-test.c (revision ff051128)
17649086fSTitus Rwantare /*
27649086fSTitus Rwantare  * QTests for the MAX34451 device
37649086fSTitus Rwantare  *
47649086fSTitus Rwantare  * Copyright 2021 Google LLC
57649086fSTitus Rwantare  *
67649086fSTitus Rwantare  * SPDX-License-Identifier: GPL-2.0-or-later
77649086fSTitus Rwantare  */
87649086fSTitus Rwantare 
97649086fSTitus Rwantare #include "qemu/osdep.h"
107649086fSTitus Rwantare #include "hw/i2c/pmbus_device.h"
117649086fSTitus Rwantare #include "libqtest-single.h"
127649086fSTitus Rwantare #include "libqos/qgraph.h"
137649086fSTitus Rwantare #include "libqos/i2c.h"
147649086fSTitus Rwantare #include "qapi/qmp/qdict.h"
157649086fSTitus Rwantare #include "qapi/qmp/qnum.h"
167649086fSTitus Rwantare #include "qemu/bitops.h"
177649086fSTitus Rwantare 
187649086fSTitus Rwantare #define TEST_ID "max34451-test"
197649086fSTitus Rwantare #define TEST_ADDR (0x4e)
207649086fSTitus Rwantare 
21*ff051128STitus Rwantare #define MAX34451_MFR_MODE               0xD1
227649086fSTitus Rwantare #define MAX34451_MFR_VOUT_PEAK          0xD4
237649086fSTitus Rwantare #define MAX34451_MFR_IOUT_PEAK          0xD5
247649086fSTitus Rwantare #define MAX34451_MFR_TEMPERATURE_PEAK   0xD6
257649086fSTitus Rwantare #define MAX34451_MFR_VOUT_MIN           0xD7
267649086fSTitus Rwantare 
277649086fSTitus Rwantare #define DEFAULT_VOUT                    0
287649086fSTitus Rwantare #define DEFAULT_UV_LIMIT                0
297649086fSTitus Rwantare #define DEFAULT_TEMPERATURE             2500
307649086fSTitus Rwantare #define DEFAULT_SCALE                   0x7FFF
317649086fSTitus Rwantare #define DEFAULT_OV_LIMIT                0x7FFF
327649086fSTitus Rwantare #define DEFAULT_OC_LIMIT                0x7FFF
337649086fSTitus Rwantare #define DEFAULT_OT_LIMIT                0x7FFF
347649086fSTitus Rwantare #define DEFAULT_VMIN                    0x7FFF
357649086fSTitus Rwantare #define DEFAULT_TON_FAULT_LIMIT         0xFFFF
367649086fSTitus Rwantare #define DEFAULT_CHANNEL_CONFIG          0x20
377649086fSTitus Rwantare #define DEFAULT_TEXT                    0x20
387649086fSTitus Rwantare 
397649086fSTitus Rwantare #define MAX34451_NUM_PWR_DEVICES        16
407649086fSTitus Rwantare #define MAX34451_NUM_TEMP_DEVICES       5
417649086fSTitus Rwantare 
427649086fSTitus Rwantare 
qmp_max34451_get(const char * id,const char * property)437649086fSTitus Rwantare static uint16_t qmp_max34451_get(const char *id, const char *property)
447649086fSTitus Rwantare {
457649086fSTitus Rwantare     QDict *response;
467649086fSTitus Rwantare     uint16_t ret;
477649086fSTitus Rwantare     response = qmp("{ 'execute': 'qom-get', 'arguments': { 'path': %s, "
487649086fSTitus Rwantare                    "'property': %s } }", id, property);
497649086fSTitus Rwantare     g_assert(qdict_haskey(response, "return"));
507649086fSTitus Rwantare     ret = qnum_get_uint(qobject_to(QNum, qdict_get(response, "return")));
517649086fSTitus Rwantare     qobject_unref(response);
527649086fSTitus Rwantare     return ret;
537649086fSTitus Rwantare }
547649086fSTitus Rwantare 
qmp_max34451_set(const char * id,const char * property,uint16_t value)557649086fSTitus Rwantare static void qmp_max34451_set(const char *id,
567649086fSTitus Rwantare                              const char *property,
577649086fSTitus Rwantare                              uint16_t value)
587649086fSTitus Rwantare {
597649086fSTitus Rwantare     QDict *response;
607649086fSTitus Rwantare 
617649086fSTitus Rwantare     response = qmp("{ 'execute': 'qom-set', 'arguments': { 'path': %s, "
627649086fSTitus Rwantare                    "'property': %s, 'value': %u } }",
637649086fSTitus Rwantare                    id, property, value);
647649086fSTitus Rwantare     g_assert(qdict_haskey(response, "return"));
657649086fSTitus Rwantare     qobject_unref(response);
667649086fSTitus Rwantare }
677649086fSTitus Rwantare 
687649086fSTitus Rwantare /* PMBus commands are little endian vs i2c_set16 in i2c.h which is big endian */
max34451_i2c_get16(QI2CDevice * i2cdev,uint8_t reg)697649086fSTitus Rwantare static uint16_t max34451_i2c_get16(QI2CDevice *i2cdev, uint8_t reg)
707649086fSTitus Rwantare {
717649086fSTitus Rwantare     uint8_t resp[2];
727649086fSTitus Rwantare     i2c_read_block(i2cdev, reg, resp, sizeof(resp));
737649086fSTitus Rwantare     return (resp[1] << 8) | resp[0];
747649086fSTitus Rwantare }
757649086fSTitus Rwantare 
767649086fSTitus Rwantare /* PMBus commands are little endian vs i2c_set16 in i2c.h which is big endian */
max34451_i2c_set16(QI2CDevice * i2cdev,uint8_t reg,uint16_t value)777649086fSTitus Rwantare static void max34451_i2c_set16(QI2CDevice *i2cdev, uint8_t reg, uint16_t value)
787649086fSTitus Rwantare {
797649086fSTitus Rwantare     uint8_t data[2];
807649086fSTitus Rwantare 
817649086fSTitus Rwantare     data[0] = value & 255;
827649086fSTitus Rwantare     data[1] = value >> 8;
837649086fSTitus Rwantare     i2c_write_block(i2cdev, reg, data, sizeof(data));
847649086fSTitus Rwantare }
857649086fSTitus Rwantare 
867649086fSTitus Rwantare /* Test default values */
test_defaults(void * obj,void * data,QGuestAllocator * alloc)877649086fSTitus Rwantare static void test_defaults(void *obj, void *data, QGuestAllocator *alloc)
887649086fSTitus Rwantare {
897649086fSTitus Rwantare     uint16_t value, i2c_value;
907649086fSTitus Rwantare     QI2CDevice *i2cdev = (QI2CDevice *)obj;
917649086fSTitus Rwantare     char *path;
927649086fSTitus Rwantare 
937649086fSTitus Rwantare     /* Default temperatures and temperature fault limits */
947649086fSTitus Rwantare     for (int i = 0; i < MAX34451_NUM_TEMP_DEVICES; i++) {
957649086fSTitus Rwantare         path = g_strdup_printf("temperature[%d]", i);
967649086fSTitus Rwantare         value = qmp_max34451_get(TEST_ID, path);
977649086fSTitus Rwantare         g_assert_cmpuint(value, ==, DEFAULT_TEMPERATURE);
987649086fSTitus Rwantare         g_free(path);
997649086fSTitus Rwantare 
1007649086fSTitus Rwantare         /* Temperature sensors start on page 16 */
1017649086fSTitus Rwantare         i2c_set8(i2cdev, PMBUS_PAGE, i + 16);
1027649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
1037649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, DEFAULT_TEMPERATURE);
1047649086fSTitus Rwantare 
1057649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_OT_FAULT_LIMIT);
1067649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, DEFAULT_OT_LIMIT);
1077649086fSTitus Rwantare 
1087649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_OT_WARN_LIMIT);
1097649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, DEFAULT_OT_LIMIT);
1107649086fSTitus Rwantare     }
1117649086fSTitus Rwantare 
1127649086fSTitus Rwantare     /* Default voltages and fault limits */
1137649086fSTitus Rwantare     for (int i = 0; i < MAX34451_NUM_PWR_DEVICES; i++) {
1147649086fSTitus Rwantare         path = g_strdup_printf("vout[%d]", i);
1157649086fSTitus Rwantare         value = qmp_max34451_get(TEST_ID, path);
1167649086fSTitus Rwantare         g_assert_cmpuint(value, ==, DEFAULT_VOUT);
1177649086fSTitus Rwantare         g_free(path);
1187649086fSTitus Rwantare 
1197649086fSTitus Rwantare         i2c_set8(i2cdev, PMBUS_PAGE, i);
1207649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_READ_VOUT);
1217649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, DEFAULT_VOUT);
1227649086fSTitus Rwantare 
1237649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT);
1247649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, DEFAULT_OV_LIMIT);
1257649086fSTitus Rwantare 
1267649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_OV_WARN_LIMIT);
1277649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, DEFAULT_OV_LIMIT);
1287649086fSTitus Rwantare 
1297649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_UV_WARN_LIMIT);
1307649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, DEFAULT_UV_LIMIT);
1317649086fSTitus Rwantare 
1327649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_UV_FAULT_LIMIT);
1337649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, DEFAULT_UV_LIMIT);
1347649086fSTitus Rwantare 
1357649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, MAX34451_MFR_VOUT_MIN);
1367649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, DEFAULT_VMIN);
1377649086fSTitus Rwantare     }
1387649086fSTitus Rwantare 
1397649086fSTitus Rwantare     i2c_value = i2c_get8(i2cdev, PMBUS_VOUT_MODE);
1407649086fSTitus Rwantare     g_assert_cmphex(i2c_value, ==, 0x40); /* DIRECT mode */
1417649086fSTitus Rwantare 
1427649086fSTitus Rwantare     i2c_value = i2c_get8(i2cdev, PMBUS_REVISION);
1437649086fSTitus Rwantare     g_assert_cmphex(i2c_value, ==, 0x11); /* Rev 1.1 */
1447649086fSTitus Rwantare }
1457649086fSTitus Rwantare 
1467649086fSTitus Rwantare /* Test setting temperature */
test_temperature(void * obj,void * data,QGuestAllocator * alloc)1477649086fSTitus Rwantare static void test_temperature(void *obj, void *data, QGuestAllocator *alloc)
1487649086fSTitus Rwantare {
1497649086fSTitus Rwantare     uint16_t value, i2c_value;
1507649086fSTitus Rwantare     QI2CDevice *i2cdev = (QI2CDevice *)obj;
1517649086fSTitus Rwantare     char *path;
1527649086fSTitus Rwantare 
1537649086fSTitus Rwantare     for (int i = 0; i < MAX34451_NUM_TEMP_DEVICES; i++) {
1547649086fSTitus Rwantare         path = g_strdup_printf("temperature[%d]", i);
1557649086fSTitus Rwantare         qmp_max34451_set(TEST_ID, path, 0xBE00 + i);
1567649086fSTitus Rwantare         value = qmp_max34451_get(TEST_ID, path);
1577649086fSTitus Rwantare         g_assert_cmphex(value, ==, 0xBE00 + i);
1587649086fSTitus Rwantare         g_free(path);
1597649086fSTitus Rwantare     }
1607649086fSTitus Rwantare 
1617649086fSTitus Rwantare     /* compare qmp read with i2c read separately */
1627649086fSTitus Rwantare     for (int i = 0; i < MAX34451_NUM_TEMP_DEVICES; i++) {
1637649086fSTitus Rwantare         /* temperature[0] is on page 16 */
1647649086fSTitus Rwantare         i2c_set8(i2cdev, PMBUS_PAGE, i + 16);
1657649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
1667649086fSTitus Rwantare         g_assert_cmphex(i2c_value, ==, 0xBE00 + i);
1677649086fSTitus Rwantare 
1687649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, MAX34451_MFR_TEMPERATURE_PEAK);
1697649086fSTitus Rwantare         g_assert_cmphex(i2c_value, ==, 0xBE00 + i);
1707649086fSTitus Rwantare     }
1717649086fSTitus Rwantare }
1727649086fSTitus Rwantare 
1737649086fSTitus Rwantare /* Test setting voltage */
test_voltage(void * obj,void * data,QGuestAllocator * alloc)1747649086fSTitus Rwantare static void test_voltage(void *obj, void *data, QGuestAllocator *alloc)
1757649086fSTitus Rwantare {
1767649086fSTitus Rwantare     uint16_t value, i2c_value;
1777649086fSTitus Rwantare     QI2CDevice *i2cdev = (QI2CDevice *)obj;
1787649086fSTitus Rwantare     char *path;
1797649086fSTitus Rwantare 
1807649086fSTitus Rwantare     for (int i = 0; i < MAX34451_NUM_PWR_DEVICES; i++) {
1817649086fSTitus Rwantare         path = g_strdup_printf("vout[%d]", i);
1827649086fSTitus Rwantare         qmp_max34451_set(TEST_ID, path, 3000 + i);
1837649086fSTitus Rwantare         value = qmp_max34451_get(TEST_ID, path);
1847649086fSTitus Rwantare         g_assert_cmpuint(value, ==, 3000 + i);
1857649086fSTitus Rwantare         g_free(path);
1867649086fSTitus Rwantare     }
1877649086fSTitus Rwantare 
1887649086fSTitus Rwantare     /* compare qmp read with i2c read separately */
1897649086fSTitus Rwantare     for (int i = 0; i < MAX34451_NUM_PWR_DEVICES; i++) {
1907649086fSTitus Rwantare         i2c_set8(i2cdev, PMBUS_PAGE, i);
1917649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_READ_VOUT);
1927649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, 3000 + i);
1937649086fSTitus Rwantare 
1947649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, MAX34451_MFR_VOUT_PEAK);
1957649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, 3000 + i);
1967649086fSTitus Rwantare 
1977649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, MAX34451_MFR_VOUT_MIN);
1987649086fSTitus Rwantare         g_assert_cmpuint(i2c_value, ==, 3000 + i);
1997649086fSTitus Rwantare     }
2007649086fSTitus Rwantare }
2017649086fSTitus Rwantare 
2027649086fSTitus Rwantare /* Test setting some read/write registers */
test_rw_regs(void * obj,void * data,QGuestAllocator * alloc)2037649086fSTitus Rwantare static void test_rw_regs(void *obj, void *data, QGuestAllocator *alloc)
2047649086fSTitus Rwantare {
2057649086fSTitus Rwantare     uint16_t i2c_value;
2067649086fSTitus Rwantare     QI2CDevice *i2cdev = (QI2CDevice *)obj;
2077649086fSTitus Rwantare 
2087649086fSTitus Rwantare     i2c_set8(i2cdev, PMBUS_PAGE, 11);
2097649086fSTitus Rwantare     i2c_value = i2c_get8(i2cdev, PMBUS_PAGE);
2107649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 11);
2117649086fSTitus Rwantare 
2127649086fSTitus Rwantare     i2c_set8(i2cdev, PMBUS_OPERATION, 1);
2137649086fSTitus Rwantare     i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION);
2147649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 1);
2157649086fSTitus Rwantare 
2167649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_VOUT_MARGIN_HIGH, 5000);
2177649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_HIGH);
2187649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 5000);
2197649086fSTitus Rwantare 
2207649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_VOUT_MARGIN_LOW, 4000);
2217649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_LOW);
2227649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 4000);
2237649086fSTitus Rwantare 
2247649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT, 5500);
2257649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT);
2267649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 5500);
2277649086fSTitus Rwantare 
2287649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_VOUT_OV_WARN_LIMIT, 5600);
2297649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_OV_WARN_LIMIT);
2307649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 5600);
2317649086fSTitus Rwantare 
2327649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_VOUT_UV_FAULT_LIMIT, 5700);
2337649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_UV_FAULT_LIMIT);
2347649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 5700);
2357649086fSTitus Rwantare 
2367649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_VOUT_UV_WARN_LIMIT, 5800);
2377649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_VOUT_UV_WARN_LIMIT);
2387649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 5800);
2397649086fSTitus Rwantare 
2407649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_POWER_GOOD_ON, 5900);
2417649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_POWER_GOOD_ON);
2427649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 5900);
2437649086fSTitus Rwantare 
2447649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_POWER_GOOD_OFF, 6100);
2457649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_POWER_GOOD_OFF);
2467649086fSTitus Rwantare     g_assert_cmpuint(i2c_value, ==, 6100);
2477649086fSTitus Rwantare }
2487649086fSTitus Rwantare 
2497649086fSTitus Rwantare /* Test that Read only registers can't be written */
test_ro_regs(void * obj,void * data,QGuestAllocator * alloc)2507649086fSTitus Rwantare static void test_ro_regs(void *obj, void *data, QGuestAllocator *alloc)
2517649086fSTitus Rwantare {
2527649086fSTitus Rwantare     uint16_t i2c_value, i2c_init_value;
2537649086fSTitus Rwantare     QI2CDevice *i2cdev = (QI2CDevice *)obj;
2547649086fSTitus Rwantare 
2557649086fSTitus Rwantare     i2c_set8(i2cdev, PMBUS_PAGE, 1); /* move to page 1 */
2567649086fSTitus Rwantare     i2c_init_value = i2c_get8(i2cdev, PMBUS_CAPABILITY);
2577649086fSTitus Rwantare     i2c_set8(i2cdev, PMBUS_CAPABILITY, 0xF9);
2587649086fSTitus Rwantare     i2c_value = i2c_get8(i2cdev, PMBUS_CAPABILITY);
2597649086fSTitus Rwantare     g_assert_cmpuint(i2c_init_value, ==, i2c_value);
2607649086fSTitus Rwantare 
2617649086fSTitus Rwantare     i2c_init_value = max34451_i2c_get16(i2cdev, PMBUS_READ_VOUT);
2627649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_READ_VOUT, 0xDEAD);
2637649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_READ_VOUT);
2647649086fSTitus Rwantare     g_assert_cmpuint(i2c_init_value, ==, i2c_value);
2657649086fSTitus Rwantare     g_assert_cmphex(i2c_value, !=, 0xDEAD);
2667649086fSTitus Rwantare 
2677649086fSTitus Rwantare     i2c_set8(i2cdev, PMBUS_PAGE, 16); /* move to page 16 */
2687649086fSTitus Rwantare     i2c_init_value = max34451_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
2697649086fSTitus Rwantare     max34451_i2c_set16(i2cdev, PMBUS_READ_TEMPERATURE_1, 0xABBA);
2707649086fSTitus Rwantare     i2c_value = max34451_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
2717649086fSTitus Rwantare     g_assert_cmpuint(i2c_init_value, ==, i2c_value);
2727649086fSTitus Rwantare     g_assert_cmphex(i2c_value, !=, 0xABBA);
2737649086fSTitus Rwantare }
2747649086fSTitus Rwantare 
2757649086fSTitus Rwantare /* test over voltage faults */
test_ov_faults(void * obj,void * data,QGuestAllocator * alloc)2767649086fSTitus Rwantare static void test_ov_faults(void *obj, void *data, QGuestAllocator *alloc)
2777649086fSTitus Rwantare {
2787649086fSTitus Rwantare     uint16_t i2c_value;
2797649086fSTitus Rwantare     uint8_t i2c_byte;
2807649086fSTitus Rwantare     QI2CDevice *i2cdev = (QI2CDevice *)obj;
2817649086fSTitus Rwantare     char *path;
2827649086fSTitus Rwantare     /* Test ov fault reporting */
2837649086fSTitus Rwantare     for (int i = 0; i < MAX34451_NUM_PWR_DEVICES; i++) {
2847649086fSTitus Rwantare         path = g_strdup_printf("vout[%d]", i);
2857649086fSTitus Rwantare         i2c_set8(i2cdev, PMBUS_PAGE, i);
2867649086fSTitus Rwantare         max34451_i2c_set16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT, 5000);
2877649086fSTitus Rwantare         qmp_max34451_set(TEST_ID, path, 5100);
2887649086fSTitus Rwantare         g_free(path);
2897649086fSTitus Rwantare 
2907649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_STATUS_WORD);
2917649086fSTitus Rwantare         i2c_byte = i2c_get8(i2cdev, PMBUS_STATUS_VOUT);
2927649086fSTitus Rwantare         g_assert_true((i2c_value & PB_STATUS_VOUT) != 0);
2937649086fSTitus Rwantare         g_assert_true((i2c_byte & PB_STATUS_VOUT_OV_FAULT) != 0);
2947649086fSTitus Rwantare     }
2957649086fSTitus Rwantare }
2967649086fSTitus Rwantare 
2977649086fSTitus Rwantare /* test over temperature faults */
test_ot_faults(void * obj,void * data,QGuestAllocator * alloc)2987649086fSTitus Rwantare static void test_ot_faults(void *obj, void *data, QGuestAllocator *alloc)
2997649086fSTitus Rwantare {
3007649086fSTitus Rwantare     uint16_t i2c_value;
3017649086fSTitus Rwantare     uint8_t i2c_byte;
3027649086fSTitus Rwantare     QI2CDevice *i2cdev = (QI2CDevice *)obj;
3037649086fSTitus Rwantare     char *path;
3047649086fSTitus Rwantare 
3057649086fSTitus Rwantare     for (int i = 0; i < MAX34451_NUM_TEMP_DEVICES; i++) {
3067649086fSTitus Rwantare         path = g_strdup_printf("temperature[%d]", i);
3077649086fSTitus Rwantare         i2c_set8(i2cdev, PMBUS_PAGE, i + 16);
3087649086fSTitus Rwantare         max34451_i2c_set16(i2cdev, PMBUS_OT_FAULT_LIMIT, 6000);
3097649086fSTitus Rwantare         qmp_max34451_set(TEST_ID, path, 6100);
3107649086fSTitus Rwantare         g_free(path);
3117649086fSTitus Rwantare 
3127649086fSTitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, PMBUS_STATUS_WORD);
3137649086fSTitus Rwantare         i2c_byte = i2c_get8(i2cdev, PMBUS_STATUS_TEMPERATURE);
3147649086fSTitus Rwantare         g_assert_true((i2c_value & PB_STATUS_TEMPERATURE) != 0);
3157649086fSTitus Rwantare         g_assert_true((i2c_byte & PB_STATUS_OT_FAULT) != 0);
3167649086fSTitus Rwantare     }
3177649086fSTitus Rwantare }
3187649086fSTitus Rwantare 
319*ff051128STitus Rwantare #define RAND_ON_OFF_CONFIG  0x12
320*ff051128STitus Rwantare #define RAND_MFR_MODE       0x3456
321*ff051128STitus Rwantare 
322*ff051128STitus Rwantare /* test writes to all pages */
test_all_pages(void * obj,void * data,QGuestAllocator * alloc)323*ff051128STitus Rwantare static void test_all_pages(void *obj, void *data, QGuestAllocator *alloc)
324*ff051128STitus Rwantare {
325*ff051128STitus Rwantare     uint16_t i2c_value;
326*ff051128STitus Rwantare     QI2CDevice *i2cdev = (QI2CDevice *)obj;
327*ff051128STitus Rwantare 
328*ff051128STitus Rwantare     i2c_set8(i2cdev, PMBUS_PAGE, PB_ALL_PAGES);
329*ff051128STitus Rwantare     i2c_set8(i2cdev, PMBUS_ON_OFF_CONFIG, RAND_ON_OFF_CONFIG);
330*ff051128STitus Rwantare     max34451_i2c_set16(i2cdev, MAX34451_MFR_MODE, RAND_MFR_MODE);
331*ff051128STitus Rwantare 
332*ff051128STitus Rwantare     for (int i = 0; i < MAX34451_NUM_TEMP_DEVICES + MAX34451_NUM_PWR_DEVICES;
333*ff051128STitus Rwantare          i++) {
334*ff051128STitus Rwantare         i2c_value = i2c_get8(i2cdev, PMBUS_ON_OFF_CONFIG);
335*ff051128STitus Rwantare         g_assert_cmphex(i2c_value, ==, RAND_ON_OFF_CONFIG);
336*ff051128STitus Rwantare         i2c_value = max34451_i2c_get16(i2cdev, MAX34451_MFR_MODE);
337*ff051128STitus Rwantare         g_assert_cmphex(i2c_value, ==, RAND_MFR_MODE);
338*ff051128STitus Rwantare     }
339*ff051128STitus Rwantare }
340*ff051128STitus Rwantare 
max34451_register_nodes(void)3417649086fSTitus Rwantare static void max34451_register_nodes(void)
3427649086fSTitus Rwantare {
3437649086fSTitus Rwantare     QOSGraphEdgeOptions opts = {
3447649086fSTitus Rwantare         .extra_device_opts = "id=" TEST_ID ",address=0x4e"
3457649086fSTitus Rwantare     };
3467649086fSTitus Rwantare     add_qi2c_address(&opts, &(QI2CAddress) { TEST_ADDR });
3477649086fSTitus Rwantare 
3487649086fSTitus Rwantare     qos_node_create_driver("max34451", i2c_device_create);
3497649086fSTitus Rwantare     qos_node_consumes("max34451", "i2c-bus", &opts);
3507649086fSTitus Rwantare 
3517649086fSTitus Rwantare     qos_add_test("test_defaults", "max34451", test_defaults, NULL);
3527649086fSTitus Rwantare     qos_add_test("test_temperature", "max34451", test_temperature, NULL);
3537649086fSTitus Rwantare     qos_add_test("test_voltage", "max34451", test_voltage, NULL);
3547649086fSTitus Rwantare     qos_add_test("test_rw_regs", "max34451", test_rw_regs, NULL);
3557649086fSTitus Rwantare     qos_add_test("test_ro_regs", "max34451", test_ro_regs, NULL);
3567649086fSTitus Rwantare     qos_add_test("test_ov_faults", "max34451", test_ov_faults, NULL);
3577649086fSTitus Rwantare     qos_add_test("test_ot_faults", "max34451", test_ot_faults, NULL);
358*ff051128STitus Rwantare     qos_add_test("test_all_pages", "max34451", test_all_pages, NULL);
3597649086fSTitus Rwantare }
3607649086fSTitus Rwantare libqos_init(max34451_register_nodes);
361