diff options
author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2006-11-24 08:47:13 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-12-07 01:38:43 -0500 |
commit | a12095c2b50c8a7c80517e37c00d6e6c863d43c5 (patch) | |
tree | 61f17cfdfa283430531e1b4749e2de93b2b0a812 | |
parent | 1c6a334e9c028c2b72c5350650cb14e6d5fdc232 (diff) |
ACPI: ibm-acpi: fix and extend fan control functions
This patch extend fan control functions, implementing enable/disable for
all write access modes, implementing level control for all level-capable
write access modes.
The patch also updates the documentation, explaining levels auto and
disengaged.
ABI changes:
1. Support level 0 as an equivalent to disable
2. Add support for level auto and level disengaged when doing
EC 0x2f fan control
3. Support enable/disable for all level-based write access modes
4. Add support for level command on FANS thinkpads, as per
thinkwiki reports
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
-rw-r--r-- | Documentation/ibm-acpi.txt | 65 | ||||
-rw-r--r-- | drivers/acpi/ibm_acpi.c | 39 |
2 files changed, 80 insertions, 24 deletions
diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt index 333b8eb97f96..cbd3a603a7ef 100644 --- a/Documentation/ibm-acpi.txt +++ b/Documentation/ibm-acpi.txt | |||
@@ -571,27 +571,57 @@ directly accesses hardware registers and may not work as expected. USE | |||
571 | WITH CAUTION! To use this feature, you need to supply the | 571 | WITH CAUTION! To use this feature, you need to supply the |
572 | experimental=1 parameter when loading the module. | 572 | experimental=1 parameter when loading the module. |
573 | 573 | ||
574 | This feature attempts to show the current fan speed. The speed is read | 574 | This feature attempts to show the current fan speed, control mode and |
575 | directly from the hardware registers of the embedded controller. This | 575 | other fan data that might be available. The speed is read directly |
576 | is known to work on later R, T and X series ThinkPads but may show a | 576 | from the hardware registers of the embedded controller. This is known |
577 | bogus value on other models. | 577 | to work on later R, T and X series ThinkPads but may show a bogus |
578 | value on other models. | ||
579 | |||
580 | Most ThinkPad fans work in "levels". Level 0 stops the fan. The higher | ||
581 | the level, the higher the fan speed, although adjacent levels often map | ||
582 | to the same fan speed. 7 is the highest level, where the fan reaches | ||
583 | the maximum recommended speed. Level "auto" means the EC changes the | ||
584 | fan level according to some internal algorithm, usually based on | ||
585 | readings from the thermal sensors. Level "disengaged" means the EC | ||
586 | disables the speed-locked closed-loop fan control, and drives the fan as | ||
587 | fast as it can go, which might exceed hardware limits, so use this level | ||
588 | with caution. | ||
589 | |||
590 | The fan usually ramps up or down slowly from one speed to another, | ||
591 | and it is normal for the EC to take several seconds to react to fan | ||
592 | commands. | ||
578 | 593 | ||
579 | The fan may be enabled or disabled with the following commands: | 594 | The fan may be enabled or disabled with the following commands: |
580 | 595 | ||
581 | echo enable >/proc/acpi/ibm/fan | 596 | echo enable >/proc/acpi/ibm/fan |
582 | echo disable >/proc/acpi/ibm/fan | 597 | echo disable >/proc/acpi/ibm/fan |
583 | 598 | ||
599 | Placing a fan on level 0 is the same as disabling it. Enabling a fan | ||
600 | will try to place it in a safe level if it is too slow or disabled. | ||
601 | |||
584 | WARNING WARNING WARNING: do not leave the fan disabled unless you are | 602 | WARNING WARNING WARNING: do not leave the fan disabled unless you are |
585 | monitoring the temperature sensor readings and you are ready to enable | 603 | monitoring all of the temperature sensor readings and you are ready to |
586 | it if necessary to avoid overheating. | 604 | enable it if necessary to avoid overheating. |
605 | |||
606 | An enabled fan in level "auto" may stop spinning if the EC decides the | ||
607 | ThinkPad is cool enough and doesn't need the extra airflow. This is | ||
608 | normal, and the EC will spin the fan up if the varios thermal readings | ||
609 | rise too much. | ||
610 | |||
611 | On the X40, this seems to depend on the CPU and HDD temperatures. | ||
612 | Specifically, the fan is turned on when either the CPU temperature | ||
613 | climbs to 56 degrees or the HDD temperature climbs to 46 degrees. The | ||
614 | fan is turned off when the CPU temperature drops to 49 degrees and the | ||
615 | HDD temperature drops to 41 degrees. These thresholds cannot | ||
616 | currently be controlled. | ||
617 | |||
618 | The fan level can be controlled with the command: | ||
587 | 619 | ||
588 | The fan only runs if it's enabled *and* the various temperature | 620 | echo 'level <level>' > /proc/acpi/ibm/thermal |
589 | sensors which control it read high enough. On the X40, this seems to | 621 | |
590 | depend on the CPU and HDD temperatures. Specifically, the fan is | 622 | Where <level> is an integer from 0 to 7, or one of the words "auto" |
591 | turned on when either the CPU temperature climbs to 56 degrees or the | 623 | or "disengaged" (without the quotes). Not all ThinkPads support the |
592 | HDD temperature climbs to 46 degrees. The fan is turned off when the | 624 | "auto" and "disengaged" levels. |
593 | CPU temperature drops to 49 degrees and the HDD temperature drops to | ||
594 | 41 degrees. These thresholds cannot currently be controlled. | ||
595 | 625 | ||
596 | On the X31 and X40 (and ONLY on those models), the fan speed can be | 626 | On the X31 and X40 (and ONLY on those models), the fan speed can be |
597 | controlled to a certain degree. Once the fan is running, it can be | 627 | controlled to a certain degree. Once the fan is running, it can be |
@@ -604,12 +634,9 @@ about 3700 to about 7350. Values outside this range either do not have | |||
604 | any effect or the fan speed eventually settles somewhere in that | 634 | any effect or the fan speed eventually settles somewhere in that |
605 | range. The fan cannot be stopped or started with this command. | 635 | range. The fan cannot be stopped or started with this command. |
606 | 636 | ||
607 | On the 570, temperature readings are not available through this | 637 | The ThinkPad's ACPI DSDT code will reprogram the fan on its own when |
608 | feature and the fan control works a little differently. The fan speed | 638 | certain conditions are met. It will override any fan programming done |
609 | is reported in levels from 0 (off) to 7 (max) and can be controlled | 639 | through ibm-acpi. |
610 | with the following command: | ||
611 | |||
612 | echo 'level <level>' > /proc/acpi/ibm/thermal | ||
613 | 640 | ||
614 | EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan | 641 | EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan |
615 | --------------------------------------- | 642 | --------------------------------------- |
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index ecb5ece79a37..4001ad193ddc 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c | |||
@@ -1833,10 +1833,13 @@ static int fan_init(void) | |||
1833 | IBMACPI_FAN_WR_ACPI_FANS; | 1833 | IBMACPI_FAN_WR_ACPI_FANS; |
1834 | fan_control_commands |= | 1834 | fan_control_commands |= |
1835 | IBMACPI_FAN_CMD_SPEED | | 1835 | IBMACPI_FAN_CMD_SPEED | |
1836 | IBMACPI_FAN_CMD_LEVEL | | ||
1836 | IBMACPI_FAN_CMD_ENABLE; | 1837 | IBMACPI_FAN_CMD_ENABLE; |
1837 | } else { | 1838 | } else { |
1838 | fan_control_access_mode = IBMACPI_FAN_WR_TPEC; | 1839 | fan_control_access_mode = IBMACPI_FAN_WR_TPEC; |
1839 | fan_control_commands |= IBMACPI_FAN_CMD_ENABLE; | 1840 | fan_control_commands |= |
1841 | IBMACPI_FAN_CMD_LEVEL | | ||
1842 | IBMACPI_FAN_CMD_ENABLE; | ||
1840 | } | 1843 | } |
1841 | } | 1844 | } |
1842 | } | 1845 | } |
@@ -1948,9 +1951,20 @@ static int fan_read(char *p) | |||
1948 | len += sprintf(p + len, "status:\t\tnot supported\n"); | 1951 | len += sprintf(p + len, "status:\t\tnot supported\n"); |
1949 | } | 1952 | } |
1950 | 1953 | ||
1951 | if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) | 1954 | if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) { |
1952 | len += sprintf(p + len, "commands:\tlevel <level>" | 1955 | len += sprintf(p + len, "commands:\tlevel <level>"); |
1953 | " (<level> is 0-7)\n"); | 1956 | |
1957 | switch (fan_control_access_mode) { | ||
1958 | case IBMACPI_FAN_WR_ACPI_SFAN: | ||
1959 | len += sprintf(p + len, " (<level> is 0-7)\n"); | ||
1960 | break; | ||
1961 | |||
1962 | default: | ||
1963 | len += sprintf(p + len, " (<level> is 0-7, " | ||
1964 | "auto, disengaged)\n"); | ||
1965 | break; | ||
1966 | } | ||
1967 | } | ||
1954 | 1968 | ||
1955 | if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE) | 1969 | if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE) |
1956 | len += sprintf(p + len, "commands:\tenable, disable\n"); | 1970 | len += sprintf(p + len, "commands:\tenable, disable\n"); |
@@ -1973,6 +1987,17 @@ static int fan_set_level(int level) | |||
1973 | return -EINVAL; | 1987 | return -EINVAL; |
1974 | break; | 1988 | break; |
1975 | 1989 | ||
1990 | case IBMACPI_FAN_WR_ACPI_FANS: | ||
1991 | case IBMACPI_FAN_WR_TPEC: | ||
1992 | if ((level != IBMACPI_FAN_EC_AUTO) && | ||
1993 | (level != IBMACPI_FAN_EC_DISENGAGED) && | ||
1994 | ((level < 0) || (level > 7))) | ||
1995 | return -EINVAL; | ||
1996 | |||
1997 | if (!acpi_ec_write(fan_status_offset, level)) | ||
1998 | return -EIO; | ||
1999 | break; | ||
2000 | |||
1976 | default: | 2001 | default: |
1977 | return -ENXIO; | 2002 | return -ENXIO; |
1978 | } | 2003 | } |
@@ -2060,7 +2085,11 @@ static int fan_write_cmd_level(const char *cmd, int *rc) | |||
2060 | { | 2085 | { |
2061 | int level; | 2086 | int level; |
2062 | 2087 | ||
2063 | if (sscanf(cmd, "level %d", &level) != 1) | 2088 | if (strlencmp(cmd, "level auto") == 0) |
2089 | level = IBMACPI_FAN_EC_AUTO; | ||
2090 | else if (strlencmp(cmd, "level disengaged") == 0) | ||
2091 | level = IBMACPI_FAN_EC_DISENGAGED; | ||
2092 | else if (sscanf(cmd, "level %d", &level) != 1) | ||
2064 | return 0; | 2093 | return 0; |
2065 | 2094 | ||
2066 | if ((*rc = fan_set_level(level)) == -ENXIO) | 2095 | if ((*rc = fan_set_level(level)) == -ENXIO) |