1 /*
2 * Analog Devices ADM1272 High Voltage Positive Hot Swap Controller and Digital
3 * Power Monitor with PMBus
4 *
5 * Copyright 2021 Google LLC
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "qemu/osdep.h"
11 #include "hw/i2c/pmbus_device.h"
12 #include "hw/irq.h"
13 #include "migration/vmstate.h"
14 #include "qapi/error.h"
15 #include "qapi/visitor.h"
16 #include "qemu/log.h"
17 #include "qemu/module.h"
18
19 #define TYPE_ADM1272 "adm1272"
20 #define ADM1272(obj) OBJECT_CHECK(ADM1272State, (obj), TYPE_ADM1272)
21
22 #define ADM1272_RESTART_TIME 0xCC
23 #define ADM1272_MFR_PEAK_IOUT 0xD0
24 #define ADM1272_MFR_PEAK_VIN 0xD1
25 #define ADM1272_MFR_PEAK_VOUT 0xD2
26 #define ADM1272_MFR_PMON_CONTROL 0xD3
27 #define ADM1272_MFR_PMON_CONFIG 0xD4
28 #define ADM1272_MFR_ALERT1_CONFIG 0xD5
29 #define ADM1272_MFR_ALERT2_CONFIG 0xD6
30 #define ADM1272_MFR_PEAK_TEMPERATURE 0xD7
31 #define ADM1272_MFR_DEVICE_CONFIG 0xD8
32 #define ADM1272_MFR_POWER_CYCLE 0xD9
33 #define ADM1272_MFR_PEAK_PIN 0xDA
34 #define ADM1272_MFR_READ_PIN_EXT 0xDB
35 #define ADM1272_MFR_READ_EIN_EXT 0xDC
36
37 #define ADM1272_HYSTERESIS_LOW 0xF2
38 #define ADM1272_HYSTERESIS_HIGH 0xF3
39 #define ADM1272_STATUS_HYSTERESIS 0xF4
40 #define ADM1272_STATUS_GPIO 0xF5
41 #define ADM1272_STRT_UP_IOUT_LIM 0xF6
42
43 /* Defaults */
44 #define ADM1272_OPERATION_DEFAULT 0x80
45 #define ADM1272_CAPABILITY_DEFAULT 0xB0
46 #define ADM1272_CAPABILITY_NO_PEC 0x30
47 #define ADM1272_DIRECT_MODE 0x40
48 #define ADM1272_HIGH_LIMIT_DEFAULT 0x0FFF
49 #define ADM1272_PIN_OP_DEFAULT 0x7FFF
50 #define ADM1272_PMBUS_REVISION_DEFAULT 0x22
51 #define ADM1272_MFR_ID_DEFAULT "ADI"
52 #define ADM1272_MODEL_DEFAULT "ADM1272-A1"
53 #define ADM1272_MFR_DEFAULT_REVISION "25"
54 #define ADM1272_DEFAULT_DATE "160301"
55 #define ADM1272_RESTART_TIME_DEFAULT 0x64
56 #define ADM1272_PMON_CONTROL_DEFAULT 0x1
57 #define ADM1272_PMON_CONFIG_DEFAULT 0x3F35
58 #define ADM1272_DEVICE_CONFIG_DEFAULT 0x8
59 #define ADM1272_HYSTERESIS_HIGH_DEFAULT 0xFFFF
60 #define ADM1272_STRT_UP_IOUT_LIM_DEFAULT 0x000F
61 #define ADM1272_VOLT_DEFAULT 12000
62 #define ADM1272_IOUT_DEFAULT 25000
63 #define ADM1272_PWR_DEFAULT 300 /* 12V 25A */
64 #define ADM1272_SHUNT 300 /* micro-ohms */
65 #define ADM1272_VOLTAGE_COEFF_DEFAULT 1
66 #define ADM1272_CURRENT_COEFF_DEFAULT 3
67 #define ADM1272_PWR_COEFF_DEFAULT 7
68 #define ADM1272_IOUT_OFFSET 0x5000
69 #define ADM1272_IOUT_OFFSET 0x5000
70
71
72 typedef struct ADM1272State {
73 PMBusDevice parent;
74
75 uint64_t ein_ext;
76 uint32_t pin_ext;
77 uint8_t restart_time;
78
79 uint16_t peak_vin;
80 uint16_t peak_vout;
81 uint16_t peak_iout;
82 uint16_t peak_temperature;
83 uint16_t peak_pin;
84
85 uint8_t pmon_control;
86 uint16_t pmon_config;
87 uint16_t alert1_config;
88 uint16_t alert2_config;
89 uint16_t device_config;
90
91 uint16_t hysteresis_low;
92 uint16_t hysteresis_high;
93 uint8_t status_hysteresis;
94 uint8_t status_gpio;
95
96 uint16_t strt_up_iout_lim;
97
98 } ADM1272State;
99
100 static const PMBusCoefficients adm1272_coefficients[] = {
101 [0] = { 6770, 0, -2 }, /* voltage, vrange 60V */
102 [1] = { 4062, 0, -2 }, /* voltage, vrange 100V */
103 [2] = { 1326, 20480, -1 }, /* current, vsense range 15mV */
104 [3] = { 663, 20480, -1 }, /* current, vsense range 30mV */
105 [4] = { 3512, 0, -2 }, /* power, vrange 60V, irange 15mV */
106 [5] = { 21071, 0, -3 }, /* power, vrange 100V, irange 15mV */
107 [6] = { 17561, 0, -3 }, /* power, vrange 60V, irange 30mV */
108 [7] = { 10535, 0, -3 }, /* power, vrange 100V, irange 30mV */
109 [8] = { 42, 31871, -1 }, /* temperature */
110 };
111
adm1272_check_limits(ADM1272State * s)112 static void adm1272_check_limits(ADM1272State *s)
113 {
114 PMBusDevice *pmdev = PMBUS_DEVICE(s);
115
116 pmbus_check_limits(pmdev);
117
118 if (pmdev->pages[0].read_vout > s->peak_vout) {
119 s->peak_vout = pmdev->pages[0].read_vout;
120 }
121
122 if (pmdev->pages[0].read_vin > s->peak_vin) {
123 s->peak_vin = pmdev->pages[0].read_vin;
124 }
125
126 if (pmdev->pages[0].read_iout > s->peak_iout) {
127 s->peak_iout = pmdev->pages[0].read_iout;
128 }
129
130 if (pmdev->pages[0].read_temperature_1 > s->peak_temperature) {
131 s->peak_temperature = pmdev->pages[0].read_temperature_1;
132 }
133
134 if (pmdev->pages[0].read_pin > s->peak_pin) {
135 s->peak_pin = pmdev->pages[0].read_pin;
136 }
137 }
138
adm1272_millivolts_to_direct(uint32_t value)139 static uint16_t adm1272_millivolts_to_direct(uint32_t value)
140 {
141 PMBusCoefficients c = adm1272_coefficients[ADM1272_VOLTAGE_COEFF_DEFAULT];
142 c.b = c.b * 1000;
143 c.R = c.R - 3;
144 return pmbus_data2direct_mode(c, value);
145 }
146
adm1272_direct_to_millivolts(uint16_t value)147 static uint32_t adm1272_direct_to_millivolts(uint16_t value)
148 {
149 PMBusCoefficients c = adm1272_coefficients[ADM1272_VOLTAGE_COEFF_DEFAULT];
150 c.b = c.b * 1000;
151 c.R = c.R - 3;
152 return pmbus_direct_mode2data(c, value);
153 }
154
adm1272_milliamps_to_direct(uint32_t value)155 static uint16_t adm1272_milliamps_to_direct(uint32_t value)
156 {
157 PMBusCoefficients c = adm1272_coefficients[ADM1272_CURRENT_COEFF_DEFAULT];
158 /* Y = (m * r_sense * x - b) * 10^R */
159 c.m = c.m * ADM1272_SHUNT / 1000; /* micro-ohms */
160 c.b = c.b * 1000;
161 c.R = c.R - 3;
162 return pmbus_data2direct_mode(c, value);
163 }
164
adm1272_direct_to_milliamps(uint16_t value)165 static uint32_t adm1272_direct_to_milliamps(uint16_t value)
166 {
167 PMBusCoefficients c = adm1272_coefficients[ADM1272_CURRENT_COEFF_DEFAULT];
168 c.m = c.m * ADM1272_SHUNT / 1000;
169 c.b = c.b * 1000;
170 c.R = c.R - 3;
171 return pmbus_direct_mode2data(c, value);
172 }
173
adm1272_watts_to_direct(uint32_t value)174 static uint16_t adm1272_watts_to_direct(uint32_t value)
175 {
176 PMBusCoefficients c = adm1272_coefficients[ADM1272_PWR_COEFF_DEFAULT];
177 c.m = c.m * ADM1272_SHUNT / 1000;
178 return pmbus_data2direct_mode(c, value);
179 }
180
adm1272_direct_to_watts(uint16_t value)181 static uint32_t adm1272_direct_to_watts(uint16_t value)
182 {
183 PMBusCoefficients c = adm1272_coefficients[ADM1272_PWR_COEFF_DEFAULT];
184 c.m = c.m * ADM1272_SHUNT / 1000;
185 return pmbus_direct_mode2data(c, value);
186 }
187
adm1272_exit_reset(Object * obj,ResetType type)188 static void adm1272_exit_reset(Object *obj, ResetType type)
189 {
190 ADM1272State *s = ADM1272(obj);
191 PMBusDevice *pmdev = PMBUS_DEVICE(obj);
192
193 pmdev->page = 0;
194 pmdev->pages[0].operation = ADM1272_OPERATION_DEFAULT;
195
196
197 pmdev->capability = ADM1272_CAPABILITY_NO_PEC;
198 pmdev->pages[0].revision = ADM1272_PMBUS_REVISION_DEFAULT;
199 pmdev->pages[0].vout_mode = ADM1272_DIRECT_MODE;
200 pmdev->pages[0].vout_ov_warn_limit = ADM1272_HIGH_LIMIT_DEFAULT;
201 pmdev->pages[0].vout_uv_warn_limit = 0;
202 pmdev->pages[0].iout_oc_warn_limit = ADM1272_HIGH_LIMIT_DEFAULT;
203 pmdev->pages[0].ot_fault_limit = ADM1272_HIGH_LIMIT_DEFAULT;
204 pmdev->pages[0].ot_warn_limit = ADM1272_HIGH_LIMIT_DEFAULT;
205 pmdev->pages[0].vin_ov_warn_limit = ADM1272_HIGH_LIMIT_DEFAULT;
206 pmdev->pages[0].vin_uv_warn_limit = 0;
207 pmdev->pages[0].pin_op_warn_limit = ADM1272_PIN_OP_DEFAULT;
208
209 pmdev->pages[0].status_word = 0;
210 pmdev->pages[0].status_vout = 0;
211 pmdev->pages[0].status_iout = 0;
212 pmdev->pages[0].status_input = 0;
213 pmdev->pages[0].status_temperature = 0;
214 pmdev->pages[0].status_mfr_specific = 0;
215
216 pmdev->pages[0].read_vin
217 = adm1272_millivolts_to_direct(ADM1272_VOLT_DEFAULT);
218 pmdev->pages[0].read_vout
219 = adm1272_millivolts_to_direct(ADM1272_VOLT_DEFAULT);
220 pmdev->pages[0].read_iout
221 = adm1272_milliamps_to_direct(ADM1272_IOUT_DEFAULT);
222 pmdev->pages[0].read_temperature_1 = 0;
223 pmdev->pages[0].read_pin = adm1272_watts_to_direct(ADM1272_PWR_DEFAULT);
224 pmdev->pages[0].revision = ADM1272_PMBUS_REVISION_DEFAULT;
225 pmdev->pages[0].mfr_id = ADM1272_MFR_ID_DEFAULT;
226 pmdev->pages[0].mfr_model = ADM1272_MODEL_DEFAULT;
227 pmdev->pages[0].mfr_revision = ADM1272_MFR_DEFAULT_REVISION;
228 pmdev->pages[0].mfr_date = ADM1272_DEFAULT_DATE;
229
230 s->pin_ext = 0;
231 s->ein_ext = 0;
232 s->restart_time = ADM1272_RESTART_TIME_DEFAULT;
233
234 s->peak_vin = 0;
235 s->peak_vout = 0;
236 s->peak_iout = 0;
237 s->peak_temperature = 0;
238 s->peak_pin = 0;
239
240 s->pmon_control = ADM1272_PMON_CONTROL_DEFAULT;
241 s->pmon_config = ADM1272_PMON_CONFIG_DEFAULT;
242 s->alert1_config = 0;
243 s->alert2_config = 0;
244 s->device_config = ADM1272_DEVICE_CONFIG_DEFAULT;
245
246 s->hysteresis_low = 0;
247 s->hysteresis_high = ADM1272_HYSTERESIS_HIGH_DEFAULT;
248 s->status_hysteresis = 0;
249 s->status_gpio = 0;
250
251 s->strt_up_iout_lim = ADM1272_STRT_UP_IOUT_LIM_DEFAULT;
252 }
253
adm1272_read_byte(PMBusDevice * pmdev)254 static uint8_t adm1272_read_byte(PMBusDevice *pmdev)
255 {
256 ADM1272State *s = ADM1272(pmdev);
257
258 switch (pmdev->code) {
259 case ADM1272_RESTART_TIME:
260 pmbus_send8(pmdev, s->restart_time);
261 break;
262
263 case ADM1272_MFR_PEAK_IOUT:
264 pmbus_send16(pmdev, s->peak_iout);
265 break;
266
267 case ADM1272_MFR_PEAK_VIN:
268 pmbus_send16(pmdev, s->peak_vin);
269 break;
270
271 case ADM1272_MFR_PEAK_VOUT:
272 pmbus_send16(pmdev, s->peak_vout);
273 break;
274
275 case ADM1272_MFR_PMON_CONTROL:
276 pmbus_send8(pmdev, s->pmon_control);
277 break;
278
279 case ADM1272_MFR_PMON_CONFIG:
280 pmbus_send16(pmdev, s->pmon_config);
281 break;
282
283 case ADM1272_MFR_ALERT1_CONFIG:
284 pmbus_send16(pmdev, s->alert1_config);
285 break;
286
287 case ADM1272_MFR_ALERT2_CONFIG:
288 pmbus_send16(pmdev, s->alert2_config);
289 break;
290
291 case ADM1272_MFR_PEAK_TEMPERATURE:
292 pmbus_send16(pmdev, s->peak_temperature);
293 break;
294
295 case ADM1272_MFR_DEVICE_CONFIG:
296 pmbus_send16(pmdev, s->device_config);
297 break;
298
299 case ADM1272_MFR_PEAK_PIN:
300 pmbus_send16(pmdev, s->peak_pin);
301 break;
302
303 case ADM1272_MFR_READ_PIN_EXT:
304 pmbus_send32(pmdev, s->pin_ext);
305 break;
306
307 case ADM1272_MFR_READ_EIN_EXT:
308 pmbus_send64(pmdev, s->ein_ext);
309 break;
310
311 case ADM1272_HYSTERESIS_LOW:
312 pmbus_send16(pmdev, s->hysteresis_low);
313 break;
314
315 case ADM1272_HYSTERESIS_HIGH:
316 pmbus_send16(pmdev, s->hysteresis_high);
317 break;
318
319 case ADM1272_STATUS_HYSTERESIS:
320 pmbus_send16(pmdev, s->status_hysteresis);
321 break;
322
323 case ADM1272_STATUS_GPIO:
324 pmbus_send16(pmdev, s->status_gpio);
325 break;
326
327 case ADM1272_STRT_UP_IOUT_LIM:
328 pmbus_send16(pmdev, s->strt_up_iout_lim);
329 break;
330
331 default:
332 qemu_log_mask(LOG_GUEST_ERROR,
333 "%s: reading from unsupported register: 0x%02x\n",
334 __func__, pmdev->code);
335 return 0xFF;
336 break;
337 }
338
339 return 0;
340 }
341
adm1272_write_data(PMBusDevice * pmdev,const uint8_t * buf,uint8_t len)342 static int adm1272_write_data(PMBusDevice *pmdev, const uint8_t *buf,
343 uint8_t len)
344 {
345 ADM1272State *s = ADM1272(pmdev);
346
347 if (len == 0) {
348 qemu_log_mask(LOG_GUEST_ERROR, "%s: writing empty data\n", __func__);
349 return -1;
350 }
351
352 pmdev->code = buf[0]; /* PMBus command code */
353
354 if (len == 1) {
355 return 0;
356 }
357
358 /* Exclude command code from buffer */
359 buf++;
360 len--;
361
362 switch (pmdev->code) {
363
364 case ADM1272_RESTART_TIME:
365 s->restart_time = pmbus_receive8(pmdev);
366 break;
367
368 case ADM1272_MFR_PMON_CONTROL:
369 s->pmon_control = pmbus_receive8(pmdev);
370 break;
371
372 case ADM1272_MFR_PMON_CONFIG:
373 s->pmon_config = pmbus_receive16(pmdev);
374 break;
375
376 case ADM1272_MFR_ALERT1_CONFIG:
377 s->alert1_config = pmbus_receive16(pmdev);
378 break;
379
380 case ADM1272_MFR_ALERT2_CONFIG:
381 s->alert2_config = pmbus_receive16(pmdev);
382 break;
383
384 case ADM1272_MFR_DEVICE_CONFIG:
385 s->device_config = pmbus_receive16(pmdev);
386 break;
387
388 case ADM1272_MFR_POWER_CYCLE:
389 device_cold_reset(DEVICE(s));
390 break;
391
392 case ADM1272_HYSTERESIS_LOW:
393 s->hysteresis_low = pmbus_receive16(pmdev);
394 break;
395
396 case ADM1272_HYSTERESIS_HIGH:
397 s->hysteresis_high = pmbus_receive16(pmdev);
398 break;
399
400 case ADM1272_STRT_UP_IOUT_LIM:
401 s->strt_up_iout_lim = pmbus_receive16(pmdev);
402 adm1272_check_limits(s);
403 break;
404
405 default:
406 qemu_log_mask(LOG_GUEST_ERROR,
407 "%s: writing to unsupported register: 0x%02x\n",
408 __func__, pmdev->code);
409 break;
410 }
411 return 0;
412 }
413
adm1272_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)414 static void adm1272_get(Object *obj, Visitor *v, const char *name, void *opaque,
415 Error **errp)
416 {
417 uint16_t value;
418
419 if (strcmp(name, "vin") == 0 || strcmp(name, "vout") == 0) {
420 value = adm1272_direct_to_millivolts(*(uint16_t *)opaque);
421 } else if (strcmp(name, "iout") == 0) {
422 value = adm1272_direct_to_milliamps(*(uint16_t *)opaque);
423 } else if (strcmp(name, "pin") == 0) {
424 value = adm1272_direct_to_watts(*(uint16_t *)opaque);
425 } else {
426 value = *(uint16_t *)opaque;
427 }
428
429 visit_type_uint16(v, name, &value, errp);
430 }
431
adm1272_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)432 static void adm1272_set(Object *obj, Visitor *v, const char *name, void *opaque,
433 Error **errp)
434 {
435 ADM1272State *s = ADM1272(obj);
436 uint16_t *internal = opaque;
437 uint16_t value;
438
439 if (!visit_type_uint16(v, name, &value, errp)) {
440 return;
441 }
442
443 if (strcmp(name, "vin") == 0 || strcmp(name, "vout") == 0) {
444 *internal = adm1272_millivolts_to_direct(value);
445 } else if (strcmp(name, "iout") == 0) {
446 *internal = adm1272_milliamps_to_direct(value);
447 } else if (strcmp(name, "pin") == 0) {
448 *internal = adm1272_watts_to_direct(value);
449 } else {
450 *internal = value;
451 }
452
453 adm1272_check_limits(s);
454 }
455
456 static const VMStateDescription vmstate_adm1272 = {
457 .name = "ADM1272",
458 .version_id = 0,
459 .minimum_version_id = 0,
460 .fields = (const VMStateField[]){
461 VMSTATE_PMBUS_DEVICE(parent, ADM1272State),
462 VMSTATE_UINT64(ein_ext, ADM1272State),
463 VMSTATE_UINT32(pin_ext, ADM1272State),
464 VMSTATE_UINT8(restart_time, ADM1272State),
465
466 VMSTATE_UINT16(peak_vin, ADM1272State),
467 VMSTATE_UINT16(peak_vout, ADM1272State),
468 VMSTATE_UINT16(peak_iout, ADM1272State),
469 VMSTATE_UINT16(peak_temperature, ADM1272State),
470 VMSTATE_UINT16(peak_pin, ADM1272State),
471
472 VMSTATE_UINT8(pmon_control, ADM1272State),
473 VMSTATE_UINT16(pmon_config, ADM1272State),
474 VMSTATE_UINT16(alert1_config, ADM1272State),
475 VMSTATE_UINT16(alert2_config, ADM1272State),
476 VMSTATE_UINT16(device_config, ADM1272State),
477
478 VMSTATE_UINT16(hysteresis_low, ADM1272State),
479 VMSTATE_UINT16(hysteresis_high, ADM1272State),
480 VMSTATE_UINT8(status_hysteresis, ADM1272State),
481 VMSTATE_UINT8(status_gpio, ADM1272State),
482
483 VMSTATE_UINT16(strt_up_iout_lim, ADM1272State),
484 VMSTATE_END_OF_LIST()
485 }
486 };
487
adm1272_init(Object * obj)488 static void adm1272_init(Object *obj)
489 {
490 PMBusDevice *pmdev = PMBUS_DEVICE(obj);
491 uint64_t flags = PB_HAS_VOUT_MODE | PB_HAS_VOUT | PB_HAS_VIN | PB_HAS_IOUT |
492 PB_HAS_PIN | PB_HAS_TEMPERATURE | PB_HAS_MFR_INFO;
493
494 pmbus_page_config(pmdev, 0, flags);
495
496 object_property_add(obj, "vin", "uint16",
497 adm1272_get,
498 adm1272_set, NULL, &pmdev->pages[0].read_vin);
499
500 object_property_add(obj, "vout", "uint16",
501 adm1272_get,
502 adm1272_set, NULL, &pmdev->pages[0].read_vout);
503
504 object_property_add(obj, "iout", "uint16",
505 adm1272_get,
506 adm1272_set, NULL, &pmdev->pages[0].read_iout);
507
508 object_property_add(obj, "pin", "uint16",
509 adm1272_get,
510 adm1272_set, NULL, &pmdev->pages[0].read_pin);
511
512 }
513
adm1272_class_init(ObjectClass * klass,void * data)514 static void adm1272_class_init(ObjectClass *klass, void *data)
515 {
516 ResettableClass *rc = RESETTABLE_CLASS(klass);
517 DeviceClass *dc = DEVICE_CLASS(klass);
518 PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);
519
520 dc->desc = "Analog Devices ADM1272 Hot Swap controller";
521 dc->vmsd = &vmstate_adm1272;
522 k->write_data = adm1272_write_data;
523 k->receive_byte = adm1272_read_byte;
524 k->device_num_pages = 1;
525
526 rc->phases.exit = adm1272_exit_reset;
527 }
528
529 static const TypeInfo adm1272_info = {
530 .name = TYPE_ADM1272,
531 .parent = TYPE_PMBUS_DEVICE,
532 .instance_size = sizeof(ADM1272State),
533 .instance_init = adm1272_init,
534 .class_init = adm1272_class_init,
535 };
536
adm1272_register_types(void)537 static void adm1272_register_types(void)
538 {
539 type_register_static(&adm1272_info);
540 }
541
542 type_init(adm1272_register_types)
543