aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-03-02 14:46:44 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2012-05-20 22:41:48 -0400
commit0531d98b1f2ec6f92074e5b2a74927b865bc605c (patch)
tree2546a596b517da316c3cd07c0e99aafec27322ce
parent76e10d158efb6d4516018846f60c2ab5501900bc (diff)
hwmon: (it87) Add support for IT8782F and IT8783E/F
Signed-off-by: Guenter Roeck <linux@roeck-us.net> Acked-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--Documentation/hwmon/it8728
-rw-r--r--drivers/hwmon/it87.c125
2 files changed, 118 insertions, 35 deletions
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index 23b7def21ba8..899128dfb130 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -30,6 +30,14 @@ Supported chips:
30 Prefix: 'it8728' 30 Prefix: 'it8728'
31 Addresses scanned: from Super I/O config space (8 I/O ports) 31 Addresses scanned: from Super I/O config space (8 I/O ports)
32 Datasheet: Not publicly available 32 Datasheet: Not publicly available
33 * IT8782F
34 Prefix: 'it8782'
35 Addresses scanned: from Super I/O config space (8 I/O ports)
36 Datasheet: Not publicly available
37 * IT8783E/F
38 Prefix: 'it8783'
39 Addresses scanned: from Super I/O config space (8 I/O ports)
40 Datasheet: Not publicly available
33 * SiS950 [clone of IT8705F] 41 * SiS950 [clone of IT8705F]
34 Prefix: 'it87' 42 Prefix: 'it87'
35 Addresses scanned: from Super I/O config space (8 I/O ports) 43 Addresses scanned: from Super I/O config space (8 I/O ports)
@@ -75,7 +83,8 @@ Description
75----------- 83-----------
76 84
77This driver implements support for the IT8705F, IT8712F, IT8716F, 85This driver implements support for the IT8705F, IT8712F, IT8716F,
78IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E and SiS950 chips. 86IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, IT8781F, IT8782F,
87IT8783E/F, and SiS950 chips.
79 88
80These chips are 'Super I/O chips', supporting floppy disks, infrared ports, 89These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
81joysticks and other miscellaneous stuff. For hardware monitoring, they 90joysticks and other miscellaneous stuff. For hardware monitoring, they
@@ -99,11 +108,11 @@ The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E and later IT8712F revisions
99have support for 2 additional fans. The additional fans are supported by the 108have support for 2 additional fans. The additional fans are supported by the
100driver. 109driver.
101 110
102The IT8716F, IT8718F, IT8720F and IT8721F/IT8758E, and late IT8712F and 111The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E, IT8782F, IT8783E/F, and late
103IT8705F also have optional 16-bit tachometer counters for fans 1 to 3. This 112IT8712F and IT8705F also have optional 16-bit tachometer counters for fans 1 to
104is better (no more fan clock divider mess) but not compatible with the older 1133. This is better (no more fan clock divider mess) but not compatible with the
105chips and revisions. The 16-bit tachometer mode is enabled by the driver when 114older chips and revisions. The 16-bit tachometer mode is enabled by the driver
106one of the above chips is detected. 115when one of the above chips is detected.
107 116
108The IT8726F is just bit enhanced IT8716F with additional hardware 117The IT8726F is just bit enhanced IT8716F with additional hardware
109for AMD power sequencing. Therefore the chip will appear as IT8716F 118for AMD power sequencing. Therefore the chip will appear as IT8716F
@@ -131,9 +140,10 @@ inputs can measure voltages between 0 and 4.08 volts, with a resolution of
1310.016 volt (except IT8721F/IT8758E and IT8728F: 0.012 volt.) The battery 1400.016 volt (except IT8721F/IT8758E and IT8728F: 0.012 volt.) The battery
132voltage in8 does not have limit registers. 141voltage in8 does not have limit registers.
133 142
134On the IT8721F/IT8758E, some voltage inputs are internal and scaled inside 143On the IT8721F/IT8758E, IT8782F, and IT8783E/F, some voltage inputs are
135the chip (in7, in8 and optionally in3). The driver handles this transparently 144internal and scaled inside the chip (in7 (optional for IT8782F and IT8783E/F),
136so user-space doesn't have to care. 145in8 and optionally in3). The driver handles this transparently so user-space
146doesn't have to care.
137 147
138The VID lines (IT8712F/IT8716F/IT8718F/IT8720F) encode the core voltage value: 148The VID lines (IT8712F/IT8716F/IT8718F/IT8720F) encode the core voltage value:
139the voltage level your processor should work with. This is hardcoded by 149the voltage level your processor should work with. This is hardcoded by
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 0b204e4cf51c..aebac1334ff6 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -19,6 +19,8 @@
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 * IT8728F Super I/O chip w/LPC interface
21 * IT8758E Super I/O chip w/LPC interface 21 * IT8758E Super I/O chip w/LPC interface
22 * IT8782F Super I/O chip w/LPC interface
23 * IT8783E/F Super I/O chip w/LPC interface
22 * Sis950 A clone of the IT8705F 24 * Sis950 A clone of the IT8705F
23 * 25 *
24 * Copyright (C) 2001 Chris Gauthron 26 * Copyright (C) 2001 Chris Gauthron
@@ -59,7 +61,8 @@
59 61
60#define DRVNAME "it87" 62#define DRVNAME "it87"
61 63
62enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728 }; 64enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8782,
65 it8783 };
63 66
64static unsigned short force_id; 67static unsigned short force_id;
65module_param(force_id, ushort, 0); 68module_param(force_id, ushort, 0);
@@ -137,13 +140,18 @@ static inline void superio_exit(void)
137#define IT8721F_DEVID 0x8721 140#define IT8721F_DEVID 0x8721
138#define IT8726F_DEVID 0x8726 141#define IT8726F_DEVID 0x8726
139#define IT8728F_DEVID 0x8728 142#define IT8728F_DEVID 0x8728
143#define IT8782F_DEVID 0x8782
144#define IT8783E_DEVID 0x8783
140#define IT87_ACT_REG 0x30 145#define IT87_ACT_REG 0x30
141#define IT87_BASE_REG 0x60 146#define IT87_BASE_REG 0x60
142 147
143/* Logical device 7 registers (IT8712F and later) */ 148/* Logical device 7 registers (IT8712F and later) */
149#define IT87_SIO_GPIO1_REG 0x25
144#define IT87_SIO_GPIO3_REG 0x27 150#define IT87_SIO_GPIO3_REG 0x27
145#define IT87_SIO_GPIO5_REG 0x29 151#define IT87_SIO_GPIO5_REG 0x29
152#define IT87_SIO_PINX1_REG 0x2a /* Pin selection */
146#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */ 153#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */
154#define IT87_SIO_SPI_REG 0xef /* SPI function pin select */
147#define IT87_SIO_VID_REG 0xfc /* VID value */ 155#define IT87_SIO_VID_REG 0xfc /* VID value */
148#define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */ 156#define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */
149 157
@@ -304,31 +312,23 @@ static inline int has_newer_autopwm(const struct it87_data *data)
304 || data->type == it8728; 312 || data->type == it8728;
305} 313}
306 314
307static u8 in_to_reg(const struct it87_data *data, int nr, long val) 315static int adc_lsb(const struct it87_data *data, int nr)
308{ 316{
309 long lsb; 317 int lsb = has_12mv_adc(data) ? 12 : 16;
310 318 if (data->in_scaled & (1 << nr))
311 if (has_12mv_adc(data)) { 319 lsb <<= 1;
312 if (data->in_scaled & (1 << nr)) 320 return lsb;
313 lsb = 24; 321}
314 else
315 lsb = 12;
316 } else
317 lsb = 16;
318 322
319 val = DIV_ROUND_CLOSEST(val, lsb); 323static u8 in_to_reg(const struct it87_data *data, int nr, long val)
324{
325 val = DIV_ROUND_CLOSEST(val, adc_lsb(data, nr));
320 return SENSORS_LIMIT(val, 0, 255); 326 return SENSORS_LIMIT(val, 0, 255);
321} 327}
322 328
323static int in_from_reg(const struct it87_data *data, int nr, int val) 329static int in_from_reg(const struct it87_data *data, int nr, int val)
324{ 330{
325 if (has_12mv_adc(data)) { 331 return val * adc_lsb(data, nr);
326 if (data->in_scaled & (1 << nr))
327 return val * 24;
328 else
329 return val * 12;
330 } else
331 return val * 16;
332} 332}
333 333
334static inline u8 FAN_TO_REG(long rpm, int div) 334static inline u8 FAN_TO_REG(long rpm, int div)
@@ -407,7 +407,9 @@ static inline int has_16bit_fans(const struct it87_data *data)
407 || data->type == it8718 407 || data->type == it8718
408 || data->type == it8720 408 || data->type == it8720
409 || data->type == it8721 409 || data->type == it8721
410 || data->type == it8728; 410 || data->type == it8728
411 || data->type == it8782
412 || data->type == it8783;
411} 413}
412 414
413static inline int has_old_autopwm(const struct it87_data *data) 415static inline int has_old_autopwm(const struct it87_data *data)
@@ -1651,6 +1653,12 @@ static int __init it87_find(unsigned short *address,
1651 case IT8728F_DEVID: 1653 case IT8728F_DEVID:
1652 sio_data->type = it8728; 1654 sio_data->type = it8728;
1653 break; 1655 break;
1656 case IT8782F_DEVID:
1657 sio_data->type = it8782;
1658 break;
1659 case IT8783E_DEVID:
1660 sio_data->type = it8783;
1661 break;
1654 case 0xffff: /* No device at all */ 1662 case 0xffff: /* No device at all */
1655 goto exit; 1663 goto exit;
1656 default: 1664 default:
@@ -1686,16 +1694,68 @@ static int __init it87_find(unsigned short *address,
1686 /* The IT8705F has a different LD number for GPIO */ 1694 /* The IT8705F has a different LD number for GPIO */
1687 superio_select(5); 1695 superio_select(5);
1688 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; 1696 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
1697 } else if (sio_data->type == it8783) {
1698 int reg25, reg27, reg2A, reg2C, regEF;
1699 bool uart6;
1700
1701 sio_data->skip_vid = 1; /* No VID */
1702
1703 superio_select(GPIO);
1704
1705 reg25 = superio_inb(IT87_SIO_GPIO1_REG);
1706 reg27 = superio_inb(IT87_SIO_GPIO3_REG);
1707 reg2A = superio_inb(IT87_SIO_PINX1_REG);
1708 reg2C = superio_inb(IT87_SIO_PINX2_REG);
1709 regEF = superio_inb(IT87_SIO_SPI_REG);
1710
1711 uart6 = reg2C & (1 << 2);
1712
1713 /* Check if fan3 is there or not */
1714 if ((reg27 & (1 << 0)) || !uart6)
1715 sio_data->skip_fan |= (1 << 2);
1716 if ((reg25 & (1 << 4))
1717 || (!(reg2A & (1 << 1)) && (regEF & (1 << 0))))
1718 sio_data->skip_pwm |= (1 << 2);
1719
1720 /* Check if fan2 is there or not */
1721 if (reg27 & (1 << 7))
1722 sio_data->skip_fan |= (1 << 1);
1723 if (reg27 & (1 << 3))
1724 sio_data->skip_pwm |= (1 << 1);
1725
1726 /* VIN5 */
1727 if ((reg27 & (1 << 0)) || uart6)
1728 ; /* No VIN5 */
1729
1730 /* VIN6 */
1731 if ((reg27 & (1 << 1)) || uart6)
1732 ; /* No VIN6 */
1733
1734 /*
1735 * VIN7
1736 * Does not depend on bit 2 of Reg2C, contrary to datasheet.
1737 */
1738 if (reg27 & (1 << 2))
1739 ; /* No VIN7 (unless internal) */
1740
1741 if (reg2C & (1 << 0))
1742 sio_data->internal |= (1 << 0);
1743 if (reg2C & (1 << 1))
1744 sio_data->internal |= (1 << 1);
1745
1746 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
1747
1689 } else { 1748 } else {
1690 int reg; 1749 int reg;
1691 1750
1692 superio_select(GPIO); 1751 superio_select(GPIO);
1693 1752
1694 reg = superio_inb(IT87_SIO_GPIO3_REG); 1753 reg = superio_inb(IT87_SIO_GPIO3_REG);
1695 if (sio_data->type == it8721 || sio_data->type == it8728) { 1754 if (sio_data->type == it8721 || sio_data->type == it8728 ||
1755 sio_data->type == it8782) {
1696 /* 1756 /*
1697 * The IT8721F/IT8758E doesn't have VID pins at all, 1757 * IT8721F/IT8758E, and IT8782F don't have VID pins
1698 * not sure about the IT8728F. 1758 * at all, not sure about the IT8728F.
1699 */ 1759 */
1700 sio_data->skip_vid = 1; 1760 sio_data->skip_vid = 1;
1701 } else { 1761 } else {
@@ -1733,8 +1793,13 @@ static int __init it87_find(unsigned short *address,
1733 * configured, even though the IT8720F datasheet claims 1793 * configured, even though the IT8720F datasheet claims
1734 * that the internal routing of VCCH to VIN7 is the default 1794 * that the internal routing of VCCH to VIN7 is the default
1735 * setting. So we force the internal routing in this case. 1795 * setting. So we force the internal routing in this case.
1796 *
1797 * On IT8782F, VIN7 is multiplexed with one of the UART6 pins.
1798 * If UART6 is enabled, re-route VIN7 to the internal divider.
1736 */ 1799 */
1737 if (sio_data->type == it8720 && !(reg & (1 << 1))) { 1800 if ((sio_data->type == it8720 ||
1801 (sio_data->type == it8782 && (reg & (1 << 2))))
1802 && !(reg & (1 << 1))) {
1738 reg |= (1 << 1); 1803 reg |= (1 << 1);
1739 superio_outb(IT87_SIO_PINX2_REG, reg); 1804 superio_outb(IT87_SIO_PINX2_REG, reg);
1740 pr_notice("Routing internal VCCH to in7\n"); 1805 pr_notice("Routing internal VCCH to in7\n");
@@ -1823,6 +1888,8 @@ static int __devinit it87_probe(struct platform_device *pdev)
1823 "it8720", 1888 "it8720",
1824 "it8721", 1889 "it8721",
1825 "it8728", 1890 "it8728",
1891 "it8782",
1892 "it8783",
1826 }; 1893 };
1827 1894
1828 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1895 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -1867,6 +1934,11 @@ static int __devinit it87_probe(struct platform_device *pdev)
1867 data->in_scaled |= (1 << 7); /* in7 is VSB */ 1934 data->in_scaled |= (1 << 7); /* in7 is VSB */
1868 if (sio_data->internal & (1 << 2)) 1935 if (sio_data->internal & (1 << 2))
1869 data->in_scaled |= (1 << 8); /* in8 is Vbat */ 1936 data->in_scaled |= (1 << 8); /* in8 is Vbat */
1937 } else if (sio_data->type == it8782 || sio_data->type == it8783) {
1938 if (sio_data->internal & (1 << 0))
1939 data->in_scaled |= (1 << 3); /* in3 is VCC5V */
1940 if (sio_data->internal & (1 << 1))
1941 data->in_scaled |= (1 << 7); /* in7 is VCCH5V */
1870 } 1942 }
1871 1943
1872 /* Initialize the IT87 chip */ 1944 /* Initialize the IT87 chip */
@@ -2143,8 +2215,9 @@ static void __devinit it87_init_device(struct platform_device *pdev)
2143 it87_write_value(data, IT87_REG_FAN_16BIT, 2215 it87_write_value(data, IT87_REG_FAN_16BIT,
2144 tmp | 0x07); 2216 tmp | 0x07);
2145 } 2217 }
2146 /* IT8705F only supports three fans. */ 2218 /* IT8705F, IT8782F, and IT8783E/F only support three fans. */
2147 if (data->type != it87) { 2219 if (data->type != it87 && data->type != it8782 &&
2220 data->type != it8783) {
2148 if (tmp & (1 << 4)) 2221 if (tmp & (1 << 4))
2149 data->has_fan |= (1 << 3); /* fan4 enabled */ 2222 data->has_fan |= (1 << 3); /* fan4 enabled */
2150 if (tmp & (1 << 5)) 2223 if (tmp & (1 << 5))