diff options
-rw-r--r-- | Documentation/hwmon/it87 | 40 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 4 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 178 |
3 files changed, 185 insertions, 37 deletions
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 9555be1ed999..aff680784222 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
@@ -13,6 +13,11 @@ Supported chips: | |||
13 | from Super I/O config space (8 I/O ports) | 13 | from Super I/O config space (8 I/O ports) |
14 | Datasheet: Publicly available at the ITE website | 14 | Datasheet: Publicly available at the ITE website |
15 | http://www.ite.com.tw/ | 15 | http://www.ite.com.tw/ |
16 | * IT8716F | ||
17 | Prefix: 'it8716' | ||
18 | Addresses scanned: from Super I/O config space (8 I/O ports) | ||
19 | Datasheet: Publicly available at the ITE website | ||
20 | http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP | ||
16 | * SiS950 [clone of IT8705F] | 21 | * SiS950 [clone of IT8705F] |
17 | Prefix: 'it87' | 22 | Prefix: 'it87' |
18 | Addresses scanned: from Super I/O config space (8 I/O ports) | 23 | Addresses scanned: from Super I/O config space (8 I/O ports) |
@@ -43,26 +48,39 @@ Module Parameters | |||
43 | Description | 48 | Description |
44 | ----------- | 49 | ----------- |
45 | 50 | ||
46 | This driver implements support for the IT8705F, IT8712F and SiS950 chips. | 51 | This driver implements support for the IT8705F, IT8712F, IT8716F and |
47 | 52 | SiS950 chips. | |
48 | This driver also supports IT8712F, which adds SMBus access, and a VID | ||
49 | input, used to report the Vcore voltage of the Pentium processor. | ||
50 | The IT8712F additionally features VID inputs. | ||
51 | 53 | ||
52 | These chips are 'Super I/O chips', supporting floppy disks, infrared ports, | 54 | These chips are 'Super I/O chips', supporting floppy disks, infrared ports, |
53 | joysticks and other miscellaneous stuff. For hardware monitoring, they | 55 | joysticks and other miscellaneous stuff. For hardware monitoring, they |
54 | include an 'environment controller' with 3 temperature sensors, 3 fan | 56 | include an 'environment controller' with 3 temperature sensors, 3 fan |
55 | rotation speed sensors, 8 voltage sensors, and associated alarms. | 57 | rotation speed sensors, 8 voltage sensors, and associated alarms. |
56 | 58 | ||
59 | The IT8712F and IT8716F additionally feature VID inputs, used to report | ||
60 | the Vcore voltage of the processor. The early IT8712F have 5 VID pins, | ||
61 | the IT8716F and late IT8712F have 6. They are shared with other functions | ||
62 | though, so the functionality may not be available on a given system. | ||
63 | The driver dumbly assume it is there. | ||
64 | |||
65 | The IT8716F and later IT8712F revisions have support for 2 additional | ||
66 | fans. They are not yet supported by the driver. | ||
67 | |||
68 | The IT8716F and late IT8712F and IT8705F also have optional 16-bit | ||
69 | tachometer counters for fans 1 to 3. This is better (no more fan | ||
70 | clock divider mess) but not compatible with the older chips and | ||
71 | revisions. For now, the driver only uses the 16-bit mode on the | ||
72 | IT8716F. | ||
73 | |||
57 | Temperatures are measured in degrees Celsius. An alarm is triggered once | 74 | Temperatures are measured in degrees Celsius. An alarm is triggered once |
58 | when the Overtemperature Shutdown limit is crossed. | 75 | when the Overtemperature Shutdown limit is crossed. |
59 | 76 | ||
60 | Fan rotation speeds are reported in RPM (rotations per minute). An alarm is | 77 | Fan rotation speeds are reported in RPM (rotations per minute). An alarm is |
61 | triggered if the rotation speed has dropped below a programmable limit. Fan | 78 | triggered if the rotation speed has dropped below a programmable limit. When |
62 | readings can be divided by a programmable divider (1, 2, 4 or 8) to give the | 79 | 16-bit tachometer counters aren't used, fan readings can be divided by |
63 | readings more range or accuracy. Not all RPM values can accurately be | 80 | a programmable divider (1, 2, 4 or 8) to give the readings more range or |
64 | represented, so some rounding is done. With a divider of 2, the lowest | 81 | accuracy. With a divider of 2, the lowest representable value is around |
65 | representable value is around 2600 RPM. | 82 | 2600 RPM. Not all RPM values can accurately be represented, so some rounding |
83 | is done. | ||
66 | 84 | ||
67 | Voltage sensors (also known as IN sensors) report their values in volts. An | 85 | Voltage sensors (also known as IN sensors) report their values in volts. An |
68 | alarm is triggered if the voltage has crossed a programmable minimum or | 86 | alarm is triggered if the voltage has crossed a programmable minimum or |
@@ -71,7 +89,7 @@ zero'; this is important for negative voltage measurements. All voltage | |||
71 | inputs can measure voltages between 0 and 4.08 volts, with a resolution of | 89 | inputs can measure voltages between 0 and 4.08 volts, with a resolution of |
72 | 0.016 volt. The battery voltage in8 does not have limit registers. | 90 | 0.016 volt. The battery voltage in8 does not have limit registers. |
73 | 91 | ||
74 | The VID lines (IT8712F only) encode the core voltage value: the voltage | 92 | The VID lines (IT8712F/IT8716F) encode the core voltage value: the voltage |
75 | level your processor should work with. This is hardcoded by the mainboard | 93 | level your processor should work with. This is hardcoded by the mainboard |
76 | and/or processor itself. It is a value in volts. | 94 | and/or processor itself. It is a value in volts. |
77 | 95 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 0e31a0c496e8..cefb1adf4534 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 IT87xx sensor chips | 189 | If you say yes here you get support for ITE IT8705F, IT8712F and |
190 | and clones: SiS960. | 190 | IT8716F 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 b0ee57492228..e7f14e61d6f2 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
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 | Sis950 A clone of the IT8705F | 8 | Sis950 A clone of the IT8705F |
8 | 9 | ||
9 | Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> | 10 | Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> |
@@ -50,7 +51,7 @@ static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; | |||
50 | static unsigned short isa_address; | 51 | static unsigned short isa_address; |
51 | 52 | ||
52 | /* Insmod parameters */ | 53 | /* Insmod parameters */ |
53 | I2C_CLIENT_INSMOD_2(it87, it8712); | 54 | I2C_CLIENT_INSMOD_3(it87, it8712, it8716); |
54 | 55 | ||
55 | #define REG 0x2e /* The register to read/write */ | 56 | #define REG 0x2e /* The register to read/write */ |
56 | #define DEV 0x07 /* Register: Logical device select */ | 57 | #define DEV 0x07 /* Register: Logical device select */ |
@@ -101,6 +102,7 @@ superio_exit(void) | |||
101 | 102 | ||
102 | #define IT8712F_DEVID 0x8712 | 103 | #define IT8712F_DEVID 0x8712 |
103 | #define IT8705F_DEVID 0x8705 | 104 | #define IT8705F_DEVID 0x8705 |
105 | #define IT8716F_DEVID 0x8716 | ||
104 | #define IT87_ACT_REG 0x30 | 106 | #define IT87_ACT_REG 0x30 |
105 | #define IT87_BASE_REG 0x60 | 107 | #define IT87_BASE_REG 0x60 |
106 | 108 | ||
@@ -132,12 +134,18 @@ static u16 chip_type; | |||
132 | #define IT87_REG_ALARM3 0x03 | 134 | #define IT87_REG_ALARM3 0x03 |
133 | 135 | ||
134 | #define IT87_REG_VID 0x0a | 136 | #define IT87_REG_VID 0x0a |
137 | /* Warning: register 0x0b is used for something completely different in | ||
138 | new chips/revisions. I suspect only 16-bit tachometer mode will work | ||
139 | for these. */ | ||
135 | #define IT87_REG_FAN_DIV 0x0b | 140 | #define IT87_REG_FAN_DIV 0x0b |
141 | #define IT87_REG_FAN_16BIT 0x0c | ||
136 | 142 | ||
137 | /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ | 143 | /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ |
138 | 144 | ||
139 | #define IT87_REG_FAN(nr) (0x0d + (nr)) | 145 | #define IT87_REG_FAN(nr) (0x0d + (nr)) |
140 | #define IT87_REG_FAN_MIN(nr) (0x10 + (nr)) | 146 | #define IT87_REG_FAN_MIN(nr) (0x10 + (nr)) |
147 | #define IT87_REG_FANX(nr) (0x18 + (nr)) | ||
148 | #define IT87_REG_FANX_MIN(nr) (0x1b + (nr)) | ||
141 | #define IT87_REG_FAN_MAIN_CTRL 0x13 | 149 | #define IT87_REG_FAN_MAIN_CTRL 0x13 |
142 | #define IT87_REG_FAN_CTL 0x14 | 150 | #define IT87_REG_FAN_CTL 0x14 |
143 | #define IT87_REG_PWM(nr) (0x15 + (nr)) | 151 | #define IT87_REG_PWM(nr) (0x15 + (nr)) |
@@ -169,7 +177,16 @@ static inline u8 FAN_TO_REG(long rpm, int div) | |||
169 | 254); | 177 | 254); |
170 | } | 178 | } |
171 | 179 | ||
180 | static inline u16 FAN16_TO_REG(long rpm) | ||
181 | { | ||
182 | if (rpm == 0) | ||
183 | return 0xffff; | ||
184 | return SENSORS_LIMIT((1350000 + rpm) / (rpm * 2), 1, 0xfffe); | ||
185 | } | ||
186 | |||
172 | #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) | 187 | #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) |
188 | /* The divider is fixed to 2 in 16-bit mode */ | ||
189 | #define FAN16_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:1350000/((val)*2)) | ||
173 | 190 | ||
174 | #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\ | 191 | #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\ |
175 | ((val)+500)/1000),-128,127)) | 192 | ((val)+500)/1000),-128,127)) |
@@ -205,8 +222,8 @@ struct it87_data { | |||
205 | u8 in[9]; /* Register value */ | 222 | u8 in[9]; /* Register value */ |
206 | u8 in_max[9]; /* Register value */ | 223 | u8 in_max[9]; /* Register value */ |
207 | u8 in_min[9]; /* Register value */ | 224 | u8 in_min[9]; /* Register value */ |
208 | u8 fan[3]; /* Register value */ | 225 | u16 fan[3]; /* Register values, possibly combined */ |
209 | u8 fan_min[3]; /* Register value */ | 226 | u16 fan_min[3]; /* Register values, possibly combined */ |
210 | u8 temp[3]; /* Register value */ | 227 | u8 temp[3]; /* Register value */ |
211 | u8 temp_high[3]; /* Register value */ | 228 | u8 temp_high[3]; /* Register value */ |
212 | u8 temp_low[3]; /* Register value */ | 229 | u8 temp_low[3]; /* Register value */ |
@@ -657,6 +674,59 @@ show_pwm_offset(1); | |||
657 | show_pwm_offset(2); | 674 | show_pwm_offset(2); |
658 | show_pwm_offset(3); | 675 | show_pwm_offset(3); |
659 | 676 | ||
677 | /* A different set of callbacks for 16-bit fans */ | ||
678 | static ssize_t show_fan16(struct device *dev, struct device_attribute *attr, | ||
679 | char *buf) | ||
680 | { | ||
681 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
682 | int nr = sensor_attr->index; | ||
683 | struct it87_data *data = it87_update_device(dev); | ||
684 | return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan[nr])); | ||
685 | } | ||
686 | |||
687 | static ssize_t show_fan16_min(struct device *dev, struct device_attribute *attr, | ||
688 | char *buf) | ||
689 | { | ||
690 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
691 | int nr = sensor_attr->index; | ||
692 | struct it87_data *data = it87_update_device(dev); | ||
693 | return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan_min[nr])); | ||
694 | } | ||
695 | |||
696 | static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr, | ||
697 | const char *buf, size_t count) | ||
698 | { | ||
699 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
700 | int nr = sensor_attr->index; | ||
701 | struct i2c_client *client = to_i2c_client(dev); | ||
702 | struct it87_data *data = i2c_get_clientdata(client); | ||
703 | int val = simple_strtol(buf, NULL, 10); | ||
704 | |||
705 | mutex_lock(&data->update_lock); | ||
706 | data->fan_min[nr] = FAN16_TO_REG(val); | ||
707 | it87_write_value(client, IT87_REG_FAN_MIN(nr), | ||
708 | data->fan_min[nr] & 0xff); | ||
709 | it87_write_value(client, IT87_REG_FANX_MIN(nr), | ||
710 | data->fan_min[nr] >> 8); | ||
711 | mutex_unlock(&data->update_lock); | ||
712 | return count; | ||
713 | } | ||
714 | |||
715 | /* We want to use the same sysfs file names as 8-bit fans, but we need | ||
716 | different variable names, so we have to use SENSOR_ATTR instead of | ||
717 | SENSOR_DEVICE_ATTR. */ | ||
718 | #define show_fan16_offset(offset) \ | ||
719 | static struct sensor_device_attribute sensor_dev_attr_fan##offset##_input16 \ | ||
720 | = SENSOR_ATTR(fan##offset##_input, S_IRUGO, \ | ||
721 | show_fan16, NULL, offset - 1); \ | ||
722 | static struct sensor_device_attribute sensor_dev_attr_fan##offset##_min16 \ | ||
723 | = SENSOR_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
724 | show_fan16_min, set_fan16_min, offset - 1) | ||
725 | |||
726 | show_fan16_offset(1); | ||
727 | show_fan16_offset(2); | ||
728 | show_fan16_offset(3); | ||
729 | |||
660 | /* Alarms */ | 730 | /* Alarms */ |
661 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) | 731 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) |
662 | { | 732 | { |
@@ -721,6 +791,7 @@ static int __init it87_find(unsigned short *address) | |||
721 | superio_enter(); | 791 | superio_enter(); |
722 | chip_type = superio_inw(DEVID); | 792 | chip_type = superio_inw(DEVID); |
723 | if (chip_type != IT8712F_DEVID | 793 | if (chip_type != IT8712F_DEVID |
794 | && chip_type != IT8716F_DEVID | ||
724 | && chip_type != IT8705F_DEVID) | 795 | && chip_type != IT8705F_DEVID) |
725 | goto exit; | 796 | goto exit; |
726 | 797 | ||
@@ -800,8 +871,16 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
800 | i = it87_read_value(new_client, IT87_REG_CHIPID); | 871 | i = it87_read_value(new_client, IT87_REG_CHIPID); |
801 | if (i == 0x90) { | 872 | if (i == 0x90) { |
802 | kind = it87; | 873 | kind = it87; |
803 | if ((is_isa) && (chip_type == IT8712F_DEVID)) | 874 | if (is_isa) { |
804 | kind = it8712; | 875 | switch (chip_type) { |
876 | case IT8712F_DEVID: | ||
877 | kind = it8712; | ||
878 | break; | ||
879 | case IT8716F_DEVID: | ||
880 | kind = it8716; | ||
881 | break; | ||
882 | } | ||
883 | } | ||
805 | } | 884 | } |
806 | else { | 885 | else { |
807 | if (kind == 0) | 886 | if (kind == 0) |
@@ -818,6 +897,8 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
818 | name = "it87"; | 897 | name = "it87"; |
819 | } else if (kind == it8712) { | 898 | } else if (kind == it8712) { |
820 | name = "it8712"; | 899 | name = "it8712"; |
900 | } else if (kind == it8716) { | ||
901 | name = "it8716"; | ||
821 | } | 902 | } |
822 | 903 | ||
823 | /* Fill in the remaining client fields and put it into the global list */ | 904 | /* Fill in the remaining client fields and put it into the global list */ |
@@ -885,15 +966,41 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
885 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_type.dev_attr); | 966 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_type.dev_attr); |
886 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_type.dev_attr); | 967 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_type.dev_attr); |
887 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr); | 968 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr); |
888 | device_create_file(&new_client->dev, &sensor_dev_attr_fan1_input.dev_attr); | 969 | |
889 | device_create_file(&new_client->dev, &sensor_dev_attr_fan2_input.dev_attr); | 970 | if (data->type == it8716) { /* 16-bit tachometers */ |
890 | device_create_file(&new_client->dev, &sensor_dev_attr_fan3_input.dev_attr); | 971 | device_create_file(&new_client->dev, |
891 | device_create_file(&new_client->dev, &sensor_dev_attr_fan1_min.dev_attr); | 972 | &sensor_dev_attr_fan1_input16.dev_attr); |
892 | device_create_file(&new_client->dev, &sensor_dev_attr_fan2_min.dev_attr); | 973 | device_create_file(&new_client->dev, |
893 | device_create_file(&new_client->dev, &sensor_dev_attr_fan3_min.dev_attr); | 974 | &sensor_dev_attr_fan2_input16.dev_attr); |
894 | device_create_file(&new_client->dev, &sensor_dev_attr_fan1_div.dev_attr); | 975 | device_create_file(&new_client->dev, |
895 | device_create_file(&new_client->dev, &sensor_dev_attr_fan2_div.dev_attr); | 976 | &sensor_dev_attr_fan3_input16.dev_attr); |
896 | device_create_file(&new_client->dev, &sensor_dev_attr_fan3_div.dev_attr); | 977 | device_create_file(&new_client->dev, |
978 | &sensor_dev_attr_fan1_min16.dev_attr); | ||
979 | device_create_file(&new_client->dev, | ||
980 | &sensor_dev_attr_fan2_min16.dev_attr); | ||
981 | device_create_file(&new_client->dev, | ||
982 | &sensor_dev_attr_fan3_min16.dev_attr); | ||
983 | } else { | ||
984 | device_create_file(&new_client->dev, | ||
985 | &sensor_dev_attr_fan1_input.dev_attr); | ||
986 | device_create_file(&new_client->dev, | ||
987 | &sensor_dev_attr_fan2_input.dev_attr); | ||
988 | device_create_file(&new_client->dev, | ||
989 | &sensor_dev_attr_fan3_input.dev_attr); | ||
990 | device_create_file(&new_client->dev, | ||
991 | &sensor_dev_attr_fan1_min.dev_attr); | ||
992 | device_create_file(&new_client->dev, | ||
993 | &sensor_dev_attr_fan2_min.dev_attr); | ||
994 | device_create_file(&new_client->dev, | ||
995 | &sensor_dev_attr_fan3_min.dev_attr); | ||
996 | device_create_file(&new_client->dev, | ||
997 | &sensor_dev_attr_fan1_div.dev_attr); | ||
998 | device_create_file(&new_client->dev, | ||
999 | &sensor_dev_attr_fan2_div.dev_attr); | ||
1000 | device_create_file(&new_client->dev, | ||
1001 | &sensor_dev_attr_fan3_div.dev_attr); | ||
1002 | } | ||
1003 | |||
897 | device_create_file(&new_client->dev, &dev_attr_alarms); | 1004 | device_create_file(&new_client->dev, &dev_attr_alarms); |
898 | if (enable_pwm_interface) { | 1005 | if (enable_pwm_interface) { |
899 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm1_enable.dev_attr); | 1006 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm1_enable.dev_attr); |
@@ -904,7 +1011,7 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
904 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr); | 1011 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr); |
905 | } | 1012 | } |
906 | 1013 | ||
907 | if (data->type == it8712) { | 1014 | if (data->type == it8712 || data->type == it8716) { |
908 | data->vrm = vid_which_vrm(); | 1015 | data->vrm = vid_which_vrm(); |
909 | device_create_file_vrm(new_client); | 1016 | device_create_file_vrm(new_client); |
910 | device_create_file_vid(new_client); | 1017 | device_create_file_vid(new_client); |
@@ -1069,6 +1176,17 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) | |||
1069 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); | 1176 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); |
1070 | } | 1177 | } |
1071 | 1178 | ||
1179 | /* Set tachometers to 16-bit mode if needed */ | ||
1180 | if (data->type == it8716) { | ||
1181 | tmp = it87_read_value(client, IT87_REG_FAN_16BIT); | ||
1182 | if ((tmp & 0x07) != 0x07) { | ||
1183 | dev_dbg(&client->dev, | ||
1184 | "Setting fan1-3 to 16-bit mode\n"); | ||
1185 | it87_write_value(client, IT87_REG_FAN_16BIT, | ||
1186 | tmp | 0x07); | ||
1187 | } | ||
1188 | } | ||
1189 | |||
1072 | /* Set current fan mode registers and the default settings for the | 1190 | /* Set current fan mode registers and the default settings for the |
1073 | * other mode registers */ | 1191 | * other mode registers */ |
1074 | for (i = 0; i < 3; i++) { | 1192 | for (i = 0; i < 3; i++) { |
@@ -1126,10 +1244,17 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1126 | data->in_max[8] = 255; | 1244 | data->in_max[8] = 255; |
1127 | 1245 | ||
1128 | for (i = 0; i < 3; i++) { | 1246 | for (i = 0; i < 3; i++) { |
1129 | data->fan[i] = | ||
1130 | it87_read_value(client, IT87_REG_FAN(i)); | ||
1131 | data->fan_min[i] = | 1247 | data->fan_min[i] = |
1132 | it87_read_value(client, IT87_REG_FAN_MIN(i)); | 1248 | it87_read_value(client, IT87_REG_FAN_MIN(i)); |
1249 | data->fan[i] = it87_read_value(client, | ||
1250 | IT87_REG_FAN(i)); | ||
1251 | /* Add high byte if in 16-bit mode */ | ||
1252 | if (data->type == it8716) { | ||
1253 | data->fan[i] |= it87_read_value(client, | ||
1254 | IT87_REG_FANX(i)) << 8; | ||
1255 | data->fan_min[i] |= it87_read_value(client, | ||
1256 | IT87_REG_FANX_MIN(i)) << 8; | ||
1257 | } | ||
1133 | } | 1258 | } |
1134 | for (i = 0; i < 3; i++) { | 1259 | for (i = 0; i < 3; i++) { |
1135 | data->temp[i] = | 1260 | data->temp[i] = |
@@ -1140,10 +1265,13 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1140 | it87_read_value(client, IT87_REG_TEMP_LOW(i)); | 1265 | it87_read_value(client, IT87_REG_TEMP_LOW(i)); |
1141 | } | 1266 | } |
1142 | 1267 | ||
1143 | i = it87_read_value(client, IT87_REG_FAN_DIV); | 1268 | /* Newer chips don't have clock dividers */ |
1144 | data->fan_div[0] = i & 0x07; | 1269 | if (data->type != it8716) { |
1145 | data->fan_div[1] = (i >> 3) & 0x07; | 1270 | i = it87_read_value(client, IT87_REG_FAN_DIV); |
1146 | data->fan_div[2] = (i & 0x40) ? 3 : 1; | 1271 | data->fan_div[0] = i & 0x07; |
1272 | data->fan_div[1] = (i >> 3) & 0x07; | ||
1273 | data->fan_div[2] = (i & 0x40) ? 3 : 1; | ||
1274 | } | ||
1147 | 1275 | ||
1148 | data->alarms = | 1276 | data->alarms = |
1149 | it87_read_value(client, IT87_REG_ALARM1) | | 1277 | it87_read_value(client, IT87_REG_ALARM1) | |
@@ -1153,9 +1281,11 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1153 | 1281 | ||
1154 | data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE); | 1282 | data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE); |
1155 | /* The 8705 does not have VID capability */ | 1283 | /* The 8705 does not have VID capability */ |
1156 | if (data->type == it8712) { | 1284 | if (data->type == it8712 || data->type == it8716) { |
1157 | data->vid = it87_read_value(client, IT87_REG_VID); | 1285 | data->vid = it87_read_value(client, IT87_REG_VID); |
1158 | data->vid &= 0x1f; | 1286 | /* The older IT8712F revisions had only 5 VID pins, |
1287 | but we assume it is always safe to read 6 bits. */ | ||
1288 | data->vid &= 0x3f; | ||
1159 | } | 1289 | } |
1160 | data->last_updated = jiffies; | 1290 | data->last_updated = jiffies; |
1161 | data->valid = 1; | 1291 | data->valid = 1; |
@@ -1194,7 +1324,7 @@ static void __exit sm_it87_exit(void) | |||
1194 | 1324 | ||
1195 | 1325 | ||
1196 | MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>"); | 1326 | MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>"); |
1197 | MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver"); | 1327 | MODULE_DESCRIPTION("IT8705F/8712F/8716F, SiS950 driver"); |
1198 | module_param(update_vbat, bool, 0); | 1328 | module_param(update_vbat, bool, 0); |
1199 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); | 1329 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); |
1200 | module_param(fix_pwm_polarity, bool, 0); | 1330 | module_param(fix_pwm_polarity, bool, 0); |