aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorMarc Hulsman <m.hulsman@tudelft.nl>2008-08-06 16:41:04 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-08-06 16:41:04 -0400
commitad02ad85cf221c9a0574b48516762e37cceca0da (patch)
tree6ba4a83e4ca37bc252ce90a734984f761462cc16 /drivers/hwmon
parent05a5e477687ac7a22c0791b3e899ed7d539f7b95 (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')
-rw-r--r--drivers/hwmon/w83791d.c24
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)
233static u8 div_to_reg(int nr, long val) 233static 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,