diff options
| -rw-r--r-- | drivers/macintosh/therm_adt746x.c | 119 |
1 files changed, 77 insertions, 42 deletions
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index c7e84abe8951..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) |
| @@ -569,6 +583,23 @@ thermostat_init(void) | |||
| 569 | "limit_adjust: %d, fan_speed: %d\n", | 583 | "limit_adjust: %d, fan_speed: %d\n", |
| 570 | therm_bus, therm_address, limit_adjust, fan_speed); | 584 | therm_bus, therm_address, limit_adjust, fan_speed); |
| 571 | 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 | |||
| 572 | of_dev = of_platform_device_create(np, "temperatures"); | 603 | of_dev = of_platform_device_create(np, "temperatures"); |
| 573 | 604 | ||
| 574 | if (of_dev == NULL) { | 605 | if (of_dev == NULL) { |
| @@ -576,15 +607,17 @@ thermostat_init(void) | |||
| 576 | return -ENODEV; | 607 | return -ENODEV; |
| 577 | } | 608 | } |
| 578 | 609 | ||
| 579 | device_create_file(&of_dev->dev, &dev_attr_cpu_temperature); | 610 | device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); |
| 580 | device_create_file(&of_dev->dev, &dev_attr_gpu_temperature); | 611 | device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); |
| 581 | device_create_file(&of_dev->dev, &dev_attr_cpu_limit); | 612 | device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); |
| 582 | 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); | ||
| 583 | device_create_file(&of_dev->dev, &dev_attr_limit_adjust); | 616 | device_create_file(&of_dev->dev, &dev_attr_limit_adjust); |
| 584 | device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); | 617 | device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); |
| 585 | device_create_file(&of_dev->dev, &dev_attr_cpu_fan_speed); | 618 | device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); |
| 586 | if(therm_type == ADT7460) | 619 | if(therm_type == ADT7460) |
| 587 | device_create_file(&of_dev->dev, &dev_attr_gpu_fan_speed); | 620 | device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); |
| 588 | 621 | ||
| 589 | #ifndef CONFIG_I2C_KEYWEST | 622 | #ifndef CONFIG_I2C_KEYWEST |
| 590 | request_module("i2c-keywest"); | 623 | request_module("i2c-keywest"); |
| @@ -597,17 +630,19 @@ static void __exit | |||
| 597 | thermostat_exit(void) | 630 | thermostat_exit(void) |
| 598 | { | 631 | { |
| 599 | if (of_dev) { | 632 | if (of_dev) { |
| 600 | device_remove_file(&of_dev->dev, &dev_attr_cpu_temperature); | 633 | device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature); |
| 601 | device_remove_file(&of_dev->dev, &dev_attr_gpu_temperature); | 634 | device_remove_file(&of_dev->dev, &dev_attr_sensor2_temperature); |
| 602 | device_remove_file(&of_dev->dev, &dev_attr_cpu_limit); | 635 | device_remove_file(&of_dev->dev, &dev_attr_sensor1_limit); |
| 603 | 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); | ||
| 604 | device_remove_file(&of_dev->dev, &dev_attr_limit_adjust); | 639 | device_remove_file(&of_dev->dev, &dev_attr_limit_adjust); |
| 605 | device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed); | 640 | device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed); |
| 606 | device_remove_file(&of_dev->dev, &dev_attr_cpu_fan_speed); | 641 | device_remove_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); |
| 607 | 642 | ||
| 608 | if(therm_type == ADT7460) | 643 | if(therm_type == ADT7460) |
| 609 | device_remove_file(&of_dev->dev, | 644 | device_remove_file(&of_dev->dev, |
| 610 | &dev_attr_gpu_fan_speed); | 645 | &dev_attr_sensor2_fan_speed); |
| 611 | 646 | ||
| 612 | of_device_unregister(of_dev); | 647 | of_device_unregister(of_dev); |
| 613 | } | 648 | } |
