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
mp2869_reg2data_linear11(u16 word)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
mp2869_identify_thwn_flt(struct i2c_client * client,struct pmbus_driver_info * info,int page)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
mp2869_identify_vout_scale(struct i2c_client * client,struct pmbus_driver_info * info,int page)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
mp2869_identify_iout_scale(struct i2c_client * client,struct pmbus_driver_info * info,int page)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
mp2869_read_byte_data(struct i2c_client * client,int page,int reg)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
mp2869_read_word_data(struct i2c_client * client,int page,int phase,int reg)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
mp2869_write_word_data(struct i2c_client * client,int page,int reg,u16 word)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
mp2869_identify(struct i2c_client * client,struct pmbus_driver_info * info)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
mp2869_probe(struct i2c_client * client)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