aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2013-02-09 18:15:52 -0500
committerGuenter Roeck <linux@roeck-us.net>2013-04-08 00:16:41 -0400
commit58615a94f6a190f2fb9f9a99f1894d161c4b85b9 (patch)
treea610147e40dbe0af85e880b1ed866e91f9730bf4
parente53e6497fc9f071734c1794c3dc08bd5f334fa7f (diff)
hwmon: (pmbus/lm25066) Add support for LM25056
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--Documentation/hwmon/lm2506618
-rw-r--r--drivers/hwmon/pmbus/Kconfig2
-rw-r--r--drivers/hwmon/pmbus/lm25066.c132
3 files changed, 139 insertions, 13 deletions
diff --git a/Documentation/hwmon/lm25066 b/Documentation/hwmon/lm25066
index 2bc5ba6aee66..c1b57d72efc3 100644
--- a/Documentation/hwmon/lm25066
+++ b/Documentation/hwmon/lm25066
@@ -1,7 +1,13 @@
1Kernel driver max8688 1Kernel driver lm25066
2===================== 2=====================
3 3
4Supported chips: 4Supported chips:
5 * TI LM25056
6 Prefix: 'lm25056'
7 Addresses scanned: -
8 Datasheets:
9 http://www.ti.com/lit/gpn/lm25056
10 http://www.ti.com/lit/gpn/lm25056a
5 * National Semiconductor LM25066 11 * National Semiconductor LM25066
6 Prefix: 'lm25066' 12 Prefix: 'lm25066'
7 Addresses scanned: - 13 Addresses scanned: -
@@ -25,8 +31,9 @@ Author: Guenter Roeck <linux@roeck-us.net>
25Description 31Description
26----------- 32-----------
27 33
28This driver supports hardware montoring for National Semiconductor LM25066, 34This driver supports hardware montoring for National Semiconductor / TI LM25056,
29LM5064, and LM5064 Power Management, Monitoring, Control, and Protection ICs. 35LM25066, LM5064, and LM5064 Power Management, Monitoring, Control, and
36Protection ICs.
30 37
31The driver is a client driver to the core PMBus driver. Please see 38The driver is a client driver to the core PMBus driver. Please see
32Documentation/hwmon/pmbus for details on PMBus client drivers. 39Documentation/hwmon/pmbus for details on PMBus client drivers.
@@ -62,8 +69,13 @@ in1_max_alarm Input voltage high alarm.
62 69
63in2_label "vmon" 70in2_label "vmon"
64in2_input Measured voltage on VAUX pin 71in2_input Measured voltage on VAUX pin
72in2_min Minimum VAUX voltage (LM25056 only).
73in2_max Maximum VAUX voltage (LM25056 only).
74in2_min_alarm VAUX voltage low alarm (LM25056 only).
75in2_max_alarm VAUX voltage high alarm (LM25056 only).
65 76
66in3_label "vout1" 77in3_label "vout1"
78 Not supported on LM25056.
67in3_input Measured output voltage. 79in3_input Measured output voltage.
68in3_average Average measured output voltage. 80in3_average Average measured output voltage.
69in3_min Minimum output voltage. 81in3_min Minimum output voltage.
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index b1adad60d6ad..39cc63edfbb0 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -42,7 +42,7 @@ config SENSORS_LM25066
42 default n 42 default n
43 help 43 help
44 If you say yes here you get hardware monitoring support for National 44 If you say yes here you get hardware monitoring support for National
45 Semiconductor LM25066, LM5064, and LM5066. 45 Semiconductor LM25056, LM25066, LM5064, and LM5066.
46 46
47 This driver can also be built as a module. If so, the module will 47 This driver can also be built as a module. If so, the module will
48 be called lm25066. 48 be called lm25066.
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c
index 08267149dc63..6a9d6edaacb3 100644
--- a/drivers/hwmon/pmbus/lm25066.c
+++ b/drivers/hwmon/pmbus/lm25066.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Hardware monitoring driver for LM25066 / LM5064 / LM5066 2 * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066
3 * 3 *
4 * Copyright (c) 2011 Ericsson AB. 4 * Copyright (c) 2011 Ericsson AB.
5 * Copyright (c) 2013 Guenter Roeck 5 * Copyright (c) 2013 Guenter Roeck
@@ -27,7 +27,7 @@
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include "pmbus.h" 28#include "pmbus.h"
29 29
30enum chips { lm25066, lm5064, lm5066 }; 30enum chips { lm25056, lm25066, lm5064, lm5066 };
31 31
32#define LM25066_READ_VAUX 0xd0 32#define LM25066_READ_VAUX 0xd0
33#define LM25066_MFR_READ_IIN 0xd1 33#define LM25066_MFR_READ_IIN 0xd1
@@ -44,6 +44,14 @@ enum chips { lm25066, lm5064, lm5066 };
44 44
45#define LM25066_DEV_SETUP_CL (1 << 4) /* Current limit */ 45#define LM25066_DEV_SETUP_CL (1 << 4) /* Current limit */
46 46
47/* LM25056 only */
48
49#define LM25056_VAUX_OV_WARN_LIMIT 0xe3
50#define LM25056_VAUX_UV_WARN_LIMIT 0xe4
51
52#define LM25056_MFR_STS_VAUX_OV_WARN (1 << 1)
53#define LM25056_MFR_STS_VAUX_UV_WARN (1 << 0)
54
47struct __coeff { 55struct __coeff {
48 short m, b, R; 56 short m, b, R;
49}; 57};
@@ -51,7 +59,34 @@ struct __coeff {
51#define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) 59#define PSC_CURRENT_IN_L (PSC_NUM_CLASSES)
52#define PSC_POWER_L (PSC_NUM_CLASSES + 1) 60#define PSC_POWER_L (PSC_NUM_CLASSES + 1)
53 61
54static struct __coeff lm25066_coeff[3][PSC_NUM_CLASSES + 2] = { 62static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = {
63 [lm25056] = {
64 [PSC_VOLTAGE_IN] = {
65 .m = 16296,
66 .R = -2,
67 },
68 [PSC_CURRENT_IN] = {
69 .m = 13797,
70 .R = -2,
71 },
72 [PSC_CURRENT_IN_L] = {
73 .m = 6726,
74 .R = -2,
75 },
76 [PSC_POWER] = {
77 .m = 5501,
78 .R = -3,
79 },
80 [PSC_POWER_L] = {
81 .m = 26882,
82 .R = -4,
83 },
84 [PSC_TEMPERATURE] = {
85 .m = 1580,
86 .b = -14500,
87 .R = -2,
88 },
89 },
55 [lm25066] = { 90 [lm25066] = {
56 [PSC_VOLTAGE_IN] = { 91 [PSC_VOLTAGE_IN] = {
57 .m = 22070, 92 .m = 22070,
@@ -161,6 +196,10 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg)
161 break; 196 break;
162 /* Adjust returned value to match VIN coefficients */ 197 /* Adjust returned value to match VIN coefficients */
163 switch (data->id) { 198 switch (data->id) {
199 case lm25056:
200 /* VIN: 6.14 mV VAUX: 293 uV LSB */
201 ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
202 break;
164 case lm25066: 203 case lm25066:
165 /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ 204 /* VIN: 4.54 mV VAUX: 283.2 uV LSB */
166 ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); 205 ret = DIV_ROUND_CLOSEST(ret * 2832, 45400);
@@ -214,6 +253,58 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg)
214 return ret; 253 return ret;
215} 254}
216 255
256static int lm25056_read_word_data(struct i2c_client *client, int page, int reg)
257{
258 int ret;
259
260 switch (reg) {
261 case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
262 ret = pmbus_read_word_data(client, 0,
263 LM25056_VAUX_UV_WARN_LIMIT);
264 if (ret < 0)
265 break;
266 /* Adjust returned value to match VIN coefficients */
267 ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
268 break;
269 case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
270 ret = pmbus_read_word_data(client, 0,
271 LM25056_VAUX_OV_WARN_LIMIT);
272 if (ret < 0)
273 break;
274 /* Adjust returned value to match VIN coefficients */
275 ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
276 break;
277 default:
278 ret = lm25066_read_word_data(client, page, reg);
279 break;
280 }
281 return ret;
282}
283
284static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg)
285{
286 int ret, s;
287
288 switch (reg) {
289 case PMBUS_VIRT_STATUS_VMON:
290 ret = pmbus_read_byte_data(client, 0,
291 PMBUS_STATUS_MFR_SPECIFIC);
292 if (ret < 0)
293 break;
294 s = 0;
295 if (ret & LM25056_MFR_STS_VAUX_UV_WARN)
296 s |= PB_VOLTAGE_UV_WARNING;
297 if (ret & LM25056_MFR_STS_VAUX_OV_WARN)
298 s |= PB_VOLTAGE_OV_WARNING;
299 ret = s;
300 break;
301 default:
302 ret = -ENODATA;
303 break;
304 }
305 return ret;
306}
307
217static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, 308static int lm25066_write_word_data(struct i2c_client *client, int page, int reg,
218 u16 word) 309 u16 word)
219{ 310{
@@ -243,6 +334,22 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg,
243 word); 334 word);
244 pmbus_clear_cache(client); 335 pmbus_clear_cache(client);
245 break; 336 break;
337 case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
338 /* Adjust from VIN coefficients (for LM25056) */
339 word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
340 word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff);
341 ret = pmbus_write_word_data(client, 0,
342 LM25056_VAUX_UV_WARN_LIMIT, word);
343 pmbus_clear_cache(client);
344 break;
345 case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
346 /* Adjust from VIN coefficients (for LM25056) */
347 word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
348 word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff);
349 ret = pmbus_write_word_data(client, 0,
350 LM25056_VAUX_OV_WARN_LIMIT, word);
351 pmbus_clear_cache(client);
352 break;
246 case PMBUS_VIRT_RESET_PIN_HISTORY: 353 case PMBUS_VIRT_RESET_PIN_HISTORY:
247 ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK); 354 ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK);
248 break; 355 break;
@@ -284,12 +391,18 @@ static int lm25066_probe(struct i2c_client *client,
284 info->format[PSC_TEMPERATURE] = direct; 391 info->format[PSC_TEMPERATURE] = direct;
285 info->format[PSC_POWER] = direct; 392 info->format[PSC_POWER] = direct;
286 393
394 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON
395 | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT
396 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
287 397
288 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON | PMBUS_HAVE_VOUT 398 if (data->id == lm25056) {
289 | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN 399 info->func[0] |= PMBUS_HAVE_STATUS_VMON;
290 | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; 400 info->read_word_data = lm25056_read_word_data;
291 401 info->read_byte_data = lm25056_read_byte_data;
292 info->read_word_data = lm25066_read_word_data; 402 } else {
403 info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
404 info->read_word_data = lm25066_read_word_data;
405 }
293 info->write_word_data = lm25066_write_word_data; 406 info->write_word_data = lm25066_write_word_data;
294 407
295 coeff = &lm25066_coeff[data->id][0]; 408 coeff = &lm25066_coeff[data->id][0];
@@ -318,6 +431,7 @@ static int lm25066_probe(struct i2c_client *client,
318} 431}
319 432
320static const struct i2c_device_id lm25066_id[] = { 433static const struct i2c_device_id lm25066_id[] = {
434 {"lm25056", lm25056},
321 {"lm25066", lm25066}, 435 {"lm25066", lm25066},
322 {"lm5064", lm5064}, 436 {"lm5064", lm5064},
323 {"lm5066", lm5066}, 437 {"lm5066", lm5066},
@@ -339,5 +453,5 @@ static struct i2c_driver lm25066_driver = {
339module_i2c_driver(lm25066_driver); 453module_i2c_driver(lm25066_driver);
340 454
341MODULE_AUTHOR("Guenter Roeck"); 455MODULE_AUTHOR("Guenter Roeck");
342MODULE_DESCRIPTION("PMBus driver for LM25066/LM5064/LM5066"); 456MODULE_DESCRIPTION("PMBus driver for LM25056/LM25066/LM5064/LM5066");
343MODULE_LICENSE("GPL"); 457MODULE_LICENSE("GPL");