diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 4 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 61 |
2 files changed, 51 insertions, 14 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index cefb1adf4534..78c237f8fa0a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -186,8 +186,8 @@ config SENSORS_IT87 | |||
186 | select I2C_ISA | 186 | select I2C_ISA |
187 | select HWMON_VID | 187 | select HWMON_VID |
188 | help | 188 | help |
189 | If you say yes here you get support for ITE IT8705F, IT8712F and | 189 | If you say yes here you get support for ITE IT8705F, IT8712F, |
190 | IT8716F sensor chips, and the SiS960 clone. | 190 | IT8716F and IT8718F sensor chips, and the SiS960 clone. |
191 | 191 | ||
192 | This driver can also be built as a module. If so, the module | 192 | This driver can also be built as a module. If so, the module |
193 | will be called it87. | 193 | will be called it87. |
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 }; | |||
51 | static unsigned short isa_address; | 52 | static unsigned short isa_address; |
52 | 53 | ||
53 | /* Insmod parameters */ | 54 | /* Insmod parameters */ |
54 | I2C_CLIENT_INSMOD_3(it87, it8712, it8716); | 55 | I2C_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 | ||
80 | static inline void | 82 | static inline void |
81 | superio_select(void) | 83 | superio_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 | ||
87 | static inline void | 89 | static 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 */ |
110 | static int update_vbat; | 118 | static int update_vbat; |
111 | 119 | ||
112 | /* Not all BIOSes properly configure the PWM registers */ | 120 | /* Not all BIOSes properly configure the PWM registers */ |
113 | static int fix_pwm_polarity; | 121 | static int fix_pwm_polarity; |
114 | 122 | ||
115 | /* Chip Type */ | 123 | /* Values read from Super-I/O config space */ |
116 | |||
117 | static u16 chip_type; | 124 | static u16 chip_type; |
125 | static 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 | |||
815 | exit: | 841 | exit: |
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 | ||
1342 | MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>"); | 1379 | MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>"); |
1343 | MODULE_DESCRIPTION("IT8705F/8712F/8716F, SiS950 driver"); | 1380 | MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F, SiS950 driver"); |
1344 | module_param(update_vbat, bool, 0); | 1381 | module_param(update_vbat, bool, 0); |
1345 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); | 1382 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); |
1346 | module_param(fix_pwm_polarity, bool, 0); | 1383 | module_param(fix_pwm_polarity, bool, 0); |