blob: e153ffd59ab07897dc1916c8b52760ad7383cde7 [file] [log] [blame]
Guenter Roeckc3ff9a62011-09-02 09:58:37 -07001/*
Guenter Roeck649ca822015-06-08 09:56:20 -07002 * Hardware monitoring driver for LTC2978 and compatible chips.
Guenter Roeckc3ff9a62011-09-02 09:58:37 -07003 *
4 * Copyright (c) 2011 Ericsson AB.
Guenter Roeck649ca822015-06-08 09:56:20 -07005 * Copyright (c) 2013, 2014, 2015 Guenter Roeck
Guenter Roeckc3ff9a62011-09-02 09:58:37 -07006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070016 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/err.h>
22#include <linux/slab.h>
23#include <linux/i2c.h>
Alan Tull77aa3582014-10-15 13:55:10 -050024#include <linux/regulator/driver.h>
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070025#include "pmbus.h"
26
Guenter Roeck649ca822015-06-08 09:56:20 -070027enum chips { ltc2974, ltc2975, ltc2977, ltc2978, ltc3880, ltc3882, ltc3883,
28 ltc3887, ltm4676 };
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070029
Guenter Roeckfd9175d2013-01-27 09:24:28 -080030/* Common for all chips */
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070031#define LTC2978_MFR_VOUT_PEAK 0xdd
32#define LTC2978_MFR_VIN_PEAK 0xde
33#define LTC2978_MFR_TEMPERATURE_PEAK 0xdf
Guenter Roeckbf893862015-06-08 10:29:45 -070034#define LTC2978_MFR_SPECIAL_ID 0xe7 /* Not on LTC3882 */
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070035
Guenter Roeck649ca822015-06-08 09:56:20 -070036/* LTC2974, LTC2975, LCT2977, and LTC2978 */
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070037#define LTC2978_MFR_VOUT_MIN 0xfb
38#define LTC2978_MFR_VIN_MIN 0xfc
39#define LTC2978_MFR_TEMPERATURE_MIN 0xfd
40
Guenter Roeck649ca822015-06-08 09:56:20 -070041/* LTC2974, LTC2975 */
Guenter Roeckfd9175d2013-01-27 09:24:28 -080042#define LTC2974_MFR_IOUT_PEAK 0xd7
43#define LTC2974_MFR_IOUT_MIN 0xd8
44
Guenter Roeck15398562015-08-07 09:06:37 -070045/* LTC3880, LTC3882, LTC3883, LTC3887, and LTM4676 */
Guenter Roeckddfb41c2011-09-11 20:31:09 -070046#define LTC3880_MFR_IOUT_PEAK 0xd7
47#define LTC3880_MFR_CLEAR_PEAKS 0xe3
48#define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4
49
Guenter Roeckfd9175d2013-01-27 09:24:28 -080050/* LTC3883 only */
51#define LTC3883_MFR_IIN_PEAK 0xe1
52
Guenter Roeck649ca822015-06-08 09:56:20 -070053/* LTC2975 only */
54#define LTC2975_MFR_IIN_PEAK 0xc4
55#define LTC2975_MFR_IIN_MIN 0xc5
56#define LTC2975_MFR_PIN_PEAK 0xc6
57#define LTC2975_MFR_PIN_MIN 0xc7
58
Guenter Roecka2e151072014-03-05 09:33:01 -080059#define LTC2974_ID_REV1 0x0212
60#define LTC2974_ID_REV2 0x0213
Guenter Roeck649ca822015-06-08 09:56:20 -070061#define LTC2975_ID 0x0223
Guenter Roeckc24c407e2013-09-23 10:56:48 -070062#define LTC2977_ID 0x0130
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070063#define LTC2978_ID_REV1 0x0121
64#define LTC2978_ID_REV2 0x0122
Guenter Roeck3f08d7f2013-09-23 11:23:37 -070065#define LTC2978A_ID 0x0124
Guenter Roeckddfb41c2011-09-11 20:31:09 -070066#define LTC3880_ID 0x4000
67#define LTC3880_ID_MASK 0xff00
Guenter Roeckfd9175d2013-01-27 09:24:28 -080068#define LTC3883_ID 0x4300
69#define LTC3883_ID_MASK 0xff00
Guenter Roeck15398562015-08-07 09:06:37 -070070#define LTC3887_ID 0x4700
71#define LTC3887_ID_MASK 0xff00
Guenter Roecke8047a22015-08-07 01:04:56 -070072#define LTM4676_ID 0x4400
73#define LTM4676_ID_2 0x4480
Guenter Roeck15398562015-08-07 09:06:37 -070074#define LTM4676A_ID 0x47e0
Guenter Roeckf76992b2014-03-05 21:23:01 -080075#define LTM4676_ID_MASK 0xfff0
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070076
Guenter Roeckfd9175d2013-01-27 09:24:28 -080077#define LTC2974_NUM_PAGES 4
Guenter Roeck3d0d2832013-02-28 08:14:45 -080078#define LTC2978_NUM_PAGES 8
79#define LTC3880_NUM_PAGES 2
Guenter Roeckfd9175d2013-01-27 09:24:28 -080080#define LTC3883_NUM_PAGES 1
Guenter Roeck3d0d2832013-02-28 08:14:45 -080081
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070082/*
83 * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
84 * happens pretty much each time chip data is updated. Raw peak data therefore
85 * does not provide much value. To be able to provide useful peak data, keep an
86 * internal cache of measured peak data, which is only cleared if an explicit
87 * "clear peak" command is executed for the sensor in question.
88 */
Guenter Roeck3d0d2832013-02-28 08:14:45 -080089
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070090struct ltc2978_data {
91 enum chips id;
Guenter Roeck3d0d2832013-02-28 08:14:45 -080092 u16 vin_min, vin_max;
Guenter Roeckfd9175d2013-01-27 09:24:28 -080093 u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES];
Guenter Roeck3d0d2832013-02-28 08:14:45 -080094 u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES];
Guenter Roeckfd9175d2013-01-27 09:24:28 -080095 u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES];
Guenter Roeck649ca822015-06-08 09:56:20 -070096 u16 iin_min, iin_max;
97 u16 pin_min, pin_max;
Guenter Roeck3d0d2832013-02-28 08:14:45 -080098 u16 temp2_max;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070099 struct pmbus_driver_info info;
100};
101
102#define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info)
103
104static inline int lin11_to_val(int data)
105{
106 s16 e = ((s16)data) >> 11;
107 s32 m = (((s16)(data << 5)) >> 5);
108
109 /*
110 * mantissa is 10 bit + sign, exponent adds up to 15 bit.
111 * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31).
112 */
113 e += 6;
114 return (e < 0 ? m >> -e : m << e);
115}
116
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700117static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
118 int reg)
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700119{
120 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
121 struct ltc2978_data *data = to_ltc2978_data(info);
122 int ret;
123
124 switch (reg) {
125 case PMBUS_VIRT_READ_VIN_MAX:
126 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_PEAK);
127 if (ret >= 0) {
128 if (lin11_to_val(ret) > lin11_to_val(data->vin_max))
129 data->vin_max = ret;
130 ret = data->vin_max;
131 }
132 break;
133 case PMBUS_VIRT_READ_VOUT_MAX:
134 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK);
135 if (ret >= 0) {
136 /*
137 * VOUT is 16 bit unsigned with fixed exponent,
138 * so we can compare it directly
139 */
140 if (ret > data->vout_max[page])
141 data->vout_max[page] = ret;
142 ret = data->vout_max[page];
143 }
144 break;
145 case PMBUS_VIRT_READ_TEMP_MAX:
146 ret = pmbus_read_word_data(client, page,
147 LTC2978_MFR_TEMPERATURE_PEAK);
148 if (ret >= 0) {
Guenter Roeck8c958c72013-02-21 10:27:54 -0800149 if (lin11_to_val(ret)
150 > lin11_to_val(data->temp_max[page]))
151 data->temp_max[page] = ret;
152 ret = data->temp_max[page];
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700153 }
154 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700155 case PMBUS_VIRT_RESET_VOUT_HISTORY:
156 case PMBUS_VIRT_RESET_VIN_HISTORY:
157 case PMBUS_VIRT_RESET_TEMP_HISTORY:
158 ret = 0;
159 break;
160 default:
161 ret = -ENODATA;
162 break;
163 }
164 return ret;
165}
166
167static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg)
168{
169 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
170 struct ltc2978_data *data = to_ltc2978_data(info);
171 int ret;
172
173 switch (reg) {
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700174 case PMBUS_VIRT_READ_VIN_MIN:
175 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_MIN);
176 if (ret >= 0) {
177 if (lin11_to_val(ret) < lin11_to_val(data->vin_min))
178 data->vin_min = ret;
179 ret = data->vin_min;
180 }
181 break;
182 case PMBUS_VIRT_READ_VOUT_MIN:
183 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_MIN);
184 if (ret >= 0) {
185 /*
186 * VOUT_MIN is known to not be supported on some lots
187 * of LTC2978 revision 1, and will return the maximum
188 * possible voltage if read. If VOUT_MAX is valid and
189 * lower than the reading of VOUT_MIN, use it instead.
190 */
191 if (data->vout_max[page] && ret > data->vout_max[page])
192 ret = data->vout_max[page];
193 if (ret < data->vout_min[page])
194 data->vout_min[page] = ret;
195 ret = data->vout_min[page];
196 }
197 break;
198 case PMBUS_VIRT_READ_TEMP_MIN:
199 ret = pmbus_read_word_data(client, page,
200 LTC2978_MFR_TEMPERATURE_MIN);
201 if (ret >= 0) {
202 if (lin11_to_val(ret)
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800203 < lin11_to_val(data->temp_min[page]))
204 data->temp_min[page] = ret;
205 ret = data->temp_min[page];
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700206 }
207 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700208 case PMBUS_VIRT_READ_IOUT_MAX:
209 case PMBUS_VIRT_RESET_IOUT_HISTORY:
210 case PMBUS_VIRT_READ_TEMP2_MAX:
211 case PMBUS_VIRT_RESET_TEMP2_HISTORY:
212 ret = -ENXIO;
213 break;
214 default:
215 ret = ltc2978_read_word_data_common(client, page, reg);
216 break;
217 }
218 return ret;
219}
220
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800221static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg)
222{
223 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
224 struct ltc2978_data *data = to_ltc2978_data(info);
225 int ret;
226
227 switch (reg) {
228 case PMBUS_VIRT_READ_IOUT_MAX:
229 ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_PEAK);
230 if (ret >= 0) {
231 if (lin11_to_val(ret)
232 > lin11_to_val(data->iout_max[page]))
233 data->iout_max[page] = ret;
234 ret = data->iout_max[page];
235 }
236 break;
237 case PMBUS_VIRT_READ_IOUT_MIN:
238 ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_MIN);
239 if (ret >= 0) {
240 if (lin11_to_val(ret)
241 < lin11_to_val(data->iout_min[page]))
242 data->iout_min[page] = ret;
243 ret = data->iout_min[page];
244 }
245 break;
246 case PMBUS_VIRT_RESET_IOUT_HISTORY:
247 ret = 0;
248 break;
249 default:
250 ret = ltc2978_read_word_data(client, page, reg);
251 break;
252 }
253 return ret;
254}
255
Guenter Roeck649ca822015-06-08 09:56:20 -0700256static int ltc2975_read_word_data(struct i2c_client *client, int page, int reg)
257{
258 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
259 struct ltc2978_data *data = to_ltc2978_data(info);
260 int ret;
261
262 switch (reg) {
263 case PMBUS_VIRT_READ_IIN_MAX:
264 ret = pmbus_read_word_data(client, page, LTC2975_MFR_IIN_PEAK);
265 if (ret >= 0) {
266 if (lin11_to_val(ret)
267 > lin11_to_val(data->iin_max))
268 data->iin_max = ret;
269 ret = data->iin_max;
270 }
271 break;
272 case PMBUS_VIRT_READ_IIN_MIN:
273 ret = pmbus_read_word_data(client, page, LTC2975_MFR_IIN_MIN);
274 if (ret >= 0) {
275 if (lin11_to_val(ret)
276 < lin11_to_val(data->iin_min))
277 data->iin_min = ret;
278 ret = data->iin_min;
279 }
280 break;
281 case PMBUS_VIRT_READ_PIN_MAX:
282 ret = pmbus_read_word_data(client, page, LTC2975_MFR_PIN_PEAK);
283 if (ret >= 0) {
284 if (lin11_to_val(ret)
285 > lin11_to_val(data->pin_max))
286 data->pin_max = ret;
287 ret = data->pin_max;
288 }
289 break;
290 case PMBUS_VIRT_READ_PIN_MIN:
291 ret = pmbus_read_word_data(client, page, LTC2975_MFR_PIN_MIN);
292 if (ret >= 0) {
293 if (lin11_to_val(ret)
294 < lin11_to_val(data->pin_min))
295 data->pin_min = ret;
296 ret = data->pin_min;
297 }
298 break;
299 case PMBUS_VIRT_RESET_IIN_HISTORY:
300 case PMBUS_VIRT_RESET_PIN_HISTORY:
301 ret = 0;
302 break;
303 default:
304 ret = ltc2978_read_word_data(client, page, reg);
305 break;
306 }
307 return ret;
308}
309
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700310static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
311{
312 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
313 struct ltc2978_data *data = to_ltc2978_data(info);
314 int ret;
315
316 switch (reg) {
317 case PMBUS_VIRT_READ_IOUT_MAX:
318 ret = pmbus_read_word_data(client, page, LTC3880_MFR_IOUT_PEAK);
319 if (ret >= 0) {
320 if (lin11_to_val(ret)
321 > lin11_to_val(data->iout_max[page]))
322 data->iout_max[page] = ret;
323 ret = data->iout_max[page];
324 }
325 break;
326 case PMBUS_VIRT_READ_TEMP2_MAX:
327 ret = pmbus_read_word_data(client, page,
328 LTC3880_MFR_TEMPERATURE2_PEAK);
329 if (ret >= 0) {
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800330 if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
331 data->temp2_max = ret;
332 ret = data->temp2_max;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700333 }
334 break;
335 case PMBUS_VIRT_READ_VIN_MIN:
336 case PMBUS_VIRT_READ_VOUT_MIN:
337 case PMBUS_VIRT_READ_TEMP_MIN:
338 ret = -ENXIO;
339 break;
340 case PMBUS_VIRT_RESET_IOUT_HISTORY:
341 case PMBUS_VIRT_RESET_TEMP2_HISTORY:
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700342 ret = 0;
343 break;
344 default:
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700345 ret = ltc2978_read_word_data_common(client, page, reg);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700346 break;
347 }
348 return ret;
349}
350
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800351static int ltc3883_read_word_data(struct i2c_client *client, int page, int reg)
352{
353 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
354 struct ltc2978_data *data = to_ltc2978_data(info);
355 int ret;
356
357 switch (reg) {
358 case PMBUS_VIRT_READ_IIN_MAX:
359 ret = pmbus_read_word_data(client, page, LTC3883_MFR_IIN_PEAK);
360 if (ret >= 0) {
361 if (lin11_to_val(ret)
362 > lin11_to_val(data->iin_max))
363 data->iin_max = ret;
364 ret = data->iin_max;
365 }
366 break;
367 case PMBUS_VIRT_RESET_IIN_HISTORY:
368 ret = 0;
369 break;
370 default:
371 ret = ltc3880_read_word_data(client, page, reg);
372 break;
373 }
374 return ret;
375}
376
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700377static int ltc2978_clear_peaks(struct i2c_client *client, int page,
378 enum chips id)
379{
380 int ret;
381
Guenter Roeck15398562015-08-07 09:06:37 -0700382 if (id == ltc3880 || id == ltc3882 || id == ltc3883 || id == ltc3887 ||
383 id == ltm4676)
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700384 ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS);
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800385 else
386 ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS);
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700387
388 return ret;
389}
390
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700391static int ltc2978_write_word_data(struct i2c_client *client, int page,
392 int reg, u16 word)
393{
394 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
395 struct ltc2978_data *data = to_ltc2978_data(info);
396 int ret;
397
398 switch (reg) {
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800399 case PMBUS_VIRT_RESET_IIN_HISTORY:
400 data->iin_max = 0x7c00;
Guenter Roeck649ca822015-06-08 09:56:20 -0700401 data->iin_min = 0x7bff;
402 ret = ltc2978_clear_peaks(client, 0, data->id);
403 break;
404 case PMBUS_VIRT_RESET_PIN_HISTORY:
405 data->pin_max = 0x7c00;
406 data->pin_min = 0x7bff;
407 ret = ltc2978_clear_peaks(client, 0, data->id);
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800408 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700409 case PMBUS_VIRT_RESET_IOUT_HISTORY:
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800410 data->iout_max[page] = 0x7c00;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800411 data->iout_min[page] = 0xfbff;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700412 ret = ltc2978_clear_peaks(client, page, data->id);
413 break;
414 case PMBUS_VIRT_RESET_TEMP2_HISTORY:
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800415 data->temp2_max = 0x7c00;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700416 ret = ltc2978_clear_peaks(client, page, data->id);
417 break;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700418 case PMBUS_VIRT_RESET_VOUT_HISTORY:
419 data->vout_min[page] = 0xffff;
420 data->vout_max[page] = 0;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700421 ret = ltc2978_clear_peaks(client, page, data->id);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700422 break;
423 case PMBUS_VIRT_RESET_VIN_HISTORY:
424 data->vin_min = 0x7bff;
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800425 data->vin_max = 0x7c00;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700426 ret = ltc2978_clear_peaks(client, page, data->id);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700427 break;
428 case PMBUS_VIRT_RESET_TEMP_HISTORY:
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800429 data->temp_min[page] = 0x7bff;
Guenter Roeck8c958c72013-02-21 10:27:54 -0800430 data->temp_max[page] = 0x7c00;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700431 ret = ltc2978_clear_peaks(client, page, data->id);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700432 break;
433 default:
434 ret = -ENODATA;
435 break;
436 }
437 return ret;
438}
439
440static const struct i2c_device_id ltc2978_id[] = {
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800441 {"ltc2974", ltc2974},
Guenter Roeck649ca822015-06-08 09:56:20 -0700442 {"ltc2975", ltc2975},
Guenter Roeckc24c407e2013-09-23 10:56:48 -0700443 {"ltc2977", ltc2977},
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700444 {"ltc2978", ltc2978},
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700445 {"ltc3880", ltc3880},
Guenter Roeckbf893862015-06-08 10:29:45 -0700446 {"ltc3882", ltc3882},
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800447 {"ltc3883", ltc3883},
Guenter Roeck15398562015-08-07 09:06:37 -0700448 {"ltc3887", ltc3887},
Guenter Roeckf76992b2014-03-05 21:23:01 -0800449 {"ltm4676", ltm4676},
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700450 {}
451};
452MODULE_DEVICE_TABLE(i2c, ltc2978_id);
453
Alan Tull77aa3582014-10-15 13:55:10 -0500454#if IS_ENABLED(CONFIG_SENSORS_LTC2978_REGULATOR)
455static const struct regulator_desc ltc2978_reg_desc[] = {
456 PMBUS_REGULATOR("vout", 0),
457 PMBUS_REGULATOR("vout", 1),
458 PMBUS_REGULATOR("vout", 2),
459 PMBUS_REGULATOR("vout", 3),
460 PMBUS_REGULATOR("vout", 4),
461 PMBUS_REGULATOR("vout", 5),
462 PMBUS_REGULATOR("vout", 6),
463 PMBUS_REGULATOR("vout", 7),
464};
465#endif /* CONFIG_SENSORS_LTC2978_REGULATOR */
466
Guenter Roeck836954d2015-06-08 10:14:00 -0700467static int ltc2978_get_id(struct i2c_client *client)
468{
469 int chip_id;
470
471 chip_id = i2c_smbus_read_word_data(client, LTC2978_MFR_SPECIAL_ID);
Guenter Roeckbf893862015-06-08 10:29:45 -0700472 if (chip_id < 0) {
473 const struct i2c_device_id *id;
474 u8 buf[I2C_SMBUS_BLOCK_MAX];
475 int ret;
476
477 if (!i2c_check_functionality(client->adapter,
478 I2C_FUNC_SMBUS_READ_BLOCK_DATA))
479 return -ENODEV;
480
481 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);
482 if (ret < 0)
483 return ret;
484 if (ret < 3 || strncmp(buf, "LTC", 3))
485 return -ENODEV;
486
487 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
488 if (ret < 0)
489 return ret;
490 for (id = &ltc2978_id[0]; strlen(id->name); id++) {
491 if (!strncasecmp(id->name, buf, strlen(id->name)))
492 return (int)id->driver_data;
493 }
494 return -ENODEV;
495 }
Guenter Roeck836954d2015-06-08 10:14:00 -0700496
497 if (chip_id == LTC2974_ID_REV1 || chip_id == LTC2974_ID_REV2)
498 return ltc2974;
Guenter Roeck649ca822015-06-08 09:56:20 -0700499 else if (chip_id == LTC2975_ID)
500 return ltc2975;
Guenter Roeck836954d2015-06-08 10:14:00 -0700501 else if (chip_id == LTC2977_ID)
502 return ltc2977;
503 else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2 ||
504 chip_id == LTC2978A_ID)
505 return ltc2978;
506 else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID)
507 return ltc3880;
508 else if ((chip_id & LTC3883_ID_MASK) == LTC3883_ID)
509 return ltc3883;
Guenter Roeck15398562015-08-07 09:06:37 -0700510 else if ((chip_id & LTC3887_ID_MASK) == LTC3887_ID)
511 return ltc3887;
Guenter Roecke8047a22015-08-07 01:04:56 -0700512 else if ((chip_id & LTM4676_ID_MASK) == LTM4676_ID ||
513 (chip_id & LTM4676_ID_MASK) == LTM4676_ID_2 ||
514 (chip_id & LTM4676_ID_MASK) == LTM4676A_ID)
Guenter Roeck836954d2015-06-08 10:14:00 -0700515 return ltm4676;
516
517 dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id);
518 return -ENODEV;
519}
520
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700521static int ltc2978_probe(struct i2c_client *client,
522 const struct i2c_device_id *id)
523{
Guenter Roeck836954d2015-06-08 10:14:00 -0700524 int i, chip_id;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700525 struct ltc2978_data *data;
526 struct pmbus_driver_info *info;
527
528 if (!i2c_check_functionality(client->adapter,
529 I2C_FUNC_SMBUS_READ_WORD_DATA))
530 return -ENODEV;
531
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800532 data = devm_kzalloc(&client->dev, sizeof(struct ltc2978_data),
533 GFP_KERNEL);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700534 if (!data)
535 return -ENOMEM;
536
Guenter Roeck836954d2015-06-08 10:14:00 -0700537 chip_id = ltc2978_get_id(client);
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800538 if (chip_id < 0)
539 return chip_id;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700540
Guenter Roeck836954d2015-06-08 10:14:00 -0700541 data->id = chip_id;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700542 if (data->id != id->driver_data)
543 dev_warn(&client->dev,
544 "Device mismatch: Configured %s, detected %s\n",
545 id->name,
546 ltc2978_id[data->id].name);
547
548 info = &data->info;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700549 info->write_word_data = ltc2978_write_word_data;
550
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700551 data->vin_min = 0x7bff;
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800552 data->vin_max = 0x7c00;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800553 for (i = 0; i < ARRAY_SIZE(data->vout_min); i++)
554 data->vout_min[i] = 0xffff;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800555 for (i = 0; i < ARRAY_SIZE(data->iout_min); i++)
556 data->iout_min[i] = 0xfbff;
557 for (i = 0; i < ARRAY_SIZE(data->iout_max); i++)
558 data->iout_max[i] = 0x7c00;
559 for (i = 0; i < ARRAY_SIZE(data->temp_min); i++)
560 data->temp_min[i] = 0x7bff;
Guenter Roeck8c958c72013-02-21 10:27:54 -0800561 for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
562 data->temp_max[i] = 0x7c00;
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800563 data->temp2_max = 0x7c00;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700564
Guenter Roeckf366fcc2013-02-21 10:49:40 -0800565 switch (data->id) {
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800566 case ltc2974:
567 info->read_word_data = ltc2974_read_word_data;
568 info->pages = LTC2974_NUM_PAGES;
569 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
570 | PMBUS_HAVE_TEMP2;
571 for (i = 0; i < info->pages; i++) {
572 info->func[i] |= PMBUS_HAVE_VOUT
573 | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT
574 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
575 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
576 }
577 break;
Guenter Roeck649ca822015-06-08 09:56:20 -0700578 case ltc2975:
579 info->read_word_data = ltc2975_read_word_data;
580 info->pages = LTC2974_NUM_PAGES;
581 info->func[0] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN
582 | PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
583 | PMBUS_HAVE_TEMP2;
584 for (i = 0; i < info->pages; i++) {
585 info->func[i] |= PMBUS_HAVE_VOUT
586 | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT
587 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
588 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
589 }
590 break;
Guenter Roeckc24c407e2013-09-23 10:56:48 -0700591 case ltc2977:
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700592 case ltc2978:
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700593 info->read_word_data = ltc2978_read_word_data;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800594 info->pages = LTC2978_NUM_PAGES;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700595 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
596 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
597 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800598 for (i = 1; i < LTC2978_NUM_PAGES; i++) {
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700599 info->func[i] = PMBUS_HAVE_VOUT
600 | PMBUS_HAVE_STATUS_VOUT;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700601 }
602 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700603 case ltc3880:
Guenter Roeck15398562015-08-07 09:06:37 -0700604 case ltc3887:
Guenter Roeckf76992b2014-03-05 21:23:01 -0800605 case ltm4676:
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700606 info->read_word_data = ltc3880_read_word_data;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800607 info->pages = LTC3880_NUM_PAGES;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700608 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
609 | PMBUS_HAVE_STATUS_INPUT
610 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
611 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
612 | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
613 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
614 info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
615 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
616 | PMBUS_HAVE_POUT
617 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800618 break;
Guenter Roeckbf893862015-06-08 10:29:45 -0700619 case ltc3882:
620 info->read_word_data = ltc3880_read_word_data;
621 info->pages = LTC3880_NUM_PAGES;
622 info->func[0] = PMBUS_HAVE_VIN
623 | PMBUS_HAVE_STATUS_INPUT
624 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
625 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
626 | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
627 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
628 info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
629 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
630 | PMBUS_HAVE_POUT
631 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
632 break;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800633 case ltc3883:
634 info->read_word_data = ltc3883_read_word_data;
635 info->pages = LTC3883_NUM_PAGES;
636 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
637 | PMBUS_HAVE_STATUS_INPUT
638 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
639 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
640 | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
641 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700642 break;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700643 default:
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800644 return -ENODEV;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700645 }
Alan Tull77aa3582014-10-15 13:55:10 -0500646
647#if IS_ENABLED(CONFIG_SENSORS_LTC2978_REGULATOR)
648 info->num_regulators = info->pages;
649 info->reg_desc = ltc2978_reg_desc;
650 if (info->num_regulators > ARRAY_SIZE(ltc2978_reg_desc)) {
651 dev_err(&client->dev, "num_regulators too large!");
652 info->num_regulators = ARRAY_SIZE(ltc2978_reg_desc);
653 }
654#endif
655
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800656 return pmbus_do_probe(client, id, info);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700657}
658
Alan Tull77aa3582014-10-15 13:55:10 -0500659#ifdef CONFIG_OF
660static const struct of_device_id ltc2978_of_match[] = {
661 { .compatible = "lltc,ltc2974" },
Guenter Roeck649ca822015-06-08 09:56:20 -0700662 { .compatible = "lltc,ltc2975" },
Alan Tull77aa3582014-10-15 13:55:10 -0500663 { .compatible = "lltc,ltc2977" },
664 { .compatible = "lltc,ltc2978" },
665 { .compatible = "lltc,ltc3880" },
Guenter Roeckbf893862015-06-08 10:29:45 -0700666 { .compatible = "lltc,ltc3882" },
Alan Tull77aa3582014-10-15 13:55:10 -0500667 { .compatible = "lltc,ltc3883" },
Guenter Roeck15398562015-08-07 09:06:37 -0700668 { .compatible = "lltc,ltc3887" },
Alan Tull77aa3582014-10-15 13:55:10 -0500669 { .compatible = "lltc,ltm4676" },
670 { }
671};
672MODULE_DEVICE_TABLE(of, ltc2978_of_match);
673#endif
674
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700675static struct i2c_driver ltc2978_driver = {
676 .driver = {
677 .name = "ltc2978",
Alan Tull77aa3582014-10-15 13:55:10 -0500678 .of_match_table = of_match_ptr(ltc2978_of_match),
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700679 },
680 .probe = ltc2978_probe,
Guenter Roeckdd285ad2012-02-22 08:56:44 -0800681 .remove = pmbus_do_remove,
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700682 .id_table = ltc2978_id,
683};
684
Axel Linf0967ee2012-01-20 15:38:18 +0800685module_i2c_driver(ltc2978_driver);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700686
687MODULE_AUTHOR("Guenter Roeck");
Guenter Roeck649ca822015-06-08 09:56:20 -0700688MODULE_DESCRIPTION("PMBus driver for LTC2978 and comppatible chips");
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700689MODULE_LICENSE("GPL");