2 * Maxim MAX34451 PMBus 16-Channel V/I monitor and 12-Channel Sequencer/Marginer
4 * Copyright 2021 Google LLC
6 * SPDX-License-Identifier: GPL-2.0-or-later
9 #include "qemu/osdep.h"
10 #include "hw/i2c/pmbus_device.h"
12 #include "migration/vmstate.h"
13 #include "qapi/error.h"
14 #include "qapi/visitor.h"
16 #include "qemu/module.h"
18 #define TYPE_MAX34451 "max34451"
19 #define MAX34451(obj) OBJECT_CHECK(MAX34451State, (obj), TYPE_MAX34451)
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
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
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
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 |_______|___________________________________________________________________|
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
137 typedef struct MAX34451State
{
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
;
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
;
161 uint16_t margin_config
[MAX34451_NUM_MARGINED_PSU
];
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
;
174 static void max34451_check_limits(MAX34451State
*s
)
176 PMBusDevice
*pmdev
= PMBUS_DEVICE(s
);
178 pmbus_check_limits(pmdev
);
180 for (int i
= 0; i
< MAX34451_NUM_PWR_DEVICES
; i
++) {
181 if (pmdev
->pages
[i
].read_vout
== 0) { /* PSU disabled */
185 if (pmdev
->pages
[i
].read_vout
> s
->vout_peak
[i
]) {
186 s
->vout_peak
[i
] = pmdev
->pages
[i
].read_vout
;
189 if (pmdev
->pages
[i
].read_vout
< s
->vout_min
[i
]) {
190 s
->vout_min
[i
] = pmdev
->pages
[i
].read_vout
;
193 if (pmdev
->pages
[i
].read_iout
> s
->iout_peak
[i
]) {
194 s
->iout_peak
[i
] = pmdev
->pages
[i
].read_iout
;
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
;
205 static uint8_t max34451_read_byte(PMBusDevice
*pmdev
)
207 MAX34451State
*s
= MAX34451(pmdev
);
208 switch (pmdev
->code
) {
210 case PMBUS_POWER_GOOD_ON
:
211 if (pmdev
->page
< 16) {
212 pmbus_send16(pmdev
, s
->power_good_on
[pmdev
->page
]);
216 case PMBUS_POWER_GOOD_OFF
:
217 if (pmdev
->page
< 16) {
218 pmbus_send16(pmdev
, s
->power_good_off
[pmdev
->page
]);
222 case PMBUS_TON_DELAY
:
223 if (pmdev
->page
< 12) {
224 pmbus_send16(pmdev
, s
->ton_delay
[pmdev
->page
]);
228 case PMBUS_TON_MAX_FAULT_LIMIT
:
229 if (pmdev
->page
< 12) {
230 pmbus_send16(pmdev
, s
->ton_max_fault_limit
[pmdev
->page
]);
234 case PMBUS_TOFF_DELAY
:
235 if (pmdev
->page
< 12) {
236 pmbus_send16(pmdev
, s
->toff_delay
[pmdev
->page
]);
240 case PMBUS_STATUS_MFR_SPECIFIC
:
241 if (pmdev
->page
< 16) {
242 pmbus_send8(pmdev
, s
->status_mfr_specific
[pmdev
->page
]);
247 pmbus_send8(pmdev
, 0x4d); /* Maxim */
250 case PMBUS_MFR_MODEL
:
251 pmbus_send8(pmdev
, 0x59);
254 case PMBUS_MFR_LOCATION
:
255 pmbus_send64(pmdev
, s
->mfr_location
);
259 pmbus_send64(pmdev
, s
->mfr_date
);
262 case PMBUS_MFR_SERIAL
:
263 pmbus_send64(pmdev
, s
->mfr_serial
);
266 case MAX34451_MFR_MODE
:
267 pmbus_send16(pmdev
, s
->mfr_mode
);
270 case MAX34451_MFR_PSEN_CONFIG
:
271 if (pmdev
->page
< 12) {
272 pmbus_send32(pmdev
, s
->psen_config
[pmdev
->page
]);
276 case MAX34451_MFR_VOUT_PEAK
:
277 if (pmdev
->page
< 16) {
278 pmbus_send16(pmdev
, s
->vout_peak
[pmdev
->page
]);
282 case MAX34451_MFR_IOUT_PEAK
:
283 if (pmdev
->page
< 16) {
284 pmbus_send16(pmdev
, s
->iout_peak
[pmdev
->page
]);
288 case MAX34451_MFR_TEMPERATURE_PEAK
:
289 if (15 < pmdev
->page
&& pmdev
->page
< 21) {
290 pmbus_send16(pmdev
, s
->temperature_peak
[pmdev
->page
% 16]);
292 pmbus_send16(pmdev
, s
->temperature_peak
[0]);
296 case MAX34451_MFR_VOUT_MIN
:
297 if (pmdev
->page
< 16) {
298 pmbus_send16(pmdev
, s
->vout_min
[pmdev
->page
]);
302 case MAX34451_MFR_NV_LOG_CONFIG
:
303 pmbus_send16(pmdev
, s
->nv_log_config
);
306 case MAX34451_MFR_FAULT_RESPONSE
:
307 if (pmdev
->page
< 16) {
308 pmbus_send32(pmdev
, s
->fault_response
[pmdev
->page
]);
312 case MAX34451_MFR_FAULT_RETRY
:
313 pmbus_send32(pmdev
, s
->fault_retry
);
316 case MAX34451_MFR_NV_FAULT_LOG
:
317 pmbus_send32(pmdev
, s
->fault_log
);
320 case MAX34451_MFR_TIME_COUNT
:
321 pmbus_send32(pmdev
, s
->time_count
);
324 case MAX34451_MFR_MARGIN_CONFIG
:
325 if (pmdev
->page
< 12) {
326 pmbus_send16(pmdev
, s
->margin_config
[pmdev
->page
]);
330 case MAX34451_MFR_FW_SERIAL
:
331 if (pmdev
->page
== 255) {
332 pmbus_send16(pmdev
, 1); /* Firmware revision */
336 case MAX34451_MFR_IOUT_AVG
:
337 if (pmdev
->page
< 16) {
338 pmbus_send16(pmdev
, s
->iout_avg
[pmdev
->page
]);
342 case MAX34451_MFR_CHANNEL_CONFIG
:
343 if (pmdev
->page
< 16) {
344 pmbus_send16(pmdev
, s
->channel_config
[pmdev
->page
]);
348 case MAX34451_MFR_TON_SEQ_MAX
:
349 if (pmdev
->page
< 12) {
350 pmbus_send16(pmdev
, s
->ton_seq_max
[pmdev
->page
]);
354 case MAX34451_MFR_PWM_CONFIG
:
355 if (pmdev
->page
< 12) {
356 pmbus_send32(pmdev
, s
->pwm_config
[pmdev
->page
]);
360 case MAX34451_MFR_SEQ_CONFIG
:
361 if (pmdev
->page
< 12) {
362 pmbus_send32(pmdev
, s
->seq_config
[pmdev
->page
]);
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]);
372 case MAX34451_MFR_STORE_SINGLE
:
373 pmbus_send32(pmdev
, s
->store_single
);
376 case MAX34451_MFR_CRC
:
377 pmbus_send32(pmdev
, s
->crc
);
381 qemu_log_mask(LOG_GUEST_ERROR
,
382 "%s: reading from unsupported register: 0x%02x\n",
383 __func__
, pmdev
->code
);
389 static int max34451_write_data(PMBusDevice
*pmdev
, const uint8_t *buf
,
392 MAX34451State
*s
= MAX34451(pmdev
);
395 qemu_log_mask(LOG_GUEST_ERROR
, "%s: writing empty data\n", __func__
);
399 pmdev
->code
= buf
[0]; /* PMBus command code */
405 /* Exclude command code from buffer */
408 uint8_t index
= pmdev
->page
;
410 switch (pmdev
->code
) {
411 case MAX34451_MFR_STORE_ALL
:
412 case MAX34451_MFR_RESTORE_ALL
:
413 case MAX34451_MFR_STORE_SINGLE
:
415 * TODO: hardware behaviour is to move the contents of volatile
416 * memory to non-volatile memory.
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
);
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
);
432 case PMBUS_TON_DELAY
: /* R/W word */
433 if (pmdev
->page
< 12) {
434 s
->ton_delay
[pmdev
->page
] = pmbus_receive16(pmdev
);
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
);
445 case PMBUS_TOFF_DELAY
: /* R/W word */
446 if (pmdev
->page
< 12) {
447 s
->toff_delay
[pmdev
->page
] = pmbus_receive16(pmdev
);
451 case PMBUS_MFR_LOCATION
: /* R/W 64 */
452 s
->mfr_location
= pmbus_receive64(pmdev
);
455 case PMBUS_MFR_DATE
: /* R/W 64 */
456 s
->mfr_date
= pmbus_receive64(pmdev
);
459 case PMBUS_MFR_SERIAL
: /* R/W 64 */
460 s
->mfr_serial
= pmbus_receive64(pmdev
);
463 case MAX34451_MFR_MODE
: /* R/W word */
464 s
->mfr_mode
= pmbus_receive16(pmdev
);
467 case MAX34451_MFR_PSEN_CONFIG
: /* R/W 32 */
468 if (pmdev
->page
< 12) {
469 s
->psen_config
[pmdev
->page
] = pmbus_receive32(pmdev
);
473 case MAX34451_MFR_VOUT_PEAK
: /* R/W word */
474 if (pmdev
->page
< 16) {
475 s
->vout_peak
[pmdev
->page
] = pmbus_receive16(pmdev
);
479 case MAX34451_MFR_IOUT_PEAK
: /* R/W word */
480 if (pmdev
->page
< 16) {
481 s
->iout_peak
[pmdev
->page
] = pmbus_receive16(pmdev
);
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
);
492 case MAX34451_MFR_VOUT_MIN
: /* R/W word */
493 if (pmdev
->page
< 16) {
494 s
->vout_min
[pmdev
->page
] = pmbus_receive16(pmdev
);
498 case MAX34451_MFR_NV_LOG_CONFIG
: /* R/W word */
499 s
->nv_log_config
= pmbus_receive16(pmdev
);
502 case MAX34451_MFR_FAULT_RESPONSE
: /* R/W 32 */
503 if (pmdev
->page
< 16) {
504 s
->fault_response
[pmdev
->page
] = pmbus_receive32(pmdev
);
508 case MAX34451_MFR_FAULT_RETRY
: /* R/W word */
509 s
->fault_retry
= pmbus_receive16(pmdev
);
512 case MAX34451_MFR_TIME_COUNT
: /* R/W 32 */
513 s
->time_count
= pmbus_receive32(pmdev
);
516 case MAX34451_MFR_MARGIN_CONFIG
: /* R/W word */
517 if (pmdev
->page
< 12) {
518 s
->margin_config
[pmdev
->page
] = pmbus_receive16(pmdev
);
522 case MAX34451_MFR_CHANNEL_CONFIG
: /* R/W word */
523 if (pmdev
->page
< 16) {
524 s
->channel_config
[pmdev
->page
] = pmbus_receive16(pmdev
);
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
);
534 case MAX34451_MFR_PWM_CONFIG
: /* R/W 32 */
535 if (pmdev
->page
< 12) {
536 s
->pwm_config
[pmdev
->page
] = pmbus_receive32(pmdev
);
540 case MAX34451_MFR_SEQ_CONFIG
: /* R/W 32 */
541 if (pmdev
->page
< 12) {
542 s
->seq_config
[pmdev
->page
] = pmbus_receive32(pmdev
);
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
);
553 case MAX34451_MFR_CRC
: /* R/W word */
554 s
->crc
= pmbus_receive16(pmdev
);
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
);
569 qemu_log_mask(LOG_GUEST_ERROR
,
570 "%s: writing to unsupported register: 0x%02x\n",
571 __func__
, pmdev
->code
);
578 static void max34451_get(Object
*obj
, Visitor
*v
, const char *name
,
579 void *opaque
, Error
**errp
)
581 visit_type_uint16(v
, name
, (uint16_t *)opaque
, errp
);
584 static void max34451_set(Object
*obj
, Visitor
*v
, const char *name
,
585 void *opaque
, Error
**errp
)
587 MAX34451State
*s
= MAX34451(obj
);
588 uint16_t *internal
= opaque
;
590 if (!visit_type_uint16(v
, name
, &value
, errp
)) {
595 max34451_check_limits(s
);
598 /* used to init uint16_t arrays */
599 static inline void *memset_word(void *s
, uint16_t c
, size_t n
)
604 for (i
= 0; i
< n
; i
++) {
611 static void max34451_exit_reset(Object
*obj
, ResetType type
)
613 PMBusDevice
*pmdev
= PMBUS_DEVICE(obj
);
614 MAX34451State
*s
= MAX34451(obj
);
615 pmdev
->capability
= DEFAULT_CAPABILITY
;
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
;
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
;
632 for (int i
= 0; i
< MAX34451_NUM_MARGINED_PSU
; i
++) {
633 pmdev
->pages
[i
].ton_max_fault_limit
= DEFAULT_TON_FAULT_LIMIT
;
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
;
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
);
648 s
->mfr_location
= DEFAULT_TEXT
;
649 s
->mfr_date
= DEFAULT_TEXT
;
650 s
->mfr_serial
= DEFAULT_TEXT
;
653 static const VMStateDescription vmstate_max34451
= {
654 .name
= TYPE_MAX34451
,
656 .minimum_version_id
= 0,
657 .fields
= (const 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()
710 static void max34451_init(Object
*obj
)
712 PMBusDevice
*pmdev
= PMBUS_DEVICE(obj
);
713 uint64_t psu_flags
= PB_HAS_VOUT
| PB_HAS_IOUT
| PB_HAS_VOUT_MODE
|
716 for (int i
= 0; i
< MAX34451_NUM_PWR_DEVICES
; i
++) {
717 pmbus_page_config(pmdev
, i
, psu_flags
);
720 for (int i
= 0; i
< MAX34451_NUM_MARGINED_PSU
; i
++) {
721 pmbus_page_config(pmdev
, i
, psu_flags
| PB_HAS_VOUT_MARGIN
);
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
);
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",
732 max34451_set
, NULL
, &pmdev
->pages
[i
].read_vout
);
736 * get and set the temperature of the internal temperature sensor in
737 * centidegrees Celsius i.e.: 2500 -> 25.00 C, max is 327.67 C
739 for (int i
= 0; i
< MAX34451_NUM_TEMP_DEVICES
; i
++) {
740 object_property_add(obj
, "temperature[*]", "uint16",
744 &pmdev
->pages
[i
+ 16].read_temperature_1
);
749 static void max34451_class_init(ObjectClass
*klass
, void *data
)
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
;
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
,
770 static void max34451_register_types(void)
772 type_register_static(&max34451_info
);
775 type_init(max34451_register_types
)