diff options
author | Marc Hulsman <m.hulsman@tudelft.nl> | 2008-08-06 16:41:04 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-08-06 16:41:04 -0400 |
commit | ad02ad85cf221c9a0574b48516762e37cceca0da (patch) | |
tree | 6ba4a83e4ca37bc252ce90a734984f761462cc16 /drivers/hwmon/w83791d.c | |
parent | 05a5e477687ac7a22c0791b3e899ed7d539f7b95 (diff) |
hwmon: (w83791d) Use fan divisor bits from vbat register
Update w83791d with fan bits in vbat mon register (7.48 of the
datasheet). This change allows all fans to have a divisor of 128,
and fixes a problem with incorrectly reported fan speeds.
Signed-off-by: Marc Hulsman <m.hulsman@tudelft.nl>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/w83791d.c')
-rw-r--r-- | drivers/hwmon/w83791d.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index e4e91c9d480a..daa7d121483b 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
@@ -233,11 +233,9 @@ static u8 fan_to_reg(long rpm, int div) | |||
233 | static u8 div_to_reg(int nr, long val) | 233 | static u8 div_to_reg(int nr, long val) |
234 | { | 234 | { |
235 | int i; | 235 | int i; |
236 | int max; | ||
237 | 236 | ||
238 | /* first three fan's divisor max out at 8, rest max out at 128 */ | 237 | /* fan divisors max out at 128 */ |
239 | max = (nr < 3) ? 8 : 128; | 238 | val = SENSORS_LIMIT(val, 1, 128) >> 1; |
240 | val = SENSORS_LIMIT(val, 1, max) >> 1; | ||
241 | for (i = 0; i < 7; i++) { | 239 | for (i = 0; i < 7; i++) { |
242 | if (val == 0) | 240 | if (val == 0) |
243 | break; | 241 | break; |
@@ -530,6 +528,7 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, | |||
530 | unsigned long min; | 528 | unsigned long min; |
531 | u8 tmp_fan_div; | 529 | u8 tmp_fan_div; |
532 | u8 fan_div_reg; | 530 | u8 fan_div_reg; |
531 | u8 vbat_reg; | ||
533 | int indx = 0; | 532 | int indx = 0; |
534 | u8 keep_mask = 0; | 533 | u8 keep_mask = 0; |
535 | u8 new_shift = 0; | 534 | u8 new_shift = 0; |
@@ -581,6 +580,16 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, | |||
581 | w83791d_write(client, W83791D_REG_FAN_DIV[indx], | 580 | w83791d_write(client, W83791D_REG_FAN_DIV[indx], |
582 | fan_div_reg | tmp_fan_div); | 581 | fan_div_reg | tmp_fan_div); |
583 | 582 | ||
583 | /* Bit 2 of fans 0-2 is stored in the vbat register (bits 5-7) */ | ||
584 | if (nr < 3) { | ||
585 | keep_mask = ~(1 << (nr + 5)); | ||
586 | vbat_reg = w83791d_read(client, W83791D_REG_VBAT) | ||
587 | & keep_mask; | ||
588 | tmp_fan_div = (data->fan_div[nr] << (3 + nr)) & ~keep_mask; | ||
589 | w83791d_write(client, W83791D_REG_VBAT, | ||
590 | vbat_reg | tmp_fan_div); | ||
591 | } | ||
592 | |||
584 | /* Restore fan_min */ | 593 | /* Restore fan_min */ |
585 | data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr])); | 594 | data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr])); |
586 | w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); | 595 | w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); |
@@ -1182,6 +1191,7 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) | |||
1182 | struct w83791d_data *data = i2c_get_clientdata(client); | 1191 | struct w83791d_data *data = i2c_get_clientdata(client); |
1183 | int i, j; | 1192 | int i, j; |
1184 | u8 reg_array_tmp[3]; | 1193 | u8 reg_array_tmp[3]; |
1194 | u8 vbat_reg; | ||
1185 | 1195 | ||
1186 | mutex_lock(&data->update_lock); | 1196 | mutex_lock(&data->update_lock); |
1187 | 1197 | ||
@@ -1219,6 +1229,12 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) | |||
1219 | data->fan_div[3] = reg_array_tmp[2] & 0x07; | 1229 | data->fan_div[3] = reg_array_tmp[2] & 0x07; |
1220 | data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; | 1230 | data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; |
1221 | 1231 | ||
1232 | /* The fan divisor for fans 0-2 get bit 2 from | ||
1233 | bits 5-7 respectively of vbat register */ | ||
1234 | vbat_reg = w83791d_read(client, W83791D_REG_VBAT); | ||
1235 | for (i = 0; i < 3; i++) | ||
1236 | data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04; | ||
1237 | |||
1222 | /* Update the first temperature sensor */ | 1238 | /* Update the first temperature sensor */ |
1223 | for (i = 0; i < 3; i++) { | 1239 | for (i = 0; i < 3; i++) { |
1224 | data->temp1[i] = w83791d_read(client, | 1240 | data->temp1[i] = w83791d_read(client, |