hwmon: (it87) Introduce support for tempX_offset sysfs attribute
Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
parent
2cece01ffd
commit
161d898ac9
|
@ -209,3 +209,12 @@ doesn't use CPU cycles.
|
||||||
Trip points must be set properly before switching to automatic fan speed
|
Trip points must be set properly before switching to automatic fan speed
|
||||||
control mode. The driver will perform basic integrity checks before
|
control mode. The driver will perform basic integrity checks before
|
||||||
actually switching to automatic control mode.
|
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.
|
||||||
|
|
|
@ -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_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 };
|
||||||
static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 };
|
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_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_MAIN_CTRL 0x13
|
||||||
#define IT87_REG_FAN_CTL 0x14
|
#define IT87_REG_FAN_CTL 0x14
|
||||||
#define IT87_REG_PWM(nr) (0x15 + (nr))
|
#define IT87_REG_PWM(nr) (0x15 + (nr))
|
||||||
|
@ -263,7 +265,7 @@ struct it87_data {
|
||||||
u16 fan[5]; /* Register values, possibly combined */
|
u16 fan[5]; /* Register values, possibly combined */
|
||||||
u16 fan_min[5]; /* Register values, possibly combined */
|
u16 fan_min[5]; /* Register values, possibly combined */
|
||||||
u8 has_temp; /* Bitfield, temp sensors enabled */
|
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 sensor; /* Register value */
|
||||||
u8 fan_div[3]; /* Register encoding, shifted right */
|
u8 fan_div[3]; /* Register encoding, shifted right */
|
||||||
u8 vid; /* Register encoding, combined */
|
u8 vid; /* Register encoding, combined */
|
||||||
|
@ -312,6 +314,17 @@ static inline int has_newer_autopwm(const struct it87_data *data)
|
||||||
|| data->type == it8728;
|
|| 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)
|
static int adc_lsb(const struct it87_data *data, int nr)
|
||||||
{
|
{
|
||||||
int lsb = has_12mv_adc(data) ? 12 : 16;
|
int lsb = has_12mv_adc(data) ? 12 : 16;
|
||||||
|
@ -546,16 +559,34 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
|
||||||
int index = sattr->index;
|
int index = sattr->index;
|
||||||
struct it87_data *data = dev_get_drvdata(dev);
|
struct it87_data *data = dev_get_drvdata(dev);
|
||||||
long val;
|
long val;
|
||||||
|
u8 reg, regval;
|
||||||
|
|
||||||
if (kstrtol(buf, 10, &val) < 0)
|
if (kstrtol(buf, 10, &val) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&data->update_lock);
|
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);
|
data->temp[nr][index] = TEMP_TO_REG(val);
|
||||||
it87_write_value(data,
|
it87_write_value(data, reg, data->temp[nr][index]);
|
||||||
index == 1 ? IT87_REG_TEMP_LOW(nr)
|
|
||||||
: IT87_REG_TEMP_HIGH(nr),
|
|
||||||
data->temp[nr][index]);
|
|
||||||
mutex_unlock(&data->update_lock);
|
mutex_unlock(&data->update_lock);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -565,16 +596,22 @@ static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
||||||
0, 1);
|
0, 1);
|
||||||
static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
||||||
0, 2);
|
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_input, S_IRUGO, show_temp, NULL, 1, 0);
|
||||||
static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
||||||
1, 1);
|
1, 1);
|
||||||
static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
||||||
1, 2);
|
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_input, S_IRUGO, show_temp, NULL, 2, 0);
|
||||||
static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
||||||
2, 1);
|
2, 1);
|
||||||
static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
|
||||||
2, 2);
|
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,
|
static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
|
@ -1429,6 +1466,12 @@ static const struct attribute_group it87_group_temp[3] = {
|
||||||
{ .attrs = it87_attributes_temp[2] },
|
{ .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[] = {
|
static struct attribute *it87_attributes[] = {
|
||||||
&dev_attr_alarms.attr,
|
&dev_attr_alarms.attr,
|
||||||
&sensor_dev_attr_intrusion0_alarm.dev_attr.attr,
|
&sensor_dev_attr_intrusion0_alarm.dev_attr.attr,
|
||||||
|
@ -1899,6 +1942,9 @@ static void it87_remove_files(struct device *dev)
|
||||||
if (!(data->has_temp & (1 << i)))
|
if (!(data->has_temp & (1 << i)))
|
||||||
continue;
|
continue;
|
||||||
sysfs_remove_group(&dev->kobj, &it87_group_temp[i]);
|
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)
|
if (sio_data->beep_pin)
|
||||||
sysfs_remove_file(&dev->kobj,
|
sysfs_remove_file(&dev->kobj,
|
||||||
it87_attributes_temp_beep[i]);
|
it87_attributes_temp_beep[i]);
|
||||||
|
@ -2026,6 +2072,12 @@ static int it87_probe(struct platform_device *pdev)
|
||||||
err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]);
|
err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]);
|
||||||
if (err)
|
if (err)
|
||||||
goto error;
|
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) {
|
if (sio_data->beep_pin) {
|
||||||
err = sysfs_create_file(&dev->kobj,
|
err = sysfs_create_file(&dev->kobj,
|
||||||
it87_attributes_temp_beep[i]);
|
it87_attributes_temp_beep[i]);
|
||||||
|
@ -2383,6 +2435,10 @@ static struct it87_data *it87_update_device(struct device *dev)
|
||||||
it87_read_value(data, IT87_REG_TEMP_LOW(i));
|
it87_read_value(data, IT87_REG_TEMP_LOW(i));
|
||||||
data->temp[i][2] =
|
data->temp[i][2] =
|
||||||
it87_read_value(data, IT87_REG_TEMP_HIGH(i));
|
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 */
|
/* Newer chips don't have clock dividers */
|
||||||
|
|
Loading…
Reference in New Issue