diff options
Diffstat (limited to 'drivers/platform/x86/thinkpad_acpi.c')
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 87 |
1 files changed, 63 insertions, 24 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index c3bfa1fe95bf..b65ce7519411 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -2043,6 +2043,7 @@ static int hotkey_autosleep_ack; | |||
2043 | 2043 | ||
2044 | static u32 hotkey_orig_mask; /* events the BIOS had enabled */ | 2044 | static u32 hotkey_orig_mask; /* events the BIOS had enabled */ |
2045 | static u32 hotkey_all_mask; /* all events supported in fw */ | 2045 | static u32 hotkey_all_mask; /* all events supported in fw */ |
2046 | static u32 hotkey_adaptive_all_mask; /* all adaptive events supported in fw */ | ||
2046 | static u32 hotkey_reserved_mask; /* events better left disabled */ | 2047 | static u32 hotkey_reserved_mask; /* events better left disabled */ |
2047 | static u32 hotkey_driver_mask; /* events needed by the driver */ | 2048 | static u32 hotkey_driver_mask; /* events needed by the driver */ |
2048 | static u32 hotkey_user_mask; /* events visible to userspace */ | 2049 | static u32 hotkey_user_mask; /* events visible to userspace */ |
@@ -2742,6 +2743,17 @@ static ssize_t hotkey_all_mask_show(struct device *dev, | |||
2742 | 2743 | ||
2743 | static DEVICE_ATTR_RO(hotkey_all_mask); | 2744 | static DEVICE_ATTR_RO(hotkey_all_mask); |
2744 | 2745 | ||
2746 | /* sysfs hotkey all_mask ----------------------------------------------- */ | ||
2747 | static ssize_t hotkey_adaptive_all_mask_show(struct device *dev, | ||
2748 | struct device_attribute *attr, | ||
2749 | char *buf) | ||
2750 | { | ||
2751 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", | ||
2752 | hotkey_adaptive_all_mask | hotkey_source_mask); | ||
2753 | } | ||
2754 | |||
2755 | static DEVICE_ATTR_RO(hotkey_adaptive_all_mask); | ||
2756 | |||
2745 | /* sysfs hotkey recommended_mask --------------------------------------- */ | 2757 | /* sysfs hotkey recommended_mask --------------------------------------- */ |
2746 | static ssize_t hotkey_recommended_mask_show(struct device *dev, | 2758 | static ssize_t hotkey_recommended_mask_show(struct device *dev, |
2747 | struct device_attribute *attr, | 2759 | struct device_attribute *attr, |
@@ -2985,6 +2997,7 @@ static struct attribute *hotkey_attributes[] __initdata = { | |||
2985 | &dev_attr_wakeup_hotunplug_complete.attr, | 2997 | &dev_attr_wakeup_hotunplug_complete.attr, |
2986 | &dev_attr_hotkey_mask.attr, | 2998 | &dev_attr_hotkey_mask.attr, |
2987 | &dev_attr_hotkey_all_mask.attr, | 2999 | &dev_attr_hotkey_all_mask.attr, |
3000 | &dev_attr_hotkey_adaptive_all_mask.attr, | ||
2988 | &dev_attr_hotkey_recommended_mask.attr, | 3001 | &dev_attr_hotkey_recommended_mask.attr, |
2989 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | 3002 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL |
2990 | &dev_attr_hotkey_source_mask.attr, | 3003 | &dev_attr_hotkey_source_mask.attr, |
@@ -3321,20 +3334,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3321 | if (!tp_features.hotkey) | 3334 | if (!tp_features.hotkey) |
3322 | return 1; | 3335 | return 1; |
3323 | 3336 | ||
3324 | /* | ||
3325 | * Check if we have an adaptive keyboard, like on the | ||
3326 | * Lenovo Carbon X1 2014 (2nd Gen). | ||
3327 | */ | ||
3328 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { | ||
3329 | if ((hkeyv >> 8) == 2) { | ||
3330 | tp_features.has_adaptive_kbd = true; | ||
3331 | res = sysfs_create_group(&tpacpi_pdev->dev.kobj, | ||
3332 | &adaptive_kbd_attr_group); | ||
3333 | if (res) | ||
3334 | goto err_exit; | ||
3335 | } | ||
3336 | } | ||
3337 | |||
3338 | quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable, | 3337 | quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable, |
3339 | ARRAY_SIZE(tpacpi_hotkey_qtable)); | 3338 | ARRAY_SIZE(tpacpi_hotkey_qtable)); |
3340 | 3339 | ||
@@ -3357,30 +3356,70 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3357 | A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking | 3356 | A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking |
3358 | for HKEY interface version 0x100 */ | 3357 | for HKEY interface version 0x100 */ |
3359 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { | 3358 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { |
3360 | if ((hkeyv >> 8) != 1) { | 3359 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
3361 | pr_err("unknown version of the HKEY interface: 0x%x\n", | 3360 | "firmware HKEY interface version: 0x%x\n", |
3362 | hkeyv); | 3361 | hkeyv); |
3363 | pr_err("please report this to %s\n", TPACPI_MAIL); | 3362 | |
3364 | } else { | 3363 | switch (hkeyv >> 8) { |
3364 | case 1: | ||
3365 | /* | 3365 | /* |
3366 | * MHKV 0x100 in A31, R40, R40e, | 3366 | * MHKV 0x100 in A31, R40, R40e, |
3367 | * T4x, X31, and later | 3367 | * T4x, X31, and later |
3368 | */ | 3368 | */ |
3369 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | ||
3370 | "firmware HKEY interface version: 0x%x\n", | ||
3371 | hkeyv); | ||
3372 | 3369 | ||
3373 | /* Paranoia check AND init hotkey_all_mask */ | 3370 | /* Paranoia check AND init hotkey_all_mask */ |
3374 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, | 3371 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, |
3375 | "MHKA", "qd")) { | 3372 | "MHKA", "qd")) { |
3376 | pr_err("missing MHKA handler, " | 3373 | pr_err("missing MHKA handler, please report this to %s\n", |
3377 | "please report this to %s\n", | ||
3378 | TPACPI_MAIL); | 3374 | TPACPI_MAIL); |
3379 | /* Fallback: pre-init for FN+F3,F4,F12 */ | 3375 | /* Fallback: pre-init for FN+F3,F4,F12 */ |
3380 | hotkey_all_mask = 0x080cU; | 3376 | hotkey_all_mask = 0x080cU; |
3381 | } else { | 3377 | } else { |
3382 | tp_features.hotkey_mask = 1; | 3378 | tp_features.hotkey_mask = 1; |
3383 | } | 3379 | } |
3380 | break; | ||
3381 | |||
3382 | case 2: | ||
3383 | /* | ||
3384 | * MHKV 0x200 in X1, T460s, X260, T560, X1 Tablet (2016) | ||
3385 | */ | ||
3386 | |||
3387 | /* Paranoia check AND init hotkey_all_mask */ | ||
3388 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, | ||
3389 | "MHKA", "dd", 1)) { | ||
3390 | pr_err("missing MHKA handler, please report this to %s\n", | ||
3391 | TPACPI_MAIL); | ||
3392 | /* Fallback: pre-init for FN+F3,F4,F12 */ | ||
3393 | hotkey_all_mask = 0x080cU; | ||
3394 | } else { | ||
3395 | tp_features.hotkey_mask = 1; | ||
3396 | } | ||
3397 | |||
3398 | /* | ||
3399 | * Check if we have an adaptive keyboard, like on the | ||
3400 | * Lenovo Carbon X1 2014 (2nd Gen). | ||
3401 | */ | ||
3402 | if (acpi_evalf(hkey_handle, &hotkey_adaptive_all_mask, | ||
3403 | "MHKA", "dd", 2)) { | ||
3404 | if (hotkey_adaptive_all_mask != 0) { | ||
3405 | tp_features.has_adaptive_kbd = true; | ||
3406 | res = sysfs_create_group( | ||
3407 | &tpacpi_pdev->dev.kobj, | ||
3408 | &adaptive_kbd_attr_group); | ||
3409 | if (res) | ||
3410 | goto err_exit; | ||
3411 | } | ||
3412 | } else { | ||
3413 | tp_features.has_adaptive_kbd = false; | ||
3414 | hotkey_adaptive_all_mask = 0x0U; | ||
3415 | } | ||
3416 | break; | ||
3417 | |||
3418 | default: | ||
3419 | pr_err("unknown version of the HKEY interface: 0x%x\n", | ||
3420 | hkeyv); | ||
3421 | pr_err("please report this to %s\n", TPACPI_MAIL); | ||
3422 | break; | ||
3384 | } | 3423 | } |
3385 | } | 3424 | } |
3386 | 3425 | ||