diff options
author | Guenter Roeck <linux@roeck-us.net> | 2013-03-16 13:25:04 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2013-10-18 12:12:02 -0400 |
commit | c8ccab7ab5c71b4fab274bfd18425503a4dcc288 (patch) | |
tree | 2855cfb80fa9c3afe7baedb5f2e827f09d139f56 | |
parent | 84fb029faa05e1de229a68829cca5dcf85c79894 (diff) |
hwmon: (pmbus/lm25066) Add support for LM25063
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | Documentation/hwmon/lm25066 | 20 | ||||
-rw-r--r-- | drivers/hwmon/pmbus/lm25066.c | 91 |
2 files changed, 101 insertions, 10 deletions
diff --git a/Documentation/hwmon/lm25066 b/Documentation/hwmon/lm25066 index c1b57d72efc3..b34c3de5c1bc 100644 --- a/Documentation/hwmon/lm25066 +++ b/Documentation/hwmon/lm25066 | |||
@@ -8,6 +8,11 @@ Supported chips: | |||
8 | Datasheets: | 8 | Datasheets: |
9 | http://www.ti.com/lit/gpn/lm25056 | 9 | http://www.ti.com/lit/gpn/lm25056 |
10 | http://www.ti.com/lit/gpn/lm25056a | 10 | http://www.ti.com/lit/gpn/lm25056a |
11 | * TI LM25063 | ||
12 | Prefix: 'lm25063' | ||
13 | Addresses scanned: - | ||
14 | Datasheet: | ||
15 | To be announced | ||
11 | * National Semiconductor LM25066 | 16 | * National Semiconductor LM25066 |
12 | Prefix: 'lm25066' | 17 | Prefix: 'lm25066' |
13 | Addresses scanned: - | 18 | Addresses scanned: - |
@@ -32,7 +37,7 @@ Description | |||
32 | ----------- | 37 | ----------- |
33 | 38 | ||
34 | This driver supports hardware montoring for National Semiconductor / TI LM25056, | 39 | This driver supports hardware montoring for National Semiconductor / TI LM25056, |
35 | LM25066, LM5064, and LM5064 Power Management, Monitoring, Control, and | 40 | LM25063, LM25066, LM5064, and LM5066 Power Management, Monitoring, Control, and |
36 | Protection ICs. | 41 | Protection ICs. |
37 | 42 | ||
38 | The driver is a client driver to the core PMBus driver. Please see | 43 | The driver is a client driver to the core PMBus driver. Please see |
@@ -64,8 +69,12 @@ in1_input Measured input voltage. | |||
64 | in1_average Average measured input voltage. | 69 | in1_average Average measured input voltage. |
65 | in1_min Minimum input voltage. | 70 | in1_min Minimum input voltage. |
66 | in1_max Maximum input voltage. | 71 | in1_max Maximum input voltage. |
72 | in1_crit Critical high input voltage (LM25063 only). | ||
73 | in1_lcrit Critical low input voltage (LM25063 only). | ||
67 | in1_min_alarm Input voltage low alarm. | 74 | in1_min_alarm Input voltage low alarm. |
68 | in1_max_alarm Input voltage high alarm. | 75 | in1_max_alarm Input voltage high alarm. |
76 | in1_lcrit_alarm Input voltage critical low alarm (LM25063 only). | ||
77 | in1_crit_alarm Input voltage critical high alarm. (LM25063 only). | ||
69 | 78 | ||
70 | in2_label "vmon" | 79 | in2_label "vmon" |
71 | in2_input Measured voltage on VAUX pin | 80 | in2_input Measured voltage on VAUX pin |
@@ -80,12 +89,16 @@ in3_input Measured output voltage. | |||
80 | in3_average Average measured output voltage. | 89 | in3_average Average measured output voltage. |
81 | in3_min Minimum output voltage. | 90 | in3_min Minimum output voltage. |
82 | in3_min_alarm Output voltage low alarm. | 91 | in3_min_alarm Output voltage low alarm. |
92 | in3_highest Historical minimum output voltage (LM25063 only). | ||
93 | in3_lowest Historical maximum output voltage (LM25063 only). | ||
83 | 94 | ||
84 | curr1_label "iin" | 95 | curr1_label "iin" |
85 | curr1_input Measured input current. | 96 | curr1_input Measured input current. |
86 | curr1_average Average measured input current. | 97 | curr1_average Average measured input current. |
87 | curr1_max Maximum input current. | 98 | curr1_max Maximum input current. |
99 | curr1_crit Critical input current (LM25063 only). | ||
88 | curr1_max_alarm Input current high alarm. | 100 | curr1_max_alarm Input current high alarm. |
101 | curr1_crit_alarm Input current critical high alarm (LM25063 only). | ||
89 | 102 | ||
90 | power1_label "pin" | 103 | power1_label "pin" |
91 | power1_input Measured input power. | 104 | power1_input Measured input power. |
@@ -95,6 +108,11 @@ power1_alarm Input power alarm | |||
95 | power1_input_highest Historical maximum power. | 108 | power1_input_highest Historical maximum power. |
96 | power1_reset_history Write any value to reset maximum power history. | 109 | power1_reset_history Write any value to reset maximum power history. |
97 | 110 | ||
111 | power2_label "pout". LM25063 only. | ||
112 | power2_input Measured output power. | ||
113 | power2_max Maximum output power limit. | ||
114 | power2_crit Critical output power limit. | ||
115 | |||
98 | temp1_input Measured temperature. | 116 | temp1_input Measured temperature. |
99 | temp1_max Maximum temperature. | 117 | temp1_max Maximum temperature. |
100 | temp1_crit Critical high temperature. | 118 | temp1_crit Critical high temperature. |
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index 6a9d6edaacb3..a26b1d1d9514 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066 | 2 | * Hardware monitoring driver for LM25056 / LM25063 / 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 | ||
30 | enum chips { lm25056, lm25066, lm5064, lm5066 }; | 30 | enum chips { lm25056, lm25063, 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 |
@@ -52,6 +52,11 @@ enum chips { lm25056, lm25066, lm5064, lm5066 }; | |||
52 | #define LM25056_MFR_STS_VAUX_OV_WARN (1 << 1) | 52 | #define LM25056_MFR_STS_VAUX_OV_WARN (1 << 1) |
53 | #define LM25056_MFR_STS_VAUX_UV_WARN (1 << 0) | 53 | #define LM25056_MFR_STS_VAUX_UV_WARN (1 << 0) |
54 | 54 | ||
55 | /* LM25063 only */ | ||
56 | |||
57 | #define LM25063_READ_VOUT_MAX 0xe5 | ||
58 | #define LM25063_READ_VOUT_MIN 0xe6 | ||
59 | |||
55 | struct __coeff { | 60 | struct __coeff { |
56 | short m, b, R; | 61 | short m, b, R; |
57 | }; | 62 | }; |
@@ -59,7 +64,7 @@ struct __coeff { | |||
59 | #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) | 64 | #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) |
60 | #define PSC_POWER_L (PSC_NUM_CLASSES + 1) | 65 | #define PSC_POWER_L (PSC_NUM_CLASSES + 1) |
61 | 66 | ||
62 | static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { | 67 | static struct __coeff lm25066_coeff[5][PSC_NUM_CLASSES + 2] = { |
63 | [lm25056] = { | 68 | [lm25056] = { |
64 | [PSC_VOLTAGE_IN] = { | 69 | [PSC_VOLTAGE_IN] = { |
65 | .m = 16296, | 70 | .m = 16296, |
@@ -116,6 +121,36 @@ static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { | |||
116 | .m = 16, | 121 | .m = 16, |
117 | }, | 122 | }, |
118 | }, | 123 | }, |
124 | [lm25063] = { | ||
125 | [PSC_VOLTAGE_IN] = { | ||
126 | .m = 16000, | ||
127 | .R = -2, | ||
128 | }, | ||
129 | [PSC_VOLTAGE_OUT] = { | ||
130 | .m = 16000, | ||
131 | .R = -2, | ||
132 | }, | ||
133 | [PSC_CURRENT_IN] = { | ||
134 | .m = 10000, | ||
135 | .R = -2, | ||
136 | }, | ||
137 | [PSC_CURRENT_IN_L] = { | ||
138 | .m = 10000, | ||
139 | .R = -2, | ||
140 | }, | ||
141 | [PSC_POWER] = { | ||
142 | .m = 5000, | ||
143 | .R = -3, | ||
144 | }, | ||
145 | [PSC_POWER_L] = { | ||
146 | .m = 5000, | ||
147 | .R = -3, | ||
148 | }, | ||
149 | [PSC_TEMPERATURE] = { | ||
150 | .m = 15596, | ||
151 | .R = -3, | ||
152 | }, | ||
153 | }, | ||
119 | [lm5064] = { | 154 | [lm5064] = { |
120 | [PSC_VOLTAGE_IN] = { | 155 | [PSC_VOLTAGE_IN] = { |
121 | .m = 4611, | 156 | .m = 4611, |
@@ -178,6 +213,7 @@ static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { | |||
178 | 213 | ||
179 | struct lm25066_data { | 214 | struct lm25066_data { |
180 | int id; | 215 | int id; |
216 | u16 rlimit; /* Maximum register value */ | ||
181 | struct pmbus_driver_info info; | 217 | struct pmbus_driver_info info; |
182 | }; | 218 | }; |
183 | 219 | ||
@@ -200,6 +236,10 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
200 | /* VIN: 6.14 mV VAUX: 293 uV LSB */ | 236 | /* VIN: 6.14 mV VAUX: 293 uV LSB */ |
201 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); | 237 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); |
202 | break; | 238 | break; |
239 | case lm25063: | ||
240 | /* VIN: 6.25 mV VAUX: 200.0 uV LSB */ | ||
241 | ret = DIV_ROUND_CLOSEST(ret * 20, 625); | ||
242 | break; | ||
203 | case lm25066: | 243 | case lm25066: |
204 | /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ | 244 | /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ |
205 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); | 245 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); |
@@ -253,6 +293,24 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
253 | return ret; | 293 | return ret; |
254 | } | 294 | } |
255 | 295 | ||
296 | static int lm25063_read_word_data(struct i2c_client *client, int page, int reg) | ||
297 | { | ||
298 | int ret; | ||
299 | |||
300 | switch (reg) { | ||
301 | case PMBUS_VIRT_READ_VOUT_MAX: | ||
302 | ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MAX); | ||
303 | break; | ||
304 | case PMBUS_VIRT_READ_VOUT_MIN: | ||
305 | ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MIN); | ||
306 | break; | ||
307 | default: | ||
308 | ret = lm25066_read_word_data(client, page, reg); | ||
309 | break; | ||
310 | } | ||
311 | return ret; | ||
312 | } | ||
313 | |||
256 | static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) | 314 | static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) |
257 | { | 315 | { |
258 | int ret; | 316 | int ret; |
@@ -308,27 +366,34 @@ static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg) | |||
308 | static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | 366 | static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, |
309 | u16 word) | 367 | u16 word) |
310 | { | 368 | { |
369 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
370 | const struct lm25066_data *data = to_lm25066_data(info); | ||
311 | int ret; | 371 | int ret; |
312 | 372 | ||
313 | switch (reg) { | 373 | switch (reg) { |
374 | case PMBUS_POUT_OP_FAULT_LIMIT: | ||
375 | case PMBUS_POUT_OP_WARN_LIMIT: | ||
314 | case PMBUS_VOUT_UV_WARN_LIMIT: | 376 | case PMBUS_VOUT_UV_WARN_LIMIT: |
315 | case PMBUS_OT_FAULT_LIMIT: | 377 | case PMBUS_OT_FAULT_LIMIT: |
316 | case PMBUS_OT_WARN_LIMIT: | 378 | case PMBUS_OT_WARN_LIMIT: |
379 | case PMBUS_IIN_OC_FAULT_LIMIT: | ||
317 | case PMBUS_VIN_UV_WARN_LIMIT: | 380 | case PMBUS_VIN_UV_WARN_LIMIT: |
381 | case PMBUS_VIN_UV_FAULT_LIMIT: | ||
382 | case PMBUS_VIN_OV_FAULT_LIMIT: | ||
318 | case PMBUS_VIN_OV_WARN_LIMIT: | 383 | case PMBUS_VIN_OV_WARN_LIMIT: |
319 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 384 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
320 | ret = pmbus_write_word_data(client, 0, reg, word); | 385 | ret = pmbus_write_word_data(client, 0, reg, word); |
321 | pmbus_clear_cache(client); | 386 | pmbus_clear_cache(client); |
322 | break; | 387 | break; |
323 | case PMBUS_IIN_OC_WARN_LIMIT: | 388 | case PMBUS_IIN_OC_WARN_LIMIT: |
324 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 389 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
325 | ret = pmbus_write_word_data(client, 0, | 390 | ret = pmbus_write_word_data(client, 0, |
326 | LM25066_MFR_IIN_OC_WARN_LIMIT, | 391 | LM25066_MFR_IIN_OC_WARN_LIMIT, |
327 | word); | 392 | word); |
328 | pmbus_clear_cache(client); | 393 | pmbus_clear_cache(client); |
329 | break; | 394 | break; |
330 | case PMBUS_PIN_OP_WARN_LIMIT: | 395 | case PMBUS_PIN_OP_WARN_LIMIT: |
331 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 396 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
332 | ret = pmbus_write_word_data(client, 0, | 397 | ret = pmbus_write_word_data(client, 0, |
333 | LM25066_MFR_PIN_OP_WARN_LIMIT, | 398 | LM25066_MFR_PIN_OP_WARN_LIMIT, |
334 | word); | 399 | word); |
@@ -337,7 +402,7 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | |||
337 | case PMBUS_VIRT_VMON_UV_WARN_LIMIT: | 402 | case PMBUS_VIRT_VMON_UV_WARN_LIMIT: |
338 | /* Adjust from VIN coefficients (for LM25056) */ | 403 | /* Adjust from VIN coefficients (for LM25056) */ |
339 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); | 404 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); |
340 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 405 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
341 | ret = pmbus_write_word_data(client, 0, | 406 | ret = pmbus_write_word_data(client, 0, |
342 | LM25056_VAUX_UV_WARN_LIMIT, word); | 407 | LM25056_VAUX_UV_WARN_LIMIT, word); |
343 | pmbus_clear_cache(client); | 408 | pmbus_clear_cache(client); |
@@ -345,7 +410,7 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | |||
345 | case PMBUS_VIRT_VMON_OV_WARN_LIMIT: | 410 | case PMBUS_VIRT_VMON_OV_WARN_LIMIT: |
346 | /* Adjust from VIN coefficients (for LM25056) */ | 411 | /* Adjust from VIN coefficients (for LM25056) */ |
347 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); | 412 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); |
348 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 413 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
349 | ret = pmbus_write_word_data(client, 0, | 414 | ret = pmbus_write_word_data(client, 0, |
350 | LM25056_VAUX_OV_WARN_LIMIT, word); | 415 | LM25056_VAUX_OV_WARN_LIMIT, word); |
351 | pmbus_clear_cache(client); | 416 | pmbus_clear_cache(client); |
@@ -399,9 +464,16 @@ static int lm25066_probe(struct i2c_client *client, | |||
399 | info->func[0] |= PMBUS_HAVE_STATUS_VMON; | 464 | info->func[0] |= PMBUS_HAVE_STATUS_VMON; |
400 | info->read_word_data = lm25056_read_word_data; | 465 | info->read_word_data = lm25056_read_word_data; |
401 | info->read_byte_data = lm25056_read_byte_data; | 466 | info->read_byte_data = lm25056_read_byte_data; |
467 | data->rlimit = 0x0fff; | ||
468 | } else if (data->id == lm25063) { | ||
469 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
470 | | PMBUS_HAVE_POUT; | ||
471 | info->read_word_data = lm25063_read_word_data; | ||
472 | data->rlimit = 0xffff; | ||
402 | } else { | 473 | } else { |
403 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | 474 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; |
404 | info->read_word_data = lm25066_read_word_data; | 475 | info->read_word_data = lm25066_read_word_data; |
476 | data->rlimit = 0x0fff; | ||
405 | } | 477 | } |
406 | info->write_word_data = lm25066_write_word_data; | 478 | info->write_word_data = lm25066_write_word_data; |
407 | 479 | ||
@@ -432,6 +504,7 @@ static int lm25066_probe(struct i2c_client *client, | |||
432 | 504 | ||
433 | static const struct i2c_device_id lm25066_id[] = { | 505 | static const struct i2c_device_id lm25066_id[] = { |
434 | {"lm25056", lm25056}, | 506 | {"lm25056", lm25056}, |
507 | {"lm25063", lm25063}, | ||
435 | {"lm25066", lm25066}, | 508 | {"lm25066", lm25066}, |
436 | {"lm5064", lm5064}, | 509 | {"lm5064", lm5064}, |
437 | {"lm5066", lm5066}, | 510 | {"lm5066", lm5066}, |
@@ -453,5 +526,5 @@ static struct i2c_driver lm25066_driver = { | |||
453 | module_i2c_driver(lm25066_driver); | 526 | module_i2c_driver(lm25066_driver); |
454 | 527 | ||
455 | MODULE_AUTHOR("Guenter Roeck"); | 528 | MODULE_AUTHOR("Guenter Roeck"); |
456 | MODULE_DESCRIPTION("PMBus driver for LM25056/LM25066/LM5064/LM5066"); | 529 | MODULE_DESCRIPTION("PMBus driver for LM25066 and compatible chips"); |
457 | MODULE_LICENSE("GPL"); | 530 | MODULE_LICENSE("GPL"); |