Commit | Line | Data |
---|---|---|
c942fddf | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
c3ff9a67 | 2 | /* |
649ca820 | 3 | * Hardware monitoring driver for LTC2978 and compatible chips. |
c3ff9a67 GR |
4 | * |
5 | * Copyright (c) 2011 Ericsson AB. | |
649ca820 | 6 | * Copyright (c) 2013, 2014, 2015 Guenter Roeck |
e04d1ce9 | 7 | * Copyright (c) 2015 Linear Technology |
4e15d05d | 8 | * Copyright (c) 2018 Analog Devices Inc. |
c3ff9a67 GR |
9 | */ |
10 | ||
e04d1ce9 MJ |
11 | #include <linux/delay.h> |
12 | #include <linux/jiffies.h> | |
c3ff9a67 GR |
13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> | |
15 | #include <linux/init.h> | |
16 | #include <linux/err.h> | |
17 | #include <linux/slab.h> | |
18 | #include <linux/i2c.h> | |
77aa3585 | 19 | #include <linux/regulator/driver.h> |
c3ff9a67 GR |
20 | #include "pmbus.h" |
21 | ||
ee44fafb MJ |
22 | enum chips { |
23 | /* Managers */ | |
24 | ltc2972, ltc2974, ltc2975, ltc2977, ltc2978, ltc2979, ltc2980, | |
25 | /* Controllers */ | |
daec55ce | 26 | ltc3880, ltc3882, ltc3883, ltc3884, ltc3886, ltc3887, ltc3889, ltc7132, ltc7880, |
ee44fafb MJ |
27 | /* Modules */ |
28 | ltm2987, ltm4664, ltm4675, ltm4676, ltm4677, ltm4678, ltm4680, ltm4686, | |
29 | ltm4700, | |
30 | }; | |
c3ff9a67 | 31 | |
fd9175d2 | 32 | /* Common for all chips */ |
c3ff9a67 GR |
33 | #define LTC2978_MFR_VOUT_PEAK 0xdd |
34 | #define LTC2978_MFR_VIN_PEAK 0xde | |
35 | #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf | |
acb092cd | 36 | #define LTC2978_MFR_SPECIAL_ID 0xe7 /* Undocumented on LTC3882 */ |
e04d1ce9 | 37 | #define LTC2978_MFR_COMMON 0xef |
c3ff9a67 | 38 | |
52aae6af | 39 | /* LTC2974, LTC2975, LCT2977, LTC2980, LTC2978, and LTM2987 */ |
c3ff9a67 GR |
40 | #define LTC2978_MFR_VOUT_MIN 0xfb |
41 | #define LTC2978_MFR_VIN_MIN 0xfc | |
42 | #define LTC2978_MFR_TEMPERATURE_MIN 0xfd | |
43 | ||
649ca820 | 44 | /* LTC2974, LTC2975 */ |
fd9175d2 GR |
45 | #define LTC2974_MFR_IOUT_PEAK 0xd7 |
46 | #define LTC2974_MFR_IOUT_MIN 0xd8 | |
47 | ||
daec55ce | 48 | /* LTC3880, LTC3882, LTC3883, LTC3887, LTM4675, LTM4676, LTC7132 */ |
ddfb41ca GR |
49 | #define LTC3880_MFR_IOUT_PEAK 0xd7 |
50 | #define LTC3880_MFR_CLEAR_PEAKS 0xe3 | |
51 | #define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4 | |
52 | ||
daec55ce | 53 | /* LTC3883, LTC3884, LTC3886, LTC3889, LTC7132, LTC7880 */ |
fd9175d2 GR |
54 | #define LTC3883_MFR_IIN_PEAK 0xe1 |
55 | ||
649ca820 GR |
56 | /* LTC2975 only */ |
57 | #define LTC2975_MFR_IIN_PEAK 0xc4 | |
58 | #define LTC2975_MFR_IIN_MIN 0xc5 | |
59 | #define LTC2975_MFR_PIN_PEAK 0xc6 | |
60 | #define LTC2975_MFR_PIN_MIN 0xc7 | |
61 | ||
00c83371 GR |
62 | #define LTC2978_ID_MASK 0xfff0 |
63 | ||
ee44fafb | 64 | #define LTC2972_ID 0x0310 |
00c83371 GR |
65 | #define LTC2974_ID 0x0210 |
66 | #define LTC2975_ID 0x0220 | |
c24c407e | 67 | #define LTC2977_ID 0x0130 |
acb092cd GR |
68 | #define LTC2978_ID_REV1 0x0110 /* Early revision */ |
69 | #define LTC2978_ID_REV2 0x0120 | |
ee44fafb MJ |
70 | #define LTC2979_ID_A 0x8060 |
71 | #define LTC2979_ID_B 0x8070 | |
52aae6af GR |
72 | #define LTC2980_ID_A 0x8030 /* A/B for two die IDs */ |
73 | #define LTC2980_ID_B 0x8040 | |
00c83371 | 74 | #define LTC3880_ID 0x4020 |
acb092cd GR |
75 | #define LTC3882_ID 0x4200 |
76 | #define LTC3882_ID_D1 0x4240 /* Dash 1 */ | |
fd9175d2 | 77 | #define LTC3883_ID 0x4300 |
ee44fafb | 78 | #define LTC3884_ID 0x4C00 |
228b687d | 79 | #define LTC3886_ID 0x4600 |
15398566 | 80 | #define LTC3887_ID 0x4700 |
ee44fafb | 81 | #define LTC3889_ID 0x4900 |
daec55ce | 82 | #define LTC7132_ID 0x4CE0 |
ee44fafb | 83 | #define LTC7880_ID 0x49E0 |
daec55ce FN |
84 | #define LTM2987_ID_A 0x8010 /* A/B for two die IDs */ |
85 | #define LTM2987_ID_B 0x8020 | |
ee44fafb | 86 | #define LTM4664_ID 0x4120 |
ccf2dc51 | 87 | #define LTM4675_ID 0x47a0 |
00c83371 GR |
88 | #define LTM4676_ID_REV1 0x4400 |
89 | #define LTM4676_ID_REV2 0x4480 | |
15398566 | 90 | #define LTM4676A_ID 0x47e0 |
ee44fafb MJ |
91 | #define LTM4677_ID_REV1 0x47B0 |
92 | #define LTM4677_ID_REV2 0x47D0 | |
93 | #define LTM4678_ID_REV1 0x4100 | |
94 | #define LTM4678_ID_REV2 0x4110 | |
95 | #define LTM4680_ID 0x4140 | |
4e15d05d | 96 | #define LTM4686_ID 0x4770 |
ee44fafb | 97 | #define LTM4700_ID 0x4130 |
c3ff9a67 | 98 | |
ee44fafb | 99 | #define LTC2972_NUM_PAGES 2 |
fd9175d2 | 100 | #define LTC2974_NUM_PAGES 4 |
3d0d2839 GR |
101 | #define LTC2978_NUM_PAGES 8 |
102 | #define LTC3880_NUM_PAGES 2 | |
fd9175d2 | 103 | #define LTC3883_NUM_PAGES 1 |
3d0d2839 | 104 | |
e04d1ce9 MJ |
105 | #define LTC_POLL_TIMEOUT 100 /* in milli-seconds */ |
106 | ||
cf2b012c MJ |
107 | #define LTC_NOT_BUSY BIT(6) |
108 | #define LTC_NOT_PENDING BIT(5) | |
e04d1ce9 | 109 | |
c3ff9a67 GR |
110 | /* |
111 | * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which | |
112 | * happens pretty much each time chip data is updated. Raw peak data therefore | |
113 | * does not provide much value. To be able to provide useful peak data, keep an | |
114 | * internal cache of measured peak data, which is only cleared if an explicit | |
115 | * "clear peak" command is executed for the sensor in question. | |
116 | */ | |
3d0d2839 | 117 | |
c3ff9a67 GR |
118 | struct ltc2978_data { |
119 | enum chips id; | |
3d0d2839 | 120 | u16 vin_min, vin_max; |
fd9175d2 | 121 | u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES]; |
3d0d2839 | 122 | u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES]; |
fd9175d2 | 123 | u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES]; |
649ca820 GR |
124 | u16 iin_min, iin_max; |
125 | u16 pin_min, pin_max; | |
3d0d2839 | 126 | u16 temp2_max; |
c3ff9a67 | 127 | struct pmbus_driver_info info; |
8582bcc8 | 128 | u32 features; |
c3ff9a67 | 129 | }; |
c3ff9a67 GR |
130 | #define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info) |
131 | ||
8582bcc8 | 132 | #define FEAT_CLEAR_PEAKS BIT(0) |
e04d1ce9 | 133 | #define FEAT_NEEDS_POLLING BIT(1) |
8582bcc8 GR |
134 | |
135 | #define has_clear_peaks(d) ((d)->features & FEAT_CLEAR_PEAKS) | |
e04d1ce9 MJ |
136 | #define needs_polling(d) ((d)->features & FEAT_NEEDS_POLLING) |
137 | ||
138 | static int ltc_wait_ready(struct i2c_client *client) | |
139 | { | |
140 | unsigned long timeout = jiffies + msecs_to_jiffies(LTC_POLL_TIMEOUT); | |
141 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
142 | struct ltc2978_data *data = to_ltc2978_data(info); | |
143 | int status; | |
144 | u8 mask; | |
145 | ||
146 | if (!needs_polling(data)) | |
147 | return 0; | |
148 | ||
149 | /* | |
150 | * LTC3883 does not support LTC_NOT_PENDING, even though | |
151 | * the datasheet claims that it does. | |
152 | */ | |
153 | mask = LTC_NOT_BUSY; | |
154 | if (data->id != ltc3883) | |
155 | mask |= LTC_NOT_PENDING; | |
156 | ||
157 | do { | |
158 | status = pmbus_read_byte_data(client, 0, LTC2978_MFR_COMMON); | |
159 | if (status == -EBADMSG || status == -ENXIO) { | |
160 | /* PEC error or NACK: chip may be busy, try again */ | |
161 | usleep_range(50, 100); | |
162 | continue; | |
163 | } | |
164 | if (status < 0) | |
165 | return status; | |
166 | ||
167 | if ((status & mask) == mask) | |
168 | return 0; | |
169 | ||
170 | usleep_range(50, 100); | |
171 | } while (time_before(jiffies, timeout)); | |
172 | ||
173 | return -ETIMEDOUT; | |
174 | } | |
175 | ||
43f33b6e GR |
176 | static int ltc_read_word_data(struct i2c_client *client, int page, int phase, |
177 | int reg) | |
e04d1ce9 MJ |
178 | { |
179 | int ret; | |
180 | ||
181 | ret = ltc_wait_ready(client); | |
182 | if (ret < 0) | |
183 | return ret; | |
184 | ||
43f33b6e | 185 | return pmbus_read_word_data(client, page, 0xff, reg); |
e04d1ce9 MJ |
186 | } |
187 | ||
188 | static int ltc_read_byte_data(struct i2c_client *client, int page, int reg) | |
189 | { | |
190 | int ret; | |
191 | ||
192 | ret = ltc_wait_ready(client); | |
193 | if (ret < 0) | |
194 | return ret; | |
195 | ||
196 | return pmbus_read_byte_data(client, page, reg); | |
197 | } | |
198 | ||
b90f994a ML |
199 | static int ltc_write_byte_data(struct i2c_client *client, int page, int reg, u8 value) |
200 | { | |
201 | int ret; | |
202 | ||
203 | ret = ltc_wait_ready(client); | |
204 | if (ret < 0) | |
205 | return ret; | |
206 | ||
207 | return pmbus_write_byte_data(client, page, reg, value); | |
208 | } | |
209 | ||
e04d1ce9 MJ |
210 | static int ltc_write_byte(struct i2c_client *client, int page, u8 byte) |
211 | { | |
212 | int ret; | |
213 | ||
214 | ret = ltc_wait_ready(client); | |
215 | if (ret < 0) | |
216 | return ret; | |
217 | ||
218 | return pmbus_write_byte(client, page, byte); | |
219 | } | |
8582bcc8 | 220 | |
c3ff9a67 GR |
221 | static inline int lin11_to_val(int data) |
222 | { | |
223 | s16 e = ((s16)data) >> 11; | |
224 | s32 m = (((s16)(data << 5)) >> 5); | |
225 | ||
226 | /* | |
227 | * mantissa is 10 bit + sign, exponent adds up to 15 bit. | |
228 | * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31). | |
229 | */ | |
230 | e += 6; | |
231 | return (e < 0 ? m >> -e : m << e); | |
232 | } | |
233 | ||
ee847a25 GR |
234 | static int ltc_get_max(struct ltc2978_data *data, struct i2c_client *client, |
235 | int page, int reg, u16 *pmax) | |
236 | { | |
237 | int ret; | |
238 | ||
43f33b6e | 239 | ret = ltc_read_word_data(client, page, 0xff, reg); |
ee847a25 GR |
240 | if (ret >= 0) { |
241 | if (lin11_to_val(ret) > lin11_to_val(*pmax)) | |
242 | *pmax = ret; | |
243 | ret = *pmax; | |
244 | } | |
245 | return ret; | |
246 | } | |
247 | ||
248 | static int ltc_get_min(struct ltc2978_data *data, struct i2c_client *client, | |
249 | int page, int reg, u16 *pmin) | |
250 | { | |
251 | int ret; | |
252 | ||
43f33b6e | 253 | ret = ltc_read_word_data(client, page, 0xff, reg); |
ee847a25 GR |
254 | if (ret >= 0) { |
255 | if (lin11_to_val(ret) < lin11_to_val(*pmin)) | |
256 | *pmin = ret; | |
257 | ret = *pmin; | |
258 | } | |
259 | return ret; | |
260 | } | |
261 | ||
ddfb41ca GR |
262 | static int ltc2978_read_word_data_common(struct i2c_client *client, int page, |
263 | int reg) | |
c3ff9a67 GR |
264 | { |
265 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
266 | struct ltc2978_data *data = to_ltc2978_data(info); | |
267 | int ret; | |
268 | ||
269 | switch (reg) { | |
270 | case PMBUS_VIRT_READ_VIN_MAX: | |
ee847a25 GR |
271 | ret = ltc_get_max(data, client, page, LTC2978_MFR_VIN_PEAK, |
272 | &data->vin_max); | |
c3ff9a67 GR |
273 | break; |
274 | case PMBUS_VIRT_READ_VOUT_MAX: | |
43f33b6e GR |
275 | ret = ltc_read_word_data(client, page, 0xff, |
276 | LTC2978_MFR_VOUT_PEAK); | |
c3ff9a67 GR |
277 | if (ret >= 0) { |
278 | /* | |
279 | * VOUT is 16 bit unsigned with fixed exponent, | |
280 | * so we can compare it directly | |
281 | */ | |
282 | if (ret > data->vout_max[page]) | |
283 | data->vout_max[page] = ret; | |
284 | ret = data->vout_max[page]; | |
285 | } | |
286 | break; | |
287 | case PMBUS_VIRT_READ_TEMP_MAX: | |
ee847a25 GR |
288 | ret = ltc_get_max(data, client, page, |
289 | LTC2978_MFR_TEMPERATURE_PEAK, | |
290 | &data->temp_max[page]); | |
c3ff9a67 | 291 | break; |
ddfb41ca GR |
292 | case PMBUS_VIRT_RESET_VOUT_HISTORY: |
293 | case PMBUS_VIRT_RESET_VIN_HISTORY: | |
294 | case PMBUS_VIRT_RESET_TEMP_HISTORY: | |
295 | ret = 0; | |
296 | break; | |
297 | default: | |
e04d1ce9 MJ |
298 | ret = ltc_wait_ready(client); |
299 | if (ret < 0) | |
300 | return ret; | |
ddfb41ca GR |
301 | ret = -ENODATA; |
302 | break; | |
303 | } | |
304 | return ret; | |
305 | } | |
306 | ||
43f33b6e GR |
307 | static int ltc2978_read_word_data(struct i2c_client *client, int page, |
308 | int phase, int reg) | |
ddfb41ca GR |
309 | { |
310 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
311 | struct ltc2978_data *data = to_ltc2978_data(info); | |
312 | int ret; | |
313 | ||
314 | switch (reg) { | |
c3ff9a67 | 315 | case PMBUS_VIRT_READ_VIN_MIN: |
ee847a25 GR |
316 | ret = ltc_get_min(data, client, page, LTC2978_MFR_VIN_MIN, |
317 | &data->vin_min); | |
c3ff9a67 GR |
318 | break; |
319 | case PMBUS_VIRT_READ_VOUT_MIN: | |
43f33b6e GR |
320 | ret = ltc_read_word_data(client, page, phase, |
321 | LTC2978_MFR_VOUT_MIN); | |
c3ff9a67 GR |
322 | if (ret >= 0) { |
323 | /* | |
324 | * VOUT_MIN is known to not be supported on some lots | |
325 | * of LTC2978 revision 1, and will return the maximum | |
326 | * possible voltage if read. If VOUT_MAX is valid and | |
327 | * lower than the reading of VOUT_MIN, use it instead. | |
328 | */ | |
329 | if (data->vout_max[page] && ret > data->vout_max[page]) | |
330 | ret = data->vout_max[page]; | |
331 | if (ret < data->vout_min[page]) | |
332 | data->vout_min[page] = ret; | |
333 | ret = data->vout_min[page]; | |
334 | } | |
335 | break; | |
336 | case PMBUS_VIRT_READ_TEMP_MIN: | |
ee847a25 GR |
337 | ret = ltc_get_min(data, client, page, |
338 | LTC2978_MFR_TEMPERATURE_MIN, | |
339 | &data->temp_min[page]); | |
c3ff9a67 | 340 | break; |
ddfb41ca GR |
341 | case PMBUS_VIRT_READ_IOUT_MAX: |
342 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | |
343 | case PMBUS_VIRT_READ_TEMP2_MAX: | |
344 | case PMBUS_VIRT_RESET_TEMP2_HISTORY: | |
345 | ret = -ENXIO; | |
346 | break; | |
347 | default: | |
348 | ret = ltc2978_read_word_data_common(client, page, reg); | |
349 | break; | |
350 | } | |
351 | return ret; | |
352 | } | |
353 | ||
43f33b6e GR |
354 | static int ltc2974_read_word_data(struct i2c_client *client, int page, |
355 | int phase, int reg) | |
fd9175d2 GR |
356 | { |
357 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
358 | struct ltc2978_data *data = to_ltc2978_data(info); | |
359 | int ret; | |
360 | ||
361 | switch (reg) { | |
362 | case PMBUS_VIRT_READ_IOUT_MAX: | |
ee847a25 GR |
363 | ret = ltc_get_max(data, client, page, LTC2974_MFR_IOUT_PEAK, |
364 | &data->iout_max[page]); | |
fd9175d2 GR |
365 | break; |
366 | case PMBUS_VIRT_READ_IOUT_MIN: | |
ee847a25 GR |
367 | ret = ltc_get_min(data, client, page, LTC2974_MFR_IOUT_MIN, |
368 | &data->iout_min[page]); | |
fd9175d2 GR |
369 | break; |
370 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | |
371 | ret = 0; | |
372 | break; | |
373 | default: | |
43f33b6e | 374 | ret = ltc2978_read_word_data(client, page, phase, reg); |
fd9175d2 GR |
375 | break; |
376 | } | |
377 | return ret; | |
378 | } | |
379 | ||
43f33b6e GR |
380 | static int ltc2975_read_word_data(struct i2c_client *client, int page, |
381 | int phase, int reg) | |
649ca820 GR |
382 | { |
383 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
384 | struct ltc2978_data *data = to_ltc2978_data(info); | |
385 | int ret; | |
386 | ||
387 | switch (reg) { | |
388 | case PMBUS_VIRT_READ_IIN_MAX: | |
ee847a25 GR |
389 | ret = ltc_get_max(data, client, page, LTC2975_MFR_IIN_PEAK, |
390 | &data->iin_max); | |
649ca820 GR |
391 | break; |
392 | case PMBUS_VIRT_READ_IIN_MIN: | |
ee847a25 GR |
393 | ret = ltc_get_min(data, client, page, LTC2975_MFR_IIN_MIN, |
394 | &data->iin_min); | |
649ca820 GR |
395 | break; |
396 | case PMBUS_VIRT_READ_PIN_MAX: | |
ee847a25 GR |
397 | ret = ltc_get_max(data, client, page, LTC2975_MFR_PIN_PEAK, |
398 | &data->pin_max); | |
649ca820 GR |
399 | break; |
400 | case PMBUS_VIRT_READ_PIN_MIN: | |
ee847a25 GR |
401 | ret = ltc_get_min(data, client, page, LTC2975_MFR_PIN_MIN, |
402 | &data->pin_min); | |
649ca820 GR |
403 | break; |
404 | case PMBUS_VIRT_RESET_IIN_HISTORY: | |
405 | case PMBUS_VIRT_RESET_PIN_HISTORY: | |
406 | ret = 0; | |
407 | break; | |
408 | default: | |
43f33b6e | 409 | ret = ltc2978_read_word_data(client, page, phase, reg); |
649ca820 GR |
410 | break; |
411 | } | |
412 | return ret; | |
413 | } | |
414 | ||
43f33b6e GR |
415 | static int ltc3880_read_word_data(struct i2c_client *client, int page, |
416 | int phase, int reg) | |
ddfb41ca GR |
417 | { |
418 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
419 | struct ltc2978_data *data = to_ltc2978_data(info); | |
420 | int ret; | |
421 | ||
422 | switch (reg) { | |
423 | case PMBUS_VIRT_READ_IOUT_MAX: | |
ee847a25 GR |
424 | ret = ltc_get_max(data, client, page, LTC3880_MFR_IOUT_PEAK, |
425 | &data->iout_max[page]); | |
ddfb41ca GR |
426 | break; |
427 | case PMBUS_VIRT_READ_TEMP2_MAX: | |
ee847a25 GR |
428 | ret = ltc_get_max(data, client, page, |
429 | LTC3880_MFR_TEMPERATURE2_PEAK, | |
430 | &data->temp2_max); | |
ddfb41ca GR |
431 | break; |
432 | case PMBUS_VIRT_READ_VIN_MIN: | |
433 | case PMBUS_VIRT_READ_VOUT_MIN: | |
434 | case PMBUS_VIRT_READ_TEMP_MIN: | |
435 | ret = -ENXIO; | |
436 | break; | |
437 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | |
438 | case PMBUS_VIRT_RESET_TEMP2_HISTORY: | |
c3ff9a67 GR |
439 | ret = 0; |
440 | break; | |
441 | default: | |
ddfb41ca | 442 | ret = ltc2978_read_word_data_common(client, page, reg); |
c3ff9a67 GR |
443 | break; |
444 | } | |
445 | return ret; | |
446 | } | |
447 | ||
43f33b6e GR |
448 | static int ltc3883_read_word_data(struct i2c_client *client, int page, |
449 | int phase, int reg) | |
fd9175d2 GR |
450 | { |
451 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
452 | struct ltc2978_data *data = to_ltc2978_data(info); | |
453 | int ret; | |
454 | ||
455 | switch (reg) { | |
456 | case PMBUS_VIRT_READ_IIN_MAX: | |
ee847a25 GR |
457 | ret = ltc_get_max(data, client, page, LTC3883_MFR_IIN_PEAK, |
458 | &data->iin_max); | |
fd9175d2 GR |
459 | break; |
460 | case PMBUS_VIRT_RESET_IIN_HISTORY: | |
461 | ret = 0; | |
462 | break; | |
463 | default: | |
43f33b6e | 464 | ret = ltc3880_read_word_data(client, page, phase, reg); |
fd9175d2 GR |
465 | break; |
466 | } | |
467 | return ret; | |
468 | } | |
469 | ||
8582bcc8 GR |
470 | static int ltc2978_clear_peaks(struct ltc2978_data *data, |
471 | struct i2c_client *client, int page) | |
ddfb41ca GR |
472 | { |
473 | int ret; | |
474 | ||
8582bcc8 | 475 | if (has_clear_peaks(data)) |
e04d1ce9 | 476 | ret = ltc_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS); |
fd9175d2 | 477 | else |
e04d1ce9 | 478 | ret = ltc_write_byte(client, page, PMBUS_CLEAR_FAULTS); |
ddfb41ca GR |
479 | |
480 | return ret; | |
481 | } | |
482 | ||
c3ff9a67 GR |
483 | static int ltc2978_write_word_data(struct i2c_client *client, int page, |
484 | int reg, u16 word) | |
485 | { | |
486 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
487 | struct ltc2978_data *data = to_ltc2978_data(info); | |
488 | int ret; | |
489 | ||
490 | switch (reg) { | |
fd9175d2 GR |
491 | case PMBUS_VIRT_RESET_IIN_HISTORY: |
492 | data->iin_max = 0x7c00; | |
649ca820 | 493 | data->iin_min = 0x7bff; |
8582bcc8 | 494 | ret = ltc2978_clear_peaks(data, client, 0); |
649ca820 GR |
495 | break; |
496 | case PMBUS_VIRT_RESET_PIN_HISTORY: | |
497 | data->pin_max = 0x7c00; | |
498 | data->pin_min = 0x7bff; | |
8582bcc8 | 499 | ret = ltc2978_clear_peaks(data, client, 0); |
fd9175d2 | 500 | break; |
ddfb41ca | 501 | case PMBUS_VIRT_RESET_IOUT_HISTORY: |
dbd712c2 | 502 | data->iout_max[page] = 0x7c00; |
fd9175d2 | 503 | data->iout_min[page] = 0xfbff; |
8582bcc8 | 504 | ret = ltc2978_clear_peaks(data, client, page); |
ddfb41ca GR |
505 | break; |
506 | case PMBUS_VIRT_RESET_TEMP2_HISTORY: | |
dbd712c2 | 507 | data->temp2_max = 0x7c00; |
8582bcc8 | 508 | ret = ltc2978_clear_peaks(data, client, page); |
ddfb41ca | 509 | break; |
c3ff9a67 GR |
510 | case PMBUS_VIRT_RESET_VOUT_HISTORY: |
511 | data->vout_min[page] = 0xffff; | |
512 | data->vout_max[page] = 0; | |
8582bcc8 | 513 | ret = ltc2978_clear_peaks(data, client, page); |
c3ff9a67 GR |
514 | break; |
515 | case PMBUS_VIRT_RESET_VIN_HISTORY: | |
516 | data->vin_min = 0x7bff; | |
dbd712c2 | 517 | data->vin_max = 0x7c00; |
8582bcc8 | 518 | ret = ltc2978_clear_peaks(data, client, page); |
c3ff9a67 GR |
519 | break; |
520 | case PMBUS_VIRT_RESET_TEMP_HISTORY: | |
fd9175d2 | 521 | data->temp_min[page] = 0x7bff; |
8c958c70 | 522 | data->temp_max[page] = 0x7c00; |
8582bcc8 | 523 | ret = ltc2978_clear_peaks(data, client, page); |
c3ff9a67 GR |
524 | break; |
525 | default: | |
e04d1ce9 MJ |
526 | ret = ltc_wait_ready(client); |
527 | if (ret < 0) | |
528 | return ret; | |
c3ff9a67 GR |
529 | ret = -ENODATA; |
530 | break; | |
531 | } | |
532 | return ret; | |
533 | } | |
534 | ||
535 | static const struct i2c_device_id ltc2978_id[] = { | |
ee44fafb | 536 | {"ltc2972", ltc2972}, |
fd9175d2 | 537 | {"ltc2974", ltc2974}, |
649ca820 | 538 | {"ltc2975", ltc2975}, |
c24c407e | 539 | {"ltc2977", ltc2977}, |
c3ff9a67 | 540 | {"ltc2978", ltc2978}, |
ee44fafb | 541 | {"ltc2979", ltc2979}, |
52aae6af | 542 | {"ltc2980", ltc2980}, |
ddfb41ca | 543 | {"ltc3880", ltc3880}, |
bf89386f | 544 | {"ltc3882", ltc3882}, |
fd9175d2 | 545 | {"ltc3883", ltc3883}, |
ee44fafb | 546 | {"ltc3884", ltc3884}, |
228b687d | 547 | {"ltc3886", ltc3886}, |
15398566 | 548 | {"ltc3887", ltc3887}, |
ee44fafb | 549 | {"ltc3889", ltc3889}, |
daec55ce | 550 | {"ltc7132", ltc7132}, |
ee44fafb | 551 | {"ltc7880", ltc7880}, |
52aae6af | 552 | {"ltm2987", ltm2987}, |
ee44fafb | 553 | {"ltm4664", ltm4664}, |
ccf2dc51 | 554 | {"ltm4675", ltm4675}, |
f76992b0 | 555 | {"ltm4676", ltm4676}, |
ee44fafb MJ |
556 | {"ltm4677", ltm4677}, |
557 | {"ltm4678", ltm4678}, | |
558 | {"ltm4680", ltm4680}, | |
4e15d05d | 559 | {"ltm4686", ltm4686}, |
ee44fafb | 560 | {"ltm4700", ltm4700}, |
c3ff9a67 GR |
561 | {} |
562 | }; | |
563 | MODULE_DEVICE_TABLE(i2c, ltc2978_id); | |
564 | ||
77aa3585 | 565 | #if IS_ENABLED(CONFIG_SENSORS_LTC2978_REGULATOR) |
4a235369 ML |
566 | #define LTC2978_ADC_RES 0xFFFF |
567 | #define LTC2978_N_ADC 122 | |
568 | #define LTC2978_MAX_UV (LTC2978_ADC_RES * LTC2978_N_ADC) | |
569 | #define LTC2978_UV_STEP 1000 | |
570 | #define LTC2978_N_VOLTAGES ((LTC2978_MAX_UV / LTC2978_UV_STEP) + 1) | |
571 | ||
77aa3585 | 572 | static const struct regulator_desc ltc2978_reg_desc[] = { |
4a235369 ML |
573 | PMBUS_REGULATOR_STEP("vout", 0, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), |
574 | PMBUS_REGULATOR_STEP("vout", 1, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), | |
575 | PMBUS_REGULATOR_STEP("vout", 2, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), | |
576 | PMBUS_REGULATOR_STEP("vout", 3, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), | |
577 | PMBUS_REGULATOR_STEP("vout", 4, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), | |
578 | PMBUS_REGULATOR_STEP("vout", 5, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), | |
579 | PMBUS_REGULATOR_STEP("vout", 6, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), | |
580 | PMBUS_REGULATOR_STEP("vout", 7, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), | |
581 | }; | |
582 | ||
583 | static const struct regulator_desc ltc2978_reg_desc_default[] = { | |
77aa3585 AT |
584 | PMBUS_REGULATOR("vout", 0), |
585 | PMBUS_REGULATOR("vout", 1), | |
586 | PMBUS_REGULATOR("vout", 2), | |
587 | PMBUS_REGULATOR("vout", 3), | |
588 | PMBUS_REGULATOR("vout", 4), | |
589 | PMBUS_REGULATOR("vout", 5), | |
590 | PMBUS_REGULATOR("vout", 6), | |
591 | PMBUS_REGULATOR("vout", 7), | |
592 | }; | |
593 | #endif /* CONFIG_SENSORS_LTC2978_REGULATOR */ | |
594 | ||
836954da GR |
595 | static int ltc2978_get_id(struct i2c_client *client) |
596 | { | |
597 | int chip_id; | |
598 | ||
599 | chip_id = i2c_smbus_read_word_data(client, LTC2978_MFR_SPECIAL_ID); | |
bf89386f GR |
600 | if (chip_id < 0) { |
601 | const struct i2c_device_id *id; | |
602 | u8 buf[I2C_SMBUS_BLOCK_MAX]; | |
603 | int ret; | |
604 | ||
605 | if (!i2c_check_functionality(client->adapter, | |
606 | I2C_FUNC_SMBUS_READ_BLOCK_DATA)) | |
607 | return -ENODEV; | |
608 | ||
609 | ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf); | |
610 | if (ret < 0) | |
611 | return ret; | |
612 | if (ret < 3 || strncmp(buf, "LTC", 3)) | |
613 | return -ENODEV; | |
614 | ||
615 | ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf); | |
616 | if (ret < 0) | |
617 | return ret; | |
618 | for (id = <c2978_id[0]; strlen(id->name); id++) { | |
619 | if (!strncasecmp(id->name, buf, strlen(id->name))) | |
620 | return (int)id->driver_data; | |
621 | } | |
622 | return -ENODEV; | |
623 | } | |
836954da | 624 | |
00c83371 GR |
625 | chip_id &= LTC2978_ID_MASK; |
626 | ||
ee44fafb MJ |
627 | if (chip_id == LTC2972_ID) |
628 | return ltc2972; | |
629 | else if (chip_id == LTC2974_ID) | |
836954da | 630 | return ltc2974; |
649ca820 GR |
631 | else if (chip_id == LTC2975_ID) |
632 | return ltc2975; | |
836954da GR |
633 | else if (chip_id == LTC2977_ID) |
634 | return ltc2977; | |
acb092cd | 635 | else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) |
836954da | 636 | return ltc2978; |
ee44fafb MJ |
637 | else if (chip_id == LTC2979_ID_A || chip_id == LTC2979_ID_B) |
638 | return ltc2979; | |
52aae6af GR |
639 | else if (chip_id == LTC2980_ID_A || chip_id == LTC2980_ID_B) |
640 | return ltc2980; | |
00c83371 | 641 | else if (chip_id == LTC3880_ID) |
836954da | 642 | return ltc3880; |
acb092cd GR |
643 | else if (chip_id == LTC3882_ID || chip_id == LTC3882_ID_D1) |
644 | return ltc3882; | |
00c83371 | 645 | else if (chip_id == LTC3883_ID) |
836954da | 646 | return ltc3883; |
ee44fafb MJ |
647 | else if (chip_id == LTC3884_ID) |
648 | return ltc3884; | |
228b687d GR |
649 | else if (chip_id == LTC3886_ID) |
650 | return ltc3886; | |
00c83371 | 651 | else if (chip_id == LTC3887_ID) |
15398566 | 652 | return ltc3887; |
ee44fafb MJ |
653 | else if (chip_id == LTC3889_ID) |
654 | return ltc3889; | |
daec55ce FN |
655 | else if (chip_id == LTC7132_ID) |
656 | return ltc7132; | |
ee44fafb MJ |
657 | else if (chip_id == LTC7880_ID) |
658 | return ltc7880; | |
52aae6af GR |
659 | else if (chip_id == LTM2987_ID_A || chip_id == LTM2987_ID_B) |
660 | return ltm2987; | |
ee44fafb MJ |
661 | else if (chip_id == LTM4664_ID) |
662 | return ltm4664; | |
ccf2dc51 GR |
663 | else if (chip_id == LTM4675_ID) |
664 | return ltm4675; | |
00c83371 GR |
665 | else if (chip_id == LTM4676_ID_REV1 || chip_id == LTM4676_ID_REV2 || |
666 | chip_id == LTM4676A_ID) | |
836954da | 667 | return ltm4676; |
ee44fafb MJ |
668 | else if (chip_id == LTM4677_ID_REV1 || chip_id == LTM4677_ID_REV2) |
669 | return ltm4677; | |
670 | else if (chip_id == LTM4678_ID_REV1 || chip_id == LTM4678_ID_REV2) | |
671 | return ltm4678; | |
672 | else if (chip_id == LTM4680_ID) | |
673 | return ltm4680; | |
4e15d05d MH |
674 | else if (chip_id == LTM4686_ID) |
675 | return ltm4686; | |
ee44fafb MJ |
676 | else if (chip_id == LTM4700_ID) |
677 | return ltm4700; | |
836954da GR |
678 | |
679 | dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id); | |
680 | return -ENODEV; | |
681 | } | |
682 | ||
dd431939 | 683 | static int ltc2978_probe(struct i2c_client *client) |
c3ff9a67 | 684 | { |
836954da | 685 | int i, chip_id; |
c3ff9a67 GR |
686 | struct ltc2978_data *data; |
687 | struct pmbus_driver_info *info; | |
dd431939 | 688 | const struct i2c_device_id *id; |
c3ff9a67 GR |
689 | |
690 | if (!i2c_check_functionality(client->adapter, | |
691 | I2C_FUNC_SMBUS_READ_WORD_DATA)) | |
692 | return -ENODEV; | |
693 | ||
8b313ca7 GR |
694 | data = devm_kzalloc(&client->dev, sizeof(struct ltc2978_data), |
695 | GFP_KERNEL); | |
c3ff9a67 GR |
696 | if (!data) |
697 | return -ENOMEM; | |
698 | ||
836954da | 699 | chip_id = ltc2978_get_id(client); |
8b313ca7 GR |
700 | if (chip_id < 0) |
701 | return chip_id; | |
c3ff9a67 | 702 | |
836954da | 703 | data->id = chip_id; |
dd431939 | 704 | id = i2c_match_id(ltc2978_id, client); |
c3ff9a67 GR |
705 | if (data->id != id->driver_data) |
706 | dev_warn(&client->dev, | |
dd431939 | 707 | "Device mismatch: Configured %s (%d), detected %d\n", |
c3ff9a67 | 708 | id->name, |
dd431939 SK |
709 | (int) id->driver_data, |
710 | chip_id); | |
c3ff9a67 GR |
711 | |
712 | info = &data->info; | |
c3ff9a67 | 713 | info->write_word_data = ltc2978_write_word_data; |
e04d1ce9 | 714 | info->write_byte = ltc_write_byte; |
b90f994a | 715 | info->write_byte_data = ltc_write_byte_data; |
e04d1ce9 MJ |
716 | info->read_word_data = ltc_read_word_data; |
717 | info->read_byte_data = ltc_read_byte_data; | |
c3ff9a67 | 718 | |
c3ff9a67 | 719 | data->vin_min = 0x7bff; |
dbd712c2 | 720 | data->vin_max = 0x7c00; |
3d0d2839 GR |
721 | for (i = 0; i < ARRAY_SIZE(data->vout_min); i++) |
722 | data->vout_min[i] = 0xffff; | |
fd9175d2 GR |
723 | for (i = 0; i < ARRAY_SIZE(data->iout_min); i++) |
724 | data->iout_min[i] = 0xfbff; | |
725 | for (i = 0; i < ARRAY_SIZE(data->iout_max); i++) | |
726 | data->iout_max[i] = 0x7c00; | |
727 | for (i = 0; i < ARRAY_SIZE(data->temp_min); i++) | |
728 | data->temp_min[i] = 0x7bff; | |
8c958c70 GR |
729 | for (i = 0; i < ARRAY_SIZE(data->temp_max); i++) |
730 | data->temp_max[i] = 0x7c00; | |
dbd712c2 | 731 | data->temp2_max = 0x7c00; |
c3ff9a67 | 732 | |
f366fccd | 733 | switch (data->id) { |
ee44fafb MJ |
734 | case ltc2972: |
735 | info->read_word_data = ltc2975_read_word_data; | |
736 | info->pages = LTC2972_NUM_PAGES; | |
737 | info->func[0] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | |
738 | | PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | |
739 | | PMBUS_HAVE_TEMP2; | |
740 | for (i = 0; i < info->pages; i++) { | |
741 | info->func[i] |= PMBUS_HAVE_VOUT | |
742 | | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT | |
743 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | |
744 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | |
745 | } | |
746 | break; | |
fd9175d2 GR |
747 | case ltc2974: |
748 | info->read_word_data = ltc2974_read_word_data; | |
749 | info->pages = LTC2974_NUM_PAGES; | |
750 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | |
751 | | PMBUS_HAVE_TEMP2; | |
752 | for (i = 0; i < info->pages; i++) { | |
753 | info->func[i] |= PMBUS_HAVE_VOUT | |
754 | | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT | |
755 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | |
756 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | |
757 | } | |
758 | break; | |
649ca820 GR |
759 | case ltc2975: |
760 | info->read_word_data = ltc2975_read_word_data; | |
761 | info->pages = LTC2974_NUM_PAGES; | |
762 | info->func[0] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | |
763 | | PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | |
764 | | PMBUS_HAVE_TEMP2; | |
765 | for (i = 0; i < info->pages; i++) { | |
766 | info->func[i] |= PMBUS_HAVE_VOUT | |
767 | | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT | |
768 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | |
769 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | |
770 | } | |
771 | break; | |
ee44fafb | 772 | |
c24c407e | 773 | case ltc2977: |
c3ff9a67 | 774 | case ltc2978: |
ee44fafb | 775 | case ltc2979: |
52aae6af GR |
776 | case ltc2980: |
777 | case ltm2987: | |
ddfb41ca | 778 | info->read_word_data = ltc2978_read_word_data; |
3d0d2839 | 779 | info->pages = LTC2978_NUM_PAGES; |
c3ff9a67 GR |
780 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
781 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
782 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | |
3d0d2839 | 783 | for (i = 1; i < LTC2978_NUM_PAGES; i++) { |
c3ff9a67 GR |
784 | info->func[i] = PMBUS_HAVE_VOUT |
785 | | PMBUS_HAVE_STATUS_VOUT; | |
c3ff9a67 GR |
786 | } |
787 | break; | |
ddfb41ca | 788 | case ltc3880: |
15398566 | 789 | case ltc3887: |
ccf2dc51 | 790 | case ltm4675: |
f76992b0 | 791 | case ltm4676: |
ee44fafb | 792 | case ltm4677: |
4e15d05d | 793 | case ltm4686: |
e04d1ce9 | 794 | data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING; |
ddfb41ca | 795 | info->read_word_data = ltc3880_read_word_data; |
3d0d2839 | 796 | info->pages = LTC3880_NUM_PAGES; |
ddfb41ca GR |
797 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN |
798 | | PMBUS_HAVE_STATUS_INPUT | |
799 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
800 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
801 | | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | |
802 | | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | |
803 | info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
804 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
805 | | PMBUS_HAVE_POUT | |
806 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | |
fd9175d2 | 807 | break; |
bf89386f | 808 | case ltc3882: |
e04d1ce9 | 809 | data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING; |
bf89386f GR |
810 | info->read_word_data = ltc3880_read_word_data; |
811 | info->pages = LTC3880_NUM_PAGES; | |
812 | info->func[0] = PMBUS_HAVE_VIN | |
813 | | PMBUS_HAVE_STATUS_INPUT | |
814 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
815 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
816 | | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | |
817 | | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | |
818 | info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
819 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
820 | | PMBUS_HAVE_POUT | |
821 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | |
822 | break; | |
fd9175d2 | 823 | case ltc3883: |
e04d1ce9 | 824 | data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING; |
fd9175d2 GR |
825 | info->read_word_data = ltc3883_read_word_data; |
826 | info->pages = LTC3883_NUM_PAGES; | |
827 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | |
828 | | PMBUS_HAVE_STATUS_INPUT | |
829 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
830 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
831 | | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | |
832 | | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | |
ddfb41ca | 833 | break; |
ee44fafb | 834 | case ltc3884: |
228b687d | 835 | case ltc3886: |
ee44fafb | 836 | case ltc3889: |
daec55ce | 837 | case ltc7132: |
ee44fafb MJ |
838 | case ltc7880: |
839 | case ltm4664: | |
840 | case ltm4678: | |
841 | case ltm4680: | |
842 | case ltm4700: | |
e04d1ce9 | 843 | data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING; |
228b687d GR |
844 | info->read_word_data = ltc3883_read_word_data; |
845 | info->pages = LTC3880_NUM_PAGES; | |
846 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | |
847 | | PMBUS_HAVE_STATUS_INPUT | |
848 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
849 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
850 | | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | |
851 | | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | |
852 | info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
853 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
854 | | PMBUS_HAVE_POUT | |
855 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | |
856 | break; | |
c3ff9a67 | 857 | default: |
8b313ca7 | 858 | return -ENODEV; |
c3ff9a67 | 859 | } |
77aa3585 AT |
860 | |
861 | #if IS_ENABLED(CONFIG_SENSORS_LTC2978_REGULATOR) | |
862 | info->num_regulators = info->pages; | |
4a235369 ML |
863 | switch (data->id) { |
864 | case ltc2972: | |
865 | case ltc2974: | |
866 | case ltc2975: | |
867 | case ltc2977: | |
868 | case ltc2978: | |
869 | case ltc2979: | |
870 | case ltc2980: | |
871 | case ltm2987: | |
872 | info->reg_desc = ltc2978_reg_desc; | |
873 | if (info->num_regulators > ARRAY_SIZE(ltc2978_reg_desc)) { | |
874 | dev_warn(&client->dev, "num_regulators too large!"); | |
875 | info->num_regulators = ARRAY_SIZE(ltc2978_reg_desc); | |
876 | } | |
877 | break; | |
878 | default: | |
879 | info->reg_desc = ltc2978_reg_desc_default; | |
880 | if (info->num_regulators > ARRAY_SIZE(ltc2978_reg_desc_default)) { | |
881 | dev_warn(&client->dev, "num_regulators too large!"); | |
882 | info->num_regulators = | |
883 | ARRAY_SIZE(ltc2978_reg_desc_default); | |
884 | } | |
885 | break; | |
77aa3585 AT |
886 | } |
887 | #endif | |
888 | ||
dd431939 | 889 | return pmbus_do_probe(client, info); |
c3ff9a67 GR |
890 | } |
891 | ||
ee44fafb | 892 | |
77aa3585 AT |
893 | #ifdef CONFIG_OF |
894 | static const struct of_device_id ltc2978_of_match[] = { | |
ee44fafb | 895 | { .compatible = "lltc,ltc2972" }, |
77aa3585 | 896 | { .compatible = "lltc,ltc2974" }, |
649ca820 | 897 | { .compatible = "lltc,ltc2975" }, |
77aa3585 AT |
898 | { .compatible = "lltc,ltc2977" }, |
899 | { .compatible = "lltc,ltc2978" }, | |
ee44fafb | 900 | { .compatible = "lltc,ltc2979" }, |
52aae6af | 901 | { .compatible = "lltc,ltc2980" }, |
77aa3585 | 902 | { .compatible = "lltc,ltc3880" }, |
bf89386f | 903 | { .compatible = "lltc,ltc3882" }, |
77aa3585 | 904 | { .compatible = "lltc,ltc3883" }, |
ee44fafb | 905 | { .compatible = "lltc,ltc3884" }, |
228b687d | 906 | { .compatible = "lltc,ltc3886" }, |
15398566 | 907 | { .compatible = "lltc,ltc3887" }, |
ee44fafb | 908 | { .compatible = "lltc,ltc3889" }, |
daec55ce | 909 | { .compatible = "lltc,ltc7132" }, |
ee44fafb | 910 | { .compatible = "lltc,ltc7880" }, |
52aae6af | 911 | { .compatible = "lltc,ltm2987" }, |
ee44fafb | 912 | { .compatible = "lltc,ltm4664" }, |
ccf2dc51 | 913 | { .compatible = "lltc,ltm4675" }, |
77aa3585 | 914 | { .compatible = "lltc,ltm4676" }, |
ee44fafb MJ |
915 | { .compatible = "lltc,ltm4677" }, |
916 | { .compatible = "lltc,ltm4678" }, | |
917 | { .compatible = "lltc,ltm4680" }, | |
4e15d05d | 918 | { .compatible = "lltc,ltm4686" }, |
ee44fafb | 919 | { .compatible = "lltc,ltm4700" }, |
77aa3585 AT |
920 | { } |
921 | }; | |
922 | MODULE_DEVICE_TABLE(of, ltc2978_of_match); | |
923 | #endif | |
924 | ||
c3ff9a67 GR |
925 | static struct i2c_driver ltc2978_driver = { |
926 | .driver = { | |
927 | .name = "ltc2978", | |
77aa3585 | 928 | .of_match_table = of_match_ptr(ltc2978_of_match), |
c3ff9a67 | 929 | }, |
dd431939 | 930 | .probe_new = ltc2978_probe, |
c3ff9a67 GR |
931 | .id_table = ltc2978_id, |
932 | }; | |
933 | ||
f0967eea | 934 | module_i2c_driver(ltc2978_driver); |
c3ff9a67 GR |
935 | |
936 | MODULE_AUTHOR("Guenter Roeck"); | |
89688e8d | 937 | MODULE_DESCRIPTION("PMBus driver for LTC2978 and compatible chips"); |
c3ff9a67 | 938 | MODULE_LICENSE("GPL"); |
b94ca77e | 939 | MODULE_IMPORT_NS(PMBUS); |