aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/pmbus/adm1275.c6
-rw-r--r--drivers/hwmon/pmbus/max16064.c6
-rw-r--r--drivers/hwmon/pmbus/max34440.c18
-rw-r--r--drivers/hwmon/pmbus/max8688.c8
-rw-r--r--drivers/hwmon/pmbus/pmbus.c34
-rw-r--r--drivers/hwmon/pmbus/pmbus.h7
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c60
7 files changed, 105 insertions, 34 deletions
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c
index 8bc1bd66372..71770ffbdaf 100644
--- a/drivers/hwmon/pmbus/adm1275.c
+++ b/drivers/hwmon/pmbus/adm1275.c
@@ -50,9 +50,9 @@ static int adm1275_probe(struct i2c_client *client,
50 } 50 }
51 51
52 info->pages = 1; 52 info->pages = 1;
53 info->direct[PSC_VOLTAGE_IN] = true; 53 info->format[PSC_VOLTAGE_IN] = direct;
54 info->direct[PSC_VOLTAGE_OUT] = true; 54 info->format[PSC_VOLTAGE_OUT] = direct;
55 info->direct[PSC_CURRENT_OUT] = true; 55 info->format[PSC_CURRENT_OUT] = direct;
56 info->m[PSC_CURRENT_OUT] = 807; 56 info->m[PSC_CURRENT_OUT] = 807;
57 info->b[PSC_CURRENT_OUT] = 20475; 57 info->b[PSC_CURRENT_OUT] = 20475;
58 info->R[PSC_CURRENT_OUT] = -1; 58 info->R[PSC_CURRENT_OUT] = -1;
diff --git a/drivers/hwmon/pmbus/max16064.c b/drivers/hwmon/pmbus/max16064.c
index 1d6d717060d..78e20bca53a 100644
--- a/drivers/hwmon/pmbus/max16064.c
+++ b/drivers/hwmon/pmbus/max16064.c
@@ -27,9 +27,9 @@
27 27
28static struct pmbus_driver_info max16064_info = { 28static struct pmbus_driver_info max16064_info = {
29 .pages = 4, 29 .pages = 4,
30 .direct[PSC_VOLTAGE_IN] = true, 30 .format[PSC_VOLTAGE_IN] = direct,
31 .direct[PSC_VOLTAGE_OUT] = true, 31 .format[PSC_VOLTAGE_OUT] = direct,
32 .direct[PSC_TEMPERATURE] = true, 32 .format[PSC_TEMPERATURE] = direct,
33 .m[PSC_VOLTAGE_IN] = 19995, 33 .m[PSC_VOLTAGE_IN] = 19995,
34 .b[PSC_VOLTAGE_IN] = 0, 34 .b[PSC_VOLTAGE_IN] = 0,
35 .R[PSC_VOLTAGE_IN] = -1, 35 .R[PSC_VOLTAGE_IN] = -1,
diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c
index db11e1a175b..2e30046a116 100644
--- a/drivers/hwmon/pmbus/max34440.c
+++ b/drivers/hwmon/pmbus/max34440.c
@@ -72,10 +72,10 @@ static int max34440_read_byte_data(struct i2c_client *client, int page, int reg)
72static struct pmbus_driver_info max34440_info[] = { 72static struct pmbus_driver_info max34440_info[] = {
73 [max34440] = { 73 [max34440] = {
74 .pages = 14, 74 .pages = 14,
75 .direct[PSC_VOLTAGE_IN] = true, 75 .format[PSC_VOLTAGE_IN] = direct,
76 .direct[PSC_VOLTAGE_OUT] = true, 76 .format[PSC_VOLTAGE_OUT] = direct,
77 .direct[PSC_TEMPERATURE] = true, 77 .format[PSC_TEMPERATURE] = direct,
78 .direct[PSC_CURRENT_OUT] = true, 78 .format[PSC_CURRENT_OUT] = direct,
79 .m[PSC_VOLTAGE_IN] = 1, 79 .m[PSC_VOLTAGE_IN] = 1,
80 .b[PSC_VOLTAGE_IN] = 0, 80 .b[PSC_VOLTAGE_IN] = 0,
81 .R[PSC_VOLTAGE_IN] = 3, /* R = 0 in datasheet reflects mV */ 81 .R[PSC_VOLTAGE_IN] = 3, /* R = 0 in datasheet reflects mV */
@@ -112,11 +112,11 @@ static struct pmbus_driver_info max34440_info[] = {
112 }, 112 },
113 [max34441] = { 113 [max34441] = {
114 .pages = 12, 114 .pages = 12,
115 .direct[PSC_VOLTAGE_IN] = true, 115 .format[PSC_VOLTAGE_IN] = direct,
116 .direct[PSC_VOLTAGE_OUT] = true, 116 .format[PSC_VOLTAGE_OUT] = direct,
117 .direct[PSC_TEMPERATURE] = true, 117 .format[PSC_TEMPERATURE] = direct,
118 .direct[PSC_CURRENT_OUT] = true, 118 .format[PSC_CURRENT_OUT] = direct,
119 .direct[PSC_FAN] = true, 119 .format[PSC_FAN] = direct,
120 .m[PSC_VOLTAGE_IN] = 1, 120 .m[PSC_VOLTAGE_IN] = 1,
121 .b[PSC_VOLTAGE_IN] = 0, 121 .b[PSC_VOLTAGE_IN] = 0,
122 .R[PSC_VOLTAGE_IN] = 3, 122 .R[PSC_VOLTAGE_IN] = 3,
diff --git a/drivers/hwmon/pmbus/max8688.c b/drivers/hwmon/pmbus/max8688.c
index 7fb93f4e9f2..ddc8a64c2ba 100644
--- a/drivers/hwmon/pmbus/max8688.c
+++ b/drivers/hwmon/pmbus/max8688.c
@@ -91,10 +91,10 @@ static int max8688_read_byte_data(struct i2c_client *client, int page, int reg)
91 91
92static struct pmbus_driver_info max8688_info = { 92static struct pmbus_driver_info max8688_info = {
93 .pages = 1, 93 .pages = 1,
94 .direct[PSC_VOLTAGE_IN] = true, 94 .format[PSC_VOLTAGE_IN] = direct,
95 .direct[PSC_VOLTAGE_OUT] = true, 95 .format[PSC_VOLTAGE_OUT] = direct,
96 .direct[PSC_TEMPERATURE] = true, 96 .format[PSC_TEMPERATURE] = direct,
97 .direct[PSC_CURRENT_OUT] = true, 97 .format[PSC_CURRENT_OUT] = direct,
98 .m[PSC_VOLTAGE_IN] = 19995, 98 .m[PSC_VOLTAGE_IN] = 19995,
99 .b[PSC_VOLTAGE_IN] = 0, 99 .b[PSC_VOLTAGE_IN] = 0,
100 .R[PSC_VOLTAGE_IN] = -1, 100 .R[PSC_VOLTAGE_IN] = -1,
diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c
index 9b1f0c37ef7..4d8e31bcd7a 100644
--- a/drivers/hwmon/pmbus/pmbus.c
+++ b/drivers/hwmon/pmbus/pmbus.c
@@ -96,6 +96,8 @@ static void pmbus_find_sensor_groups(struct i2c_client *client,
96static int pmbus_identify(struct i2c_client *client, 96static int pmbus_identify(struct i2c_client *client,
97 struct pmbus_driver_info *info) 97 struct pmbus_driver_info *info)
98{ 98{
99 int ret = 0;
100
99 if (!info->pages) { 101 if (!info->pages) {
100 /* 102 /*
101 * Check if the PAGE command is supported. If it is, 103 * Check if the PAGE command is supported. If it is,
@@ -117,6 +119,27 @@ static int pmbus_identify(struct i2c_client *client,
117 } 119 }
118 } 120 }
119 121
122 if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) {
123 int vout_mode;
124
125 vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
126 if (vout_mode >= 0 && vout_mode != 0xff) {
127 switch (vout_mode >> 5) {
128 case 0:
129 break;
130 case 1:
131 info->format[PSC_VOLTAGE_OUT] = vid;
132 break;
133 case 2:
134 info->format[PSC_VOLTAGE_OUT] = direct;
135 break;
136 default:
137 ret = -ENODEV;
138 goto abort;
139 }
140 }
141 }
142
120 /* 143 /*
121 * We should check if the COEFFICIENTS register is supported. 144 * We should check if the COEFFICIENTS register is supported.
122 * If it is, and the chip is configured for direct mode, we can read 145 * If it is, and the chip is configured for direct mode, we can read
@@ -125,13 +148,18 @@ static int pmbus_identify(struct i2c_client *client,
125 * 148 *
126 * To do this, we will need access to a chip which actually supports the 149 * To do this, we will need access to a chip which actually supports the
127 * COEFFICIENTS command, since the command is too complex to implement 150 * COEFFICIENTS command, since the command is too complex to implement
128 * without testing it. 151 * without testing it. Until then, abort if a chip configured for direct
152 * mode was detected.
129 */ 153 */
154 if (info->format[PSC_VOLTAGE_OUT] == direct) {
155 ret = -ENODEV;
156 goto abort;
157 }
130 158
131 /* Try to find sensor groups */ 159 /* Try to find sensor groups */
132 pmbus_find_sensor_groups(client, info); 160 pmbus_find_sensor_groups(client, info);
133 161abort:
134 return 0; 162 return ret;
135} 163}
136 164
137static int pmbus_probe(struct i2c_client *client, 165static int pmbus_probe(struct i2c_client *client,
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index 50647ab7235..cc5b6a23260 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -266,11 +266,11 @@ enum pmbus_sensor_classes {
266#define PMBUS_HAVE_STATUS_FAN12 (1 << 16) 266#define PMBUS_HAVE_STATUS_FAN12 (1 << 16)
267#define PMBUS_HAVE_STATUS_FAN34 (1 << 17) 267#define PMBUS_HAVE_STATUS_FAN34 (1 << 17)
268 268
269enum pmbus_data_format { linear = 0, direct, vid };
270
269struct pmbus_driver_info { 271struct pmbus_driver_info {
270 int pages; /* Total number of pages */ 272 int pages; /* Total number of pages */
271 bool direct[PSC_NUM_CLASSES]; 273 enum pmbus_data_format format[PSC_NUM_CLASSES];
272 /* true if device uses direct data format
273 for the given sensor class */
274 /* 274 /*
275 * Support one set of coefficients for each sensor type 275 * Support one set of coefficients for each sensor type
276 * Used for chips providing data in direct mode. 276 * Used for chips providing data in direct mode.
@@ -299,6 +299,7 @@ struct pmbus_driver_info {
299 299
300int pmbus_set_page(struct i2c_client *client, u8 page); 300int pmbus_set_page(struct i2c_client *client, u8 page);
301int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); 301int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
302int pmbus_read_byte_data(struct i2c_client *client, u8 page, u8 reg);
302void pmbus_clear_faults(struct i2c_client *client); 303void pmbus_clear_faults(struct i2c_client *client);
303bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); 304bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg);
304bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); 305bool pmbus_check_word_register(struct i2c_client *client, int page, int reg);
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 8e31a8e2c74..cef763c7da3 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -197,7 +197,7 @@ int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg)
197} 197}
198EXPORT_SYMBOL_GPL(pmbus_read_word_data); 198EXPORT_SYMBOL_GPL(pmbus_read_word_data);
199 199
200static int pmbus_read_byte_data(struct i2c_client *client, u8 page, u8 reg) 200int pmbus_read_byte_data(struct i2c_client *client, u8 page, u8 reg)
201{ 201{
202 int rv; 202 int rv;
203 203
@@ -207,6 +207,7 @@ static int pmbus_read_byte_data(struct i2c_client *client, u8 page, u8 reg)
207 207
208 return i2c_smbus_read_byte_data(client, reg); 208 return i2c_smbus_read_byte_data(client, reg);
209} 209}
210EXPORT_SYMBOL_GPL(pmbus_read_byte_data);
210 211
211static void pmbus_clear_fault_page(struct i2c_client *client, int page) 212static void pmbus_clear_fault_page(struct i2c_client *client, int page)
212{ 213{
@@ -443,15 +444,37 @@ static long pmbus_reg2data_direct(struct pmbus_data *data,
443 return (val - b) / m; 444 return (val - b) / m;
444} 445}
445 446
447/*
448 * Convert VID sensor values to milli- or micro-units
449 * depending on sensor type.
450 * We currently only support VR11.
451 */
452static long pmbus_reg2data_vid(struct pmbus_data *data,
453 struct pmbus_sensor *sensor)
454{
455 long val = sensor->data;
456
457 if (val < 0x02 || val > 0xb2)
458 return 0;
459 return DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100);
460}
461
446static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) 462static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
447{ 463{
448 long val; 464 long val;
449 465
450 if (data->info->direct[sensor->class]) 466 switch (data->info->format[sensor->class]) {
467 case direct:
451 val = pmbus_reg2data_direct(data, sensor); 468 val = pmbus_reg2data_direct(data, sensor);
452 else 469 break;
470 case vid:
471 val = pmbus_reg2data_vid(data, sensor);
472 break;
473 case linear:
474 default:
453 val = pmbus_reg2data_linear(data, sensor); 475 val = pmbus_reg2data_linear(data, sensor);
454 476 break;
477 }
455 return val; 478 return val;
456} 479}
457 480
@@ -561,16 +584,31 @@ static u16 pmbus_data2reg_direct(struct pmbus_data *data,
561 return val; 584 return val;
562} 585}
563 586
587static u16 pmbus_data2reg_vid(struct pmbus_data *data,
588 enum pmbus_sensor_classes class, long val)
589{
590 val = SENSORS_LIMIT(val, 500, 1600);
591
592 return 2 + DIV_ROUND_CLOSEST((1600 - val) * 100, 625);
593}
594
564static u16 pmbus_data2reg(struct pmbus_data *data, 595static u16 pmbus_data2reg(struct pmbus_data *data,
565 enum pmbus_sensor_classes class, long val) 596 enum pmbus_sensor_classes class, long val)
566{ 597{
567 u16 regval; 598 u16 regval;
568 599
569 if (data->info->direct[class]) 600 switch (data->info->format[class]) {
601 case direct:
570 regval = pmbus_data2reg_direct(data, class, val); 602 regval = pmbus_data2reg_direct(data, class, val);
571 else 603 break;
604 case vid:
605 regval = pmbus_data2reg_vid(data, class, val);
606 break;
607 case linear:
608 default:
572 regval = pmbus_data2reg_linear(data, class, val); 609 regval = pmbus_data2reg_linear(data, class, val);
573 610 break;
611 }
574 return regval; 612 return regval;
575} 613}
576 614
@@ -1380,7 +1418,7 @@ static int pmbus_identify_common(struct i2c_client *client,
1380 */ 1418 */
1381 switch (vout_mode >> 5) { 1419 switch (vout_mode >> 5) {
1382 case 0: /* linear mode */ 1420 case 0: /* linear mode */
1383 if (data->info->direct[PSC_VOLTAGE_OUT]) 1421 if (data->info->format[PSC_VOLTAGE_OUT] != linear)
1384 return -ENODEV; 1422 return -ENODEV;
1385 1423
1386 exponent = vout_mode & 0x1f; 1424 exponent = vout_mode & 0x1f;
@@ -1389,8 +1427,12 @@ static int pmbus_identify_common(struct i2c_client *client,
1389 exponent |= ~0x1f; 1427 exponent |= ~0x1f;
1390 data->exponent = exponent; 1428 data->exponent = exponent;
1391 break; 1429 break;
1430 case 1: /* VID mode */
1431 if (data->info->format[PSC_VOLTAGE_OUT] != vid)
1432 return -ENODEV;
1433 break;
1392 case 2: /* direct mode */ 1434 case 2: /* direct mode */
1393 if (!data->info->direct[PSC_VOLTAGE_OUT]) 1435 if (data->info->format[PSC_VOLTAGE_OUT] != direct)
1394 return -ENODEV; 1436 return -ENODEV;
1395 break; 1437 break;
1396 default: 1438 default: