aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2015-03-17 16:19:51 -0400
committerGuenter Roeck <linux@roeck-us.net>2015-08-09 16:44:27 -0400
commit68a403823600fc9d8277f930981d3a013353b2fe (patch)
treeeaec5d7fe49ddf2c8182cc002894f4df15e9cad3 /drivers/hwmon
parent48065a138acb8435c60739ffa62622d69f61b712 (diff)
hwmon: (adm1275) Add support for ADM1293 and ADM1294
ADM1293 and ADM1294 are mostly compatible with other chips of the same series, but have more configuration options. There are also some differences in register details. 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/adm1275.c141
2 files changed, 135 insertions, 10 deletions
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 9f7dbd189c97..67901cb08f77 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -30,8 +30,8 @@ config SENSORS_ADM1275
30 default n 30 default n
31 help 31 help
32 If you say yes here you get hardware monitoring support for Analog 32 If you say yes here you get hardware monitoring support for Analog
33 Devices ADM1075, ADM1275, and ADM1276 Hot-Swap Controller and Digital 33 Devices ADM1075, ADM1275, ADM1276, ADM1293, and ADM1294 Hot-Swap
34 Power Monitors. 34 Controller and Digital Power Monitors.
35 35
36 This driver can also be built as a module. If so, the module will 36 This driver can also be built as a module. If so, the module will
37 be called adm1275. 37 be called adm1275.
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c
index 1c19a2ee415c..188af4c89f40 100644
--- a/drivers/hwmon/pmbus/adm1275.c
+++ b/drivers/hwmon/pmbus/adm1275.c
@@ -24,7 +24,11 @@
24#include <linux/bitops.h> 24#include <linux/bitops.h>
25#include "pmbus.h" 25#include "pmbus.h"
26 26
27enum chips { adm1075, adm1275, adm1276 }; 27enum chips { adm1075, adm1275, adm1276, adm1293, adm1294 };
28
29#define ADM1275_MFR_STATUS_IOUT_WARN2 BIT(0)
30#define ADM1293_MFR_STATUS_VAUX_UV_WARN BIT(5)
31#define ADM1293_MFR_STATUS_VAUX_OV_WARN BIT(6)
28 32
29#define ADM1275_PEAK_IOUT 0xd0 33#define ADM1275_PEAK_IOUT 0xd0
30#define ADM1275_PEAK_VIN 0xd1 34#define ADM1275_PEAK_VIN 0xd1
@@ -37,18 +41,30 @@ enum chips { adm1075, adm1275, adm1276 };
37#define ADM1075_IRANGE_25 BIT(3) 41#define ADM1075_IRANGE_25 BIT(3)
38#define ADM1075_IRANGE_MASK (BIT(3) | BIT(4)) 42#define ADM1075_IRANGE_MASK (BIT(3) | BIT(4))
39 43
44#define ADM1293_IRANGE_25 0
45#define ADM1293_IRANGE_50 BIT(6)
46#define ADM1293_IRANGE_100 BIT(7)
47#define ADM1293_IRANGE_200 (BIT(6) | BIT(7))
48#define ADM1293_IRANGE_MASK (BIT(6) | BIT(7))
49
50#define ADM1293_VIN_SEL_012 BIT(2)
51#define ADM1293_VIN_SEL_074 BIT(3)
52#define ADM1293_VIN_SEL_210 (BIT(2) | BIT(3))
53#define ADM1293_VIN_SEL_MASK (BIT(2) | BIT(3))
54
55#define ADM1293_VAUX_EN BIT(1)
56
40#define ADM1275_IOUT_WARN2_LIMIT 0xd7 57#define ADM1275_IOUT_WARN2_LIMIT 0xd7
41#define ADM1275_DEVICE_CONFIG 0xd8 58#define ADM1275_DEVICE_CONFIG 0xd8
42 59
43#define ADM1275_IOUT_WARN2_SELECT BIT(4) 60#define ADM1275_IOUT_WARN2_SELECT BIT(4)
44 61
45#define ADM1276_PEAK_PIN 0xda 62#define ADM1276_PEAK_PIN 0xda
46
47#define ADM1275_MFR_STATUS_IOUT_WARN2 BIT(0)
48
49#define ADM1075_READ_VAUX 0xdd 63#define ADM1075_READ_VAUX 0xdd
50#define ADM1075_VAUX_OV_WARN_LIMIT 0xde 64#define ADM1075_VAUX_OV_WARN_LIMIT 0xde
51#define ADM1075_VAUX_UV_WARN_LIMIT 0xdf 65#define ADM1075_VAUX_UV_WARN_LIMIT 0xdf
66#define ADM1293_IOUT_MIN 0xe3
67#define ADM1293_PIN_MIN 0xe4
52#define ADM1075_VAUX_STATUS 0xf6 68#define ADM1075_VAUX_STATUS 0xf6
53 69
54#define ADM1075_VAUX_OV_WARN BIT(7) 70#define ADM1075_VAUX_OV_WARN BIT(7)
@@ -60,6 +76,9 @@ struct adm1275_data {
60 bool have_uc_fault; 76 bool have_uc_fault;
61 bool have_vout; 77 bool have_vout;
62 bool have_vaux_status; 78 bool have_vaux_status;
79 bool have_mfr_vaux_status;
80 bool have_iout_min;
81 bool have_pin_min;
63 bool have_pin_max; 82 bool have_pin_max;
64 struct pmbus_driver_info info; 83 struct pmbus_driver_info info;
65}; 84};
@@ -94,6 +113,28 @@ static const struct coefficients adm1276_coefficients[] = {
94 [4] = { 2115, 0, -1 }, /* power, vrange not set */ 113 [4] = { 2115, 0, -1 }, /* power, vrange not set */
95}; 114};
96 115
116static const struct coefficients adm1293_coefficients[] = {
117 [0] = { 3333, -1, 0 }, /* voltage, vrange 1.2V */
118 [1] = { 5552, -5, -1 }, /* voltage, vrange 7.4V */
119 [2] = { 19604, -50, -2 }, /* voltage, vrange 21V */
120 [3] = { 8000, -100, -2 }, /* current, irange25 */
121 [4] = { 4000, -100, -2 }, /* current, irange50 */
122 [5] = { 20000, -1000, -3 }, /* current, irange100 */
123 [6] = { 10000, -1000, -3 }, /* current, irange200 */
124 [7] = { 10417, 0, -1 }, /* power, 1.2V, irange25 */
125 [8] = { 5208, 0, -1 }, /* power, 1.2V, irange50 */
126 [9] = { 26042, 0, -2 }, /* power, 1.2V, irange100 */
127 [10] = { 13021, 0, -2 }, /* power, 1.2V, irange200 */
128 [11] = { 17351, 0, -2 }, /* power, 7.4V, irange25 */
129 [12] = { 8676, 0, -2 }, /* power, 7.4V, irange50 */
130 [13] = { 4338, 0, -2 }, /* power, 7.4V, irange100 */
131 [14] = { 21689, 0, -3 }, /* power, 7.4V, irange200 */
132 [15] = { 6126, 0, -2 }, /* power, 21V, irange25 */
133 [16] = { 30631, 0, -3 }, /* power, 21V, irange50 */
134 [17] = { 15316, 0, -3 }, /* power, 21V, irange100 */
135 [18] = { 7658, 0, -3 }, /* power, 21V, irange200 */
136};
137
97static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) 138static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
98{ 139{
99 const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 140 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
@@ -131,6 +172,11 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
131 return -ENODATA; 172 return -ENODATA;
132 ret = pmbus_read_word_data(client, 0, ADM1075_READ_VAUX); 173 ret = pmbus_read_word_data(client, 0, ADM1075_READ_VAUX);
133 break; 174 break;
175 case PMBUS_VIRT_READ_IOUT_MIN:
176 if (!data->have_iout_min)
177 return -ENXIO;
178 ret = pmbus_read_word_data(client, 0, ADM1293_IOUT_MIN);
179 break;
134 case PMBUS_VIRT_READ_IOUT_MAX: 180 case PMBUS_VIRT_READ_IOUT_MAX:
135 ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT); 181 ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT);
136 break; 182 break;
@@ -140,6 +186,11 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
140 case PMBUS_VIRT_READ_VIN_MAX: 186 case PMBUS_VIRT_READ_VIN_MAX:
141 ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN); 187 ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN);
142 break; 188 break;
189 case PMBUS_VIRT_READ_PIN_MIN:
190 if (!data->have_pin_min)
191 return -ENXIO;
192 ret = pmbus_read_word_data(client, 0, ADM1293_PIN_MIN);
193 break;
143 case PMBUS_VIRT_READ_PIN_MAX: 194 case PMBUS_VIRT_READ_PIN_MAX:
144 if (!data->have_pin_max) 195 if (!data->have_pin_max)
145 return -ENXIO; 196 return -ENXIO;
@@ -163,6 +214,8 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
163static int adm1275_write_word_data(struct i2c_client *client, int page, int reg, 214static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
164 u16 word) 215 u16 word)
165{ 216{
217 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
218 const struct adm1275_data *data = to_adm1275_data(info);
166 int ret; 219 int ret;
167 220
168 if (page) 221 if (page)
@@ -176,6 +229,9 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
176 break; 229 break;
177 case PMBUS_VIRT_RESET_IOUT_HISTORY: 230 case PMBUS_VIRT_RESET_IOUT_HISTORY:
178 ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_IOUT, 0); 231 ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_IOUT, 0);
232 if (!ret && data->have_iout_min)
233 ret = pmbus_write_word_data(client, 0,
234 ADM1293_IOUT_MIN, 0);
179 break; 235 break;
180 case PMBUS_VIRT_RESET_VOUT_HISTORY: 236 case PMBUS_VIRT_RESET_VOUT_HISTORY:
181 ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VOUT, 0); 237 ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VOUT, 0);
@@ -185,6 +241,9 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
185 break; 241 break;
186 case PMBUS_VIRT_RESET_PIN_HISTORY: 242 case PMBUS_VIRT_RESET_PIN_HISTORY:
187 ret = pmbus_write_word_data(client, 0, ADM1276_PEAK_PIN, 0); 243 ret = pmbus_write_word_data(client, 0, ADM1276_PEAK_PIN, 0);
244 if (!ret && data->have_pin_min)
245 ret = pmbus_write_word_data(client, 0,
246 ADM1293_PIN_MIN, 0);
188 break; 247 break;
189 default: 248 default:
190 ret = -ENODATA; 249 ret = -ENODATA;
@@ -231,6 +290,15 @@ static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg)
231 ret |= PB_VOLTAGE_OV_WARNING; 290 ret |= PB_VOLTAGE_OV_WARNING;
232 if (mfr_status & ADM1075_VAUX_UV_WARN) 291 if (mfr_status & ADM1075_VAUX_UV_WARN)
233 ret |= PB_VOLTAGE_UV_WARNING; 292 ret |= PB_VOLTAGE_UV_WARNING;
293 } else if (data->have_mfr_vaux_status) {
294 mfr_status = pmbus_read_byte_data(client, page,
295 PMBUS_STATUS_MFR_SPECIFIC);
296 if (mfr_status < 0)
297 return mfr_status;
298 if (mfr_status & ADM1293_MFR_STATUS_VAUX_OV_WARN)
299 ret |= PB_VOLTAGE_OV_WARNING;
300 if (mfr_status & ADM1293_MFR_STATUS_VAUX_UV_WARN)
301 ret |= PB_VOLTAGE_UV_WARNING;
234 } 302 }
235 break; 303 break;
236 default: 304 default:
@@ -244,6 +312,8 @@ static const struct i2c_device_id adm1275_id[] = {
244 { "adm1075", adm1075 }, 312 { "adm1075", adm1075 },
245 { "adm1275", adm1275 }, 313 { "adm1275", adm1275 },
246 { "adm1276", adm1276 }, 314 { "adm1276", adm1276 },
315 { "adm1293", adm1293 },
316 { "adm1294", adm1294 },
247 { } 317 { }
248}; 318};
249MODULE_DEVICE_TABLE(i2c, adm1275_id); 319MODULE_DEVICE_TABLE(i2c, adm1275_id);
@@ -258,7 +328,7 @@ static int adm1275_probe(struct i2c_client *client,
258 struct adm1275_data *data; 328 struct adm1275_data *data;
259 const struct i2c_device_id *mid; 329 const struct i2c_device_id *mid;
260 const struct coefficients *coefficients; 330 const struct coefficients *coefficients;
261 int vindex = -1, cindex = -1, pindex = -1; 331 int vindex = -1, voindex = -1, cindex = -1, pindex = -1;
262 332
263 if (!i2c_check_functionality(client->adapter, 333 if (!i2c_check_functionality(client->adapter,
264 I2C_FUNC_SMBUS_READ_BYTE_DATA 334 I2C_FUNC_SMBUS_READ_BYTE_DATA
@@ -390,17 +460,72 @@ static int adm1275_probe(struct i2c_client *client,
390 info->func[0] |= 460 info->func[0] |=
391 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; 461 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
392 break; 462 break;
463 case adm1293:
464 case adm1294:
465 data->have_iout_min = true;
466 data->have_pin_min = true;
467 data->have_pin_max = true;
468 data->have_mfr_vaux_status = true;
469
470 coefficients = adm1293_coefficients;
471
472 voindex = 0;
473 switch (config & ADM1293_VIN_SEL_MASK) {
474 case ADM1293_VIN_SEL_012: /* 1.2V */
475 vindex = 0;
476 break;
477 case ADM1293_VIN_SEL_074: /* 7.4V */
478 vindex = 1;
479 break;
480 case ADM1293_VIN_SEL_210: /* 21V */
481 vindex = 2;
482 break;
483 default: /* disabled */
484 break;
485 }
486
487 switch (config & ADM1293_IRANGE_MASK) {
488 case ADM1293_IRANGE_25:
489 cindex = 3;
490 break;
491 case ADM1293_IRANGE_50:
492 cindex = 4;
493 break;
494 case ADM1293_IRANGE_100:
495 cindex = 5;
496 break;
497 case ADM1293_IRANGE_200:
498 cindex = 6;
499 break;
500 }
501
502 if (vindex >= 0)
503 pindex = 7 + vindex * 4 + (cindex - 3);
504
505 if (config & ADM1293_VAUX_EN)
506 info->func[0] |=
507 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
508
509 info->func[0] |= PMBUS_HAVE_PIN |
510 PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
511
512 break;
393 default: 513 default:
394 dev_err(&client->dev, "Unsupported device\n"); 514 dev_err(&client->dev, "Unsupported device\n");
395 return -ENODEV; 515 return -ENODEV;
396 } 516 }
517
518 if (voindex < 0)
519 voindex = vindex;
397 if (vindex >= 0) { 520 if (vindex >= 0) {
398 info->m[PSC_VOLTAGE_IN] = coefficients[vindex].m; 521 info->m[PSC_VOLTAGE_IN] = coefficients[vindex].m;
399 info->b[PSC_VOLTAGE_IN] = coefficients[vindex].b; 522 info->b[PSC_VOLTAGE_IN] = coefficients[vindex].b;
400 info->R[PSC_VOLTAGE_IN] = coefficients[vindex].R; 523 info->R[PSC_VOLTAGE_IN] = coefficients[vindex].R;
401 info->m[PSC_VOLTAGE_OUT] = coefficients[vindex].m; 524 }
402 info->b[PSC_VOLTAGE_OUT] = coefficients[vindex].b; 525 if (voindex >= 0) {
403 info->R[PSC_VOLTAGE_OUT] = coefficients[vindex].R; 526 info->m[PSC_VOLTAGE_OUT] = coefficients[voindex].m;
527 info->b[PSC_VOLTAGE_OUT] = coefficients[voindex].b;
528 info->R[PSC_VOLTAGE_OUT] = coefficients[voindex].R;
404 } 529 }
405 if (cindex >= 0) { 530 if (cindex >= 0) {
406 info->m[PSC_CURRENT_OUT] = coefficients[cindex].m; 531 info->m[PSC_CURRENT_OUT] = coefficients[cindex].m;