Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 347356
b: refs/heads/master
c: 161d898
h: refs/heads/master
v: v3
  • Loading branch information
Guenter Roeck authored and Jean Delvare committed Dec 19, 2012
1 parent af2e57a commit f9563e2
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2cece01ffd622ab65a4f5a6704e3a74c1174d2fa
refs/heads/master: 161d898ac974818156afe48d755578bfd0d6e7c0
9 changes: 9 additions & 0 deletions trunk/Documentation/hwmon/it87
Original file line number Diff line number Diff line change
Expand Up @@ -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.
66 changes: 61 additions & 5 deletions trunk/drivers/hwmon/it87.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -312,6 +314,17 @@ static inline int has_newer_autopwm(const struct it87_data *data)
|| data->type == it8728;
}

static inline int has_temp_offset(const struct it87_data *data)
{
return data->type == it8716
|| data->type == it8718
|| data->type == it8720
|| data->type == it8721
|| data->type == it8728
|| data->type == it8782
|| data->type == it8783;
}

static int adc_lsb(const struct it87_data *data, int nr)
{
int lsb = has_12mv_adc(data) ? 12 : 16;
Expand Down Expand Up @@ -546,16 +559,34 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
int index = sattr->index;
struct it87_data *data = dev_get_drvdata(dev);
long val;
u8 reg, regval;

if (kstrtol(buf, 10, &val) < 0)
return -EINVAL;

mutex_lock(&data->update_lock);

switch (index) {
default:
case 1:
reg = IT87_REG_TEMP_LOW(nr);
break;
case 2:
reg = IT87_REG_TEMP_HIGH(nr);
break;
case 3:
regval = it87_read_value(data, IT87_REG_BEEP_ENABLE);
if (!(regval & 0x80)) {
regval |= 0x80;
it87_write_value(data, IT87_REG_BEEP_ENABLE, regval);
}
data->valid = 0;
reg = IT87_REG_TEMP_OFFSET[nr];
break;
}

data->temp[nr][index] = TEMP_TO_REG(val);
it87_write_value(data,
index == 1 ? IT87_REG_TEMP_LOW(nr)
: IT87_REG_TEMP_HIGH(nr),
data->temp[nr][index]);
it87_write_value(data, reg, data->temp[nr][index]);
mutex_unlock(&data->update_lock);
return count;
}
Expand All @@ -565,16 +596,22 @@ static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
0, 1);
static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
0, 2);
static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, 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_IRUGO | S_IWUSR, show_temp, set_temp,
1, 1);
static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
1, 2);
static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, 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_IRUGO | S_IWUSR, show_temp, set_temp,
2, 1);
static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
2, 2);
static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp,
set_temp, 2, 3);

static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
char *buf)
Expand Down Expand Up @@ -1429,6 +1466,12 @@ static const struct attribute_group it87_group_temp[3] = {
{ .attrs = it87_attributes_temp[2] },
};

static struct attribute *it87_attributes_temp_offset[] = {
&sensor_dev_attr_temp1_offset.dev_attr.attr,
&sensor_dev_attr_temp2_offset.dev_attr.attr,
&sensor_dev_attr_temp3_offset.dev_attr.attr,
};

static struct attribute *it87_attributes[] = {
&dev_attr_alarms.attr,
&sensor_dev_attr_intrusion0_alarm.dev_attr.attr,
Expand Down Expand Up @@ -1899,6 +1942,9 @@ static void it87_remove_files(struct device *dev)
if (!(data->has_temp & (1 << i)))
continue;
sysfs_remove_group(&dev->kobj, &it87_group_temp[i]);
if (has_temp_offset(data))
sysfs_remove_file(&dev->kobj,
it87_attributes_temp_offset[i]);
if (sio_data->beep_pin)
sysfs_remove_file(&dev->kobj,
it87_attributes_temp_beep[i]);
Expand Down Expand Up @@ -2026,6 +2072,12 @@ static int it87_probe(struct platform_device *pdev)
err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]);
if (err)
goto error;
if (has_temp_offset(data)) {
err = sysfs_create_file(&dev->kobj,
it87_attributes_temp_offset[i]);
if (err)
goto error;
}
if (sio_data->beep_pin) {
err = sysfs_create_file(&dev->kobj,
it87_attributes_temp_beep[i]);
Expand Down Expand Up @@ -2383,6 +2435,10 @@ 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));
if (has_temp_offset(data))
data->temp[i][3] =
it87_read_value(data,
IT87_REG_TEMP_OFFSET[i]);
}

/* Newer chips don't have clock dividers */
Expand Down

0 comments on commit f9563e2

Please sign in to comment.