diff options
Diffstat (limited to 'drivers/platform/x86/thinkpad_acpi.c')
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 77f6e707a2a9..26c5b117df22 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -184,6 +184,10 @@ enum tpacpi_hkey_event_t { | |||
184 | 184 | ||
185 | /* Misc bay events */ | 185 | /* Misc bay events */ |
186 | TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */ | 186 | TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */ |
187 | TP_HKEY_EV_HOTPLUG_DOCK = 0x4010, /* docked into hotplug dock | ||
188 | or port replicator */ | ||
189 | TP_HKEY_EV_HOTPLUG_UNDOCK = 0x4011, /* undocked from hotplug | ||
190 | dock or port replicator */ | ||
187 | 191 | ||
188 | /* User-interface events */ | 192 | /* User-interface events */ |
189 | TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */ | 193 | TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */ |
@@ -194,6 +198,10 @@ enum tpacpi_hkey_event_t { | |||
194 | TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */ | 198 | TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */ |
195 | TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */ | 199 | TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */ |
196 | 200 | ||
201 | /* Key-related user-interface events */ | ||
202 | TP_HKEY_EV_KEY_NUMLOCK = 0x6000, /* NumLock key pressed */ | ||
203 | TP_HKEY_EV_KEY_FN = 0x6005, /* Fn key pressed? E420 */ | ||
204 | |||
197 | /* Thermal events */ | 205 | /* Thermal events */ |
198 | TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ | 206 | TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ |
199 | TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */ | 207 | TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */ |
@@ -201,6 +209,10 @@ enum tpacpi_hkey_event_t { | |||
201 | TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */ | 209 | TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */ |
202 | TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* thermal table changed */ | 210 | TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* thermal table changed */ |
203 | 211 | ||
212 | TP_HKEY_EV_UNK_6040 = 0x6040, /* Related to AC change? | ||
213 | some sort of APM hint, | ||
214 | W520 */ | ||
215 | |||
204 | /* Misc */ | 216 | /* Misc */ |
205 | TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */ | 217 | TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */ |
206 | }; | 218 | }; |
@@ -3513,6 +3525,34 @@ static bool hotkey_notify_wakeup(const u32 hkey, | |||
3513 | return true; | 3525 | return true; |
3514 | } | 3526 | } |
3515 | 3527 | ||
3528 | static bool hotkey_notify_dockevent(const u32 hkey, | ||
3529 | bool *send_acpi_ev, | ||
3530 | bool *ignore_acpi_ev) | ||
3531 | { | ||
3532 | /* 0x4000-0x4FFF: dock-related events */ | ||
3533 | *send_acpi_ev = true; | ||
3534 | *ignore_acpi_ev = false; | ||
3535 | |||
3536 | switch (hkey) { | ||
3537 | case TP_HKEY_EV_UNDOCK_ACK: | ||
3538 | /* ACPI undock operation completed after wakeup */ | ||
3539 | hotkey_autosleep_ack = 1; | ||
3540 | pr_info("undocked\n"); | ||
3541 | hotkey_wakeup_hotunplug_complete_notify_change(); | ||
3542 | return true; | ||
3543 | |||
3544 | case TP_HKEY_EV_HOTPLUG_DOCK: /* docked to port replicator */ | ||
3545 | pr_info("docked into hotplug port replicator\n"); | ||
3546 | return true; | ||
3547 | case TP_HKEY_EV_HOTPLUG_UNDOCK: /* undocked from port replicator */ | ||
3548 | pr_info("undocked from hotplug port replicator\n"); | ||
3549 | return true; | ||
3550 | |||
3551 | default: | ||
3552 | return false; | ||
3553 | } | ||
3554 | } | ||
3555 | |||
3516 | static bool hotkey_notify_usrevent(const u32 hkey, | 3556 | static bool hotkey_notify_usrevent(const u32 hkey, |
3517 | bool *send_acpi_ev, | 3557 | bool *send_acpi_ev, |
3518 | bool *ignore_acpi_ev) | 3558 | bool *ignore_acpi_ev) |
@@ -3547,13 +3587,13 @@ static bool hotkey_notify_usrevent(const u32 hkey, | |||
3547 | 3587 | ||
3548 | static void thermal_dump_all_sensors(void); | 3588 | static void thermal_dump_all_sensors(void); |
3549 | 3589 | ||
3550 | static bool hotkey_notify_thermal(const u32 hkey, | 3590 | static bool hotkey_notify_6xxx(const u32 hkey, |
3551 | bool *send_acpi_ev, | 3591 | bool *send_acpi_ev, |
3552 | bool *ignore_acpi_ev) | 3592 | bool *ignore_acpi_ev) |
3553 | { | 3593 | { |
3554 | bool known = true; | 3594 | bool known = true; |
3555 | 3595 | ||
3556 | /* 0x6000-0x6FFF: thermal alarms */ | 3596 | /* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */ |
3557 | *send_acpi_ev = true; | 3597 | *send_acpi_ev = true; |
3558 | *ignore_acpi_ev = false; | 3598 | *ignore_acpi_ev = false; |
3559 | 3599 | ||
@@ -3582,8 +3622,17 @@ static bool hotkey_notify_thermal(const u32 hkey, | |||
3582 | "a sensor reports something is extremely hot!\n"); | 3622 | "a sensor reports something is extremely hot!\n"); |
3583 | /* recommended action: immediate sleep/hibernate */ | 3623 | /* recommended action: immediate sleep/hibernate */ |
3584 | break; | 3624 | break; |
3625 | |||
3626 | case TP_HKEY_EV_KEY_NUMLOCK: | ||
3627 | case TP_HKEY_EV_KEY_FN: | ||
3628 | /* key press events, we just ignore them as long as the EC | ||
3629 | * is still reporting them in the normal keyboard stream */ | ||
3630 | *send_acpi_ev = false; | ||
3631 | *ignore_acpi_ev = true; | ||
3632 | return true; | ||
3633 | |||
3585 | default: | 3634 | default: |
3586 | pr_alert("THERMAL ALERT: unknown thermal alarm received\n"); | 3635 | pr_warn("unknown possible thermal alarm or keyboard event received\n"); |
3587 | known = false; | 3636 | known = false; |
3588 | } | 3637 | } |
3589 | 3638 | ||
@@ -3652,15 +3701,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3652 | } | 3701 | } |
3653 | break; | 3702 | break; |
3654 | case 4: | 3703 | case 4: |
3655 | /* 0x4000-0x4FFF: dock-related wakeups */ | 3704 | /* 0x4000-0x4FFF: dock-related events */ |
3656 | if (hkey == TP_HKEY_EV_UNDOCK_ACK) { | 3705 | known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev, |
3657 | hotkey_autosleep_ack = 1; | 3706 | &ignore_acpi_ev); |
3658 | pr_info("undocked\n"); | ||
3659 | hotkey_wakeup_hotunplug_complete_notify_change(); | ||
3660 | known_ev = true; | ||
3661 | } else { | ||
3662 | known_ev = false; | ||
3663 | } | ||
3664 | break; | 3707 | break; |
3665 | case 5: | 3708 | case 5: |
3666 | /* 0x5000-0x5FFF: human interface helpers */ | 3709 | /* 0x5000-0x5FFF: human interface helpers */ |
@@ -3668,8 +3711,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3668 | &ignore_acpi_ev); | 3711 | &ignore_acpi_ev); |
3669 | break; | 3712 | break; |
3670 | case 6: | 3713 | case 6: |
3671 | /* 0x6000-0x6FFF: thermal alarms */ | 3714 | /* 0x6000-0x6FFF: thermal alarms/notices and |
3672 | known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev, | 3715 | * keyboard events */ |
3716 | known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev, | ||
3673 | &ignore_acpi_ev); | 3717 | &ignore_acpi_ev); |
3674 | break; | 3718 | break; |
3675 | case 7: | 3719 | case 7: |