max34451.c (27463B)
1/* 2 * Maxim MAX34451 PMBus 16-Channel V/I monitor and 12-Channel Sequencer/Marginer 3 * 4 * Copyright 2021 Google LLC 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9#include "qemu/osdep.h" 10#include "hw/i2c/pmbus_device.h" 11#include "hw/irq.h" 12#include "migration/vmstate.h" 13#include "qapi/error.h" 14#include "qapi/visitor.h" 15#include "qemu/log.h" 16#include "qemu/module.h" 17 18#define TYPE_MAX34451 "max34451" 19#define MAX34451(obj) OBJECT_CHECK(MAX34451State, (obj), TYPE_MAX34451) 20 21#define MAX34451_MFR_MODE 0xD1 22#define MAX34451_MFR_PSEN_CONFIG 0xD2 23#define MAX34451_MFR_VOUT_PEAK 0xD4 24#define MAX34451_MFR_IOUT_PEAK 0xD5 25#define MAX34451_MFR_TEMPERATURE_PEAK 0xD6 26#define MAX34451_MFR_VOUT_MIN 0xD7 27#define MAX34451_MFR_NV_LOG_CONFIG 0xD8 28#define MAX34451_MFR_FAULT_RESPONSE 0xD9 29#define MAX34451_MFR_FAULT_RETRY 0xDA 30#define MAX34451_MFR_NV_FAULT_LOG 0xDC 31#define MAX34451_MFR_TIME_COUNT 0xDD 32#define MAX34451_MFR_MARGIN_CONFIG 0xDF 33#define MAX34451_MFR_FW_SERIAL 0xE0 34#define MAX34451_MFR_IOUT_AVG 0xE2 35#define MAX34451_MFR_CHANNEL_CONFIG 0xE4 36#define MAX34451_MFR_TON_SEQ_MAX 0xE6 37#define MAX34451_MFR_PWM_CONFIG 0xE7 38#define MAX34451_MFR_SEQ_CONFIG 0xE8 39#define MAX34451_MFR_STORE_ALL 0xEE 40#define MAX34451_MFR_RESTORE_ALL 0xEF 41#define MAX34451_MFR_TEMP_SENSOR_CONFIG 0xF0 42#define MAX34451_MFR_STORE_SINGLE 0xFC 43#define MAX34451_MFR_CRC 0xFE 44 45#define MAX34451_NUM_MARGINED_PSU 12 46#define MAX34451_NUM_PWR_DEVICES 16 47#define MAX34451_NUM_TEMP_DEVICES 5 48#define MAX34451_NUM_PAGES 21 49 50#define DEFAULT_OP_ON 0x80 51#define DEFAULT_CAPABILITY 0x20 52#define DEFAULT_ON_OFF_CONFIG 0x1a 53#define DEFAULT_VOUT_MODE 0x40 54#define DEFAULT_TEMPERATURE 2500 55#define DEFAULT_SCALE 0x7FFF 56#define DEFAULT_OV_LIMIT 0x7FFF 57#define DEFAULT_OC_LIMIT 0x7FFF 58#define DEFAULT_OT_LIMIT 0x7FFF 59#define DEFAULT_VMIN 0x7FFF 60#define DEFAULT_TON_FAULT_LIMIT 0xFFFF 61#define DEFAULT_CHANNEL_CONFIG 0x20 62#define DEFAULT_TEXT 0x3130313031303130 63 64/** 65 * MAX34451State: 66 * @code: The command code received 67 * @page: Each page corresponds to a device monitored by the Max 34451 68 * The page register determines the available commands depending on device 69 ___________________________________________________________________________ 70 | 0 | Power supply monitored by RS0, controlled by PSEN0, and | 71 | | margined with PWM0. | 72 |_______|___________________________________________________________________| 73 | 1 | Power supply monitored by RS1, controlled by PSEN1, and | 74 | | margined with PWM1. | 75 |_______|___________________________________________________________________| 76 | 2 | Power supply monitored by RS2, controlled by PSEN2, and | 77 | | margined with PWM2. | 78 |_______|___________________________________________________________________| 79 | 3 | Power supply monitored by RS3, controlled by PSEN3, and | 80 | | margined with PWM3. | 81 |_______|___________________________________________________________________| 82 | 4 | Power supply monitored by RS4, controlled by PSEN4, and | 83 | | margined with PWM4. | 84 |_______|___________________________________________________________________| 85 | 5 | Power supply monitored by RS5, controlled by PSEN5, and | 86 | | margined with PWM5. | 87 |_______|___________________________________________________________________| 88 | 6 | Power supply monitored by RS6, controlled by PSEN6, and | 89 | | margined with PWM6. | 90 |_______|___________________________________________________________________| 91 | 7 | Power supply monitored by RS7, controlled by PSEN7, and | 92 | | margined with PWM7. | 93 |_______|___________________________________________________________________| 94 | 8 | Power supply monitored by RS8, controlled by PSEN8, and | 95 | | optionally margined by OUT0 of external DS4424 at I2C address A0h.| 96 |_______|___________________________________________________________________| 97 | 9 | Power supply monitored by RS9, controlled by PSEN9, and | 98 | | optionally margined by OUT1 of external DS4424 at I2C address A0h.| 99 |_______|___________________________________________________________________| 100 | 10 | Power supply monitored by RS10, controlled by PSEN10, and | 101 | | optionally margined by OUT2 of external DS4424 at I2C address A0h.| 102 |_______|___________________________________________________________________| 103 | 11 | Power supply monitored by RS11, controlled by PSEN11, and | 104 | | optionally margined by OUT3 of external DS4424 at I2C address A0h.| 105 |_______|___________________________________________________________________| 106 | 12 | ADC channel 12 (monitors voltage or current) or GPI. | 107 |_______|___________________________________________________________________| 108 | 13 | ADC channel 13 (monitors voltage or current) or GPI. | 109 |_______|___________________________________________________________________| 110 | 14 | ADC channel 14 (monitors voltage or current) or GPI. | 111 |_______|___________________________________________________________________| 112 | 15 | ADC channel 15 (monitors voltage or current) or GPI. | 113 |_______|___________________________________________________________________| 114 | 16 | Internal temperature sensor. | 115 |_______|___________________________________________________________________| 116 | 17 | External DS75LV temperature sensor with I2C address 90h. | 117 |_______|___________________________________________________________________| 118 | 18 | External DS75LV temperature sensor with I2C address 92h. | 119 |_______|___________________________________________________________________| 120 | 19 | External DS75LV temperature sensor with I2C address 94h. | 121 |_______|___________________________________________________________________| 122 | 20 | External DS75LV temperature sensor with I2C address 96h. | 123 |_______|___________________________________________________________________| 124 | 21=E2=80=93254| Reserved. | 125 |_______|___________________________________________________________________| 126 | 255 | Applies to all pages. | 127 |_______|___________________________________________________________________| 128 * 129 * @operation: Turn on and off power supplies 130 * @on_off_config: Configure the power supply on and off transition behaviour 131 * @write_protect: protect against changes to the device's memory 132 * @vout_margin_high: the voltage when OPERATION is set to margin high 133 * @vout_margin_low: the voltage when OPERATION is set to margin low 134 * @vout_scale: scale ADC reading to actual device reading if different 135 * @iout_cal_gain: set ratio of the voltage at the ADC input to sensed current 136 */ 137typedef struct MAX34451State { 138 PMBusDevice parent; 139 140 uint16_t power_good_on[MAX34451_NUM_PWR_DEVICES]; 141 uint16_t power_good_off[MAX34451_NUM_PWR_DEVICES]; 142 uint16_t ton_delay[MAX34451_NUM_MARGINED_PSU]; 143 uint16_t ton_max_fault_limit[MAX34451_NUM_MARGINED_PSU]; 144 uint16_t toff_delay[MAX34451_NUM_MARGINED_PSU]; 145 uint8_t status_mfr_specific[MAX34451_NUM_PWR_DEVICES]; 146 /* Manufacturer specific function */ 147 uint64_t mfr_location; 148 uint64_t mfr_date; 149 uint64_t mfr_serial; 150 uint16_t mfr_mode; 151 uint32_t psen_config[MAX34451_NUM_MARGINED_PSU]; 152 uint16_t vout_peak[MAX34451_NUM_PWR_DEVICES]; 153 uint16_t iout_peak[MAX34451_NUM_PWR_DEVICES]; 154 uint16_t temperature_peak[MAX34451_NUM_TEMP_DEVICES]; 155 uint16_t vout_min[MAX34451_NUM_PWR_DEVICES]; 156 uint16_t nv_log_config; 157 uint32_t fault_response[MAX34451_NUM_PWR_DEVICES]; 158 uint16_t fault_retry; 159 uint32_t fault_log; 160 uint32_t time_count; 161 uint16_t margin_config[MAX34451_NUM_MARGINED_PSU]; 162 uint16_t fw_serial; 163 uint16_t iout_avg[MAX34451_NUM_PWR_DEVICES]; 164 uint16_t channel_config[MAX34451_NUM_PWR_DEVICES]; 165 uint16_t ton_seq_max[MAX34451_NUM_MARGINED_PSU]; 166 uint32_t pwm_config[MAX34451_NUM_MARGINED_PSU]; 167 uint32_t seq_config[MAX34451_NUM_MARGINED_PSU]; 168 uint16_t temp_sensor_config[MAX34451_NUM_TEMP_DEVICES]; 169 uint16_t store_single; 170 uint16_t crc; 171} MAX34451State; 172 173 174static void max34451_check_limits(MAX34451State *s) 175{ 176 PMBusDevice *pmdev = PMBUS_DEVICE(s); 177 178 pmbus_check_limits(pmdev); 179 180 for (int i = 0; i < MAX34451_NUM_PWR_DEVICES; i++) { 181 if (pmdev->pages[i].read_vout == 0) { /* PSU disabled */ 182 continue; 183 } 184 185 if (pmdev->pages[i].read_vout > s->vout_peak[i]) { 186 s->vout_peak[i] = pmdev->pages[i].read_vout; 187 } 188 189 if (pmdev->pages[i].read_vout < s->vout_min[i]) { 190 s->vout_min[i] = pmdev->pages[i].read_vout; 191 } 192 193 if (pmdev->pages[i].read_iout > s->iout_peak[i]) { 194 s->iout_peak[i] = pmdev->pages[i].read_iout; 195 } 196 } 197 198 for (int i = 0; i < MAX34451_NUM_TEMP_DEVICES; i++) { 199 if (pmdev->pages[i + 16].read_temperature_1 > s->temperature_peak[i]) { 200 s->temperature_peak[i] = pmdev->pages[i + 16].read_temperature_1; 201 } 202 } 203} 204 205static uint8_t max34451_read_byte(PMBusDevice *pmdev) 206{ 207 MAX34451State *s = MAX34451(pmdev); 208 switch (pmdev->code) { 209 210 case PMBUS_POWER_GOOD_ON: 211 if (pmdev->page < 16) { 212 pmbus_send16(pmdev, s->power_good_on[pmdev->page]); 213 } 214 break; 215 216 case PMBUS_POWER_GOOD_OFF: 217 if (pmdev->page < 16) { 218 pmbus_send16(pmdev, s->power_good_off[pmdev->page]); 219 } 220 break; 221 222 case PMBUS_TON_DELAY: 223 if (pmdev->page < 12) { 224 pmbus_send16(pmdev, s->ton_delay[pmdev->page]); 225 } 226 break; 227 228 case PMBUS_TON_MAX_FAULT_LIMIT: 229 if (pmdev->page < 12) { 230 pmbus_send16(pmdev, s->ton_max_fault_limit[pmdev->page]); 231 } 232 break; 233 234 case PMBUS_TOFF_DELAY: 235 if (pmdev->page < 12) { 236 pmbus_send16(pmdev, s->toff_delay[pmdev->page]); 237 } 238 break; 239 240 case PMBUS_STATUS_MFR_SPECIFIC: 241 if (pmdev->page < 16) { 242 pmbus_send8(pmdev, s->status_mfr_specific[pmdev->page]); 243 } 244 break; 245 246 case PMBUS_MFR_ID: 247 pmbus_send8(pmdev, 0x4d); /* Maxim */ 248 break; 249 250 case PMBUS_MFR_MODEL: 251 pmbus_send8(pmdev, 0x59); 252 break; 253 254 case PMBUS_MFR_LOCATION: 255 pmbus_send64(pmdev, s->mfr_location); 256 break; 257 258 case PMBUS_MFR_DATE: 259 pmbus_send64(pmdev, s->mfr_date); 260 break; 261 262 case PMBUS_MFR_SERIAL: 263 pmbus_send64(pmdev, s->mfr_serial); 264 break; 265 266 case MAX34451_MFR_MODE: 267 pmbus_send16(pmdev, s->mfr_mode); 268 break; 269 270 case MAX34451_MFR_PSEN_CONFIG: 271 if (pmdev->page < 12) { 272 pmbus_send32(pmdev, s->psen_config[pmdev->page]); 273 } 274 break; 275 276 case MAX34451_MFR_VOUT_PEAK: 277 if (pmdev->page < 16) { 278 pmbus_send16(pmdev, s->vout_peak[pmdev->page]); 279 } 280 break; 281 282 case MAX34451_MFR_IOUT_PEAK: 283 if (pmdev->page < 16) { 284 pmbus_send16(pmdev, s->iout_peak[pmdev->page]); 285 } 286 break; 287 288 case MAX34451_MFR_TEMPERATURE_PEAK: 289 if (15 < pmdev->page && pmdev->page < 21) { 290 pmbus_send16(pmdev, s->temperature_peak[pmdev->page % 16]); 291 } else { 292 pmbus_send16(pmdev, s->temperature_peak[0]); 293 } 294 break; 295 296 case MAX34451_MFR_VOUT_MIN: 297 if (pmdev->page < 16) { 298 pmbus_send16(pmdev, s->vout_min[pmdev->page]); 299 } 300 break; 301 302 case MAX34451_MFR_NV_LOG_CONFIG: 303 pmbus_send16(pmdev, s->nv_log_config); 304 break; 305 306 case MAX34451_MFR_FAULT_RESPONSE: 307 if (pmdev->page < 16) { 308 pmbus_send32(pmdev, s->fault_response[pmdev->page]); 309 } 310 break; 311 312 case MAX34451_MFR_FAULT_RETRY: 313 pmbus_send32(pmdev, s->fault_retry); 314 break; 315 316 case MAX34451_MFR_NV_FAULT_LOG: 317 pmbus_send32(pmdev, s->fault_log); 318 break; 319 320 case MAX34451_MFR_TIME_COUNT: 321 pmbus_send32(pmdev, s->time_count); 322 break; 323 324 case MAX34451_MFR_MARGIN_CONFIG: 325 if (pmdev->page < 12) { 326 pmbus_send16(pmdev, s->margin_config[pmdev->page]); 327 } 328 break; 329 330 case MAX34451_MFR_FW_SERIAL: 331 if (pmdev->page == 255) { 332 pmbus_send16(pmdev, 1); /* Firmware revision */ 333 } 334 break; 335 336 case MAX34451_MFR_IOUT_AVG: 337 if (pmdev->page < 16) { 338 pmbus_send16(pmdev, s->iout_avg[pmdev->page]); 339 } 340 break; 341 342 case MAX34451_MFR_CHANNEL_CONFIG: 343 if (pmdev->page < 16) { 344 pmbus_send16(pmdev, s->channel_config[pmdev->page]); 345 } 346 break; 347 348 case MAX34451_MFR_TON_SEQ_MAX: 349 if (pmdev->page < 12) { 350 pmbus_send16(pmdev, s->ton_seq_max[pmdev->page]); 351 } 352 break; 353 354 case MAX34451_MFR_PWM_CONFIG: 355 if (pmdev->page < 12) { 356 pmbus_send32(pmdev, s->pwm_config[pmdev->page]); 357 } 358 break; 359 360 case MAX34451_MFR_SEQ_CONFIG: 361 if (pmdev->page < 12) { 362 pmbus_send32(pmdev, s->seq_config[pmdev->page]); 363 } 364 break; 365 366 case MAX34451_MFR_TEMP_SENSOR_CONFIG: 367 if (15 < pmdev->page && pmdev->page < 21) { 368 pmbus_send32(pmdev, s->temp_sensor_config[pmdev->page % 16]); 369 } 370 break; 371 372 case MAX34451_MFR_STORE_SINGLE: 373 pmbus_send32(pmdev, s->store_single); 374 break; 375 376 case MAX34451_MFR_CRC: 377 pmbus_send32(pmdev, s->crc); 378 break; 379 380 default: 381 qemu_log_mask(LOG_GUEST_ERROR, 382 "%s: reading from unsupported register: 0x%02x\n", 383 __func__, pmdev->code); 384 break; 385 } 386 return 0xFF; 387} 388 389static int max34451_write_data(PMBusDevice *pmdev, const uint8_t *buf, 390 uint8_t len) 391{ 392 MAX34451State *s = MAX34451(pmdev); 393 394 if (len == 0) { 395 qemu_log_mask(LOG_GUEST_ERROR, "%s: writing empty data\n", __func__); 396 return -1; 397 } 398 399 pmdev->code = buf[0]; /* PMBus command code */ 400 401 if (len == 1) { 402 return 0; 403 } 404 405 /* Exclude command code from buffer */ 406 buf++; 407 len--; 408 uint8_t index = pmdev->page; 409 410 switch (pmdev->code) { 411 case MAX34451_MFR_STORE_ALL: 412 case MAX34451_MFR_RESTORE_ALL: 413 case MAX34451_MFR_STORE_SINGLE: 414 /* 415 * TODO: hardware behaviour is to move the contents of volatile 416 * memory to non-volatile memory. 417 */ 418 break; 419 420 case PMBUS_POWER_GOOD_ON: /* R/W word */ 421 if (pmdev->page < MAX34451_NUM_PWR_DEVICES) { 422 s->power_good_on[pmdev->page] = pmbus_receive16(pmdev); 423 } 424 break; 425 426 case PMBUS_POWER_GOOD_OFF: /* R/W word */ 427 if (pmdev->page < MAX34451_NUM_PWR_DEVICES) { 428 s->power_good_off[pmdev->page] = pmbus_receive16(pmdev); 429 } 430 break; 431 432 case PMBUS_TON_DELAY: /* R/W word */ 433 if (pmdev->page < 12) { 434 s->ton_delay[pmdev->page] = pmbus_receive16(pmdev); 435 } 436 break; 437 438 case PMBUS_TON_MAX_FAULT_LIMIT: /* R/W word */ 439 if (pmdev->page < 12) { 440 s->ton_max_fault_limit[pmdev->page] 441 = pmbus_receive16(pmdev); 442 } 443 break; 444 445 case PMBUS_TOFF_DELAY: /* R/W word */ 446 if (pmdev->page < 12) { 447 s->toff_delay[pmdev->page] = pmbus_receive16(pmdev); 448 } 449 break; 450 451 case PMBUS_MFR_LOCATION: /* R/W 64 */ 452 s->mfr_location = pmbus_receive64(pmdev); 453 break; 454 455 case PMBUS_MFR_DATE: /* R/W 64 */ 456 s->mfr_date = pmbus_receive64(pmdev); 457 break; 458 459 case PMBUS_MFR_SERIAL: /* R/W 64 */ 460 s->mfr_serial = pmbus_receive64(pmdev); 461 break; 462 463 case MAX34451_MFR_MODE: /* R/W word */ 464 s->mfr_mode = pmbus_receive16(pmdev); 465 break; 466 467 case MAX34451_MFR_PSEN_CONFIG: /* R/W 32 */ 468 if (pmdev->page < 12) { 469 s->psen_config[pmdev->page] = pmbus_receive32(pmdev); 470 } 471 break; 472 473 case MAX34451_MFR_VOUT_PEAK: /* R/W word */ 474 if (pmdev->page < 16) { 475 s->vout_peak[pmdev->page] = pmbus_receive16(pmdev); 476 } 477 break; 478 479 case MAX34451_MFR_IOUT_PEAK: /* R/W word */ 480 if (pmdev->page < 16) { 481 s->iout_peak[pmdev->page] = pmbus_receive16(pmdev); 482 } 483 break; 484 485 case MAX34451_MFR_TEMPERATURE_PEAK: /* R/W word */ 486 if (15 < pmdev->page && pmdev->page < 21) { 487 s->temperature_peak[pmdev->page % 16] 488 = pmbus_receive16(pmdev); 489 } 490 break; 491 492 case MAX34451_MFR_VOUT_MIN: /* R/W word */ 493 if (pmdev->page < 16) { 494 s->vout_min[pmdev->page] = pmbus_receive16(pmdev); 495 } 496 break; 497 498 case MAX34451_MFR_NV_LOG_CONFIG: /* R/W word */ 499 s->nv_log_config = pmbus_receive16(pmdev); 500 break; 501 502 case MAX34451_MFR_FAULT_RESPONSE: /* R/W 32 */ 503 if (pmdev->page < 16) { 504 s->fault_response[pmdev->page] = pmbus_receive32(pmdev); 505 } 506 break; 507 508 case MAX34451_MFR_FAULT_RETRY: /* R/W word */ 509 s->fault_retry = pmbus_receive16(pmdev); 510 break; 511 512 case MAX34451_MFR_TIME_COUNT: /* R/W 32 */ 513 s->time_count = pmbus_receive32(pmdev); 514 break; 515 516 case MAX34451_MFR_MARGIN_CONFIG: /* R/W word */ 517 if (pmdev->page < 12) { 518 s->margin_config[pmdev->page] = pmbus_receive16(pmdev); 519 } 520 break; 521 522 case MAX34451_MFR_CHANNEL_CONFIG: /* R/W word */ 523 if (pmdev->page < 16) { 524 s->channel_config[pmdev->page] = pmbus_receive16(pmdev); 525 } 526 break; 527 528 case MAX34451_MFR_TON_SEQ_MAX: /* R/W word */ 529 if (pmdev->page < 12) { 530 s->ton_seq_max[pmdev->page] = pmbus_receive16(pmdev); 531 } 532 break; 533 534 case MAX34451_MFR_PWM_CONFIG: /* R/W 32 */ 535 if (pmdev->page < 12) { 536 s->pwm_config[pmdev->page] = pmbus_receive32(pmdev); 537 } 538 break; 539 540 case MAX34451_MFR_SEQ_CONFIG: /* R/W 32 */ 541 if (pmdev->page < 12) { 542 s->seq_config[pmdev->page] = pmbus_receive32(pmdev); 543 } 544 break; 545 546 case MAX34451_MFR_TEMP_SENSOR_CONFIG: /* R/W word */ 547 if (15 < pmdev->page && pmdev->page < 21) { 548 s->temp_sensor_config[pmdev->page % 16] 549 = pmbus_receive16(pmdev); 550 } 551 break; 552 553 case MAX34451_MFR_CRC: /* R/W word */ 554 s->crc = pmbus_receive16(pmdev); 555 break; 556 557 case MAX34451_MFR_NV_FAULT_LOG: 558 case MAX34451_MFR_FW_SERIAL: 559 case MAX34451_MFR_IOUT_AVG: 560 /* Read only commands */ 561 pmdev->pages[index].status_word |= PMBUS_STATUS_CML; 562 pmdev->pages[index].status_cml |= PB_CML_FAULT_INVALID_DATA; 563 qemu_log_mask(LOG_GUEST_ERROR, 564 "%s: writing to read-only register 0x%02x\n", 565 __func__, pmdev->code); 566 break; 567 568 default: 569 qemu_log_mask(LOG_GUEST_ERROR, 570 "%s: writing to unsupported register: 0x%02x\n", 571 __func__, pmdev->code); 572 break; 573 } 574 575 return 0; 576} 577 578static void max34451_get(Object *obj, Visitor *v, const char *name, 579 void *opaque, Error **errp) 580{ 581 visit_type_uint16(v, name, (uint16_t *)opaque, errp); 582} 583 584static void max34451_set(Object *obj, Visitor *v, const char *name, 585 void *opaque, Error **errp) 586{ 587 MAX34451State *s = MAX34451(obj); 588 uint16_t *internal = opaque; 589 uint16_t value; 590 if (!visit_type_uint16(v, name, &value, errp)) { 591 return; 592 } 593 594 *internal = value; 595 max34451_check_limits(s); 596} 597 598/* used to init uint16_t arrays */ 599static inline void *memset_word(void *s, uint16_t c, size_t n) 600{ 601 size_t i; 602 uint16_t *p = s; 603 604 for (i = 0; i < n; i++) { 605 p[i] = c; 606 } 607 608 return s; 609} 610 611static void max34451_exit_reset(Object *obj) 612{ 613 PMBusDevice *pmdev = PMBUS_DEVICE(obj); 614 MAX34451State *s = MAX34451(obj); 615 pmdev->capability = DEFAULT_CAPABILITY; 616 617 for (int i = 0; i < MAX34451_NUM_PAGES; i++) { 618 pmdev->pages[i].operation = DEFAULT_OP_ON; 619 pmdev->pages[i].on_off_config = DEFAULT_ON_OFF_CONFIG; 620 pmdev->pages[i].revision = 0x11; 621 pmdev->pages[i].vout_mode = DEFAULT_VOUT_MODE; 622 } 623 624 for (int i = 0; i < MAX34451_NUM_PWR_DEVICES; i++) { 625 pmdev->pages[i].vout_scale_monitor = DEFAULT_SCALE; 626 pmdev->pages[i].vout_ov_fault_limit = DEFAULT_OV_LIMIT; 627 pmdev->pages[i].vout_ov_warn_limit = DEFAULT_OV_LIMIT; 628 pmdev->pages[i].iout_oc_warn_limit = DEFAULT_OC_LIMIT; 629 pmdev->pages[i].iout_oc_fault_limit = DEFAULT_OC_LIMIT; 630 } 631 632 for (int i = 0; i < MAX34451_NUM_MARGINED_PSU; i++) { 633 pmdev->pages[i].ton_max_fault_limit = DEFAULT_TON_FAULT_LIMIT; 634 } 635 636 for (int i = 16; i < MAX34451_NUM_TEMP_DEVICES + 16; i++) { 637 pmdev->pages[i].read_temperature_1 = DEFAULT_TEMPERATURE; 638 pmdev->pages[i].ot_warn_limit = DEFAULT_OT_LIMIT; 639 pmdev->pages[i].ot_fault_limit = DEFAULT_OT_LIMIT; 640 } 641 642 memset_word(s->ton_max_fault_limit, DEFAULT_TON_FAULT_LIMIT, 643 MAX34451_NUM_MARGINED_PSU); 644 memset_word(s->channel_config, DEFAULT_CHANNEL_CONFIG, 645 MAX34451_NUM_PWR_DEVICES); 646 memset_word(s->vout_min, DEFAULT_VMIN, MAX34451_NUM_PWR_DEVICES); 647 648 s->mfr_location = DEFAULT_TEXT; 649 s->mfr_date = DEFAULT_TEXT; 650 s->mfr_serial = DEFAULT_TEXT; 651} 652 653static const VMStateDescription vmstate_max34451 = { 654 .name = TYPE_MAX34451, 655 .version_id = 0, 656 .minimum_version_id = 0, 657 .fields = (VMStateField[]){ 658 VMSTATE_PMBUS_DEVICE(parent, MAX34451State), 659 VMSTATE_UINT16_ARRAY(power_good_on, MAX34451State, 660 MAX34451_NUM_PWR_DEVICES), 661 VMSTATE_UINT16_ARRAY(power_good_off, MAX34451State, 662 MAX34451_NUM_PWR_DEVICES), 663 VMSTATE_UINT16_ARRAY(ton_delay, MAX34451State, 664 MAX34451_NUM_MARGINED_PSU), 665 VMSTATE_UINT16_ARRAY(ton_max_fault_limit, MAX34451State, 666 MAX34451_NUM_MARGINED_PSU), 667 VMSTATE_UINT16_ARRAY(toff_delay, MAX34451State, 668 MAX34451_NUM_MARGINED_PSU), 669 VMSTATE_UINT8_ARRAY(status_mfr_specific, MAX34451State, 670 MAX34451_NUM_PWR_DEVICES), 671 VMSTATE_UINT64(mfr_location, MAX34451State), 672 VMSTATE_UINT64(mfr_date, MAX34451State), 673 VMSTATE_UINT64(mfr_serial, MAX34451State), 674 VMSTATE_UINT16(mfr_mode, MAX34451State), 675 VMSTATE_UINT32_ARRAY(psen_config, MAX34451State, 676 MAX34451_NUM_MARGINED_PSU), 677 VMSTATE_UINT16_ARRAY(vout_peak, MAX34451State, 678 MAX34451_NUM_PWR_DEVICES), 679 VMSTATE_UINT16_ARRAY(iout_peak, MAX34451State, 680 MAX34451_NUM_PWR_DEVICES), 681 VMSTATE_UINT16_ARRAY(temperature_peak, MAX34451State, 682 MAX34451_NUM_TEMP_DEVICES), 683 VMSTATE_UINT16_ARRAY(vout_min, MAX34451State, MAX34451_NUM_PWR_DEVICES), 684 VMSTATE_UINT16(nv_log_config, MAX34451State), 685 VMSTATE_UINT32_ARRAY(fault_response, MAX34451State, 686 MAX34451_NUM_PWR_DEVICES), 687 VMSTATE_UINT16(fault_retry, MAX34451State), 688 VMSTATE_UINT32(fault_log, MAX34451State), 689 VMSTATE_UINT32(time_count, MAX34451State), 690 VMSTATE_UINT16_ARRAY(margin_config, MAX34451State, 691 MAX34451_NUM_MARGINED_PSU), 692 VMSTATE_UINT16(fw_serial, MAX34451State), 693 VMSTATE_UINT16_ARRAY(iout_avg, MAX34451State, MAX34451_NUM_PWR_DEVICES), 694 VMSTATE_UINT16_ARRAY(channel_config, MAX34451State, 695 MAX34451_NUM_PWR_DEVICES), 696 VMSTATE_UINT16_ARRAY(ton_seq_max, MAX34451State, 697 MAX34451_NUM_MARGINED_PSU), 698 VMSTATE_UINT32_ARRAY(pwm_config, MAX34451State, 699 MAX34451_NUM_MARGINED_PSU), 700 VMSTATE_UINT32_ARRAY(seq_config, MAX34451State, 701 MAX34451_NUM_MARGINED_PSU), 702 VMSTATE_UINT16_ARRAY(temp_sensor_config, MAX34451State, 703 MAX34451_NUM_TEMP_DEVICES), 704 VMSTATE_UINT16(store_single, MAX34451State), 705 VMSTATE_UINT16(crc, MAX34451State), 706 VMSTATE_END_OF_LIST() 707 } 708}; 709 710static void max34451_init(Object *obj) 711{ 712 PMBusDevice *pmdev = PMBUS_DEVICE(obj); 713 uint64_t psu_flags = PB_HAS_VOUT | PB_HAS_IOUT | PB_HAS_VOUT_MODE | 714 PB_HAS_IOUT_GAIN; 715 716 for (int i = 0; i < MAX34451_NUM_PWR_DEVICES; i++) { 717 pmbus_page_config(pmdev, i, psu_flags); 718 } 719 720 for (int i = 0; i < MAX34451_NUM_MARGINED_PSU; i++) { 721 pmbus_page_config(pmdev, i, psu_flags | PB_HAS_VOUT_MARGIN); 722 } 723 724 for (int i = 16; i < MAX34451_NUM_TEMP_DEVICES + 16; i++) { 725 pmbus_page_config(pmdev, i, PB_HAS_TEMPERATURE | PB_HAS_VOUT_MODE); 726 } 727 728 /* get and set the voltage in millivolts, max is 32767 mV */ 729 for (int i = 0; i < MAX34451_NUM_PWR_DEVICES; i++) { 730 object_property_add(obj, "vout[*]", "uint16", 731 max34451_get, 732 max34451_set, NULL, &pmdev->pages[i].read_vout); 733 } 734 735 /* 736 * get and set the temperature of the internal temperature sensor in 737 * centidegrees Celcius i.e.: 2500 -> 25.00 C, max is 327.67 C 738 */ 739 for (int i = 0; i < MAX34451_NUM_TEMP_DEVICES; i++) { 740 object_property_add(obj, "temperature[*]", "uint16", 741 max34451_get, 742 max34451_set, 743 NULL, 744 &pmdev->pages[i + 16].read_temperature_1); 745 } 746 747} 748 749static void max34451_class_init(ObjectClass *klass, void *data) 750{ 751 ResettableClass *rc = RESETTABLE_CLASS(klass); 752 DeviceClass *dc = DEVICE_CLASS(klass); 753 PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass); 754 dc->desc = "Maxim MAX34451 16-Channel V/I monitor"; 755 dc->vmsd = &vmstate_max34451; 756 k->write_data = max34451_write_data; 757 k->receive_byte = max34451_read_byte; 758 k->device_num_pages = MAX34451_NUM_PAGES; 759 rc->phases.exit = max34451_exit_reset; 760} 761 762static const TypeInfo max34451_info = { 763 .name = TYPE_MAX34451, 764 .parent = TYPE_PMBUS_DEVICE, 765 .instance_size = sizeof(MAX34451State), 766 .instance_init = max34451_init, 767 .class_init = max34451_class_init, 768}; 769 770static void max34451_register_types(void) 771{ 772 type_register_static(&max34451_info); 773} 774 775type_init(max34451_register_types)