aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2009-01-06 17:41:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 18:59:18 -0500
commit2e75a4b7ae0dd4bf7b34e41c2c3be7ac23b8f1cc (patch)
tree3adaaa6a78b2d11b7648a93956c10a0968abd09c /drivers/hwmon
parent8f8c1fb0c829278b889588da211a5a557518b06c (diff)
adt7470: fix pwm at a certain level during temperature sensor scan
In the small window that it takes to read the temperature sensors, the pwm outputs momentarily drop to 0. This causes a noticeable hiccup in fan speed, which is slightly annoying. The solution is to manually program the pwm output with whatever the automatic value is and then shift the fans to manual control while reading temperatures. Once that is done, put the fans back to whatever mode of control was there before. Signed-off-by: Darrick J. Wong <djwong@us.ibm.com> Cc: Jean Delvare <khali@linux-fr.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/adt7470.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index da6c9306ca5..b7a442a80bd 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -74,6 +74,7 @@ I2C_CLIENT_INSMOD_1(adt7470);
74#define ADT7470_REG_PWM12_CFG 0x68 74#define ADT7470_REG_PWM12_CFG 0x68
75#define ADT7470_PWM2_AUTO_MASK 0x40 75#define ADT7470_PWM2_AUTO_MASK 0x40
76#define ADT7470_PWM1_AUTO_MASK 0x80 76#define ADT7470_PWM1_AUTO_MASK 0x80
77#define ADT7470_PWM_AUTO_MASK 0xC0
77#define ADT7470_REG_PWM34_CFG 0x69 78#define ADT7470_REG_PWM34_CFG 0x69
78#define ADT7470_PWM3_AUTO_MASK 0x40 79#define ADT7470_PWM3_AUTO_MASK 0x40
79#define ADT7470_PWM4_AUTO_MASK 0x80 80#define ADT7470_PWM4_AUTO_MASK 0x80
@@ -223,7 +224,7 @@ static struct adt7470_data *adt7470_update_device(struct device *dev)
223 struct i2c_client *client = to_i2c_client(dev); 224 struct i2c_client *client = to_i2c_client(dev);
224 struct adt7470_data *data = i2c_get_clientdata(client); 225 struct adt7470_data *data = i2c_get_clientdata(client);
225 unsigned long local_jiffies = jiffies; 226 unsigned long local_jiffies = jiffies;
226 u8 cfg; 227 u8 cfg, pwm[4], pwm_cfg[2];
227 int i; 228 int i;
228 229
229 mutex_lock(&data->lock); 230 mutex_lock(&data->lock);
@@ -232,6 +233,24 @@ static struct adt7470_data *adt7470_update_device(struct device *dev)
232 && data->sensors_valid) 233 && data->sensors_valid)
233 goto no_sensor_update; 234 goto no_sensor_update;
234 235
236 /* save pwm[1-4] config register */
237 pwm_cfg[0] = i2c_smbus_read_byte_data(client, ADT7470_REG_PWM_CFG(0));
238 pwm_cfg[1] = i2c_smbus_read_byte_data(client, ADT7470_REG_PWM_CFG(2));
239
240 /* set manual pwm to whatever it is set to now */
241 for (i = 0; i < ADT7470_FAN_COUNT; i++)
242 pwm[i] = i2c_smbus_read_byte_data(client, ADT7470_REG_PWM(i));
243
244 /* put pwm in manual mode */
245 i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(0),
246 pwm_cfg[0] & ~(ADT7470_PWM_AUTO_MASK));
247 i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(2),
248 pwm_cfg[1] & ~(ADT7470_PWM_AUTO_MASK));
249
250 /* write pwm control to whatever it was */
251 for (i = 0; i < ADT7470_FAN_COUNT; i++)
252 i2c_smbus_write_byte_data(client, ADT7470_REG_PWM(i), pwm[i]);
253
235 /* start reading temperature sensors */ 254 /* start reading temperature sensors */
236 cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); 255 cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG);
237 cfg |= 0x80; 256 cfg |= 0x80;
@@ -249,6 +268,10 @@ static struct adt7470_data *adt7470_update_device(struct device *dev)
249 cfg &= ~0x80; 268 cfg &= ~0x80;
250 i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); 269 i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg);
251 270
271 /* restore pwm[1-4] config registers */
272 i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(0), pwm_cfg[0]);
273 i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]);
274
252 for (i = 0; i < ADT7470_TEMP_COUNT; i++) 275 for (i = 0; i < ADT7470_TEMP_COUNT; i++)
253 data->temp[i] = i2c_smbus_read_byte_data(client, 276 data->temp[i] = i2c_smbus_read_byte_data(client,
254 ADT7470_TEMP_REG(i)); 277 ADT7470_TEMP_REG(i));