]> git.proxmox.com Git - mirror_qemu.git/blame - hw/sensor/max31785.c
Merge tag 'pull-aspeed-20220630' of https://github.com/legoater/qemu into staging
[mirror_qemu.git] / hw / sensor / max31785.c
CommitLineData
62365482
MK
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Maxim MAX31785 PMBus 6-Channel Fan Controller
4 *
5 * Datasheet:
6 * https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf
7 *
8 * Copyright(c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
9 */
10
11#include "qemu/osdep.h"
12#include "hw/i2c/pmbus_device.h"
13#include "hw/irq.h"
14#include "migration/vmstate.h"
15#include "qapi/error.h"
16#include "qapi/visitor.h"
17#include "qemu/log.h"
18#include "qemu/module.h"
19
20#define TYPE_MAX31785 "max31785"
21#define MAX31785(obj) OBJECT_CHECK(MAX31785State, (obj), TYPE_MAX31785)
22
23/* MAX31785 mfr specific PMBus commands */
24#define MAX31785_MFR_MODE 0xD1
25#define MAX31785_MFR_PSEN_CONFIG 0xD2
26#define MAX31785_MFR_VOUT_PEAK 0xD4
27#define MAX31785_MFR_TEMPERATURE_PEAK 0xD6
28#define MAX31785_MFR_VOUT_MIN 0xD7
29#define MAX31785_MFR_FAULT_RESPONSE 0xD9
30#define MAX31785_MFR_NV_FAULT_LOG 0xDC
31#define MAX31785_MFR_TIME_COUNT 0xDD
32#define MAX31785_MFR_TEMP_SENSOR_CONFIG 0xF0
33#define MAX31785_MFR_FAN_CONFIG 0xF1
34#define MAX31785_MFR_FAN_LUT 0xF2
35#define MAX31785_MFR_READ_FAN_PWM 0xF3
36#define MAX31785_MFR_FAN_FAULT_LIMIT 0xF5
37#define MAX31785_MFR_FAN_WARN_LIMIT 0xF6
38#define MAX31785_MFR_FAN_RUN_TIME 0xF7
39#define MAX31785_MFR_FAN_PWM_AVG 0xF8
40#define MAX31785_MFR_FAN_PWM2RPM 0xF9
41
42/* defaults as per the data sheet */
43#define MAX31785_DEFAULT_CAPABILITY 0x10
44#define MAX31785_DEFAULT_VOUT_MODE 0x40
45#define MAX31785_DEFAULT_VOUT_SCALE_MONITOR 0x7FFF
46#define MAX31785_DEFAULT_FAN_COMMAND_1 0x7FFF
47#define MAX31785_DEFAULT_OV_FAULT_LIMIT 0x7FFF
48#define MAX31785_DEFAULT_OV_WARN_LIMIT 0x7FFF
49#define MAX31785_DEFAULT_OT_FAULT_LIMIT 0x7FFF
50#define MAX31785_DEFAULT_OT_WARN_LIMIT 0x7FFF
51#define MAX31785_DEFAULT_PMBUS_REVISION 0x11
52#define MAX31785_DEFAULT_MFR_ID 0x4D
53#define MAX31785_DEFAULT_MFR_MODEL 0x53
54#define MAX31785_DEFAULT_MFR_REVISION 0x3030
55#define MAX31785A_DEFAULT_MFR_REVISION 0x3040
56#define MAX31785B_DEFAULT_MFR_REVISION 0x3061
57#define MAX31785B_DEFAULT_MFR_TEMPERATURE_PEAK 0x8000
58#define MAX31785B_DEFAULT_MFR_VOUT_MIN 0x7FFF
59#define MAX31785_DEFAULT_TEXT 0x3130313031303130
60
61/* MAX31785 pages */
62#define MAX31785_TOTAL_NUM_PAGES 23
63#define MAX31785_FAN_PAGES 6
64#define MAX31785_MIN_FAN_PAGE 0
65#define MAX31785_MAX_FAN_PAGE 5
66#define MAX31785_MIN_TEMP_PAGE 6
67#define MAX31785_MAX_TEMP_PAGE 16
68#define MAX31785_MIN_ADC_VOLTAGE_PAGE 17
69#define MAX31785_MAX_ADC_VOLTAGE_PAGE 22
70
71/* FAN_CONFIG_1_2 */
72#define MAX31785_MFR_FAN_CONFIG 0xF1
73#define MAX31785_FAN_CONFIG_ENABLE BIT(7)
74#define MAX31785_FAN_CONFIG_RPM_PWM BIT(6)
75#define MAX31785_FAN_CONFIG_PULSE(pulse) (pulse << 4)
76#define MAX31785_DEFAULT_FAN_CONFIG_1_2(pulse) \
77 (MAX31785_FAN_CONFIG_ENABLE | MAX31785_FAN_CONFIG_PULSE(pulse))
78#define MAX31785_DEFAULT_MFR_FAN_CONFIG 0x0000
79
80/* fan speed in RPM */
81#define MAX31785_DEFAULT_FAN_SPEED 0x7fff
82#define MAX31785_DEFAULT_FAN_STATUS 0x00
83
84#define MAX31785_DEFAULT_FAN_MAX_PWM 0x2710
85
86/*
87 * MAX31785State:
88 * @code: The command code received
89 * @page: Each page corresponds to a device monitored by the Max 31785
90 * The page register determines the available commands depending on device
91 * _____________________________________________________________________________
92 * | 0 | Fan Connected to PWM0 |
93 * |_______|___________________________________________________________________|
94 * | 1 | Fan Connected to PWM1 |
95 * |_______|___________________________________________________________________|
96 * | 2 | Fan Connected to PWM2 |
97 * |_______|___________________________________________________________________|
98 * | 3 | Fan Connected to PWM3 |
99 * |_______|___________________________________________________________________|
100 * | 4 | Fan Connected to PWM4 |
101 * |_______|___________________________________________________________________|
102 * | 5 | Fan Connected to PWM5 |
103 * |_______|___________________________________________________________________|
104 * | 6 | Remote Thermal Diode Connected to ADC 0 |
105 * |_______|___________________________________________________________________|
106 * | 7 | Remote Thermal Diode Connected to ADC 1 |
107 * |_______|___________________________________________________________________|
108 * | 8 | Remote Thermal Diode Connected to ADC 2 |
109 * |_______|___________________________________________________________________|
110 * | 9 | Remote Thermal Diode Connected to ADC 3 |
111 * |_______|___________________________________________________________________|
112 * | 10 | Remote Thermal Diode Connected to ADC 4 |
113 * |_______|___________________________________________________________________|
114 * | 11 | Remote Thermal Diode Connected to ADC 5 |
115 * |_______|___________________________________________________________________|
116 * | 12 | Internal Temperature Sensor |
117 * |_______|___________________________________________________________________|
118 * | 13 | Remote I2C Temperature Sensor with Address 0 |
119 * |_______|___________________________________________________________________|
120 * | 14 | Remote I2C Temperature Sensor with Address 1 |
121 * |_______|___________________________________________________________________|
122 * | 15 | Remote I2C Temperature Sensor with Address 2 |
123 * |_______|___________________________________________________________________|
124 * | 16 | Remote I2C Temperature Sensor with Address 3 |
125 * |_______|___________________________________________________________________|
126 * | 17 | Remote I2C Temperature Sensor with Address 4 |
127 * |_______|___________________________________________________________________|
128 * | 17 | Remote Voltage Connected to ADC0 |
129 * |_______|___________________________________________________________________|
130 * | 18 | Remote Voltage Connected to ADC1 |
131 * |_______|___________________________________________________________________|
132 * | 19 | Remote Voltage Connected to ADC2 |
133 * |_______|___________________________________________________________________|
134 * | 20 | Remote Voltage Connected to ADC3 |
135 * |_______|___________________________________________________________________|
136 * | 21 | Remote Voltage Connected to ADC4 |
137 * |_______|___________________________________________________________________|
138 * | 22 | Remote Voltage Connected to ADC5 |
139 * |_______|___________________________________________________________________|
140 * |23-254 | Reserved |
141 * |_______|___________________________________________________________________|
142 * | 255 | Applies to all pages |
143 * |_______|___________________________________________________________________|
144 */
145
146/* Place holder to save the max31785 mfr specific registers */
147typedef struct MAX31785State {
148 PMBusDevice parent;
149 uint16_t mfr_mode[MAX31785_TOTAL_NUM_PAGES];
150 uint16_t vout_peak[MAX31785_TOTAL_NUM_PAGES];
151 uint16_t temperature_peak[MAX31785_TOTAL_NUM_PAGES];
152 uint16_t vout_min[MAX31785_TOTAL_NUM_PAGES];
153 uint8_t fault_response[MAX31785_TOTAL_NUM_PAGES];
154 uint32_t time_count[MAX31785_TOTAL_NUM_PAGES];
155 uint16_t temp_sensor_config[MAX31785_TOTAL_NUM_PAGES];
156 uint16_t fan_config[MAX31785_TOTAL_NUM_PAGES];
157 uint16_t read_fan_pwm[MAX31785_TOTAL_NUM_PAGES];
158 uint16_t fan_fault_limit[MAX31785_TOTAL_NUM_PAGES];
159 uint16_t fan_warn_limit[MAX31785_TOTAL_NUM_PAGES];
160 uint16_t fan_run_time[MAX31785_TOTAL_NUM_PAGES];
161 uint16_t fan_pwm_avg[MAX31785_TOTAL_NUM_PAGES];
162 uint64_t fan_pwm2rpm[MAX31785_TOTAL_NUM_PAGES];
163 uint64_t mfr_location;
164 uint64_t mfr_date;
165 uint64_t mfr_serial;
166 uint16_t mfr_revision;
167} MAX31785State;
168
169static uint8_t max31785_read_byte(PMBusDevice *pmdev)
170{
171 MAX31785State *s = MAX31785(pmdev);
172 switch (pmdev->code) {
173
174 case PMBUS_FAN_CONFIG_1_2:
175 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
176 pmbus_send8(pmdev, pmdev->pages[pmdev->page].fan_config_1_2);
177 }
178 break;
179
180 case PMBUS_FAN_COMMAND_1:
181 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
182 pmbus_send16(pmdev, pmdev->pages[pmdev->page].fan_command_1);
183 }
184 break;
185
186 case PMBUS_READ_FAN_SPEED_1:
187 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
188 pmbus_send16(pmdev, pmdev->pages[pmdev->page].read_fan_speed_1);
189 }
190 break;
191
192 case PMBUS_STATUS_FANS_1_2:
193 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
194 pmbus_send16(pmdev, pmdev->pages[pmdev->page].status_fans_1_2);
195 }
196 break;
197
198 case PMBUS_MFR_REVISION:
199 pmbus_send16(pmdev, MAX31785_DEFAULT_MFR_REVISION);
200 break;
201
202 case PMBUS_MFR_ID:
203 pmbus_send8(pmdev, 0x4d); /* Maxim */
204 break;
205
206 case PMBUS_MFR_MODEL:
207 pmbus_send8(pmdev, 0x53);
208 break;
209
210 case PMBUS_MFR_LOCATION:
211 pmbus_send64(pmdev, s->mfr_location);
212 break;
213
214 case PMBUS_MFR_DATE:
215 pmbus_send64(pmdev, s->mfr_date);
216 break;
217
218 case PMBUS_MFR_SERIAL:
219 pmbus_send64(pmdev, s->mfr_serial);
220 break;
221
222 case MAX31785_MFR_MODE:
223 pmbus_send16(pmdev, s->mfr_mode[pmdev->page]);
224 break;
225
226 case MAX31785_MFR_VOUT_PEAK:
227 if ((pmdev->page >= MAX31785_MIN_ADC_VOLTAGE_PAGE) &&
228 (pmdev->page <= MAX31785_MAX_ADC_VOLTAGE_PAGE)) {
229 pmbus_send16(pmdev, s->vout_peak[pmdev->page]);
230 }
231 break;
232
233 case MAX31785_MFR_TEMPERATURE_PEAK:
234 if ((pmdev->page >= MAX31785_MIN_TEMP_PAGE) &&
235 (pmdev->page <= MAX31785_MAX_TEMP_PAGE)) {
236 pmbus_send16(pmdev, s->temperature_peak[pmdev->page]);
237 }
238 break;
239
240 case MAX31785_MFR_VOUT_MIN:
241 if ((pmdev->page >= MAX31785_MIN_ADC_VOLTAGE_PAGE) &&
242 (pmdev->page <= MAX31785_MAX_ADC_VOLTAGE_PAGE)) {
243 pmbus_send16(pmdev, s->vout_min[pmdev->page]);
244 }
245 break;
246
247 case MAX31785_MFR_FAULT_RESPONSE:
248 pmbus_send8(pmdev, s->fault_response[pmdev->page]);
249 break;
250
251 case MAX31785_MFR_TIME_COUNT: /* R/W 32 */
252 pmbus_send32(pmdev, s->time_count[pmdev->page]);
253 break;
254
255 case MAX31785_MFR_TEMP_SENSOR_CONFIG: /* R/W 16 */
256 if ((pmdev->page >= MAX31785_MIN_TEMP_PAGE) &&
257 (pmdev->page <= MAX31785_MAX_TEMP_PAGE)) {
258 pmbus_send16(pmdev, s->temp_sensor_config[pmdev->page]);
259 }
260 break;
261
262 case MAX31785_MFR_FAN_CONFIG: /* R/W 16 */
263 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
264 pmbus_send16(pmdev, s->fan_config[pmdev->page]);
265 }
266 break;
267
268 case MAX31785_MFR_READ_FAN_PWM: /* R/W 16 */
269 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
270 pmbus_send16(pmdev, s->read_fan_pwm[pmdev->page]);
271 }
272 break;
273
274 case MAX31785_MFR_FAN_FAULT_LIMIT: /* R/W 16 */
275 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
276 pmbus_send16(pmdev, s->fan_fault_limit[pmdev->page]);
277 }
278 break;
279
280 case MAX31785_MFR_FAN_WARN_LIMIT: /* R/W 16 */
281 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
282 pmbus_send16(pmdev, s->fan_warn_limit[pmdev->page]);
283 }
284 break;
285
286 case MAX31785_MFR_FAN_RUN_TIME: /* R/W 16 */
287 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
288 pmbus_send16(pmdev, s->fan_run_time[pmdev->page]);
289 }
290 break;
291
292 case MAX31785_MFR_FAN_PWM_AVG: /* R/W 16 */
293 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
294 pmbus_send16(pmdev, s->fan_pwm_avg[pmdev->page]);
295 }
296 break;
297
298 case MAX31785_MFR_FAN_PWM2RPM: /* R/W 64 */
299 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
300 pmbus_send64(pmdev, s->fan_pwm2rpm[pmdev->page]);
301 }
302 break;
303
304 default:
305 qemu_log_mask(LOG_GUEST_ERROR,
306 "%s: reading from unsupported register: 0x%02x\n",
307 __func__, pmdev->code);
308 break;
309 }
310
311 return 0xFF;
312}
313
314static int max31785_write_data(PMBusDevice *pmdev, const uint8_t *buf,
315 uint8_t len)
316{
317 MAX31785State *s = MAX31785(pmdev);
318 if (len == 0) {
319 qemu_log_mask(LOG_GUEST_ERROR, "%s: writing empty data\n", __func__);
320 return -1;
321 }
322
323 pmdev->code = buf[0]; /* PMBus command code */
324
325 if (len == 1) {
326 return 0;
327 }
328
329 /* Exclude command code from buffer */
330 buf++;
331 len--;
332
333 switch (pmdev->code) {
334
335 case PMBUS_FAN_CONFIG_1_2:
336 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
337 pmdev->pages[pmdev->page].fan_config_1_2 = pmbus_receive8(pmdev);
338 }
339 break;
340
341 case PMBUS_FAN_COMMAND_1:
342 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
343 pmdev->pages[pmdev->page].fan_command_1 = pmbus_receive16(pmdev);
344 pmdev->pages[pmdev->page].read_fan_speed_1 =
345 ((MAX31785_DEFAULT_FAN_SPEED / MAX31785_DEFAULT_FAN_MAX_PWM) *
346 pmdev->pages[pmdev->page].fan_command_1);
347 }
348 break;
349
350 case PMBUS_MFR_LOCATION: /* R/W 64 */
351 s->mfr_location = pmbus_receive64(pmdev);
352 break;
353
354 case PMBUS_MFR_DATE: /* R/W 64 */
355 s->mfr_date = pmbus_receive64(pmdev);
356 break;
357
358 case PMBUS_MFR_SERIAL: /* R/W 64 */
359 s->mfr_serial = pmbus_receive64(pmdev);
360 break;
361
362 case MAX31785_MFR_MODE: /* R/W word */
363 s->mfr_mode[pmdev->page] = pmbus_receive16(pmdev);
364 break;
365
366 case MAX31785_MFR_VOUT_PEAK: /* R/W word */
367 if ((pmdev->page >= MAX31785_MIN_ADC_VOLTAGE_PAGE) &&
368 (pmdev->page <= MAX31785_MAX_ADC_VOLTAGE_PAGE)) {
369 s->vout_peak[pmdev->page] = pmbus_receive16(pmdev);
370 }
371 break;
372
373 case MAX31785_MFR_TEMPERATURE_PEAK: /* R/W word */
374 if ((pmdev->page >= 6) && (pmdev->page <= 16)) {
375 s->temperature_peak[pmdev->page] = pmbus_receive16(pmdev);
376 }
377 break;
378
379 case MAX31785_MFR_VOUT_MIN: /* R/W word */
380 if ((pmdev->page >= MAX31785_MIN_ADC_VOLTAGE_PAGE) &&
381 (pmdev->page <= MAX31785_MAX_ADC_VOLTAGE_PAGE)) {
382 s->vout_min[pmdev->page] = pmbus_receive16(pmdev);
383 }
384 break;
385
386 case MAX31785_MFR_FAULT_RESPONSE: /* R/W 8 */
387 s->fault_response[pmdev->page] = pmbus_receive8(pmdev);
388 break;
389
390 case MAX31785_MFR_TIME_COUNT: /* R/W 32 */
391 s->time_count[pmdev->page] = pmbus_receive32(pmdev);
392 break;
393
394 case MAX31785_MFR_TEMP_SENSOR_CONFIG: /* R/W 16 */
395 if ((pmdev->page >= MAX31785_MIN_TEMP_PAGE) &&
396 (pmdev->page <= MAX31785_MAX_TEMP_PAGE)) {
397 s->temp_sensor_config[pmdev->page] = pmbus_receive16(pmdev);
398 }
399 break;
400
401 case MAX31785_MFR_FAN_CONFIG: /* R/W 16 */
402 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
403 s->fan_config[pmdev->page] = pmbus_receive16(pmdev);
404 }
405 break;
406
407 case MAX31785_MFR_FAN_FAULT_LIMIT: /* R/W 16 */
408 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
409 s->fan_fault_limit[pmdev->page] = pmbus_receive16(pmdev);
410 }
411 break;
412
413 case MAX31785_MFR_FAN_WARN_LIMIT: /* R/W 16 */
414 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
415 s->fan_warn_limit[pmdev->page] = pmbus_receive16(pmdev);
416 }
417 break;
418
419 case MAX31785_MFR_FAN_RUN_TIME: /* R/W 16 */
420 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
421 s->fan_run_time[pmdev->page] = pmbus_receive16(pmdev);
422 }
423 break;
424
425 case MAX31785_MFR_FAN_PWM_AVG: /* R/W 16 */
426 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
427 s->fan_pwm_avg[pmdev->page] = pmbus_receive16(pmdev);
428 }
429 break;
430
431 case MAX31785_MFR_FAN_PWM2RPM: /* R/W 64 */
432 if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
433 s->fan_pwm2rpm[pmdev->page] = pmbus_receive64(pmdev);
434 }
435 break;
436
437 default:
438 qemu_log_mask(LOG_GUEST_ERROR,
439 "%s: writing to unsupported register: 0x%02x\n",
440 __func__, pmdev->code);
441 break;
442 }
443
444 return 0;
445}
446
447static void max31785_exit_reset(Object *obj)
448{
449 PMBusDevice *pmdev = PMBUS_DEVICE(obj);
450 MAX31785State *s = MAX31785(obj);
451
452 pmdev->capability = MAX31785_DEFAULT_CAPABILITY;
453
454 for (int i = MAX31785_MIN_FAN_PAGE; i <= MAX31785_MAX_FAN_PAGE; i++) {
455 pmdev->pages[i].vout_mode = MAX31785_DEFAULT_VOUT_MODE;
456 pmdev->pages[i].fan_command_1 = MAX31785_DEFAULT_FAN_COMMAND_1;
457 pmdev->pages[i].revision = MAX31785_DEFAULT_PMBUS_REVISION;
458 pmdev->pages[i].fan_config_1_2 = MAX31785_DEFAULT_FAN_CONFIG_1_2(0);
459 pmdev->pages[i].read_fan_speed_1 = MAX31785_DEFAULT_FAN_SPEED;
460 pmdev->pages[i].status_fans_1_2 = MAX31785_DEFAULT_FAN_STATUS;
461 }
462
463 for (int i = MAX31785_MIN_TEMP_PAGE; i <= MAX31785_MAX_TEMP_PAGE; i++) {
464 pmdev->pages[i].vout_mode = MAX31785_DEFAULT_VOUT_MODE;
465 pmdev->pages[i].revision = MAX31785_DEFAULT_PMBUS_REVISION;
466 pmdev->pages[i].ot_fault_limit = MAX31785_DEFAULT_OT_FAULT_LIMIT;
467 pmdev->pages[i].ot_warn_limit = MAX31785_DEFAULT_OT_WARN_LIMIT;
468 }
469
470 for (int i = MAX31785_MIN_ADC_VOLTAGE_PAGE;
471 i <= MAX31785_MAX_ADC_VOLTAGE_PAGE;
472 i++) {
473 pmdev->pages[i].vout_mode = MAX31785_DEFAULT_VOUT_MODE;
474 pmdev->pages[i].revision = MAX31785_DEFAULT_PMBUS_REVISION;
475 pmdev->pages[i].vout_scale_monitor =
476 MAX31785_DEFAULT_VOUT_SCALE_MONITOR;
477 pmdev->pages[i].vout_ov_fault_limit = MAX31785_DEFAULT_OV_FAULT_LIMIT;
478 pmdev->pages[i].vout_ov_warn_limit = MAX31785_DEFAULT_OV_WARN_LIMIT;
479 }
480
481 s->mfr_location = MAX31785_DEFAULT_TEXT;
482 s->mfr_date = MAX31785_DEFAULT_TEXT;
483 s->mfr_serial = MAX31785_DEFAULT_TEXT;
484}
485
486static const VMStateDescription vmstate_max31785 = {
487 .name = TYPE_MAX31785,
488 .version_id = 0,
489 .minimum_version_id = 0,
490 .fields = (VMStateField[]){
491 VMSTATE_PMBUS_DEVICE(parent, MAX31785State),
492 VMSTATE_UINT16_ARRAY(mfr_mode, MAX31785State,
493 MAX31785_TOTAL_NUM_PAGES),
494 VMSTATE_UINT16_ARRAY(vout_peak, MAX31785State,
495 MAX31785_TOTAL_NUM_PAGES),
496 VMSTATE_UINT16_ARRAY(temperature_peak, MAX31785State,
497 MAX31785_TOTAL_NUM_PAGES),
498 VMSTATE_UINT16_ARRAY(vout_min, MAX31785State,
499 MAX31785_TOTAL_NUM_PAGES),
500 VMSTATE_UINT8_ARRAY(fault_response, MAX31785State,
501 MAX31785_TOTAL_NUM_PAGES),
502 VMSTATE_UINT32_ARRAY(time_count, MAX31785State,
503 MAX31785_TOTAL_NUM_PAGES),
504 VMSTATE_UINT16_ARRAY(temp_sensor_config, MAX31785State,
505 MAX31785_TOTAL_NUM_PAGES),
506 VMSTATE_UINT16_ARRAY(fan_config, MAX31785State,
507 MAX31785_TOTAL_NUM_PAGES),
508 VMSTATE_UINT16_ARRAY(read_fan_pwm, MAX31785State,
509 MAX31785_TOTAL_NUM_PAGES),
510 VMSTATE_UINT16_ARRAY(fan_fault_limit, MAX31785State,
511 MAX31785_TOTAL_NUM_PAGES),
512 VMSTATE_UINT16_ARRAY(fan_warn_limit, MAX31785State,
513 MAX31785_TOTAL_NUM_PAGES),
514 VMSTATE_UINT16_ARRAY(fan_run_time, MAX31785State,
515 MAX31785_TOTAL_NUM_PAGES),
516 VMSTATE_UINT16_ARRAY(fan_pwm_avg, MAX31785State,
517 MAX31785_TOTAL_NUM_PAGES),
518 VMSTATE_UINT64_ARRAY(fan_pwm2rpm, MAX31785State,
519 MAX31785_TOTAL_NUM_PAGES),
520 VMSTATE_UINT64(mfr_location, MAX31785State),
521 VMSTATE_UINT64(mfr_date, MAX31785State),
522 VMSTATE_UINT64(mfr_serial, MAX31785State),
523 VMSTATE_END_OF_LIST()
524 }
525};
526
527static void max31785_init(Object *obj)
528{
529 PMBusDevice *pmdev = PMBUS_DEVICE(obj);
530
531 for (int i = MAX31785_MIN_FAN_PAGE; i <= MAX31785_MAX_FAN_PAGE; i++) {
532 pmbus_page_config(pmdev, i, PB_HAS_VOUT_MODE);
533 }
534
535 for (int i = MAX31785_MIN_TEMP_PAGE; i <= MAX31785_MAX_TEMP_PAGE; i++) {
536 pmbus_page_config(pmdev, i, PB_HAS_VOUT_MODE | PB_HAS_TEMPERATURE);
537 }
538
539 for (int i = MAX31785_MIN_ADC_VOLTAGE_PAGE;
540 i <= MAX31785_MAX_ADC_VOLTAGE_PAGE;
541 i++) {
542 pmbus_page_config(pmdev, i, PB_HAS_VOUT_MODE | PB_HAS_VOUT |
543 PB_HAS_VOUT_RATING);
544 }
545}
546
547static void max31785_class_init(ObjectClass *klass, void *data)
548{
549 ResettableClass *rc = RESETTABLE_CLASS(klass);
550 DeviceClass *dc = DEVICE_CLASS(klass);
551 PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);
552 dc->desc = "Maxim MAX31785 6-Channel Fan Controller";
553 dc->vmsd = &vmstate_max31785;
554 k->write_data = max31785_write_data;
555 k->receive_byte = max31785_read_byte;
556 k->device_num_pages = MAX31785_TOTAL_NUM_PAGES;
557 rc->phases.exit = max31785_exit_reset;
558}
559
560static const TypeInfo max31785_info = {
561 .name = TYPE_MAX31785,
562 .parent = TYPE_PMBUS_DEVICE,
563 .instance_size = sizeof(MAX31785State),
564 .instance_init = max31785_init,
565 .class_init = max31785_class_init,
566};
567
568static void max31785_register_types(void)
569{
570 type_register_static(&max31785_info);
571}
572
573type_init(max31785_register_types)