Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx> --- v2: The macro to calculate IT87_REG_TEMP_OFFSET was broken. Use array instead. When writing the temperature offset attribute, set the flag to enable it. Add documentation describing the new attributes. Documentation/hwmon/it87 | 9 +++++++++ drivers/hwmon/it87.c | 25 ++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 87850d8..92ce617 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 @@ -209,3 +209,12 @@ doesn't use CPU cycles. Trip points must be set properly before switching to automatic fan speed control mode. The driver will perform basic integrity checks before actually switching to automatic control mode. + + +Temperature offset attributes +----------------------------- + +The driver supports temp[1-3]_offset sysfs attributes to adjust the reported +temperature for thermal diodes or diode connected thermal transistors. +If a temperature sensor is configured for thermistors, the attribute values +are ignored. diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 82f7924..fe2cdd4 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -203,6 +203,8 @@ static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82 }; static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 }; static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 }; static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; +static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 }; + #define IT87_REG_FAN_MAIN_CTRL 0x13 #define IT87_REG_FAN_CTL 0x14 #define IT87_REG_PWM(nr) (0x15 + (nr)) @@ -263,7 +265,7 @@ struct it87_data { u16 fan[5]; /* Register values, possibly combined */ u16 fan_min[5]; /* Register values, possibly combined */ u8 has_temp; /* Bitfield, temp sensors enabled */ - s8 temp[3][3]; /* [nr][0]=temp, [1]=min, [2]=max */ + s8 temp[3][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */ u8 sensor; /* Register value */ u8 fan_div[3]; /* Register encoding, shifted right */ u8 vid; /* Register encoding, combined */ @@ -538,10 +540,19 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); data->temp[nr][index] = TEMP_TO_REG(val); + if (index == 3) { + u8 reg = it87_read_value(data, IT87_REG_BEEP_ENABLE); + if (!(reg & 0x80)) { + reg |= 0x80; + it87_write_value(data, IT87_REG_BEEP_ENABLE, reg); + } + } it87_write_value(data, index == 1 ? IT87_REG_TEMP_LOW(nr) - : IT87_REG_TEMP_HIGH(nr), + : index == 2 ? IT87_REG_TEMP_HIGH(nr) + : IT87_REG_TEMP_OFFSET[nr], data->temp[nr][index]); + data->valid = 0; mutex_unlock(&data->update_lock); return count; } @@ -549,12 +560,15 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGOWU, show_temp, set_temp, 0, 1); static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGOWU, show_temp, set_temp, 0, 2); +static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGOWU, show_temp, set_temp, 0, 3); static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0); static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGOWU, show_temp, set_temp, 1, 1); static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGOWU, show_temp, set_temp, 1, 2); +static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGOWU, show_temp, set_temp, 1, 3); static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0); static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGOWU, show_temp, set_temp, 2, 1); static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGOWU, show_temp, set_temp, 2, 2); +static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGOWU, show_temp, set_temp, 2, 3); static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) @@ -1376,11 +1390,12 @@ static const struct attribute_group it87_group_in[9] = { { .attrs = it87_attributes_in[8] }, }; -static struct attribute *it87_attributes_temp[3][6] = { +static struct attribute *it87_attributes_temp[3][7] = { { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_offset.dev_attr.attr, &sensor_dev_attr_temp1_type.dev_attr.attr, &sensor_dev_attr_temp1_alarm.dev_attr.attr, NULL @@ -1388,6 +1403,7 @@ static struct attribute *it87_attributes_temp[3][6] = { &sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_offset.dev_attr.attr, &sensor_dev_attr_temp2_type.dev_attr.attr, &sensor_dev_attr_temp2_alarm.dev_attr.attr, NULL @@ -1395,6 +1411,7 @@ static struct attribute *it87_attributes_temp[3][6] = { &sensor_dev_attr_temp3_input.dev_attr.attr, &sensor_dev_attr_temp3_max.dev_attr.attr, &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_offset.dev_attr.attr, &sensor_dev_attr_temp3_type.dev_attr.attr, &sensor_dev_attr_temp3_alarm.dev_attr.attr, NULL @@ -2360,6 +2377,8 @@ static struct it87_data *it87_update_device(struct device *dev) it87_read_value(data, IT87_REG_TEMP_LOW(i)); data->temp[i][2] = it87_read_value(data, IT87_REG_TEMP_HIGH(i)); + data->temp[i][3] = + it87_read_value(data, IT87_REG_TEMP_OFFSET[i]); } /* Newer chips don't have clock dividers */ -- 1.7.9.7 _______________________________________________ lm-sensors mailing list lm-sensors@xxxxxxxxxxxxxx http://lists.lm-sensors.org/mailman/listinfo/lm-sensors