1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Hardware monitoring driver for MPS2856/2857
4 * Monolithic Power Systems VR Controllers
6 * Copyright (C) 2023 Quanta Computer lnc.
10 #include <linux/i2c.h>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/pmbus.h>
17 /* Vendor specific registers. */
18 #define MP2856_MFR_VR_MULTI_CONFIG_R1 0x0d
19 #define MP2856_MFR_VR_MULTI_CONFIG_R2 0x1d
21 #define MP2856_MUL1_BOOT_SR_R2 0x10
22 #define MP2856_VR_ACTIVE BIT(15)
24 #define MP2856_MFR_VR_CONFIG2 0x5e
25 #define MP2856_VOUT_MODE BIT(11)
27 #define MP2856_MFR_VR_CONFIG1 0x68
28 #define MP2856_DRMOS_KCS GENMASK(13, 12)
30 #define MP2856_MFR_READ_CS1_2_R1 0x82
31 #define MP2856_MFR_READ_CS3_4_R1 0x83
32 #define MP2856_MFR_READ_CS5_6_R1 0x84
33 #define MP2856_MFR_READ_CS7_8_R1 0x85
34 #define MP2856_MFR_READ_CS9_10_R1 0x86
35 #define MP2856_MFR_READ_CS11_12_R1 0x87
37 #define MP2856_MFR_READ_CS1_2_R2 0x85
38 #define MP2856_MFR_READ_CS3_4_R2 0x86
39 #define MP2856_MFR_READ_CS5_6_R2 0x87
41 #define MP2856_MAX_PHASE_RAIL1 8
42 #define MP2856_MAX_PHASE_RAIL2 4
44 #define MP2857_MAX_PHASE_RAIL1 12
45 #define MP2857_MAX_PHASE_RAIL2 4
47 #define MP2856_PAGE_NUM 2
49 enum chips
{ mp2856
, mp2857
};
51 static const int mp2856_max_phases
[][MP2856_PAGE_NUM
] = {
52 [mp2856
] = { MP2856_MAX_PHASE_RAIL1
, MP2856_MAX_PHASE_RAIL2
},
53 [mp2857
] = { MP2857_MAX_PHASE_RAIL1
, MP2857_MAX_PHASE_RAIL2
},
56 static const struct i2c_device_id mp2856_id
[] = {
62 MODULE_DEVICE_TABLE(i2c
, mp2856_id
);
65 struct pmbus_driver_info info
;
66 int vout_format
[MP2856_PAGE_NUM
];
67 int curr_sense_gain
[MP2856_PAGE_NUM
];
68 int max_phases
[MP2856_PAGE_NUM
];
71 #define to_mp2856_data(x) container_of(x, struct mp2856_data, info)
73 #define MAX_LIN_MANTISSA (1023 * 1000)
74 #define MIN_LIN_MANTISSA (511 * 1000)
76 static u16
val2linear11(s64 val
)
78 s16 exponent
= 0, mantissa
;
79 bool negative
= false;
89 /* Reduce large mantissa until it fits into 10 bit */
90 while (val
>= MAX_LIN_MANTISSA
&& exponent
< 15) {
94 /* Increase small mantissa to improve precision */
95 while (val
< MIN_LIN_MANTISSA
&& exponent
> -15) {
100 /* Convert mantissa from milli-units to units */
101 mantissa
= clamp_val(DIV_ROUND_CLOSEST_ULL(val
, 1000), 0, 0x3ff);
105 mantissa
= -mantissa
;
107 /* Convert to 5 bit exponent, 11 bit mantissa */
108 return (mantissa
& 0x7ff) | ((exponent
<< 11) & 0xf800);
112 mp2856_read_word_helper(struct i2c_client
*client
, int page
, int phase
, u8 reg
,
115 int ret
= pmbus_read_word_data(client
, page
, phase
, reg
);
117 return (ret
> 0) ? ret
& mask
: ret
;
121 mp2856_read_vout(struct i2c_client
*client
, struct mp2856_data
*data
, int page
,
126 ret
= mp2856_read_word_helper(client
, page
, phase
, reg
,
131 /* convert vout result to direct format */
132 ret
= (data
->vout_format
[page
] == vid
) ?
133 ((ret
+ 49) * 5) : ((ret
* 1000) >> 8);
139 mp2856_read_phase(struct i2c_client
*client
, struct mp2856_data
*data
,
140 int page
, int phase
, u8 reg
)
145 ret
= pmbus_read_word_data(client
, page
, phase
, reg
);
149 if (!((phase
+ 1) % MP2856_PAGE_NUM
))
154 * Output value is calculated as: (READ_CSx * 12.5mV - 1.23V) / (Kcs * Rcs)
156 val
= (ret
* 125) - 12300;
158 return val2linear11(val
);
162 mp2856_read_phases(struct i2c_client
*client
, struct mp2856_data
*data
,
170 ret
= mp2856_read_phase(client
, data
, page
, phase
,
171 MP2856_MFR_READ_CS1_2_R1
);
174 ret
= mp2856_read_phase(client
, data
, page
, phase
,
175 MP2856_MFR_READ_CS3_4_R1
);
178 ret
= mp2856_read_phase(client
, data
, page
, phase
,
179 MP2856_MFR_READ_CS5_6_R1
);
182 ret
= mp2856_read_phase(client
, data
, page
, phase
,
183 MP2856_MFR_READ_CS7_8_R1
);
191 ret
= mp2856_read_phase(client
, data
, page
, phase
,
192 MP2856_MFR_READ_CS1_2_R2
);
195 ret
= mp2856_read_phase(client
, data
, page
, phase
,
196 MP2856_MFR_READ_CS1_2_R2
);
206 mp2856_read_word_data(struct i2c_client
*client
, int page
,
209 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
210 struct mp2856_data
*data
= to_mp2856_data(info
);
214 case PMBUS_READ_VOUT
:
215 ret
= mp2856_read_vout(client
, data
, page
, phase
, reg
);
217 case PMBUS_READ_IOUT
:
219 ret
= mp2856_read_phases(client
, data
, page
, phase
);
221 ret
= pmbus_read_word_data(client
, page
, phase
, reg
);
231 mp2856_read_byte_data(struct i2c_client
*client
, int page
, int reg
)
234 case PMBUS_VOUT_MODE
:
235 /* Enforce VOUT direct format. */
236 return PB_VOUT_MODE_DIRECT
;
243 mp2856_identify_multiphase(struct i2c_client
*client
, u8 reg
, u8 max_phase
,
248 ret
= i2c_smbus_write_byte_data(client
, PMBUS_PAGE
, 2);
252 ret
= i2c_smbus_read_word_data(client
, reg
);
257 return (ret
>= max_phase
) ? max_phase
: ret
;
261 mp2856_identify_multiphase_rail1(struct i2c_client
*client
,
262 struct mp2856_data
*data
)
266 ret
= mp2856_identify_multiphase(client
, MP2856_MFR_VR_MULTI_CONFIG_R1
,
267 MP2856_MAX_PHASE_RAIL1
, GENMASK(3, 0));
271 data
->info
.phases
[0] = (ret
> data
->max_phases
[0]) ?
272 data
->max_phases
[0] : ret
;
274 for (i
= 0 ; i
< data
->info
.phases
[0]; i
++)
275 data
->info
.pfunc
[i
] |= PMBUS_HAVE_IOUT
;
281 mp2856_identify_multiphase_rail2(struct i2c_client
*client
,
282 struct mp2856_data
*data
)
286 ret
= mp2856_identify_multiphase(client
, MP2856_MFR_VR_MULTI_CONFIG_R2
,
287 MP2856_MAX_PHASE_RAIL2
, GENMASK(2, 0));
291 data
->info
.phases
[1] = (ret
> data
->max_phases
[1]) ?
292 data
->max_phases
[1] : ret
;
294 for (i
= 0 ; i
< data
->info
.phases
[0]; i
++)
295 data
->info
.pfunc
[i
] |= PMBUS_HAVE_IOUT
;
301 mp2856_current_sense_gain_get(struct i2c_client
*client
,
302 struct mp2856_data
*data
)
307 * Obtain DrMOS current sense gain of power stage from the register
308 * MP2856_MFR_VR_CONFIG1, bits 13-12. The value is selected as below:
309 * 00b - 5µA/A, 01b - 8.5µA/A, 10b - 9.7µA/A, 11b - 10µA/A. Other
310 * values are invalid.
312 for (i
= 0 ; i
< data
->info
.pages
; i
++) {
313 ret
= i2c_smbus_write_byte_data(client
, PMBUS_PAGE
, i
);
316 ret
= i2c_smbus_read_word_data(client
,
317 MP2856_MFR_VR_CONFIG1
);
321 switch ((ret
& MP2856_DRMOS_KCS
) >> 12) {
323 data
->curr_sense_gain
[i
] = 50;
326 data
->curr_sense_gain
[i
] = 85;
329 data
->curr_sense_gain
[i
] = 97;
332 data
->curr_sense_gain
[i
] = 100;
340 mp2856_identify_vout_format(struct i2c_client
*client
,
341 struct mp2856_data
*data
)
345 for (i
= 0; i
< data
->info
.pages
; i
++) {
346 ret
= i2c_smbus_write_byte_data(client
, PMBUS_PAGE
, i
);
350 ret
= i2c_smbus_read_word_data(client
, MP2856_MFR_VR_CONFIG2
);
354 data
->vout_format
[i
] = (ret
& MP2856_VOUT_MODE
) ? linear
: vid
;
360 mp2856_is_rail2_active(struct i2c_client
*client
)
364 ret
= i2c_smbus_write_byte_data(client
, PMBUS_PAGE
, 2);
368 ret
= i2c_smbus_read_word_data(client
, MP2856_MUL1_BOOT_SR_R2
);
372 return (ret
& MP2856_VR_ACTIVE
) ? true : false;
375 static struct pmbus_driver_info mp2856_info
= {
376 .pages
= MP2856_PAGE_NUM
,
377 .format
[PSC_VOLTAGE_IN
] = linear
,
378 .format
[PSC_VOLTAGE_OUT
] = direct
,
379 .format
[PSC_TEMPERATURE
] = linear
,
380 .format
[PSC_CURRENT_IN
] = linear
,
381 .format
[PSC_CURRENT_OUT
] = linear
,
382 .format
[PSC_POWER
] = linear
,
383 .m
[PSC_VOLTAGE_OUT
] = 1,
384 .R
[PSC_VOLTAGE_OUT
] = 3,
385 .func
[0] = PMBUS_HAVE_VIN
| PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
|
386 PMBUS_HAVE_IIN
| PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
|
387 PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
| PMBUS_HAVE_POUT
|
388 PMBUS_HAVE_PIN
| PMBUS_HAVE_STATUS_INPUT
,
389 .func
[1] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
| PMBUS_HAVE_IOUT
|
390 PMBUS_HAVE_STATUS_IOUT
| PMBUS_HAVE_POUT
| PMBUS_HAVE_TEMP
,
391 .read_byte_data
= mp2856_read_byte_data
,
392 .read_word_data
= mp2856_read_word_data
,
395 static int mp2856_probe(struct i2c_client
*client
)
397 struct pmbus_driver_info
*info
;
398 struct mp2856_data
*data
;
402 data
= devm_kzalloc(&client
->dev
, sizeof(struct mp2856_data
),
407 chip_id
= (kernel_ulong_t
)i2c_get_match_data(client
);
409 memcpy(data
->max_phases
, mp2856_max_phases
[chip_id
],
410 sizeof(data
->max_phases
));
412 memcpy(&data
->info
, &mp2856_info
, sizeof(*info
));
415 /* Identify multiphase configuration. */
416 ret
= mp2856_identify_multiphase_rail1(client
, data
);
420 if (mp2856_is_rail2_active(client
)) {
421 ret
= mp2856_identify_multiphase_rail2(client
, data
);
425 /* rail2 is not active */
429 /* Obtain current sense gain of power stage. */
430 ret
= mp2856_current_sense_gain_get(client
, data
);
434 /* Identify vout format. */
435 ret
= mp2856_identify_vout_format(client
, data
);
439 /* set the device to page 0 */
440 i2c_smbus_write_byte_data(client
, PMBUS_PAGE
, 0);
442 return pmbus_do_probe(client
, info
);
445 static const struct of_device_id __maybe_unused mp2856_of_match
[] = {
446 {.compatible
= "mps,mp2856", .data
= (void *)mp2856
},
447 {.compatible
= "mps,mp2857", .data
= (void *)mp2857
},
450 MODULE_DEVICE_TABLE(of
, mp2856_of_match
);
452 static struct i2c_driver mp2856_driver
= {
455 .of_match_table
= mp2856_of_match
,
457 .probe
= mp2856_probe
,
458 .id_table
= mp2856_id
,
461 module_i2c_driver(mp2856_driver
);
463 MODULE_AUTHOR("Peter Yin <peter.yin@quantatw.com>");
464 MODULE_DESCRIPTION("PMBus driver for MPS MP2856/MP2857 device");
465 MODULE_LICENSE("GPL");
466 MODULE_IMPORT_NS("PMBUS");