aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/pmbus_core.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c
index b7c64ba31f4c..d025a118bf92 100644
--- a/drivers/hwmon/pmbus_core.c
+++ b/drivers/hwmon/pmbus_core.c
@@ -58,12 +58,10 @@
58#define PMBUS_MAX_INPUT_LABELS 4 /* vin, vcap, iin, pin */ 58#define PMBUS_MAX_INPUT_LABELS 4 /* vin, vcap, iin, pin */
59 59
60/* 60/*
61 * status, status_vout, status_iout, status_fans, and status_temp 61 * status, status_vout, status_iout, status_fans, status_fan34, and status_temp
62 * are paged. status_input and status_fan34 are unpaged. 62 * are paged. status_input is unpaged.
63 * status_fan34 is a special case to handle a second set of fans
64 * on page 0.
65 */ 63 */
66#define PB_NUM_STATUS_REG (PMBUS_PAGES * 5 + 2) 64#define PB_NUM_STATUS_REG (PMBUS_PAGES * 6 + 1)
67 65
68/* 66/*
69 * Index into status register array, per status register group 67 * Index into status register array, per status register group
@@ -73,7 +71,7 @@
73#define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES) 71#define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES)
74#define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES) 72#define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES)
75#define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES) 73#define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES)
76#define PB_STATUS_INPUT_BASE (PB_STATUS_FAN34_BASE + 1) 74#define PB_STATUS_INPUT_BASE (PB_STATUS_FAN34_BASE + PMBUS_PAGES)
77#define PB_STATUS_TEMP_BASE (PB_STATUS_INPUT_BASE + 1) 75#define PB_STATUS_TEMP_BASE (PB_STATUS_INPUT_BASE + 1)
78 76
79struct pmbus_sensor { 77struct pmbus_sensor {
@@ -327,14 +325,17 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)
327 = pmbus_get_status(client, i, PMBUS_STATUS_FAN_12); 325 = pmbus_get_status(client, i, PMBUS_STATUS_FAN_12);
328 } 326 }
329 327
328 for (i = 0; i < info->pages; i++) {
329 if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN34))
330 continue;
331 data->status[PB_STATUS_FAN34_BASE + i]
332 = pmbus_get_status(client, i, PMBUS_STATUS_FAN_34);
333 }
334
330 if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) 335 if (info->func[0] & PMBUS_HAVE_STATUS_INPUT)
331 data->status[PB_STATUS_INPUT_BASE] 336 data->status[PB_STATUS_INPUT_BASE]
332 = pmbus_get_status(client, 0, PMBUS_STATUS_INPUT); 337 = pmbus_get_status(client, 0, PMBUS_STATUS_INPUT);
333 338
334 if (info->func[0] & PMBUS_HAVE_STATUS_FAN34)
335 data->status[PB_STATUS_FAN34_BASE]
336 = pmbus_get_status(client, 0, PMBUS_STATUS_FAN_34);
337
338 for (i = 0; i < data->num_sensors; i++) { 339 for (i = 0; i < data->num_sensors; i++) {
339 struct pmbus_sensor *sensor = &data->sensors[i]; 340 struct pmbus_sensor *sensor = &data->sensors[i];
340 341
@@ -817,6 +818,20 @@ static const int pmbus_fan_status_registers[] = {
817 PMBUS_STATUS_FAN_34 818 PMBUS_STATUS_FAN_34
818}; 819};
819 820
821static const u32 pmbus_fan_flags[] = {
822 PMBUS_HAVE_FAN12,
823 PMBUS_HAVE_FAN12,
824 PMBUS_HAVE_FAN34,
825 PMBUS_HAVE_FAN34
826};
827
828static const u32 pmbus_fan_status_flags[] = {
829 PMBUS_HAVE_STATUS_FAN12,
830 PMBUS_HAVE_STATUS_FAN12,
831 PMBUS_HAVE_STATUS_FAN34,
832 PMBUS_HAVE_STATUS_FAN34
833};
834
820/* 835/*
821 * Determine maximum number of sensors, booleans, and labels. 836 * Determine maximum number of sensors, booleans, and labels.
822 * To keep things simple, only make a rough high estimate. 837 * To keep things simple, only make a rough high estimate.
@@ -848,17 +863,12 @@ static void pmbus_find_max_attr(struct i2c_client *client,
848 max_labels++; 863 max_labels++;
849 } 864 }
850 if (info->func[page] & PMBUS_HAVE_FAN12) { 865 if (info->func[page] & PMBUS_HAVE_FAN12) {
851 if (page == 0) { 866 max_sensors += 2 * PMBUS_MAX_SENSORS_PER_FAN;
852 max_sensors += 867 max_booleans += 2 * PMBUS_MAX_BOOLEANS_PER_FAN;
853 ARRAY_SIZE(pmbus_fan_registers) * 868 }
854 PMBUS_MAX_SENSORS_PER_FAN; 869 if (info->func[page] & PMBUS_HAVE_FAN34) {
855 max_booleans += 870 max_sensors += 2 * PMBUS_MAX_SENSORS_PER_FAN;
856 ARRAY_SIZE(pmbus_fan_registers) * 871 max_booleans += 2 * PMBUS_MAX_BOOLEANS_PER_FAN;
857 PMBUS_MAX_BOOLEANS_PER_FAN;
858 } else {
859 max_sensors += PMBUS_MAX_SENSORS_PER_FAN;
860 max_booleans += PMBUS_MAX_BOOLEANS_PER_FAN;
861 }
862 } 872 }
863 if (info->func[page] & PMBUS_HAVE_TEMP) { 873 if (info->func[page] & PMBUS_HAVE_TEMP) {
864 if (page == 0) { 874 if (page == 0) {
@@ -1365,15 +1375,14 @@ static void pmbus_find_attributes(struct i2c_client *client,
1365 */ 1375 */
1366 in_index = 1; 1376 in_index = 1;
1367 for (page = 0; page < info->pages; page++) { 1377 for (page = 0; page < info->pages; page++) {
1368 int fans, f; 1378 int f;
1369 1379
1370 if (!(info->func[page] & PMBUS_HAVE_FAN12)) 1380 for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) {
1371 continue;
1372
1373 fans = page ? 1 : ARRAY_SIZE(pmbus_fan_registers);
1374 for (f = 0; f < fans; f++) {
1375 int regval; 1381 int regval;
1376 1382
1383 if (!(info->func[page] & pmbus_fan_flags[f]))
1384 break;
1385
1377 if (!pmbus_check_word_register(client, page, 1386 if (!pmbus_check_word_register(client, page,
1378 pmbus_fan_registers[f]) 1387 pmbus_fan_registers[f])
1379 || !pmbus_check_byte_register(client, page, 1388 || !pmbus_check_byte_register(client, page,
@@ -1399,12 +1408,13 @@ static void pmbus_find_attributes(struct i2c_client *client,
1399 * Each fan status register covers multiple fans, 1408 * Each fan status register covers multiple fans,
1400 * so we have to do some magic. 1409 * so we have to do some magic.
1401 */ 1410 */
1402 if (pmbus_check_byte_register 1411 if ((info->func[page] & pmbus_fan_status_flags[f]) &&
1403 (client, page, pmbus_fan_status_registers[f])) { 1412 pmbus_check_byte_register(client,
1413 page, pmbus_fan_status_registers[f])) {
1404 int base; 1414 int base;
1405 1415
1406 if (f > 1) /* fan 3, 4 */ 1416 if (f > 1) /* fan 3, 4 */
1407 base = PB_STATUS_FAN34_BASE; 1417 base = PB_STATUS_FAN34_BASE + page;
1408 else 1418 else
1409 base = PB_STATUS_FAN_BASE + page; 1419 base = PB_STATUS_FAN_BASE + page;
1410 pmbus_add_boolean_reg(data, "fan", "alarm", 1420 pmbus_add_boolean_reg(data, "fan", "alarm",