--- linux-2.6.16/drivers/acpi/ibm_acpi.c 2006-03-20 06:53:29.000000000 +0100 +++ /usr/src/linux/drivers/acpi/ibm_acpi.c 2006-07-19 00:32:24.000000000 +0200 @@ -1229,28 +1229,43 @@ if (!thermal_tmp_supported) len += sprintf(p + len, "temperatures:\tnot supported\n"); else { - int i, t; - char tmpi[] = "TMPi"; - s8 tmp[8]; + int i; + const static size_t addresses[] = { + 0x78, /* CPU (below fan) */ + 0x79, /* APS sensor */ + 0x7A, /* PCMCIA */ + 0x7B, /* GPU */ + 0x7C, /* Battery (bat0?) */ + 0x7D, /* ?? */ + 0x7E, /* Battery (bat1?) */ + 0x7F, /* ?? */ + 0xC0, /* Northbridge */ + 0xC1, /* Southbridge (wlan) */ + 0xC2 /* Power */ }; + const static size_t sensor_count = sizeof addresses / + sizeof *addresses; + s8 tmp[sensor_count]; if (thermal_updt_supported) if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) return -EIO; - for (i = 0; i < 8; i++) { - tmpi[3] = '0' + i; - if (!acpi_evalf(ec_handle, &t, tmpi, "d")) + for (i = 0; i < sensor_count; i++) { + size_t address = addresses[i]; + u8 value; + + if (!acpi_ec_read(address, &value)) return -EIO; if (thermal_updt_supported) - tmp[i] = (t - 2732 + 5) / 10; + tmp[i] = ((s8)value - 2732 + 5) / 10; else - tmp[i] = t; + tmp[i] = (s8)value; } - - len += sprintf(p + len, - "temperatures:\t%d %d %d %d %d %d %d %d\n", - tmp[0], tmp[1], tmp[2], tmp[3], - tmp[4], tmp[5], tmp[6], tmp[7]); + + len += sprintf(p + len, "temperatures:\t" ); + for (i = 0; i < sensor_count; ++i ) + len += sprintf(p + len, "%d%c", tmp[i], + i == sensor_count - 1 ? '\n' : ' '); } return len; @@ -1465,6 +1480,7 @@ { int len = 0; int s; + char status_read = 0; u8 lo, hi, status; if (gfan_handle) { @@ -1477,9 +1493,11 @@ /* all except 570, 600e/x, 770e, 770x */ if (!acpi_ec_read(fan_status_offset, &status)) len += sprintf(p + len, "status:\t\tunreadable\n"); - else + else { len += sprintf(p + len, "status:\t\t%s\n", - enabled(status, 7)); + status ? "enabled" : "disabled"); + status_read = 1; + } if (!acpi_ec_read(fan_rpm_offset, &lo) || !acpi_ec_read(fan_rpm_offset + 1, &hi)) @@ -1487,6 +1505,14 @@ else len += sprintf(p + len, "speed:\t\t%d\n", (hi << 8) + lo); + if ( status_read ) { + if ( status & 0x40 ) + len += sprintf(p + len, "level:\t\tdisengaged\n"); + else if ( status & 0x80 ) + len += sprintf(p + len, "level:\t\tauto\n"); + else + len += sprintf(p + len, "level:\t\t%d\n", status); + } } if (sfan_handle) @@ -1495,7 +1521,10 @@ " ( is 0-7)\n"); if (!gfan_handle) /* all except 570, 600e/x, 770e, 770x */ - len += sprintf(p + len, "commands:\tenable, disable\n"); + len += sprintf(p + len, + "commands:\tenable, disable, level \n" + " \t( is 0-7, auto " + "or disengaged)\n"); if (fans_handle) /* X31, X40 */ len += sprintf(p + len, "commands:\tspeed " @@ -1516,7 +1545,9 @@ /* 570, 770x-JL */ if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) return -EIO; - } else if (!gfan_handle && strlencmp(cmd, "enable") == 0) { + } else if (!gfan_handle && + ( (strlencmp(cmd, "enable") == 0) || + (strlencmp(cmd, "level auto") == 0) ) ) { /* all except 570, 600e/x, 770e, 770x */ if (!acpi_ec_write(fan_status_offset, 0x80)) return -EIO; @@ -1524,7 +1555,18 @@ /* all except 570, 600e/x, 770e, 770x */ if (!acpi_ec_write(fan_status_offset, 0x00)) return -EIO; - } else if (fans_handle && + } else if (!gfan_handle && + strlencmp(cmd, "level disengaged") == 0) { + /* all except 570, 600e/x, 770e, 770x */ + if (!acpi_ec_write(fan_status_offset, 0x40)) + return -EIO; + } else if (!gfan_handle && + sscanf(cmd, "level %d", &level) == 1 && + level >=0 && level <= 7) { + /* all except 570, 600e/x, 770e, 770x */ + if (!acpi_ec_write(fan_status_offset, level)) + return -EIO; + } else if (fans_handle && sscanf(cmd, "speed %d", &speed) == 1 && speed >= 0 && speed <= 65535) { /* X31, X40 */