qemu/tests/qtest/isl_pmbus_vr-test.c
<<
>>
Prefs
   1/*
   2 * QTests for the ISL_PMBUS digital voltage regulators
   3 *
   4 * Copyright 2021 Google LLC
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms of the GNU General Public License as published by the
   8 * Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14 * for more details.
  15 */
  16
  17#include "qemu/osdep.h"
  18#include <math.h>
  19#include "hw/i2c/pmbus_device.h"
  20#include "hw/sensor/isl_pmbus_vr.h"
  21#include "libqtest-single.h"
  22#include "libqos/qgraph.h"
  23#include "libqos/i2c.h"
  24#include "qapi/qmp/qdict.h"
  25#include "qapi/qmp/qnum.h"
  26#include "qemu/bitops.h"
  27
  28#define TEST_ID "isl_pmbus_vr-test"
  29#define TEST_ADDR (0x43)
  30
  31static uint16_t qmp_isl_pmbus_vr_get(const char *id, const char *property)
  32{
  33    QDict *response;
  34    uint64_t ret;
  35
  36    response = qmp("{ 'execute': 'qom-get', 'arguments': { 'path': %s, "
  37                   "'property': %s } }", id, property);
  38    g_assert(qdict_haskey(response, "return"));
  39    ret = qnum_get_uint(qobject_to(QNum, qdict_get(response, "return")));
  40    qobject_unref(response);
  41    return ret;
  42}
  43
  44static void qmp_isl_pmbus_vr_set(const char *id,
  45                            const char *property,
  46                            uint16_t value)
  47{
  48    QDict *response;
  49
  50    response = qmp("{ 'execute': 'qom-set', 'arguments': { 'path': %s, "
  51                   "'property': %s, 'value': %u } }", id, property, value);
  52    g_assert(qdict_haskey(response, "return"));
  53    qobject_unref(response);
  54}
  55
  56/* PMBus commands are little endian vs i2c_set16 in i2c.h which is big endian */
  57static uint16_t isl_pmbus_vr_i2c_get16(QI2CDevice *i2cdev, uint8_t reg)
  58{
  59    uint8_t resp[2];
  60    i2c_read_block(i2cdev, reg, resp, sizeof(resp));
  61    return (resp[1] << 8) | resp[0];
  62}
  63
  64/* PMBus commands are little endian vs i2c_set16 in i2c.h which is big endian */
  65static void isl_pmbus_vr_i2c_set16(QI2CDevice *i2cdev, uint8_t reg,
  66                                   uint16_t value)
  67{
  68    uint8_t data[2];
  69
  70    data[0] = value & 255;
  71    data[1] = value >> 8;
  72    i2c_write_block(i2cdev, reg, data, sizeof(data));
  73}
  74
  75static void test_defaults(void *obj, void *data, QGuestAllocator *alloc)
  76{
  77    uint16_t value, i2c_value;
  78    QI2CDevice *i2cdev = (QI2CDevice *)obj;
  79
  80    value = qmp_isl_pmbus_vr_get(TEST_ID, "vout[0]");
  81    g_assert_cmpuint(value, ==, ISL_READ_VOUT_DEFAULT);
  82
  83    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
  84    g_assert_cmpuint(i2c_value, ==, ISL_READ_IOUT_DEFAULT);
  85
  86    value = qmp_isl_pmbus_vr_get(TEST_ID, "pout[0]");
  87    g_assert_cmpuint(value, ==, ISL_READ_POUT_DEFAULT);
  88
  89    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VIN);
  90    g_assert_cmpuint(i2c_value, ==, ISL_READ_VIN_DEFAULT);
  91
  92    value = qmp_isl_pmbus_vr_get(TEST_ID, "iin[0]");
  93    g_assert_cmpuint(value, ==, ISL_READ_IIN_DEFAULT);
  94
  95    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_PIN);
  96    g_assert_cmpuint(i2c_value, ==, ISL_READ_PIN_DEFAULT);
  97
  98    value = qmp_isl_pmbus_vr_get(TEST_ID, "temp1[0]");
  99    g_assert_cmpuint(value, ==, ISL_READ_TEMP_DEFAULT);
 100
 101    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_2);
 102    g_assert_cmpuint(i2c_value, ==, ISL_READ_TEMP_DEFAULT);
 103
 104    i2c_value = i2c_get8(i2cdev, PMBUS_CAPABILITY);
 105    g_assert_cmphex(i2c_value, ==, ISL_CAPABILITY_DEFAULT);
 106
 107    i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION);
 108    g_assert_cmphex(i2c_value, ==, ISL_OPERATION_DEFAULT);
 109
 110    i2c_value = i2c_get8(i2cdev, PMBUS_ON_OFF_CONFIG);
 111    g_assert_cmphex(i2c_value, ==, ISL_ON_OFF_CONFIG_DEFAULT);
 112
 113    i2c_value = i2c_get8(i2cdev, PMBUS_VOUT_MODE);
 114    g_assert_cmphex(i2c_value, ==, ISL_VOUT_MODE_DEFAULT);
 115
 116    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_COMMAND);
 117    g_assert_cmphex(i2c_value, ==, ISL_VOUT_COMMAND_DEFAULT);
 118
 119    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MAX);
 120    g_assert_cmphex(i2c_value, ==, ISL_VOUT_MAX_DEFAULT);
 121
 122    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_HIGH);
 123    g_assert_cmphex(i2c_value, ==, ISL_VOUT_MARGIN_HIGH_DEFAULT);
 124
 125    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_LOW);
 126    g_assert_cmphex(i2c_value, ==, ISL_VOUT_MARGIN_LOW_DEFAULT);
 127
 128    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_TRANSITION_RATE);
 129    g_assert_cmphex(i2c_value, ==, ISL_VOUT_TRANSITION_RATE_DEFAULT);
 130
 131    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT);
 132    g_assert_cmphex(i2c_value, ==, ISL_VOUT_OV_FAULT_LIMIT_DEFAULT);
 133
 134    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_FAULT_LIMIT);
 135    g_assert_cmphex(i2c_value, ==, ISL_OT_FAULT_LIMIT_DEFAULT);
 136
 137    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_WARN_LIMIT);
 138    g_assert_cmphex(i2c_value, ==, ISL_OT_WARN_LIMIT_DEFAULT);
 139
 140    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_OV_WARN_LIMIT);
 141    g_assert_cmphex(i2c_value, ==, ISL_VIN_OV_WARN_LIMIT_DEFAULT);
 142
 143    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_UV_WARN_LIMIT);
 144    g_assert_cmphex(i2c_value, ==, ISL_VIN_UV_WARN_LIMIT_DEFAULT);
 145
 146    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_IIN_OC_FAULT_LIMIT);
 147    g_assert_cmphex(i2c_value, ==, ISL_IIN_OC_FAULT_LIMIT_DEFAULT);
 148
 149    i2c_value = i2c_get8(i2cdev, PMBUS_REVISION);
 150    g_assert_cmphex(i2c_value, ==, ISL_REVISION_DEFAULT);
 151}
 152
 153static void raa228000_test_defaults(void *obj, void *data,
 154                                    QGuestAllocator *alloc)
 155{
 156    uint16_t value, i2c_value;
 157    QI2CDevice *i2cdev = (QI2CDevice *)obj;
 158
 159    value = qmp_isl_pmbus_vr_get(TEST_ID, "vout[0]");
 160    g_assert_cmpuint(value, ==, 0);
 161
 162    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
 163    g_assert_cmpuint(i2c_value, ==, 0);
 164
 165    value = qmp_isl_pmbus_vr_get(TEST_ID, "pout[0]");
 166    g_assert_cmpuint(value, ==, 0);
 167
 168    i2c_value = i2c_get8(i2cdev, PMBUS_CAPABILITY);
 169    g_assert_cmphex(i2c_value, ==, ISL_CAPABILITY_DEFAULT);
 170
 171    i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION);
 172    g_assert_cmphex(i2c_value, ==, ISL_OPERATION_DEFAULT);
 173
 174    i2c_value = i2c_get8(i2cdev, PMBUS_ON_OFF_CONFIG);
 175    g_assert_cmphex(i2c_value, ==, ISL_ON_OFF_CONFIG_DEFAULT);
 176
 177    i2c_value = i2c_get8(i2cdev, PMBUS_VOUT_MODE);
 178    g_assert_cmphex(i2c_value, ==, ISL_VOUT_MODE_DEFAULT);
 179
 180    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_COMMAND);
 181    g_assert_cmphex(i2c_value, ==, ISL_VOUT_COMMAND_DEFAULT);
 182
 183    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MAX);
 184    g_assert_cmphex(i2c_value, ==, ISL_VOUT_MAX_DEFAULT);
 185
 186    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_HIGH);
 187    g_assert_cmphex(i2c_value, ==, ISL_VOUT_MARGIN_HIGH_DEFAULT);
 188
 189    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_LOW);
 190    g_assert_cmphex(i2c_value, ==, ISL_VOUT_MARGIN_LOW_DEFAULT);
 191
 192    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_TRANSITION_RATE);
 193    g_assert_cmphex(i2c_value, ==, ISL_VOUT_TRANSITION_RATE_DEFAULT);
 194
 195    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT);
 196    g_assert_cmphex(i2c_value, ==, ISL_VOUT_OV_FAULT_LIMIT_DEFAULT);
 197
 198    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_FAULT_LIMIT);
 199    g_assert_cmphex(i2c_value, ==, ISL_OT_FAULT_LIMIT_DEFAULT);
 200
 201    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_WARN_LIMIT);
 202    g_assert_cmphex(i2c_value, ==, ISL_OT_WARN_LIMIT_DEFAULT);
 203
 204    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_OV_WARN_LIMIT);
 205    g_assert_cmphex(i2c_value, ==, ISL_VIN_OV_WARN_LIMIT_DEFAULT);
 206
 207    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_UV_WARN_LIMIT);
 208    g_assert_cmphex(i2c_value, ==, ISL_VIN_UV_WARN_LIMIT_DEFAULT);
 209
 210    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_IIN_OC_FAULT_LIMIT);
 211    g_assert_cmphex(i2c_value, ==, ISL_IIN_OC_FAULT_LIMIT_DEFAULT);
 212
 213    i2c_value = i2c_get8(i2cdev, PMBUS_REVISION);
 214    g_assert_cmphex(i2c_value, ==, ISL_REVISION_DEFAULT);
 215}
 216
 217/* test qmp access */
 218static void test_tx_rx(void *obj, void *data, QGuestAllocator *alloc)
 219{
 220    uint16_t i2c_value, value;
 221    QI2CDevice *i2cdev = (QI2CDevice *)obj;
 222
 223    qmp_isl_pmbus_vr_set(TEST_ID, "vin[0]", 200);
 224    value = qmp_isl_pmbus_vr_get(TEST_ID, "vin[0]");
 225    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VIN);
 226    g_assert_cmpuint(value, ==, i2c_value);
 227
 228    qmp_isl_pmbus_vr_set(TEST_ID, "vout[0]", 2500);
 229    value = qmp_isl_pmbus_vr_get(TEST_ID, "vout[0]");
 230    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VOUT);
 231    g_assert_cmpuint(value, ==, i2c_value);
 232
 233    qmp_isl_pmbus_vr_set(TEST_ID, "iin[0]", 300);
 234    value = qmp_isl_pmbus_vr_get(TEST_ID, "iin[0]");
 235    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IIN);
 236    g_assert_cmpuint(value, ==, i2c_value);
 237
 238    qmp_isl_pmbus_vr_set(TEST_ID, "iout[0]", 310);
 239    value = qmp_isl_pmbus_vr_get(TEST_ID, "iout[0]");
 240    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
 241    g_assert_cmpuint(value, ==, i2c_value);
 242
 243    qmp_isl_pmbus_vr_set(TEST_ID, "pin[0]", 100);
 244    value = qmp_isl_pmbus_vr_get(TEST_ID, "pin[0]");
 245    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_PIN);
 246    g_assert_cmpuint(value, ==, i2c_value);
 247
 248    qmp_isl_pmbus_vr_set(TEST_ID, "pout[0]", 95);
 249    value = qmp_isl_pmbus_vr_get(TEST_ID, "pout[0]");
 250    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_POUT);
 251    g_assert_cmpuint(value, ==, i2c_value);
 252
 253    qmp_isl_pmbus_vr_set(TEST_ID, "temp1[0]", 26);
 254    value = qmp_isl_pmbus_vr_get(TEST_ID, "temp1[0]");
 255    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
 256    g_assert_cmpuint(value, ==, i2c_value);
 257
 258    qmp_isl_pmbus_vr_set(TEST_ID, "temp2[0]", 27);
 259    value = qmp_isl_pmbus_vr_get(TEST_ID, "temp2[0]");
 260    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_2);
 261    g_assert_cmpuint(value, ==, i2c_value);
 262
 263    qmp_isl_pmbus_vr_set(TEST_ID, "temp3[0]", 28);
 264    value = qmp_isl_pmbus_vr_get(TEST_ID, "temp3[0]");
 265    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_3);
 266    g_assert_cmpuint(value, ==, i2c_value);
 267
 268}
 269
 270/* test r/w registers */
 271static void test_rw_regs(void *obj, void *data, QGuestAllocator *alloc)
 272{
 273    uint16_t i2c_value;
 274    QI2CDevice *i2cdev = (QI2CDevice *)obj;
 275
 276    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_COMMAND, 0x1234);
 277    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_COMMAND);
 278    g_assert_cmphex(i2c_value, ==, 0x1234);
 279
 280    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_TRIM, 0x4567);
 281    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_TRIM);
 282    g_assert_cmphex(i2c_value, ==, 0x4567);
 283
 284    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_MAX, 0x9876);
 285    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MAX);
 286    g_assert_cmphex(i2c_value, ==, 0x9876);
 287
 288    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_MARGIN_HIGH, 0xABCD);
 289    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_HIGH);
 290    g_assert_cmphex(i2c_value, ==, 0xABCD);
 291
 292    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_MARGIN_LOW, 0xA1B2);
 293    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_LOW);
 294    g_assert_cmphex(i2c_value, ==, 0xA1B2);
 295
 296    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_TRANSITION_RATE, 0xDEF1);
 297    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_TRANSITION_RATE);
 298    g_assert_cmphex(i2c_value, ==, 0xDEF1);
 299
 300    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_DROOP, 0x5678);
 301    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_DROOP);
 302    g_assert_cmphex(i2c_value, ==, 0x5678);
 303
 304    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_MIN, 0x1234);
 305    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MIN);
 306    g_assert_cmphex(i2c_value, ==, 0x1234);
 307
 308    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT, 0x2345);
 309    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT);
 310    g_assert_cmphex(i2c_value, ==, 0x2345);
 311
 312    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_UV_FAULT_LIMIT, 0xFA12);
 313    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_UV_FAULT_LIMIT);
 314    g_assert_cmphex(i2c_value, ==, 0xFA12);
 315
 316    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_OT_FAULT_LIMIT, 0xF077);
 317    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_FAULT_LIMIT);
 318    g_assert_cmphex(i2c_value, ==, 0xF077);
 319
 320    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_OT_WARN_LIMIT, 0x7137);
 321    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_WARN_LIMIT);
 322    g_assert_cmphex(i2c_value, ==, 0x7137);
 323
 324    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VIN_OV_FAULT_LIMIT, 0x3456);
 325    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_OV_FAULT_LIMIT);
 326    g_assert_cmphex(i2c_value, ==, 0x3456);
 327
 328    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VIN_UV_FAULT_LIMIT, 0xBADA);
 329    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_UV_FAULT_LIMIT);
 330    g_assert_cmphex(i2c_value, ==, 0xBADA);
 331
 332    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_IIN_OC_FAULT_LIMIT, 0xB1B0);
 333    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_IIN_OC_FAULT_LIMIT);
 334    g_assert_cmphex(i2c_value, ==, 0xB1B0);
 335
 336    i2c_set8(i2cdev, PMBUS_OPERATION, 0xA);
 337    i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION);
 338    g_assert_cmphex(i2c_value, ==, 0xA);
 339
 340    i2c_set8(i2cdev, PMBUS_ON_OFF_CONFIG, 0x42);
 341    i2c_value = i2c_get8(i2cdev, PMBUS_ON_OFF_CONFIG);
 342    g_assert_cmphex(i2c_value, ==, 0x42);
 343}
 344
 345/* test that devices with multiple pages can switch between them */
 346static void test_pages_rw(void *obj, void *data, QGuestAllocator *alloc)
 347{
 348    uint16_t i2c_value;
 349    QI2CDevice *i2cdev = (QI2CDevice *)obj;
 350
 351    i2c_set8(i2cdev, PMBUS_PAGE, 1);
 352    i2c_value = i2c_get8(i2cdev, PMBUS_PAGE);
 353    g_assert_cmphex(i2c_value, ==, 1);
 354
 355    i2c_set8(i2cdev, PMBUS_PAGE, 0);
 356    i2c_value = i2c_get8(i2cdev, PMBUS_PAGE);
 357    g_assert_cmphex(i2c_value, ==, 0);
 358}
 359
 360/* test read-only registers */
 361static void test_ro_regs(void *obj, void *data, QGuestAllocator *alloc)
 362{
 363    uint16_t i2c_init_value, i2c_value;
 364    QI2CDevice *i2cdev = (QI2CDevice *)obj;
 365
 366    i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VIN);
 367    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_VIN, 0xBEEF);
 368    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VIN);
 369    g_assert_cmphex(i2c_init_value, ==, i2c_value);
 370
 371    i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IIN);
 372    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_IIN, 0xB00F);
 373    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IIN);
 374    g_assert_cmphex(i2c_init_value, ==, i2c_value);
 375
 376    i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VOUT);
 377    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_VOUT, 0x1234);
 378    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VOUT);
 379    g_assert_cmphex(i2c_init_value, ==, i2c_value);
 380
 381    i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
 382    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_IOUT, 0x6547);
 383    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
 384    g_assert_cmphex(i2c_init_value, ==, i2c_value);
 385
 386    i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
 387    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_TEMPERATURE_1, 0x1597);
 388    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
 389    g_assert_cmphex(i2c_init_value, ==, i2c_value);
 390
 391    i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_2);
 392    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_TEMPERATURE_2, 0x1897);
 393    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_2);
 394    g_assert_cmphex(i2c_init_value, ==, i2c_value);
 395
 396    i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_3);
 397    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_TEMPERATURE_3, 0x1007);
 398    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_3);
 399    g_assert_cmphex(i2c_init_value, ==, i2c_value);
 400
 401    i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_PIN);
 402    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_PIN, 0xDEAD);
 403    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_PIN);
 404    g_assert_cmphex(i2c_init_value, ==, i2c_value);
 405
 406    i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_POUT);
 407    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_POUT, 0xD00D);
 408    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_POUT);
 409    g_assert_cmphex(i2c_init_value, ==, i2c_value);
 410}
 411
 412/* test voltage fault handling */
 413static void test_voltage_faults(void *obj, void *data, QGuestAllocator *alloc)
 414{
 415    uint16_t i2c_value;
 416    uint8_t i2c_byte;
 417    QI2CDevice *i2cdev = (QI2CDevice *)obj;
 418
 419    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_OV_WARN_LIMIT, 5000);
 420    qmp_isl_pmbus_vr_set(TEST_ID, "vout[0]", 5100);
 421
 422    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_STATUS_WORD);
 423    i2c_byte = i2c_get8(i2cdev, PMBUS_STATUS_VOUT);
 424    g_assert_true((i2c_value & PB_STATUS_VOUT) != 0);
 425    g_assert_true((i2c_byte & PB_STATUS_VOUT_OV_WARN) != 0);
 426
 427    qmp_isl_pmbus_vr_set(TEST_ID, "vout[0]", 4500);
 428    i2c_set8(i2cdev, PMBUS_CLEAR_FAULTS, 0);
 429    i2c_byte = i2c_get8(i2cdev, PMBUS_STATUS_VOUT);
 430    g_assert_true((i2c_byte & PB_STATUS_VOUT_OV_WARN) == 0);
 431
 432    isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_UV_WARN_LIMIT, 4600);
 433
 434    i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_STATUS_WORD);
 435    i2c_byte = i2c_get8(i2cdev, PMBUS_STATUS_VOUT);
 436    g_assert_true((i2c_value & PB_STATUS_VOUT) != 0);
 437    g_assert_true((i2c_byte & PB_STATUS_VOUT_UV_WARN) != 0);
 438
 439}
 440
 441static void isl_pmbus_vr_register_nodes(void)
 442{
 443    QOSGraphEdgeOptions opts = {
 444        .extra_device_opts = "id=" TEST_ID ",address=0x43"
 445    };
 446    add_qi2c_address(&opts, &(QI2CAddress) { TEST_ADDR });
 447
 448    qos_node_create_driver("isl69260", i2c_device_create);
 449    qos_node_consumes("isl69260", "i2c-bus", &opts);
 450
 451    qos_add_test("test_defaults", "isl69260", test_defaults, NULL);
 452    qos_add_test("test_tx_rx", "isl69260", test_tx_rx, NULL);
 453    qos_add_test("test_rw_regs", "isl69260", test_rw_regs, NULL);
 454    qos_add_test("test_pages_rw", "isl69260", test_pages_rw, NULL);
 455    qos_add_test("test_ro_regs", "isl69260", test_ro_regs, NULL);
 456    qos_add_test("test_ov_faults", "isl69260", test_voltage_faults, NULL);
 457
 458    qos_node_create_driver("raa229004", i2c_device_create);
 459    qos_node_consumes("raa229004", "i2c-bus", &opts);
 460
 461    qos_add_test("test_tx_rx", "raa229004", test_tx_rx, NULL);
 462    qos_add_test("test_rw_regs", "raa229004", test_rw_regs, NULL);
 463    qos_add_test("test_pages_rw", "raa229004", test_pages_rw, NULL);
 464    qos_add_test("test_ov_faults", "raa229004", test_voltage_faults, NULL);
 465
 466    qos_node_create_driver("raa228000", i2c_device_create);
 467    qos_node_consumes("raa228000", "i2c-bus", &opts);
 468
 469    qos_add_test("test_defaults", "raa228000", raa228000_test_defaults, NULL);
 470    qos_add_test("test_tx_rx", "raa228000", test_tx_rx, NULL);
 471    qos_add_test("test_rw_regs", "raa228000", test_rw_regs, NULL);
 472    qos_add_test("test_ov_faults", "raa228000", test_voltage_faults, NULL);
 473}
 474libqos_init(isl_pmbus_vr_register_nodes);
 475