aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c116
1 files changed, 94 insertions, 22 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 7a3616ccbf05..14a5d981be7d 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -15,7 +15,9 @@
15 * IT8716F Super I/O chip w/LPC interface 15 * IT8716F Super I/O chip w/LPC interface
16 * IT8718F Super I/O chip w/LPC interface 16 * IT8718F Super I/O chip w/LPC interface
17 * IT8720F Super I/O chip w/LPC interface 17 * IT8720F Super I/O chip w/LPC interface
18 * IT8721F Super I/O chip w/LPC interface
18 * IT8726F Super I/O chip w/LPC interface 19 * IT8726F Super I/O chip w/LPC interface
20 * IT8758E Super I/O chip w/LPC interface
19 * Sis950 A clone of the IT8705F 21 * Sis950 A clone of the IT8705F
20 * 22 *
21 * Copyright (C) 2001 Chris Gauthron 23 * Copyright (C) 2001 Chris Gauthron
@@ -54,7 +56,7 @@
54 56
55#define DRVNAME "it87" 57#define DRVNAME "it87"
56 58
57enum chips { it87, it8712, it8716, it8718, it8720 }; 59enum chips { it87, it8712, it8716, it8718, it8720, it8721 };
58 60
59static unsigned short force_id; 61static unsigned short force_id;
60module_param(force_id, ushort, 0); 62module_param(force_id, ushort, 0);
@@ -126,6 +128,7 @@ superio_exit(void)
126#define IT8716F_DEVID 0x8716 128#define IT8716F_DEVID 0x8716
127#define IT8718F_DEVID 0x8718 129#define IT8718F_DEVID 0x8718
128#define IT8720F_DEVID 0x8720 130#define IT8720F_DEVID 0x8720
131#define IT8721F_DEVID 0x8721
129#define IT8726F_DEVID 0x8726 132#define IT8726F_DEVID 0x8726
130#define IT87_ACT_REG 0x30 133#define IT87_ACT_REG 0x30
131#define IT87_BASE_REG 0x60 134#define IT87_BASE_REG 0x60
@@ -229,6 +232,7 @@ struct it87_data {
229 char valid; /* !=0 if following fields are valid */ 232 char valid; /* !=0 if following fields are valid */
230 unsigned long last_updated; /* In jiffies */ 233 unsigned long last_updated; /* In jiffies */
231 234
235 u16 in_scaled; /* Internal voltage sensors are scaled */
232 u8 in[9]; /* Register value */ 236 u8 in[9]; /* Register value */
233 u8 in_max[8]; /* Register value */ 237 u8 in_max[8]; /* Register value */
234 u8 in_min[8]; /* Register value */ 238 u8 in_min[8]; /* Register value */
@@ -260,8 +264,32 @@ struct it87_data {
260 s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ 264 s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */
261}; 265};
262 266
263#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8) / 16), 0, 255)) 267static u8 in_to_reg(const struct it87_data *data, int nr, long val)
264#define IN_FROM_REG(val) ((val) * 16) 268{
269 long lsb;
270
271 if (data->type == it8721) {
272 if (data->in_scaled & (1 << nr))
273 lsb = 24;
274 else
275 lsb = 12;
276 } else
277 lsb = 16;
278
279 val = DIV_ROUND_CLOSEST(val, lsb);
280 return SENSORS_LIMIT(val, 0, 255);
281}
282
283static int in_from_reg(const struct it87_data *data, int nr, int val)
284{
285 if (data->type == it8721) {
286 if (data->in_scaled & (1 << nr))
287 return val * 24;
288 else
289 return val * 12;
290 } else
291 return val * 16;
292}
265 293
266static inline u8 FAN_TO_REG(long rpm, int div) 294static inline u8 FAN_TO_REG(long rpm, int div)
267{ 295{
@@ -289,8 +317,22 @@ static inline u16 FAN16_TO_REG(long rpm)
289 ((val) + 500) / 1000), -128, 127)) 317 ((val) + 500) / 1000), -128, 127))
290#define TEMP_FROM_REG(val) ((val) * 1000) 318#define TEMP_FROM_REG(val) ((val) * 1000)
291 319
292#define PWM_TO_REG(val) ((val) >> 1) 320static u8 pwm_to_reg(const struct it87_data *data, long val)
293#define PWM_FROM_REG(val) (((val) & 0x7f) << 1) 321{
322 if (data->type == it8721)
323 return val;
324 else
325 return val >> 1;
326}
327
328static int pwm_from_reg(const struct it87_data *data, u8 reg)
329{
330 if (data->type == it8721)
331 return reg;
332 else
333 return (reg & 0x7f) << 1;
334}
335
294 336
295static int DIV_TO_REG(int val) 337static int DIV_TO_REG(int val)
296{ 338{
@@ -321,7 +363,8 @@ static inline int has_16bit_fans(const struct it87_data *data)
321 || (data->type == it8712 && data->revision >= 0x08) 363 || (data->type == it8712 && data->revision >= 0x08)
322 || data->type == it8716 364 || data->type == it8716
323 || data->type == it8718 365 || data->type == it8718
324 || data->type == it8720; 366 || data->type == it8720
367 || data->type == it8721;
325} 368}
326 369
327static inline int has_old_autopwm(const struct it87_data *data) 370static inline int has_old_autopwm(const struct it87_data *data)
@@ -359,7 +402,7 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr,
359 int nr = sensor_attr->index; 402 int nr = sensor_attr->index;
360 403
361 struct it87_data *data = it87_update_device(dev); 404 struct it87_data *data = it87_update_device(dev);
362 return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])); 405 return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in[nr]));
363} 406}
364 407
365static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, 408static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
@@ -369,7 +412,7 @@ static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
369 int nr = sensor_attr->index; 412 int nr = sensor_attr->index;
370 413
371 struct it87_data *data = it87_update_device(dev); 414 struct it87_data *data = it87_update_device(dev);
372 return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])); 415 return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in_min[nr]));
373} 416}
374 417
375static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, 418static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
@@ -379,7 +422,7 @@ static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
379 int nr = sensor_attr->index; 422 int nr = sensor_attr->index;
380 423
381 struct it87_data *data = it87_update_device(dev); 424 struct it87_data *data = it87_update_device(dev);
382 return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])); 425 return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in_max[nr]));
383} 426}
384 427
385static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, 428static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
@@ -395,7 +438,7 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
395 return -EINVAL; 438 return -EINVAL;
396 439
397 mutex_lock(&data->update_lock); 440 mutex_lock(&data->update_lock);
398 data->in_min[nr] = IN_TO_REG(val); 441 data->in_min[nr] = in_to_reg(data, nr, val);
399 it87_write_value(data, IT87_REG_VIN_MIN(nr), 442 it87_write_value(data, IT87_REG_VIN_MIN(nr),
400 data->in_min[nr]); 443 data->in_min[nr]);
401 mutex_unlock(&data->update_lock); 444 mutex_unlock(&data->update_lock);
@@ -414,7 +457,7 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
414 return -EINVAL; 457 return -EINVAL;
415 458
416 mutex_lock(&data->update_lock); 459 mutex_lock(&data->update_lock);
417 data->in_max[nr] = IN_TO_REG(val); 460 data->in_max[nr] = in_to_reg(data, nr, val);
418 it87_write_value(data, IT87_REG_VIN_MAX(nr), 461 it87_write_value(data, IT87_REG_VIN_MAX(nr),
419 data->in_max[nr]); 462 data->in_max[nr]);
420 mutex_unlock(&data->update_lock); 463 mutex_unlock(&data->update_lock);
@@ -644,7 +687,8 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
644 int nr = sensor_attr->index; 687 int nr = sensor_attr->index;
645 688
646 struct it87_data *data = it87_update_device(dev); 689 struct it87_data *data = it87_update_device(dev);
647 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm_duty[nr])); 690 return sprintf(buf, "%d\n",
691 pwm_from_reg(data, data->pwm_duty[nr]));
648} 692}
649static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, 693static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
650 char *buf) 694 char *buf)
@@ -814,7 +858,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
814 return -EINVAL; 858 return -EINVAL;
815 859
816 mutex_lock(&data->update_lock); 860 mutex_lock(&data->update_lock);
817 data->pwm_duty[nr] = PWM_TO_REG(val); 861 data->pwm_duty[nr] = pwm_to_reg(data, val);
818 /* If we are in manual mode, write the duty cycle immediately; 862 /* If we are in manual mode, write the duty cycle immediately;
819 * otherwise, just store it for later use. */ 863 * otherwise, just store it for later use. */
820 if (!(data->pwm_ctrl[nr] & 0x80)) { 864 if (!(data->pwm_ctrl[nr] & 0x80)) {
@@ -918,7 +962,8 @@ static ssize_t show_auto_pwm(struct device *dev,
918 int nr = sensor_attr->nr; 962 int nr = sensor_attr->nr;
919 int point = sensor_attr->index; 963 int point = sensor_attr->index;
920 964
921 return sprintf(buf, "%d\n", PWM_FROM_REG(data->auto_pwm[nr][point])); 965 return sprintf(buf, "%d\n",
966 pwm_from_reg(data, data->auto_pwm[nr][point]));
922} 967}
923 968
924static ssize_t set_auto_pwm(struct device *dev, 969static ssize_t set_auto_pwm(struct device *dev,
@@ -935,7 +980,7 @@ static ssize_t set_auto_pwm(struct device *dev,
935 return -EINVAL; 980 return -EINVAL;
936 981
937 mutex_lock(&data->update_lock); 982 mutex_lock(&data->update_lock);
938 data->auto_pwm[nr][point] = PWM_TO_REG(val); 983 data->auto_pwm[nr][point] = pwm_to_reg(data, val);
939 it87_write_value(data, IT87_REG_AUTO_PWM(nr, point), 984 it87_write_value(data, IT87_REG_AUTO_PWM(nr, point),
940 data->auto_pwm[nr][point]); 985 data->auto_pwm[nr][point]);
941 mutex_unlock(&data->update_lock); 986 mutex_unlock(&data->update_lock);
@@ -1205,9 +1250,16 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
1205 "5VSB", 1250 "5VSB",
1206 "Vbat", 1251 "Vbat",
1207 }; 1252 };
1253 static const char *labels_it8721[] = {
1254 "+3.3V",
1255 "3VSB",
1256 "Vbat",
1257 };
1258 struct it87_data *data = dev_get_drvdata(dev);
1208 int nr = to_sensor_dev_attr(attr)->index; 1259 int nr = to_sensor_dev_attr(attr)->index;
1209 1260
1210 return sprintf(buf, "%s\n", labels[nr]); 1261 return sprintf(buf, "%s\n", data->type == it8721 ? labels_it8721[nr]
1262 : labels[nr]);
1211} 1263}
1212static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0); 1264static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
1213static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1); 1265static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
@@ -1492,6 +1544,9 @@ static int __init it87_find(unsigned short *address,
1492 case IT8720F_DEVID: 1544 case IT8720F_DEVID:
1493 sio_data->type = it8720; 1545 sio_data->type = it8720;
1494 break; 1546 break;
1547 case IT8721F_DEVID:
1548 sio_data->type = it8721;
1549 break;
1495 case 0xffff: /* No device at all */ 1550 case 0xffff: /* No device at all */
1496 goto exit; 1551 goto exit;
1497 default: 1552 default:
@@ -1532,11 +1587,17 @@ static int __init it87_find(unsigned short *address,
1532 int reg; 1587 int reg;
1533 1588
1534 superio_select(GPIO); 1589 superio_select(GPIO);
1535 /* We need at least 4 VID pins */ 1590
1536 reg = superio_inb(IT87_SIO_GPIO3_REG); 1591 reg = superio_inb(IT87_SIO_GPIO3_REG);
1537 if (reg & 0x0f) { 1592 if (sio_data->type == it8721) {
1538 pr_info("it87: VID is disabled (pins used for GPIO)\n"); 1593 /* The IT8721F/IT8758E doesn't have VID pins at all */
1539 sio_data->skip_vid = 1; 1594 sio_data->skip_vid = 1;
1595 } else {
1596 /* We need at least 4 VID pins */
1597 if (reg & 0x0f) {
1598 pr_info("it87: VID is disabled (pins used for GPIO)\n");
1599 sio_data->skip_vid = 1;
1600 }
1540 } 1601 }
1541 1602
1542 /* Check if fan3 is there or not */ 1603 /* Check if fan3 is there or not */
@@ -1574,7 +1635,7 @@ static int __init it87_find(unsigned short *address,
1574 } 1635 }
1575 if (reg & (1 << 0)) 1636 if (reg & (1 << 0))
1576 sio_data->internal |= (1 << 0); 1637 sio_data->internal |= (1 << 0);
1577 if (reg & (1 << 1)) 1638 if ((reg & (1 << 1)) || sio_data->type == it8721)
1578 sio_data->internal |= (1 << 1); 1639 sio_data->internal |= (1 << 1);
1579 1640
1580 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; 1641 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
@@ -1652,6 +1713,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1652 "it8716", 1713 "it8716",
1653 "it8718", 1714 "it8718",
1654 "it8720", 1715 "it8720",
1716 "it8721",
1655 }; 1717 };
1656 1718
1657 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1719 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -1688,6 +1750,16 @@ static int __devinit it87_probe(struct platform_device *pdev)
1688 /* Check PWM configuration */ 1750 /* Check PWM configuration */
1689 enable_pwm_interface = it87_check_pwm(dev); 1751 enable_pwm_interface = it87_check_pwm(dev);
1690 1752
1753 /* Starting with IT8721F, we handle scaling of internal voltages */
1754 if (data->type == it8721) {
1755 if (sio_data->internal & (1 << 0))
1756 data->in_scaled |= (1 << 3); /* in3 is AVCC */
1757 if (sio_data->internal & (1 << 1))
1758 data->in_scaled |= (1 << 7); /* in7 is VSB */
1759 if (sio_data->internal & (1 << 2))
1760 data->in_scaled |= (1 << 8); /* in8 is Vbat */
1761 }
1762
1691 /* Initialize the IT87 chip */ 1763 /* Initialize the IT87 chip */
1692 it87_init_device(pdev); 1764 it87_init_device(pdev);
1693 1765
@@ -2053,7 +2125,7 @@ static struct it87_data *it87_update_device(struct device *dev)
2053 2125
2054 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); 2126 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
2055 /* The 8705 does not have VID capability. 2127 /* The 8705 does not have VID capability.
2056 The 8718 and the 8720 don't use IT87_REG_VID for the 2128 The 8718 and later don't use IT87_REG_VID for the
2057 same purpose. */ 2129 same purpose. */
2058 if (data->type == it8712 || data->type == it8716) { 2130 if (data->type == it8712 || data->type == it8716) {
2059 data->vid = it87_read_value(data, IT87_REG_VID); 2131 data->vid = it87_read_value(data, IT87_REG_VID);
@@ -2153,7 +2225,7 @@ static void __exit sm_it87_exit(void)
2153 2225
2154MODULE_AUTHOR("Chris Gauthron, " 2226MODULE_AUTHOR("Chris Gauthron, "
2155 "Jean Delvare <khali@linux-fr.org>"); 2227 "Jean Delvare <khali@linux-fr.org>");
2156MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F/8720F/8726F, SiS950 driver"); 2228MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver");
2157module_param(update_vbat, bool, 0); 2229module_param(update_vbat, bool, 0);
2158MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); 2230MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
2159module_param(fix_pwm_polarity, bool, 0); 2231module_param(fix_pwm_polarity, bool, 0);