Message ID | 1479278381-3930-2-git-send-email-alex.hung@canonical.com |
---|---|
State | New |
Headers | show |
On 16/11/16 06:39, Alex Hung wrote: > From: Dennis Wassenberg <dennis.wassenberg@secunet.com> > > Lenovo Thinkpad devices T460, T460s, T460p, T560, X260 use > HKEY version 0x200 without adaptive keyboard. > > HKEY version 0x200 has method MHKA with one parameter value. > Passing parameter value 1 will get hotkey_all_mask (the same like > HKEY version 0x100 without parameter). Passing parameter value 2 to > MHKA method will retrieve hotkey_all_adaptive_mask. If 0 is returned in > that case there is no adaptive keyboard available. > > BugLink: http://bugs.launchpad.net/bugs/1642114 > > Signed-off-by: Dennis Wassenberg <dennis.wassenberg@secunet.com> > Signed-off-by: Lyude <cpaul@redhat.com> > Tested-by: Lyude <cpaul@redhat.com> > Tested-by: Marco Trevisan <marco@ubuntu.com> > Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> > [dvhart: Keep MHKA error string on one line in new and existing pr_err calls] > Signed-off-by: Darren Hart <dvhart@linux.intel.com> > > (cherry picked from commit 0118c2d3eac0545d4095877e5a015b5dc763b3c2) > Signed-off-by: Alex Hung <alex.hung@canonical.com> > --- > drivers/platform/x86/thinkpad_acpi.c | 87 ++++++++++++++++++++++++++---------- > 1 file changed, 63 insertions(+), 24 deletions(-) > > diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c > index a268a7a..a4dbacd 100644 > --- a/drivers/platform/x86/thinkpad_acpi.c > +++ b/drivers/platform/x86/thinkpad_acpi.c > @@ -2043,6 +2043,7 @@ static int hotkey_autosleep_ack; > > static u32 hotkey_orig_mask; /* events the BIOS had enabled */ > static u32 hotkey_all_mask; /* all events supported in fw */ > +static u32 hotkey_adaptive_all_mask; /* all adaptive events supported in fw */ > static u32 hotkey_reserved_mask; /* events better left disabled */ > static u32 hotkey_driver_mask; /* events needed by the driver */ > static u32 hotkey_user_mask; /* events visible to userspace */ > @@ -2742,6 +2743,17 @@ static ssize_t hotkey_all_mask_show(struct device *dev, > > static DEVICE_ATTR_RO(hotkey_all_mask); > > +/* sysfs hotkey all_mask ----------------------------------------------- */ > +static ssize_t hotkey_adaptive_all_mask_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + return snprintf(buf, PAGE_SIZE, "0x%08x\n", > + hotkey_adaptive_all_mask | hotkey_source_mask); > +} > + > +static DEVICE_ATTR_RO(hotkey_adaptive_all_mask); > + > /* sysfs hotkey recommended_mask --------------------------------------- */ > static ssize_t hotkey_recommended_mask_show(struct device *dev, > struct device_attribute *attr, > @@ -2985,6 +2997,7 @@ static struct attribute *hotkey_attributes[] __initdata = { > &dev_attr_wakeup_hotunplug_complete.attr, > &dev_attr_hotkey_mask.attr, > &dev_attr_hotkey_all_mask.attr, > + &dev_attr_hotkey_adaptive_all_mask.attr, > &dev_attr_hotkey_recommended_mask.attr, > #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL > &dev_attr_hotkey_source_mask.attr, > @@ -3321,20 +3334,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) > if (!tp_features.hotkey) > return 1; > > - /* > - * Check if we have an adaptive keyboard, like on the > - * Lenovo Carbon X1 2014 (2nd Gen). > - */ > - if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { > - if ((hkeyv >> 8) == 2) { > - tp_features.has_adaptive_kbd = true; > - res = sysfs_create_group(&tpacpi_pdev->dev.kobj, > - &adaptive_kbd_attr_group); > - if (res) > - goto err_exit; > - } > - } > - > quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable, > ARRAY_SIZE(tpacpi_hotkey_qtable)); > > @@ -3357,30 +3356,70 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) > A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking > for HKEY interface version 0x100 */ > if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { > - if ((hkeyv >> 8) != 1) { > - pr_err("unknown version of the HKEY interface: 0x%x\n", > - hkeyv); > - pr_err("please report this to %s\n", TPACPI_MAIL); > - } else { > + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, > + "firmware HKEY interface version: 0x%x\n", > + hkeyv); > + > + switch (hkeyv >> 8) { > + case 1: > /* > * MHKV 0x100 in A31, R40, R40e, > * T4x, X31, and later > */ > - vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, > - "firmware HKEY interface version: 0x%x\n", > - hkeyv); > > /* Paranoia check AND init hotkey_all_mask */ > if (!acpi_evalf(hkey_handle, &hotkey_all_mask, > "MHKA", "qd")) { > - pr_err("missing MHKA handler, " > - "please report this to %s\n", > + pr_err("missing MHKA handler, please report this to %s\n", > TPACPI_MAIL); > /* Fallback: pre-init for FN+F3,F4,F12 */ > hotkey_all_mask = 0x080cU; > } else { > tp_features.hotkey_mask = 1; > } > + break; > + > + case 2: > + /* > + * MHKV 0x200 in X1, T460s, X260, T560, X1 Tablet (2016) > + */ > + > + /* Paranoia check AND init hotkey_all_mask */ > + if (!acpi_evalf(hkey_handle, &hotkey_all_mask, > + "MHKA", "dd", 1)) { > + pr_err("missing MHKA handler, please report this to %s\n", > + TPACPI_MAIL); > + /* Fallback: pre-init for FN+F3,F4,F12 */ > + hotkey_all_mask = 0x080cU; > + } else { > + tp_features.hotkey_mask = 1; > + } > + > + /* > + * Check if we have an adaptive keyboard, like on the > + * Lenovo Carbon X1 2014 (2nd Gen). > + */ > + if (acpi_evalf(hkey_handle, &hotkey_adaptive_all_mask, > + "MHKA", "dd", 2)) { > + if (hotkey_adaptive_all_mask != 0) { > + tp_features.has_adaptive_kbd = true; > + res = sysfs_create_group( > + &tpacpi_pdev->dev.kobj, > + &adaptive_kbd_attr_group); > + if (res) > + goto err_exit; > + } > + } else { > + tp_features.has_adaptive_kbd = false; > + hotkey_adaptive_all_mask = 0x0U; > + } > + break; > + > + default: > + pr_err("unknown version of the HKEY interface: 0x%x\n", > + hkeyv); > + pr_err("please report this to %s\n", TPACPI_MAIL); > + break; > } > } > > Upstream fix, touches a limited set of platforms and just extends a particular hot key event control. Looks sane to me. Acked-by: Colin Ian King <colin.king@canonical.com>
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index a268a7a..a4dbacd 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2043,6 +2043,7 @@ static int hotkey_autosleep_ack; static u32 hotkey_orig_mask; /* events the BIOS had enabled */ static u32 hotkey_all_mask; /* all events supported in fw */ +static u32 hotkey_adaptive_all_mask; /* all adaptive events supported in fw */ static u32 hotkey_reserved_mask; /* events better left disabled */ static u32 hotkey_driver_mask; /* events needed by the driver */ static u32 hotkey_user_mask; /* events visible to userspace */ @@ -2742,6 +2743,17 @@ static ssize_t hotkey_all_mask_show(struct device *dev, static DEVICE_ATTR_RO(hotkey_all_mask); +/* sysfs hotkey all_mask ----------------------------------------------- */ +static ssize_t hotkey_adaptive_all_mask_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "0x%08x\n", + hotkey_adaptive_all_mask | hotkey_source_mask); +} + +static DEVICE_ATTR_RO(hotkey_adaptive_all_mask); + /* sysfs hotkey recommended_mask --------------------------------------- */ static ssize_t hotkey_recommended_mask_show(struct device *dev, struct device_attribute *attr, @@ -2985,6 +2997,7 @@ static struct attribute *hotkey_attributes[] __initdata = { &dev_attr_wakeup_hotunplug_complete.attr, &dev_attr_hotkey_mask.attr, &dev_attr_hotkey_all_mask.attr, + &dev_attr_hotkey_adaptive_all_mask.attr, &dev_attr_hotkey_recommended_mask.attr, #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL &dev_attr_hotkey_source_mask.attr, @@ -3321,20 +3334,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) if (!tp_features.hotkey) return 1; - /* - * Check if we have an adaptive keyboard, like on the - * Lenovo Carbon X1 2014 (2nd Gen). - */ - if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { - if ((hkeyv >> 8) == 2) { - tp_features.has_adaptive_kbd = true; - res = sysfs_create_group(&tpacpi_pdev->dev.kobj, - &adaptive_kbd_attr_group); - if (res) - goto err_exit; - } - } - quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable, ARRAY_SIZE(tpacpi_hotkey_qtable)); @@ -3357,30 +3356,70 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking for HKEY interface version 0x100 */ if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { - if ((hkeyv >> 8) != 1) { - pr_err("unknown version of the HKEY interface: 0x%x\n", - hkeyv); - pr_err("please report this to %s\n", TPACPI_MAIL); - } else { + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, + "firmware HKEY interface version: 0x%x\n", + hkeyv); + + switch (hkeyv >> 8) { + case 1: /* * MHKV 0x100 in A31, R40, R40e, * T4x, X31, and later */ - vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, - "firmware HKEY interface version: 0x%x\n", - hkeyv); /* Paranoia check AND init hotkey_all_mask */ if (!acpi_evalf(hkey_handle, &hotkey_all_mask, "MHKA", "qd")) { - pr_err("missing MHKA handler, " - "please report this to %s\n", + pr_err("missing MHKA handler, please report this to %s\n", TPACPI_MAIL); /* Fallback: pre-init for FN+F3,F4,F12 */ hotkey_all_mask = 0x080cU; } else { tp_features.hotkey_mask = 1; } + break; + + case 2: + /* + * MHKV 0x200 in X1, T460s, X260, T560, X1 Tablet (2016) + */ + + /* Paranoia check AND init hotkey_all_mask */ + if (!acpi_evalf(hkey_handle, &hotkey_all_mask, + "MHKA", "dd", 1)) { + pr_err("missing MHKA handler, please report this to %s\n", + TPACPI_MAIL); + /* Fallback: pre-init for FN+F3,F4,F12 */ + hotkey_all_mask = 0x080cU; + } else { + tp_features.hotkey_mask = 1; + } + + /* + * Check if we have an adaptive keyboard, like on the + * Lenovo Carbon X1 2014 (2nd Gen). + */ + if (acpi_evalf(hkey_handle, &hotkey_adaptive_all_mask, + "MHKA", "dd", 2)) { + if (hotkey_adaptive_all_mask != 0) { + tp_features.has_adaptive_kbd = true; + res = sysfs_create_group( + &tpacpi_pdev->dev.kobj, + &adaptive_kbd_attr_group); + if (res) + goto err_exit; + } + } else { + tp_features.has_adaptive_kbd = false; + hotkey_adaptive_all_mask = 0x0U; + } + break; + + default: + pr_err("unknown version of the HKEY interface: 0x%x\n", + hkeyv); + pr_err("please report this to %s\n", TPACPI_MAIL); + break; } }