xref: /linux/drivers/hwmon/pmbus/mp2869.c (revision 3f276cece4dd9e8bf199d9bf3901eef8ca904c2d)
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, mfr;
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 		mfr = pmbus_read_byte_data(client, page,
192 					   PMBUS_STATUS_MFR_SPECIFIC);
193 		if (mfr < 0)
194 			return mfr;
195 
196 		ret = (ret & ~GENMASK(2, 2)) |
197 			FIELD_PREP(GENMASK(2, 2),
198 				   FIELD_GET(GENMASK(1, 1), mfr));
199 		break;
200 	case PMBUS_STATUS_TEMPERATURE:
201 		/*
202 		 * If the tsns digital fault is enabled, the OT Fault and OT Warning
203 		 * flag of PMBUS_STATUS_TEMPERATURE should come from STATUS_MFR_SPECIFIC
204 		 * register bit1.
205 		 */
206 		if (!data->mfr_thwn_flt_en)
207 			return -ENODATA;
208 
209 		ret = pmbus_read_byte_data(client, page, reg);
210 		if (ret < 0)
211 			return ret;
212 
213 		mfr = pmbus_read_byte_data(client, page,
214 					   PMBUS_STATUS_MFR_SPECIFIC);
215 		if (mfr < 0)
216 			return mfr;
217 
218 		ret = (ret & ~GENMASK(7, 6)) |
219 			FIELD_PREP(GENMASK(6, 6),
220 				   FIELD_GET(GENMASK(1, 1), mfr)) |
221 			 FIELD_PREP(GENMASK(7, 7),
222 				    FIELD_GET(GENMASK(1, 1), mfr));
223 		break;
224 	default:
225 		ret = -ENODATA;
226 		break;
227 	}
228 
229 	return ret;
230 }
231 
232 static int mp2869_read_word_data(struct i2c_client *client, int page, int phase,
233 				 int reg)
234 {
235 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
236 	struct mp2869_data *data = to_mp2869_data(info);
237 	int ret, mfr;
238 
239 	switch (reg) {
240 	case PMBUS_STATUS_WORD:
241 		/*
242 		 * If the tsns digital fault is enabled, the OT Fault flag
243 		 * of PMBUS_STATUS_WORD should come from STATUS_MFR_SPECIFIC
244 		 * register bit1.
245 		 */
246 		if (!data->mfr_thwn_flt_en)
247 			return -ENODATA;
248 
249 		ret = pmbus_read_word_data(client, page, phase, reg);
250 		if (ret < 0)
251 			return ret;
252 
253 		mfr = pmbus_read_byte_data(client, page,
254 					   PMBUS_STATUS_MFR_SPECIFIC);
255 		if (mfr < 0)
256 			return mfr;
257 
258 		ret = (ret & ~GENMASK(2, 2)) |
259 			 FIELD_PREP(GENMASK(2, 2),
260 				    FIELD_GET(GENMASK(1, 1), mfr));
261 		break;
262 	case PMBUS_READ_VIN:
263 		/*
264 		 * The MP2869 PMBUS_READ_VIN[10:0] is the vin value, the vin scale is
265 		 * 31.25mV/LSB. And the vin scale is set to 31.25mV/Lsb(using r/m/b scale)
266 		 * in MP2869 pmbus_driver_info struct, so the word data bit0-bit10 can be
267 		 * returned to pmbus core directly.
268 		 */
269 		ret = pmbus_read_word_data(client, page, phase, reg);
270 		if (ret < 0)
271 			return ret;
272 
273 		ret = FIELD_GET(GENMASK(10, 0), ret);
274 		break;
275 	case PMBUS_READ_IIN:
276 		/*
277 		 * The MP2869 redefine the standard 0x95 register as iin telemetry
278 		 * per rail.
279 		 */
280 		ret = pmbus_read_word_data(client, page, phase, MFR_READ_IIN_EST);
281 		if (ret < 0)
282 			return ret;
283 
284 		break;
285 	case PMBUS_READ_PIN:
286 		/*
287 		 * The MP2869 redefine the standard 0x94 register as pin telemetry
288 		 * per rail. The MP2869 MFR_READ_PIN_EST register is linear11 format,
289 		 * but the pin scale is set to 1W/Lsb(using r/m/b scale). As a result,
290 		 * the pin read from MP2869 should be converted to W, then return
291 		 * the result to pmbus core.
292 		 */
293 		ret = pmbus_read_word_data(client, page, phase, MFR_READ_PIN_EST);
294 		if (ret < 0)
295 			return ret;
296 
297 		ret = mp2869_reg2data_linear11(ret);
298 		break;
299 	case PMBUS_READ_VOUT:
300 		ret = pmbus_read_word_data(client, page, phase, reg);
301 		if (ret < 0)
302 			return ret;
303 
304 		ret = DIV_ROUND_CLOSEST((ret &  GENMASK(11, 0)) * data->vout_scale[page],
305 					MP2869_READ_VOUT_DIV);
306 		break;
307 	case PMBUS_READ_IOUT:
308 		ret = pmbus_read_word_data(client, page, phase, reg);
309 		if (ret < 0)
310 			return ret;
311 
312 		ret = DIV_ROUND_CLOSEST((ret & GENMASK(10, 0)) * data->iout_scale[page],
313 					MP2869_READ_IOUT_DIV);
314 		break;
315 	case PMBUS_READ_POUT:
316 		/*
317 		 * The MP2869 PMBUS_READ_POUT register is linear11 format, but the pout
318 		 * scale is set to 1W/Lsb(using r/m/b scale). As a result, the pout read
319 		 * from MP2869 should be converted to W, then return the result to pmbus
320 		 * core.
321 		 */
322 		ret = pmbus_read_word_data(client, page, phase, reg);
323 		if (ret < 0)
324 			return ret;
325 
326 		ret = mp2869_reg2data_linear11(ret);
327 		break;
328 	case PMBUS_READ_TEMPERATURE_1:
329 		ret = pmbus_read_word_data(client, page, phase, reg);
330 		if (ret < 0)
331 			return ret;
332 
333 		ret = FIELD_GET(GENMASK(10, 0), ret);
334 		break;
335 	case PMBUS_VOUT_OV_FAULT_LIMIT:
336 		ret = pmbus_read_word_data(client, page, phase, reg);
337 		if (ret < 0)
338 			return ret;
339 
340 		if (FIELD_GET(GENMASK(12, 9), ret))
341 			ret = FIELD_GET(GENMASK(8, 0), ret) * MP2869_OVUV_LIMIT_SCALE +
342 				(FIELD_GET(GENMASK(12, 9), ret) + 1) * MP2869_OVUV_DELTA_SCALE;
343 		else
344 			ret = FIELD_GET(GENMASK(8, 0), ret) * MP2869_OVUV_LIMIT_SCALE;
345 		break;
346 	case PMBUS_VOUT_UV_FAULT_LIMIT:
347 		ret = pmbus_read_word_data(client, page, phase, reg);
348 		if (ret < 0)
349 			return ret;
350 
351 		if (FIELD_GET(GENMASK(12, 9), ret))
352 			ret = FIELD_GET(GENMASK(8, 0), ret) * MP2869_OVUV_LIMIT_SCALE -
353 				(FIELD_GET(GENMASK(12, 9), ret) + 1) * MP2869_OVUV_DELTA_SCALE;
354 		else
355 			ret = FIELD_GET(GENMASK(8, 0), ret) * MP2869_OVUV_LIMIT_SCALE;
356 		break;
357 	case PMBUS_OT_FAULT_LIMIT:
358 	case PMBUS_OT_WARN_LIMIT:
359 		/*
360 		 * The scale of MP2869 PMBUS_OT_FAULT_LIMIT and PMBUS_OT_WARN_LIMIT
361 		 * is 1°C/LSB and they have 40°C offset.
362 		 */
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_TEMP_LIMIT_OFFSET;
368 		break;
369 	case PMBUS_VIN_OV_FAULT_LIMIT:
370 		ret = pmbus_read_word_data(client, page, phase, reg);
371 		if (ret < 0)
372 			return ret;
373 
374 		ret = (ret & GENMASK(7, 0)) * MP2869_VIN_OV_FAULT_GAIN;
375 		break;
376 	case PMBUS_VIN_UV_WARN_LIMIT:
377 	case PMBUS_VIN_UV_FAULT_LIMIT:
378 		ret = pmbus_read_word_data(client, page, phase, reg);
379 		if (ret < 0)
380 			return ret;
381 
382 		ret = FIELD_GET(GENMASK(9, 0), ret);
383 		break;
384 	case PMBUS_IOUT_OC_FAULT_LIMIT:
385 	case PMBUS_IOUT_OC_WARN_LIMIT:
386 		ret = pmbus_read_word_data(client, page, phase, reg);
387 		if (ret < 0)
388 			return ret;
389 
390 		ret = DIV_ROUND_CLOSEST((ret & GENMASK(7, 0)) * data->iout_scale[page] *
391 						MP2869_IOUT_LIMIT_UINT, MP2869_READ_IOUT_DIV);
392 		break;
393 	case PMBUS_POUT_OP_WARN_LIMIT:
394 		ret = pmbus_read_word_data(client, page, phase, reg);
395 		if (ret < 0)
396 			return ret;
397 
398 		ret = (ret & GENMASK(7, 0)) * MP2869_POUT_OP_GAIN;
399 		break;
400 	default:
401 		ret = -EINVAL;
402 		break;
403 	}
404 
405 	return ret;
406 }
407 
408 static int mp2869_write_word_data(struct i2c_client *client, int page, int reg,
409 				  u16 word)
410 {
411 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
412 	struct mp2869_data *data = to_mp2869_data(info);
413 	int ret;
414 
415 	switch (reg) {
416 	case PMBUS_VOUT_UV_FAULT_LIMIT:
417 		/*
418 		 * The MP2869 PMBUS_VOUT_UV_FAULT_LIMIT[8:0] is the limit value,
419 		 * and bit9-bit15 should not be changed.
420 		 */
421 		ret = pmbus_read_word_data(client, page, 0xff, reg);
422 		if (ret < 0)
423 			return ret;
424 
425 		if (FIELD_GET(GENMASK(12, 9), ret))
426 			ret = pmbus_write_word_data(client, page, reg,
427 						    (ret & ~GENMASK(8, 0)) |
428 				FIELD_PREP(GENMASK(8, 0),
429 					   DIV_ROUND_CLOSEST(word +
430 						(FIELD_GET(GENMASK(12, 9),
431 						ret) + 1) *
432 					MP2869_OVUV_DELTA_SCALE,
433 					MP2869_OVUV_LIMIT_SCALE)));
434 		else
435 			ret = pmbus_write_word_data(client, page, reg,
436 						    (ret & ~GENMASK(8, 0)) |
437 					FIELD_PREP(GENMASK(8, 0),
438 						   DIV_ROUND_CLOSEST(word,
439 								     MP2869_OVUV_LIMIT_SCALE)));
440 		break;
441 	case PMBUS_VOUT_OV_FAULT_LIMIT:
442 		/*
443 		 * The MP2869 PMBUS_VOUT_OV_FAULT_LIMIT[8:0] is the limit value,
444 		 * and bit9-bit15 should not be changed.
445 		 */
446 		ret = pmbus_read_word_data(client, page, 0xff, reg);
447 		if (ret < 0)
448 			return ret;
449 
450 		if (FIELD_GET(GENMASK(12, 9), ret))
451 			ret = pmbus_write_word_data(client, page, reg,
452 						    (ret & ~GENMASK(8, 0)) |
453 				FIELD_PREP(GENMASK(8, 0),
454 					   DIV_ROUND_CLOSEST(word -
455 							(FIELD_GET(GENMASK(12, 9),
456 							ret) + 1) *
457 						MP2869_OVUV_DELTA_SCALE,
458 						MP2869_OVUV_LIMIT_SCALE)));
459 		else
460 			ret = pmbus_write_word_data(client, page, reg,
461 						    (ret & ~GENMASK(8, 0)) |
462 				FIELD_PREP(GENMASK(8, 0),
463 					   DIV_ROUND_CLOSEST(word,
464 							     MP2869_OVUV_LIMIT_SCALE)));
465 		break;
466 	case PMBUS_OT_FAULT_LIMIT:
467 	case PMBUS_OT_WARN_LIMIT:
468 		/*
469 		 * If the tsns digital fault is enabled, the PMBUS_OT_FAULT_LIMIT and
470 		 * PMBUS_OT_WARN_LIMIT can not be written.
471 		 */
472 		if (data->mfr_thwn_flt_en)
473 			return -EINVAL;
474 
475 		/*
476 		 * The MP2869 scale of MP2869 PMBUS_OT_FAULT_LIMIT and PMBUS_OT_WARN_LIMIT
477 		 * have 40°C offset. The bit0-bit7 is the limit value, and bit8-bit15
478 		 * should not be changed.
479 		 */
480 		ret = pmbus_read_word_data(client, page, 0xff, reg);
481 		if (ret < 0)
482 			return ret;
483 
484 		ret = pmbus_write_word_data(client, page, reg,
485 					    (ret & ~GENMASK(7, 0)) |
486 					 FIELD_PREP(GENMASK(7, 0),
487 						    word + MP2869_TEMP_LIMIT_OFFSET));
488 		break;
489 	case PMBUS_VIN_OV_FAULT_LIMIT:
490 		/*
491 		 * The MP2869 PMBUS_VIN_OV_FAULT_LIMIT[7:0] is the limit value, and bit8-bit15
492 		 * should not be changed. The scale of PMBUS_VIN_OV_FAULT_LIMIT is 125mV/Lsb,
493 		 * but the vin scale is set to 31.25mV/Lsb(using r/m/b scale), so the word data
494 		 * should divide by MP2869_VIN_OV_FAULT_GAIN(4)
495 		 */
496 		ret = pmbus_read_word_data(client, page, 0xff, reg);
497 		if (ret < 0)
498 			return ret;
499 
500 		ret = pmbus_write_word_data(client, page, reg,
501 					    (ret & ~GENMASK(7, 0)) |
502 					FIELD_PREP(GENMASK(7, 0),
503 						   DIV_ROUND_CLOSEST(word,
504 								     MP2869_VIN_OV_FAULT_GAIN)));
505 		break;
506 	case PMBUS_VIN_UV_WARN_LIMIT:
507 	case PMBUS_VIN_UV_FAULT_LIMIT:
508 		/*
509 		 * The PMBUS_VIN_UV_LIMIT[9:0] is the limit value, and bit10-bit15 should
510 		 * not be changed. The scale of PMBUS_VIN_UV_LIMIT is 31.25mV/Lsb, and the
511 		 * vin scale is set to 31.25mV/Lsb(using r/m/b scale), so the word data can
512 		 * be written directly.
513 		 */
514 		ret = pmbus_read_word_data(client, page, 0xff, reg);
515 		if (ret < 0)
516 			return ret;
517 
518 		ret = pmbus_write_word_data(client, page, reg,
519 					    (ret & ~GENMASK(9, 0)) |
520 						FIELD_PREP(GENMASK(9, 0),
521 							   word));
522 		break;
523 	case PMBUS_IOUT_OC_FAULT_LIMIT:
524 	case PMBUS_IOUT_OC_WARN_LIMIT:
525 		ret = pmbus_write_word_data(client, page, reg,
526 					    DIV_ROUND_CLOSEST(word * MP2869_READ_IOUT_DIV,
527 							      MP2869_IOUT_LIMIT_UINT *
528 								  data->iout_scale[page]));
529 		break;
530 	case PMBUS_POUT_OP_WARN_LIMIT:
531 		/*
532 		 * The POUT_OP_WARN_LIMIT[11:0] is the limit value, and bit12-bit15 should
533 		 * not be changed. The scale of POUT_OP_WARN_LIMIT is 2W/Lsb.
534 		 */
535 		ret = pmbus_read_word_data(client, page, 0xff, reg);
536 		if (ret < 0)
537 			return ret;
538 
539 		ret = pmbus_write_word_data(client, page, reg,
540 					    (ret & ~GENMASK(11, 0)) |
541 					FIELD_PREP(GENMASK(11, 0),
542 						   DIV_ROUND_CLOSEST(word,
543 								     MP2869_POUT_OP_GAIN)));
544 		break;
545 	default:
546 		ret = -EINVAL;
547 		break;
548 	}
549 
550 	return ret;
551 }
552 
553 static int mp2869_identify(struct i2c_client *client, struct pmbus_driver_info *info)
554 {
555 	int ret;
556 
557 	/* Identify whether tsns digital fault is enable */
558 	ret = mp2869_identify_thwn_flt(client, info, 1);
559 	if (ret < 0)
560 		return 0;
561 
562 	/* Identify vout scale for rail1. */
563 	ret = mp2869_identify_vout_scale(client, info, 0);
564 	if (ret < 0)
565 		return ret;
566 
567 	/* Identify vout scale for rail2. */
568 	ret = mp2869_identify_vout_scale(client, info, 1);
569 	if (ret < 0)
570 		return ret;
571 
572 	/* Identify iout scale for rail 1. */
573 	ret = mp2869_identify_iout_scale(client, info, 0);
574 	if (ret < 0)
575 		return ret;
576 
577 	/* Identify iout scale for rail 2. */
578 	return mp2869_identify_iout_scale(client, info, 1);
579 }
580 
581 static const struct pmbus_driver_info mp2869_info = {
582 	.pages = MP2869_PAGE_NUM,
583 	.format[PSC_VOLTAGE_IN] = direct,
584 	.format[PSC_CURRENT_IN] = linear,
585 	.format[PSC_CURRENT_OUT] = direct,
586 	.format[PSC_TEMPERATURE] = direct,
587 	.format[PSC_POWER] = direct,
588 	.format[PSC_VOLTAGE_OUT] = direct,
589 
590 	.m[PSC_VOLTAGE_IN] = 32,
591 	.R[PSC_VOLTAGE_IN] = 0,
592 	.b[PSC_VOLTAGE_IN] = 0,
593 
594 	.m[PSC_VOLTAGE_OUT] = 1,
595 	.R[PSC_VOLTAGE_OUT] = 3,
596 	.b[PSC_VOLTAGE_OUT] = 0,
597 
598 	.m[PSC_CURRENT_OUT] = 1,
599 	.R[PSC_CURRENT_OUT] = 0,
600 	.b[PSC_CURRENT_OUT] = 0,
601 
602 	.m[PSC_TEMPERATURE] = 1,
603 	.R[PSC_TEMPERATURE] = 0,
604 	.b[PSC_TEMPERATURE] = 0,
605 
606 	.m[PSC_POWER] = 1,
607 	.R[PSC_POWER] = 0,
608 	.b[PSC_POWER] = 0,
609 
610 	.func[0] = MP2869_RAIL1_FUNC,
611 	.func[1] = MP2869_RAIL2_FUNC,
612 	.read_word_data = mp2869_read_word_data,
613 	.write_word_data = mp2869_write_word_data,
614 	.read_byte_data = mp2869_read_byte_data,
615 	.identify = mp2869_identify,
616 };
617 
618 static int mp2869_probe(struct i2c_client *client)
619 {
620 	struct pmbus_driver_info *info;
621 	struct mp2869_data *data;
622 
623 	data = devm_kzalloc(&client->dev, sizeof(struct mp2869_data),
624 			    GFP_KERNEL);
625 	if (!data)
626 		return -ENOMEM;
627 
628 	memcpy(&data->info, &mp2869_info, sizeof(*info));
629 	info = &data->info;
630 
631 	return pmbus_do_probe(client, info);
632 }
633 
634 static const struct i2c_device_id mp2869_id[] = {
635 	{"mp2869", 0},
636 	{"mp29608", 1},
637 	{"mp29612", 2},
638 	{"mp29816", 3},
639 	{}
640 };
641 MODULE_DEVICE_TABLE(i2c, mp2869_id);
642 
643 static const struct of_device_id __maybe_unused mp2869_of_match[] = {
644 	{.compatible = "mps,mp2869", .data = (void *)0},
645 	{.compatible = "mps,mp29608", .data = (void *)1},
646 	{.compatible = "mps,mp29612", .data = (void *)2},
647 	{.compatible = "mps,mp29816", .data = (void *)3},
648 	{}
649 };
650 MODULE_DEVICE_TABLE(of, mp2869_of_match);
651 
652 static struct i2c_driver mp2869_driver = {
653 	.driver = {
654 		.name = "mp2869",
655 		.of_match_table = mp2869_of_match,
656 	},
657 	.probe = mp2869_probe,
658 	.id_table = mp2869_id,
659 };
660 
661 module_i2c_driver(mp2869_driver);
662 
663 MODULE_AUTHOR("Wensheng Wang <wenswang@yeah.net>");
664 MODULE_DESCRIPTION("PMBus driver for MPS MP2869");
665 MODULE_LICENSE("GPL");
666 MODULE_IMPORT_NS("PMBUS");
667