aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2006-08-28 08:37:19 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-28 18:31:13 -0400
commit87673dd735b8e089b7f2830edd353aa5f5e743ad (patch)
tree030b275650c5d8c79285bc3f7b0ba8f1c2cc25b6 /drivers/hwmon/it87.c
parent8ab4ec3ef45cc2facbe14c733ef7230e7d94fcf2 (diff)
it87: Add support for the IT8718F
it87: Add support for the IT8718F The IT8718F is a Super-I/O chip with integrated hardware monitoring functions. It is very similar to the IT8716F, so adding support to the it87 driver was pretty straightforward. The most significant difference is that the IT8718F has up to 8 VID pins, instead of 6 for the older chips. For the IT8718F, the VID value can only be read from Super-I/O space. Userspace support is already in lm_sensors SVN (to be soon released as 2.10.1.) Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index e9ab8a32903b..956cd553c711 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -5,6 +5,7 @@
5 Supports: IT8705F Super I/O chip w/LPC interface 5 Supports: IT8705F Super I/O chip w/LPC interface
6 IT8712F Super I/O chip w/LPC interface & SMBus 6 IT8712F Super I/O chip w/LPC interface & SMBus
7 IT8716F Super I/O chip w/LPC interface 7 IT8716F Super I/O chip w/LPC interface
8 IT8718F Super I/O chip w/LPC interface
8 Sis950 A clone of the IT8705F 9 Sis950 A clone of the IT8705F
9 10
10 Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> 11 Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com>
@@ -51,12 +52,13 @@ static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
51static unsigned short isa_address; 52static unsigned short isa_address;
52 53
53/* Insmod parameters */ 54/* Insmod parameters */
54I2C_CLIENT_INSMOD_3(it87, it8712, it8716); 55I2C_CLIENT_INSMOD_4(it87, it8712, it8716, it8718);
55 56
56#define REG 0x2e /* The register to read/write */ 57#define REG 0x2e /* The register to read/write */
57#define DEV 0x07 /* Register: Logical device select */ 58#define DEV 0x07 /* Register: Logical device select */
58#define VAL 0x2f /* The value to read/write */ 59#define VAL 0x2f /* The value to read/write */
59#define PME 0x04 /* The device with the fan registers in it */ 60#define PME 0x04 /* The device with the fan registers in it */
61#define GPIO 0x07 /* The device with the IT8718F VID value in it */
60#define DEVID 0x20 /* Register: Device ID */ 62#define DEVID 0x20 /* Register: Device ID */
61#define DEVREV 0x22 /* Register: Device Revision */ 63#define DEVREV 0x22 /* Register: Device Revision */
62 64
@@ -78,10 +80,10 @@ static int superio_inw(int reg)
78} 80}
79 81
80static inline void 82static inline void
81superio_select(void) 83superio_select(int ldn)
82{ 84{
83 outb(DEV, REG); 85 outb(DEV, REG);
84 outb(PME, VAL); 86 outb(ldn, VAL);
85} 87}
86 88
87static inline void 89static inline void
@@ -100,21 +102,27 @@ superio_exit(void)
100 outb(0x02, VAL); 102 outb(0x02, VAL);
101} 103}
102 104
105/* Logical device 4 registers */
103#define IT8712F_DEVID 0x8712 106#define IT8712F_DEVID 0x8712
104#define IT8705F_DEVID 0x8705 107#define IT8705F_DEVID 0x8705
105#define IT8716F_DEVID 0x8716 108#define IT8716F_DEVID 0x8716
109#define IT8718F_DEVID 0x8718
106#define IT87_ACT_REG 0x30 110#define IT87_ACT_REG 0x30
107#define IT87_BASE_REG 0x60 111#define IT87_BASE_REG 0x60
108 112
113/* Logical device 7 registers (IT8712F and later) */
114#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */
115#define IT87_SIO_VID_REG 0xfc /* VID value */
116
109/* Update battery voltage after every reading if true */ 117/* Update battery voltage after every reading if true */
110static int update_vbat; 118static int update_vbat;
111 119
112/* Not all BIOSes properly configure the PWM registers */ 120/* Not all BIOSes properly configure the PWM registers */
113static int fix_pwm_polarity; 121static int fix_pwm_polarity;
114 122
115/* Chip Type */ 123/* Values read from Super-I/O config space */
116
117static u16 chip_type; 124static u16 chip_type;
125static u8 vid_value;
118 126
119/* Many IT87 constants specified below */ 127/* Many IT87 constants specified below */
120 128
@@ -133,6 +141,8 @@ static u16 chip_type;
133#define IT87_REG_ALARM2 0x02 141#define IT87_REG_ALARM2 0x02
134#define IT87_REG_ALARM3 0x03 142#define IT87_REG_ALARM3 0x03
135 143
144/* The IT8718F has the VID value in a different register, in Super-I/O
145 configuration space. */
136#define IT87_REG_VID 0x0a 146#define IT87_REG_VID 0x0a
137/* Warning: register 0x0b is used for something completely different in 147/* Warning: register 0x0b is used for something completely different in
138 new chips/revisions. I suspect only 16-bit tachometer mode will work 148 new chips/revisions. I suspect only 16-bit tachometer mode will work
@@ -793,10 +803,11 @@ static int __init it87_find(unsigned short *address)
793 chip_type = superio_inw(DEVID); 803 chip_type = superio_inw(DEVID);
794 if (chip_type != IT8712F_DEVID 804 if (chip_type != IT8712F_DEVID
795 && chip_type != IT8716F_DEVID 805 && chip_type != IT8716F_DEVID
806 && chip_type != IT8718F_DEVID
796 && chip_type != IT8705F_DEVID) 807 && chip_type != IT8705F_DEVID)
797 goto exit; 808 goto exit;
798 809
799 superio_select(); 810 superio_select(PME);
800 if (!(superio_inb(IT87_ACT_REG) & 0x01)) { 811 if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
801 pr_info("it87: Device not activated, skipping\n"); 812 pr_info("it87: Device not activated, skipping\n");
802 goto exit; 813 goto exit;
@@ -812,6 +823,21 @@ static int __init it87_find(unsigned short *address)
812 pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", 823 pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
813 chip_type, *address, superio_inb(DEVREV) & 0x0f); 824 chip_type, *address, superio_inb(DEVREV) & 0x0f);
814 825
826 /* Read GPIO config and VID value from LDN 7 (GPIO) */
827 if (chip_type != IT8705F_DEVID) {
828 int reg;
829
830 superio_select(GPIO);
831 if (chip_type == it8718)
832 vid_value = superio_inb(IT87_SIO_VID_REG);
833
834 reg = superio_inb(IT87_SIO_PINX2_REG);
835 if (reg & (1 << 0))
836 pr_info("it87: in3 is VCC (+5V)\n");
837 if (reg & (1 << 1))
838 pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
839 }
840
815exit: 841exit:
816 superio_exit(); 842 superio_exit();
817 return err; 843 return err;
@@ -880,6 +906,9 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
880 case IT8716F_DEVID: 906 case IT8716F_DEVID:
881 kind = it8716; 907 kind = it8716;
882 break; 908 break;
909 case IT8718F_DEVID:
910 kind = it8718;
911 break;
883 } 912 }
884 } 913 }
885 } 914 }
@@ -900,6 +929,8 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
900 name = "it8712"; 929 name = "it8712";
901 } else if (kind == it8716) { 930 } else if (kind == it8716) {
902 name = "it8716"; 931 name = "it8716";
932 } else if (kind == it8718) {
933 name = "it8718";
903 } 934 }
904 935
905 /* Fill in the remaining client fields and put it into the global list */ 936 /* Fill in the remaining client fields and put it into the global list */
@@ -969,7 +1000,8 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
969 device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr); 1000 device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr);
970 1001
971 /* Do not create fan files for disabled fans */ 1002 /* Do not create fan files for disabled fans */
972 if (data->type == it8716) { /* 16-bit tachometers */ 1003 if (data->type == it8716 || data->type == it8718) {
1004 /* 16-bit tachometers */
973 if (data->has_fan & (1 << 0)) { 1005 if (data->has_fan & (1 << 0)) {
974 device_create_file(&new_client->dev, 1006 device_create_file(&new_client->dev,
975 &sensor_dev_attr_fan1_input16.dev_attr); 1007 &sensor_dev_attr_fan1_input16.dev_attr);
@@ -989,6 +1021,7 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
989 &sensor_dev_attr_fan3_min16.dev_attr); 1021 &sensor_dev_attr_fan3_min16.dev_attr);
990 } 1022 }
991 } else { 1023 } else {
1024 /* 8-bit tachometers with clock divider */
992 if (data->has_fan & (1 << 0)) { 1025 if (data->has_fan & (1 << 0)) {
993 device_create_file(&new_client->dev, 1026 device_create_file(&new_client->dev,
994 &sensor_dev_attr_fan1_input.dev_attr); 1027 &sensor_dev_attr_fan1_input.dev_attr);
@@ -1025,8 +1058,11 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
1025 device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr); 1058 device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr);
1026 } 1059 }
1027 1060
1028 if (data->type == it8712 || data->type == it8716) { 1061 if (data->type == it8712 || data->type == it8716
1062 || data->type == it8718) {
1029 data->vrm = vid_which_vrm(); 1063 data->vrm = vid_which_vrm();
1064 /* VID reading from Super-I/O config space if available */
1065 data->vid = vid_value;
1030 device_create_file_vrm(new_client); 1066 device_create_file_vrm(new_client);
1031 device_create_file_vid(new_client); 1067 device_create_file_vid(new_client);
1032 } 1068 }
@@ -1192,7 +1228,7 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data)
1192 data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; 1228 data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
1193 1229
1194 /* Set tachometers to 16-bit mode if needed */ 1230 /* Set tachometers to 16-bit mode if needed */
1195 if (data->type == it8716) { 1231 if (data->type == it8716 || data->type == it8718) {
1196 tmp = it87_read_value(client, IT87_REG_FAN_16BIT); 1232 tmp = it87_read_value(client, IT87_REG_FAN_16BIT);
1197 if (~tmp & 0x07 & data->has_fan) { 1233 if (~tmp & 0x07 & data->has_fan) {
1198 dev_dbg(&client->dev, 1234 dev_dbg(&client->dev,
@@ -1265,7 +1301,7 @@ static struct it87_data *it87_update_device(struct device *dev)
1265 data->fan[i] = it87_read_value(client, 1301 data->fan[i] = it87_read_value(client,
1266 IT87_REG_FAN(i)); 1302 IT87_REG_FAN(i));
1267 /* Add high byte if in 16-bit mode */ 1303 /* Add high byte if in 16-bit mode */
1268 if (data->type == it8716) { 1304 if (data->type == it8716 || data->type == it8718) {
1269 data->fan[i] |= it87_read_value(client, 1305 data->fan[i] |= it87_read_value(client,
1270 IT87_REG_FANX(i)) << 8; 1306 IT87_REG_FANX(i)) << 8;
1271 data->fan_min[i] |= it87_read_value(client, 1307 data->fan_min[i] |= it87_read_value(client,
@@ -1282,7 +1318,8 @@ static struct it87_data *it87_update_device(struct device *dev)
1282 } 1318 }
1283 1319
1284 /* Newer chips don't have clock dividers */ 1320 /* Newer chips don't have clock dividers */
1285 if ((data->has_fan & 0x07) && data->type != it8716) { 1321 if ((data->has_fan & 0x07) && data->type != it8716
1322 && data->type != it8718) {
1286 i = it87_read_value(client, IT87_REG_FAN_DIV); 1323 i = it87_read_value(client, IT87_REG_FAN_DIV);
1287 data->fan_div[0] = i & 0x07; 1324 data->fan_div[0] = i & 0x07;
1288 data->fan_div[1] = (i >> 3) & 0x07; 1325 data->fan_div[1] = (i >> 3) & 0x07;
@@ -1340,7 +1377,7 @@ static void __exit sm_it87_exit(void)
1340 1377
1341 1378
1342MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>"); 1379MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>");
1343MODULE_DESCRIPTION("IT8705F/8712F/8716F, SiS950 driver"); 1380MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F, SiS950 driver");
1344module_param(update_vbat, bool, 0); 1381module_param(update_vbat, bool, 0);
1345MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); 1382MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
1346module_param(fix_pwm_polarity, bool, 0); 1383module_param(fix_pwm_polarity, bool, 0);