diff options
author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2006-11-24 08:47:11 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-12-07 01:38:40 -0500 |
commit | a8b7a6626d7605a795b33317cd730b7d76da3d0a (patch) | |
tree | 4e6654a1237d4350d3b7ff0a781a7b9a3d939804 | |
parent | 18ad7996e17649d81c15a2c9dae03c75050a05a8 (diff) |
ACPI: ibm-acpi: document fan control
This patch documents the ThinkPad fan control strategies. Source of the
data:
0. ibm-acpi source
1. DSDTs for various ThinkPads (770, X31, X40, X41, T43, A21m, T22)
2. http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
3. http://thinkwiki.org/wiki/How_to_control_fan_speed
4. Various threads about windows fan control utilities in thinkpads.com
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
-rw-r--r-- | drivers/acpi/ibm_acpi.c | 110 |
1 files changed, 108 insertions, 2 deletions
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 187af1bfcb9d..faf78d3eac2d 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c | |||
@@ -205,7 +205,7 @@ IBM_HANDLE(led, ec, "SLED", /* 570 */ | |||
205 | IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ | 205 | IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ |
206 | IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */ | 206 | IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */ |
207 | IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */ | 207 | IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */ |
208 | IBM_HANDLE(fans, ec, "FANS"); /* X31, X40 */ | 208 | IBM_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */ |
209 | 209 | ||
210 | IBM_HANDLE(gfan, ec, "GFAN", /* 570 */ | 210 | IBM_HANDLE(gfan, ec, "GFAN", /* 570 */ |
211 | "\\FSPD", /* 600e/x, 770e, 770x */ | 211 | "\\FSPD", /* 600e/x, 770e, 770x */ |
@@ -231,6 +231,106 @@ struct ibm_thermal_sensors_struct { | |||
231 | s32 temp[IBMACPI_MAX_THERMAL_SENSORS]; | 231 | s32 temp[IBMACPI_MAX_THERMAL_SENSORS]; |
232 | }; | 232 | }; |
233 | 233 | ||
234 | /* | ||
235 | * FAN ACCESS MODES | ||
236 | * | ||
237 | * IBMACPI_FAN_RD_ACPI_GFAN: | ||
238 | * ACPI GFAN method: returns fan level | ||
239 | * | ||
240 | * see IBMACPI_FAN_WR_ACPI_SFAN | ||
241 | * EC 0x2f not available if GFAN exists | ||
242 | * | ||
243 | * IBMACPI_FAN_WR_ACPI_SFAN: | ||
244 | * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max) | ||
245 | * | ||
246 | * EC 0x2f might be available *for reading*, but never for writing. | ||
247 | * | ||
248 | * IBMACPI_FAN_WR_TPEC: | ||
249 | * ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported | ||
250 | * on almost all ThinkPads | ||
251 | * | ||
252 | * Fan speed changes of any sort (including those caused by the | ||
253 | * disengaged mode) are usually done slowly by the firmware as the | ||
254 | * maximum ammount of fan duty cycle change per second seems to be | ||
255 | * limited. | ||
256 | * | ||
257 | * Reading is not available if GFAN exists. | ||
258 | * Writing is not available if SFAN exists. | ||
259 | * | ||
260 | * Bits | ||
261 | * 7 automatic mode engaged; | ||
262 | * (default operation mode of the ThinkPad) | ||
263 | * fan level is ignored in this mode. | ||
264 | * 6 disengage mode (takes precedence over bit 7); | ||
265 | * not available on all thinkpads. May disable | ||
266 | * the tachometer, and speeds up fan to 100% duty-cycle, | ||
267 | * which speeds it up far above the standard RPM | ||
268 | * levels. It is not impossible that it could cause | ||
269 | * hardware damage. | ||
270 | * 5-3 unused in some models. Extra bits for fan level | ||
271 | * in others, but still useless as all values above | ||
272 | * 7 map to the same speed as level 7 in these models. | ||
273 | * 2-0 fan level (0..7 usually) | ||
274 | * 0x00 = stop | ||
275 | * 0x07 = max (set when temperatures critical) | ||
276 | * Some ThinkPads may have other levels, see | ||
277 | * IBMACPI_FAN_WR_ACPI_FANS (X31/X40/X41) | ||
278 | * | ||
279 | * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at | ||
280 | * boot. Apparently the EC does not intialize it, so unless ACPI DSDT | ||
281 | * does so, its initial value is meaningless (0x07). | ||
282 | * | ||
283 | * For firmware bugs, refer to: | ||
284 | * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues | ||
285 | * | ||
286 | * ---- | ||
287 | * | ||
288 | * ThinkPad EC register 0x84 (LSB), 0x85 (MSB): | ||
289 | * Main fan tachometer reading (in RPM) | ||
290 | * | ||
291 | * This register is present on all ThinkPads with a new-style EC, and | ||
292 | * it is known not to be present on the A21m/e, and T22, as there is | ||
293 | * something else in offset 0x84 according to the ACPI DSDT. Other | ||
294 | * ThinkPads from this same time period (and earlier) probably lack the | ||
295 | * tachometer as well. | ||
296 | * | ||
297 | * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare | ||
298 | * was never fixed by IBM to report the EC firmware version string | ||
299 | * probably support the tachometer (like the early X models), so | ||
300 | * detecting it is quite hard. We need more data to know for sure. | ||
301 | * | ||
302 | * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings | ||
303 | * might result. | ||
304 | * | ||
305 | * FIRMWARE BUG: when EC 0x2f bit 6 is set (disengaged mode), this | ||
306 | * register is not invalidated in ThinkPads that disable tachometer | ||
307 | * readings. Thus, the tachometer readings go stale. | ||
308 | * | ||
309 | * For firmware bugs, refer to: | ||
310 | * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues | ||
311 | * | ||
312 | * IBMACPI_FAN_WR_ACPI_FANS: | ||
313 | * ThinkPad X31, X40, X41. Not available in the X60. | ||
314 | * | ||
315 | * FANS ACPI handle: takes three arguments: low speed, medium speed, | ||
316 | * high speed. ACPI DSDT seems to map these three speeds to levels | ||
317 | * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH | ||
318 | * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3") | ||
319 | * | ||
320 | * The speeds are stored on handles | ||
321 | * (FANA:FAN9), (FANC:FANB), (FANE:FAND). | ||
322 | * | ||
323 | * There are three default speed sets, acessible as handles: | ||
324 | * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H | ||
325 | * | ||
326 | * ACPI DSDT switches which set is in use depending on various | ||
327 | * factors. | ||
328 | * | ||
329 | * IBMACPI_FAN_WR_TPEC is also available and should be used to | ||
330 | * command the fan. The X31/X40/X41 seems to have 8 fan levels, | ||
331 | * but the ACPI tables just mention level 7. | ||
332 | */ | ||
333 | |||
234 | enum fan_status_access_mode { | 334 | enum fan_status_access_mode { |
235 | IBMACPI_FAN_NONE = 0, /* No fan status or control */ | 335 | IBMACPI_FAN_NONE = 0, /* No fan status or control */ |
236 | IBMACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */ | 336 | IBMACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */ |
@@ -1722,7 +1822,7 @@ static int fan_init(void) | |||
1722 | /* all other models implement TP EC 0x2f control */ | 1822 | /* all other models implement TP EC 0x2f control */ |
1723 | 1823 | ||
1724 | if (fans_handle) { | 1824 | if (fans_handle) { |
1725 | /* X31, X40 */ | 1825 | /* X31, X40, X41 */ |
1726 | fan_control_access_mode = | 1826 | fan_control_access_mode = |
1727 | IBMACPI_FAN_WR_ACPI_FANS; | 1827 | IBMACPI_FAN_WR_ACPI_FANS; |
1728 | fan_control_commands |= | 1828 | fan_control_commands |= |
@@ -1742,6 +1842,9 @@ static int fan_get_status(u8 *status) | |||
1742 | { | 1842 | { |
1743 | u8 s; | 1843 | u8 s; |
1744 | 1844 | ||
1845 | /* TODO: | ||
1846 | * Add IBMACPI_FAN_RD_ACPI_FANS ? */ | ||
1847 | |||
1745 | switch (fan_status_access_mode) { | 1848 | switch (fan_status_access_mode) { |
1746 | case IBMACPI_FAN_RD_ACPI_GFAN: | 1849 | case IBMACPI_FAN_RD_ACPI_GFAN: |
1747 | /* 570, 600e/x, 770e, 770x */ | 1850 | /* 570, 600e/x, 770e, 770x */ |
@@ -1950,6 +2053,9 @@ static int fan_write_cmd_speed(const char *cmd, int *rc) | |||
1950 | { | 2053 | { |
1951 | int speed; | 2054 | int speed; |
1952 | 2055 | ||
2056 | /* TODO: | ||
2057 | * Support speed <low> <medium> <high> ? */ | ||
2058 | |||
1953 | if (sscanf(cmd, "speed %d", &speed) != 1) | 2059 | if (sscanf(cmd, "speed %d", &speed) != 1) |
1954 | return 0; | 2060 | return 0; |
1955 | 2061 | ||