aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <guenter.roeck@ericsson.com>2011-07-09 11:30:26 -0400
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-07-28 20:09:32 -0400
commit6f183d33a02e686608f708ef713b6423db39bcba (patch)
treee2571fe569000af44818a914325e13edb8072f9a
parent0084e9faabbc1e228fda9c8a78ef1ea8ee97a9ae (diff)
hwmon: (pmbus) Add support for peak attributes
Most PMBus devices provide manufacturer specific commands to read low and/or high peak values for some or all of its sensors. To support providing those values as lowest/highest attributes to the user, introduce virtual PMBus commands. Those commands reside outside the normal command set and have to be implemented in device specific code, which map the virtual commands to device specific commands. Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com> Reviewed-by: Robert Coulson <robert.coulson@ericsson.com>
-rw-r--r--drivers/hwmon/pmbus/pmbus.h36
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c142
2 files changed, 163 insertions, 15 deletions
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index ceb71f7b91ac..9973d265b28f 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -126,6 +126,42 @@
126#define PMBUS_MFR_SERIAL 0x9E 126#define PMBUS_MFR_SERIAL 0x9E
127 127
128/* 128/*
129 * Virtual registers.
130 * Useful to support attributes which are not supported by standard PMBus
131 * registers but exist as manufacturer specific registers on individual chips.
132 * Must be mapped to real registers in device specific code.
133 *
134 * Semantics:
135 * Virtual registers are all word size.
136 * READ registers are read-only; writes are either ignored or return an error.
137 * RESET registers are read/write. Reading returns zero (used for detection),
138 * writing any value causes the associated history to be reset.
139 */
140#define PMBUS_VIRT_BASE 0x100
141#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 0)
142#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 1)
143#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 2)
144#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 3)
145#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 4)
146#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 5)
147#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 6)
148#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 7)
149#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 8)
150#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 9)
151#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 10)
152#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 11)
153#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 12)
154#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 13)
155#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 14)
156#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 15)
157#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 16)
158#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 17)
159#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 18)
160#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 19)
161#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 20)
162#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 21)
163
164/*
129 * CAPABILITY 165 * CAPABILITY
130 */ 166 */
131#define PB_CAPABILITY_SMBALERT (1<<4) 167#define PB_CAPABILITY_SMBALERT (1<<4)
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index df3971f6414c..9baf119b64db 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -33,14 +33,18 @@
33/* 33/*
34 * Constants needed to determine number of sensors, booleans, and labels. 34 * Constants needed to determine number of sensors, booleans, and labels.
35 */ 35 */
36#define PMBUS_MAX_INPUT_SENSORS 11 /* 6*volt, 3*curr, 2*power */ 36#define PMBUS_MAX_INPUT_SENSORS 22 /* 10*volt, 7*curr, 5*power */
37#define PMBUS_VOUT_SENSORS_PER_PAGE 5 /* input, min, max, lcrit, 37#define PMBUS_VOUT_SENSORS_PER_PAGE 9 /* input, min, max, lcrit,
38 crit */ 38 crit, lowest, highest, avg,
39#define PMBUS_IOUT_SENSORS_PER_PAGE 4 /* input, min, max, crit */ 39 reset */
40#define PMBUS_IOUT_SENSORS_PER_PAGE 8 /* input, min, max, crit,
41 lowest, highest, avg,
42 reset */
40#define PMBUS_POUT_SENSORS_PER_PAGE 4 /* input, cap, max, crit */ 43#define PMBUS_POUT_SENSORS_PER_PAGE 4 /* input, cap, max, crit */
41#define PMBUS_MAX_SENSORS_PER_FAN 1 /* input */ 44#define PMBUS_MAX_SENSORS_PER_FAN 1 /* input */
42#define PMBUS_MAX_SENSORS_PER_TEMP 5 /* input, min, max, lcrit, 45#define PMBUS_MAX_SENSORS_PER_TEMP 8 /* input, min, max, lcrit,
43 crit */ 46 crit, lowest, highest,
47 reset */
44 48
45#define PMBUS_MAX_INPUT_BOOLEANS 7 /* v: min_alarm, max_alarm, 49#define PMBUS_MAX_INPUT_BOOLEANS 7 /* v: min_alarm, max_alarm,
46 lcrit_alarm, crit_alarm; 50 lcrit_alarm, crit_alarm;
@@ -80,7 +84,7 @@ struct pmbus_sensor {
80 char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ 84 char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */
81 struct sensor_device_attribute attribute; 85 struct sensor_device_attribute attribute;
82 u8 page; /* page number */ 86 u8 page; /* page number */
83 u8 reg; /* register */ 87 u16 reg; /* register */
84 enum pmbus_sensor_classes class; /* sensor class */ 88 enum pmbus_sensor_classes class; /* sensor class */
85 bool update; /* runtime sensor update needed */ 89 bool update; /* runtime sensor update needed */
86 int data; /* Sensor data. 90 int data; /* Sensor data.
@@ -237,6 +241,8 @@ static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg)
237 if (status != -ENODATA) 241 if (status != -ENODATA)
238 return status; 242 return status;
239 } 243 }
244 if (reg >= PMBUS_VIRT_BASE)
245 return -EINVAL;
240 return pmbus_read_word_data(client, page, reg); 246 return pmbus_read_word_data(client, page, reg);
241} 247}
242 248
@@ -318,7 +324,7 @@ bool pmbus_check_word_register(struct i2c_client *client, int page, int reg)
318 int rv; 324 int rv;
319 struct pmbus_data *data = i2c_get_clientdata(client); 325 struct pmbus_data *data = i2c_get_clientdata(client);
320 326
321 rv = pmbus_read_word_data(client, page, reg); 327 rv = _pmbus_read_word_data(client, page, reg);
322 if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) 328 if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK))
323 rv = pmbus_check_status_cml(client); 329 rv = pmbus_check_status_cml(client);
324 pmbus_clear_fault_page(client, -1); 330 pmbus_clear_fault_page(client, -1);
@@ -951,7 +957,8 @@ static void pmbus_find_max_attr(struct i2c_client *client,
951 * and its associated alarm attribute. 957 * and its associated alarm attribute.
952 */ 958 */
953struct pmbus_limit_attr { 959struct pmbus_limit_attr {
954 u8 reg; /* Limit register */ 960 u16 reg; /* Limit register */
961 bool update; /* True if register needs updates */
955 const char *attr; /* Attribute name */ 962 const char *attr; /* Attribute name */
956 const char *alarm; /* Alarm attribute name */ 963 const char *alarm; /* Alarm attribute name */
957 u32 sbit; /* Alarm attribute status bit */ 964 u32 sbit; /* Alarm attribute status bit */
@@ -996,9 +1003,10 @@ static bool pmbus_add_limit_attrs(struct i2c_client *client,
996 if (pmbus_check_word_register(client, page, l->reg)) { 1003 if (pmbus_check_word_register(client, page, l->reg)) {
997 cindex = data->num_sensors; 1004 cindex = data->num_sensors;
998 pmbus_add_sensor(data, name, l->attr, index, page, 1005 pmbus_add_sensor(data, name, l->attr, index, page,
999 l->reg, attr->class, attr->update, 1006 l->reg, attr->class,
1007 attr->update || l->update,
1000 false); 1008 false);
1001 if (info->func[page] & attr->sfunc) { 1009 if (l->sbit && (info->func[page] & attr->sfunc)) {
1002 if (attr->compare) { 1010 if (attr->compare) {
1003 pmbus_add_boolean_cmp(data, name, 1011 pmbus_add_boolean_cmp(data, name,
1004 l->alarm, index, 1012 l->alarm, index,
@@ -1094,6 +1102,21 @@ static const struct pmbus_limit_attr vin_limit_attrs[] = {
1094 .attr = "crit", 1102 .attr = "crit",
1095 .alarm = "crit_alarm", 1103 .alarm = "crit_alarm",
1096 .sbit = PB_VOLTAGE_OV_FAULT, 1104 .sbit = PB_VOLTAGE_OV_FAULT,
1105 }, {
1106 .reg = PMBUS_VIRT_READ_VIN_AVG,
1107 .update = true,
1108 .attr = "average",
1109 }, {
1110 .reg = PMBUS_VIRT_READ_VIN_MIN,
1111 .update = true,
1112 .attr = "lowest",
1113 }, {
1114 .reg = PMBUS_VIRT_READ_VIN_MAX,
1115 .update = true,
1116 .attr = "highest",
1117 }, {
1118 .reg = PMBUS_VIRT_RESET_VIN_HISTORY,
1119 .attr = "reset_history",
1097 }, 1120 },
1098}; 1121};
1099 1122
@@ -1118,6 +1141,21 @@ static const struct pmbus_limit_attr vout_limit_attrs[] = {
1118 .attr = "crit", 1141 .attr = "crit",
1119 .alarm = "crit_alarm", 1142 .alarm = "crit_alarm",
1120 .sbit = PB_VOLTAGE_OV_FAULT, 1143 .sbit = PB_VOLTAGE_OV_FAULT,
1144 }, {
1145 .reg = PMBUS_VIRT_READ_VOUT_AVG,
1146 .update = true,
1147 .attr = "average",
1148 }, {
1149 .reg = PMBUS_VIRT_READ_VOUT_MIN,
1150 .update = true,
1151 .attr = "lowest",
1152 }, {
1153 .reg = PMBUS_VIRT_READ_VOUT_MAX,
1154 .update = true,
1155 .attr = "highest",
1156 }, {
1157 .reg = PMBUS_VIRT_RESET_VOUT_HISTORY,
1158 .attr = "reset_history",
1121 } 1159 }
1122}; 1160};
1123 1161
@@ -1164,6 +1202,21 @@ static const struct pmbus_limit_attr iin_limit_attrs[] = {
1164 .attr = "crit", 1202 .attr = "crit",
1165 .alarm = "crit_alarm", 1203 .alarm = "crit_alarm",
1166 .sbit = PB_IIN_OC_FAULT, 1204 .sbit = PB_IIN_OC_FAULT,
1205 }, {
1206 .reg = PMBUS_VIRT_READ_IIN_AVG,
1207 .update = true,
1208 .attr = "average",
1209 }, {
1210 .reg = PMBUS_VIRT_READ_IIN_MIN,
1211 .update = true,
1212 .attr = "lowest",
1213 }, {
1214 .reg = PMBUS_VIRT_READ_IIN_MAX,
1215 .update = true,
1216 .attr = "highest",
1217 }, {
1218 .reg = PMBUS_VIRT_RESET_IIN_HISTORY,
1219 .attr = "reset_history",
1167 } 1220 }
1168}; 1221};
1169 1222
@@ -1183,6 +1236,21 @@ static const struct pmbus_limit_attr iout_limit_attrs[] = {
1183 .attr = "crit", 1236 .attr = "crit",
1184 .alarm = "crit_alarm", 1237 .alarm = "crit_alarm",
1185 .sbit = PB_IOUT_OC_FAULT, 1238 .sbit = PB_IOUT_OC_FAULT,
1239 }, {
1240 .reg = PMBUS_VIRT_READ_IOUT_AVG,
1241 .update = true,
1242 .attr = "average",
1243 }, {
1244 .reg = PMBUS_VIRT_READ_IOUT_MIN,
1245 .update = true,
1246 .attr = "lowest",
1247 }, {
1248 .reg = PMBUS_VIRT_READ_IOUT_MAX,
1249 .update = true,
1250 .attr = "highest",
1251 }, {
1252 .reg = PMBUS_VIRT_RESET_IOUT_HISTORY,
1253 .attr = "reset_history",
1186 } 1254 }
1187}; 1255};
1188 1256
@@ -1218,6 +1286,17 @@ static const struct pmbus_limit_attr pin_limit_attrs[] = {
1218 .attr = "max", 1286 .attr = "max",
1219 .alarm = "alarm", 1287 .alarm = "alarm",
1220 .sbit = PB_PIN_OP_WARNING, 1288 .sbit = PB_PIN_OP_WARNING,
1289 }, {
1290 .reg = PMBUS_VIRT_READ_PIN_AVG,
1291 .update = true,
1292 .attr = "average",
1293 }, {
1294 .reg = PMBUS_VIRT_READ_PIN_MAX,
1295 .update = true,
1296 .attr = "input_highest",
1297 }, {
1298 .reg = PMBUS_VIRT_RESET_PIN_HISTORY,
1299 .attr = "reset_history",
1221 } 1300 }
1222}; 1301};
1223 1302
@@ -1286,6 +1365,39 @@ static const struct pmbus_limit_attr temp_limit_attrs[] = {
1286 .attr = "crit", 1365 .attr = "crit",
1287 .alarm = "crit_alarm", 1366 .alarm = "crit_alarm",
1288 .sbit = PB_TEMP_OT_FAULT, 1367 .sbit = PB_TEMP_OT_FAULT,
1368 }, {
1369 .reg = PMBUS_VIRT_READ_TEMP_MIN,
1370 .attr = "lowest",
1371 }, {
1372 .reg = PMBUS_VIRT_READ_TEMP_MAX,
1373 .attr = "highest",
1374 }, {
1375 .reg = PMBUS_VIRT_RESET_TEMP_HISTORY,
1376 .attr = "reset_history",
1377 }
1378};
1379
1380static const struct pmbus_limit_attr temp_limit_attrs23[] = {
1381 {
1382 .reg = PMBUS_UT_WARN_LIMIT,
1383 .attr = "min",
1384 .alarm = "min_alarm",
1385 .sbit = PB_TEMP_UT_WARNING,
1386 }, {
1387 .reg = PMBUS_UT_FAULT_LIMIT,
1388 .attr = "lcrit",
1389 .alarm = "lcrit_alarm",
1390 .sbit = PB_TEMP_UT_FAULT,
1391 }, {
1392 .reg = PMBUS_OT_WARN_LIMIT,
1393 .attr = "max",
1394 .alarm = "max_alarm",
1395 .sbit = PB_TEMP_OT_WARNING,
1396 }, {
1397 .reg = PMBUS_OT_FAULT_LIMIT,
1398 .attr = "crit",
1399 .alarm = "crit_alarm",
1400 .sbit = PB_TEMP_OT_FAULT,
1289 } 1401 }
1290}; 1402};
1291 1403
@@ -1312,8 +1424,8 @@ static const struct pmbus_sensor_attr temp_attributes[] = {
1312 .sfunc = PMBUS_HAVE_STATUS_TEMP, 1424 .sfunc = PMBUS_HAVE_STATUS_TEMP,
1313 .sbase = PB_STATUS_TEMP_BASE, 1425 .sbase = PB_STATUS_TEMP_BASE,
1314 .gbit = PB_STATUS_TEMPERATURE, 1426 .gbit = PB_STATUS_TEMPERATURE,
1315 .limit = temp_limit_attrs, 1427 .limit = temp_limit_attrs23,
1316 .nlimit = ARRAY_SIZE(temp_limit_attrs), 1428 .nlimit = ARRAY_SIZE(temp_limit_attrs23),
1317 }, { 1429 }, {
1318 .reg = PMBUS_READ_TEMPERATURE_3, 1430 .reg = PMBUS_READ_TEMPERATURE_3,
1319 .class = PSC_TEMPERATURE, 1431 .class = PSC_TEMPERATURE,
@@ -1324,8 +1436,8 @@ static const struct pmbus_sensor_attr temp_attributes[] = {
1324 .sfunc = PMBUS_HAVE_STATUS_TEMP, 1436 .sfunc = PMBUS_HAVE_STATUS_TEMP,
1325 .sbase = PB_STATUS_TEMP_BASE, 1437 .sbase = PB_STATUS_TEMP_BASE,
1326 .gbit = PB_STATUS_TEMPERATURE, 1438 .gbit = PB_STATUS_TEMPERATURE,
1327 .limit = temp_limit_attrs, 1439 .limit = temp_limit_attrs23,
1328 .nlimit = ARRAY_SIZE(temp_limit_attrs), 1440 .nlimit = ARRAY_SIZE(temp_limit_attrs23),
1329 } 1441 }
1330}; 1442};
1331 1443