public inbox for linux-input@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Input: atkbd: add keymap fixup for notebooks using 0x6e as Fn modifier
@ 2026-02-18  4:13 Mikhail Novosyolov
  2026-02-18  6:26 ` Dmitry Torokhov
  0 siblings, 1 reply; 3+ messages in thread
From: Mikhail Novosyolov @ 2026-02-18  4:13 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input, mpearson-lenovo, m.novosyolov

Commit dc8c9c171ef3 ("Input: atkbd - map F23 key to support default
copilot shortcut") mapped scancode 0x6e to KEY_F23 to support the
Microsoft Copilot key on Lenovo, HP, and Dell notebooks.

However, some notebook platforms (including Positron Proxima 15 and
possibly others based on the same OEM design) use scancode 0x6e for the
Fn modifier key instead of a dedicated Copilot key. When 0x6e generates
KEY_F23 events, the Fn key breaks Fn combinations such as Fn+F5
(touchpad toggle).

On these platforms, the hardware relies on 0x6e being unmapped to
properly handle Fn combinations at the firmware level. When the kernel
maps it to KEY_F23, desktop environments intercept this as a global
hotkey and toggle the touchpad, but cannot re-enable it because the
firmware no longer recognizes Fn as a valid modifier.

Userspace solutions (systemd hwdb) cannot fix this because the keycode
mapping happens in the atkbd driver before events reach userspace.
A kernel-level quirk is required.

Add a DMI-based keymap fixup to remap scancode 0x6e to 0 for affected
systems. Currently only Positron Proxima 15 is known to be affected,
but other notebooks based on the same OEM platform may exhibit the same
behavior and can be added to the quirk table.

Scancode 0x6e has different meanings on different hardware:
- Lenovo/HP/Dell: F23 (Copilot key) - correctly mapped to KEY_F23
- Some OEM platforms: Fn modifier - must be unmapped

A generic solution is not feasible without breaking Copilot support
on other vendors.

Link: https://linux-hardware.org/?probe=7aca7ed668
Link: https://bugzilla.rosa.ru/show_bug.cgi?id=19950

Fixes: dc8c9c171ef3 ("Input: atkbd - map F23 key to support default copilot shortcut")
Co-developed-by: GLM-4.7 AI <noreply@z.ai>
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosa.ru>
---
 drivers/input/keyboard/atkbd.c | 51 ++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 6c999d89ee4b..e4ecdd9fc07b 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -1068,6 +1068,40 @@ static unsigned int atkbd_volume_forced_release_keys[] = {
 	0xae, 0xb0, -1U
 };
 
+/*
+ * Positron notebooks where scancode 0x6e is used by the Fn key and should
+ * not generate KEY_F23 events.
+ *
+ * Commit dc8c9c171ef3 ("Input: atkbd - map F23 key to support default
+ * copilot shortcut") mapped scancode 0x6e to KEY_F23 for Copilot support.
+ * However, on Positron notebooks scancode 0x6e is generated by the Fn
+ * modifier key and should be unmapped to allow firmware/hardware to
+ * process Fn+F5 and other Fn combinations properly.
+ */
+static unsigned int atkbd_positron_fn_keymap_fixup_scancodes[] = {
+	0x6e, -1U
+};
+
+/*
+ * Fixup to remap scancodes to 0 (no keycode) for machines where
+ * the default keymap incorrectly assigns keys that should be unused.
+ * This is needed when BIOS/firmware uses certain scancodes for
+ * internal purposes (e.g., Fn modifier) and they should not generate
+ * keyboard events.
+ */
+static void atkbd_apply_keymap_fixup(struct atkbd *atkbd, const void *data)
+{
+	const unsigned int *scancodes = data;
+	unsigned int i;
+
+	for (i = 0; scancodes[i] != -1U; i++) {
+		unsigned int scancode = scancodes[i];
+
+		if (scancode < ATKBD_KEYMAP_SIZE)
+			atkbd->keycode[scancode] = 0;
+	}
+}
+
 /*
  * OQO 01+ multimedia keys (64--66) generate e0 6x upon release whereas
  * they should be generating e4-e6 (0x80 | code).
@@ -1775,6 +1809,14 @@ static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)
 	return 1;
 }
 
+static int __init atkbd_setup_keymap_fixup(const struct dmi_system_id *id)
+{
+	atkbd_platform_fixup = atkbd_apply_keymap_fixup;
+	atkbd_platform_fixup_data = id->driver_data;
+
+	return 1;
+}
+
 static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id)
 {
 	atkbd_platform_scancode_fixup = id->driver_data;
@@ -1937,6 +1979,15 @@ static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = {
 		},
 		.callback = atkbd_deactivate_fixup,
 	},
+	{
+		/* Positron Proxima 15 - Fn key (0x6e) should not generate F23 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LNPO Positron LLC"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "G1569"),
+		},
+		.callback = atkbd_setup_keymap_fixup,
+		.driver_data = atkbd_positron_fn_keymap_fixup_scancodes,
+	},
 	{ }
 };
 
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-03-03 12:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-18  4:13 [PATCH] Input: atkbd: add keymap fixup for notebooks using 0x6e as Fn modifier Mikhail Novosyolov
2026-02-18  6:26 ` Dmitry Torokhov
2026-03-03 12:42   ` Mikhail Novosyolov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox