2 * Hardware monitoring driver for LTC2978 and LTC3880
4 * Copyright (c) 2011 Ericsson AB.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/err.h>
25 #include <linux/slab.h>
26 #include <linux/i2c.h>
29 enum chips
{ ltc2978
, ltc3880
};
31 /* LTC2978 and LTC3880 */
32 #define LTC2978_MFR_VOUT_PEAK 0xdd
33 #define LTC2978_MFR_VIN_PEAK 0xde
34 #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf
35 #define LTC2978_MFR_SPECIAL_ID 0xe7
38 #define LTC2978_MFR_VOUT_MIN 0xfb
39 #define LTC2978_MFR_VIN_MIN 0xfc
40 #define LTC2978_MFR_TEMPERATURE_MIN 0xfd
43 #define LTC3880_MFR_IOUT_PEAK 0xd7
44 #define LTC3880_MFR_CLEAR_PEAKS 0xe3
45 #define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4
47 #define LTC2978_ID_REV1 0x0121
48 #define LTC2978_ID_REV2 0x0122
49 #define LTC3880_ID 0x4000
50 #define LTC3880_ID_MASK 0xff00
53 * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
54 * happens pretty much each time chip data is updated. Raw peak data therefore
55 * does not provide much value. To be able to provide useful peak data, keep an
56 * internal cache of measured peak data, which is only cleared if an explicit
57 * "clear peak" command is executed for the sensor in question.
62 int temp_min
, temp_max
;
63 int vout_min
[8], vout_max
[8];
66 struct pmbus_driver_info info
;
69 #define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info)
71 static inline int lin11_to_val(int data
)
73 s16 e
= ((s16
)data
) >> 11;
74 s32 m
= (((s16
)(data
<< 5)) >> 5);
77 * mantissa is 10 bit + sign, exponent adds up to 15 bit.
78 * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31).
81 return (e
< 0 ? m
>> -e
: m
<< e
);
84 static int ltc2978_read_word_data_common(struct i2c_client
*client
, int page
,
87 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
88 struct ltc2978_data
*data
= to_ltc2978_data(info
);
92 case PMBUS_VIRT_READ_VIN_MAX
:
93 ret
= pmbus_read_word_data(client
, page
, LTC2978_MFR_VIN_PEAK
);
95 if (lin11_to_val(ret
) > lin11_to_val(data
->vin_max
))
100 case PMBUS_VIRT_READ_VOUT_MAX
:
101 ret
= pmbus_read_word_data(client
, page
, LTC2978_MFR_VOUT_PEAK
);
104 * VOUT is 16 bit unsigned with fixed exponent,
105 * so we can compare it directly
107 if (ret
> data
->vout_max
[page
])
108 data
->vout_max
[page
] = ret
;
109 ret
= data
->vout_max
[page
];
112 case PMBUS_VIRT_READ_TEMP_MAX
:
113 ret
= pmbus_read_word_data(client
, page
,
114 LTC2978_MFR_TEMPERATURE_PEAK
);
116 if (lin11_to_val(ret
) > lin11_to_val(data
->temp_max
))
117 data
->temp_max
= ret
;
118 ret
= data
->temp_max
;
121 case PMBUS_VIRT_RESET_VOUT_HISTORY
:
122 case PMBUS_VIRT_RESET_VIN_HISTORY
:
123 case PMBUS_VIRT_RESET_TEMP_HISTORY
:
133 static int ltc2978_read_word_data(struct i2c_client
*client
, int page
, int reg
)
135 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
136 struct ltc2978_data
*data
= to_ltc2978_data(info
);
140 case PMBUS_VIRT_READ_VIN_MIN
:
141 ret
= pmbus_read_word_data(client
, page
, LTC2978_MFR_VIN_MIN
);
143 if (lin11_to_val(ret
) < lin11_to_val(data
->vin_min
))
148 case PMBUS_VIRT_READ_VOUT_MIN
:
149 ret
= pmbus_read_word_data(client
, page
, LTC2978_MFR_VOUT_MIN
);
152 * VOUT_MIN is known to not be supported on some lots
153 * of LTC2978 revision 1, and will return the maximum
154 * possible voltage if read. If VOUT_MAX is valid and
155 * lower than the reading of VOUT_MIN, use it instead.
157 if (data
->vout_max
[page
] && ret
> data
->vout_max
[page
])
158 ret
= data
->vout_max
[page
];
159 if (ret
< data
->vout_min
[page
])
160 data
->vout_min
[page
] = ret
;
161 ret
= data
->vout_min
[page
];
164 case PMBUS_VIRT_READ_TEMP_MIN
:
165 ret
= pmbus_read_word_data(client
, page
,
166 LTC2978_MFR_TEMPERATURE_MIN
);
168 if (lin11_to_val(ret
)
169 < lin11_to_val(data
->temp_min
))
170 data
->temp_min
= ret
;
171 ret
= data
->temp_min
;
174 case PMBUS_VIRT_READ_IOUT_MAX
:
175 case PMBUS_VIRT_RESET_IOUT_HISTORY
:
176 case PMBUS_VIRT_READ_TEMP2_MAX
:
177 case PMBUS_VIRT_RESET_TEMP2_HISTORY
:
181 ret
= ltc2978_read_word_data_common(client
, page
, reg
);
187 static int ltc3880_read_word_data(struct i2c_client
*client
, int page
, int reg
)
189 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
190 struct ltc2978_data
*data
= to_ltc2978_data(info
);
194 case PMBUS_VIRT_READ_IOUT_MAX
:
195 ret
= pmbus_read_word_data(client
, page
, LTC3880_MFR_IOUT_PEAK
);
197 if (lin11_to_val(ret
)
198 > lin11_to_val(data
->iout_max
[page
]))
199 data
->iout_max
[page
] = ret
;
200 ret
= data
->iout_max
[page
];
203 case PMBUS_VIRT_READ_TEMP2_MAX
:
204 ret
= pmbus_read_word_data(client
, page
,
205 LTC3880_MFR_TEMPERATURE2_PEAK
);
207 if (lin11_to_val(ret
)
208 > lin11_to_val(data
->temp2_max
[page
]))
209 data
->temp2_max
[page
] = ret
;
210 ret
= data
->temp2_max
[page
];
213 case PMBUS_VIRT_READ_VIN_MIN
:
214 case PMBUS_VIRT_READ_VOUT_MIN
:
215 case PMBUS_VIRT_READ_TEMP_MIN
:
218 case PMBUS_VIRT_RESET_IOUT_HISTORY
:
219 case PMBUS_VIRT_RESET_TEMP2_HISTORY
:
223 ret
= ltc2978_read_word_data_common(client
, page
, reg
);
229 static int ltc2978_clear_peaks(struct i2c_client
*client
, int page
,
235 ret
= pmbus_write_byte(client
, page
, PMBUS_CLEAR_FAULTS
);
237 ret
= pmbus_write_byte(client
, 0, LTC3880_MFR_CLEAR_PEAKS
);
242 static int ltc2978_write_word_data(struct i2c_client
*client
, int page
,
245 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
246 struct ltc2978_data
*data
= to_ltc2978_data(info
);
250 case PMBUS_VIRT_RESET_IOUT_HISTORY
:
251 data
->iout_max
[page
] = 0x7fff;
252 ret
= ltc2978_clear_peaks(client
, page
, data
->id
);
254 case PMBUS_VIRT_RESET_TEMP2_HISTORY
:
255 data
->temp2_max
[page
] = 0x7fff;
256 ret
= ltc2978_clear_peaks(client
, page
, data
->id
);
258 case PMBUS_VIRT_RESET_VOUT_HISTORY
:
259 data
->vout_min
[page
] = 0xffff;
260 data
->vout_max
[page
] = 0;
261 ret
= ltc2978_clear_peaks(client
, page
, data
->id
);
263 case PMBUS_VIRT_RESET_VIN_HISTORY
:
264 data
->vin_min
= 0x7bff;
266 ret
= ltc2978_clear_peaks(client
, page
, data
->id
);
268 case PMBUS_VIRT_RESET_TEMP_HISTORY
:
269 data
->temp_min
= 0x7bff;
270 data
->temp_max
= 0x7fff;
271 ret
= ltc2978_clear_peaks(client
, page
, data
->id
);
280 static const struct i2c_device_id ltc2978_id
[] = {
281 {"ltc2978", ltc2978
},
282 {"ltc3880", ltc3880
},
285 MODULE_DEVICE_TABLE(i2c
, ltc2978_id
);
287 static int ltc2978_probe(struct i2c_client
*client
,
288 const struct i2c_device_id
*id
)
291 struct ltc2978_data
*data
;
292 struct pmbus_driver_info
*info
;
294 if (!i2c_check_functionality(client
->adapter
,
295 I2C_FUNC_SMBUS_READ_WORD_DATA
))
298 data
= kzalloc(sizeof(struct ltc2978_data
), GFP_KERNEL
);
302 chip_id
= i2c_smbus_read_word_data(client
, LTC2978_MFR_SPECIAL_ID
);
308 if (chip_id
== LTC2978_ID_REV1
|| chip_id
== LTC2978_ID_REV2
) {
310 } else if ((chip_id
& LTC3880_ID_MASK
) == LTC3880_ID
) {
313 dev_err(&client
->dev
, "Unsupported chip ID 0x%x\n", chip_id
);
317 if (data
->id
!= id
->driver_data
)
318 dev_warn(&client
->dev
,
319 "Device mismatch: Configured %s, detected %s\n",
321 ltc2978_id
[data
->id
].name
);
324 info
->write_word_data
= ltc2978_write_word_data
;
326 data
->vout_min
[0] = 0xffff;
327 data
->vin_min
= 0x7bff;
328 data
->temp_min
= 0x7bff;
329 data
->temp_max
= 0x7fff;
331 switch (id
->driver_data
) {
333 info
->read_word_data
= ltc2978_read_word_data
;
335 info
->func
[0] = PMBUS_HAVE_VIN
| PMBUS_HAVE_STATUS_INPUT
336 | PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
337 | PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
;
338 for (i
= 1; i
< 8; i
++) {
339 info
->func
[i
] = PMBUS_HAVE_VOUT
340 | PMBUS_HAVE_STATUS_VOUT
;
341 data
->vout_min
[i
] = 0xffff;
345 info
->read_word_data
= ltc3880_read_word_data
;
347 info
->func
[0] = PMBUS_HAVE_VIN
| PMBUS_HAVE_IIN
348 | PMBUS_HAVE_STATUS_INPUT
349 | PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
350 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
351 | PMBUS_HAVE_POUT
| PMBUS_HAVE_TEMP
352 | PMBUS_HAVE_TEMP2
| PMBUS_HAVE_STATUS_TEMP
;
353 info
->func
[1] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
354 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
356 | PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
;
357 data
->vout_min
[1] = 0xffff;
364 ret
= pmbus_do_probe(client
, id
, info
);
374 static int ltc2978_remove(struct i2c_client
*client
)
376 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
377 const struct ltc2978_data
*data
= to_ltc2978_data(info
);
379 pmbus_do_remove(client
);
384 /* This is the driver that will be inserted */
385 static struct i2c_driver ltc2978_driver
= {
389 .probe
= ltc2978_probe
,
390 .remove
= ltc2978_remove
,
391 .id_table
= ltc2978_id
,
394 static int __init
ltc2978_init(void)
396 return i2c_add_driver(<c2978_driver
);
399 static void __exit
ltc2978_exit(void)
401 i2c_del_driver(<c2978_driver
);
404 MODULE_AUTHOR("Guenter Roeck");
405 MODULE_DESCRIPTION("PMBus driver for LTC2978 and LTC3880");
406 MODULE_LICENSE("GPL");
407 module_init(ltc2978_init
);
408 module_exit(ltc2978_exit
);