1*5861f5abSTitus Rwantare /* 2*5861f5abSTitus Rwantare * Analog Devices ADM1266 Cascadable Super Sequencer with Margin Control and 3*5861f5abSTitus Rwantare * Fault Recording with PMBus 4*5861f5abSTitus Rwantare * 5*5861f5abSTitus Rwantare * Copyright 2022 Google LLC 6*5861f5abSTitus Rwantare * 7*5861f5abSTitus Rwantare * SPDX-License-Identifier: GPL-2.0-or-later 8*5861f5abSTitus Rwantare */ 9*5861f5abSTitus Rwantare 10*5861f5abSTitus Rwantare #include "qemu/osdep.h" 11*5861f5abSTitus Rwantare #include <math.h> 12*5861f5abSTitus Rwantare #include "hw/i2c/pmbus_device.h" 13*5861f5abSTitus Rwantare #include "libqtest-single.h" 14*5861f5abSTitus Rwantare #include "libqos/qgraph.h" 15*5861f5abSTitus Rwantare #include "libqos/i2c.h" 16*5861f5abSTitus Rwantare #include "qapi/qmp/qdict.h" 17*5861f5abSTitus Rwantare #include "qapi/qmp/qnum.h" 18*5861f5abSTitus Rwantare #include "qemu/bitops.h" 19*5861f5abSTitus Rwantare 20*5861f5abSTitus Rwantare #define TEST_ID "adm1266-test" 21*5861f5abSTitus Rwantare #define TEST_ADDR (0x12) 22*5861f5abSTitus Rwantare 23*5861f5abSTitus Rwantare #define ADM1266_BLACKBOX_CONFIG 0xD3 24*5861f5abSTitus Rwantare #define ADM1266_PDIO_CONFIG 0xD4 25*5861f5abSTitus Rwantare #define ADM1266_READ_STATE 0xD9 26*5861f5abSTitus Rwantare #define ADM1266_READ_BLACKBOX 0xDE 27*5861f5abSTitus Rwantare #define ADM1266_SET_RTC 0xDF 28*5861f5abSTitus Rwantare #define ADM1266_GPIO_SYNC_CONFIGURATION 0xE1 29*5861f5abSTitus Rwantare #define ADM1266_BLACKBOX_INFORMATION 0xE6 30*5861f5abSTitus Rwantare #define ADM1266_PDIO_STATUS 0xE9 31*5861f5abSTitus Rwantare #define ADM1266_GPIO_STATUS 0xEA 32*5861f5abSTitus Rwantare 33*5861f5abSTitus Rwantare /* Defaults */ 34*5861f5abSTitus Rwantare #define ADM1266_OPERATION_DEFAULT 0x80 35*5861f5abSTitus Rwantare #define ADM1266_CAPABILITY_DEFAULT 0xA0 36*5861f5abSTitus Rwantare #define ADM1266_CAPABILITY_NO_PEC 0x20 37*5861f5abSTitus Rwantare #define ADM1266_PMBUS_REVISION_DEFAULT 0x22 38*5861f5abSTitus Rwantare #define ADM1266_MFR_ID_DEFAULT "ADI" 39*5861f5abSTitus Rwantare #define ADM1266_MFR_ID_DEFAULT_LEN 32 40*5861f5abSTitus Rwantare #define ADM1266_MFR_MODEL_DEFAULT "ADM1266-A1" 41*5861f5abSTitus Rwantare #define ADM1266_MFR_MODEL_DEFAULT_LEN 32 42*5861f5abSTitus Rwantare #define ADM1266_MFR_REVISION_DEFAULT "25" 43*5861f5abSTitus Rwantare #define ADM1266_MFR_REVISION_DEFAULT_LEN 8 44*5861f5abSTitus Rwantare #define TEST_STRING_A "a sample" 45*5861f5abSTitus Rwantare #define TEST_STRING_B "b sample" 46*5861f5abSTitus Rwantare #define TEST_STRING_C "rev c" 47*5861f5abSTitus Rwantare 48*5861f5abSTitus Rwantare static void compare_string(QI2CDevice *i2cdev, uint8_t reg, 49*5861f5abSTitus Rwantare const char *test_str) 50*5861f5abSTitus Rwantare { 51*5861f5abSTitus Rwantare uint8_t len = i2c_get8(i2cdev, reg); 52*5861f5abSTitus Rwantare char i2c_str[SMBUS_DATA_MAX_LEN] = {0}; 53*5861f5abSTitus Rwantare 54*5861f5abSTitus Rwantare i2c_read_block(i2cdev, reg, (uint8_t *)i2c_str, len); 55*5861f5abSTitus Rwantare g_assert_cmpstr(i2c_str, ==, test_str); 56*5861f5abSTitus Rwantare } 57*5861f5abSTitus Rwantare 58*5861f5abSTitus Rwantare static void write_and_compare_string(QI2CDevice *i2cdev, uint8_t reg, 59*5861f5abSTitus Rwantare const char *test_str, uint8_t len) 60*5861f5abSTitus Rwantare { 61*5861f5abSTitus Rwantare char buf[SMBUS_DATA_MAX_LEN] = {0}; 62*5861f5abSTitus Rwantare buf[0] = len; 63*5861f5abSTitus Rwantare strncpy(buf + 1, test_str, len); 64*5861f5abSTitus Rwantare i2c_write_block(i2cdev, reg, (uint8_t *)buf, len + 1); 65*5861f5abSTitus Rwantare compare_string(i2cdev, reg, test_str); 66*5861f5abSTitus Rwantare } 67*5861f5abSTitus Rwantare 68*5861f5abSTitus Rwantare static void test_defaults(void *obj, void *data, QGuestAllocator *alloc) 69*5861f5abSTitus Rwantare { 70*5861f5abSTitus Rwantare uint16_t i2c_value; 71*5861f5abSTitus Rwantare QI2CDevice *i2cdev = (QI2CDevice *)obj; 72*5861f5abSTitus Rwantare 73*5861f5abSTitus Rwantare i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION); 74*5861f5abSTitus Rwantare g_assert_cmphex(i2c_value, ==, ADM1266_OPERATION_DEFAULT); 75*5861f5abSTitus Rwantare 76*5861f5abSTitus Rwantare i2c_value = i2c_get8(i2cdev, PMBUS_REVISION); 77*5861f5abSTitus Rwantare g_assert_cmphex(i2c_value, ==, ADM1266_PMBUS_REVISION_DEFAULT); 78*5861f5abSTitus Rwantare 79*5861f5abSTitus Rwantare compare_string(i2cdev, PMBUS_MFR_ID, ADM1266_MFR_ID_DEFAULT); 80*5861f5abSTitus Rwantare compare_string(i2cdev, PMBUS_MFR_MODEL, ADM1266_MFR_MODEL_DEFAULT); 81*5861f5abSTitus Rwantare compare_string(i2cdev, PMBUS_MFR_REVISION, ADM1266_MFR_REVISION_DEFAULT); 82*5861f5abSTitus Rwantare } 83*5861f5abSTitus Rwantare 84*5861f5abSTitus Rwantare /* test r/w registers */ 85*5861f5abSTitus Rwantare static void test_rw_regs(void *obj, void *data, QGuestAllocator *alloc) 86*5861f5abSTitus Rwantare { 87*5861f5abSTitus Rwantare QI2CDevice *i2cdev = (QI2CDevice *)obj; 88*5861f5abSTitus Rwantare 89*5861f5abSTitus Rwantare /* empty strings */ 90*5861f5abSTitus Rwantare i2c_set8(i2cdev, PMBUS_MFR_ID, 0); 91*5861f5abSTitus Rwantare compare_string(i2cdev, PMBUS_MFR_ID, ""); 92*5861f5abSTitus Rwantare 93*5861f5abSTitus Rwantare i2c_set8(i2cdev, PMBUS_MFR_MODEL, 0); 94*5861f5abSTitus Rwantare compare_string(i2cdev, PMBUS_MFR_MODEL, ""); 95*5861f5abSTitus Rwantare 96*5861f5abSTitus Rwantare i2c_set8(i2cdev, PMBUS_MFR_REVISION, 0); 97*5861f5abSTitus Rwantare compare_string(i2cdev, PMBUS_MFR_REVISION, ""); 98*5861f5abSTitus Rwantare 99*5861f5abSTitus Rwantare /* test strings */ 100*5861f5abSTitus Rwantare write_and_compare_string(i2cdev, PMBUS_MFR_ID, TEST_STRING_A, 101*5861f5abSTitus Rwantare sizeof(TEST_STRING_A)); 102*5861f5abSTitus Rwantare write_and_compare_string(i2cdev, PMBUS_MFR_ID, TEST_STRING_B, 103*5861f5abSTitus Rwantare sizeof(TEST_STRING_B)); 104*5861f5abSTitus Rwantare write_and_compare_string(i2cdev, PMBUS_MFR_ID, TEST_STRING_C, 105*5861f5abSTitus Rwantare sizeof(TEST_STRING_C)); 106*5861f5abSTitus Rwantare } 107*5861f5abSTitus Rwantare 108*5861f5abSTitus Rwantare static void adm1266_register_nodes(void) 109*5861f5abSTitus Rwantare { 110*5861f5abSTitus Rwantare QOSGraphEdgeOptions opts = { 111*5861f5abSTitus Rwantare .extra_device_opts = "id=" TEST_ID ",address=0x12" 112*5861f5abSTitus Rwantare }; 113*5861f5abSTitus Rwantare add_qi2c_address(&opts, &(QI2CAddress) { TEST_ADDR }); 114*5861f5abSTitus Rwantare 115*5861f5abSTitus Rwantare qos_node_create_driver("adm1266", i2c_device_create); 116*5861f5abSTitus Rwantare qos_node_consumes("adm1266", "i2c-bus", &opts); 117*5861f5abSTitus Rwantare 118*5861f5abSTitus Rwantare qos_add_test("test_defaults", "adm1266", test_defaults, NULL); 119*5861f5abSTitus Rwantare qos_add_test("test_rw_regs", "adm1266", test_rw_regs, NULL); 120*5861f5abSTitus Rwantare } 121*5861f5abSTitus Rwantare 122*5861f5abSTitus Rwantare libqos_init(adm1266_register_nodes); 123