12 #include <linux/types.h>
13 #include <linux/module.h>
14 #include <linux/errno.h>
15 #include <linux/kernel.h>
17 #include <linux/sched.h>
18 #include <linux/i2c.h>
19 #include <linux/slab.h>
22 #include <linux/wait.h>
30 #include <asm/machdep.h>
32 #include <asm/sections.h>
36 #define CONFIG_REG 0x40
37 #define MANUAL_MASK 0xe0
38 #define AUTO_MASK 0x20
39 #define INVERT_MASK 0x10
42 static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c};
43 static u8 MANUAL_MODE[2] = {0x5c, 0x5d};
44 static u8 REM_CONTROL[2] = {0x00, 0x40};
45 static u8 FAN_SPEED[2] = {0x28, 0x2a};
46 static u8 FAN_SPD_SET[2] = {0x30, 0x31};
48 static u8 default_limits_local[3] = {70, 50, 70};
49 static u8 default_limits_chip[3] = {80, 65, 80};
50 static const char *sensor_location[3] = {
"?",
"?",
"?" };
52 static int limit_adjust;
53 static int fan_speed = -1;
62 MODULE_PARM_DESC(limit_adjust,
"Adjust maximum temperatures (50 sensor1, 70 sensor2) "
90 static void write_both_fan_speed(
struct thermostat *
th,
int speed);
136 res = tmp[1] + (tmp[0] << 8);
138 return (res == 0xffff ? 0 : (90000*60)/
res);
141 static void write_both_fan_speed(
struct thermostat *th,
int speed)
143 write_fan_speed(th, speed, 0);
144 if (th->
type == ADT7460)
145 write_fan_speed(th, speed, 1);
148 static void write_fan_speed(
struct thermostat *th,
int speed,
int fan)
157 if (th->
type == ADT7467 && fan == 1)
164 "for %s fan.\n", sensor_location[fan+1]);
167 "for %s fan.\n", speed, sensor_location[fan+1]);
173 manual =
read_reg(th, MANUAL_MODE[fan]);
180 if(th->
type == ADT7460) {
186 MANUAL_MODE[fan], manual|REM_CONTROL[fan]);
188 manual =
read_reg(th, MANUAL_MODE[fan]);
198 static void read_sensors(
struct thermostat *th)
202 for (i = 0; i < 3; i++)
207 static void display_stats(
struct thermostat *th)
213 " thermostats: %d,%d,%d;"
215 " fan speed: %d RPM\n",
218 read_fan_speed(th, FAN_SPEED[0]));
226 static void update_fans_speed (
struct thermostat *th)
232 for (i = 1; i < 3; i++) {
234 int fan_number = (th->
type == ADT7460 && i == 2);
238 int step = (255 - fan_speed) / 7;
247 new_speed = fan_speed + ((var-1)*step);
249 if (new_speed < fan_speed)
250 new_speed = fan_speed;
256 "(limit exceeded by %d on %s)\n",
258 sensor_location[fan_number+1]);
259 write_both_fan_speed(th, new_speed);
261 }
else if (var < -2) {
264 if (i == 2 && lastvar < -1) {
269 write_both_fan_speed(th, 0);
281 static int monitor_task(
void *
arg)
298 update_fans_speed(th);
309 static void set_limit(
struct thermostat *th,
int i)
312 th->
limits[
i] = default_limits_chip[
i] + limit_adjust;
316 th->
limits[
i] = default_limits_local[
i] + limit_adjust;
319 #define BUILD_SHOW_FUNC_INT(name, data) \
320 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
322 struct thermostat *th = dev_get_drvdata(dev); \
323 return sprintf(buf, "%d\n", data); \
326 #define BUILD_SHOW_FUNC_INT_LITE(name, data) \
327 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
329 return sprintf(buf, "%d\n", data); \
332 #define BUILD_SHOW_FUNC_STR(name, data) \
333 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
335 return sprintf(buf, "%s\n", data); \
338 #define BUILD_SHOW_FUNC_FAN(name, data) \
339 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
341 struct thermostat *th = dev_get_drvdata(dev); \
342 return sprintf(buf, "%d (%d rpm)\n", \
343 th->last_speed[data], \
344 read_fan_speed(th, FAN_SPEED[data]) \
348 #define BUILD_STORE_FUNC_DEG(name, data) \
349 static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
351 struct thermostat *th = dev_get_drvdata(dev); \
354 val = simple_strtol(buf, NULL, 10); \
355 printk(KERN_INFO "Adjusting limits by %d degrees\n", val); \
356 limit_adjust = val; \
357 for (i=0; i < 3; i++) \
362 #define BUILD_STORE_FUNC_INT(name, data) \
363 static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
366 val = simple_strtol(buf, NULL, 10); \
367 if (val < 0 || val > 255) \
369 printk(KERN_INFO "Setting specified fan speed to %d\n", val); \
391 show_sensor1_temperature,
NULL);
393 show_sensor2_temperature,NULL);
395 show_sensor1_limit, NULL);
397 show_sensor2_limit, NULL);
399 show_sensor1_location, NULL);
401 show_sensor2_location, NULL);
404 show_specified_fan_speed,store_specified_fan_speed);
407 show_sensor1_fan_speed, NULL);
409 show_sensor2_fan_speed, NULL);
412 show_limit_adjust, store_limit_adjust);
424 th->pdev = of_platform_device_create(np,
"temperatures", NULL);
427 dev = &th->pdev->dev;
438 if(th->type == ADT7460)
442 "Failed to create temperature attribute file(s).\n");
445 static void thermostat_remove_files(
struct thermostat *th)
451 dev = &th->
pdev->dev;
461 if (th->
type == ADT7460)
482 vers, vers == 1 ?
"" :
"un");
487 for (i = 0; i < 3; i++) {
491 if (sensor_location[i] ==
NULL)
492 sensor_location[
i] =
"";
495 offset +=
strlen(sensor_location[i]) + 1;
503 i2c_set_clientdata(client, th);
505 th->
type =
id->driver_data;
509 dev_err(&client->
dev,
"Thermostat failed to read config!\n");
525 for (i = 0; i < 3; i++) {
546 if (fan_speed != -1) {
548 write_both_fan_speed(th, 0);
551 write_both_fan_speed(th, -1);
561 thermostat_create_files(th);
566 static int remove_thermostat(
struct i2c_client *client)
568 struct thermostat *th = i2c_get_clientdata(client);
571 thermostat_remove_files(th);
577 "%d, %d, %d to %d, %d, %d\n",
582 for (i = 0; i < 3; i++)
585 write_both_fan_speed(th, -1);
593 {
"MAC,adt7460", ADT7460 },
594 {
"MAC,adt7467", ADT7467 },
599 static struct i2c_driver thermostat_driver = {
601 .name =
"therm_adt746x",
603 .probe = probe_thermostat,
604 .remove = remove_thermostat,
605 .id_table = therm_adt746x_id,
608 static int __init thermostat_init(
void)
610 #ifndef CONFIG_I2C_POWERMAC
611 request_module(
"i2c-powermac");
614 return i2c_add_driver(&thermostat_driver);
617 static void __exit thermostat_exit(
void)