From: Henrique de M. H. <hm...@hm...> - 2006-11-22 20:13:46
|
From: Henrique de Moraes Holschuh <hm...@hm...> This patch lays some groundwork for a fan_read and fan_write cleanup in t= he next patches. To do so, it provides a new fan_init initializer, and also= some constants (through enums). Signed-off-by: Henrique de Moraes Holschuh <hm...@hm...> --- drivers/acpi/ibm_acpi.c | 81 +++++++++++++++++++++++++++++++++++++++++= +++++- 1 files changed, 79 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 1f8a2c6..2c2ee63 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -231,6 +231,31 @@ struct ibm_thermal_sensors_struct { s32 temp[IBMACPI_MAX_THERMAL_SENSORS]; }; =20 +enum fan_status_access_mode { + IBMACPI_FAN_NONE =3D 0, /* No fan status or control */ + IBMACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */ + IBMACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */ +}; + +enum fan_control_access_mode { + IBMACPI_FAN_WR_NONE =3D 0, /* No fan control */ + IBMACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */ + IBMACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */ + IBMACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */ +}; + +enum fan_control_commands { + IBMACPI_FAN_CMD_SPEED =3D 0x0001, /* speed command */ + IBMACPI_FAN_CMD_LEVEL =3D 0x0002, /* level command */ + IBMACPI_FAN_CMD_ENABLE =3D 0x0004, /* enable/disable cmd */ +}; + +enum { /* Fan control constants */ + fan_status_offset =3D 0x2f, /* EC register 0x2f */ + fan_rpm_offset =3D 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) + * 0x84 must be read before 0x85 */ +}; + static int ibm_thinkpad_ec_found; =20 struct ibm_struct { @@ -1659,8 +1684,59 @@ static int volume_write(char *buf) return 0; } =20 -static int fan_status_offset =3D 0x2f; -static int fan_rpm_offset =3D 0x84; +static enum fan_status_access_mode fan_status_access_mode; +static enum fan_control_access_mode fan_control_access_mode; +static enum fan_control_commands fan_control_commands; + +static int fan_init(void) +{ + u8 status; + + fan_status_access_mode =3D IBMACPI_FAN_NONE; + fan_control_access_mode =3D IBMACPI_FAN_WR_NONE; + fan_control_commands =3D 0; + + if (gfan_handle) { + /* 570, 600e/x, 770e, 770x */ + fan_status_access_mode =3D IBMACPI_FAN_RD_ACPI_GFAN; + } else { + /* all other ThinkPads: note that even old-style + * ThinkPad ECs supports the fan control register */ + if (likely(acpi_ec_read(fan_status_offset, &status))) { + fan_status_access_mode =3D IBMACPI_FAN_RD_TPEC; + } else { + printk(IBM_ERR + "ThinkPad ACPI EC access misbehaving, " + "fan status and control unavailable\n"); + return 0; + } + } + + if (sfan_handle) { + /* 570, 770x-JL */ + fan_control_access_mode =3D IBMACPI_FAN_WR_ACPI_SFAN; + fan_control_commands |=3D IBMACPI_FAN_CMD_LEVEL; + } else { + if (!gfan_handle) { + /* gfan without sfan means no fan control */ + /* all other models implement TP EC 0x2f control */ + + if (fans_handle) { + /* X31, X40 */ + fan_control_access_mode =3D + IBMACPI_FAN_WR_ACPI_FANS; + fan_control_commands |=3D + IBMACPI_FAN_CMD_SPEED | + IBMACPI_FAN_CMD_ENABLE; + } else { + fan_control_access_mode =3D IBMACPI_FAN_WR_TPEC; + fan_control_commands |=3D IBMACPI_FAN_CMD_ENABLE; + } + } + } + + return 0; +} =20 static int fan_read(char *p) { @@ -1849,6 +1925,7 @@ static struct ibm_struct ibms[] =3D { .name =3D "fan", .read =3D fan_read, .write =3D fan_write, + .init =3D fan_init, .experimental =3D 1, }, }; |