]> git.proxmox.com Git - mirror_qemu.git/blame - hw/sensor/max34451.c
hw/ppc/mac.h: Remove MAX_CPUS macro
[mirror_qemu.git] / hw / sensor / max34451.c
CommitLineData
7215456a
TR
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)