|
@@ -793,53 +793,6 @@ static void pmbus_add_label(struct pmbus_data *data,
|
|
|
data->num_labels++;
|
|
|
}
|
|
|
|
|
|
-static const int pmbus_temp_registers[] = {
|
|
|
- PMBUS_READ_TEMPERATURE_1,
|
|
|
- PMBUS_READ_TEMPERATURE_2,
|
|
|
- PMBUS_READ_TEMPERATURE_3
|
|
|
-};
|
|
|
-
|
|
|
-static const int pmbus_temp_flags[] = {
|
|
|
- PMBUS_HAVE_TEMP,
|
|
|
- PMBUS_HAVE_TEMP2,
|
|
|
- PMBUS_HAVE_TEMP3
|
|
|
-};
|
|
|
-
|
|
|
-static const int pmbus_fan_registers[] = {
|
|
|
- PMBUS_READ_FAN_SPEED_1,
|
|
|
- PMBUS_READ_FAN_SPEED_2,
|
|
|
- PMBUS_READ_FAN_SPEED_3,
|
|
|
- PMBUS_READ_FAN_SPEED_4
|
|
|
-};
|
|
|
-
|
|
|
-static const int pmbus_fan_config_registers[] = {
|
|
|
- PMBUS_FAN_CONFIG_12,
|
|
|
- PMBUS_FAN_CONFIG_12,
|
|
|
- PMBUS_FAN_CONFIG_34,
|
|
|
- PMBUS_FAN_CONFIG_34
|
|
|
-};
|
|
|
-
|
|
|
-static const int pmbus_fan_status_registers[] = {
|
|
|
- PMBUS_STATUS_FAN_12,
|
|
|
- PMBUS_STATUS_FAN_12,
|
|
|
- PMBUS_STATUS_FAN_34,
|
|
|
- PMBUS_STATUS_FAN_34
|
|
|
-};
|
|
|
-
|
|
|
-static const u32 pmbus_fan_flags[] = {
|
|
|
- PMBUS_HAVE_FAN12,
|
|
|
- PMBUS_HAVE_FAN12,
|
|
|
- PMBUS_HAVE_FAN34,
|
|
|
- PMBUS_HAVE_FAN34
|
|
|
-};
|
|
|
-
|
|
|
-static const u32 pmbus_fan_status_flags[] = {
|
|
|
- PMBUS_HAVE_STATUS_FAN12,
|
|
|
- PMBUS_HAVE_STATUS_FAN12,
|
|
|
- PMBUS_HAVE_STATUS_FAN34,
|
|
|
- PMBUS_HAVE_STATUS_FAN34
|
|
|
-};
|
|
|
-
|
|
|
/*
|
|
|
* Determine maximum number of sensors, booleans, and labels.
|
|
|
* To keep things simple, only make a rough high estimate.
|
|
@@ -900,499 +853,431 @@ static void pmbus_find_max_attr(struct i2c_client *client,
|
|
|
/*
|
|
|
* Search for attributes. Allocate sensors, booleans, and labels as needed.
|
|
|
*/
|
|
|
-static void pmbus_find_attributes(struct i2c_client *client,
|
|
|
- struct pmbus_data *data)
|
|
|
-{
|
|
|
- const struct pmbus_driver_info *info = data->info;
|
|
|
- int page, i0, i1, in_index;
|
|
|
|
|
|
- /*
|
|
|
- * Input voltage sensors
|
|
|
- */
|
|
|
- in_index = 1;
|
|
|
- if (info->func[0] & PMBUS_HAVE_VIN) {
|
|
|
- bool have_alarm = false;
|
|
|
-
|
|
|
- i0 = data->num_sensors;
|
|
|
- pmbus_add_label(data, "in", in_index, "vin", 0);
|
|
|
- pmbus_add_sensor(data, "in", "input", in_index, 0,
|
|
|
- PMBUS_READ_VIN, PSC_VOLTAGE_IN, true, true);
|
|
|
- if (pmbus_check_word_register(client, 0,
|
|
|
- PMBUS_VIN_UV_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "in", "min", in_index,
|
|
|
- 0, PMBUS_VIN_UV_WARN_LIMIT,
|
|
|
- PSC_VOLTAGE_IN, false, false);
|
|
|
- if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
|
|
|
- pmbus_add_boolean_reg(data, "in", "min_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_INPUT_BASE,
|
|
|
- PB_VOLTAGE_UV_WARNING);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, 0,
|
|
|
- PMBUS_VIN_UV_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "in", "lcrit", in_index,
|
|
|
- 0, PMBUS_VIN_UV_FAULT_LIMIT,
|
|
|
- PSC_VOLTAGE_IN, false, false);
|
|
|
- if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
|
|
|
- pmbus_add_boolean_reg(data, "in", "lcrit_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_INPUT_BASE,
|
|
|
- PB_VOLTAGE_UV_FAULT);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, 0,
|
|
|
- PMBUS_VIN_OV_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "in", "max", in_index,
|
|
|
- 0, PMBUS_VIN_OV_WARN_LIMIT,
|
|
|
- PSC_VOLTAGE_IN, false, false);
|
|
|
- if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
|
|
|
- pmbus_add_boolean_reg(data, "in", "max_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_INPUT_BASE,
|
|
|
- PB_VOLTAGE_OV_WARNING);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, 0,
|
|
|
- PMBUS_VIN_OV_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "in", "crit", in_index,
|
|
|
- 0, PMBUS_VIN_OV_FAULT_LIMIT,
|
|
|
- PSC_VOLTAGE_IN, false, false);
|
|
|
- if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
|
|
|
- pmbus_add_boolean_reg(data, "in", "crit_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_INPUT_BASE,
|
|
|
- PB_VOLTAGE_OV_FAULT);
|
|
|
+/*
|
|
|
+ * The pmbus_limit_attr structure describes a single limit attribute
|
|
|
+ * and its associated alarm attribute.
|
|
|
+ */
|
|
|
+struct pmbus_limit_attr {
|
|
|
+ u8 reg; /* Limit register */
|
|
|
+ const char *attr; /* Attribute name */
|
|
|
+ const char *alarm; /* Alarm attribute name */
|
|
|
+ u32 sbit; /* Alarm attribute status bit */
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * The pmbus_sensor_attr structure describes one sensor attribute. This
|
|
|
+ * description includes a reference to the associated limit attributes.
|
|
|
+ */
|
|
|
+struct pmbus_sensor_attr {
|
|
|
+ u8 reg; /* sensor register */
|
|
|
+ enum pmbus_sensor_classes class;/* sensor class */
|
|
|
+ const char *label; /* sensor label */
|
|
|
+ bool paged; /* true if paged sensor */
|
|
|
+ bool update; /* true if update needed */
|
|
|
+ bool compare; /* true if compare function needed */
|
|
|
+ u32 func; /* sensor mask */
|
|
|
+ u32 sfunc; /* sensor status mask */
|
|
|
+ int sbase; /* status base register */
|
|
|
+ u32 gbit; /* generic status bit */
|
|
|
+ const struct pmbus_limit_attr *limit;/* limit registers */
|
|
|
+ int nlimit; /* # of limit registers */
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * Add a set of limit attributes and, if supported, the associated
|
|
|
+ * alarm attributes.
|
|
|
+ */
|
|
|
+static bool pmbus_add_limit_attrs(struct i2c_client *client,
|
|
|
+ struct pmbus_data *data,
|
|
|
+ const struct pmbus_driver_info *info,
|
|
|
+ const char *name, int index, int page,
|
|
|
+ int cbase,
|
|
|
+ const struct pmbus_sensor_attr *attr)
|
|
|
+{
|
|
|
+ const struct pmbus_limit_attr *l = attr->limit;
|
|
|
+ int nlimit = attr->nlimit;
|
|
|
+ bool have_alarm = false;
|
|
|
+ int i, cindex;
|
|
|
+
|
|
|
+ for (i = 0; i < nlimit; i++) {
|
|
|
+ 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,
|
|
|
+ false);
|
|
|
+ if (info->func[page] & attr->sfunc) {
|
|
|
+ if (attr->compare) {
|
|
|
+ pmbus_add_boolean_cmp(data, name,
|
|
|
+ l->alarm, index,
|
|
|
+ cbase, cindex,
|
|
|
+ attr->sbase + page, l->sbit);
|
|
|
+ } else {
|
|
|
+ pmbus_add_boolean_reg(data, name,
|
|
|
+ l->alarm, index,
|
|
|
+ attr->sbase + page, l->sbit);
|
|
|
+ }
|
|
|
have_alarm = true;
|
|
|
}
|
|
|
}
|
|
|
- /*
|
|
|
- * Add generic alarm attribute only if there are no individual
|
|
|
- * attributes.
|
|
|
- */
|
|
|
- if (!have_alarm)
|
|
|
- pmbus_add_boolean_reg(data, "in", "alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_BASE,
|
|
|
- PB_STATUS_VIN_UV);
|
|
|
- in_index++;
|
|
|
- }
|
|
|
- if (info->func[0] & PMBUS_HAVE_VCAP) {
|
|
|
- pmbus_add_label(data, "in", in_index, "vcap", 0);
|
|
|
- pmbus_add_sensor(data, "in", "input", in_index, 0,
|
|
|
- PMBUS_READ_VCAP, PSC_VOLTAGE_IN, true, true);
|
|
|
- in_index++;
|
|
|
+ l++;
|
|
|
}
|
|
|
+ return have_alarm;
|
|
|
+}
|
|
|
|
|
|
- /*
|
|
|
- * Output voltage sensors
|
|
|
- */
|
|
|
- for (page = 0; page < info->pages; page++) {
|
|
|
- bool have_alarm = false;
|
|
|
-
|
|
|
- if (!(info->func[page] & PMBUS_HAVE_VOUT))
|
|
|
- continue;
|
|
|
-
|
|
|
- i0 = data->num_sensors;
|
|
|
- pmbus_add_label(data, "in", in_index, "vout", page + 1);
|
|
|
- pmbus_add_sensor(data, "in", "input", in_index, page,
|
|
|
- PMBUS_READ_VOUT, PSC_VOLTAGE_OUT, true, true);
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_VOUT_UV_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "in", "min", in_index, page,
|
|
|
- PMBUS_VOUT_UV_WARN_LIMIT,
|
|
|
- PSC_VOLTAGE_OUT, false, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
|
|
|
- pmbus_add_boolean_reg(data, "in", "min_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_VOUT_BASE +
|
|
|
- page,
|
|
|
- PB_VOLTAGE_UV_WARNING);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_VOUT_UV_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "in", "lcrit", in_index, page,
|
|
|
- PMBUS_VOUT_UV_FAULT_LIMIT,
|
|
|
- PSC_VOLTAGE_OUT, false, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
|
|
|
- pmbus_add_boolean_reg(data, "in", "lcrit_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_VOUT_BASE +
|
|
|
- page,
|
|
|
- PB_VOLTAGE_UV_FAULT);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_VOUT_OV_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "in", "max", in_index, page,
|
|
|
- PMBUS_VOUT_OV_WARN_LIMIT,
|
|
|
- PSC_VOLTAGE_OUT, false, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
|
|
|
- pmbus_add_boolean_reg(data, "in", "max_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_VOUT_BASE +
|
|
|
- page,
|
|
|
- PB_VOLTAGE_OV_WARNING);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_VOUT_OV_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "in", "crit", in_index, page,
|
|
|
- PMBUS_VOUT_OV_FAULT_LIMIT,
|
|
|
- PSC_VOLTAGE_OUT, false, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
|
|
|
- pmbus_add_boolean_reg(data, "in", "crit_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_VOUT_BASE +
|
|
|
- page,
|
|
|
- PB_VOLTAGE_OV_FAULT);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
+static void pmbus_add_sensor_attrs_one(struct i2c_client *client,
|
|
|
+ struct pmbus_data *data,
|
|
|
+ const struct pmbus_driver_info *info,
|
|
|
+ const char *name,
|
|
|
+ int index, int page,
|
|
|
+ const struct pmbus_sensor_attr *attr)
|
|
|
+{
|
|
|
+ bool have_alarm;
|
|
|
+ int cbase = data->num_sensors;
|
|
|
+
|
|
|
+ if (attr->label)
|
|
|
+ pmbus_add_label(data, name, index, attr->label,
|
|
|
+ attr->paged ? page + 1 : 0);
|
|
|
+ pmbus_add_sensor(data, name, "input", index, page, attr->reg,
|
|
|
+ attr->class, true, true);
|
|
|
+ if (attr->sfunc) {
|
|
|
+ have_alarm = pmbus_add_limit_attrs(client, data, info, name,
|
|
|
+ index, page, cbase, attr);
|
|
|
/*
|
|
|
* Add generic alarm attribute only if there are no individual
|
|
|
- * attributes.
|
|
|
+ * alarm attributes, and if there is a global alarm bit.
|
|
|
*/
|
|
|
- if (!have_alarm)
|
|
|
- pmbus_add_boolean_reg(data, "in", "alarm",
|
|
|
- in_index,
|
|
|
+ if (!have_alarm && attr->gbit)
|
|
|
+ pmbus_add_boolean_reg(data, name, "alarm", index,
|
|
|
PB_STATUS_BASE + page,
|
|
|
- PB_STATUS_VOUT_OV);
|
|
|
- in_index++;
|
|
|
+ attr->gbit);
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- /*
|
|
|
- * Current sensors
|
|
|
- */
|
|
|
+static void pmbus_add_sensor_attrs(struct i2c_client *client,
|
|
|
+ struct pmbus_data *data,
|
|
|
+ const char *name,
|
|
|
+ const struct pmbus_sensor_attr *attrs,
|
|
|
+ int nattrs)
|
|
|
+{
|
|
|
+ const struct pmbus_driver_info *info = data->info;
|
|
|
+ int index, i;
|
|
|
|
|
|
- /*
|
|
|
- * Input current sensors
|
|
|
- */
|
|
|
- in_index = 1;
|
|
|
- if (info->func[0] & PMBUS_HAVE_IIN) {
|
|
|
- i0 = data->num_sensors;
|
|
|
- pmbus_add_label(data, "curr", in_index, "iin", 0);
|
|
|
- pmbus_add_sensor(data, "curr", "input", in_index, 0,
|
|
|
- PMBUS_READ_IIN, PSC_CURRENT_IN, true, true);
|
|
|
- if (pmbus_check_word_register(client, 0,
|
|
|
- PMBUS_IIN_OC_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "curr", "max", in_index,
|
|
|
- 0, PMBUS_IIN_OC_WARN_LIMIT,
|
|
|
- PSC_CURRENT_IN, false, false);
|
|
|
- if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
|
|
|
- pmbus_add_boolean_reg(data, "curr", "max_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_INPUT_BASE,
|
|
|
- PB_IIN_OC_WARNING);
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, 0,
|
|
|
- PMBUS_IIN_OC_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "curr", "crit", in_index,
|
|
|
- 0, PMBUS_IIN_OC_FAULT_LIMIT,
|
|
|
- PSC_CURRENT_IN, false, false);
|
|
|
- if (info->func[0] & PMBUS_HAVE_STATUS_INPUT)
|
|
|
- pmbus_add_boolean_reg(data, "curr",
|
|
|
- "crit_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_INPUT_BASE,
|
|
|
- PB_IIN_OC_FAULT);
|
|
|
+ index = 1;
|
|
|
+ for (i = 0; i < nattrs; i++) {
|
|
|
+ int page, pages;
|
|
|
+
|
|
|
+ pages = attrs->paged ? info->pages : 1;
|
|
|
+ for (page = 0; page < pages; page++) {
|
|
|
+ if (!(info->func[page] & attrs->func))
|
|
|
+ continue;
|
|
|
+ pmbus_add_sensor_attrs_one(client, data, info, name,
|
|
|
+ index, page, attrs);
|
|
|
+ index++;
|
|
|
}
|
|
|
- in_index++;
|
|
|
+ attrs++;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- /*
|
|
|
- * Output current sensors
|
|
|
- */
|
|
|
- for (page = 0; page < info->pages; page++) {
|
|
|
- bool have_alarm = false;
|
|
|
-
|
|
|
- if (!(info->func[page] & PMBUS_HAVE_IOUT))
|
|
|
- continue;
|
|
|
-
|
|
|
- i0 = data->num_sensors;
|
|
|
- pmbus_add_label(data, "curr", in_index, "iout", page + 1);
|
|
|
- pmbus_add_sensor(data, "curr", "input", in_index, page,
|
|
|
- PMBUS_READ_IOUT, PSC_CURRENT_OUT, true, true);
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_IOUT_OC_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "curr", "max", in_index, page,
|
|
|
- PMBUS_IOUT_OC_WARN_LIMIT,
|
|
|
- PSC_CURRENT_OUT, false, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) {
|
|
|
- pmbus_add_boolean_reg(data, "curr", "max_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_IOUT_BASE +
|
|
|
- page, PB_IOUT_OC_WARNING);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_IOUT_UC_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "curr", "lcrit", in_index, page,
|
|
|
- PMBUS_IOUT_UC_FAULT_LIMIT,
|
|
|
- PSC_CURRENT_OUT, false, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) {
|
|
|
- pmbus_add_boolean_reg(data, "curr",
|
|
|
- "lcrit_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_IOUT_BASE +
|
|
|
- page, PB_IOUT_UC_FAULT);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_IOUT_OC_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "curr", "crit", in_index, page,
|
|
|
- PMBUS_IOUT_OC_FAULT_LIMIT,
|
|
|
- PSC_CURRENT_OUT, false, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) {
|
|
|
- pmbus_add_boolean_reg(data, "curr",
|
|
|
- "crit_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_IOUT_BASE +
|
|
|
- page, PB_IOUT_OC_FAULT);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- /*
|
|
|
- * Add generic alarm attribute only if there are no individual
|
|
|
- * attributes.
|
|
|
- */
|
|
|
- if (!have_alarm)
|
|
|
- pmbus_add_boolean_reg(data, "curr", "alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_BASE + page,
|
|
|
- PB_STATUS_IOUT_OC);
|
|
|
- in_index++;
|
|
|
+static const struct pmbus_limit_attr vin_limit_attrs[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_VIN_UV_WARN_LIMIT,
|
|
|
+ .attr = "min",
|
|
|
+ .alarm = "min_alarm",
|
|
|
+ .sbit = PB_VOLTAGE_UV_WARNING,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_VIN_UV_FAULT_LIMIT,
|
|
|
+ .attr = "lcrit",
|
|
|
+ .alarm = "lcrit_alarm",
|
|
|
+ .sbit = PB_VOLTAGE_UV_FAULT,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_VIN_OV_WARN_LIMIT,
|
|
|
+ .attr = "max",
|
|
|
+ .alarm = "max_alarm",
|
|
|
+ .sbit = PB_VOLTAGE_OV_WARNING,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_VIN_OV_FAULT_LIMIT,
|
|
|
+ .attr = "crit",
|
|
|
+ .alarm = "crit_alarm",
|
|
|
+ .sbit = PB_VOLTAGE_OV_FAULT,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static const struct pmbus_limit_attr vout_limit_attrs[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_VOUT_UV_WARN_LIMIT,
|
|
|
+ .attr = "min",
|
|
|
+ .alarm = "min_alarm",
|
|
|
+ .sbit = PB_VOLTAGE_UV_WARNING,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_VOUT_UV_FAULT_LIMIT,
|
|
|
+ .attr = "lcrit",
|
|
|
+ .alarm = "lcrit_alarm",
|
|
|
+ .sbit = PB_VOLTAGE_UV_FAULT,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_VOUT_OV_WARN_LIMIT,
|
|
|
+ .attr = "max",
|
|
|
+ .alarm = "max_alarm",
|
|
|
+ .sbit = PB_VOLTAGE_OV_WARNING,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_VOUT_OV_FAULT_LIMIT,
|
|
|
+ .attr = "crit",
|
|
|
+ .alarm = "crit_alarm",
|
|
|
+ .sbit = PB_VOLTAGE_OV_FAULT,
|
|
|
}
|
|
|
+};
|
|
|
|
|
|
- /*
|
|
|
- * Power sensors
|
|
|
- */
|
|
|
- /*
|
|
|
- * Input Power sensors
|
|
|
- */
|
|
|
- in_index = 1;
|
|
|
- if (info->func[0] & PMBUS_HAVE_PIN) {
|
|
|
- i0 = data->num_sensors;
|
|
|
- pmbus_add_label(data, "power", in_index, "pin", 0);
|
|
|
- pmbus_add_sensor(data, "power", "input", in_index,
|
|
|
- 0, PMBUS_READ_PIN, PSC_POWER, true, true);
|
|
|
- if (pmbus_check_word_register(client, 0,
|
|
|
- PMBUS_PIN_OP_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "power", "max", in_index,
|
|
|
- 0, PMBUS_PIN_OP_WARN_LIMIT, PSC_POWER,
|
|
|
- false, false);
|
|
|
- if (info->func[0] & PMBUS_HAVE_STATUS_INPUT)
|
|
|
- pmbus_add_boolean_reg(data, "power",
|
|
|
- "alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_INPUT_BASE,
|
|
|
- PB_PIN_OP_WARNING);
|
|
|
- }
|
|
|
- in_index++;
|
|
|
+static const struct pmbus_sensor_attr voltage_attributes[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_READ_VIN,
|
|
|
+ .class = PSC_VOLTAGE_IN,
|
|
|
+ .label = "vin",
|
|
|
+ .func = PMBUS_HAVE_VIN,
|
|
|
+ .sfunc = PMBUS_HAVE_STATUS_INPUT,
|
|
|
+ .sbase = PB_STATUS_INPUT_BASE,
|
|
|
+ .gbit = PB_STATUS_VIN_UV,
|
|
|
+ .limit = vin_limit_attrs,
|
|
|
+ .nlimit = ARRAY_SIZE(vin_limit_attrs),
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_READ_VCAP,
|
|
|
+ .class = PSC_VOLTAGE_IN,
|
|
|
+ .label = "vcap",
|
|
|
+ .func = PMBUS_HAVE_VCAP,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_READ_VOUT,
|
|
|
+ .class = PSC_VOLTAGE_OUT,
|
|
|
+ .label = "vout",
|
|
|
+ .paged = true,
|
|
|
+ .func = PMBUS_HAVE_VOUT,
|
|
|
+ .sfunc = PMBUS_HAVE_STATUS_VOUT,
|
|
|
+ .sbase = PB_STATUS_VOUT_BASE,
|
|
|
+ .gbit = PB_STATUS_VOUT_OV,
|
|
|
+ .limit = vout_limit_attrs,
|
|
|
+ .nlimit = ARRAY_SIZE(vout_limit_attrs),
|
|
|
}
|
|
|
+};
|
|
|
|
|
|
- /*
|
|
|
- * Output Power sensors
|
|
|
- */
|
|
|
- for (page = 0; page < info->pages; page++) {
|
|
|
- bool need_alarm = false;
|
|
|
+/* Current attributes */
|
|
|
+
|
|
|
+static const struct pmbus_limit_attr iin_limit_attrs[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_IIN_OC_WARN_LIMIT,
|
|
|
+ .attr = "max",
|
|
|
+ .alarm = "max_alarm",
|
|
|
+ .sbit = PB_IIN_OC_WARNING,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_IIN_OC_FAULT_LIMIT,
|
|
|
+ .attr = "crit",
|
|
|
+ .alarm = "crit_alarm",
|
|
|
+ .sbit = PB_IIN_OC_FAULT,
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- if (!(info->func[page] & PMBUS_HAVE_POUT))
|
|
|
- continue;
|
|
|
+static const struct pmbus_limit_attr iout_limit_attrs[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_IOUT_OC_WARN_LIMIT,
|
|
|
+ .attr = "max",
|
|
|
+ .alarm = "max_alarm",
|
|
|
+ .sbit = PB_IOUT_OC_WARNING,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_IOUT_UC_FAULT_LIMIT,
|
|
|
+ .attr = "lcrit",
|
|
|
+ .alarm = "lcrit_alarm",
|
|
|
+ .sbit = PB_IOUT_UC_FAULT,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_IOUT_OC_FAULT_LIMIT,
|
|
|
+ .attr = "crit",
|
|
|
+ .alarm = "crit_alarm",
|
|
|
+ .sbit = PB_IOUT_OC_FAULT,
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- i0 = data->num_sensors;
|
|
|
- pmbus_add_label(data, "power", in_index, "pout", page + 1);
|
|
|
- pmbus_add_sensor(data, "power", "input", in_index, page,
|
|
|
- PMBUS_READ_POUT, PSC_POWER, true, true);
|
|
|
- /*
|
|
|
- * Per hwmon sysfs API, power_cap is to be used to limit output
|
|
|
- * power.
|
|
|
- * We have two registers related to maximum output power,
|
|
|
- * PMBUS_POUT_MAX and PMBUS_POUT_OP_WARN_LIMIT.
|
|
|
- * PMBUS_POUT_MAX matches the powerX_cap attribute definition.
|
|
|
- * There is no attribute in the API to match
|
|
|
- * PMBUS_POUT_OP_WARN_LIMIT. We use powerX_max for now.
|
|
|
- */
|
|
|
- if (pmbus_check_word_register(client, page, PMBUS_POUT_MAX)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "power", "cap", in_index, page,
|
|
|
- PMBUS_POUT_MAX, PSC_POWER,
|
|
|
- false, false);
|
|
|
- need_alarm = true;
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_POUT_OP_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "power", "max", in_index, page,
|
|
|
- PMBUS_POUT_OP_WARN_LIMIT, PSC_POWER,
|
|
|
- false, false);
|
|
|
- need_alarm = true;
|
|
|
- }
|
|
|
- if (need_alarm && (info->func[page] & PMBUS_HAVE_STATUS_IOUT))
|
|
|
- pmbus_add_boolean_reg(data, "power", "alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_IOUT_BASE + page,
|
|
|
- PB_POUT_OP_WARNING
|
|
|
- | PB_POWER_LIMITING);
|
|
|
-
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_POUT_OP_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "power", "crit", in_index, page,
|
|
|
- PMBUS_POUT_OP_FAULT_LIMIT, PSC_POWER,
|
|
|
- false, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_IOUT)
|
|
|
- pmbus_add_boolean_reg(data, "power",
|
|
|
- "crit_alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_IOUT_BASE
|
|
|
- + page,
|
|
|
- PB_POUT_OP_FAULT);
|
|
|
- }
|
|
|
- in_index++;
|
|
|
+static const struct pmbus_sensor_attr current_attributes[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_READ_IIN,
|
|
|
+ .class = PSC_CURRENT_IN,
|
|
|
+ .label = "iin",
|
|
|
+ .func = PMBUS_HAVE_IIN,
|
|
|
+ .sfunc = PMBUS_HAVE_STATUS_INPUT,
|
|
|
+ .sbase = PB_STATUS_INPUT_BASE,
|
|
|
+ .limit = iin_limit_attrs,
|
|
|
+ .nlimit = ARRAY_SIZE(iin_limit_attrs),
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_READ_IOUT,
|
|
|
+ .class = PSC_CURRENT_OUT,
|
|
|
+ .label = "iout",
|
|
|
+ .paged = true,
|
|
|
+ .func = PMBUS_HAVE_IOUT,
|
|
|
+ .sfunc = PMBUS_HAVE_STATUS_IOUT,
|
|
|
+ .sbase = PB_STATUS_IOUT_BASE,
|
|
|
+ .gbit = PB_STATUS_IOUT_OC,
|
|
|
+ .limit = iout_limit_attrs,
|
|
|
+ .nlimit = ARRAY_SIZE(iout_limit_attrs),
|
|
|
}
|
|
|
+};
|
|
|
|
|
|
- /*
|
|
|
- * Temperature sensors
|
|
|
- */
|
|
|
- in_index = 1;
|
|
|
- for (page = 0; page < info->pages; page++) {
|
|
|
- int t;
|
|
|
+/* Power attributes */
|
|
|
|
|
|
- for (t = 0; t < ARRAY_SIZE(pmbus_temp_registers); t++) {
|
|
|
- bool have_alarm = false;
|
|
|
+static const struct pmbus_limit_attr pin_limit_attrs[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_PIN_OP_WARN_LIMIT,
|
|
|
+ .attr = "max",
|
|
|
+ .alarm = "alarm",
|
|
|
+ .sbit = PB_PIN_OP_WARNING,
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- /*
|
|
|
- * A PMBus chip may support any combination of
|
|
|
- * temperature registers on any page. So we can not
|
|
|
- * abort after a failure to detect a register, but have
|
|
|
- * to continue checking for all registers on all pages.
|
|
|
- */
|
|
|
- if (!(info->func[page] & pmbus_temp_flags[t]))
|
|
|
- continue;
|
|
|
+static const struct pmbus_limit_attr pout_limit_attrs[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_POUT_MAX,
|
|
|
+ .attr = "cap",
|
|
|
+ .alarm = "cap_alarm",
|
|
|
+ .sbit = PB_POWER_LIMITING,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_POUT_OP_WARN_LIMIT,
|
|
|
+ .attr = "max",
|
|
|
+ .alarm = "max_alarm",
|
|
|
+ .sbit = PB_POUT_OP_WARNING,
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_POUT_OP_FAULT_LIMIT,
|
|
|
+ .attr = "crit",
|
|
|
+ .alarm = "crit_alarm",
|
|
|
+ .sbit = PB_POUT_OP_FAULT,
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- if (!pmbus_check_word_register
|
|
|
- (client, page, pmbus_temp_registers[t]))
|
|
|
- continue;
|
|
|
+static const struct pmbus_sensor_attr power_attributes[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_READ_PIN,
|
|
|
+ .class = PSC_POWER,
|
|
|
+ .label = "pin",
|
|
|
+ .func = PMBUS_HAVE_PIN,
|
|
|
+ .sfunc = PMBUS_HAVE_STATUS_INPUT,
|
|
|
+ .sbase = PB_STATUS_INPUT_BASE,
|
|
|
+ .limit = pin_limit_attrs,
|
|
|
+ .nlimit = ARRAY_SIZE(pin_limit_attrs),
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_READ_POUT,
|
|
|
+ .class = PSC_POWER,
|
|
|
+ .label = "pout",
|
|
|
+ .paged = true,
|
|
|
+ .func = PMBUS_HAVE_POUT,
|
|
|
+ .sfunc = PMBUS_HAVE_STATUS_IOUT,
|
|
|
+ .sbase = PB_STATUS_IOUT_BASE,
|
|
|
+ .limit = pout_limit_attrs,
|
|
|
+ .nlimit = ARRAY_SIZE(pout_limit_attrs),
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- i0 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "temp", "input", in_index, page,
|
|
|
- pmbus_temp_registers[t],
|
|
|
- PSC_TEMPERATURE, true, true);
|
|
|
+/* Temperature atributes */
|
|
|
+
|
|
|
+static const struct pmbus_limit_attr temp_limit_attrs[] = {
|
|
|
+ {
|
|
|
+ .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,
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- /*
|
|
|
- * PMBus provides only one status register for TEMP1-3.
|
|
|
- * Thus, we can not use the status register to determine
|
|
|
- * which of the three sensors actually caused an alarm.
|
|
|
- * Always compare current temperature against the limit
|
|
|
- * registers to determine alarm conditions for a
|
|
|
- * specific sensor.
|
|
|
- *
|
|
|
- * Since there is only one set of limit registers for
|
|
|
- * up to three temperature sensors, we need to update
|
|
|
- * all limit registers after the limit was changed for
|
|
|
- * one of the sensors. This ensures that correct limits
|
|
|
- * are reported for all temperature sensors.
|
|
|
- */
|
|
|
- if (pmbus_check_word_register
|
|
|
- (client, page, PMBUS_UT_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "temp", "min", in_index,
|
|
|
- page, PMBUS_UT_WARN_LIMIT,
|
|
|
- PSC_TEMPERATURE, true, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
|
|
|
- pmbus_add_boolean_cmp(data, "temp",
|
|
|
- "min_alarm", in_index, i1, i0,
|
|
|
- PB_STATUS_TEMP_BASE + page,
|
|
|
- PB_TEMP_UT_WARNING);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_UT_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "temp", "lcrit",
|
|
|
- in_index, page,
|
|
|
- PMBUS_UT_FAULT_LIMIT,
|
|
|
- PSC_TEMPERATURE, true, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
|
|
|
- pmbus_add_boolean_cmp(data, "temp",
|
|
|
- "lcrit_alarm", in_index, i1, i0,
|
|
|
- PB_STATUS_TEMP_BASE + page,
|
|
|
- PB_TEMP_UT_FAULT);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register
|
|
|
- (client, page, PMBUS_OT_WARN_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "temp", "max", in_index,
|
|
|
- page, PMBUS_OT_WARN_LIMIT,
|
|
|
- PSC_TEMPERATURE, true, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
|
|
|
- pmbus_add_boolean_cmp(data, "temp",
|
|
|
- "max_alarm", in_index, i0, i1,
|
|
|
- PB_STATUS_TEMP_BASE + page,
|
|
|
- PB_TEMP_OT_WARNING);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pmbus_check_word_register(client, page,
|
|
|
- PMBUS_OT_FAULT_LIMIT)) {
|
|
|
- i1 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "temp", "crit", in_index,
|
|
|
- page, PMBUS_OT_FAULT_LIMIT,
|
|
|
- PSC_TEMPERATURE, true, false);
|
|
|
- if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
|
|
|
- pmbus_add_boolean_cmp(data, "temp",
|
|
|
- "crit_alarm", in_index, i0, i1,
|
|
|
- PB_STATUS_TEMP_BASE + page,
|
|
|
- PB_TEMP_OT_FAULT);
|
|
|
- have_alarm = true;
|
|
|
- }
|
|
|
- }
|
|
|
- /*
|
|
|
- * Last resort - we were not able to create any alarm
|
|
|
- * registers. Report alarm for all sensors using the
|
|
|
- * status register temperature alarm bit.
|
|
|
- */
|
|
|
- if (!have_alarm)
|
|
|
- pmbus_add_boolean_reg(data, "temp", "alarm",
|
|
|
- in_index,
|
|
|
- PB_STATUS_BASE + page,
|
|
|
- PB_STATUS_TEMPERATURE);
|
|
|
- in_index++;
|
|
|
- }
|
|
|
+static const struct pmbus_sensor_attr temp_attributes[] = {
|
|
|
+ {
|
|
|
+ .reg = PMBUS_READ_TEMPERATURE_1,
|
|
|
+ .class = PSC_TEMPERATURE,
|
|
|
+ .paged = true,
|
|
|
+ .update = true,
|
|
|
+ .compare = true,
|
|
|
+ .func = PMBUS_HAVE_TEMP,
|
|
|
+ .sfunc = PMBUS_HAVE_STATUS_TEMP,
|
|
|
+ .sbase = PB_STATUS_TEMP_BASE,
|
|
|
+ .gbit = PB_STATUS_TEMPERATURE,
|
|
|
+ .limit = temp_limit_attrs,
|
|
|
+ .nlimit = ARRAY_SIZE(temp_limit_attrs),
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_READ_TEMPERATURE_2,
|
|
|
+ .class = PSC_TEMPERATURE,
|
|
|
+ .paged = true,
|
|
|
+ .update = true,
|
|
|
+ .compare = true,
|
|
|
+ .func = PMBUS_HAVE_TEMP2,
|
|
|
+ .sfunc = PMBUS_HAVE_STATUS_TEMP,
|
|
|
+ .sbase = PB_STATUS_TEMP_BASE,
|
|
|
+ .gbit = PB_STATUS_TEMPERATURE,
|
|
|
+ .limit = temp_limit_attrs,
|
|
|
+ .nlimit = ARRAY_SIZE(temp_limit_attrs),
|
|
|
+ }, {
|
|
|
+ .reg = PMBUS_READ_TEMPERATURE_3,
|
|
|
+ .class = PSC_TEMPERATURE,
|
|
|
+ .paged = true,
|
|
|
+ .update = true,
|
|
|
+ .compare = true,
|
|
|
+ .func = PMBUS_HAVE_TEMP3,
|
|
|
+ .sfunc = PMBUS_HAVE_STATUS_TEMP,
|
|
|
+ .sbase = PB_STATUS_TEMP_BASE,
|
|
|
+ .gbit = PB_STATUS_TEMPERATURE,
|
|
|
+ .limit = temp_limit_attrs,
|
|
|
+ .nlimit = ARRAY_SIZE(temp_limit_attrs),
|
|
|
}
|
|
|
+};
|
|
|
+
|
|
|
+static const int pmbus_fan_registers[] = {
|
|
|
+ PMBUS_READ_FAN_SPEED_1,
|
|
|
+ PMBUS_READ_FAN_SPEED_2,
|
|
|
+ PMBUS_READ_FAN_SPEED_3,
|
|
|
+ PMBUS_READ_FAN_SPEED_4
|
|
|
+};
|
|
|
+
|
|
|
+static const int pmbus_fan_config_registers[] = {
|
|
|
+ PMBUS_FAN_CONFIG_12,
|
|
|
+ PMBUS_FAN_CONFIG_12,
|
|
|
+ PMBUS_FAN_CONFIG_34,
|
|
|
+ PMBUS_FAN_CONFIG_34
|
|
|
+};
|
|
|
+
|
|
|
+static const int pmbus_fan_status_registers[] = {
|
|
|
+ PMBUS_STATUS_FAN_12,
|
|
|
+ PMBUS_STATUS_FAN_12,
|
|
|
+ PMBUS_STATUS_FAN_34,
|
|
|
+ PMBUS_STATUS_FAN_34
|
|
|
+};
|
|
|
+
|
|
|
+static const u32 pmbus_fan_flags[] = {
|
|
|
+ PMBUS_HAVE_FAN12,
|
|
|
+ PMBUS_HAVE_FAN12,
|
|
|
+ PMBUS_HAVE_FAN34,
|
|
|
+ PMBUS_HAVE_FAN34
|
|
|
+};
|
|
|
+
|
|
|
+static const u32 pmbus_fan_status_flags[] = {
|
|
|
+ PMBUS_HAVE_STATUS_FAN12,
|
|
|
+ PMBUS_HAVE_STATUS_FAN12,
|
|
|
+ PMBUS_HAVE_STATUS_FAN34,
|
|
|
+ PMBUS_HAVE_STATUS_FAN34
|
|
|
+};
|
|
|
+
|
|
|
+/* Fans */
|
|
|
+static void pmbus_add_fan_attributes(struct i2c_client *client,
|
|
|
+ struct pmbus_data *data)
|
|
|
+{
|
|
|
+ const struct pmbus_driver_info *info = data->info;
|
|
|
+ int index = 1;
|
|
|
+ int page;
|
|
|
|
|
|
- /*
|
|
|
- * Fans
|
|
|
- */
|
|
|
- in_index = 1;
|
|
|
for (page = 0; page < info->pages; page++) {
|
|
|
int f;
|
|
|
|
|
@@ -1419,8 +1304,7 @@ static void pmbus_find_attributes(struct i2c_client *client,
|
|
|
(!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4)))))
|
|
|
continue;
|
|
|
|
|
|
- i0 = data->num_sensors;
|
|
|
- pmbus_add_sensor(data, "fan", "input", in_index, page,
|
|
|
+ pmbus_add_sensor(data, "fan", "input", index, page,
|
|
|
pmbus_fan_registers[f], PSC_FAN, true,
|
|
|
true);
|
|
|
|
|
@@ -1438,17 +1322,40 @@ static void pmbus_find_attributes(struct i2c_client *client,
|
|
|
else
|
|
|
base = PB_STATUS_FAN_BASE + page;
|
|
|
pmbus_add_boolean_reg(data, "fan", "alarm",
|
|
|
- in_index, base,
|
|
|
+ index, base,
|
|
|
PB_FAN_FAN1_WARNING >> (f & 1));
|
|
|
pmbus_add_boolean_reg(data, "fan", "fault",
|
|
|
- in_index, base,
|
|
|
+ index, base,
|
|
|
PB_FAN_FAN1_FAULT >> (f & 1));
|
|
|
}
|
|
|
- in_index++;
|
|
|
+ index++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void pmbus_find_attributes(struct i2c_client *client,
|
|
|
+ struct pmbus_data *data)
|
|
|
+{
|
|
|
+ /* Voltage sensors */
|
|
|
+ pmbus_add_sensor_attrs(client, data, "in", voltage_attributes,
|
|
|
+ ARRAY_SIZE(voltage_attributes));
|
|
|
+
|
|
|
+ /* Current sensors */
|
|
|
+ pmbus_add_sensor_attrs(client, data, "curr", current_attributes,
|
|
|
+ ARRAY_SIZE(current_attributes));
|
|
|
+
|
|
|
+ /* Power sensors */
|
|
|
+ pmbus_add_sensor_attrs(client, data, "power", power_attributes,
|
|
|
+ ARRAY_SIZE(power_attributes));
|
|
|
+
|
|
|
+ /* Temperature sensors */
|
|
|
+ pmbus_add_sensor_attrs(client, data, "temp", temp_attributes,
|
|
|
+ ARRAY_SIZE(temp_attributes));
|
|
|
+
|
|
|
+ /* Fans */
|
|
|
+ pmbus_add_fan_attributes(client, data);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Identify chip parameters.
|
|
|
* This function is called for all chips.
|