blob: 586a89ef9e0f4f28a6264fd48e00273fad2a1c5a [file] [log] [blame]
Guenter Roeckc3ff9a62011-09-02 09:58:37 -07001/*
Guenter Roeckfd9175d2013-01-27 09:24:28 -08002 * Hardware monitoring driver for LTC2974, LTC2978, LTC3880, and LTC3883
Guenter Roeckc3ff9a62011-09-02 09:58:37 -07003 *
4 * Copyright (c) 2011 Ericsson AB.
Guenter Roeckfd9175d2013-01-27 09:24:28 -08005 * Copyright (c) 2013 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.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/err.h>
26#include <linux/slab.h>
27#include <linux/i2c.h>
28#include "pmbus.h"
29
Guenter Roeckfd9175d2013-01-27 09:24:28 -080030enum chips { ltc2974, ltc2978, ltc3880, ltc3883 };
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070031
Guenter Roeckfd9175d2013-01-27 09:24:28 -080032/* Common for all chips */
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070033#define LTC2978_MFR_VOUT_PEAK 0xdd
34#define LTC2978_MFR_VIN_PEAK 0xde
35#define LTC2978_MFR_TEMPERATURE_PEAK 0xdf
36#define LTC2978_MFR_SPECIAL_ID 0xe7
37
Guenter Roeckfd9175d2013-01-27 09:24:28 -080038/* LTC2974 and LTC2978 */
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070039#define LTC2978_MFR_VOUT_MIN 0xfb
40#define LTC2978_MFR_VIN_MIN 0xfc
41#define LTC2978_MFR_TEMPERATURE_MIN 0xfd
42
Guenter Roeckfd9175d2013-01-27 09:24:28 -080043/* LTC2974 only */
44#define LTC2974_MFR_IOUT_PEAK 0xd7
45#define LTC2974_MFR_IOUT_MIN 0xd8
46
47/* LTC3880 and LTC3883 */
Guenter Roeckddfb41c2011-09-11 20:31:09 -070048#define LTC3880_MFR_IOUT_PEAK 0xd7
49#define LTC3880_MFR_CLEAR_PEAKS 0xe3
50#define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4
51
Guenter Roeckfd9175d2013-01-27 09:24:28 -080052/* LTC3883 only */
53#define LTC3883_MFR_IIN_PEAK 0xe1
54
55#define LTC2974_ID 0x0212
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070056#define LTC2978_ID_REV1 0x0121
57#define LTC2978_ID_REV2 0x0122
Guenter Roeckddfb41c2011-09-11 20:31:09 -070058#define LTC3880_ID 0x4000
59#define LTC3880_ID_MASK 0xff00
Guenter Roeckfd9175d2013-01-27 09:24:28 -080060#define LTC3883_ID 0x4300
61#define LTC3883_ID_MASK 0xff00
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070062
Guenter Roeckfd9175d2013-01-27 09:24:28 -080063#define LTC2974_NUM_PAGES 4
Guenter Roeck3d0d2832013-02-28 08:14:45 -080064#define LTC2978_NUM_PAGES 8
65#define LTC3880_NUM_PAGES 2
Guenter Roeckfd9175d2013-01-27 09:24:28 -080066#define LTC3883_NUM_PAGES 1
Guenter Roeck3d0d2832013-02-28 08:14:45 -080067
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070068/*
69 * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
70 * happens pretty much each time chip data is updated. Raw peak data therefore
71 * does not provide much value. To be able to provide useful peak data, keep an
72 * internal cache of measured peak data, which is only cleared if an explicit
73 * "clear peak" command is executed for the sensor in question.
74 */
Guenter Roeck3d0d2832013-02-28 08:14:45 -080075
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070076struct ltc2978_data {
77 enum chips id;
Guenter Roeck3d0d2832013-02-28 08:14:45 -080078 u16 vin_min, vin_max;
Guenter Roeckfd9175d2013-01-27 09:24:28 -080079 u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES];
Guenter Roeck3d0d2832013-02-28 08:14:45 -080080 u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES];
Guenter Roeckfd9175d2013-01-27 09:24:28 -080081 u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES];
82 u16 iin_max;
Guenter Roeck3d0d2832013-02-28 08:14:45 -080083 u16 temp2_max;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070084 struct pmbus_driver_info info;
85};
86
87#define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info)
88
89static inline int lin11_to_val(int data)
90{
91 s16 e = ((s16)data) >> 11;
92 s32 m = (((s16)(data << 5)) >> 5);
93
94 /*
95 * mantissa is 10 bit + sign, exponent adds up to 15 bit.
96 * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31).
97 */
98 e += 6;
99 return (e < 0 ? m >> -e : m << e);
100}
101
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700102static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
103 int reg)
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700104{
105 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
106 struct ltc2978_data *data = to_ltc2978_data(info);
107 int ret;
108
109 switch (reg) {
110 case PMBUS_VIRT_READ_VIN_MAX:
111 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_PEAK);
112 if (ret >= 0) {
113 if (lin11_to_val(ret) > lin11_to_val(data->vin_max))
114 data->vin_max = ret;
115 ret = data->vin_max;
116 }
117 break;
118 case PMBUS_VIRT_READ_VOUT_MAX:
119 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK);
120 if (ret >= 0) {
121 /*
122 * VOUT is 16 bit unsigned with fixed exponent,
123 * so we can compare it directly
124 */
125 if (ret > data->vout_max[page])
126 data->vout_max[page] = ret;
127 ret = data->vout_max[page];
128 }
129 break;
130 case PMBUS_VIRT_READ_TEMP_MAX:
131 ret = pmbus_read_word_data(client, page,
132 LTC2978_MFR_TEMPERATURE_PEAK);
133 if (ret >= 0) {
Guenter Roeck8c958c72013-02-21 10:27:54 -0800134 if (lin11_to_val(ret)
135 > lin11_to_val(data->temp_max[page]))
136 data->temp_max[page] = ret;
137 ret = data->temp_max[page];
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700138 }
139 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700140 case PMBUS_VIRT_RESET_VOUT_HISTORY:
141 case PMBUS_VIRT_RESET_VIN_HISTORY:
142 case PMBUS_VIRT_RESET_TEMP_HISTORY:
143 ret = 0;
144 break;
145 default:
146 ret = -ENODATA;
147 break;
148 }
149 return ret;
150}
151
152static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg)
153{
154 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
155 struct ltc2978_data *data = to_ltc2978_data(info);
156 int ret;
157
158 switch (reg) {
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700159 case PMBUS_VIRT_READ_VIN_MIN:
160 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_MIN);
161 if (ret >= 0) {
162 if (lin11_to_val(ret) < lin11_to_val(data->vin_min))
163 data->vin_min = ret;
164 ret = data->vin_min;
165 }
166 break;
167 case PMBUS_VIRT_READ_VOUT_MIN:
168 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_MIN);
169 if (ret >= 0) {
170 /*
171 * VOUT_MIN is known to not be supported on some lots
172 * of LTC2978 revision 1, and will return the maximum
173 * possible voltage if read. If VOUT_MAX is valid and
174 * lower than the reading of VOUT_MIN, use it instead.
175 */
176 if (data->vout_max[page] && ret > data->vout_max[page])
177 ret = data->vout_max[page];
178 if (ret < data->vout_min[page])
179 data->vout_min[page] = ret;
180 ret = data->vout_min[page];
181 }
182 break;
183 case PMBUS_VIRT_READ_TEMP_MIN:
184 ret = pmbus_read_word_data(client, page,
185 LTC2978_MFR_TEMPERATURE_MIN);
186 if (ret >= 0) {
187 if (lin11_to_val(ret)
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800188 < lin11_to_val(data->temp_min[page]))
189 data->temp_min[page] = ret;
190 ret = data->temp_min[page];
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700191 }
192 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700193 case PMBUS_VIRT_READ_IOUT_MAX:
194 case PMBUS_VIRT_RESET_IOUT_HISTORY:
195 case PMBUS_VIRT_READ_TEMP2_MAX:
196 case PMBUS_VIRT_RESET_TEMP2_HISTORY:
197 ret = -ENXIO;
198 break;
199 default:
200 ret = ltc2978_read_word_data_common(client, page, reg);
201 break;
202 }
203 return ret;
204}
205
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800206static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg)
207{
208 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
209 struct ltc2978_data *data = to_ltc2978_data(info);
210 int ret;
211
212 switch (reg) {
213 case PMBUS_VIRT_READ_IOUT_MAX:
214 ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_PEAK);
215 if (ret >= 0) {
216 if (lin11_to_val(ret)
217 > lin11_to_val(data->iout_max[page]))
218 data->iout_max[page] = ret;
219 ret = data->iout_max[page];
220 }
221 break;
222 case PMBUS_VIRT_READ_IOUT_MIN:
223 ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_MIN);
224 if (ret >= 0) {
225 if (lin11_to_val(ret)
226 < lin11_to_val(data->iout_min[page]))
227 data->iout_min[page] = ret;
228 ret = data->iout_min[page];
229 }
230 break;
231 case PMBUS_VIRT_RESET_IOUT_HISTORY:
232 ret = 0;
233 break;
234 default:
235 ret = ltc2978_read_word_data(client, page, reg);
236 break;
237 }
238 return ret;
239}
240
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700241static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
242{
243 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
244 struct ltc2978_data *data = to_ltc2978_data(info);
245 int ret;
246
247 switch (reg) {
248 case PMBUS_VIRT_READ_IOUT_MAX:
249 ret = pmbus_read_word_data(client, page, LTC3880_MFR_IOUT_PEAK);
250 if (ret >= 0) {
251 if (lin11_to_val(ret)
252 > lin11_to_val(data->iout_max[page]))
253 data->iout_max[page] = ret;
254 ret = data->iout_max[page];
255 }
256 break;
257 case PMBUS_VIRT_READ_TEMP2_MAX:
258 ret = pmbus_read_word_data(client, page,
259 LTC3880_MFR_TEMPERATURE2_PEAK);
260 if (ret >= 0) {
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800261 if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
262 data->temp2_max = ret;
263 ret = data->temp2_max;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700264 }
265 break;
266 case PMBUS_VIRT_READ_VIN_MIN:
267 case PMBUS_VIRT_READ_VOUT_MIN:
268 case PMBUS_VIRT_READ_TEMP_MIN:
269 ret = -ENXIO;
270 break;
271 case PMBUS_VIRT_RESET_IOUT_HISTORY:
272 case PMBUS_VIRT_RESET_TEMP2_HISTORY:
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700273 ret = 0;
274 break;
275 default:
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700276 ret = ltc2978_read_word_data_common(client, page, reg);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700277 break;
278 }
279 return ret;
280}
281
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800282static int ltc3883_read_word_data(struct i2c_client *client, int page, int reg)
283{
284 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
285 struct ltc2978_data *data = to_ltc2978_data(info);
286 int ret;
287
288 switch (reg) {
289 case PMBUS_VIRT_READ_IIN_MAX:
290 ret = pmbus_read_word_data(client, page, LTC3883_MFR_IIN_PEAK);
291 if (ret >= 0) {
292 if (lin11_to_val(ret)
293 > lin11_to_val(data->iin_max))
294 data->iin_max = ret;
295 ret = data->iin_max;
296 }
297 break;
298 case PMBUS_VIRT_RESET_IIN_HISTORY:
299 ret = 0;
300 break;
301 default:
302 ret = ltc3880_read_word_data(client, page, reg);
303 break;
304 }
305 return ret;
306}
307
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700308static int ltc2978_clear_peaks(struct i2c_client *client, int page,
309 enum chips id)
310{
311 int ret;
312
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800313 if (id == ltc3880 || id == ltc3883)
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700314 ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS);
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800315 else
316 ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS);
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700317
318 return ret;
319}
320
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700321static int ltc2978_write_word_data(struct i2c_client *client, int page,
322 int reg, u16 word)
323{
324 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
325 struct ltc2978_data *data = to_ltc2978_data(info);
326 int ret;
327
328 switch (reg) {
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800329 case PMBUS_VIRT_RESET_IIN_HISTORY:
330 data->iin_max = 0x7c00;
331 ret = ltc2978_clear_peaks(client, page, data->id);
332 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700333 case PMBUS_VIRT_RESET_IOUT_HISTORY:
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800334 data->iout_max[page] = 0x7c00;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800335 data->iout_min[page] = 0xfbff;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700336 ret = ltc2978_clear_peaks(client, page, data->id);
337 break;
338 case PMBUS_VIRT_RESET_TEMP2_HISTORY:
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800339 data->temp2_max = 0x7c00;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700340 ret = ltc2978_clear_peaks(client, page, data->id);
341 break;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700342 case PMBUS_VIRT_RESET_VOUT_HISTORY:
343 data->vout_min[page] = 0xffff;
344 data->vout_max[page] = 0;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700345 ret = ltc2978_clear_peaks(client, page, data->id);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700346 break;
347 case PMBUS_VIRT_RESET_VIN_HISTORY:
348 data->vin_min = 0x7bff;
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800349 data->vin_max = 0x7c00;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700350 ret = ltc2978_clear_peaks(client, page, data->id);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700351 break;
352 case PMBUS_VIRT_RESET_TEMP_HISTORY:
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800353 data->temp_min[page] = 0x7bff;
Guenter Roeck8c958c72013-02-21 10:27:54 -0800354 data->temp_max[page] = 0x7c00;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700355 ret = ltc2978_clear_peaks(client, page, data->id);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700356 break;
357 default:
358 ret = -ENODATA;
359 break;
360 }
361 return ret;
362}
363
364static const struct i2c_device_id ltc2978_id[] = {
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800365 {"ltc2974", ltc2974},
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700366 {"ltc2978", ltc2978},
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700367 {"ltc3880", ltc3880},
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800368 {"ltc3883", ltc3883},
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700369 {}
370};
371MODULE_DEVICE_TABLE(i2c, ltc2978_id);
372
373static int ltc2978_probe(struct i2c_client *client,
374 const struct i2c_device_id *id)
375{
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800376 int chip_id, i;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700377 struct ltc2978_data *data;
378 struct pmbus_driver_info *info;
379
380 if (!i2c_check_functionality(client->adapter,
381 I2C_FUNC_SMBUS_READ_WORD_DATA))
382 return -ENODEV;
383
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800384 data = devm_kzalloc(&client->dev, sizeof(struct ltc2978_data),
385 GFP_KERNEL);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700386 if (!data)
387 return -ENOMEM;
388
389 chip_id = i2c_smbus_read_word_data(client, LTC2978_MFR_SPECIAL_ID);
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800390 if (chip_id < 0)
391 return chip_id;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700392
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800393 if (chip_id == LTC2974_ID) {
394 data->id = ltc2974;
395 } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) {
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700396 data->id = ltc2978;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700397 } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) {
398 data->id = ltc3880;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800399 } else if ((chip_id & LTC3883_ID_MASK) == LTC3883_ID) {
400 data->id = ltc3883;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700401 } else {
402 dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id);
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800403 return -ENODEV;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700404 }
405 if (data->id != id->driver_data)
406 dev_warn(&client->dev,
407 "Device mismatch: Configured %s, detected %s\n",
408 id->name,
409 ltc2978_id[data->id].name);
410
411 info = &data->info;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700412 info->write_word_data = ltc2978_write_word_data;
413
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700414 data->vin_min = 0x7bff;
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800415 data->vin_max = 0x7c00;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800416 for (i = 0; i < ARRAY_SIZE(data->vout_min); i++)
417 data->vout_min[i] = 0xffff;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800418 for (i = 0; i < ARRAY_SIZE(data->iout_min); i++)
419 data->iout_min[i] = 0xfbff;
420 for (i = 0; i < ARRAY_SIZE(data->iout_max); i++)
421 data->iout_max[i] = 0x7c00;
422 for (i = 0; i < ARRAY_SIZE(data->temp_min); i++)
423 data->temp_min[i] = 0x7bff;
Guenter Roeck8c958c72013-02-21 10:27:54 -0800424 for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
425 data->temp_max[i] = 0x7c00;
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800426 data->temp2_max = 0x7c00;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700427
Guenter Roeckf366fcc2013-02-21 10:49:40 -0800428 switch (data->id) {
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800429 case ltc2974:
430 info->read_word_data = ltc2974_read_word_data;
431 info->pages = LTC2974_NUM_PAGES;
432 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
433 | PMBUS_HAVE_TEMP2;
434 for (i = 0; i < info->pages; i++) {
435 info->func[i] |= PMBUS_HAVE_VOUT
436 | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT
437 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
438 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
439 }
440 break;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700441 case ltc2978:
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700442 info->read_word_data = ltc2978_read_word_data;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800443 info->pages = LTC2978_NUM_PAGES;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700444 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
445 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
446 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800447 for (i = 1; i < LTC2978_NUM_PAGES; i++) {
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700448 info->func[i] = PMBUS_HAVE_VOUT
449 | PMBUS_HAVE_STATUS_VOUT;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700450 }
451 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700452 case ltc3880:
453 info->read_word_data = ltc3880_read_word_data;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800454 info->pages = LTC3880_NUM_PAGES;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700455 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
456 | PMBUS_HAVE_STATUS_INPUT
457 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
458 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
459 | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
460 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
461 info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
462 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
463 | PMBUS_HAVE_POUT
464 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800465 break;
466 case ltc3883:
467 info->read_word_data = ltc3883_read_word_data;
468 info->pages = LTC3883_NUM_PAGES;
469 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
470 | PMBUS_HAVE_STATUS_INPUT
471 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
472 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
473 | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
474 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700475 break;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700476 default:
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800477 return -ENODEV;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700478 }
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800479 return pmbus_do_probe(client, id, info);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700480}
481
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700482/* This is the driver that will be inserted */
483static struct i2c_driver ltc2978_driver = {
484 .driver = {
485 .name = "ltc2978",
486 },
487 .probe = ltc2978_probe,
Guenter Roeckdd285ad2012-02-22 08:56:44 -0800488 .remove = pmbus_do_remove,
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700489 .id_table = ltc2978_id,
490};
491
Axel Linf0967ee2012-01-20 15:38:18 +0800492module_i2c_driver(ltc2978_driver);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700493
494MODULE_AUTHOR("Guenter Roeck");
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800495MODULE_DESCRIPTION("PMBus driver for LTC2974, LTC2978, LTC3880, and LTC3883");
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700496MODULE_LICENSE("GPL");