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