summaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-12-19 16:17:01 -0500
committerJean Delvare <khali@endymion.delvare>2012-12-19 16:17:01 -0500
commit161d898ac974818156afe48d755578bfd0d6e7c0 (patch)
treea6e6b76494ec02219f2b701c0b2103e7ff1777aa /drivers/hwmon/it87.c
parent2cece01ffd622ab65a4f5a6704e3a74c1174d2fa (diff)
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>
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c66
1 files changed, 61 insertions, 5 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 21fb7f24152c..767563269182 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 };
203static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 }; 203static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 };
204static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 }; 204static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 };
205static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; 205static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
206static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 };
207
206#define IT87_REG_FAN_MAIN_CTRL 0x13 208#define IT87_REG_FAN_MAIN_CTRL 0x13
207#define IT87_REG_FAN_CTL 0x14 209#define IT87_REG_FAN_CTL 0x14
208#define IT87_REG_PWM(nr) (0x15 + (nr)) 210#define IT87_REG_PWM(nr) (0x15 + (nr))
@@ -263,7 +265,7 @@ struct it87_data {
263 u16 fan[5]; /* Register values, possibly combined */ 265 u16 fan[5]; /* Register values, possibly combined */
264 u16 fan_min[5]; /* Register values, possibly combined */ 266 u16 fan_min[5]; /* Register values, possibly combined */
265 u8 has_temp; /* Bitfield, temp sensors enabled */ 267 u8 has_temp; /* Bitfield, temp sensors enabled */
266 s8 temp[3][3]; /* [nr][0]=temp, [1]=min, [2]=max */ 268 s8 temp[3][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */
267 u8 sensor; /* Register value */ 269 u8 sensor; /* Register value */
268 u8 fan_div[3]; /* Register encoding, shifted right */ 270 u8 fan_div[3]; /* Register encoding, shifted right */
269 u8 vid; /* Register encoding, combined */ 271 u8 vid; /* Register encoding, combined */
@@ -312,6 +314,17 @@ static inline int has_newer_autopwm(const struct it87_data *data)
312 || data->type == it8728; 314 || data->type == it8728;
313} 315}
314 316
317static inline int has_temp_offset(const struct it87_data *data)
318{
319 return data->type == it8716
320 || data->type == it8718
321 || data->type == it8720
322 || data->type == it8721
323 || data->type == it8728
324 || data->type == it8782
325 || data->type == it8783;
326}
327
315static int adc_lsb(const struct it87_data *data, int nr) 328static int adc_lsb(const struct it87_data *data, int nr)
316{ 329{
317 int lsb = has_12mv_adc(data) ? 12 : 16; 330 int lsb = has_12mv_adc(data) ? 12 : 16;
@@ -546,16 +559,34 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
546 int index = sattr->index; 559 int index = sattr->index;
547 struct it87_data *data = dev_get_drvdata(dev); 560 struct it87_data *data = dev_get_drvdata(dev);
548 long val; 561 long val;
562 u8 reg, regval;
549 563
550 if (kstrtol(buf, 10, &val) < 0) 564 if (kstrtol(buf, 10, &val) < 0)
551 return -EINVAL; 565 return -EINVAL;
552 566
553 mutex_lock(&data->update_lock); 567 mutex_lock(&data->update_lock);
568
569 switch (index) {
570 default:
571 case 1:
572 reg = IT87_REG_TEMP_LOW(nr);
573 break;
574 case 2:
575 reg = IT87_REG_TEMP_HIGH(nr);
576 break;
577 case 3:
578 regval = it87_read_value(data, IT87_REG_BEEP_ENABLE);
579 if (!(regval & 0x80)) {
580 regval |= 0x80;
581 it87_write_value(data, IT87_REG_BEEP_ENABLE, regval);
582 }
583 data->valid = 0;
584 reg = IT87_REG_TEMP_OFFSET[nr];
585 break;
586 }
587
554 data->temp[nr][index] = TEMP_TO_REG(val); 588 data->temp[nr][index] = TEMP_TO_REG(val);
555 it87_write_value(data, 589 it87_write_value(data, reg, data->temp[nr][index]);
556 index == 1 ? IT87_REG_TEMP_LOW(nr)
557 : IT87_REG_TEMP_HIGH(nr),
558 data->temp[nr][index]);
559 mutex_unlock(&data->update_lock); 590 mutex_unlock(&data->update_lock);
560 return count; 591 return count;
561} 592}
@@ -565,16 +596,22 @@ static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
565 0, 1); 596 0, 1);
566static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp, 597static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
567 0, 2); 598 0, 2);
599static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, show_temp,
600 set_temp, 0, 3);
568static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0); 601static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0);
569static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp, 602static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
570 1, 1); 603 1, 1);
571static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp, 604static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
572 1, 2); 605 1, 2);
606static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, show_temp,
607 set_temp, 1, 3);
573static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0); 608static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0);
574static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp, 609static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
575 2, 1); 610 2, 1);
576static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp, 611static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
577 2, 2); 612 2, 2);
613static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp,
614 set_temp, 2, 3);
578 615
579static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, 616static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
580 char *buf) 617 char *buf)
@@ -1429,6 +1466,12 @@ static const struct attribute_group it87_group_temp[3] = {
1429 { .attrs = it87_attributes_temp[2] }, 1466 { .attrs = it87_attributes_temp[2] },
1430}; 1467};
1431 1468
1469static struct attribute *it87_attributes_temp_offset[] = {
1470 &sensor_dev_attr_temp1_offset.dev_attr.attr,
1471 &sensor_dev_attr_temp2_offset.dev_attr.attr,
1472 &sensor_dev_attr_temp3_offset.dev_attr.attr,
1473};
1474
1432static struct attribute *it87_attributes[] = { 1475static struct attribute *it87_attributes[] = {
1433 &dev_attr_alarms.attr, 1476 &dev_attr_alarms.attr,
1434 &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, 1477 &sensor_dev_attr_intrusion0_alarm.dev_attr.attr,
@@ -1899,6 +1942,9 @@ static void it87_remove_files(struct device *dev)
1899 if (!(data->has_temp & (1 << i))) 1942 if (!(data->has_temp & (1 << i)))
1900 continue; 1943 continue;
1901 sysfs_remove_group(&dev->kobj, &it87_group_temp[i]); 1944 sysfs_remove_group(&dev->kobj, &it87_group_temp[i]);
1945 if (has_temp_offset(data))
1946 sysfs_remove_file(&dev->kobj,
1947 it87_attributes_temp_offset[i]);
1902 if (sio_data->beep_pin) 1948 if (sio_data->beep_pin)
1903 sysfs_remove_file(&dev->kobj, 1949 sysfs_remove_file(&dev->kobj,
1904 it87_attributes_temp_beep[i]); 1950 it87_attributes_temp_beep[i]);
@@ -2026,6 +2072,12 @@ static int it87_probe(struct platform_device *pdev)
2026 err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]); 2072 err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]);
2027 if (err) 2073 if (err)
2028 goto error; 2074 goto error;
2075 if (has_temp_offset(data)) {
2076 err = sysfs_create_file(&dev->kobj,
2077 it87_attributes_temp_offset[i]);
2078 if (err)
2079 goto error;
2080 }
2029 if (sio_data->beep_pin) { 2081 if (sio_data->beep_pin) {
2030 err = sysfs_create_file(&dev->kobj, 2082 err = sysfs_create_file(&dev->kobj,
2031 it87_attributes_temp_beep[i]); 2083 it87_attributes_temp_beep[i]);
@@ -2383,6 +2435,10 @@ static struct it87_data *it87_update_device(struct device *dev)
2383 it87_read_value(data, IT87_REG_TEMP_LOW(i)); 2435 it87_read_value(data, IT87_REG_TEMP_LOW(i));
2384 data->temp[i][2] = 2436 data->temp[i][2] =
2385 it87_read_value(data, IT87_REG_TEMP_HIGH(i)); 2437 it87_read_value(data, IT87_REG_TEMP_HIGH(i));
2438 if (has_temp_offset(data))
2439 data->temp[i][3] =
2440 it87_read_value(data,
2441 IT87_REG_TEMP_OFFSET[i]);
2386 } 2442 }
2387 2443
2388 /* Newer chips don't have clock dividers */ 2444 /* Newer chips don't have clock dividers */