diff options
author | Guenter Roeck <linux@roeck-us.net> | 2015-07-05 14:04:56 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2016-03-05 09:36:03 -0500 |
commit | 709066acdd12c3312c94ebccc37630932e381949 (patch) | |
tree | d8111e43114f762136eb596c16bf13760122af1f /drivers/hwmon/pmbus | |
parent | 54ce3a0d801142c96935122736a46c08d15d83b5 (diff) |
hwmon: (adm1275) Add support for ADM1278
ADM1278 is mostly compatible to other chips of the same series.
Besides the usual difference in coefficients, it supports
a temperature sensor, and it can measure both input and output
voltage at the same time.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/pmbus')
-rw-r--r-- | drivers/hwmon/pmbus/Kconfig | 4 | ||||
-rw-r--r-- | drivers/hwmon/pmbus/adm1275.c | 56 |
2 files changed, 57 insertions, 3 deletions
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 7e5cc3d025ef..054d3d863802 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
@@ -31,8 +31,8 @@ config SENSORS_ADM1275 | |||
31 | default n | 31 | default n |
32 | help | 32 | help |
33 | If you say yes here you get hardware monitoring support for Analog | 33 | If you say yes here you get hardware monitoring support for Analog |
34 | Devices ADM1075, ADM1275, ADM1276, ADM1293, and ADM1294 Hot-Swap | 34 | Devices ADM1075, ADM1275, ADM1276, ADM1278, ADM1293, and ADM1294 |
35 | Controller and Digital Power Monitors. | 35 | Hot-Swap Controller and Digital Power Monitors. |
36 | 36 | ||
37 | This driver can also be built as a module. If so, the module will | 37 | This driver can also be built as a module. If so, the module will |
38 | be called adm1275. | 38 | be called adm1275. |
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 188af4c89f40..3baa4f4a8c5e 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
25 | #include "pmbus.h" | 25 | #include "pmbus.h" |
26 | 26 | ||
27 | enum chips { adm1075, adm1275, adm1276, adm1293, adm1294 }; | 27 | enum chips { adm1075, adm1275, adm1276, adm1278, adm1293, adm1294 }; |
28 | 28 | ||
29 | #define ADM1275_MFR_STATUS_IOUT_WARN2 BIT(0) | 29 | #define ADM1275_MFR_STATUS_IOUT_WARN2 BIT(0) |
30 | #define ADM1293_MFR_STATUS_VAUX_UV_WARN BIT(5) | 30 | #define ADM1293_MFR_STATUS_VAUX_UV_WARN BIT(5) |
@@ -41,6 +41,10 @@ enum chips { adm1075, adm1275, adm1276, adm1293, adm1294 }; | |||
41 | #define ADM1075_IRANGE_25 BIT(3) | 41 | #define ADM1075_IRANGE_25 BIT(3) |
42 | #define ADM1075_IRANGE_MASK (BIT(3) | BIT(4)) | 42 | #define ADM1075_IRANGE_MASK (BIT(3) | BIT(4)) |
43 | 43 | ||
44 | #define ADM1278_TEMP1_EN BIT(3) | ||
45 | #define ADM1278_VIN_EN BIT(2) | ||
46 | #define ADM1278_VOUT_EN BIT(1) | ||
47 | |||
44 | #define ADM1293_IRANGE_25 0 | 48 | #define ADM1293_IRANGE_25 0 |
45 | #define ADM1293_IRANGE_50 BIT(6) | 49 | #define ADM1293_IRANGE_50 BIT(6) |
46 | #define ADM1293_IRANGE_100 BIT(7) | 50 | #define ADM1293_IRANGE_100 BIT(7) |
@@ -54,6 +58,7 @@ enum chips { adm1075, adm1275, adm1276, adm1293, adm1294 }; | |||
54 | 58 | ||
55 | #define ADM1293_VAUX_EN BIT(1) | 59 | #define ADM1293_VAUX_EN BIT(1) |
56 | 60 | ||
61 | #define ADM1278_PEAK_TEMP 0xd7 | ||
57 | #define ADM1275_IOUT_WARN2_LIMIT 0xd7 | 62 | #define ADM1275_IOUT_WARN2_LIMIT 0xd7 |
58 | #define ADM1275_DEVICE_CONFIG 0xd8 | 63 | #define ADM1275_DEVICE_CONFIG 0xd8 |
59 | 64 | ||
@@ -80,6 +85,7 @@ struct adm1275_data { | |||
80 | bool have_iout_min; | 85 | bool have_iout_min; |
81 | bool have_pin_min; | 86 | bool have_pin_min; |
82 | bool have_pin_max; | 87 | bool have_pin_max; |
88 | bool have_temp_max; | ||
83 | struct pmbus_driver_info info; | 89 | struct pmbus_driver_info info; |
84 | }; | 90 | }; |
85 | 91 | ||
@@ -113,6 +119,13 @@ static const struct coefficients adm1276_coefficients[] = { | |||
113 | [4] = { 2115, 0, -1 }, /* power, vrange not set */ | 119 | [4] = { 2115, 0, -1 }, /* power, vrange not set */ |
114 | }; | 120 | }; |
115 | 121 | ||
122 | static const struct coefficients adm1278_coefficients[] = { | ||
123 | [0] = { 19599, 0, -2 }, /* voltage */ | ||
124 | [1] = { 800, 20475, -1 }, /* current */ | ||
125 | [2] = { 6123, 0, -2 }, /* power */ | ||
126 | [3] = { 42, 31880, -1 }, /* temperature */ | ||
127 | }; | ||
128 | |||
116 | static const struct coefficients adm1293_coefficients[] = { | 129 | static const struct coefficients adm1293_coefficients[] = { |
117 | [0] = { 3333, -1, 0 }, /* voltage, vrange 1.2V */ | 130 | [0] = { 3333, -1, 0 }, /* voltage, vrange 1.2V */ |
118 | [1] = { 5552, -5, -1 }, /* voltage, vrange 7.4V */ | 131 | [1] = { 5552, -5, -1 }, /* voltage, vrange 7.4V */ |
@@ -196,6 +209,11 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) | |||
196 | return -ENXIO; | 209 | return -ENXIO; |
197 | ret = pmbus_read_word_data(client, 0, ADM1276_PEAK_PIN); | 210 | ret = pmbus_read_word_data(client, 0, ADM1276_PEAK_PIN); |
198 | break; | 211 | break; |
212 | case PMBUS_VIRT_READ_TEMP_MAX: | ||
213 | if (!data->have_temp_max) | ||
214 | return -ENXIO; | ||
215 | ret = pmbus_read_word_data(client, 0, ADM1278_PEAK_TEMP); | ||
216 | break; | ||
199 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | 217 | case PMBUS_VIRT_RESET_IOUT_HISTORY: |
200 | case PMBUS_VIRT_RESET_VOUT_HISTORY: | 218 | case PMBUS_VIRT_RESET_VOUT_HISTORY: |
201 | case PMBUS_VIRT_RESET_VIN_HISTORY: | 219 | case PMBUS_VIRT_RESET_VIN_HISTORY: |
@@ -204,6 +222,10 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) | |||
204 | if (!data->have_pin_max) | 222 | if (!data->have_pin_max) |
205 | return -ENXIO; | 223 | return -ENXIO; |
206 | break; | 224 | break; |
225 | case PMBUS_VIRT_RESET_TEMP_HISTORY: | ||
226 | if (!data->have_temp_max) | ||
227 | return -ENXIO; | ||
228 | break; | ||
207 | default: | 229 | default: |
208 | ret = -ENODATA; | 230 | ret = -ENODATA; |
209 | break; | 231 | break; |
@@ -245,6 +267,9 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg, | |||
245 | ret = pmbus_write_word_data(client, 0, | 267 | ret = pmbus_write_word_data(client, 0, |
246 | ADM1293_PIN_MIN, 0); | 268 | ADM1293_PIN_MIN, 0); |
247 | break; | 269 | break; |
270 | case PMBUS_VIRT_RESET_TEMP_HISTORY: | ||
271 | ret = pmbus_write_word_data(client, 0, ADM1278_PEAK_TEMP, 0); | ||
272 | break; | ||
248 | default: | 273 | default: |
249 | ret = -ENODATA; | 274 | ret = -ENODATA; |
250 | break; | 275 | break; |
@@ -312,6 +337,7 @@ static const struct i2c_device_id adm1275_id[] = { | |||
312 | { "adm1075", adm1075 }, | 337 | { "adm1075", adm1075 }, |
313 | { "adm1275", adm1275 }, | 338 | { "adm1275", adm1275 }, |
314 | { "adm1276", adm1276 }, | 339 | { "adm1276", adm1276 }, |
340 | { "adm1278", adm1278 }, | ||
315 | { "adm1293", adm1293 }, | 341 | { "adm1293", adm1293 }, |
316 | { "adm1294", adm1294 }, | 342 | { "adm1294", adm1294 }, |
317 | { } | 343 | { } |
@@ -329,6 +355,7 @@ static int adm1275_probe(struct i2c_client *client, | |||
329 | const struct i2c_device_id *mid; | 355 | const struct i2c_device_id *mid; |
330 | const struct coefficients *coefficients; | 356 | const struct coefficients *coefficients; |
331 | int vindex = -1, voindex = -1, cindex = -1, pindex = -1; | 357 | int vindex = -1, voindex = -1, cindex = -1, pindex = -1; |
358 | int tindex = -1; | ||
332 | 359 | ||
333 | if (!i2c_check_functionality(client->adapter, | 360 | if (!i2c_check_functionality(client->adapter, |
334 | I2C_FUNC_SMBUS_READ_BYTE_DATA | 361 | I2C_FUNC_SMBUS_READ_BYTE_DATA |
@@ -386,6 +413,7 @@ static int adm1275_probe(struct i2c_client *client, | |||
386 | info->format[PSC_VOLTAGE_OUT] = direct; | 413 | info->format[PSC_VOLTAGE_OUT] = direct; |
387 | info->format[PSC_CURRENT_OUT] = direct; | 414 | info->format[PSC_CURRENT_OUT] = direct; |
388 | info->format[PSC_POWER] = direct; | 415 | info->format[PSC_POWER] = direct; |
416 | info->format[PSC_TEMPERATURE] = direct; | ||
389 | info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | 417 | info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; |
390 | 418 | ||
391 | info->read_word_data = adm1275_read_word_data; | 419 | info->read_word_data = adm1275_read_word_data; |
@@ -460,6 +488,27 @@ static int adm1275_probe(struct i2c_client *client, | |||
460 | info->func[0] |= | 488 | info->func[0] |= |
461 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | 489 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; |
462 | break; | 490 | break; |
491 | case adm1278: | ||
492 | data->have_vout = true; | ||
493 | data->have_pin_max = true; | ||
494 | data->have_temp_max = true; | ||
495 | |||
496 | coefficients = adm1278_coefficients; | ||
497 | vindex = 0; | ||
498 | cindex = 1; | ||
499 | pindex = 2; | ||
500 | tindex = 3; | ||
501 | |||
502 | info->func[0] |= PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT; | ||
503 | if (config & ADM1278_TEMP1_EN) | ||
504 | info->func[0] |= | ||
505 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | ||
506 | if (config & ADM1278_VIN_EN) | ||
507 | info->func[0] |= PMBUS_HAVE_VIN; | ||
508 | if (config & ADM1278_VOUT_EN) | ||
509 | info->func[0] |= | ||
510 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | ||
511 | break; | ||
463 | case adm1293: | 512 | case adm1293: |
464 | case adm1294: | 513 | case adm1294: |
465 | data->have_iout_min = true; | 514 | data->have_iout_min = true; |
@@ -537,6 +586,11 @@ static int adm1275_probe(struct i2c_client *client, | |||
537 | info->b[PSC_POWER] = coefficients[pindex].b; | 586 | info->b[PSC_POWER] = coefficients[pindex].b; |
538 | info->R[PSC_POWER] = coefficients[pindex].R; | 587 | info->R[PSC_POWER] = coefficients[pindex].R; |
539 | } | 588 | } |
589 | if (tindex >= 0) { | ||
590 | info->m[PSC_TEMPERATURE] = coefficients[tindex].m; | ||
591 | info->b[PSC_TEMPERATURE] = coefficients[tindex].b; | ||
592 | info->R[PSC_TEMPERATURE] = coefficients[tindex].R; | ||
593 | } | ||
540 | 594 | ||
541 | return pmbus_do_probe(client, id, info); | 595 | return pmbus_do_probe(client, id, info); |
542 | } | 596 | } |