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 
31 static 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 
44 static 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 */
57 static 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 */
65 static 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 
75 static 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 
153 static 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 */
218 static 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 */
271 static 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 */
346 static 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 */
361 static 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 */
413 static 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 
441 static 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 }
474 libqos_init(isl_pmbus_vr_register_nodes);
475