From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5A99839C63E; Mon, 8 Jun 2026 09:09:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780909777; cv=none; b=U0qyuScLPpu7ZwCoELPdIyyMFWRRa9ZH03ome7K+molvnHxjXvbhlWUceWZNzQEe8rw7qJGbtBR8h13EDgiC7IBlzAdQHSesxncRV/noOknecRDQU+GCAgtOEml5NeKo5U2jS3uewMxEJ5ym96UXX8cRojJsNgli370wyUGj31Y= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780909777; c=relaxed/simple; bh=7TtTyc0T7UkVE3z8NugD7l/ScYxBGIVay7o40LqbpVs=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=riaXpGi+vEQuBrhNbfFKAR+7ZJizjdqqPvISL0+39Wet0BHkjv16dmLrgLOvarqSLe+j81vDjN5gTrjpeEJM3NXF1pL+Jpq5EZMNaKrd++mjexVTYg1f+/2RvBMcjroSbHPIG7snpcY+B6lGotQXiYxn3/8P+ksGK8dWf46CL7M= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EbN0mYjV; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EbN0mYjV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1C2BE1F00893; Mon, 8 Jun 2026 09:09:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780909776; bh=DC9M+VJB63+AlefnkvC7BOt5ivnEG3IkY0k3v7g8GZI=; h=Date:Subject:To:Cc:References:From:In-Reply-To; b=EbN0mYjVcgMe7cxQiILnMDQ/JJ1pcnI+5Ollhrmx+jyVJh10D0hUJ16wHAVBPJro/ zvgfe5iX/PcGWfhwR9VqpZXufkn4Zxu/hM7s0zxv5ooXUds6Xfvc1zrN3U1hmX9piZ gF2aEkLnCCEAxOoQJQhHM9gdvhD72wyr01u5/fGTOXMiQzKENkYCG92fPf3ZtsdJcG vcxY2AXyUy2JatVpX5aEz5UVzreHSPOTaG2/CqI4d6y/MmXhdO11pM3eUjxKEplHnA u4+b/Yq4l0gKMUKaBxRSkbJLSTbwBBnNJHZS+BPbJRykzhz0BOjhcuo1jf334wpITW X5JKaASeWz/Eg== Message-ID: <84f822c5-ff42-453a-bbd6-3b2afba28621@kernel.org> Date: Mon, 8 Jun 2026 11:09:31 +0200 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2] platform/x86: thinkpad-acpi: Add X1 Fold keyboard attachment detection To: Pit Henrich , hmh@hmh.eng.br, Dave Carey , Armin Wolf Cc: mpearson-lenovo@squebb.ca, derekjohn.clark@gmail.com, ilpo.jarvinen@linux.intel.com, ibm-acpi-devel@lists.sourceforge.net, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, pithenrich2d@gmail.com References: <20260419102724.91451-1-pithenrich2d@gmail.com> From: Hans de Goede Content-Language: en-US, nl In-Reply-To: <20260419102724.91451-1-pithenrich2d@gmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Hi, On 19-Apr-26 12:27 PM, Pit Henrich wrote: > ThinkPad X1 Fold 16 Gen 1 firmware reports whether the keyboard is magnetically > attached (on the screen), but thinkpad-acpi does not expose this to userspace. > The state can be obtained via ACPI methods: GDST (get device state). > > Add a read-only keyboard_attached_on_screen sysfs attribute, gated by > a DMI match. The state is read directly from the EC. > > Cache the state and emit a sysfs notification on > TP_HKEY_EV_TABLET_CHANGED (0x60c0) when it changes. Initialize the cache during > hotkey setup and refresh it before the resume notification to keep the state > consistent across suspend and resume. > > Signed-off-by: Pit Henrich > --- > This replaced the v1 patch in: > https://lore.kernel.org/all/20260314142236.74514-1-pithenrich2d@gmail.com/ > > Changes v1 -> v2: > * Use ACPI method instead of using the EC directly (thanks Mark). Thank you for your patch. It seems that this information is also exposed via WMI and a WMI driver exposing the same information is also being worked on: https://patchwork.kernel.org/project/platform-driver-x86/patch/20260527122701.242907-1-carvsdriver@gmail.com/ +Cc Dave Carey (author of that driver) and Armin (WMI maintainer) Since doing this in thinkpad_acpi requires adding a DMI match and directly calling an APCI method which name may change I believe that the WMI approach may be better. There we can rely on only the Fold exposing the WMI GUID for this functionality. Dave, I see that your "[PATCH v5] platform/x86/lenovo: Add Yoga Book 9 keyboard dock detection driver" patch also uses a DMI match, is that necessary ? If we need the DMI match because the GUID is not unique enough, then we might just as well add this functionality here as this patch is doing ... I do wonder since this seems to emit TP_HKEY_EV_TABLET_CHANGED thinkpad_acpi events if the existing thinkpad_acpi support does not already provide working SW_TABLET_MODE input ? If it does then also having the WMI driver emit SW_TABLET_MODE events seems to be undesirable duplicate functionality. Regards, Hans > > --- > drivers/platform/x86/lenovo/thinkpad_acpi.c | 85 ++++++++++++++++++++- > 1 file changed, 83 insertions(+), 2 deletions(-) > > diff --git a/drivers/platform/x86/lenovo/thinkpad_acpi.c b/drivers/platform/x86/lenovo/thinkpad_acpi.c > index 8982d92dfd97..b57ae7eb5548 100644 > --- a/drivers/platform/x86/lenovo/thinkpad_acpi.c > +++ b/drivers/platform/x86/lenovo/thinkpad_acpi.c > @@ -218,8 +218,9 @@ enum tpacpi_hkey_event_t { > TP_HKEY_EV_LID_OPEN = 0x5002, /* laptop lid opened */ > TP_HKEY_EV_TABLET_TABLET = 0x5009, /* tablet swivel up */ > TP_HKEY_EV_TABLET_NOTEBOOK = 0x500a, /* tablet swivel down */ > - TP_HKEY_EV_TABLET_CHANGED = 0x60c0, /* X1 Yoga (2016): > - * enter/leave tablet mode > + TP_HKEY_EV_TABLET_CHANGED = 0x60c0, /* posture change event: > + * X1 Yoga (2016): enter/leave tablet mode > + * X1 Fold 16 Gen 1: keyboard attachment state changed > */ > TP_HKEY_EV_PEN_INSERTED = 0x500b, /* tablet pen inserted */ > TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */ > @@ -375,6 +376,7 @@ static struct { > u32 has_adaptive_kbd:1; > u32 kbd_lang:1; > u32 trackpoint_doubletap:1; > + u32 has_keyboard_attached_on_screen:1; > struct quirk_entry *quirks; > } tp_features; > > @@ -2928,6 +2930,63 @@ static void hotkey_tablet_mode_notify_change(void) > "hotkey_tablet_mode"); > } > > +static bool keyboard_attached_on_screen; > +static bool keyboard_attached_on_screen_initialized; > + > +static int x1_fold_keyboard_attached_on_screen_get(bool *attached) > +{ > + int state; > + > + if (!tp_features.has_keyboard_attached_on_screen) > + return -ENODEV; > + > + if (!acpi_evalf(NULL, &state, "\\_SB.DEVD.GDST", "d")) > + return -EIO; > + > + *attached = state != 0; > + return 0; > +} > + > +static ssize_t keyboard_attached_on_screen_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + bool attached; > + int res; > + > + res = x1_fold_keyboard_attached_on_screen_get(&attached); > + if (res) > + return res; > + > + return sysfs_emit(buf, "%d\n", attached); > +} > + > +static DEVICE_ATTR_RO(keyboard_attached_on_screen); > + > +static void keyboard_attached_on_screen_notify_change(void) > +{ > + if (tp_features.has_keyboard_attached_on_screen) > + sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, > + "keyboard_attached_on_screen"); > +} > + > +static bool keyboard_attached_on_screen_update(void) > +{ > + bool attached; > + > + if (x1_fold_keyboard_attached_on_screen_get(&attached)) > + return false; > + > + if (keyboard_attached_on_screen_initialized && > + keyboard_attached_on_screen == attached) > + return false; > + > + keyboard_attached_on_screen = attached; > + keyboard_attached_on_screen_initialized = true; > + > + return true; > +} > + > /* sysfs wakeup reason (pollable) -------------------------------------- */ > static ssize_t hotkey_wakeup_reason_show(struct device *dev, > struct device_attribute *attr, > @@ -3032,6 +3091,7 @@ static struct attribute *hotkey_attributes[] = { > &dev_attr_hotkey_adaptive_all_mask.attr, > &dev_attr_hotkey_recommended_mask.attr, > &dev_attr_hotkey_tablet_mode.attr, > + &dev_attr_keyboard_attached_on_screen.attr, > &dev_attr_hotkey_radio_sw.attr, > #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL > &dev_attr_hotkey_source_mask.attr, > @@ -3046,6 +3106,9 @@ static umode_t hotkey_attr_is_visible(struct kobject *kobj, > if (attr == &dev_attr_hotkey_tablet_mode.attr) { > if (!tp_features.hotkey_tablet) > return 0; > + } else if (attr == &dev_attr_keyboard_attached_on_screen.attr) { > + if (!tp_features.has_keyboard_attached_on_screen) > + return 0; > } else if (attr == &dev_attr_hotkey_radio_sw.attr) { > if (!tp_features.hotkey_wlsw) > return 0; > @@ -3462,6 +3525,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) > } > > tabletsw_state = hotkey_init_tablet_mode(); > + keyboard_attached_on_screen_update(); > > /* Set up key map */ > keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable, > @@ -3842,6 +3906,8 @@ static bool hotkey_notify_6xxx(const u32 hkey, bool *send_acpi_ev) > case TP_HKEY_EV_TABLET_CHANGED: > tpacpi_input_send_tabletsw(); > hotkey_tablet_mode_notify_change(); > + if (keyboard_attached_on_screen_update()) > + keyboard_attached_on_screen_notify_change(); > *send_acpi_ev = false; > return true; > > @@ -3998,6 +4064,8 @@ static void hotkey_resume(void) > tpacpi_send_radiosw_update(); > tpacpi_input_send_tabletsw(); > hotkey_tablet_mode_notify_change(); > + keyboard_attached_on_screen_update(); > + keyboard_attached_on_screen_notify_change(); > hotkey_wakeup_reason_notify_change(); > hotkey_wakeup_hotunplug_complete_notify_change(); > hotkey_poll_setup_safe(false); > @@ -4296,6 +4364,17 @@ static const struct dmi_system_id fwbug_list[] __initconst = { > {} > }; > > +static const struct dmi_system_id keyboard_attached_on_screen_list[] __initconst = { > + { > + .ident = "ThinkPad X1 Fold 16 Gen 1", > + .matches = { > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), > + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Fold 16 Gen 1"), > + }, > + }, > + {} > +}; > + > static const struct pci_device_id fwbug_cards_ids[] __initconst = { > { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24F3) }, > { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24FD) }, > @@ -12230,6 +12309,8 @@ static int __init thinkpad_acpi_module_init(void) > dmi_id = dmi_first_match(fwbug_list); > if (dmi_id) > tp_features.quirks = dmi_id->driver_data; > + tp_features.has_keyboard_attached_on_screen = > + dmi_check_system(keyboard_attached_on_screen_list); > > /* Device initialization */ > tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, PLATFORM_DEVID_NONE,