aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2012-01-16 16:51:48 -0500
committerJean Delvare <khali@endymion.delvare>2012-01-16 16:51:48 -0500
commit16b5dda22e3798e61bb008d2329d4f4d90ef764e (patch)
treef9b00eb0982045d496835b2ab0e829995c3d94d9 /drivers/hwmon/it87.c
parentd6db23c7ce8d02896197394c1d741bdffe58ac54 (diff)
hwmon: (it87) Add IT8728F support
Until we get a datasheet for the IT8728F, treat it as fully compatible with the IT8721F, as it seems to work reasonably well. This closes kernel bug #27262. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 603ef2af2707..0054d6f9cec9 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -17,6 +17,7 @@
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 * IT8721F Super I/O chip w/LPC interface
19 * IT8726F Super I/O chip w/LPC interface 19 * IT8726F Super I/O chip w/LPC interface
20 * IT8728F Super I/O chip w/LPC interface
20 * IT8758E Super I/O chip w/LPC interface 21 * IT8758E Super I/O chip w/LPC interface
21 * Sis950 A clone of the IT8705F 22 * Sis950 A clone of the IT8705F
22 * 23 *
@@ -58,7 +59,7 @@
58 59
59#define DRVNAME "it87" 60#define DRVNAME "it87"
60 61
61enum chips { it87, it8712, it8716, it8718, it8720, it8721 }; 62enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728 };
62 63
63static unsigned short force_id; 64static unsigned short force_id;
64module_param(force_id, ushort, 0); 65module_param(force_id, ushort, 0);
@@ -135,6 +136,7 @@ static inline void superio_exit(void)
135#define IT8720F_DEVID 0x8720 136#define IT8720F_DEVID 0x8720
136#define IT8721F_DEVID 0x8721 137#define IT8721F_DEVID 0x8721
137#define IT8726F_DEVID 0x8726 138#define IT8726F_DEVID 0x8726
139#define IT8728F_DEVID 0x8728
138#define IT87_ACT_REG 0x30 140#define IT87_ACT_REG 0x30
139#define IT87_BASE_REG 0x60 141#define IT87_BASE_REG 0x60
140 142
@@ -274,11 +276,31 @@ struct it87_data {
274 s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ 276 s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */
275}; 277};
276 278
279static inline int has_12mv_adc(const struct it87_data *data)
280{
281 /*
282 * IT8721F and later have a 12 mV ADC, also with internal scaling
283 * on selected inputs.
284 */
285 return data->type == it8721
286 || data->type == it8728;
287}
288
289static inline int has_newer_autopwm(const struct it87_data *data)
290{
291 /*
292 * IT8721F and later have separate registers for the temperature
293 * mapping and the manual duty cycle.
294 */
295 return data->type == it8721
296 || data->type == it8728;
297}
298
277static u8 in_to_reg(const struct it87_data *data, int nr, long val) 299static u8 in_to_reg(const struct it87_data *data, int nr, long val)
278{ 300{
279 long lsb; 301 long lsb;
280 302
281 if (data->type == it8721) { 303 if (has_12mv_adc(data)) {
282 if (data->in_scaled & (1 << nr)) 304 if (data->in_scaled & (1 << nr))
283 lsb = 24; 305 lsb = 24;
284 else 306 else
@@ -292,7 +314,7 @@ static u8 in_to_reg(const struct it87_data *data, int nr, long val)
292 314
293static int in_from_reg(const struct it87_data *data, int nr, int val) 315static int in_from_reg(const struct it87_data *data, int nr, int val)
294{ 316{
295 if (data->type == it8721) { 317 if (has_12mv_adc(data)) {
296 if (data->in_scaled & (1 << nr)) 318 if (data->in_scaled & (1 << nr))
297 return val * 24; 319 return val * 24;
298 else 320 else
@@ -329,7 +351,7 @@ static inline u16 FAN16_TO_REG(long rpm)
329 351
330static u8 pwm_to_reg(const struct it87_data *data, long val) 352static u8 pwm_to_reg(const struct it87_data *data, long val)
331{ 353{
332 if (data->type == it8721) 354 if (has_newer_autopwm(data))
333 return val; 355 return val;
334 else 356 else
335 return val >> 1; 357 return val >> 1;
@@ -337,7 +359,7 @@ static u8 pwm_to_reg(const struct it87_data *data, long val)
337 359
338static int pwm_from_reg(const struct it87_data *data, u8 reg) 360static int pwm_from_reg(const struct it87_data *data, u8 reg)
339{ 361{
340 if (data->type == it8721) 362 if (has_newer_autopwm(data))
341 return reg; 363 return reg;
342 else 364 else
343 return (reg & 0x7f) << 1; 365 return (reg & 0x7f) << 1;
@@ -374,7 +396,8 @@ static inline int has_16bit_fans(const struct it87_data *data)
374 || data->type == it8716 396 || data->type == it8716
375 || data->type == it8718 397 || data->type == it8718
376 || data->type == it8720 398 || data->type == it8720
377 || data->type == it8721; 399 || data->type == it8721
400 || data->type == it8728;
378} 401}
379 402
380static inline int has_old_autopwm(const struct it87_data *data) 403static inline int has_old_autopwm(const struct it87_data *data)
@@ -842,7 +865,7 @@ static ssize_t set_pwm_enable(struct device *dev,
842 data->fan_main_ctrl); 865 data->fan_main_ctrl);
843 } else { 866 } else {
844 if (val == 1) /* Manual mode */ 867 if (val == 1) /* Manual mode */
845 data->pwm_ctrl[nr] = data->type == it8721 ? 868 data->pwm_ctrl[nr] = has_newer_autopwm(data) ?
846 data->pwm_temp_map[nr] : 869 data->pwm_temp_map[nr] :
847 data->pwm_duty[nr]; 870 data->pwm_duty[nr];
848 else /* Automatic mode */ 871 else /* Automatic mode */
@@ -870,7 +893,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
870 return -EINVAL; 893 return -EINVAL;
871 894
872 mutex_lock(&data->update_lock); 895 mutex_lock(&data->update_lock);
873 if (data->type == it8721) { 896 if (has_newer_autopwm(data)) {
874 /* If we are in automatic mode, the PWM duty cycle register 897 /* If we are in automatic mode, the PWM duty cycle register
875 * is read-only so we can't write the value */ 898 * is read-only so we can't write the value */
876 if (data->pwm_ctrl[nr] & 0x80) { 899 if (data->pwm_ctrl[nr] & 0x80) {
@@ -1311,8 +1334,8 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
1311 struct it87_data *data = dev_get_drvdata(dev); 1334 struct it87_data *data = dev_get_drvdata(dev);
1312 int nr = to_sensor_dev_attr(attr)->index; 1335 int nr = to_sensor_dev_attr(attr)->index;
1313 1336
1314 return sprintf(buf, "%s\n", data->type == it8721 ? labels_it8721[nr] 1337 return sprintf(buf, "%s\n", has_12mv_adc(data) ? labels_it8721[nr]
1315 : labels[nr]); 1338 : labels[nr]);
1316} 1339}
1317static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0); 1340static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
1318static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1); 1341static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
@@ -1605,6 +1628,9 @@ static int __init it87_find(unsigned short *address,
1605 case IT8721F_DEVID: 1628 case IT8721F_DEVID:
1606 sio_data->type = it8721; 1629 sio_data->type = it8721;
1607 break; 1630 break;
1631 case IT8728F_DEVID:
1632 sio_data->type = it8728;
1633 break;
1608 case 0xffff: /* No device at all */ 1634 case 0xffff: /* No device at all */
1609 goto exit; 1635 goto exit;
1610 default: 1636 default:
@@ -1646,8 +1672,11 @@ static int __init it87_find(unsigned short *address,
1646 superio_select(GPIO); 1672 superio_select(GPIO);
1647 1673
1648 reg = superio_inb(IT87_SIO_GPIO3_REG); 1674 reg = superio_inb(IT87_SIO_GPIO3_REG);
1649 if (sio_data->type == it8721) { 1675 if (sio_data->type == it8721 || sio_data->type == it8728) {
1650 /* The IT8721F/IT8758E doesn't have VID pins at all */ 1676 /*
1677 * The IT8721F/IT8758E doesn't have VID pins at all,
1678 * not sure about the IT8728F.
1679 */
1651 sio_data->skip_vid = 1; 1680 sio_data->skip_vid = 1;
1652 } else { 1681 } else {
1653 /* We need at least 4 VID pins */ 1682 /* We need at least 4 VID pins */
@@ -1692,7 +1721,8 @@ static int __init it87_find(unsigned short *address,
1692 } 1721 }
1693 if (reg & (1 << 0)) 1722 if (reg & (1 << 0))
1694 sio_data->internal |= (1 << 0); 1723 sio_data->internal |= (1 << 0);
1695 if ((reg & (1 << 1)) || sio_data->type == it8721) 1724 if ((reg & (1 << 1)) || sio_data->type == it8721 ||
1725 sio_data->type == it8728)
1696 sio_data->internal |= (1 << 1); 1726 sio_data->internal |= (1 << 1);
1697 1727
1698 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; 1728 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
@@ -1770,6 +1800,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1770 "it8718", 1800 "it8718",
1771 "it8720", 1801 "it8720",
1772 "it8721", 1802 "it8721",
1803 "it8728",
1773 }; 1804 };
1774 1805
1775 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1806 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -1807,7 +1838,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1807 enable_pwm_interface = it87_check_pwm(dev); 1838 enable_pwm_interface = it87_check_pwm(dev);
1808 1839
1809 /* Starting with IT8721F, we handle scaling of internal voltages */ 1840 /* Starting with IT8721F, we handle scaling of internal voltages */
1810 if (data->type == it8721) { 1841 if (has_12mv_adc(data)) {
1811 if (sio_data->internal & (1 << 0)) 1842 if (sio_data->internal & (1 << 0))
1812 data->in_scaled |= (1 << 3); /* in3 is AVCC */ 1843 data->in_scaled |= (1 << 3); /* in3 is AVCC */
1813 if (sio_data->internal & (1 << 1)) 1844 if (sio_data->internal & (1 << 1))
@@ -2093,7 +2124,7 @@ static void __devinit it87_init_device(struct platform_device *pdev)
2093static void it87_update_pwm_ctrl(struct it87_data *data, int nr) 2124static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
2094{ 2125{
2095 data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); 2126 data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
2096 if (data->type == it8721) { 2127 if (has_newer_autopwm(data)) {
2097 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; 2128 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
2098 data->pwm_duty[nr] = it87_read_value(data, 2129 data->pwm_duty[nr] = it87_read_value(data,
2099 IT87_REG_PWM_DUTY(nr)); 2130 IT87_REG_PWM_DUTY(nr));