#define PMBUS_MFR_SERIAL 0x9E
/*
+ * Virtual registers.
+ * Useful to support attributes which are not supported by standard PMBus
+ * registers but exist as manufacturer specific registers on individual chips.
+ * Must be mapped to real registers in device specific code.
+ *
+ * Semantics:
+ * Virtual registers are all word size.
+ * READ registers are read-only; writes are either ignored or return an error.
+ * RESET registers are read/write. Reading returns zero (used for detection),
+ * writing any value causes the associated history to be reset.
+ */
+#define PMBUS_VIRT_BASE 0x100
+#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 0)
+#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 1)
+#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 2)
+#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 3)
+#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 4)
+#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 5)
+#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 6)
+#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 7)
+#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 8)
+#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 9)
+#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 10)
+#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 11)
+#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 12)
+#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 13)
+#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 14)
+#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 15)
+#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 16)
+#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 17)
+#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 18)
+#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 19)
+#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 20)
+#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 21)
+
+/*
* CAPABILITY
*/
#define PB_CAPABILITY_SMBALERT (1<<4)
/*
* Constants needed to determine number of sensors, booleans, and labels.
*/
-#define PMBUS_MAX_INPUT_SENSORS 11 /* 6*volt, 3*curr, 2*power */
-#define PMBUS_VOUT_SENSORS_PER_PAGE 5 /* input, min, max, lcrit,
- crit */
-#define PMBUS_IOUT_SENSORS_PER_PAGE 4 /* input, min, max, crit */
+#define PMBUS_MAX_INPUT_SENSORS 22 /* 10*volt, 7*curr, 5*power */
+#define PMBUS_VOUT_SENSORS_PER_PAGE 9 /* input, min, max, lcrit,
+ crit, lowest, highest, avg,
+ reset */
+#define PMBUS_IOUT_SENSORS_PER_PAGE 8 /* input, min, max, crit,
+ lowest, highest, avg,
+ reset */
#define PMBUS_POUT_SENSORS_PER_PAGE 4 /* input, cap, max, crit */
#define PMBUS_MAX_SENSORS_PER_FAN 1 /* input */
-#define PMBUS_MAX_SENSORS_PER_TEMP 5 /* input, min, max, lcrit,
- crit */
+#define PMBUS_MAX_SENSORS_PER_TEMP 8 /* input, min, max, lcrit,
+ crit, lowest, highest,
+ reset */
#define PMBUS_MAX_INPUT_BOOLEANS 7 /* v: min_alarm, max_alarm,
lcrit_alarm, crit_alarm;
char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */
struct sensor_device_attribute attribute;
u8 page; /* page number */
- u8 reg; /* register */
+ u16 reg; /* register */
enum pmbus_sensor_classes class; /* sensor class */
bool update; /* runtime sensor update needed */
int data; /* Sensor data.
if (status != -ENODATA)
return status;
}
+ if (reg >= PMBUS_VIRT_BASE)
+ return -EINVAL;
return pmbus_read_word_data(client, page, reg);
}
int rv;
struct pmbus_data *data = i2c_get_clientdata(client);
- rv = pmbus_read_word_data(client, page, reg);
+ rv = _pmbus_read_word_data(client, page, reg);
if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK))
rv = pmbus_check_status_cml(client);
pmbus_clear_fault_page(client, -1);
* and its associated alarm attribute.
*/
struct pmbus_limit_attr {
- u8 reg; /* Limit register */
+ u16 reg; /* Limit register */
+ bool update; /* True if register needs updates */
const char *attr; /* Attribute name */
const char *alarm; /* Alarm attribute name */
u32 sbit; /* Alarm attribute status bit */
if (pmbus_check_word_register(client, page, l->reg)) {
cindex = data->num_sensors;
pmbus_add_sensor(data, name, l->attr, index, page,
- l->reg, attr->class, attr->update,
+ l->reg, attr->class,
+ attr->update || l->update,
false);
- if (info->func[page] & attr->sfunc) {
+ if (l->sbit && (info->func[page] & attr->sfunc)) {
if (attr->compare) {
pmbus_add_boolean_cmp(data, name,
l->alarm, index,
.attr = "crit",
.alarm = "crit_alarm",
.sbit = PB_VOLTAGE_OV_FAULT,
+ }, {
+ .reg = PMBUS_VIRT_READ_VIN_AVG,
+ .update = true,
+ .attr = "average",
+ }, {
+ .reg = PMBUS_VIRT_READ_VIN_MIN,
+ .update = true,
+ .attr = "lowest",
+ }, {
+ .reg = PMBUS_VIRT_READ_VIN_MAX,
+ .update = true,
+ .attr = "highest",
+ }, {
+ .reg = PMBUS_VIRT_RESET_VIN_HISTORY,
+ .attr = "reset_history",
},
};
.attr = "crit",
.alarm = "crit_alarm",
.sbit = PB_VOLTAGE_OV_FAULT,
+ }, {
+ .reg = PMBUS_VIRT_READ_VOUT_AVG,
+ .update = true,
+ .attr = "average",
+ }, {
+ .reg = PMBUS_VIRT_READ_VOUT_MIN,
+ .update = true,
+ .attr = "lowest",
+ }, {
+ .reg = PMBUS_VIRT_READ_VOUT_MAX,
+ .update = true,
+ .attr = "highest",
+ }, {
+ .reg = PMBUS_VIRT_RESET_VOUT_HISTORY,
+ .attr = "reset_history",
}
};
.attr = "crit",
.alarm = "crit_alarm",
.sbit = PB_IIN_OC_FAULT,
+ }, {
+ .reg = PMBUS_VIRT_READ_IIN_AVG,
+ .update = true,
+ .attr = "average",
+ }, {
+ .reg = PMBUS_VIRT_READ_IIN_MIN,
+ .update = true,
+ .attr = "lowest",
+ }, {
+ .reg = PMBUS_VIRT_READ_IIN_MAX,
+ .update = true,
+ .attr = "highest",
+ }, {
+ .reg = PMBUS_VIRT_RESET_IIN_HISTORY,
+ .attr = "reset_history",
}
};
.attr = "crit",
.alarm = "crit_alarm",
.sbit = PB_IOUT_OC_FAULT,
+ }, {
+ .reg = PMBUS_VIRT_READ_IOUT_AVG,
+ .update = true,
+ .attr = "average",
+ }, {
+ .reg = PMBUS_VIRT_READ_IOUT_MIN,
+ .update = true,
+ .attr = "lowest",
+ }, {
+ .reg = PMBUS_VIRT_READ_IOUT_MAX,
+ .update = true,
+ .attr = "highest",
+ }, {
+ .reg = PMBUS_VIRT_RESET_IOUT_HISTORY,
+ .attr = "reset_history",
}
};
.attr = "max",
.alarm = "alarm",
.sbit = PB_PIN_OP_WARNING,
+ }, {
+ .reg = PMBUS_VIRT_READ_PIN_AVG,
+ .update = true,
+ .attr = "average",
+ }, {
+ .reg = PMBUS_VIRT_READ_PIN_MAX,
+ .update = true,
+ .attr = "input_highest",
+ }, {
+ .reg = PMBUS_VIRT_RESET_PIN_HISTORY,
+ .attr = "reset_history",
}
};
.attr = "crit",
.alarm = "crit_alarm",
.sbit = PB_TEMP_OT_FAULT,
+ }, {
+ .reg = PMBUS_VIRT_READ_TEMP_MIN,
+ .attr = "lowest",
+ }, {
+ .reg = PMBUS_VIRT_READ_TEMP_MAX,
+ .attr = "highest",
+ }, {
+ .reg = PMBUS_VIRT_RESET_TEMP_HISTORY,
+ .attr = "reset_history",
+ }
+};
+
+static const struct pmbus_limit_attr temp_limit_attrs23[] = {
+ {
+ .reg = PMBUS_UT_WARN_LIMIT,
+ .attr = "min",
+ .alarm = "min_alarm",
+ .sbit = PB_TEMP_UT_WARNING,
+ }, {
+ .reg = PMBUS_UT_FAULT_LIMIT,
+ .attr = "lcrit",
+ .alarm = "lcrit_alarm",
+ .sbit = PB_TEMP_UT_FAULT,
+ }, {
+ .reg = PMBUS_OT_WARN_LIMIT,
+ .attr = "max",
+ .alarm = "max_alarm",
+ .sbit = PB_TEMP_OT_WARNING,
+ }, {
+ .reg = PMBUS_OT_FAULT_LIMIT,
+ .attr = "crit",
+ .alarm = "crit_alarm",
+ .sbit = PB_TEMP_OT_FAULT,
}
};
.sfunc = PMBUS_HAVE_STATUS_TEMP,
.sbase = PB_STATUS_TEMP_BASE,
.gbit = PB_STATUS_TEMPERATURE,
- .limit = temp_limit_attrs,
- .nlimit = ARRAY_SIZE(temp_limit_attrs),
+ .limit = temp_limit_attrs23,
+ .nlimit = ARRAY_SIZE(temp_limit_attrs23),
}, {
.reg = PMBUS_READ_TEMPERATURE_3,
.class = PSC_TEMPERATURE,
.sfunc = PMBUS_HAVE_STATUS_TEMP,
.sbase = PB_STATUS_TEMP_BASE,
.gbit = PB_STATUS_TEMPERATURE,
- .limit = temp_limit_attrs,
- .nlimit = ARRAY_SIZE(temp_limit_attrs),
+ .limit = temp_limit_attrs23,
+ .nlimit = ARRAY_SIZE(temp_limit_attrs23),
}
};