aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/pmbus/adm1275.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/pmbus/adm1275.c')
-rw-r--r--drivers/hwmon/pmbus/adm1275.c141
1 files changed, 133 insertions, 8 deletions
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;