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