Re: [PATCH v13 2/2] platform/x86/lenovo: Add Yoga Book 9 keyboard dock detection driver

Dave Carey <[email protected]>
Newsgroups org.kernel.vger.platform-driver-x86,org.kernel.vger.linux-input,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Ugh ... let me check, was trying to do a few different things today at 
the same time.  Appreciate the patience.


-DC


On 7/22/26 10:42 AM, Ilpo Järvinen wrote:
> On Wed, 22 Jul 2026, Dave Carey wrote:
>
>> The Lenovo Yoga Book 9 14IAH10 ships with a detachable Bluetooth keyboard
>> that magnetically attaches to the bottom (secondary) screen in one of two
>> positions.  The Embedded Controller tracks the attachment state in a 2-bit
>> field called BKBD and signals changes via WMI event GUID
>> 806BD2A2-177B-481D-BFB5-3BA0BB4A2285 (notify ID 0xEB on the WM10 ACPI
>> device, _UID "GMZN").
>>
>> The device contains embedded BMOF data (WQDD, 20705 bytes) documenting
>> both WMI interfaces used by this driver:
>>
>>    LENOVO_BTKBD_EVENT (event GUID): WmiDataId(1) uint32 Status.
>>    The ACPI _WED(0xEB) method returns EC.BKBD directly as an integer,
>>    so the notify callback receives BKBD without a separate query.
>>
>>    LENOVO_FEATURE_STATUS_DATA (block GUID, WQAF method): returns an
>>    8-byte buffer {uint32 IDs=0x00060000, uint32 Status=BKBD}.
>>    Used for the initial state read on probe and after resume.
>>
>> BKBD encoding:
>>    0 = keyboard detached
>>    1 = keyboard docked on top half of bottom screen
>>    2 = keyboard docked on bottom half of bottom screen
>>    3 = reserved (not observed in practice)
>>
>> This driver registers two WMI drivers sharing a module-level
>> BLOCKING_NOTIFIER_HEAD:
>>
>>    - The event driver (LENOVO_BTKBD_EVENT) uses .notify_new() to receive
>>      a pre-parsed wmi_buffer and fires the notifier chain with the BKBD
>>      value extracted from the buffer.
>>
>>    - The block driver (LENOVO_FEATURE_STATUS_DATA) owns the input_dev in
>>      its per-device private struct.  At probe time it registers a
>>      notifier_block on the chain and reads the initial BKBD state via
>>      wmidev_query_block().  The WMI buffer is parsed as
>>      struct lenovo_feature_status { __le32 id; __le32 status; }, and the
>>      ID field is verified before the status is used.
>>
>>    - SW_TABLET_MODE=1 is reported when the keyboard is detached;
>>      SW_TABLET_MODE=0 when docked in either position (keyboard present).
>>
>>    - The raw BKBD value is exposed via read-only sysfs attribute
>>      "keyboard_position".
>>
>>    - BKBD state is re-read via wmidev_query_block() on resume from
>>      suspend or hibernation.
>>
>> Tested on: Lenovo Yoga Book 9 14IAH10 (model 83KJ), kernel 7.0.
>>
>> Acked-by: Hans de Goede <[email protected]>
>> Reviewed-by: Armin Wolf <[email protected]>
>> Signed-off-by: Dave Carey <[email protected]>
>> ---
>> v13:
>> - Resend of v12: patch was corrupted in transit.  git-send-email chose
>>    quoted-printable encoding (triggered by non-ASCII in the changelog)
>>    which encoded '=' as '=3D', corrupting the RST table separators in
>>    the ABI doc and breaking git-am.  No content changes from v12.
>>
>> v12:
>> - Add #include <linux/sysfs.h> (for sysfs_emit; Ilpo Järvinen)
>> - Add #include <linux/types.h> (for __le32 and __packed; Ilpo Järvinen)
>>
>> v11 (addressing Armin Wolf's v10 review):
>> - ABI doc: correct Date to "June 2027" and KernelVersion to "7.3"
>>
>> v10 (addressing Armin Wolf's v9 review):
>> - Update ABI doc: Date: June 2026, KernelVersion: 6.16
>> - Add #include <linux/compiler_attributes.h> and <linux/types.h>
>> - yb9_kbdock_query(): change return to pointer-out u32 *bkbd
>> - struct yb9_kbdock_data: add spinlock_t lock
>> - yb9_kbdock_report(): hold lock across input_report_switch + input_sync
>> - yb9_kbdock_sync(): return int, propagate query error to callers
>> - yb9_kbdock_resume(), yb9_kbdock_block_probe(): propagate sync error
>> - struct wmi_buffer out: remove zero-initializer
>> - yb9_kbdock_notify_new(): drop manual length check; use
>>    .min_event_size = sizeof(__le32) in struct wmi_driver instead
>>
>>   .../testing/sysfs-driver-lenovo-yb9-kbdock    |  19 ++
>>   MAINTAINERS                                   |   7 +
>>   drivers/platform/x86/lenovo/Kconfig           |  14 +
>>   drivers/platform/x86/lenovo/Makefile          |   1 +
>>   drivers/platform/x86/lenovo/yb9-kbdock.c      | 312 ++++++++++++++++++
>>   5 files changed, 353 insertions(+)
>>   create mode 100644 Documentation/ABI/testing/sysfs-driver-lenovo-yb9-kbdock
>>   create mode 100644 drivers/platform/x86/lenovo/yb9-kbdock.c
>>
>> diff --git a/Documentation/ABI/testing/sysfs-driver-lenovo-yb9-kbdock b/Documentation/ABI/testing/sysfs-driver-lenovo-yb9-kbdock
>> new file mode 100644
>> index 0000000..ebe713a
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-driver-lenovo-yb9-kbdock
>> @@ -0,0 +1,19 @@
>> +What:		/sys/bus/wmi/drivers/lenovo-yb9-kbdock/<guid>/keyboard_position
>> +Date:		June 2027
>> +KernelVersion:	7.3
>> +Contact:	Dave Carey <[email protected]>
>> +Description:
>> +		Read-only attribute reporting the current keyboard dock position
>> +		as reported by the Embedded Controller on the Lenovo Yoga Book 9
>> +		14IAH10.
>> +
>> +		Possible values:
>> +
>> +		==  =============================================================
>> +		0   keyboard is not docked to any screen (detached)
>> +		1   keyboard docked on the top half of the bottom screen
>> +		2   keyboard docked on the bottom half of the bottom screen
>> +		==  =============================================================
>> +
>> +		SW_TABLET_MODE input events are also emitted: 0 when the keyboard
>> +		is docked (either position), 1 when detached.
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index d1cc0e1..00e8275 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -14479,6 +14479,13 @@ L:	[email protected]
>>   S:	Maintained
>>   F:	drivers/platform/x86/lenovo/wmi-hotkey-utilities.c
>>   
>> +LENOVO YOGA BOOK 9 KEYBOARD DOCK DRIVER
>> +M:	Dave Carey <[email protected]>
>> +L:	[email protected]
>> +S:	Maintained
>> +F:	Documentation/ABI/testing/sysfs-driver-lenovo-yb9-kbdock
>> +F:	drivers/platform/x86/lenovo/yb9-kbdock.c
>> +
>>   LETSKETCH HID TABLET DRIVER
>>   M:	Hans de Goede <[email protected]>
>>   L:	[email protected]
>> diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/lenovo/Kconfig
>> index 9c48487..938b361 100644
>> --- a/drivers/platform/x86/lenovo/Kconfig
>> +++ b/drivers/platform/x86/lenovo/Kconfig
>> @@ -43,6 +43,20 @@ config LENOVO_WMI_CAMERA
>>   	  To compile this driver as a module, choose M here: the module
>>   	  will be called lenovo-wmi-camera.
>>   
>> +config LENOVO_YB9_KBDOCK
>> +	tristate "Lenovo Yoga Book 9 keyboard dock detection"
>> +	depends on ACPI_WMI
>> +	depends on DMI
>> +	depends on INPUT
>> +	help
>> +	  Say Y here to enable keyboard dock detection on the Lenovo Yoga Book 9
>> +	  14IAH10.  The detachable Bluetooth keyboard magnetically attaches to
>> +	  either screen; this driver reports SW_TABLET_MODE input events based
>> +	  on the attachment state and exposes the raw position in sysfs.
>> +
>> +	  To compile this driver as a module, choose M here: the module will be
>> +	  called lenovo-yb9-kbdock.
>> +
>>   config LENOVO_YMC
>>   	tristate "Lenovo Yoga Tablet Mode Control"
>>   	depends on ACPI_WMI
>> diff --git a/drivers/platform/x86/lenovo/Makefile b/drivers/platform/x86/lenovo/Makefile
>> index 7b2128e..2842d7d 100644
>> --- a/drivers/platform/x86/lenovo/Makefile
>> +++ b/drivers/platform/x86/lenovo/Makefile
>> @@ -8,6 +8,7 @@ obj-$(CONFIG_THINKPAD_LMI)	+= think-lmi.o
>>   obj-$(CONFIG_THINKPAD_ACPI)	+= thinkpad_acpi.o
>>   
>>   lenovo-target-$(CONFIG_LENOVO_WMI_HOTKEY_UTILITIES)	+= wmi-hotkey-utilities.o
>> +lenovo-target-$(CONFIG_LENOVO_YB9_KBDOCK)	+= yb9-kbdock.o
>>   lenovo-target-$(CONFIG_LENOVO_YMC)	+= ymc.o
>>   lenovo-target-$(CONFIG_YOGABOOK)	+= yogabook.o
>>   lenovo-target-$(CONFIG_YT2_1380)	+= yoga-tab2-pro-1380-fastcharger.o
>> diff --git a/drivers/platform/x86/lenovo/yb9-kbdock.c b/drivers/platform/x86/lenovo/yb9-kbdock.c
>> new file mode 100644
>> index 0000000..69c68a0
>> --- /dev/null
>> +++ b/drivers/platform/x86/lenovo/yb9-kbdock.c
>> @@ -0,0 +1,312 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Lenovo Yoga Book 9 keyboard-dock detection
>> + *
>> + * The Yoga Book 9 ships with a detachable Bluetooth keyboard that magnetically
>> + * attaches to the bottom screen in one of two positions.  The EC tracks
>> + * attachment state in a 2-bit field called BKBD and signals changes via WMI
>> + * event 0xEB on the WM10 ACPI device (_UID "GMZN").
>> + *
>> + * BKBD values:
>> + *   0 = keyboard detached
>> + *   1 = keyboard docked on the top half of the bottom screen
>> + *   2 = keyboard docked on the bottom half of the bottom screen
>> + *   3 = reserved / not observed
>> + *
>> + * Two WMI interfaces are used (documented in embedded BMOF, WQDD, 20705 bytes):
>> + *
>> + *   LENOVO_BTKBD_EVENT (event GUID, 806BD2A2-...)
>> + *     WmiDataId(1) uint32 Status — _WED(0xEB) returns EC.BKBD directly.
>> + *     The notify callback receives BKBD as an integer; no separate query needed.
>> + *
>> + *   LENOVO_FEATURE_STATUS_DATA (block GUID, E7F300FA-...)
>> + *     WmiDataId(1) uint32 IDs   = 0x00060000 (feature selector)
>> + *     WmiDataId(2) uint32 Status = BKBD value
>> + *     Used on probe and resume to read initial state.
>> + *
>> + * The event driver (LENOVO_BTKBD_EVENT) fires a notifier chain on each WMI
>> + * event.  The block driver (LENOVO_FEATURE_STATUS_DATA) owns the input_dev
>> + * and registers a notifier_block to receive those events, eliminating the
>> + * need for shared global state or a mutex.
>> + *
>> + * SW_TABLET_MODE=1 is reported when the keyboard is detached;
>> + * SW_TABLET_MODE=0 when docked in either position (keyboard present).
>> + * The raw BKBD value is exposed via the sysfs attribute "keyboard_position".
>> + *
>> + * Copyright (C) 2026 Dave Carey <[email protected]>
>> + */
>> +
>> +#include <linux/acpi.h>
>> +#include <linux/cleanup.h>
>> +#include <linux/dev_printk.h>
>> +#include <linux/dmi.h>
>> +#include <linux/input.h>
>> +#include <linux/module.h>
>> +#include <linux/notifier.h>
>> +#include <linux/pm.h>
>> +#include <linux/slab.h>
>> +#include <linux/sysfs.h>
>> +#include <linux/types.h>
>> +#include <linux/wmi.h>
> Hi,
>
> Are you sure you sent the latest version, AFAICT, v12 had this:
>
> +#include <linux/acpi.h>
> +#include <linux/cleanup.h>
> +#include <linux/compiler_attributes.h>
> +#include <linux/dev_printk.h>
> ...
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +#include <linux/sysfs.h>
> +#include <linux/types.h>
> +#include <linux/wmi.h>
>
> ?
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.