1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066 |
4 | * |
5 | * Copyright (c) 2011 Ericsson AB. |
6 | * Copyright (c) 2013 Guenter Roeck |
7 | */ |
8 | |
9 | #include <linux/bitops.h> |
10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> |
12 | #include <linux/init.h> |
13 | #include <linux/err.h> |
14 | #include <linux/slab.h> |
15 | #include <linux/i2c.h> |
16 | #include <linux/log2.h> |
17 | #include <linux/of_device.h> |
18 | #include "pmbus.h" |
19 | |
20 | enum chips { lm25056, lm25066, lm5064, lm5066, lm5066i }; |
21 | |
22 | #define LM25066_READ_VAUX 0xd0 |
23 | #define LM25066_MFR_READ_IIN 0xd1 |
24 | #define LM25066_MFR_READ_PIN 0xd2 |
25 | #define LM25066_MFR_IIN_OC_WARN_LIMIT 0xd3 |
26 | #define LM25066_MFR_PIN_OP_WARN_LIMIT 0xd4 |
27 | #define LM25066_READ_PIN_PEAK 0xd5 |
28 | #define LM25066_CLEAR_PIN_PEAK 0xd6 |
29 | #define LM25066_DEVICE_SETUP 0xd9 |
30 | #define LM25066_READ_AVG_VIN 0xdc |
31 | #define LM25066_SAMPLES_FOR_AVG 0xdb |
32 | #define LM25066_READ_AVG_VOUT 0xdd |
33 | #define LM25066_READ_AVG_IIN 0xde |
34 | #define LM25066_READ_AVG_PIN 0xdf |
35 | |
36 | #define LM25066_DEV_SETUP_CL BIT(4) /* Current limit */ |
37 | |
38 | #define LM25066_SAMPLES_FOR_AVG_MAX 4096 |
39 | |
40 | /* LM25056 only */ |
41 | |
42 | #define LM25056_VAUX_OV_WARN_LIMIT 0xe3 |
43 | #define LM25056_VAUX_UV_WARN_LIMIT 0xe4 |
44 | |
45 | #define LM25056_MFR_STS_VAUX_OV_WARN BIT(1) |
46 | #define LM25056_MFR_STS_VAUX_UV_WARN BIT(0) |
47 | |
48 | struct __coeff { |
49 | short m, b, R; |
50 | }; |
51 | |
52 | #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) |
53 | #define PSC_POWER_L (PSC_NUM_CLASSES + 1) |
54 | |
55 | static const struct __coeff lm25066_coeff[][PSC_NUM_CLASSES + 2] = { |
56 | [lm25056] = { |
57 | [PSC_VOLTAGE_IN] = { |
58 | .m = 16296, |
59 | .b = 1343, |
60 | .R = -2, |
61 | }, |
62 | [PSC_CURRENT_IN] = { |
63 | .m = 13797, |
64 | .b = -1833, |
65 | .R = -2, |
66 | }, |
67 | [PSC_CURRENT_IN_L] = { |
68 | .m = 6726, |
69 | .b = -537, |
70 | .R = -2, |
71 | }, |
72 | [PSC_POWER] = { |
73 | .m = 5501, |
74 | .b = -2908, |
75 | .R = -3, |
76 | }, |
77 | [PSC_POWER_L] = { |
78 | .m = 26882, |
79 | .b = -5646, |
80 | .R = -4, |
81 | }, |
82 | [PSC_TEMPERATURE] = { |
83 | .m = 1580, |
84 | .b = -14500, |
85 | .R = -2, |
86 | }, |
87 | }, |
88 | [lm25066] = { |
89 | [PSC_VOLTAGE_IN] = { |
90 | .m = 22070, |
91 | .b = -1800, |
92 | .R = -2, |
93 | }, |
94 | [PSC_VOLTAGE_OUT] = { |
95 | .m = 22070, |
96 | .b = -1800, |
97 | .R = -2, |
98 | }, |
99 | [PSC_CURRENT_IN] = { |
100 | .m = 13661, |
101 | .b = -5200, |
102 | .R = -2, |
103 | }, |
104 | [PSC_CURRENT_IN_L] = { |
105 | .m = 6854, |
106 | .b = -3100, |
107 | .R = -2, |
108 | }, |
109 | [PSC_POWER] = { |
110 | .m = 736, |
111 | .b = -3300, |
112 | .R = -2, |
113 | }, |
114 | [PSC_POWER_L] = { |
115 | .m = 369, |
116 | .b = -1900, |
117 | .R = -2, |
118 | }, |
119 | [PSC_TEMPERATURE] = { |
120 | .m = 16, |
121 | }, |
122 | }, |
123 | [lm5064] = { |
124 | [PSC_VOLTAGE_IN] = { |
125 | .m = 4611, |
126 | .b = -642, |
127 | .R = -2, |
128 | }, |
129 | [PSC_VOLTAGE_OUT] = { |
130 | .m = 4621, |
131 | .b = 423, |
132 | .R = -2, |
133 | }, |
134 | [PSC_CURRENT_IN] = { |
135 | .m = 10742, |
136 | .b = 1552, |
137 | .R = -2, |
138 | }, |
139 | [PSC_CURRENT_IN_L] = { |
140 | .m = 5456, |
141 | .b = 2118, |
142 | .R = -2, |
143 | }, |
144 | [PSC_POWER] = { |
145 | .m = 1204, |
146 | .b = 8524, |
147 | .R = -3, |
148 | }, |
149 | [PSC_POWER_L] = { |
150 | .m = 612, |
151 | .b = 11202, |
152 | .R = -3, |
153 | }, |
154 | [PSC_TEMPERATURE] = { |
155 | .m = 16, |
156 | }, |
157 | }, |
158 | [lm5066] = { |
159 | [PSC_VOLTAGE_IN] = { |
160 | .m = 4587, |
161 | .b = -1200, |
162 | .R = -2, |
163 | }, |
164 | [PSC_VOLTAGE_OUT] = { |
165 | .m = 4587, |
166 | .b = -2400, |
167 | .R = -2, |
168 | }, |
169 | [PSC_CURRENT_IN] = { |
170 | .m = 10753, |
171 | .b = -1200, |
172 | .R = -2, |
173 | }, |
174 | [PSC_CURRENT_IN_L] = { |
175 | .m = 5405, |
176 | .b = -600, |
177 | .R = -2, |
178 | }, |
179 | [PSC_POWER] = { |
180 | .m = 1204, |
181 | .b = -6000, |
182 | .R = -3, |
183 | }, |
184 | [PSC_POWER_L] = { |
185 | .m = 605, |
186 | .b = -8000, |
187 | .R = -3, |
188 | }, |
189 | [PSC_TEMPERATURE] = { |
190 | .m = 16, |
191 | }, |
192 | }, |
193 | [lm5066i] = { |
194 | [PSC_VOLTAGE_IN] = { |
195 | .m = 4617, |
196 | .b = -140, |
197 | .R = -2, |
198 | }, |
199 | [PSC_VOLTAGE_OUT] = { |
200 | .m = 4602, |
201 | .b = 500, |
202 | .R = -2, |
203 | }, |
204 | [PSC_CURRENT_IN] = { |
205 | .m = 15076, |
206 | .b = -504, |
207 | .R = -2, |
208 | }, |
209 | [PSC_CURRENT_IN_L] = { |
210 | .m = 7645, |
211 | .b = 100, |
212 | .R = -2, |
213 | }, |
214 | [PSC_POWER] = { |
215 | .m = 1701, |
216 | .b = -4000, |
217 | .R = -3, |
218 | }, |
219 | [PSC_POWER_L] = { |
220 | .m = 861, |
221 | .b = -965, |
222 | .R = -3, |
223 | }, |
224 | [PSC_TEMPERATURE] = { |
225 | .m = 16, |
226 | }, |
227 | }, |
228 | }; |
229 | |
230 | struct lm25066_data { |
231 | int id; |
232 | u16 rlimit; /* Maximum register value */ |
233 | struct pmbus_driver_info info; |
234 | }; |
235 | |
236 | #define to_lm25066_data(x) container_of(x, struct lm25066_data, info) |
237 | |
238 | static int lm25066_read_word_data(struct i2c_client *client, int page, |
239 | int phase, int reg) |
240 | { |
241 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
242 | const struct lm25066_data *data = to_lm25066_data(info); |
243 | int ret; |
244 | |
245 | switch (reg) { |
246 | case PMBUS_VIRT_READ_VMON: |
247 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, LM25066_READ_VAUX); |
248 | if (ret < 0) |
249 | break; |
250 | /* Adjust returned value to match VIN coefficients */ |
251 | switch (data->id) { |
252 | case lm25056: |
253 | /* VIN: 6.14 mV VAUX: 293 uV LSB */ |
254 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); |
255 | break; |
256 | case lm25066: |
257 | /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ |
258 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); |
259 | break; |
260 | case lm5064: |
261 | /* VIN: 4.53 mV VAUX: 700 uV LSB */ |
262 | ret = DIV_ROUND_CLOSEST(ret * 70, 453); |
263 | break; |
264 | case lm5066: |
265 | case lm5066i: |
266 | /* VIN: 2.18 mV VAUX: 725 uV LSB */ |
267 | ret = DIV_ROUND_CLOSEST(ret * 725, 2180); |
268 | break; |
269 | } |
270 | break; |
271 | case PMBUS_READ_IIN: |
272 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
273 | LM25066_MFR_READ_IIN); |
274 | break; |
275 | case PMBUS_READ_PIN: |
276 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
277 | LM25066_MFR_READ_PIN); |
278 | break; |
279 | case PMBUS_IIN_OC_WARN_LIMIT: |
280 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
281 | LM25066_MFR_IIN_OC_WARN_LIMIT); |
282 | break; |
283 | case PMBUS_PIN_OP_WARN_LIMIT: |
284 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
285 | LM25066_MFR_PIN_OP_WARN_LIMIT); |
286 | break; |
287 | case PMBUS_VIRT_READ_VIN_AVG: |
288 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
289 | LM25066_READ_AVG_VIN); |
290 | break; |
291 | case PMBUS_VIRT_READ_VOUT_AVG: |
292 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
293 | LM25066_READ_AVG_VOUT); |
294 | break; |
295 | case PMBUS_VIRT_READ_IIN_AVG: |
296 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
297 | LM25066_READ_AVG_IIN); |
298 | break; |
299 | case PMBUS_VIRT_READ_PIN_AVG: |
300 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
301 | LM25066_READ_AVG_PIN); |
302 | break; |
303 | case PMBUS_VIRT_READ_PIN_MAX: |
304 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
305 | LM25066_READ_PIN_PEAK); |
306 | break; |
307 | case PMBUS_VIRT_RESET_PIN_HISTORY: |
308 | ret = 0; |
309 | break; |
310 | case PMBUS_VIRT_SAMPLES: |
311 | ret = pmbus_read_byte_data(client, page: 0, LM25066_SAMPLES_FOR_AVG); |
312 | if (ret < 0) |
313 | break; |
314 | ret = 1 << ret; |
315 | break; |
316 | default: |
317 | ret = -ENODATA; |
318 | break; |
319 | } |
320 | return ret; |
321 | } |
322 | |
323 | static int lm25056_read_word_data(struct i2c_client *client, int page, |
324 | int phase, int reg) |
325 | { |
326 | int ret; |
327 | |
328 | switch (reg) { |
329 | case PMBUS_VIRT_VMON_UV_WARN_LIMIT: |
330 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
331 | LM25056_VAUX_UV_WARN_LIMIT); |
332 | if (ret < 0) |
333 | break; |
334 | /* Adjust returned value to match VIN coefficients */ |
335 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); |
336 | break; |
337 | case PMBUS_VIRT_VMON_OV_WARN_LIMIT: |
338 | ret = pmbus_read_word_data(client, page: 0, phase: 0xff, |
339 | LM25056_VAUX_OV_WARN_LIMIT); |
340 | if (ret < 0) |
341 | break; |
342 | /* Adjust returned value to match VIN coefficients */ |
343 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); |
344 | break; |
345 | default: |
346 | ret = lm25066_read_word_data(client, page, phase, reg); |
347 | break; |
348 | } |
349 | return ret; |
350 | } |
351 | |
352 | static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg) |
353 | { |
354 | int ret, s; |
355 | |
356 | switch (reg) { |
357 | case PMBUS_VIRT_STATUS_VMON: |
358 | ret = pmbus_read_byte_data(client, page: 0, |
359 | reg: PMBUS_STATUS_MFR_SPECIFIC); |
360 | if (ret < 0) |
361 | break; |
362 | s = 0; |
363 | if (ret & LM25056_MFR_STS_VAUX_UV_WARN) |
364 | s |= PB_VOLTAGE_UV_WARNING; |
365 | if (ret & LM25056_MFR_STS_VAUX_OV_WARN) |
366 | s |= PB_VOLTAGE_OV_WARNING; |
367 | ret = s; |
368 | break; |
369 | default: |
370 | ret = -ENODATA; |
371 | break; |
372 | } |
373 | return ret; |
374 | } |
375 | |
376 | static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, |
377 | u16 word) |
378 | { |
379 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
380 | const struct lm25066_data *data = to_lm25066_data(info); |
381 | int ret; |
382 | |
383 | switch (reg) { |
384 | case PMBUS_POUT_OP_FAULT_LIMIT: |
385 | case PMBUS_POUT_OP_WARN_LIMIT: |
386 | case PMBUS_VOUT_UV_WARN_LIMIT: |
387 | case PMBUS_OT_FAULT_LIMIT: |
388 | case PMBUS_OT_WARN_LIMIT: |
389 | case PMBUS_IIN_OC_FAULT_LIMIT: |
390 | case PMBUS_VIN_UV_WARN_LIMIT: |
391 | case PMBUS_VIN_UV_FAULT_LIMIT: |
392 | case PMBUS_VIN_OV_FAULT_LIMIT: |
393 | case PMBUS_VIN_OV_WARN_LIMIT: |
394 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
395 | ret = pmbus_write_word_data(client, page: 0, reg, word); |
396 | break; |
397 | case PMBUS_IIN_OC_WARN_LIMIT: |
398 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
399 | ret = pmbus_write_word_data(client, page: 0, |
400 | LM25066_MFR_IIN_OC_WARN_LIMIT, |
401 | word); |
402 | break; |
403 | case PMBUS_PIN_OP_WARN_LIMIT: |
404 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
405 | ret = pmbus_write_word_data(client, page: 0, |
406 | LM25066_MFR_PIN_OP_WARN_LIMIT, |
407 | word); |
408 | break; |
409 | case PMBUS_VIRT_VMON_UV_WARN_LIMIT: |
410 | /* Adjust from VIN coefficients (for LM25056) */ |
411 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); |
412 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
413 | ret = pmbus_write_word_data(client, page: 0, |
414 | LM25056_VAUX_UV_WARN_LIMIT, word); |
415 | break; |
416 | case PMBUS_VIRT_VMON_OV_WARN_LIMIT: |
417 | /* Adjust from VIN coefficients (for LM25056) */ |
418 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); |
419 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
420 | ret = pmbus_write_word_data(client, page: 0, |
421 | LM25056_VAUX_OV_WARN_LIMIT, word); |
422 | break; |
423 | case PMBUS_VIRT_RESET_PIN_HISTORY: |
424 | ret = pmbus_write_byte(client, page: 0, LM25066_CLEAR_PIN_PEAK); |
425 | break; |
426 | case PMBUS_VIRT_SAMPLES: |
427 | word = clamp_val(word, 1, LM25066_SAMPLES_FOR_AVG_MAX); |
428 | ret = pmbus_write_byte_data(client, page: 0, LM25066_SAMPLES_FOR_AVG, |
429 | ilog2(word)); |
430 | break; |
431 | default: |
432 | ret = -ENODATA; |
433 | break; |
434 | } |
435 | return ret; |
436 | } |
437 | |
438 | #if IS_ENABLED(CONFIG_SENSORS_LM25066_REGULATOR) |
439 | static const struct regulator_desc lm25066_reg_desc[] = { |
440 | PMBUS_REGULATOR("vout" , 0), |
441 | }; |
442 | #endif |
443 | |
444 | static const struct i2c_device_id lm25066_id[] = { |
445 | {"lm25056" , lm25056}, |
446 | {"lm25066" , lm25066}, |
447 | {"lm5064" , lm5064}, |
448 | {"lm5066" , lm5066}, |
449 | {"lm5066i" , lm5066i}, |
450 | { } |
451 | }; |
452 | MODULE_DEVICE_TABLE(i2c, lm25066_id); |
453 | |
454 | static const struct of_device_id __maybe_unused lm25066_of_match[] = { |
455 | { .compatible = "ti,lm25056" , .data = (void *)lm25056, }, |
456 | { .compatible = "ti,lm25066" , .data = (void *)lm25066, }, |
457 | { .compatible = "ti,lm5064" , .data = (void *)lm5064, }, |
458 | { .compatible = "ti,lm5066" , .data = (void *)lm5066, }, |
459 | { .compatible = "ti,lm5066i" , .data = (void *)lm5066i, }, |
460 | { }, |
461 | }; |
462 | MODULE_DEVICE_TABLE(of, lm25066_of_match); |
463 | |
464 | static int lm25066_probe(struct i2c_client *client) |
465 | { |
466 | int config; |
467 | u32 shunt; |
468 | struct lm25066_data *data; |
469 | struct pmbus_driver_info *info; |
470 | const struct __coeff *coeff; |
471 | const struct of_device_id *of_id; |
472 | const struct i2c_device_id *i2c_id; |
473 | |
474 | if (!i2c_check_functionality(adap: client->adapter, |
475 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) |
476 | return -ENODEV; |
477 | |
478 | data = devm_kzalloc(dev: &client->dev, size: sizeof(struct lm25066_data), |
479 | GFP_KERNEL); |
480 | if (!data) |
481 | return -ENOMEM; |
482 | |
483 | config = i2c_smbus_read_byte_data(client, LM25066_DEVICE_SETUP); |
484 | if (config < 0) |
485 | return config; |
486 | |
487 | i2c_id = i2c_match_id(id: lm25066_id, client); |
488 | |
489 | of_id = of_match_device(matches: lm25066_of_match, dev: &client->dev); |
490 | if (of_id && (unsigned long)of_id->data != i2c_id->driver_data) |
491 | dev_notice(&client->dev, "Device mismatch: %s in device tree, %s detected\n" , |
492 | of_id->name, i2c_id->name); |
493 | |
494 | data->id = i2c_id->driver_data; |
495 | info = &data->info; |
496 | |
497 | info->pages = 1; |
498 | info->format[PSC_VOLTAGE_IN] = direct; |
499 | info->format[PSC_VOLTAGE_OUT] = direct; |
500 | info->format[PSC_CURRENT_IN] = direct; |
501 | info->format[PSC_TEMPERATURE] = direct; |
502 | info->format[PSC_POWER] = direct; |
503 | |
504 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON |
505 | | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT |
506 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_SAMPLES; |
507 | |
508 | if (data->id == lm25056) { |
509 | info->func[0] |= PMBUS_HAVE_STATUS_VMON; |
510 | info->read_word_data = lm25056_read_word_data; |
511 | info->read_byte_data = lm25056_read_byte_data; |
512 | data->rlimit = 0x0fff; |
513 | } else { |
514 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; |
515 | info->read_word_data = lm25066_read_word_data; |
516 | data->rlimit = 0x0fff; |
517 | } |
518 | info->write_word_data = lm25066_write_word_data; |
519 | |
520 | coeff = &lm25066_coeff[data->id][0]; |
521 | info->m[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].m; |
522 | info->b[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].b; |
523 | info->R[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].R; |
524 | info->m[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].m; |
525 | info->b[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].b; |
526 | info->R[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].R; |
527 | info->m[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].m; |
528 | info->b[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].b; |
529 | info->R[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].R; |
530 | info->R[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].R; |
531 | info->R[PSC_POWER] = coeff[PSC_POWER].R; |
532 | if (config & LM25066_DEV_SETUP_CL) { |
533 | info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].m; |
534 | info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].b; |
535 | info->m[PSC_POWER] = coeff[PSC_POWER_L].m; |
536 | info->b[PSC_POWER] = coeff[PSC_POWER_L].b; |
537 | } else { |
538 | info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].m; |
539 | info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b; |
540 | info->m[PSC_POWER] = coeff[PSC_POWER].m; |
541 | info->b[PSC_POWER] = coeff[PSC_POWER].b; |
542 | } |
543 | |
544 | /* |
545 | * Values in the TI datasheets are normalized for a 1mOhm sense |
546 | * resistor; assume that unless DT specifies a value explicitly. |
547 | */ |
548 | if (of_property_read_u32(np: client->dev.of_node, propname: "shunt-resistor-micro-ohms" , out_value: &shunt)) |
549 | shunt = 1000; |
550 | |
551 | info->m[PSC_CURRENT_IN] = info->m[PSC_CURRENT_IN] * shunt / 1000; |
552 | info->m[PSC_POWER] = info->m[PSC_POWER] * shunt / 1000; |
553 | |
554 | #if IS_ENABLED(CONFIG_SENSORS_LM25066_REGULATOR) |
555 | /* LM25056 doesn't support OPERATION */ |
556 | if (data->id != lm25056) { |
557 | info->num_regulators = ARRAY_SIZE(lm25066_reg_desc); |
558 | info->reg_desc = lm25066_reg_desc; |
559 | } |
560 | #endif |
561 | |
562 | return pmbus_do_probe(client, info); |
563 | } |
564 | |
565 | /* This is the driver that will be inserted */ |
566 | static struct i2c_driver lm25066_driver = { |
567 | .driver = { |
568 | .name = "lm25066" , |
569 | .of_match_table = of_match_ptr(lm25066_of_match), |
570 | }, |
571 | .probe = lm25066_probe, |
572 | .id_table = lm25066_id, |
573 | }; |
574 | |
575 | module_i2c_driver(lm25066_driver); |
576 | |
577 | MODULE_AUTHOR("Guenter Roeck" ); |
578 | MODULE_DESCRIPTION("PMBus driver for LM25066 and compatible chips" ); |
579 | MODULE_LICENSE("GPL" ); |
580 | MODULE_IMPORT_NS(PMBUS); |
581 | |