aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/adt7470.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2009-01-06 17:41:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 18:59:18 -0500
commit89fac11cb3e7c5860c425dba14845c09ccede39d (patch)
tree1c5d66ce88efaeb2461c250f43036faa620f6bf7 /drivers/hwmon/adt7470.c
parent2f22d5dff6f95d777c4cb217b99bfdf1fe306128 (diff)
adt7470: make automatic fan control really work
It turns out that the adt7470's automatic fan control algorithm only works when the temperature sensors get updated. This in turn happens only when someone tells the chip to read its temperature sensors. Regrettably, this means that we have to drive the chip periodically. 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/adt7470.c')
-rw-r--r--drivers/hwmon/adt7470.c156
1 files changed, 134 insertions, 22 deletions
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index ab8d5ebc9f75..633e1a1e9d79 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -28,6 +28,7 @@
28#include <linux/mutex.h> 28#include <linux/mutex.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/log2.h> 30#include <linux/log2.h>
31#include <linux/kthread.h>
31 32
32/* Addresses to scan */ 33/* Addresses to scan */
33static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; 34static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
@@ -132,6 +133,9 @@ I2C_CLIENT_INSMOD_1(adt7470);
132/* Wait at least 200ms per sensor for 10 sensors */ 133/* Wait at least 200ms per sensor for 10 sensors */
133#define TEMP_COLLECTION_TIME 2000 134#define TEMP_COLLECTION_TIME 2000
134 135
136/* auto update thing won't fire more than every 2s */
137#define AUTO_UPDATE_INTERVAL 2000
138
135/* datasheet says to divide this number by the fan reading to get fan rpm */ 139/* datasheet says to divide this number by the fan reading to get fan rpm */
136#define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) 140#define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x))
137#define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM 141#define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM
@@ -148,6 +152,7 @@ struct adt7470_data {
148 unsigned long limits_last_updated; /* In jiffies */ 152 unsigned long limits_last_updated; /* In jiffies */
149 153
150 int num_temp_sensors; /* -1 = probe */ 154 int num_temp_sensors; /* -1 = probe */
155 int temperatures_probed;
151 156
152 s8 temp[ADT7470_TEMP_COUNT]; 157 s8 temp[ADT7470_TEMP_COUNT];
153 s8 temp_min[ADT7470_TEMP_COUNT]; 158 s8 temp_min[ADT7470_TEMP_COUNT];
@@ -164,6 +169,10 @@ struct adt7470_data {
164 u8 pwm_min[ADT7470_PWM_COUNT]; 169 u8 pwm_min[ADT7470_PWM_COUNT];
165 s8 pwm_tmin[ADT7470_PWM_COUNT]; 170 s8 pwm_tmin[ADT7470_PWM_COUNT];
166 u8 pwm_auto_temp[ADT7470_PWM_COUNT]; 171 u8 pwm_auto_temp[ADT7470_PWM_COUNT];
172
173 struct task_struct *auto_update;
174 struct completion auto_update_stop;
175 unsigned int auto_update_interval;
167}; 176};
168 177
169static int adt7470_probe(struct i2c_client *client, 178static int adt7470_probe(struct i2c_client *client,
@@ -221,19 +230,13 @@ static void adt7470_init_client(struct i2c_client *client)
221 } 230 }
222} 231}
223 232
224static struct adt7470_data *adt7470_update_device(struct device *dev) 233/* Probe for temperature sensors. Assumes lock is held */
234static int adt7470_read_temperatures(struct i2c_client *client,
235 struct adt7470_data *data)
225{ 236{
226 struct i2c_client *client = to_i2c_client(dev); 237 unsigned long res;
227 struct adt7470_data *data = i2c_get_clientdata(client);
228 unsigned long local_jiffies = jiffies;
229 u8 cfg, pwm[4], pwm_cfg[2];
230 int i; 238 int i;
231 239 u8 cfg, pwm[4], pwm_cfg[2];
232 mutex_lock(&data->lock);
233 if (time_before(local_jiffies, data->sensors_last_updated +
234 SENSOR_REFRESH_INTERVAL)
235 && data->sensors_valid)
236 goto no_sensor_update;
237 240
238 /* save pwm[1-4] config register */ 241 /* save pwm[1-4] config register */
239 pwm_cfg[0] = i2c_smbus_read_byte_data(client, ADT7470_REG_PWM_CFG(0)); 242 pwm_cfg[0] = i2c_smbus_read_byte_data(client, ADT7470_REG_PWM_CFG(0));
@@ -259,9 +262,9 @@ static struct adt7470_data *adt7470_update_device(struct device *dev)
259 i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); 262 i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg);
260 263
261 /* Delay is 200ms * number of temp sensors. */ 264 /* Delay is 200ms * number of temp sensors. */
262 msleep((data->num_temp_sensors >= 0 ? 265 res = msleep_interruptible((data->num_temp_sensors >= 0 ?
263 data->num_temp_sensors * 200 : 266 data->num_temp_sensors * 200 :
264 TEMP_COLLECTION_TIME)); 267 TEMP_COLLECTION_TIME));
265 268
266 /* done reading temperature sensors */ 269 /* done reading temperature sensors */
267 cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); 270 cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG);
@@ -272,15 +275,81 @@ static struct adt7470_data *adt7470_update_device(struct device *dev)
272 i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(0), pwm_cfg[0]); 275 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]); 276 i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]);
274 277
275 for (i = 0; i < ADT7470_TEMP_COUNT; i++) 278 if (res) {
279 printk(KERN_ERR "ha ha, interrupted");
280 return -EAGAIN;
281 }
282
283 /* Only count fans if we have to */
284 if (data->num_temp_sensors >= 0)
285 return 0;
286
287 for (i = 0; i < ADT7470_TEMP_COUNT; i++) {
276 data->temp[i] = i2c_smbus_read_byte_data(client, 288 data->temp[i] = i2c_smbus_read_byte_data(client,
277 ADT7470_TEMP_REG(i)); 289 ADT7470_TEMP_REG(i));
290 if (data->temp[i])
291 data->num_temp_sensors = i + 1;
292 }
293 data->temperatures_probed = 1;
294 return 0;
295}
278 296
279 /* Figure out the number of temp sensors */ 297static int adt7470_update_thread(void *p)
280 if (data->num_temp_sensors < 0) 298{
299 struct i2c_client *client = p;
300 struct adt7470_data *data = i2c_get_clientdata(client);
301
302 while (!kthread_should_stop()) {
303 mutex_lock(&data->lock);
304 adt7470_read_temperatures(client, data);
305 mutex_unlock(&data->lock);
306 if (kthread_should_stop())
307 break;
308 msleep_interruptible(data->auto_update_interval);
309 }
310
311 complete_all(&data->auto_update_stop);
312 return 0;
313}
314
315static struct adt7470_data *adt7470_update_device(struct device *dev)
316{
317 struct i2c_client *client = to_i2c_client(dev);
318 struct adt7470_data *data = i2c_get_clientdata(client);
319 unsigned long local_jiffies = jiffies;
320 u8 cfg;
321 int i;
322 int need_sensors = 1;
323 int need_limits = 1;
324
325 /*
326 * Figure out if we need to update the shadow registers.
327 * Lockless means that we may occasionally report out of
328 * date data.
329 */
330 if (time_before(local_jiffies, data->sensors_last_updated +
331 SENSOR_REFRESH_INTERVAL) &&
332 data->sensors_valid)
333 need_sensors = 0;
334
335 if (time_before(local_jiffies, data->limits_last_updated +
336 LIMIT_REFRESH_INTERVAL) &&
337 data->limits_valid)
338 need_limits = 0;
339
340 if (!need_sensors && !need_limits)
341 return data;
342
343 mutex_lock(&data->lock);
344 if (!need_sensors)
345 goto no_sensor_update;
346
347 if (!data->temperatures_probed)
348 adt7470_read_temperatures(client, data);
349 else
281 for (i = 0; i < ADT7470_TEMP_COUNT; i++) 350 for (i = 0; i < ADT7470_TEMP_COUNT; i++)
282 if (data->temp[i]) 351 data->temp[i] = i2c_smbus_read_byte_data(client,
283 data->num_temp_sensors = i + 1; 352 ADT7470_TEMP_REG(i));
284 353
285 for (i = 0; i < ADT7470_FAN_COUNT; i++) 354 for (i = 0; i < ADT7470_FAN_COUNT; i++)
286 data->fan[i] = adt7470_read_word_data(client, 355 data->fan[i] = adt7470_read_word_data(client,
@@ -329,9 +398,7 @@ static struct adt7470_data *adt7470_update_device(struct device *dev)
329 data->sensors_valid = 1; 398 data->sensors_valid = 1;
330 399
331no_sensor_update: 400no_sensor_update:
332 if (time_before(local_jiffies, data->limits_last_updated + 401 if (!need_limits)
333 LIMIT_REFRESH_INTERVAL)
334 && data->limits_valid)
335 goto out; 402 goto out;
336 403
337 for (i = 0; i < ADT7470_TEMP_COUNT; i++) { 404 for (i = 0; i < ADT7470_TEMP_COUNT; i++) {
@@ -365,6 +432,35 @@ out:
365 return data; 432 return data;
366} 433}
367 434
435static ssize_t show_auto_update_interval(struct device *dev,
436 struct device_attribute *devattr,
437 char *buf)
438{
439 struct adt7470_data *data = adt7470_update_device(dev);
440 return sprintf(buf, "%d\n", data->auto_update_interval);
441}
442
443static ssize_t set_auto_update_interval(struct device *dev,
444 struct device_attribute *devattr,
445 const char *buf,
446 size_t count)
447{
448 struct i2c_client *client = to_i2c_client(dev);
449 struct adt7470_data *data = i2c_get_clientdata(client);
450 long temp;
451
452 if (strict_strtol(buf, 10, &temp))
453 return -EINVAL;
454
455 temp = SENSORS_LIMIT(temp, 0, 60000);
456
457 mutex_lock(&data->lock);
458 data->auto_update_interval = temp;
459 mutex_unlock(&data->lock);
460
461 return count;
462}
463
368static ssize_t show_num_temp_sensors(struct device *dev, 464static ssize_t show_num_temp_sensors(struct device *dev,
369 struct device_attribute *devattr, 465 struct device_attribute *devattr,
370 char *buf) 466 char *buf)
@@ -389,6 +485,8 @@ static ssize_t set_num_temp_sensors(struct device *dev,
389 485
390 mutex_lock(&data->lock); 486 mutex_lock(&data->lock);
391 data->num_temp_sensors = temp; 487 data->num_temp_sensors = temp;
488 if (temp < 0)
489 data->temperatures_probed = 0;
392 mutex_unlock(&data->lock); 490 mutex_unlock(&data->lock);
393 491
394 return count; 492 return count;
@@ -862,6 +960,8 @@ static ssize_t show_alarm(struct device *dev,
862static DEVICE_ATTR(alarm_mask, S_IRUGO, show_alarm_mask, NULL); 960static DEVICE_ATTR(alarm_mask, S_IRUGO, show_alarm_mask, NULL);
863static DEVICE_ATTR(num_temp_sensors, S_IWUSR | S_IRUGO, show_num_temp_sensors, 961static DEVICE_ATTR(num_temp_sensors, S_IWUSR | S_IRUGO, show_num_temp_sensors,
864 set_num_temp_sensors); 962 set_num_temp_sensors);
963static DEVICE_ATTR(auto_update_interval, S_IWUSR | S_IRUGO,
964 show_auto_update_interval, set_auto_update_interval);
865 965
866static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, 966static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
867 set_temp_max, 0); 967 set_temp_max, 0);
@@ -1035,6 +1135,7 @@ static struct attribute *adt7470_attr[] =
1035{ 1135{
1036 &dev_attr_alarm_mask.attr, 1136 &dev_attr_alarm_mask.attr,
1037 &dev_attr_num_temp_sensors.attr, 1137 &dev_attr_num_temp_sensors.attr,
1138 &dev_attr_auto_update_interval.attr,
1038 &sensor_dev_attr_temp1_max.dev_attr.attr, 1139 &sensor_dev_attr_temp1_max.dev_attr.attr,
1039 &sensor_dev_attr_temp2_max.dev_attr.attr, 1140 &sensor_dev_attr_temp2_max.dev_attr.attr,
1040 &sensor_dev_attr_temp3_max.dev_attr.attr, 1141 &sensor_dev_attr_temp3_max.dev_attr.attr,
@@ -1168,6 +1269,7 @@ static int adt7470_probe(struct i2c_client *client,
1168 } 1269 }
1169 1270
1170 data->num_temp_sensors = -1; 1271 data->num_temp_sensors = -1;
1272 data->auto_update_interval = AUTO_UPDATE_INTERVAL;
1171 1273
1172 i2c_set_clientdata(client, data); 1274 i2c_set_clientdata(client, data);
1173 mutex_init(&data->lock); 1275 mutex_init(&data->lock);
@@ -1188,8 +1290,16 @@ static int adt7470_probe(struct i2c_client *client,
1188 goto exit_remove; 1290 goto exit_remove;
1189 } 1291 }
1190 1292
1293 init_completion(&data->auto_update_stop);
1294 data->auto_update = kthread_run(adt7470_update_thread, client,
1295 dev_name(data->hwmon_dev));
1296 if (IS_ERR(data->auto_update))
1297 goto exit_unregister;
1298
1191 return 0; 1299 return 0;
1192 1300
1301exit_unregister:
1302 hwmon_device_unregister(data->hwmon_dev);
1193exit_remove: 1303exit_remove:
1194 sysfs_remove_group(&client->dev.kobj, &data->attrs); 1304 sysfs_remove_group(&client->dev.kobj, &data->attrs);
1195exit_free: 1305exit_free:
@@ -1202,6 +1312,8 @@ static int adt7470_remove(struct i2c_client *client)
1202{ 1312{
1203 struct adt7470_data *data = i2c_get_clientdata(client); 1313 struct adt7470_data *data = i2c_get_clientdata(client);
1204 1314
1315 kthread_stop(data->auto_update);
1316 wait_for_completion(&data->auto_update_stop);
1205 hwmon_device_unregister(data->hwmon_dev); 1317 hwmon_device_unregister(data->hwmon_dev);
1206 sysfs_remove_group(&client->dev.kobj, &data->attrs); 1318 sysfs_remove_group(&client->dev.kobj, &data->attrs);
1207 kfree(data); 1319 kfree(data);