qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

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  */
    137 typedef 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 
    174 static 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 
    205 static 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 
    389 static 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 
    578 static 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 
    584 static 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 */
    599 static 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 
    611 static 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 
    653 static 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 
    710 static 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 
    749 static 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 
    762 static 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 
    770 static void max34451_register_types(void)
    771 {
    772     type_register_static(&max34451_info);
    773 }
    774 
    775 type_init(max34451_register_types)