aboutsummaryrefslogtreecommitdiff
path: root/drivers/hwmon/w83791d.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-08-07 18:05:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-08-07 18:05:39 -0700
commita06dee41a31bff488a261dfc542776ffd2f24ff1 (patch)
tree4930b7698d5d238f159c2d6628c7c1c62765b42b /drivers/hwmon/w83791d.c
parentb588e2bbd7b872c9cdf635fe0f04840534e72443 (diff)
parent816d8c6a2580562698cf0fa0b9e5b4dd570e636e (diff)
Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
* 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6: hwmon: (it87) Support for 16-bit fan reading in it8705 >= rev 0x03 hwmon: (it87) Support for 16-bit fan reading in it8712 >= rev 0x07 hwmon: (hwmon-vid) Add 6-bit vid codes for AMD NPT 0Fh cpus hwmon: (hwmon-vid) Trivial format multi-line comments per CodingStyle hwmon: ad7414 driver hwmon: (thmc50) Add support for critical temperature limits hwmon: (adm9240) Remove EXPERIMENTAL dependency hwmon: (w83627hf) Drop reset module parameter hwmon: (w83627hf) Add pwm_enable sysfs interface hwmon: (w83791d) Use fan divisor bits from vbat register hwmon: (f71882fg) Delete needless forward declarations hwmon: (dme1737) Add support for the SMSC SCH5027 hwmon: (dme1737) Skip detection if forced hwmon: (dme1737) Cleanups
Diffstat (limited to 'drivers/hwmon/w83791d.c')
-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 e4e91c9d480..daa7d121483 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -233,11 +233,9 @@ static u8 fan_to_reg(long rpm, int div)
static u8 div_to_reg(int nr, long val)
{
int i;
- int max;
- /* first three fan's divisor max out at 8, rest max out at 128 */
- max = (nr < 3) ? 8 : 128;
- val = SENSORS_LIMIT(val, 1, max) >> 1;
+ /* fan divisors max out at 128 */
+ val = SENSORS_LIMIT(val, 1, 128) >> 1;
for (i = 0; i < 7; i++) {
if (val == 0)
break;
@@ -530,6 +528,7 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,
unsigned long min;
u8 tmp_fan_div;
u8 fan_div_reg;
+ u8 vbat_reg;
int indx = 0;
u8 keep_mask = 0;
u8 new_shift = 0;
@@ -581,6 +580,16 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,
w83791d_write(client, W83791D_REG_FAN_DIV[indx],
fan_div_reg | tmp_fan_div);
+ /* Bit 2 of fans 0-2 is stored in the vbat register (bits 5-7) */
+ if (nr < 3) {
+ keep_mask = ~(1 << (nr + 5));
+ vbat_reg = w83791d_read(client, W83791D_REG_VBAT)
+ & keep_mask;
+ tmp_fan_div = (data->fan_div[nr] << (3 + nr)) & ~keep_mask;
+ w83791d_write(client, W83791D_REG_VBAT,
+ vbat_reg | tmp_fan_div);
+ }
+
/* Restore fan_min */
data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr]));
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)
struct w83791d_data *data = i2c_get_clientdata(client);
int i, j;
u8 reg_array_tmp[3];
+ u8 vbat_reg;
mutex_lock(&data->update_lock);
@@ -1219,6 +1229,12 @@ static struct w83791d_data *w83791d_update_device(struct device *dev)
data->fan_div[3] = reg_array_tmp[2] & 0x07;
data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07;
+ /* The fan divisor for fans 0-2 get bit 2 from
+ bits 5-7 respectively of vbat register */
+ vbat_reg = w83791d_read(client, W83791D_REG_VBAT);
+ for (i = 0; i < 3; i++)
+ data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04;
+
/* Update the first temperature sensor */
for (i = 0; i < 3; i++) {
data->temp1[i] = w83791d_read(client,