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 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 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 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 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 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 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 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 188 static void adm1272_exit_reset(Object *obj) 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 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 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 adm1272_exit_reset((Object *)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 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 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 = (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 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 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 537 static void adm1272_register_types(void) 538 { 539 type_register_static(&adm1272_info); 540 } 541 542 type_init(adm1272_register_types) 543