diff options
Diffstat (limited to 'drivers/macintosh/therm_adt746x.c')
-rw-r--r-- | drivers/macintosh/therm_adt746x.c | 125 |
1 files changed, 83 insertions, 42 deletions
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index e0ac63effa55..d09308f30960 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -39,15 +39,16 @@ | |||
39 | #define MANUAL_MASK 0xe0 | 39 | #define MANUAL_MASK 0xe0 |
40 | #define AUTO_MASK 0x20 | 40 | #define AUTO_MASK 0x20 |
41 | 41 | ||
42 | static u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, cpu, gpu */ | 42 | static u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */ |
43 | static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, cpu, gpu */ | 43 | static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */ |
44 | static u8 MANUAL_MODE[2] = {0x5c, 0x5d}; | 44 | static u8 MANUAL_MODE[2] = {0x5c, 0x5d}; |
45 | static u8 REM_CONTROL[2] = {0x00, 0x40}; | 45 | static u8 REM_CONTROL[2] = {0x00, 0x40}; |
46 | static u8 FAN_SPEED[2] = {0x28, 0x2a}; | 46 | static u8 FAN_SPEED[2] = {0x28, 0x2a}; |
47 | static u8 FAN_SPD_SET[2] = {0x30, 0x31}; | 47 | static u8 FAN_SPD_SET[2] = {0x30, 0x31}; |
48 | 48 | ||
49 | static u8 default_limits_local[3] = {70, 50, 70}; /* local, cpu, gpu */ | 49 | static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */ |
50 | static u8 default_limits_chip[3] = {80, 65, 80}; /* local, cpu, gpu */ | 50 | static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */ |
51 | static char *sensor_location[3] = {NULL, NULL, NULL}; | ||
51 | 52 | ||
52 | static int limit_adjust = 0; | 53 | static int limit_adjust = 0; |
53 | static int fan_speed = -1; | 54 | static int fan_speed = -1; |
@@ -58,7 +59,7 @@ MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and " | |||
58 | MODULE_LICENSE("GPL"); | 59 | MODULE_LICENSE("GPL"); |
59 | 60 | ||
60 | module_param(limit_adjust, int, 0644); | 61 | module_param(limit_adjust, int, 0644); |
61 | MODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 cpu, 70 gpu) " | 62 | MODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 sensor1, 70 sensor2) " |
62 | "by N degrees."); | 63 | "by N degrees."); |
63 | 64 | ||
64 | module_param(fan_speed, int, 0644); | 65 | module_param(fan_speed, int, 0644); |
@@ -213,10 +214,10 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan) | |||
213 | if (th->last_speed[fan] != speed) { | 214 | if (th->last_speed[fan] != speed) { |
214 | if (speed == -1) | 215 | if (speed == -1) |
215 | printk(KERN_DEBUG "adt746x: Setting speed to automatic " | 216 | printk(KERN_DEBUG "adt746x: Setting speed to automatic " |
216 | "for %s fan.\n", fan?"GPU":"CPU"); | 217 | "for %s fan.\n", sensor_location[fan+1]); |
217 | else | 218 | else |
218 | printk(KERN_DEBUG "adt746x: Setting speed to %d " | 219 | printk(KERN_DEBUG "adt746x: Setting speed to %d " |
219 | "for %s fan.\n", speed, fan?"GPU":"CPU"); | 220 | "for %s fan.\n", speed, sensor_location[fan+1]); |
220 | } else | 221 | } else |
221 | return; | 222 | return; |
222 | 223 | ||
@@ -300,11 +301,11 @@ static void update_fans_speed (struct thermostat *th) | |||
300 | printk(KERN_DEBUG "adt746x: setting fans speed to %d " | 301 | printk(KERN_DEBUG "adt746x: setting fans speed to %d " |
301 | "(limit exceeded by %d on %s) \n", | 302 | "(limit exceeded by %d on %s) \n", |
302 | new_speed, var, | 303 | new_speed, var, |
303 | fan_number?"GPU/pwr":"CPU"); | 304 | sensor_location[fan_number+1]); |
304 | write_both_fan_speed(th, new_speed); | 305 | write_both_fan_speed(th, new_speed); |
305 | th->last_var[fan_number] = var; | 306 | th->last_var[fan_number] = var; |
306 | } else if (var < -2) { | 307 | } else if (var < -2) { |
307 | /* don't stop fan if GPU/power is cold and CPU is not | 308 | /* don't stop fan if sensor2 is cold and sensor1 is not |
308 | * so cold (lastvar >= -1) */ | 309 | * so cold (lastvar >= -1) */ |
309 | if (i == 2 && lastvar < -1) { | 310 | if (i == 2 && lastvar < -1) { |
310 | if (th->last_speed[fan_number] != 0) | 311 | if (th->last_speed[fan_number] != 0) |
@@ -318,7 +319,7 @@ static void update_fans_speed (struct thermostat *th) | |||
318 | 319 | ||
319 | if (started) | 320 | if (started) |
320 | return; /* we don't want to re-stop the fan | 321 | return; /* we don't want to re-stop the fan |
321 | * if CPU is heating and GPU/power is not */ | 322 | * if sensor1 is heating and sensor2 is not */ |
322 | } | 323 | } |
323 | } | 324 | } |
324 | 325 | ||
@@ -353,7 +354,7 @@ static int monitor_task(void *arg) | |||
353 | 354 | ||
354 | static void set_limit(struct thermostat *th, int i) | 355 | static void set_limit(struct thermostat *th, int i) |
355 | { | 356 | { |
356 | /* Set CPU limit higher to avoid powerdowns */ | 357 | /* Set sensor1 limit higher to avoid powerdowns */ |
357 | th->limits[i] = default_limits_chip[i] + limit_adjust; | 358 | th->limits[i] = default_limits_chip[i] + limit_adjust; |
358 | write_reg(th, LIMIT_REG[i], th->limits[i]); | 359 | write_reg(th, LIMIT_REG[i], th->limits[i]); |
359 | 360 | ||
@@ -461,6 +462,12 @@ static ssize_t show_##name(struct device *dev, char *buf) \ | |||
461 | return sprintf(buf, "%d\n", data); \ | 462 | return sprintf(buf, "%d\n", data); \ |
462 | } | 463 | } |
463 | 464 | ||
465 | #define BUILD_SHOW_FUNC_STR(name, data) \ | ||
466 | static ssize_t show_##name(struct device *dev, char *buf) \ | ||
467 | { \ | ||
468 | return sprintf(buf, "%s\n", data); \ | ||
469 | } | ||
470 | |||
464 | #define BUILD_SHOW_FUNC_FAN(name, data) \ | 471 | #define BUILD_SHOW_FUNC_FAN(name, data) \ |
465 | static ssize_t show_##name(struct device *dev, char *buf) \ | 472 | static ssize_t show_##name(struct device *dev, char *buf) \ |
466 | { \ | 473 | { \ |
@@ -476,7 +483,7 @@ static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \ | |||
476 | int val; \ | 483 | int val; \ |
477 | int i; \ | 484 | int i; \ |
478 | val = simple_strtol(buf, NULL, 10); \ | 485 | val = simple_strtol(buf, NULL, 10); \ |
479 | printk(KERN_INFO "Adjusting limits by %d°C\n", val); \ | 486 | printk(KERN_INFO "Adjusting limits by %d degrees\n", val); \ |
480 | limit_adjust = val; \ | 487 | limit_adjust = val; \ |
481 | for (i=0; i < 3; i++) \ | 488 | for (i=0; i < 3; i++) \ |
482 | set_limit(thermostat, i); \ | 489 | set_limit(thermostat, i); \ |
@@ -495,35 +502,41 @@ static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \ | |||
495 | return n; \ | 502 | return n; \ |
496 | } | 503 | } |
497 | 504 | ||
498 | BUILD_SHOW_FUNC_INT(cpu_temperature, (read_reg(thermostat, TEMP_REG[1]))) | 505 | BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(thermostat, TEMP_REG[1]))) |
499 | BUILD_SHOW_FUNC_INT(gpu_temperature, (read_reg(thermostat, TEMP_REG[2]))) | 506 | BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(thermostat, TEMP_REG[2]))) |
500 | BUILD_SHOW_FUNC_INT(cpu_limit, thermostat->limits[1]) | 507 | BUILD_SHOW_FUNC_INT(sensor1_limit, thermostat->limits[1]) |
501 | BUILD_SHOW_FUNC_INT(gpu_limit, thermostat->limits[2]) | 508 | BUILD_SHOW_FUNC_INT(sensor2_limit, thermostat->limits[2]) |
509 | BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1]) | ||
510 | BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2]) | ||
502 | 511 | ||
503 | BUILD_SHOW_FUNC_INT(specified_fan_speed, fan_speed) | 512 | BUILD_SHOW_FUNC_INT(specified_fan_speed, fan_speed) |
504 | BUILD_SHOW_FUNC_FAN(cpu_fan_speed, 0) | 513 | BUILD_SHOW_FUNC_FAN(sensor1_fan_speed, 0) |
505 | BUILD_SHOW_FUNC_FAN(gpu_fan_speed, 1) | 514 | BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1) |
506 | 515 | ||
507 | BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed) | 516 | BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed) |
508 | BUILD_SHOW_FUNC_INT(limit_adjust, limit_adjust) | 517 | BUILD_SHOW_FUNC_INT(limit_adjust, limit_adjust) |
509 | BUILD_STORE_FUNC_DEG(limit_adjust, thermostat) | 518 | BUILD_STORE_FUNC_DEG(limit_adjust, thermostat) |
510 | 519 | ||
511 | static DEVICE_ATTR(cpu_temperature, S_IRUGO, | 520 | static DEVICE_ATTR(sensor1_temperature, S_IRUGO, |
512 | show_cpu_temperature,NULL); | 521 | show_sensor1_temperature,NULL); |
513 | static DEVICE_ATTR(gpu_temperature, S_IRUGO, | 522 | static DEVICE_ATTR(sensor2_temperature, S_IRUGO, |
514 | show_gpu_temperature,NULL); | 523 | show_sensor2_temperature,NULL); |
515 | static DEVICE_ATTR(cpu_limit, S_IRUGO, | 524 | static DEVICE_ATTR(sensor1_limit, S_IRUGO, |
516 | show_cpu_limit, NULL); | 525 | show_sensor1_limit, NULL); |
517 | static DEVICE_ATTR(gpu_limit, S_IRUGO, | 526 | static DEVICE_ATTR(sensor2_limit, S_IRUGO, |
518 | show_gpu_limit, NULL); | 527 | show_sensor2_limit, NULL); |
528 | static DEVICE_ATTR(sensor1_location, S_IRUGO, | ||
529 | show_sensor1_location, NULL); | ||
530 | static DEVICE_ATTR(sensor2_location, S_IRUGO, | ||
531 | show_sensor2_location, NULL); | ||
519 | 532 | ||
520 | static DEVICE_ATTR(specified_fan_speed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, | 533 | static DEVICE_ATTR(specified_fan_speed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, |
521 | show_specified_fan_speed,store_specified_fan_speed); | 534 | show_specified_fan_speed,store_specified_fan_speed); |
522 | 535 | ||
523 | static DEVICE_ATTR(cpu_fan_speed, S_IRUGO, | 536 | static DEVICE_ATTR(sensor1_fan_speed, S_IRUGO, |
524 | show_cpu_fan_speed, NULL); | 537 | show_sensor1_fan_speed, NULL); |
525 | static DEVICE_ATTR(gpu_fan_speed, S_IRUGO, | 538 | static DEVICE_ATTR(sensor2_fan_speed, S_IRUGO, |
526 | show_gpu_fan_speed, NULL); | 539 | show_sensor2_fan_speed, NULL); |
527 | 540 | ||
528 | static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, | 541 | static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, |
529 | show_limit_adjust, store_limit_adjust); | 542 | show_limit_adjust, store_limit_adjust); |
@@ -534,6 +547,7 @@ thermostat_init(void) | |||
534 | { | 547 | { |
535 | struct device_node* np; | 548 | struct device_node* np; |
536 | u32 *prop; | 549 | u32 *prop; |
550 | int i = 0, offset = 0; | ||
537 | 551 | ||
538 | np = of_find_node_by_name(NULL, "fan"); | 552 | np = of_find_node_by_name(NULL, "fan"); |
539 | if (!np) | 553 | if (!np) |
@@ -545,6 +559,12 @@ thermostat_init(void) | |||
545 | else | 559 | else |
546 | return -ENODEV; | 560 | return -ENODEV; |
547 | 561 | ||
562 | prop = (u32 *)get_property(np, "hwsensor-params-version", NULL); | ||
563 | printk(KERN_INFO "adt746x: version %d (%ssupported)\n", *prop, | ||
564 | (*prop == 1)?"":"un"); | ||
565 | if (*prop != 1) | ||
566 | return -ENODEV; | ||
567 | |||
548 | prop = (u32 *)get_property(np, "reg", NULL); | 568 | prop = (u32 *)get_property(np, "reg", NULL); |
549 | if (!prop) | 569 | if (!prop) |
550 | return -ENODEV; | 570 | return -ENODEV; |
@@ -563,6 +583,23 @@ thermostat_init(void) | |||
563 | "limit_adjust: %d, fan_speed: %d\n", | 583 | "limit_adjust: %d, fan_speed: %d\n", |
564 | therm_bus, therm_address, limit_adjust, fan_speed); | 584 | therm_bus, therm_address, limit_adjust, fan_speed); |
565 | 585 | ||
586 | if (get_property(np, "hwsensor-location", NULL)) { | ||
587 | for (i = 0; i < 3; i++) { | ||
588 | sensor_location[i] = get_property(np, | ||
589 | "hwsensor-location", NULL) + offset; | ||
590 | |||
591 | if (sensor_location[i] == NULL) | ||
592 | sensor_location[i] = ""; | ||
593 | |||
594 | printk(KERN_INFO "sensor %d: %s\n", i, sensor_location[i]); | ||
595 | offset += strlen(sensor_location[i]) + 1; | ||
596 | } | ||
597 | } else { | ||
598 | sensor_location[0] = "?"; | ||
599 | sensor_location[1] = "?"; | ||
600 | sensor_location[2] = "?"; | ||
601 | } | ||
602 | |||
566 | of_dev = of_platform_device_create(np, "temperatures"); | 603 | of_dev = of_platform_device_create(np, "temperatures"); |
567 | 604 | ||
568 | if (of_dev == NULL) { | 605 | if (of_dev == NULL) { |
@@ -570,15 +607,17 @@ thermostat_init(void) | |||
570 | return -ENODEV; | 607 | return -ENODEV; |
571 | } | 608 | } |
572 | 609 | ||
573 | device_create_file(&of_dev->dev, &dev_attr_cpu_temperature); | 610 | device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); |
574 | device_create_file(&of_dev->dev, &dev_attr_gpu_temperature); | 611 | device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); |
575 | device_create_file(&of_dev->dev, &dev_attr_cpu_limit); | 612 | device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); |
576 | device_create_file(&of_dev->dev, &dev_attr_gpu_limit); | 613 | device_create_file(&of_dev->dev, &dev_attr_sensor2_limit); |
614 | device_create_file(&of_dev->dev, &dev_attr_sensor1_location); | ||
615 | device_create_file(&of_dev->dev, &dev_attr_sensor2_location); | ||
577 | device_create_file(&of_dev->dev, &dev_attr_limit_adjust); | 616 | device_create_file(&of_dev->dev, &dev_attr_limit_adjust); |
578 | device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); | 617 | device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); |
579 | device_create_file(&of_dev->dev, &dev_attr_cpu_fan_speed); | 618 | device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); |
580 | if(therm_type == ADT7460) | 619 | if(therm_type == ADT7460) |
581 | device_create_file(&of_dev->dev, &dev_attr_gpu_fan_speed); | 620 | device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); |
582 | 621 | ||
583 | #ifndef CONFIG_I2C_KEYWEST | 622 | #ifndef CONFIG_I2C_KEYWEST |
584 | request_module("i2c-keywest"); | 623 | request_module("i2c-keywest"); |
@@ -591,17 +630,19 @@ static void __exit | |||
591 | thermostat_exit(void) | 630 | thermostat_exit(void) |
592 | { | 631 | { |
593 | if (of_dev) { | 632 | if (of_dev) { |
594 | device_remove_file(&of_dev->dev, &dev_attr_cpu_temperature); | 633 | device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature); |
595 | device_remove_file(&of_dev->dev, &dev_attr_gpu_temperature); | 634 | device_remove_file(&of_dev->dev, &dev_attr_sensor2_temperature); |
596 | device_remove_file(&of_dev->dev, &dev_attr_cpu_limit); | 635 | device_remove_file(&of_dev->dev, &dev_attr_sensor1_limit); |
597 | device_remove_file(&of_dev->dev, &dev_attr_gpu_limit); | 636 | device_remove_file(&of_dev->dev, &dev_attr_sensor2_limit); |
637 | device_remove_file(&of_dev->dev, &dev_attr_sensor1_location); | ||
638 | device_remove_file(&of_dev->dev, &dev_attr_sensor2_location); | ||
598 | device_remove_file(&of_dev->dev, &dev_attr_limit_adjust); | 639 | device_remove_file(&of_dev->dev, &dev_attr_limit_adjust); |
599 | device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed); | 640 | device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed); |
600 | device_remove_file(&of_dev->dev, &dev_attr_cpu_fan_speed); | 641 | device_remove_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); |
601 | 642 | ||
602 | if(therm_type == ADT7460) | 643 | if(therm_type == ADT7460) |
603 | device_remove_file(&of_dev->dev, | 644 | device_remove_file(&of_dev->dev, |
604 | &dev_attr_gpu_fan_speed); | 645 | &dev_attr_sensor2_fan_speed); |
605 | 646 | ||
606 | of_device_unregister(of_dev); | 647 | of_device_unregister(of_dev); |
607 | } | 648 | } |