aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2015-06-08 12:56:20 -0400
committerGuenter Roeck <linux@roeck-us.net>2015-08-17 14:55:55 -0400
commit649ca820dab3d76e12408b74af3e8e97abb07ae0 (patch)
tree20d6e9797f112f6af616b532b809fd3dd1fd4d2d /drivers/hwmon
parent15398566f0ea95c66d202b8705dba4f59b9ba01c (diff)
hwmon: (ltc2978) Add support for LTC2975
LTC2975 is mostly compatible to LTC2974, but supports input current and power measurement. Tested-by: Michael Jones <mike@proclivis.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/pmbus/Kconfig4
-rw-r--r--drivers/hwmon/pmbus/ltc2978.c104
2 files changed, 96 insertions, 12 deletions
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 43b6de900ce5..8279727987cb 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -52,8 +52,8 @@ config SENSORS_LTC2978
52 default n 52 default n
53 help 53 help
54 If you say yes here you get hardware monitoring support for Linear 54 If you say yes here you get hardware monitoring support for Linear
55 Technology LTC2974, LTC2977, LTC2978, LTC3880, LTC3883, LTC3887, 55 Technology LTC2974, LTC2975, LTC2977, LTC2978, LTC3880, LTC3883,
56 and LTM4676. 56 LTC3887, and LTM4676.
57 57
58 This driver can also be built as a module. If so, the module will 58 This driver can also be built as a module. If so, the module will
59 be called ltc2978. 59 be called ltc2978.
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c
index 0756d8ae9dad..e153ffd59ab0 100644
--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * Hardware monitoring driver for LTC2974, LTC2977, LTC2978, LTC3880, 2 * Hardware monitoring driver for LTC2978 and compatible chips.
3 * LTC3883, LTC3887. and LTM4676
4 * 3 *
5 * Copyright (c) 2011 Ericsson AB. 4 * Copyright (c) 2011 Ericsson AB.
6 * Copyright (c) 2013, 2014 Guenter Roeck 5 * Copyright (c) 2013, 2014, 2015 Guenter Roeck
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify 7 * 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 8 * it under the terms of the GNU General Public License as published by
@@ -25,8 +24,8 @@
25#include <linux/regulator/driver.h> 24#include <linux/regulator/driver.h>
26#include "pmbus.h" 25#include "pmbus.h"
27 26
28enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3882, ltc3883, ltc3887, 27enum chips { ltc2974, ltc2975, ltc2977, ltc2978, ltc3880, ltc3882, ltc3883,
29 ltm4676 }; 28 ltc3887, ltm4676 };
30 29
31/* Common for all chips */ 30/* Common for all chips */
32#define LTC2978_MFR_VOUT_PEAK 0xdd 31#define LTC2978_MFR_VOUT_PEAK 0xdd
@@ -34,12 +33,12 @@ enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3882, ltc3883, ltc3887,
34#define LTC2978_MFR_TEMPERATURE_PEAK 0xdf 33#define LTC2978_MFR_TEMPERATURE_PEAK 0xdf
35#define LTC2978_MFR_SPECIAL_ID 0xe7 /* Not on LTC3882 */ 34#define LTC2978_MFR_SPECIAL_ID 0xe7 /* Not on LTC3882 */
36 35
37/* LTC2974, LCT2977, and LTC2978 */ 36/* LTC2974, LTC2975, LCT2977, and LTC2978 */
38#define LTC2978_MFR_VOUT_MIN 0xfb 37#define LTC2978_MFR_VOUT_MIN 0xfb
39#define LTC2978_MFR_VIN_MIN 0xfc 38#define LTC2978_MFR_VIN_MIN 0xfc
40#define LTC2978_MFR_TEMPERATURE_MIN 0xfd 39#define LTC2978_MFR_TEMPERATURE_MIN 0xfd
41 40
42/* LTC2974 only */ 41/* LTC2974, LTC2975 */
43#define LTC2974_MFR_IOUT_PEAK 0xd7 42#define LTC2974_MFR_IOUT_PEAK 0xd7
44#define LTC2974_MFR_IOUT_MIN 0xd8 43#define LTC2974_MFR_IOUT_MIN 0xd8
45 44
@@ -51,8 +50,15 @@ enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3882, ltc3883, ltc3887,
51/* LTC3883 only */ 50/* LTC3883 only */
52#define LTC3883_MFR_IIN_PEAK 0xe1 51#define LTC3883_MFR_IIN_PEAK 0xe1
53 52
53/* 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
54#define LTC2974_ID_REV1 0x0212 59#define LTC2974_ID_REV1 0x0212
55#define LTC2974_ID_REV2 0x0213 60#define LTC2974_ID_REV2 0x0213
61#define LTC2975_ID 0x0223
56#define LTC2977_ID 0x0130 62#define LTC2977_ID 0x0130
57#define LTC2978_ID_REV1 0x0121 63#define LTC2978_ID_REV1 0x0121
58#define LTC2978_ID_REV2 0x0122 64#define LTC2978_ID_REV2 0x0122
@@ -87,7 +93,8 @@ struct ltc2978_data {
87 u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES]; 93 u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES];
88 u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES]; 94 u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES];
89 u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES]; 95 u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES];
90 u16 iin_max; 96 u16 iin_min, iin_max;
97 u16 pin_min, pin_max;
91 u16 temp2_max; 98 u16 temp2_max;
92 struct pmbus_driver_info info; 99 struct pmbus_driver_info info;
93}; 100};
@@ -246,6 +253,60 @@ static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg)
246 return ret; 253 return ret;
247} 254}
248 255
256static 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
249static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) 310static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
250{ 311{
251 const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 312 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
@@ -337,7 +398,13 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
337 switch (reg) { 398 switch (reg) {
338 case PMBUS_VIRT_RESET_IIN_HISTORY: 399 case PMBUS_VIRT_RESET_IIN_HISTORY:
339 data->iin_max = 0x7c00; 400 data->iin_max = 0x7c00;
340 ret = ltc2978_clear_peaks(client, page, data->id); 401 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);
341 break; 408 break;
342 case PMBUS_VIRT_RESET_IOUT_HISTORY: 409 case PMBUS_VIRT_RESET_IOUT_HISTORY:
343 data->iout_max[page] = 0x7c00; 410 data->iout_max[page] = 0x7c00;
@@ -372,6 +439,7 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
372 439
373static const struct i2c_device_id ltc2978_id[] = { 440static const struct i2c_device_id ltc2978_id[] = {
374 {"ltc2974", ltc2974}, 441 {"ltc2974", ltc2974},
442 {"ltc2975", ltc2975},
375 {"ltc2977", ltc2977}, 443 {"ltc2977", ltc2977},
376 {"ltc2978", ltc2978}, 444 {"ltc2978", ltc2978},
377 {"ltc3880", ltc3880}, 445 {"ltc3880", ltc3880},
@@ -428,6 +496,8 @@ static int ltc2978_get_id(struct i2c_client *client)
428 496
429 if (chip_id == LTC2974_ID_REV1 || chip_id == LTC2974_ID_REV2) 497 if (chip_id == LTC2974_ID_REV1 || chip_id == LTC2974_ID_REV2)
430 return ltc2974; 498 return ltc2974;
499 else if (chip_id == LTC2975_ID)
500 return ltc2975;
431 else if (chip_id == LTC2977_ID) 501 else if (chip_id == LTC2977_ID)
432 return ltc2977; 502 return ltc2977;
433 else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2 || 503 else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2 ||
@@ -505,6 +575,19 @@ static int ltc2978_probe(struct i2c_client *client,
505 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; 575 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
506 } 576 }
507 break; 577 break;
578 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;
508 case ltc2977: 591 case ltc2977:
509 case ltc2978: 592 case ltc2978:
510 info->read_word_data = ltc2978_read_word_data; 593 info->read_word_data = ltc2978_read_word_data;
@@ -576,6 +659,7 @@ static int ltc2978_probe(struct i2c_client *client,
576#ifdef CONFIG_OF 659#ifdef CONFIG_OF
577static const struct of_device_id ltc2978_of_match[] = { 660static const struct of_device_id ltc2978_of_match[] = {
578 { .compatible = "lltc,ltc2974" }, 661 { .compatible = "lltc,ltc2974" },
662 { .compatible = "lltc,ltc2975" },
579 { .compatible = "lltc,ltc2977" }, 663 { .compatible = "lltc,ltc2977" },
580 { .compatible = "lltc,ltc2978" }, 664 { .compatible = "lltc,ltc2978" },
581 { .compatible = "lltc,ltc3880" }, 665 { .compatible = "lltc,ltc3880" },
@@ -601,5 +685,5 @@ static struct i2c_driver ltc2978_driver = {
601module_i2c_driver(ltc2978_driver); 685module_i2c_driver(ltc2978_driver);
602 686
603MODULE_AUTHOR("Guenter Roeck"); 687MODULE_AUTHOR("Guenter Roeck");
604MODULE_DESCRIPTION("PMBus driver for LTC2974, LTC2978, LTC3880, LTC3883, and LTM4676"); 688MODULE_DESCRIPTION("PMBus driver for LTC2978 and comppatible chips");
605MODULE_LICENSE("GPL"); 689MODULE_LICENSE("GPL");