xref: /linux/drivers/hwmon/pmbus/mp2869.c (revision b615879dbfea6cf1236acbc3f2fb25ae84e07071)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP2869)
4  */
5 
6 #include <linux/bitfield.h>
7 #include <linux/i2c.h>
8 #include <linux/module.h>
9 #include <linux/of_device.h>
10 #include "pmbus.h"
11 
12 /*
13  * Vender specific registers, the register MFR_SVI3_IOUT_PRT(0x67),
14  * READ_PIN_EST(0x94)and READ_IIN_EST(0x95) redefine the standard
15  * PMBUS register. The MFR_VOUT_LOOP_CTRL(0x29) is used to identify
16  * the vout scale and the MFR_SVI3_IOUT_PRT(0x67) is used to identify
17  * the iout scale. The READ_PIN_EST(0x94) is used to read input power
18  * per rail. The MP2891 does not have standard READ_IIN register(0x89),
19  * the iin telemetry can be obtained through the vendor redefined
20  * register READ_IIN_EST(0x95).
21  */
22 #define MFR_SVI3_IOUT_PRT	0x67
23 #define MFR_READ_PIN_EST	0x94
24 #define MFR_READ_IIN_EST	0x95
25 #define MFR_TSNS_FLT_SET	0xBB
26 
27 #define MP2869_VIN_OV_FAULT_GAIN	4
28 #define MP2869_READ_VOUT_DIV	1024
29 #define MP2869_READ_IOUT_DIV	32
30 #define MP2869_OVUV_LIMIT_SCALE	10
31 #define MP2869_OVUV_DELTA_SCALE	50
32 #define MP2869_TEMP_LIMIT_OFFSET	40
33 #define MP2869_IOUT_LIMIT_UINT	8
34 #define MP2869_POUT_OP_GAIN	2
35 
36 #define MP2869_PAGE_NUM	2
37 
38 #define MP2869_RAIL1_FUNC	(PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | \
39 							PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | \
40 							PMBUS_HAVE_TEMP | PMBUS_HAVE_PIN | \
41 							PMBUS_HAVE_IIN | \
42 							PMBUS_HAVE_STATUS_VOUT | \
43 							PMBUS_HAVE_STATUS_IOUT | \
44 							PMBUS_HAVE_STATUS_TEMP | \
45 							PMBUS_HAVE_STATUS_INPUT)
46 
47 #define MP2869_RAIL2_FUNC	(PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | \
48 							 PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | \
49 							 PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | \
50 							 PMBUS_HAVE_STATUS_VOUT | \
51 							 PMBUS_HAVE_STATUS_IOUT | \
52 							 PMBUS_HAVE_STATUS_TEMP | \
53 							 PMBUS_HAVE_STATUS_INPUT)
54 
55 struct mp2869_data {
56 	struct pmbus_driver_info info;
57 	bool mfr_thwn_flt_en;
58 	int vout_scale[MP2869_PAGE_NUM];
59 	int iout_scale[MP2869_PAGE_NUM];
60 };
61 
62 static const int mp2869_vout_sacle[8] = {6400, 5120, 2560, 2048, 1024,
63 										 4, 2, 1};
64 static const int mp2869_iout_sacle[8] = {32, 1, 2, 4, 8, 16, 32, 64};
65 
66 #define to_mp2869_data(x)	container_of(x, struct mp2869_data, info)
67 
68 static u16 mp2869_reg2data_linear11(u16 word)
69 {
70 	s16 exponent;
71 	s32 mantissa;
72 	s64 val;
73 
74 	exponent = ((s16)word) >> 11;
75 	mantissa = ((s16)((word & 0x7ff) << 5)) >> 5;
76 	val = mantissa;
77 
78 	if (exponent >= 0)
79 		val <<= exponent;
80 	else
81 		val >>= -exponent;
82 
83 	return val;
84 }
85 
86 static int
87 mp2869_identify_thwn_flt(struct i2c_client *client, struct pmbus_driver_info *info,
88 			 int page)
89 {
90 	struct mp2869_data *data = to_mp2869_data(info);
91 	int ret;
92 
93 	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
94 	if (ret < 0)
95 		return ret;
96 
97 	ret = i2c_smbus_read_word_data(client, MFR_TSNS_FLT_SET);
98 	if (ret < 0)
99 		return ret;
100 
101 	data->mfr_thwn_flt_en = FIELD_GET(GENMASK(13, 13), ret);
102 
103 	return 0;
104 }
105 
106 static int
107 mp2869_identify_vout_scale(struct i2c_client *client, struct pmbus_driver_info *info,
108 			   int page)
109 {
110 	struct mp2869_data *data = to_mp2869_data(info);
111 	int ret;
112 
113 	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
114 	if (ret < 0)
115 		return ret;
116 
117 	ret = i2c_smbus_read_word_data(client, PMBUS_VOUT_SCALE_LOOP);
118 	if (ret < 0)
119 		return ret;
120 
121 	/*
122 	 * The output voltage is equal to the READ_VOUT(0x8B) register value multiply
123 	 * by vout_scale.
124 	 * Obtain vout scale from the register PMBUS_VOUT_SCALE_LOOP, bits 12-10
125 	 * PMBUS_VOUT_SCALE_LOOP[12:10]:
126 	 * 000b - 6.25mV/LSB, 001b - 5mV/LSB, 010b - 2.5mV/LSB, 011b - 2mV/LSB
127 	 * 100b - 1mV/Lsb, 101b - (1/256)mV/LSB, 110b - (1/512)mV/LSB,
128 	 * 111b - (1/1024)mV/LSB
129 	 */
130 	data->vout_scale[page] = mp2869_vout_sacle[FIELD_GET(GENMASK(12, 10), ret)];
131 
132 	return 0;
133 }
134 
135 static int
136 mp2869_identify_iout_scale(struct i2c_client *client, struct pmbus_driver_info *info,
137 			   int page)
138 {
139 	struct mp2869_data *data = to_mp2869_data(info);
140 	int ret;
141 
142 	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
143 	if (ret < 0)
144 		return ret;
145 
146 	ret = i2c_smbus_read_word_data(client, MFR_SVI3_IOUT_PRT);
147 	if (ret < 0)
148 		return ret;
149 
150 	/*
151 	 * The output current is equal to the READ_IOUT(0x8C) register value
152 	 * multiply by iout_scale.
153 	 * Obtain iout_scale from the register MFR_SVI3_IOUT_PRT[2:0].
154 	 * The value is selected as below:
155 	 * 000b - 1A/LSB, 001b - (1/32)A/LSB, 010b - (1/16)A/LSB,
156 	 * 011b - (1/8)A/LSB, 100b - (1/4)A/LSB, 101b - (1/2)A/LSB
157 	 * 110b - 1A/LSB, 111b - 2A/LSB
158 	 */
159 	data->iout_scale[page] = mp2869_iout_sacle[FIELD_GET(GENMASK(2, 0), ret)];
160 
161 	return 0;
162 }
163 
164 static int mp2869_read_byte_data(struct i2c_client *client, int page, int reg)
165 {
166 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
167 	struct mp2869_data *data = to_mp2869_data(info);
168 	int ret;
169 
170 	switch (reg) {
171 	case PMBUS_VOUT_MODE:
172 		/*
173 		 * The calculation of vout in this driver is based on direct format.
174 		 * As a result, the format of vout is enforced to direct.
175 		 */
176 		ret = PB_VOUT_MODE_DIRECT;
177 		break;
178 	case PMBUS_STATUS_BYTE:
179 		/*
180 		 * If the tsns digital fault is enabled, the TEMPERATURE flag
181 		 * of PMBUS_STATUS_BYTE should come from STATUS_MFR_SPECIFIC
182 		 * register bit1.
183 		 */
184 		if (!data->mfr_thwn_flt_en)
185 			return -ENODATA;
186 
187 		ret = pmbus_read_byte_data(client, page, reg);
188 		if (ret < 0)
189 			return ret;
190 
191 		ret = (ret & ~GENMASK(2, 2)) |
192 			FIELD_PREP(GENMASK(2, 2),
193 				   FIELD_GET(GENMASK(1, 1),
194 					     pmbus_read_byte_data(client, page,
195 								  PMBUS_STATUS_MFR_SPECIFIC)));
196 		break;
197 	case PMBUS_STATUS_TEMPERATURE:
198 		/*
199 		 * If the tsns digital fault is enabled, the OT Fault and OT Warning
200 		 * flag of PMBUS_STATUS_TEMPERATURE should come from STATUS_MFR_SPECIFIC
201 		 * register bit1.
202 		 */
203 		if (!data->mfr_thwn_flt_en)
204 			return -ENODATA;
205 
206 		ret = pmbus_read_byte_data(client, page, reg);
207 		if (ret < 0)
208 			return ret;
209 
210 		ret = (ret & ~GENMASK(7, 6)) |
211 			FIELD_PREP(GENMASK(6, 6),
212 				   FIELD_GET(GENMASK(1, 1),
213 					     pmbus_read_byte_data(client, page,
214 								  PMBUS_STATUS_MFR_SPECIFIC))) |
215 			 FIELD_PREP(GENMASK(7, 7),
216 				    FIELD_GET(GENMASK(1, 1),
217 					      pmbus_read_byte_data(client, page,
218 								   PMBUS_STATUS_MFR_SPECIFIC)));
219 		break;
220 	default:
221 		ret = -ENODATA;
222 		break;
223 	}
224 
225 	return ret;
226 }
227 
228 static int mp2869_read_word_data(struct i2c_client *client, int page, int phase,
229 				 int reg)
230 {
231 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
232 	struct mp2869_data *data = to_mp2869_data(info);
233 	int ret;
234 
235 	switch (reg) {
236 	case PMBUS_STATUS_WORD:
237 		/*
238 		 * If the tsns digital fault is enabled, the OT Fault flag
239 		 * of PMBUS_STATUS_WORD should come from STATUS_MFR_SPECIFIC
240 		 * register bit1.
241 		 */
242 		if (!data->mfr_thwn_flt_en)
243 			return -ENODATA;
244 
245 		ret = pmbus_read_word_data(client, page, phase, reg);
246 		if (ret < 0)
247 			return ret;
248 
249 		ret = (ret & ~GENMASK(2, 2)) |
250 			 FIELD_PREP(GENMASK(2, 2),
251 				    FIELD_GET(GENMASK(1, 1),
252 					      pmbus_read_byte_data(client, page,
253 								   PMBUS_STATUS_MFR_SPECIFIC)));
254 		break;
255 	case PMBUS_READ_VIN:
256 		/*
257 		 * The MP2869 PMBUS_READ_VIN[10:0] is the vin value, the vin scale is
258 		 * 31.25mV/LSB. And the vin scale is set to 31.25mV/Lsb(using r/m/b scale)
259 		 * in MP2869 pmbus_driver_info struct, so the word data bit0-bit10 can be
260 		 * returned to pmbus core directly.
261 		 */
262 		ret = pmbus_read_word_data(client, page, phase, reg);
263 		if (ret < 0)
264 			return ret;
265 
266 		ret = FIELD_GET(GENMASK(10, 0), ret);
267 		break;
268 	case PMBUS_READ_IIN:
269 		/*
270 		 * The MP2869 redefine the standard 0x95 register as iin telemetry
271 		 * per rail.
272 		 */
273 		ret = pmbus_read_word_data(client, page, phase, MFR_READ_IIN_EST);
274 		if (ret < 0)
275 			return ret;
276 
277 		break;
278 	case PMBUS_READ_PIN:
279 		/*
280 		 * The MP2869 redefine the standard 0x94 register as pin telemetry
281 		 * per rail. The MP2869 MFR_READ_PIN_EST register is linear11 format,
282 		 * but the pin scale is set to 1W/Lsb(using r/m/b scale). As a result,
283 		 * the pin read from MP2869 should be converted to W, then return
284 		 * the result to pmbus core.
285 		 */
286 		ret = pmbus_read_word_data(client, page, phase, MFR_READ_PIN_EST);
287 		if (ret < 0)
288 			return ret;
289 
290 		ret = mp2869_reg2data_linear11(ret);
291 		break;
292 	case PMBUS_READ_VOUT:
293 		ret = pmbus_read_word_data(client, page, phase, reg);
294 		if (ret < 0)
295 			return ret;
296 
297 		ret = DIV_ROUND_CLOSEST((ret &  GENMASK(11, 0)) * data->vout_scale[page],
298 					MP2869_READ_VOUT_DIV);
299 		break;
300 	case PMBUS_READ_IOUT:
301 		ret = pmbus_read_word_data(client, page, phase, reg);
302 		if (ret < 0)
303 			return ret;
304 
305 		ret = DIV_ROUND_CLOSEST((ret & GENMASK(10, 0)) * data->iout_scale[page],
306 					MP2869_READ_IOUT_DIV);
307 		break;
308 	case PMBUS_READ_POUT:
309 		/*
310 		 * The MP2869 PMBUS_READ_POUT register is linear11 format, but the pout
311 		 * scale is set to 1W/Lsb(using r/m/b scale). As a result, the pout read
312 		 * from MP2869 should be converted to W, then return the result to pmbus
313 		 * core.
314 		 */
315 		ret = pmbus_read_word_data(client, page, phase, reg);
316 		if (ret < 0)
317 			return ret;
318 
319 		ret = mp2869_reg2data_linear11(ret);
320 		break;
321 	case PMBUS_READ_TEMPERATURE_1:
322 		ret = pmbus_read_word_data(client, page, phase, reg);
323 		if (ret < 0)
324 			return ret;
325 
326 		ret = FIELD_GET(GENMASK(10, 0), ret);
327 		break;
328 	case PMBUS_VOUT_OV_FAULT_LIMIT:
329 		ret = pmbus_read_word_data(client, page, phase, reg);
330 		if (ret < 0)
331 			return ret;
332 
333 		if (FIELD_GET(GENMASK(12, 9), ret))
334 			ret = FIELD_GET(GENMASK(8, 0), ret) * MP2869_OVUV_LIMIT_SCALE +
335 				(FIELD_GET(GENMASK(12, 9), ret) + 1) * MP2869_OVUV_DELTA_SCALE;
336 		else
337 			ret = FIELD_GET(GENMASK(8, 0), ret) * MP2869_OVUV_LIMIT_SCALE;
338 		break;
339 	case PMBUS_VOUT_UV_FAULT_LIMIT:
340 		ret = pmbus_read_word_data(client, page, phase, reg);
341 		if (ret < 0)
342 			return ret;
343 
344 		if (FIELD_GET(GENMASK(12, 9), ret))
345 			ret = FIELD_GET(GENMASK(8, 0), ret) * MP2869_OVUV_LIMIT_SCALE -
346 				(FIELD_GET(GENMASK(12, 9), ret) + 1) * MP2869_OVUV_DELTA_SCALE;
347 		else
348 			ret = FIELD_GET(GENMASK(8, 0), ret) * MP2869_OVUV_LIMIT_SCALE;
349 		break;
350 	case PMBUS_OT_FAULT_LIMIT:
351 	case PMBUS_OT_WARN_LIMIT:
352 		/*
353 		 * The scale of MP2869 PMBUS_OT_FAULT_LIMIT and PMBUS_OT_WARN_LIMIT
354 		 * is 1°C/LSB and they have 40°C offset.
355 		 */
356 		ret = pmbus_read_word_data(client, page, phase, reg);
357 		if (ret < 0)
358 			return ret;
359 
360 		ret = (ret & GENMASK(7, 0)) - MP2869_TEMP_LIMIT_OFFSET;
361 		break;
362 	case PMBUS_VIN_OV_FAULT_LIMIT:
363 		ret = pmbus_read_word_data(client, page, phase, reg);
364 		if (ret < 0)
365 			return ret;
366 
367 		ret = (ret & GENMASK(7, 0)) * MP2869_VIN_OV_FAULT_GAIN;
368 		break;
369 	case PMBUS_VIN_UV_WARN_LIMIT:
370 	case PMBUS_VIN_UV_FAULT_LIMIT:
371 		ret = pmbus_read_word_data(client, page, phase, reg);
372 		if (ret < 0)
373 			return ret;
374 
375 		ret = FIELD_GET(GENMASK(9, 0), ret);
376 		break;
377 	case PMBUS_IOUT_OC_FAULT_LIMIT:
378 	case PMBUS_IOUT_OC_WARN_LIMIT:
379 		ret = pmbus_read_word_data(client, page, phase, reg);
380 		if (ret < 0)
381 			return ret;
382 
383 		ret = DIV_ROUND_CLOSEST((ret & GENMASK(7, 0)) * data->iout_scale[page] *
384 						MP2869_IOUT_LIMIT_UINT, MP2869_READ_IOUT_DIV);
385 		break;
386 	case PMBUS_POUT_OP_WARN_LIMIT:
387 		ret = pmbus_read_word_data(client, page, phase, reg);
388 		if (ret < 0)
389 			return ret;
390 
391 		ret = (ret & GENMASK(7, 0)) * MP2869_POUT_OP_GAIN;
392 		break;
393 	default:
394 		ret = -EINVAL;
395 		break;
396 	}
397 
398 	return ret;
399 }
400 
401 static int mp2869_write_word_data(struct i2c_client *client, int page, int reg,
402 				  u16 word)
403 {
404 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
405 	struct mp2869_data *data = to_mp2869_data(info);
406 	int ret;
407 
408 	switch (reg) {
409 	case PMBUS_VOUT_UV_FAULT_LIMIT:
410 		/*
411 		 * The MP2869 PMBUS_VOUT_UV_FAULT_LIMIT[8:0] is the limit value,
412 		 * and bit9-bit15 should not be changed.
413 		 */
414 		ret = pmbus_read_word_data(client, page, 0xff, reg);
415 		if (ret < 0)
416 			return ret;
417 
418 		if (FIELD_GET(GENMASK(12, 9), ret))
419 			ret = pmbus_write_word_data(client, page, reg,
420 						    (ret & ~GENMASK(8, 0)) |
421 				FIELD_PREP(GENMASK(8, 0),
422 					   DIV_ROUND_CLOSEST(word +
423 						(FIELD_GET(GENMASK(12, 9),
424 						ret) + 1) *
425 					MP2869_OVUV_DELTA_SCALE,
426 					MP2869_OVUV_LIMIT_SCALE)));
427 		else
428 			ret = pmbus_write_word_data(client, page, reg,
429 						    (ret & ~GENMASK(8, 0)) |
430 					FIELD_PREP(GENMASK(8, 0),
431 						   DIV_ROUND_CLOSEST(word,
432 								     MP2869_OVUV_LIMIT_SCALE)));
433 		break;
434 	case PMBUS_VOUT_OV_FAULT_LIMIT:
435 		/*
436 		 * The MP2869 PMBUS_VOUT_OV_FAULT_LIMIT[8:0] is the limit value,
437 		 * and bit9-bit15 should not be changed.
438 		 */
439 		ret = pmbus_read_word_data(client, page, 0xff, reg);
440 		if (ret < 0)
441 			return ret;
442 
443 		if (FIELD_GET(GENMASK(12, 9), ret))
444 			ret = pmbus_write_word_data(client, page, reg,
445 						    (ret & ~GENMASK(8, 0)) |
446 				FIELD_PREP(GENMASK(8, 0),
447 					   DIV_ROUND_CLOSEST(word -
448 							(FIELD_GET(GENMASK(12, 9),
449 							ret) + 1) *
450 						MP2869_OVUV_DELTA_SCALE,
451 						MP2869_OVUV_LIMIT_SCALE)));
452 		else
453 			ret = pmbus_write_word_data(client, page, reg,
454 						    (ret & ~GENMASK(8, 0)) |
455 				FIELD_PREP(GENMASK(8, 0),
456 					   DIV_ROUND_CLOSEST(word,
457 							     MP2869_OVUV_LIMIT_SCALE)));
458 		break;
459 	case PMBUS_OT_FAULT_LIMIT:
460 	case PMBUS_OT_WARN_LIMIT:
461 		/*
462 		 * If the tsns digital fault is enabled, the PMBUS_OT_FAULT_LIMIT and
463 		 * PMBUS_OT_WARN_LIMIT can not be written.
464 		 */
465 		if (data->mfr_thwn_flt_en)
466 			return -EINVAL;
467 
468 		/*
469 		 * The MP2869 scale of MP2869 PMBUS_OT_FAULT_LIMIT and PMBUS_OT_WARN_LIMIT
470 		 * have 40°C offset. The bit0-bit7 is the limit value, and bit8-bit15
471 		 * should not be changed.
472 		 */
473 		ret = pmbus_read_word_data(client, page, 0xff, reg);
474 		if (ret < 0)
475 			return ret;
476 
477 		ret = pmbus_write_word_data(client, page, reg,
478 					    (ret & ~GENMASK(7, 0)) |
479 					 FIELD_PREP(GENMASK(7, 0),
480 						    word + MP2869_TEMP_LIMIT_OFFSET));
481 		break;
482 	case PMBUS_VIN_OV_FAULT_LIMIT:
483 		/*
484 		 * The MP2869 PMBUS_VIN_OV_FAULT_LIMIT[7:0] is the limit value, and bit8-bit15
485 		 * should not be changed. The scale of PMBUS_VIN_OV_FAULT_LIMIT is 125mV/Lsb,
486 		 * but the vin scale is set to 31.25mV/Lsb(using r/m/b scale), so the word data
487 		 * should divide by MP2869_VIN_OV_FAULT_GAIN(4)
488 		 */
489 		ret = pmbus_read_word_data(client, page, 0xff, reg);
490 		if (ret < 0)
491 			return ret;
492 
493 		ret = pmbus_write_word_data(client, page, reg,
494 					    (ret & ~GENMASK(7, 0)) |
495 					FIELD_PREP(GENMASK(7, 0),
496 						   DIV_ROUND_CLOSEST(word,
497 								     MP2869_VIN_OV_FAULT_GAIN)));
498 		break;
499 	case PMBUS_VIN_UV_WARN_LIMIT:
500 	case PMBUS_VIN_UV_FAULT_LIMIT:
501 		/*
502 		 * The PMBUS_VIN_UV_LIMIT[9:0] is the limit value, and bit10-bit15 should
503 		 * not be changed. The scale of PMBUS_VIN_UV_LIMIT is 31.25mV/Lsb, and the
504 		 * vin scale is set to 31.25mV/Lsb(using r/m/b scale), so the word data can
505 		 * be written directly.
506 		 */
507 		ret = pmbus_read_word_data(client, page, 0xff, reg);
508 		if (ret < 0)
509 			return ret;
510 
511 		ret = pmbus_write_word_data(client, page, reg,
512 					    (ret & ~GENMASK(9, 0)) |
513 						FIELD_PREP(GENMASK(9, 0),
514 							   word));
515 		break;
516 	case PMBUS_IOUT_OC_FAULT_LIMIT:
517 	case PMBUS_IOUT_OC_WARN_LIMIT:
518 		ret = pmbus_write_word_data(client, page, reg,
519 					    DIV_ROUND_CLOSEST(word * MP2869_READ_IOUT_DIV,
520 							      MP2869_IOUT_LIMIT_UINT *
521 								  data->iout_scale[page]));
522 		break;
523 	case PMBUS_POUT_OP_WARN_LIMIT:
524 		/*
525 		 * The POUT_OP_WARN_LIMIT[11:0] is the limit value, and bit12-bit15 should
526 		 * not be changed. The scale of POUT_OP_WARN_LIMIT is 2W/Lsb.
527 		 */
528 		ret = pmbus_read_word_data(client, page, 0xff, reg);
529 		if (ret < 0)
530 			return ret;
531 
532 		ret = pmbus_write_word_data(client, page, reg,
533 					    (ret & ~GENMASK(11, 0)) |
534 					FIELD_PREP(GENMASK(11, 0),
535 						   DIV_ROUND_CLOSEST(word,
536 								     MP2869_POUT_OP_GAIN)));
537 		break;
538 	default:
539 		ret = -EINVAL;
540 		break;
541 	}
542 
543 	return ret;
544 }
545 
546 static int mp2869_identify(struct i2c_client *client, struct pmbus_driver_info *info)
547 {
548 	int ret;
549 
550 	/* Identify whether tsns digital fault is enable */
551 	ret = mp2869_identify_thwn_flt(client, info, 1);
552 	if (ret < 0)
553 		return 0;
554 
555 	/* Identify vout scale for rail1. */
556 	ret = mp2869_identify_vout_scale(client, info, 0);
557 	if (ret < 0)
558 		return ret;
559 
560 	/* Identify vout scale for rail2. */
561 	ret = mp2869_identify_vout_scale(client, info, 1);
562 	if (ret < 0)
563 		return ret;
564 
565 	/* Identify iout scale for rail 1. */
566 	ret = mp2869_identify_iout_scale(client, info, 0);
567 	if (ret < 0)
568 		return ret;
569 
570 	/* Identify iout scale for rail 2. */
571 	return mp2869_identify_iout_scale(client, info, 1);
572 }
573 
574 static const struct pmbus_driver_info mp2869_info = {
575 	.pages = MP2869_PAGE_NUM,
576 	.format[PSC_VOLTAGE_IN] = direct,
577 	.format[PSC_CURRENT_IN] = linear,
578 	.format[PSC_CURRENT_OUT] = direct,
579 	.format[PSC_TEMPERATURE] = direct,
580 	.format[PSC_POWER] = direct,
581 	.format[PSC_VOLTAGE_OUT] = direct,
582 
583 	.m[PSC_VOLTAGE_IN] = 32,
584 	.R[PSC_VOLTAGE_IN] = 0,
585 	.b[PSC_VOLTAGE_IN] = 0,
586 
587 	.m[PSC_VOLTAGE_OUT] = 1,
588 	.R[PSC_VOLTAGE_OUT] = 3,
589 	.b[PSC_VOLTAGE_OUT] = 0,
590 
591 	.m[PSC_CURRENT_OUT] = 1,
592 	.R[PSC_CURRENT_OUT] = 0,
593 	.b[PSC_CURRENT_OUT] = 0,
594 
595 	.m[PSC_TEMPERATURE] = 1,
596 	.R[PSC_TEMPERATURE] = 0,
597 	.b[PSC_TEMPERATURE] = 0,
598 
599 	.m[PSC_POWER] = 1,
600 	.R[PSC_POWER] = 0,
601 	.b[PSC_POWER] = 0,
602 
603 	.func[0] = MP2869_RAIL1_FUNC,
604 	.func[1] = MP2869_RAIL2_FUNC,
605 	.read_word_data = mp2869_read_word_data,
606 	.write_word_data = mp2869_write_word_data,
607 	.read_byte_data = mp2869_read_byte_data,
608 	.identify = mp2869_identify,
609 };
610 
611 static int mp2869_probe(struct i2c_client *client)
612 {
613 	struct pmbus_driver_info *info;
614 	struct mp2869_data *data;
615 
616 	data = devm_kzalloc(&client->dev, sizeof(struct mp2869_data),
617 			    GFP_KERNEL);
618 	if (!data)
619 		return -ENOMEM;
620 
621 	memcpy(&data->info, &mp2869_info, sizeof(*info));
622 	info = &data->info;
623 
624 	return pmbus_do_probe(client, info);
625 }
626 
627 static const struct i2c_device_id mp2869_id[] = {
628 	{"mp2869", 0},
629 	{"mp29608", 1},
630 	{"mp29612", 2},
631 	{"mp29816", 3},
632 	{}
633 };
634 MODULE_DEVICE_TABLE(i2c, mp2869_id);
635 
636 static const struct of_device_id __maybe_unused mp2869_of_match[] = {
637 	{.compatible = "mps,mp2869", .data = (void *)0},
638 	{.compatible = "mps,mp29608", .data = (void *)1},
639 	{.compatible = "mps,mp29612", .data = (void *)2},
640 	{.compatible = "mps,mp29816", .data = (void *)3},
641 	{}
642 };
643 MODULE_DEVICE_TABLE(of, mp2869_of_match);
644 
645 static struct i2c_driver mp2869_driver = {
646 	.driver = {
647 		.name = "mp2869",
648 		.of_match_table = mp2869_of_match,
649 	},
650 	.probe = mp2869_probe,
651 	.id_table = mp2869_id,
652 };
653 
654 module_i2c_driver(mp2869_driver);
655 
656 MODULE_AUTHOR("Wensheng Wang <wenswang@yeah.net>");
657 MODULE_DESCRIPTION("PMBus driver for MPS MP2869");
658 MODULE_LICENSE("GPL");
659 MODULE_IMPORT_NS("PMBUS");
660