qemu

Форк
0
/
max31785.c 
573 строки · 21.7 Кб
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 */
147
typedef 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

169
static 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

314
static 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

447
static void max31785_exit_reset(Object *obj, ResetType type)
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

486
static const VMStateDescription vmstate_max31785 = {
487
    .name = TYPE_MAX31785,
488
    .version_id = 0,
489
    .minimum_version_id = 0,
490
    .fields = (const 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

527
static 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

547
static 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

560
static 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

568
static void max31785_register_types(void)
569
{
570
    type_register_static(&max31785_info);
571
}
572

573
type_init(max31785_register_types)
574

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.