blob: de3c152a1d9a1f2ed011b679f04ed2f6de74308b [file] [log] [blame]
Guenter Roeckc3ff9a62011-09-02 09:58:37 -07001/*
Guenter Roeckc24c407e2013-09-23 10:56:48 -07002 * Hardware monitoring driver for LTC2974, LTC2977, LTC2978, LTC3880,
3 * and LTC3883
Guenter Roeckc3ff9a62011-09-02 09:58:37 -07004 *
5 * Copyright (c) 2011 Ericsson AB.
Guenter Roeckfd9175d2013-01-27 09:24:28 -08006 * Copyright (c) 2013 Guenter Roeck
Guenter Roeckc3ff9a62011-09-02 09:58:37 -07007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/err.h>
27#include <linux/slab.h>
28#include <linux/i2c.h>
29#include "pmbus.h"
30
Guenter Roeckc24c407e2013-09-23 10:56:48 -070031enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3883 };
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070032
Guenter Roeckfd9175d2013-01-27 09:24:28 -080033/* Common for all chips */
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070034#define LTC2978_MFR_VOUT_PEAK 0xdd
35#define LTC2978_MFR_VIN_PEAK 0xde
36#define LTC2978_MFR_TEMPERATURE_PEAK 0xdf
37#define LTC2978_MFR_SPECIAL_ID 0xe7
38
Guenter Roeckc24c407e2013-09-23 10:56:48 -070039/* LTC2974, LCT2977, and LTC2978 */
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070040#define LTC2978_MFR_VOUT_MIN 0xfb
41#define LTC2978_MFR_VIN_MIN 0xfc
42#define LTC2978_MFR_TEMPERATURE_MIN 0xfd
43
Guenter Roeckfd9175d2013-01-27 09:24:28 -080044/* LTC2974 only */
45#define LTC2974_MFR_IOUT_PEAK 0xd7
46#define LTC2974_MFR_IOUT_MIN 0xd8
47
48/* LTC3880 and LTC3883 */
Guenter Roeckddfb41c2011-09-11 20:31:09 -070049#define LTC3880_MFR_IOUT_PEAK 0xd7
50#define LTC3880_MFR_CLEAR_PEAKS 0xe3
51#define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4
52
Guenter Roeckfd9175d2013-01-27 09:24:28 -080053/* LTC3883 only */
54#define LTC3883_MFR_IIN_PEAK 0xe1
55
56#define LTC2974_ID 0x0212
Guenter Roeckc24c407e2013-09-23 10:56:48 -070057#define LTC2977_ID 0x0130
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070058#define LTC2978_ID_REV1 0x0121
59#define LTC2978_ID_REV2 0x0122
Guenter Roeck3f08d7f2013-09-23 11:23:37 -070060#define LTC2978A_ID 0x0124
Guenter Roeckddfb41c2011-09-11 20:31:09 -070061#define LTC3880_ID 0x4000
62#define LTC3880_ID_MASK 0xff00
Guenter Roeckfd9175d2013-01-27 09:24:28 -080063#define LTC3883_ID 0x4300
64#define LTC3883_ID_MASK 0xff00
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070065
Guenter Roeckfd9175d2013-01-27 09:24:28 -080066#define LTC2974_NUM_PAGES 4
Guenter Roeck3d0d2832013-02-28 08:14:45 -080067#define LTC2978_NUM_PAGES 8
68#define LTC3880_NUM_PAGES 2
Guenter Roeckfd9175d2013-01-27 09:24:28 -080069#define LTC3883_NUM_PAGES 1
Guenter Roeck3d0d2832013-02-28 08:14:45 -080070
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070071/*
72 * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
73 * happens pretty much each time chip data is updated. Raw peak data therefore
74 * does not provide much value. To be able to provide useful peak data, keep an
75 * internal cache of measured peak data, which is only cleared if an explicit
76 * "clear peak" command is executed for the sensor in question.
77 */
Guenter Roeck3d0d2832013-02-28 08:14:45 -080078
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070079struct ltc2978_data {
80 enum chips id;
Guenter Roeck3d0d2832013-02-28 08:14:45 -080081 u16 vin_min, vin_max;
Guenter Roeckfd9175d2013-01-27 09:24:28 -080082 u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES];
Guenter Roeck3d0d2832013-02-28 08:14:45 -080083 u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES];
Guenter Roeckfd9175d2013-01-27 09:24:28 -080084 u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES];
85 u16 iin_max;
Guenter Roeck3d0d2832013-02-28 08:14:45 -080086 u16 temp2_max;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -070087 struct pmbus_driver_info info;
88};
89
90#define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info)
91
92static inline int lin11_to_val(int data)
93{
94 s16 e = ((s16)data) >> 11;
95 s32 m = (((s16)(data << 5)) >> 5);
96
97 /*
98 * mantissa is 10 bit + sign, exponent adds up to 15 bit.
99 * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31).
100 */
101 e += 6;
102 return (e < 0 ? m >> -e : m << e);
103}
104
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700105static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
106 int reg)
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700107{
108 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
109 struct ltc2978_data *data = to_ltc2978_data(info);
110 int ret;
111
112 switch (reg) {
113 case PMBUS_VIRT_READ_VIN_MAX:
114 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_PEAK);
115 if (ret >= 0) {
116 if (lin11_to_val(ret) > lin11_to_val(data->vin_max))
117 data->vin_max = ret;
118 ret = data->vin_max;
119 }
120 break;
121 case PMBUS_VIRT_READ_VOUT_MAX:
122 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK);
123 if (ret >= 0) {
124 /*
125 * VOUT is 16 bit unsigned with fixed exponent,
126 * so we can compare it directly
127 */
128 if (ret > data->vout_max[page])
129 data->vout_max[page] = ret;
130 ret = data->vout_max[page];
131 }
132 break;
133 case PMBUS_VIRT_READ_TEMP_MAX:
134 ret = pmbus_read_word_data(client, page,
135 LTC2978_MFR_TEMPERATURE_PEAK);
136 if (ret >= 0) {
Guenter Roeck8c958c72013-02-21 10:27:54 -0800137 if (lin11_to_val(ret)
138 > lin11_to_val(data->temp_max[page]))
139 data->temp_max[page] = ret;
140 ret = data->temp_max[page];
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700141 }
142 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700143 case PMBUS_VIRT_RESET_VOUT_HISTORY:
144 case PMBUS_VIRT_RESET_VIN_HISTORY:
145 case PMBUS_VIRT_RESET_TEMP_HISTORY:
146 ret = 0;
147 break;
148 default:
149 ret = -ENODATA;
150 break;
151 }
152 return ret;
153}
154
155static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg)
156{
157 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
158 struct ltc2978_data *data = to_ltc2978_data(info);
159 int ret;
160
161 switch (reg) {
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700162 case PMBUS_VIRT_READ_VIN_MIN:
163 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_MIN);
164 if (ret >= 0) {
165 if (lin11_to_val(ret) < lin11_to_val(data->vin_min))
166 data->vin_min = ret;
167 ret = data->vin_min;
168 }
169 break;
170 case PMBUS_VIRT_READ_VOUT_MIN:
171 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_MIN);
172 if (ret >= 0) {
173 /*
174 * VOUT_MIN is known to not be supported on some lots
175 * of LTC2978 revision 1, and will return the maximum
176 * possible voltage if read. If VOUT_MAX is valid and
177 * lower than the reading of VOUT_MIN, use it instead.
178 */
179 if (data->vout_max[page] && ret > data->vout_max[page])
180 ret = data->vout_max[page];
181 if (ret < data->vout_min[page])
182 data->vout_min[page] = ret;
183 ret = data->vout_min[page];
184 }
185 break;
186 case PMBUS_VIRT_READ_TEMP_MIN:
187 ret = pmbus_read_word_data(client, page,
188 LTC2978_MFR_TEMPERATURE_MIN);
189 if (ret >= 0) {
190 if (lin11_to_val(ret)
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800191 < lin11_to_val(data->temp_min[page]))
192 data->temp_min[page] = ret;
193 ret = data->temp_min[page];
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700194 }
195 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700196 case PMBUS_VIRT_READ_IOUT_MAX:
197 case PMBUS_VIRT_RESET_IOUT_HISTORY:
198 case PMBUS_VIRT_READ_TEMP2_MAX:
199 case PMBUS_VIRT_RESET_TEMP2_HISTORY:
200 ret = -ENXIO;
201 break;
202 default:
203 ret = ltc2978_read_word_data_common(client, page, reg);
204 break;
205 }
206 return ret;
207}
208
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800209static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg)
210{
211 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
212 struct ltc2978_data *data = to_ltc2978_data(info);
213 int ret;
214
215 switch (reg) {
216 case PMBUS_VIRT_READ_IOUT_MAX:
217 ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_PEAK);
218 if (ret >= 0) {
219 if (lin11_to_val(ret)
220 > lin11_to_val(data->iout_max[page]))
221 data->iout_max[page] = ret;
222 ret = data->iout_max[page];
223 }
224 break;
225 case PMBUS_VIRT_READ_IOUT_MIN:
226 ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_MIN);
227 if (ret >= 0) {
228 if (lin11_to_val(ret)
229 < lin11_to_val(data->iout_min[page]))
230 data->iout_min[page] = ret;
231 ret = data->iout_min[page];
232 }
233 break;
234 case PMBUS_VIRT_RESET_IOUT_HISTORY:
235 ret = 0;
236 break;
237 default:
238 ret = ltc2978_read_word_data(client, page, reg);
239 break;
240 }
241 return ret;
242}
243
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700244static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
245{
246 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
247 struct ltc2978_data *data = to_ltc2978_data(info);
248 int ret;
249
250 switch (reg) {
251 case PMBUS_VIRT_READ_IOUT_MAX:
252 ret = pmbus_read_word_data(client, page, LTC3880_MFR_IOUT_PEAK);
253 if (ret >= 0) {
254 if (lin11_to_val(ret)
255 > lin11_to_val(data->iout_max[page]))
256 data->iout_max[page] = ret;
257 ret = data->iout_max[page];
258 }
259 break;
260 case PMBUS_VIRT_READ_TEMP2_MAX:
261 ret = pmbus_read_word_data(client, page,
262 LTC3880_MFR_TEMPERATURE2_PEAK);
263 if (ret >= 0) {
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800264 if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
265 data->temp2_max = ret;
266 ret = data->temp2_max;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700267 }
268 break;
269 case PMBUS_VIRT_READ_VIN_MIN:
270 case PMBUS_VIRT_READ_VOUT_MIN:
271 case PMBUS_VIRT_READ_TEMP_MIN:
272 ret = -ENXIO;
273 break;
274 case PMBUS_VIRT_RESET_IOUT_HISTORY:
275 case PMBUS_VIRT_RESET_TEMP2_HISTORY:
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700276 ret = 0;
277 break;
278 default:
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700279 ret = ltc2978_read_word_data_common(client, page, reg);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700280 break;
281 }
282 return ret;
283}
284
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800285static int ltc3883_read_word_data(struct i2c_client *client, int page, int reg)
286{
287 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
288 struct ltc2978_data *data = to_ltc2978_data(info);
289 int ret;
290
291 switch (reg) {
292 case PMBUS_VIRT_READ_IIN_MAX:
293 ret = pmbus_read_word_data(client, page, LTC3883_MFR_IIN_PEAK);
294 if (ret >= 0) {
295 if (lin11_to_val(ret)
296 > lin11_to_val(data->iin_max))
297 data->iin_max = ret;
298 ret = data->iin_max;
299 }
300 break;
301 case PMBUS_VIRT_RESET_IIN_HISTORY:
302 ret = 0;
303 break;
304 default:
305 ret = ltc3880_read_word_data(client, page, reg);
306 break;
307 }
308 return ret;
309}
310
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700311static int ltc2978_clear_peaks(struct i2c_client *client, int page,
312 enum chips id)
313{
314 int ret;
315
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800316 if (id == ltc3880 || id == ltc3883)
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700317 ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS);
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800318 else
319 ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS);
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700320
321 return ret;
322}
323
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700324static int ltc2978_write_word_data(struct i2c_client *client, int page,
325 int reg, u16 word)
326{
327 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
328 struct ltc2978_data *data = to_ltc2978_data(info);
329 int ret;
330
331 switch (reg) {
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800332 case PMBUS_VIRT_RESET_IIN_HISTORY:
333 data->iin_max = 0x7c00;
334 ret = ltc2978_clear_peaks(client, page, data->id);
335 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700336 case PMBUS_VIRT_RESET_IOUT_HISTORY:
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800337 data->iout_max[page] = 0x7c00;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800338 data->iout_min[page] = 0xfbff;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700339 ret = ltc2978_clear_peaks(client, page, data->id);
340 break;
341 case PMBUS_VIRT_RESET_TEMP2_HISTORY:
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800342 data->temp2_max = 0x7c00;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700343 ret = ltc2978_clear_peaks(client, page, data->id);
344 break;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700345 case PMBUS_VIRT_RESET_VOUT_HISTORY:
346 data->vout_min[page] = 0xffff;
347 data->vout_max[page] = 0;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700348 ret = ltc2978_clear_peaks(client, page, data->id);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700349 break;
350 case PMBUS_VIRT_RESET_VIN_HISTORY:
351 data->vin_min = 0x7bff;
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800352 data->vin_max = 0x7c00;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700353 ret = ltc2978_clear_peaks(client, page, data->id);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700354 break;
355 case PMBUS_VIRT_RESET_TEMP_HISTORY:
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800356 data->temp_min[page] = 0x7bff;
Guenter Roeck8c958c72013-02-21 10:27:54 -0800357 data->temp_max[page] = 0x7c00;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700358 ret = ltc2978_clear_peaks(client, page, data->id);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700359 break;
360 default:
361 ret = -ENODATA;
362 break;
363 }
364 return ret;
365}
366
367static const struct i2c_device_id ltc2978_id[] = {
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800368 {"ltc2974", ltc2974},
Guenter Roeckc24c407e2013-09-23 10:56:48 -0700369 {"ltc2977", ltc2977},
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700370 {"ltc2978", ltc2978},
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700371 {"ltc3880", ltc3880},
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800372 {"ltc3883", ltc3883},
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700373 {}
374};
375MODULE_DEVICE_TABLE(i2c, ltc2978_id);
376
377static int ltc2978_probe(struct i2c_client *client,
378 const struct i2c_device_id *id)
379{
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800380 int chip_id, i;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700381 struct ltc2978_data *data;
382 struct pmbus_driver_info *info;
383
384 if (!i2c_check_functionality(client->adapter,
385 I2C_FUNC_SMBUS_READ_WORD_DATA))
386 return -ENODEV;
387
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800388 data = devm_kzalloc(&client->dev, sizeof(struct ltc2978_data),
389 GFP_KERNEL);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700390 if (!data)
391 return -ENOMEM;
392
393 chip_id = i2c_smbus_read_word_data(client, LTC2978_MFR_SPECIAL_ID);
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800394 if (chip_id < 0)
395 return chip_id;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700396
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800397 if (chip_id == LTC2974_ID) {
398 data->id = ltc2974;
Guenter Roeckc24c407e2013-09-23 10:56:48 -0700399 } else if (chip_id == LTC2977_ID) {
400 data->id = ltc2977;
Guenter Roeck3f08d7f2013-09-23 11:23:37 -0700401 } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2 ||
402 chip_id == LTC2978A_ID) {
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700403 data->id = ltc2978;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700404 } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) {
405 data->id = ltc3880;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800406 } else if ((chip_id & LTC3883_ID_MASK) == LTC3883_ID) {
407 data->id = ltc3883;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700408 } else {
409 dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id);
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800410 return -ENODEV;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700411 }
412 if (data->id != id->driver_data)
413 dev_warn(&client->dev,
414 "Device mismatch: Configured %s, detected %s\n",
415 id->name,
416 ltc2978_id[data->id].name);
417
418 info = &data->info;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700419 info->write_word_data = ltc2978_write_word_data;
420
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700421 data->vin_min = 0x7bff;
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800422 data->vin_max = 0x7c00;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800423 for (i = 0; i < ARRAY_SIZE(data->vout_min); i++)
424 data->vout_min[i] = 0xffff;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800425 for (i = 0; i < ARRAY_SIZE(data->iout_min); i++)
426 data->iout_min[i] = 0xfbff;
427 for (i = 0; i < ARRAY_SIZE(data->iout_max); i++)
428 data->iout_max[i] = 0x7c00;
429 for (i = 0; i < ARRAY_SIZE(data->temp_min); i++)
430 data->temp_min[i] = 0x7bff;
Guenter Roeck8c958c72013-02-21 10:27:54 -0800431 for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
432 data->temp_max[i] = 0x7c00;
Guenter Roeckdbd712c2013-02-21 09:33:25 -0800433 data->temp2_max = 0x7c00;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700434
Guenter Roeckf366fcc2013-02-21 10:49:40 -0800435 switch (data->id) {
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800436 case ltc2974:
437 info->read_word_data = ltc2974_read_word_data;
438 info->pages = LTC2974_NUM_PAGES;
439 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
440 | PMBUS_HAVE_TEMP2;
441 for (i = 0; i < info->pages; i++) {
442 info->func[i] |= PMBUS_HAVE_VOUT
443 | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT
444 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
445 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
446 }
447 break;
Guenter Roeckc24c407e2013-09-23 10:56:48 -0700448 case ltc2977:
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700449 case ltc2978:
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700450 info->read_word_data = ltc2978_read_word_data;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800451 info->pages = LTC2978_NUM_PAGES;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700452 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
453 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
454 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800455 for (i = 1; i < LTC2978_NUM_PAGES; i++) {
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700456 info->func[i] = PMBUS_HAVE_VOUT
457 | PMBUS_HAVE_STATUS_VOUT;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700458 }
459 break;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700460 case ltc3880:
461 info->read_word_data = ltc3880_read_word_data;
Guenter Roeck3d0d2832013-02-28 08:14:45 -0800462 info->pages = LTC3880_NUM_PAGES;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700463 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
464 | PMBUS_HAVE_STATUS_INPUT
465 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
466 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
467 | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
468 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
469 info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
470 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
471 | PMBUS_HAVE_POUT
472 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800473 break;
474 case ltc3883:
475 info->read_word_data = ltc3883_read_word_data;
476 info->pages = LTC3883_NUM_PAGES;
477 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
478 | PMBUS_HAVE_STATUS_INPUT
479 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
480 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
481 | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
482 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
Guenter Roeckddfb41c2011-09-11 20:31:09 -0700483 break;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700484 default:
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800485 return -ENODEV;
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700486 }
Guenter Roeck8b313ca2012-02-22 08:56:43 -0800487 return pmbus_do_probe(client, id, info);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700488}
489
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700490/* This is the driver that will be inserted */
491static struct i2c_driver ltc2978_driver = {
492 .driver = {
493 .name = "ltc2978",
494 },
495 .probe = ltc2978_probe,
Guenter Roeckdd285ad2012-02-22 08:56:44 -0800496 .remove = pmbus_do_remove,
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700497 .id_table = ltc2978_id,
498};
499
Axel Linf0967ee2012-01-20 15:38:18 +0800500module_i2c_driver(ltc2978_driver);
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700501
502MODULE_AUTHOR("Guenter Roeck");
Guenter Roeckfd9175d2013-01-27 09:24:28 -0800503MODULE_DESCRIPTION("PMBus driver for LTC2974, LTC2978, LTC3880, and LTC3883");
Guenter Roeckc3ff9a62011-09-02 09:58:37 -0700504MODULE_LICENSE("GPL");