diff options
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r-- | drivers/hwmon/it87.c | 83 |
1 files changed, 51 insertions, 32 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e7f14e61d6f2..0317e441ca51 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -222,6 +222,7 @@ struct it87_data { | |||
222 | u8 in[9]; /* Register value */ | 222 | u8 in[9]; /* Register value */ |
223 | u8 in_max[9]; /* Register value */ | 223 | u8 in_max[9]; /* Register value */ |
224 | u8 in_min[9]; /* Register value */ | 224 | u8 in_min[9]; /* Register value */ |
225 | u8 has_fan; /* Bitfield, fans enabled */ | ||
225 | u16 fan[3]; /* Register values, possibly combined */ | 226 | u16 fan[3]; /* Register values, possibly combined */ |
226 | u16 fan_min[3]; /* Register values, possibly combined */ | 227 | u16 fan_min[3]; /* Register values, possibly combined */ |
227 | u8 temp[3]; /* Register value */ | 228 | u8 temp[3]; /* Register value */ |
@@ -967,38 +968,51 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
967 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_type.dev_attr); | 968 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_type.dev_attr); |
968 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr); | 969 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr); |
969 | 970 | ||
971 | /* Do not create fan files for disabled fans */ | ||
970 | if (data->type == it8716) { /* 16-bit tachometers */ | 972 | if (data->type == it8716) { /* 16-bit tachometers */ |
971 | device_create_file(&new_client->dev, | 973 | if (data->has_fan & (1 << 0)) { |
972 | &sensor_dev_attr_fan1_input16.dev_attr); | 974 | device_create_file(&new_client->dev, |
973 | device_create_file(&new_client->dev, | 975 | &sensor_dev_attr_fan1_input16.dev_attr); |
974 | &sensor_dev_attr_fan2_input16.dev_attr); | 976 | device_create_file(&new_client->dev, |
975 | device_create_file(&new_client->dev, | 977 | &sensor_dev_attr_fan1_min16.dev_attr); |
976 | &sensor_dev_attr_fan3_input16.dev_attr); | 978 | } |
977 | device_create_file(&new_client->dev, | 979 | if (data->has_fan & (1 << 1)) { |
978 | &sensor_dev_attr_fan1_min16.dev_attr); | 980 | device_create_file(&new_client->dev, |
979 | device_create_file(&new_client->dev, | 981 | &sensor_dev_attr_fan2_input16.dev_attr); |
980 | &sensor_dev_attr_fan2_min16.dev_attr); | 982 | device_create_file(&new_client->dev, |
981 | device_create_file(&new_client->dev, | 983 | &sensor_dev_attr_fan2_min16.dev_attr); |
982 | &sensor_dev_attr_fan3_min16.dev_attr); | 984 | } |
985 | if (data->has_fan & (1 << 2)) { | ||
986 | device_create_file(&new_client->dev, | ||
987 | &sensor_dev_attr_fan3_input16.dev_attr); | ||
988 | device_create_file(&new_client->dev, | ||
989 | &sensor_dev_attr_fan3_min16.dev_attr); | ||
990 | } | ||
983 | } else { | 991 | } else { |
984 | device_create_file(&new_client->dev, | 992 | if (data->has_fan & (1 << 0)) { |
985 | &sensor_dev_attr_fan1_input.dev_attr); | 993 | device_create_file(&new_client->dev, |
986 | device_create_file(&new_client->dev, | 994 | &sensor_dev_attr_fan1_input.dev_attr); |
987 | &sensor_dev_attr_fan2_input.dev_attr); | 995 | device_create_file(&new_client->dev, |
988 | device_create_file(&new_client->dev, | 996 | &sensor_dev_attr_fan1_min.dev_attr); |
989 | &sensor_dev_attr_fan3_input.dev_attr); | 997 | device_create_file(&new_client->dev, |
990 | device_create_file(&new_client->dev, | 998 | &sensor_dev_attr_fan1_div.dev_attr); |
991 | &sensor_dev_attr_fan1_min.dev_attr); | 999 | } |
992 | device_create_file(&new_client->dev, | 1000 | if (data->has_fan & (1 << 1)) { |
993 | &sensor_dev_attr_fan2_min.dev_attr); | 1001 | device_create_file(&new_client->dev, |
994 | device_create_file(&new_client->dev, | 1002 | &sensor_dev_attr_fan2_input.dev_attr); |
995 | &sensor_dev_attr_fan3_min.dev_attr); | 1003 | device_create_file(&new_client->dev, |
996 | device_create_file(&new_client->dev, | 1004 | &sensor_dev_attr_fan2_min.dev_attr); |
997 | &sensor_dev_attr_fan1_div.dev_attr); | 1005 | device_create_file(&new_client->dev, |
998 | device_create_file(&new_client->dev, | 1006 | &sensor_dev_attr_fan2_div.dev_attr); |
999 | &sensor_dev_attr_fan2_div.dev_attr); | 1007 | } |
1000 | device_create_file(&new_client->dev, | 1008 | if (data->has_fan & (1 << 2)) { |
1001 | &sensor_dev_attr_fan3_div.dev_attr); | 1009 | device_create_file(&new_client->dev, |
1010 | &sensor_dev_attr_fan3_input.dev_attr); | ||
1011 | device_create_file(&new_client->dev, | ||
1012 | &sensor_dev_attr_fan3_min.dev_attr); | ||
1013 | device_create_file(&new_client->dev, | ||
1014 | &sensor_dev_attr_fan3_div.dev_attr); | ||
1015 | } | ||
1002 | } | 1016 | } |
1003 | 1017 | ||
1004 | device_create_file(&new_client->dev, &dev_attr_alarms); | 1018 | device_create_file(&new_client->dev, &dev_attr_alarms); |
@@ -1175,11 +1189,12 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) | |||
1175 | data->fan_main_ctrl |= 0x70; | 1189 | data->fan_main_ctrl |= 0x70; |
1176 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); | 1190 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); |
1177 | } | 1191 | } |
1192 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; | ||
1178 | 1193 | ||
1179 | /* Set tachometers to 16-bit mode if needed */ | 1194 | /* Set tachometers to 16-bit mode if needed */ |
1180 | if (data->type == it8716) { | 1195 | if (data->type == it8716) { |
1181 | tmp = it87_read_value(client, IT87_REG_FAN_16BIT); | 1196 | tmp = it87_read_value(client, IT87_REG_FAN_16BIT); |
1182 | if ((tmp & 0x07) != 0x07) { | 1197 | if (~tmp & 0x07 & data->has_fan) { |
1183 | dev_dbg(&client->dev, | 1198 | dev_dbg(&client->dev, |
1184 | "Setting fan1-3 to 16-bit mode\n"); | 1199 | "Setting fan1-3 to 16-bit mode\n"); |
1185 | it87_write_value(client, IT87_REG_FAN_16BIT, | 1200 | it87_write_value(client, IT87_REG_FAN_16BIT, |
@@ -1244,6 +1259,10 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1244 | data->in_max[8] = 255; | 1259 | data->in_max[8] = 255; |
1245 | 1260 | ||
1246 | for (i = 0; i < 3; i++) { | 1261 | for (i = 0; i < 3; i++) { |
1262 | /* Skip disabled fans */ | ||
1263 | if (!(data->has_fan & (1 << i))) | ||
1264 | continue; | ||
1265 | |||
1247 | data->fan_min[i] = | 1266 | data->fan_min[i] = |
1248 | it87_read_value(client, IT87_REG_FAN_MIN(i)); | 1267 | it87_read_value(client, IT87_REG_FAN_MIN(i)); |
1249 | data->fan[i] = it87_read_value(client, | 1268 | data->fan[i] = it87_read_value(client, |
@@ -1266,7 +1285,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1266 | } | 1285 | } |
1267 | 1286 | ||
1268 | /* Newer chips don't have clock dividers */ | 1287 | /* Newer chips don't have clock dividers */ |
1269 | if (data->type != it8716) { | 1288 | if ((data->has_fan & 0x07) && data->type != it8716) { |
1270 | i = it87_read_value(client, IT87_REG_FAN_DIV); | 1289 | i = it87_read_value(client, IT87_REG_FAN_DIV); |
1271 | data->fan_div[0] = i & 0x07; | 1290 | data->fan_div[0] = i & 0x07; |
1272 | data->fan_div[1] = (i >> 3) & 0x07; | 1291 | data->fan_div[1] = (i >> 3) & 0x07; |