qemu/hw/sensor/max34451.c
<<
>>
Prefs
   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)
 776