xref: /linux/drivers/hwmon/pmbus/mp2985.c (revision 9611c0ce215a66770ccbe5c126bf57ba8c31bcad)
1*e656735fSWensheng Wang // SPDX-License-Identifier: GPL-2.0-or-later
2*e656735fSWensheng Wang /*
3*e656735fSWensheng Wang  * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP2985)
4*e656735fSWensheng Wang  *
5*e656735fSWensheng Wang  * Copyright (C) 2026 MPS
6*e656735fSWensheng Wang  */
7*e656735fSWensheng Wang 
8*e656735fSWensheng Wang #include <linux/bitfield.h>
9*e656735fSWensheng Wang #include <linux/i2c.h>
10*e656735fSWensheng Wang #include <linux/module.h>
11*e656735fSWensheng Wang #include <linux/of_device.h>
12*e656735fSWensheng Wang #include "pmbus.h"
13*e656735fSWensheng Wang 
14*e656735fSWensheng Wang /*
15*e656735fSWensheng Wang  * Vender specific register READ_PIN_EST(0x93), READ_IIN_EST(0x8E),
16*e656735fSWensheng Wang  * MFR_VR_MULTI_CONFIG_R1(0x0D) and MFR_VR_MULTI_CONFIG_R2(0x1D).
17*e656735fSWensheng Wang  * The READ_PIN_EST is used to read pin telemetry, the READ_IIN_EST
18*e656735fSWensheng Wang  * is used to read iin telemetry and the MFR_VR_MULTI_CONFIG_R1,
19*e656735fSWensheng Wang  * MFR_VR_MULTI_CONFIG_R2 are used to obtain vid scale.
20*e656735fSWensheng Wang  */
21*e656735fSWensheng Wang #define READ_PIN_EST	0x93
22*e656735fSWensheng Wang #define READ_IIN_EST	0x8E
23*e656735fSWensheng Wang #define MFR_VR_MULTI_CONFIG_R1	0x0D
24*e656735fSWensheng Wang #define MFR_VR_MULTI_CONFIG_R2	0x1D
25*e656735fSWensheng Wang 
26*e656735fSWensheng Wang #define MP2985_VOUT_DIV	64
27*e656735fSWensheng Wang #define MP2985_VOUT_OVUV_UINT	125
28*e656735fSWensheng Wang #define MP2985_VOUT_OVUV_DIV	64
29*e656735fSWensheng Wang 
30*e656735fSWensheng Wang #define MP2985_PAGE_NUM	2
31*e656735fSWensheng Wang 
32*e656735fSWensheng Wang #define MP2985_RAIL1_FUNC	(PMBUS_HAVE_VIN | PMBUS_HAVE_PIN | \
33*e656735fSWensheng Wang 							 PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | \
34*e656735fSWensheng Wang 							 PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | \
35*e656735fSWensheng Wang 							 PMBUS_HAVE_STATUS_VOUT | \
36*e656735fSWensheng Wang 							 PMBUS_HAVE_STATUS_IOUT | \
37*e656735fSWensheng Wang 							 PMBUS_HAVE_STATUS_TEMP | \
38*e656735fSWensheng Wang 							 PMBUS_HAVE_STATUS_INPUT)
39*e656735fSWensheng Wang 
40*e656735fSWensheng Wang #define MP2985_RAIL2_FUNC	(PMBUS_HAVE_PIN | PMBUS_HAVE_VOUT | \
41*e656735fSWensheng Wang 							 PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | \
42*e656735fSWensheng Wang 							 PMBUS_HAVE_TEMP | PMBUS_HAVE_IIN | \
43*e656735fSWensheng Wang 							 PMBUS_HAVE_STATUS_VOUT | \
44*e656735fSWensheng Wang 							 PMBUS_HAVE_STATUS_IOUT | \
45*e656735fSWensheng Wang 							 PMBUS_HAVE_STATUS_TEMP | \
46*e656735fSWensheng Wang 							 PMBUS_HAVE_STATUS_INPUT)
47*e656735fSWensheng Wang 
48*e656735fSWensheng Wang struct mp2985_data {
49*e656735fSWensheng Wang 	struct pmbus_driver_info info;
50*e656735fSWensheng Wang 	int vout_scale[MP2985_PAGE_NUM];
51*e656735fSWensheng Wang 	int vid_offset[MP2985_PAGE_NUM];
52*e656735fSWensheng Wang };
53*e656735fSWensheng Wang 
54*e656735fSWensheng Wang #define to_mp2985_data(x) container_of(x, struct mp2985_data, info)
55*e656735fSWensheng Wang 
56*e656735fSWensheng Wang static u16 mp2985_linear_exp_transfer(u16 word, u16 expect_exponent)
57*e656735fSWensheng Wang {
58*e656735fSWensheng Wang 	s16 exponent, mantissa, target_exponent;
59*e656735fSWensheng Wang 
60*e656735fSWensheng Wang 	exponent = ((s16)word) >> 11;
61*e656735fSWensheng Wang 	mantissa = ((s16)((word & 0x7ff) << 5)) >> 5;
62*e656735fSWensheng Wang 	target_exponent = (s16)((expect_exponent & 0x1f) << 11) >> 11;
63*e656735fSWensheng Wang 
64*e656735fSWensheng Wang 	/*
65*e656735fSWensheng Wang 	 * The MP2985 does not support negtive limit value, if a negtive
66*e656735fSWensheng Wang 	 * limit value is written, the limit value will become to 0. And
67*e656735fSWensheng Wang 	 * the maximum positive limit value is limitted to 0x3FF.
68*e656735fSWensheng Wang 	 */
69*e656735fSWensheng Wang 	if (mantissa < 0) {
70*e656735fSWensheng Wang 		mantissa = 0;
71*e656735fSWensheng Wang 	} else {
72*e656735fSWensheng Wang 		if (exponent > target_exponent) {
73*e656735fSWensheng Wang 			mantissa = (1023 >> (exponent - target_exponent)) >= mantissa ?
74*e656735fSWensheng Wang 						mantissa << (exponent - target_exponent) :
75*e656735fSWensheng Wang 						0x3FF;
76*e656735fSWensheng Wang 		} else {
77*e656735fSWensheng Wang 			mantissa = clamp_val(mantissa >> (target_exponent - exponent),
78*e656735fSWensheng Wang 					     0, 0x3FF);
79*e656735fSWensheng Wang 		}
80*e656735fSWensheng Wang 	}
81*e656735fSWensheng Wang 
82*e656735fSWensheng Wang 	return mantissa | ((expect_exponent << 11) & 0xf800);
83*e656735fSWensheng Wang }
84*e656735fSWensheng Wang 
85*e656735fSWensheng Wang static int mp2985_read_byte_data(struct i2c_client *client, int page, int reg)
86*e656735fSWensheng Wang {
87*e656735fSWensheng Wang 	int ret;
88*e656735fSWensheng Wang 
89*e656735fSWensheng Wang 	switch (reg) {
90*e656735fSWensheng Wang 	case PMBUS_VOUT_MODE:
91*e656735fSWensheng Wang 		/*
92*e656735fSWensheng Wang 		 * The MP2985 does not follow standard PMBus protocol completely,
93*e656735fSWensheng Wang 		 * and the calculation of vout in this driver is based on direct
94*e656735fSWensheng Wang 		 * format. As a result, the format of vout is enforced to direct.
95*e656735fSWensheng Wang 		 */
96*e656735fSWensheng Wang 		ret = PB_VOUT_MODE_DIRECT;
97*e656735fSWensheng Wang 		break;
98*e656735fSWensheng Wang 	default:
99*e656735fSWensheng Wang 		ret = -ENODATA;
100*e656735fSWensheng Wang 		break;
101*e656735fSWensheng Wang 	}
102*e656735fSWensheng Wang 
103*e656735fSWensheng Wang 	return ret;
104*e656735fSWensheng Wang }
105*e656735fSWensheng Wang 
106*e656735fSWensheng Wang static int mp2985_read_word_data(struct i2c_client *client, int page, int phase,
107*e656735fSWensheng Wang 				 int reg)
108*e656735fSWensheng Wang {
109*e656735fSWensheng Wang 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
110*e656735fSWensheng Wang 	struct mp2985_data *data = to_mp2985_data(info);
111*e656735fSWensheng Wang 	int ret;
112*e656735fSWensheng Wang 
113*e656735fSWensheng Wang 	switch (reg) {
114*e656735fSWensheng Wang 	case PMBUS_READ_VOUT:
115*e656735fSWensheng Wang 		ret = pmbus_read_word_data(client, page, phase, reg);
116*e656735fSWensheng Wang 		if (ret < 0)
117*e656735fSWensheng Wang 			return ret;
118*e656735fSWensheng Wang 
119*e656735fSWensheng Wang 		/*
120*e656735fSWensheng Wang 		 * The MP2985 supports three vout mode, direct, linear11 and vid mode.
121*e656735fSWensheng Wang 		 * In vid mode, the MP2985 vout telemetry has 49 vid step offset, but
122*e656735fSWensheng Wang 		 * PMBUS_VOUT_OV_FAULT_LIMIT and PMBUS_VOUT_UV_FAULT_LIMIT do not take
123*e656735fSWensheng Wang 		 * this into consideration, their resolution are 1.953125mV/LSB, as a
124*e656735fSWensheng Wang 		 * result, format[PSC_VOLTAGE_OUT] can not be set to vid mode directly.
125*e656735fSWensheng Wang 		 * Adding extra vid_offset variable for vout telemetry.
126*e656735fSWensheng Wang 		 */
127*e656735fSWensheng Wang 		ret = clamp_val(DIV_ROUND_CLOSEST(((ret & GENMASK(11, 0)) +
128*e656735fSWensheng Wang 									data->vid_offset[page]) *
129*e656735fSWensheng Wang 							data->vout_scale[page], MP2985_VOUT_DIV),
130*e656735fSWensheng Wang 							0, 0x7FFF);
131*e656735fSWensheng Wang 		break;
132*e656735fSWensheng Wang 	case PMBUS_READ_IIN:
133*e656735fSWensheng Wang 		/*
134*e656735fSWensheng Wang 		 * The MP2985 has standard PMBUS_READ_IIN register(0x89), but this is
135*e656735fSWensheng Wang 		 * not used to read the input current of per rail. The input current
136*e656735fSWensheng Wang 		 * is read through the vender redefined register READ_IIN_EST(0x8E).
137*e656735fSWensheng Wang 		 */
138*e656735fSWensheng Wang 		ret = pmbus_read_word_data(client, page, phase, READ_IIN_EST);
139*e656735fSWensheng Wang 		break;
140*e656735fSWensheng Wang 	case PMBUS_READ_PIN:
141*e656735fSWensheng Wang 		/*
142*e656735fSWensheng Wang 		 * The MP2985 has standard PMBUS_READ_PIN register(0x97), but this
143*e656735fSWensheng Wang 		 * is not used to read the input power of per rail. The input power
144*e656735fSWensheng Wang 		 * of per rail is read through the vender redefined register
145*e656735fSWensheng Wang 		 * READ_PIN_EST(0x93).
146*e656735fSWensheng Wang 		 */
147*e656735fSWensheng Wang 		ret = pmbus_read_word_data(client, page, phase, READ_PIN_EST);
148*e656735fSWensheng Wang 		break;
149*e656735fSWensheng Wang 	case PMBUS_VOUT_OV_FAULT_LIMIT:
150*e656735fSWensheng Wang 	case PMBUS_VOUT_UV_FAULT_LIMIT:
151*e656735fSWensheng Wang 		ret = pmbus_read_word_data(client, page, phase, reg);
152*e656735fSWensheng Wang 		if (ret < 0)
153*e656735fSWensheng Wang 			return ret;
154*e656735fSWensheng Wang 
155*e656735fSWensheng Wang 		ret = DIV_ROUND_CLOSEST((ret & GENMASK(11, 0)) * MP2985_VOUT_OVUV_UINT,
156*e656735fSWensheng Wang 					MP2985_VOUT_OVUV_DIV);
157*e656735fSWensheng Wang 		break;
158*e656735fSWensheng Wang 	case PMBUS_STATUS_WORD:
159*e656735fSWensheng Wang 	case PMBUS_READ_VIN:
160*e656735fSWensheng Wang 	case PMBUS_READ_IOUT:
161*e656735fSWensheng Wang 	case PMBUS_READ_POUT:
162*e656735fSWensheng Wang 	case PMBUS_READ_TEMPERATURE_1:
163*e656735fSWensheng Wang 	case PMBUS_VIN_OV_FAULT_LIMIT:
164*e656735fSWensheng Wang 	case PMBUS_VIN_OV_WARN_LIMIT:
165*e656735fSWensheng Wang 	case PMBUS_VIN_UV_WARN_LIMIT:
166*e656735fSWensheng Wang 	case PMBUS_VIN_UV_FAULT_LIMIT:
167*e656735fSWensheng Wang 	case PMBUS_IOUT_OC_FAULT_LIMIT:
168*e656735fSWensheng Wang 	case PMBUS_IOUT_OC_WARN_LIMIT:
169*e656735fSWensheng Wang 	case PMBUS_OT_FAULT_LIMIT:
170*e656735fSWensheng Wang 	case PMBUS_OT_WARN_LIMIT:
171*e656735fSWensheng Wang 		/*
172*e656735fSWensheng Wang 		 * These register is not explicitly handled by the driver,
173*e656735fSWensheng Wang 		 * as a result, return -ENODATA directly.
174*e656735fSWensheng Wang 		 */
175*e656735fSWensheng Wang 		ret = -ENODATA;
176*e656735fSWensheng Wang 		break;
177*e656735fSWensheng Wang 	default:
178*e656735fSWensheng Wang 		/*
179*e656735fSWensheng Wang 		 * The MP2985 do not support other telemetry and limit value
180*e656735fSWensheng Wang 		 * reading, so, return -EINVAL directly.
181*e656735fSWensheng Wang 		 */
182*e656735fSWensheng Wang 		ret = -EINVAL;
183*e656735fSWensheng Wang 		break;
184*e656735fSWensheng Wang 	}
185*e656735fSWensheng Wang 
186*e656735fSWensheng Wang 	return ret;
187*e656735fSWensheng Wang }
188*e656735fSWensheng Wang 
189*e656735fSWensheng Wang static int mp2985_write_word_data(struct i2c_client *client, int page, int reg,
190*e656735fSWensheng Wang 				  u16 word)
191*e656735fSWensheng Wang {
192*e656735fSWensheng Wang 	int ret;
193*e656735fSWensheng Wang 
194*e656735fSWensheng Wang 	switch (reg) {
195*e656735fSWensheng Wang 	case PMBUS_VIN_OV_FAULT_LIMIT:
196*e656735fSWensheng Wang 	case PMBUS_VIN_OV_WARN_LIMIT:
197*e656735fSWensheng Wang 	case PMBUS_VIN_UV_WARN_LIMIT:
198*e656735fSWensheng Wang 	case PMBUS_VIN_UV_FAULT_LIMIT:
199*e656735fSWensheng Wang 		/*
200*e656735fSWensheng Wang 		 * The PMBUS_VIN_OV_FAULT_LIMIT, PMBUS_VIN_OV_WARN_LIMIT,
201*e656735fSWensheng Wang 		 * PMBUS_VIN_UV_WARN_LIMIT and PMBUS_VIN_UV_FAULT_LIMIT
202*e656735fSWensheng Wang 		 * of MP2985 is linear11 format, and the exponent is a
203*e656735fSWensheng Wang 		 * constant value(5'b11101), so the exponent of word
204*e656735fSWensheng Wang 		 * parameter should be converted to 5'b11101(0x1D).
205*e656735fSWensheng Wang 		 */
206*e656735fSWensheng Wang 		ret = pmbus_write_word_data(client, page, reg,
207*e656735fSWensheng Wang 					    mp2985_linear_exp_transfer(word, 0x1D));
208*e656735fSWensheng Wang 		break;
209*e656735fSWensheng Wang 	case PMBUS_VOUT_OV_FAULT_LIMIT:
210*e656735fSWensheng Wang 	case PMBUS_VOUT_UV_FAULT_LIMIT:
211*e656735fSWensheng Wang 		/*
212*e656735fSWensheng Wang 		 * The bit0-bit11 is the limit value, and bit12-bit15
213*e656735fSWensheng Wang 		 * should not be changed.
214*e656735fSWensheng Wang 		 */
215*e656735fSWensheng Wang 		ret = pmbus_read_word_data(client, page, 0xff, reg);
216*e656735fSWensheng Wang 		if (ret < 0)
217*e656735fSWensheng Wang 			return ret;
218*e656735fSWensheng Wang 
219*e656735fSWensheng Wang 		ret = pmbus_write_word_data(client, page, reg,
220*e656735fSWensheng Wang 					    (ret & ~GENMASK(11, 0)) |
221*e656735fSWensheng Wang 				clamp_val(DIV_ROUND_CLOSEST(word * MP2985_VOUT_OVUV_DIV,
222*e656735fSWensheng Wang 							    MP2985_VOUT_OVUV_UINT), 0, 0xFFF));
223*e656735fSWensheng Wang 		break;
224*e656735fSWensheng Wang 	case PMBUS_OT_FAULT_LIMIT:
225*e656735fSWensheng Wang 	case PMBUS_OT_WARN_LIMIT:
226*e656735fSWensheng Wang 		/*
227*e656735fSWensheng Wang 		 * The PMBUS_OT_FAULT_LIMIT and PMBUS_OT_WARN_LIMIT of
228*e656735fSWensheng Wang 		 * MP2985 is linear11 format, and the exponent is a
229*e656735fSWensheng Wang 		 * constant value(5'b00000), so the exponent of word
230*e656735fSWensheng Wang 		 * parameter should be converted to 5'b00000.
231*e656735fSWensheng Wang 		 */
232*e656735fSWensheng Wang 		ret = pmbus_write_word_data(client, page, reg,
233*e656735fSWensheng Wang 					    mp2985_linear_exp_transfer(word, 0x00));
234*e656735fSWensheng Wang 		break;
235*e656735fSWensheng Wang 	case PMBUS_IOUT_OC_FAULT_LIMIT:
236*e656735fSWensheng Wang 	case PMBUS_IOUT_OC_WARN_LIMIT:
237*e656735fSWensheng Wang 		/*
238*e656735fSWensheng Wang 		 * The PMBUS_IOUT_OC_FAULT_LIMIT and PMBUS_IOUT_OC_WARN_LIMIT
239*e656735fSWensheng Wang 		 * of MP2985 is linear11 format, and the exponent can not be
240*e656735fSWensheng Wang 		 * changed.
241*e656735fSWensheng Wang 		 */
242*e656735fSWensheng Wang 		ret = pmbus_read_word_data(client, page, 0xff, reg);
243*e656735fSWensheng Wang 		if (ret < 0)
244*e656735fSWensheng Wang 			return ret;
245*e656735fSWensheng Wang 
246*e656735fSWensheng Wang 		ret = pmbus_write_word_data(client, page, reg,
247*e656735fSWensheng Wang 					    mp2985_linear_exp_transfer(word,
248*e656735fSWensheng Wang 								       FIELD_GET(GENMASK(15, 11),
249*e656735fSWensheng Wang 										 ret)));
250*e656735fSWensheng Wang 		break;
251*e656735fSWensheng Wang 	default:
252*e656735fSWensheng Wang 		/*
253*e656735fSWensheng Wang 		 * The MP2985 do not support other limit value configuration,
254*e656735fSWensheng Wang 		 * so, return -EINVAL directly.
255*e656735fSWensheng Wang 		 */
256*e656735fSWensheng Wang 		ret = -EINVAL;
257*e656735fSWensheng Wang 		break;
258*e656735fSWensheng Wang 	}
259*e656735fSWensheng Wang 
260*e656735fSWensheng Wang 	return ret;
261*e656735fSWensheng Wang }
262*e656735fSWensheng Wang 
263*e656735fSWensheng Wang static int
264*e656735fSWensheng Wang mp2985_identify_vout_scale(struct i2c_client *client, struct pmbus_driver_info *info,
265*e656735fSWensheng Wang 			   int page)
266*e656735fSWensheng Wang {
267*e656735fSWensheng Wang 	struct mp2985_data *data = to_mp2985_data(info);
268*e656735fSWensheng Wang 	int ret;
269*e656735fSWensheng Wang 
270*e656735fSWensheng Wang 	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
271*e656735fSWensheng Wang 	if (ret < 0)
272*e656735fSWensheng Wang 		return ret;
273*e656735fSWensheng Wang 
274*e656735fSWensheng Wang 	ret = i2c_smbus_read_byte_data(client, PMBUS_VOUT_MODE);
275*e656735fSWensheng Wang 	if (ret < 0)
276*e656735fSWensheng Wang 		return ret;
277*e656735fSWensheng Wang 
278*e656735fSWensheng Wang 	/*
279*e656735fSWensheng Wang 	 * The MP2985 supports three vout mode. If PMBUS_VOUT_MODE
280*e656735fSWensheng Wang 	 * bit5 is 1, it is vid mode. If PMBUS PMBUS_VOUT_MODE bit4
281*e656735fSWensheng Wang 	 * is 1, it is linear11 mode, the vout scale is 1.953125mv/LSB.
282*e656735fSWensheng Wang 	 * If PMBUS PMBUS_VOUT_MODE bit6 is 1, it is direct mode, the
283*e656735fSWensheng Wang 	 * vout scale is 1mv/LSB. In vid mode, the MP2985 vout telemetry
284*e656735fSWensheng Wang 	 * has 49 vid step offset.
285*e656735fSWensheng Wang 	 */
286*e656735fSWensheng Wang 	if (FIELD_GET(BIT(5), ret)) {
287*e656735fSWensheng Wang 		ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 2);
288*e656735fSWensheng Wang 		if (ret < 0)
289*e656735fSWensheng Wang 			return ret;
290*e656735fSWensheng Wang 
291*e656735fSWensheng Wang 		ret = i2c_smbus_read_word_data(client, page == 0 ?
292*e656735fSWensheng Wang 						MFR_VR_MULTI_CONFIG_R1 :
293*e656735fSWensheng Wang 						MFR_VR_MULTI_CONFIG_R2);
294*e656735fSWensheng Wang 		if (ret < 0)
295*e656735fSWensheng Wang 			return ret;
296*e656735fSWensheng Wang 
297*e656735fSWensheng Wang 		if (page == 0) {
298*e656735fSWensheng Wang 			if (FIELD_GET(BIT(4), ret))
299*e656735fSWensheng Wang 				data->vout_scale[page] = 320;
300*e656735fSWensheng Wang 			else
301*e656735fSWensheng Wang 				data->vout_scale[page] = 640;
302*e656735fSWensheng Wang 		} else {
303*e656735fSWensheng Wang 			if (FIELD_GET(BIT(3), ret))
304*e656735fSWensheng Wang 				data->vout_scale[page] = 320;
305*e656735fSWensheng Wang 			else
306*e656735fSWensheng Wang 				data->vout_scale[page] = 640;
307*e656735fSWensheng Wang 		}
308*e656735fSWensheng Wang 
309*e656735fSWensheng Wang 		data->vid_offset[page] = 49;
310*e656735fSWensheng Wang 
311*e656735fSWensheng Wang 		/*
312*e656735fSWensheng Wang 		 * For vid mode, the MP2985 should be changed to page 2
313*e656735fSWensheng Wang 		 * to obtain vout scale value, this may confuse the PMBus
314*e656735fSWensheng Wang 		 * core. To avoid this, switch back to the previous page
315*e656735fSWensheng Wang 		 * again.
316*e656735fSWensheng Wang 		 */
317*e656735fSWensheng Wang 		ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
318*e656735fSWensheng Wang 		if (ret < 0)
319*e656735fSWensheng Wang 			return ret;
320*e656735fSWensheng Wang 	} else if (FIELD_GET(BIT(4), ret)) {
321*e656735fSWensheng Wang 		data->vout_scale[page] = 125;
322*e656735fSWensheng Wang 		data->vid_offset[page] = 0;
323*e656735fSWensheng Wang 	} else {
324*e656735fSWensheng Wang 		data->vout_scale[page] = 64;
325*e656735fSWensheng Wang 		data->vid_offset[page] = 0;
326*e656735fSWensheng Wang 	}
327*e656735fSWensheng Wang 
328*e656735fSWensheng Wang 	return 0;
329*e656735fSWensheng Wang }
330*e656735fSWensheng Wang 
331*e656735fSWensheng Wang static int mp2985_identify(struct i2c_client *client, struct pmbus_driver_info *info)
332*e656735fSWensheng Wang {
333*e656735fSWensheng Wang 	int ret;
334*e656735fSWensheng Wang 
335*e656735fSWensheng Wang 	ret = mp2985_identify_vout_scale(client, info, 0);
336*e656735fSWensheng Wang 	if (ret < 0)
337*e656735fSWensheng Wang 		return ret;
338*e656735fSWensheng Wang 
339*e656735fSWensheng Wang 	return mp2985_identify_vout_scale(client, info, 1);
340*e656735fSWensheng Wang }
341*e656735fSWensheng Wang 
342*e656735fSWensheng Wang static struct pmbus_driver_info mp2985_info = {
343*e656735fSWensheng Wang 	.pages = MP2985_PAGE_NUM,
344*e656735fSWensheng Wang 	.format[PSC_VOLTAGE_IN] = linear,
345*e656735fSWensheng Wang 	.format[PSC_CURRENT_IN] = linear,
346*e656735fSWensheng Wang 	.format[PSC_CURRENT_OUT] = linear,
347*e656735fSWensheng Wang 	.format[PSC_POWER] = linear,
348*e656735fSWensheng Wang 	.format[PSC_TEMPERATURE] = linear,
349*e656735fSWensheng Wang 	.format[PSC_VOLTAGE_OUT] = direct,
350*e656735fSWensheng Wang 
351*e656735fSWensheng Wang 	.m[PSC_VOLTAGE_OUT] = 1,
352*e656735fSWensheng Wang 	.R[PSC_VOLTAGE_OUT] = 3,
353*e656735fSWensheng Wang 	.b[PSC_VOLTAGE_OUT] = 0,
354*e656735fSWensheng Wang 
355*e656735fSWensheng Wang 	.func[0] = MP2985_RAIL1_FUNC,
356*e656735fSWensheng Wang 	.func[1] = MP2985_RAIL2_FUNC,
357*e656735fSWensheng Wang 	.read_word_data = mp2985_read_word_data,
358*e656735fSWensheng Wang 	.read_byte_data = mp2985_read_byte_data,
359*e656735fSWensheng Wang 	.write_word_data = mp2985_write_word_data,
360*e656735fSWensheng Wang 	.identify = mp2985_identify,
361*e656735fSWensheng Wang };
362*e656735fSWensheng Wang 
363*e656735fSWensheng Wang static int mp2985_probe(struct i2c_client *client)
364*e656735fSWensheng Wang {
365*e656735fSWensheng Wang 	struct mp2985_data *data;
366*e656735fSWensheng Wang 
367*e656735fSWensheng Wang 	data = devm_kzalloc(&client->dev, sizeof(struct mp2985_data), GFP_KERNEL);
368*e656735fSWensheng Wang 	if (!data)
369*e656735fSWensheng Wang 		return -ENOMEM;
370*e656735fSWensheng Wang 
371*e656735fSWensheng Wang 	memcpy(&data->info, &mp2985_info, sizeof(mp2985_info));
372*e656735fSWensheng Wang 
373*e656735fSWensheng Wang 	return pmbus_do_probe(client, &data->info);
374*e656735fSWensheng Wang }
375*e656735fSWensheng Wang 
376*e656735fSWensheng Wang static const struct i2c_device_id mp2985_id[] = {
377*e656735fSWensheng Wang 	{"mp2985", 0},
378*e656735fSWensheng Wang 	{}
379*e656735fSWensheng Wang };
380*e656735fSWensheng Wang MODULE_DEVICE_TABLE(i2c, mp2985_id);
381*e656735fSWensheng Wang 
382*e656735fSWensheng Wang static const struct of_device_id __maybe_unused mp2985_of_match[] = {
383*e656735fSWensheng Wang 	{.compatible = "mps,mp2985"},
384*e656735fSWensheng Wang 	{}
385*e656735fSWensheng Wang };
386*e656735fSWensheng Wang MODULE_DEVICE_TABLE(of, mp2985_of_match);
387*e656735fSWensheng Wang 
388*e656735fSWensheng Wang static struct i2c_driver mp2985_driver = {
389*e656735fSWensheng Wang 	.driver = {
390*e656735fSWensheng Wang 		.name = "mp2985",
391*e656735fSWensheng Wang 		.of_match_table = mp2985_of_match,
392*e656735fSWensheng Wang 	},
393*e656735fSWensheng Wang 	.probe = mp2985_probe,
394*e656735fSWensheng Wang 	.id_table = mp2985_id,
395*e656735fSWensheng Wang };
396*e656735fSWensheng Wang 
397*e656735fSWensheng Wang module_i2c_driver(mp2985_driver);
398*e656735fSWensheng Wang 
399*e656735fSWensheng Wang MODULE_AUTHOR("Wensheng Wang <wenswang@yeah.net>");
400*e656735fSWensheng Wang MODULE_DESCRIPTION("PMBus driver for MPS MP2985 device");
401*e656735fSWensheng Wang MODULE_LICENSE("GPL");
402*e656735fSWensheng Wang MODULE_IMPORT_NS("PMBUS");
403