diff mbox series

[v2,2/2] Input: atkbd - Fix TUXEDO NB02 notebook keyboards FN-keys

Message ID 20250303190442.551961-2-wse@tuxedocomputers.com (mailing list archive)
State Changes Requested, archived
Headers show
Series None | expand

Commit Message

Werner Sembach March 3, 2025, 7:04 p.m. UTC
This small driver does 2 things:

It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
F21 to conform with established userspace defaults. Note that the
Hangaku/Zenkaku scancode used here is usually unused, with real
Hangaku/Zenkaku keys using the tilde scancode.

It suppresses the reserved scancode produced by pressing the FN-key on its
own, which fixes a warning spamming the dmesg log otherwise.

Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
---
 MAINTAINERS                                 |  6 ++
 drivers/platform/x86/Kconfig                |  2 +
 drivers/platform/x86/Makefile               |  3 +
 drivers/platform/x86/tuxedo/Kbuild          |  6 ++
 drivers/platform/x86/tuxedo/Kconfig         |  6 ++
 drivers/platform/x86/tuxedo/nb02/Kbuild     |  7 ++
 drivers/platform/x86/tuxedo/nb02/Kconfig    | 15 ++++
 drivers/platform/x86/tuxedo/nb02/platform.c | 94 +++++++++++++++++++++
 8 files changed, 139 insertions(+)
 create mode 100644 drivers/platform/x86/tuxedo/Kbuild
 create mode 100644 drivers/platform/x86/tuxedo/Kconfig
 create mode 100644 drivers/platform/x86/tuxedo/nb02/Kbuild
 create mode 100644 drivers/platform/x86/tuxedo/nb02/Kconfig
 create mode 100644 drivers/platform/x86/tuxedo/nb02/platform.c

Comments

Mario Limonciello March 4, 2025, 6:53 p.m. UTC | #1
On 3/3/2025 13:04, Werner Sembach wrote:
> This small driver does 2 things:
> 
> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
> F21 to conform with established userspace defaults. Note that the
> Hangaku/Zenkaku scancode used here is usually unused, with real
> Hangaku/Zenkaku keys using the tilde scancode.
> 
> It suppresses the reserved scancode produced by pressing the FN-key on its
> own, which fixes a warning spamming the dmesg log otherwise.
> 
> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
> ---
>   MAINTAINERS                                 |  6 ++
>   drivers/platform/x86/Kconfig                |  2 +
>   drivers/platform/x86/Makefile               |  3 +
>   drivers/platform/x86/tuxedo/Kbuild          |  6 ++
>   drivers/platform/x86/tuxedo/Kconfig         |  6 ++
>   drivers/platform/x86/tuxedo/nb02/Kbuild     |  7 ++
>   drivers/platform/x86/tuxedo/nb02/Kconfig    | 15 ++++
>   drivers/platform/x86/tuxedo/nb02/platform.c | 94 +++++++++++++++++++++
>   8 files changed, 139 insertions(+)
>   create mode 100644 drivers/platform/x86/tuxedo/Kbuild
>   create mode 100644 drivers/platform/x86/tuxedo/Kconfig
>   create mode 100644 drivers/platform/x86/tuxedo/nb02/Kbuild
>   create mode 100644 drivers/platform/x86/tuxedo/nb02/Kconfig
>   create mode 100644 drivers/platform/x86/tuxedo/nb02/platform.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4ff26fa94895d..d3fbbcef813b0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -24178,6 +24178,12 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git turbostat
>   F:	tools/power/x86/turbostat/
>   F:	tools/testing/selftests/turbostat/
>   
> +TUXEDO DRIVERS
> +M:	Werner Sembach <wse@tuxedocomputers.com>
> +L:	platform-driver-x86@vger.kernel.org
> +S:	Supported
> +F:	drivers/platform/x86/tuxedo/
> +
>   TW5864 VIDEO4LINUX DRIVER
>   M:	Bluecherry Maintainers <maintainers@bluecherrydvr.com>
>   M:	Andrey Utkin <andrey.utkin@corp.bluecherry.net>
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index 0258dd879d64b..9b78a1255c08e 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -1199,3 +1199,5 @@ config P2SB
>   	  The main purpose of this library is to unhide P2SB device in case
>   	  firmware kept it hidden on some platforms in order to access devices
>   	  behind it.
> +
> +source "drivers/platform/x86/tuxedo/Kconfig"
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index e1b1429470674..1562dcd7ad9a5 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -153,3 +153,6 @@ obj-$(CONFIG_WINMATE_FM07_KEYS)		+= winmate-fm07-keys.o
>   
>   # SEL
>   obj-$(CONFIG_SEL3350_PLATFORM)		+= sel3350-platform.o
> +
> +# TUXEDO
> +obj-y					+= tuxedo/
> diff --git a/drivers/platform/x86/tuxedo/Kbuild b/drivers/platform/x86/tuxedo/Kbuild
> new file mode 100644
> index 0000000000000..e9c4243d438ba
> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/Kbuild
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# TUXEDO X86 Platform Specific Drivers
> +#
> +
> +obj-y	+= nb02/
> diff --git a/drivers/platform/x86/tuxedo/Kconfig b/drivers/platform/x86/tuxedo/Kconfig
> new file mode 100644
> index 0000000000000..e463f92135780
> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/Kconfig
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# TUXEDO X86 Platform Specific Drivers
> +#
> +
> +source "drivers/platform/x86/tuxedo/nb02/Kconfig"
> diff --git a/drivers/platform/x86/tuxedo/nb02/Kbuild b/drivers/platform/x86/tuxedo/nb02/Kbuild
> new file mode 100644
> index 0000000000000..8624a012cd683

For a brand new directory isn't this structure a bit heavy handed for a 
single source file?

Or are you envisioning a lot more coming to this structure and just want 
to be ready?

Why not just d/p/x86/tuxedo?

And within there you can have exactly 3 files: nb02.c, Kconfig and Kbuild.

> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/nb02/Kbuild
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# TUXEDO X86 Platform Specific Drivers
> +#
> +
> +tuxedo_nb02_platform-y			:= platform.o
> +obj-$(CONFIG_TUXEDO_NB02_PLATFORM)	+= tuxedo_nb02_platform.o
> diff --git a/drivers/platform/x86/tuxedo/nb02/Kconfig b/drivers/platform/x86/tuxedo/nb02/Kconfig
> new file mode 100644
> index 0000000000000..bed56276b9b36
> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/nb02/Kconfig
> @@ -0,0 +1,15 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# TUXEDO X86 Platform Specific Drivers
> +#
> +
> +menuconfig TUXEDO_NB02_PLATFORM
> +	tristate "TUXEDO NB02 Platform Driver"
> +	help
> +	  This driver implements miscellaneous things found on TUXEDO Notebooks
> +	  with board vendor NB02. For the time being this is only remapping the
> +	  touchpad toggle key to something supported by most Linux distros
> +	  out-of-the-box and suppressing an unsupported scancode from the
> +	  FN-key.
> +
> +	  When compiled as a module it will be called tuxedo_nb02_platform.
> diff --git a/drivers/platform/x86/tuxedo/nb02/platform.c b/drivers/platform/x86/tuxedo/nb02/platform.c
> new file mode 100644
> index 0000000000000..68d83b9b4c2f5
> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/nb02/platform.c
> @@ -0,0 +1,94 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2025 Werner Sembach wse@tuxedocomputers.com
> + */
> +
> +#include <linux/dmi.h>
> +#include <linux/i8042.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/serio.h>
> +
> +static u8 tux_nb02_touchp_toggle_seq[] = {
> +	0xe0, 0x5b, // Super down
> +	0x1d,       // Control down
> +	0x76,       // Zenkaku/Hankaku down
> +	0xf6,       // Zenkaku/Hankaku up
> +	0x9d,       // Control up
> +	0xe0, 0xdb  // Super up
> +};
> +
> +static bool tux_nb02_i8042_filter(unsigned char data,
> +				  unsigned char str,
> +				  struct serio *port,
> +				  __always_unused void *context)
> +{
> +	static u8 seq_pos;
> +
> +	if (unlikely(str & I8042_STR_AUXDATA))
> +		return false;
> +
> +	/* Replace touchpad toggle key sequence with a singular press of the
> +	 * F21-key.
> +	 */
> +	if (unlikely(data == tux_nb02_touchp_toggle_seq[seq_pos])) {
> +		++seq_pos;
> +		if (seq_pos == ARRAY_SIZE(tux_nb02_touchp_toggle_seq)) {
> +			seq_pos = 0;
> +			serio_interrupt(port, 0x6c, 0); // F21 down
> +			serio_interrupt(port, 0xec, 0); // F21 up
> +		}
> +		return true;
> +	}
> +
> +	/* Ignore bogus scancode produced by the FN-key. Reuse seq_pos as first
> +	 * byte of that is just the "extended"-byte.
> +	 */
> +	if (unlikely(seq_pos == 1 && (data == 0x78 || data == 0xf8))) {
> +		seq_pos = 0;
> +		return true;
> +	}
> +
> +	/* Replay skipped sequence bytes if it did not finish and it was not a
> +	 * FN-key press.
> +	 */
> +	if (unlikely(seq_pos)) {
> +		for (u8 i; i < seq_pos; ++i)
> +			serio_interrupt(port, tux_nb02_touchp_toggle_seq[i], 0);
> +		seq_pos = 0;
> +	}
> +
> +	return false;
> +}
> +
> +static const struct dmi_system_id tux_nb02_dmi_string_match[] __initconst = {
> +	{
> +		.matches = {
> +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
> +			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "NB02"),
> +		},
> +	},
> +	{ }
> +};
> +
> +static int __init tux_nb02_plat_init(void)
> +{
> +	if (!dmi_check_system(tux_nb02_dmi_string_match))
> +		return -ENODEV;
> +
> +	return i8042_install_filter(tux_nb02_i8042_filter, NULL);
> +}
> +
> +static void __exit tux_nb02_plat_exit(void)
> +{
> +	i8042_remove_filter(tux_nb02_i8042_filter);
> +}
> +
> +module_init(tux_nb02_plat_init);
> +module_exit(tux_nb02_plat_exit);
> +
> +MODULE_ALIAS("dmi:*:svnTUXEDO:*:rvnNB02:*");
> +
> +MODULE_DESCRIPTION("TUXEDO NB02 Platform");
> +MODULE_AUTHOR("Werner Sembach <wse@tuxedocomputers.com>");
> +MODULE_LICENSE("GPL");
Werner Sembach March 4, 2025, 8:11 p.m. UTC | #2
Am 04.03.25 um 19:53 schrieb Mario Limonciello:
> On 3/3/2025 13:04, Werner Sembach wrote:
>> This small driver does 2 things:
>>
>> It remaps the touchpad toggle key from Control + Super + 
>> Hangaku/Zenkaku to
>> F21 to conform with established userspace defaults. Note that the
>> Hangaku/Zenkaku scancode used here is usually unused, with real
>> Hangaku/Zenkaku keys using the tilde scancode.
>>
>> It suppresses the reserved scancode produced by pressing the FN-key 
>> on its
>> own, which fixes a warning spamming the dmesg log otherwise.
>>
>> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
>> ---
>>   MAINTAINERS                                 |  6 ++
>>   drivers/platform/x86/Kconfig                |  2 +
>>   drivers/platform/x86/Makefile               |  3 +
>>   drivers/platform/x86/tuxedo/Kbuild          |  6 ++
>>   drivers/platform/x86/tuxedo/Kconfig         |  6 ++
>>   drivers/platform/x86/tuxedo/nb02/Kbuild     |  7 ++
>>   drivers/platform/x86/tuxedo/nb02/Kconfig    | 15 ++++
>>   drivers/platform/x86/tuxedo/nb02/platform.c | 94 +++++++++++++++++++++
>>   8 files changed, 139 insertions(+)
>>   create mode 100644 drivers/platform/x86/tuxedo/Kbuild
>>   create mode 100644 drivers/platform/x86/tuxedo/Kconfig
>>   create mode 100644 drivers/platform/x86/tuxedo/nb02/Kbuild
>>   create mode 100644 drivers/platform/x86/tuxedo/nb02/Kconfig
>>   create mode 100644 drivers/platform/x86/tuxedo/nb02/platform.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 4ff26fa94895d..d3fbbcef813b0 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -24178,6 +24178,12 @@ T:    git 
>> git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git turbostat
>>   F:    tools/power/x86/turbostat/
>>   F:    tools/testing/selftests/turbostat/
>>   +TUXEDO DRIVERS
>> +M:    Werner Sembach <wse@tuxedocomputers.com>
>> +L:    platform-driver-x86@vger.kernel.org
>> +S:    Supported
>> +F:    drivers/platform/x86/tuxedo/
>> +
>>   TW5864 VIDEO4LINUX DRIVER
>>   M:    Bluecherry Maintainers <maintainers@bluecherrydvr.com>
>>   M:    Andrey Utkin <andrey.utkin@corp.bluecherry.net>
>> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
>> index 0258dd879d64b..9b78a1255c08e 100644
>> --- a/drivers/platform/x86/Kconfig
>> +++ b/drivers/platform/x86/Kconfig
>> @@ -1199,3 +1199,5 @@ config P2SB
>>         The main purpose of this library is to unhide P2SB device in 
>> case
>>         firmware kept it hidden on some platforms in order to access 
>> devices
>>         behind it.
>> +
>> +source "drivers/platform/x86/tuxedo/Kconfig"
>> diff --git a/drivers/platform/x86/Makefile 
>> b/drivers/platform/x86/Makefile
>> index e1b1429470674..1562dcd7ad9a5 100644
>> --- a/drivers/platform/x86/Makefile
>> +++ b/drivers/platform/x86/Makefile
>> @@ -153,3 +153,6 @@ obj-$(CONFIG_WINMATE_FM07_KEYS)        += 
>> winmate-fm07-keys.o
>>     # SEL
>>   obj-$(CONFIG_SEL3350_PLATFORM)        += sel3350-platform.o
>> +
>> +# TUXEDO
>> +obj-y                    += tuxedo/
>> diff --git a/drivers/platform/x86/tuxedo/Kbuild 
>> b/drivers/platform/x86/tuxedo/Kbuild
>> new file mode 100644
>> index 0000000000000..e9c4243d438ba
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/Kbuild
>> @@ -0,0 +1,6 @@
>> +# SPDX-License-Identifier: GPL-2.0-or-later
>> +#
>> +# TUXEDO X86 Platform Specific Drivers
>> +#
>> +
>> +obj-y    += nb02/
>> diff --git a/drivers/platform/x86/tuxedo/Kconfig 
>> b/drivers/platform/x86/tuxedo/Kconfig
>> new file mode 100644
>> index 0000000000000..e463f92135780
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/Kconfig
>> @@ -0,0 +1,6 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +#
>> +# TUXEDO X86 Platform Specific Drivers
>> +#
>> +
>> +source "drivers/platform/x86/tuxedo/nb02/Kconfig"
>> diff --git a/drivers/platform/x86/tuxedo/nb02/Kbuild 
>> b/drivers/platform/x86/tuxedo/nb02/Kbuild
>> new file mode 100644
>> index 0000000000000..8624a012cd683
>
> For a brand new directory isn't this structure a bit heavy handed for 
> a single source file?
>
> Or are you envisioning a lot more coming to this structure and just 
> want to be ready?

Exactly.

A rewrite and upstream of all of this is (eventually) planned: 
https://gitlab.com/tuxedocomputers/development/packages/tuxedo-drivers/-/tree/67b781fbe0498fa6acba5b926d0083e00c287011/src

And already in progress: 
https://lore.kernel.org/all/20250121225510.751444-1-wse@tuxedocomputers.com/ 
and 
https://lore.kernel.org/all/20250205162109.222619-1-wse@tuxedocomputers.com/

The folder structure I envision is:

tuxedo/
     nb01/
     nb02/
     nb04/
     nb05/
     nbxx/

NB03 doesn't exist as a DMI board_vendor string on TUXEDO devices for 
historic reasons.

The different firmwares of the different board_vendor devices have very 
little in common and so do their drivers.

nbxx is for the TUXI driver, an ACPI interface we plan on eventually 
getting on more firmwares (currently only on the nb04 devices).

For nb02 there is also a WMI interface to control fans and NVIDIA cTGP 
and stuff that I plan to implement in a separate driver, that would go 
in the same folder.

>
> Why not just d/p/x86/tuxedo?
>
> And within there you can have exactly 3 files: nb02.c, Kconfig and 
> Kbuild.
>
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/nb02/Kbuild
>> @@ -0,0 +1,7 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +#
>> +# TUXEDO X86 Platform Specific Drivers
>> +#
>> +
>> +tuxedo_nb02_platform-y            := platform.o
>> +obj-$(CONFIG_TUXEDO_NB02_PLATFORM)    += tuxedo_nb02_platform.o
>> diff --git a/drivers/platform/x86/tuxedo/nb02/Kconfig 
>> b/drivers/platform/x86/tuxedo/nb02/Kconfig
>> new file mode 100644
>> index 0000000000000..bed56276b9b36
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/nb02/Kconfig
>> @@ -0,0 +1,15 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +#
>> +# TUXEDO X86 Platform Specific Drivers
>> +#
>> +
>> +menuconfig TUXEDO_NB02_PLATFORM
>> +    tristate "TUXEDO NB02 Platform Driver"
>> +    help
>> +      This driver implements miscellaneous things found on TUXEDO 
>> Notebooks
>> +      with board vendor NB02. For the time being this is only 
>> remapping the
>> +      touchpad toggle key to something supported by most Linux distros
>> +      out-of-the-box and suppressing an unsupported scancode from the
>> +      FN-key.
>> +
>> +      When compiled as a module it will be called tuxedo_nb02_platform.
>> diff --git a/drivers/platform/x86/tuxedo/nb02/platform.c 
>> b/drivers/platform/x86/tuxedo/nb02/platform.c
>> new file mode 100644
>> index 0000000000000..68d83b9b4c2f5
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/nb02/platform.c
>> @@ -0,0 +1,94 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (C) 2025 Werner Sembach wse@tuxedocomputers.com
>> + */
>> +
>> +#include <linux/dmi.h>
>> +#include <linux/i8042.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/serio.h>
>> +
>> +static u8 tux_nb02_touchp_toggle_seq[] = {
>> +    0xe0, 0x5b, // Super down
>> +    0x1d,       // Control down
>> +    0x76,       // Zenkaku/Hankaku down
>> +    0xf6,       // Zenkaku/Hankaku up
>> +    0x9d,       // Control up
>> +    0xe0, 0xdb  // Super up
>> +};
>> +
>> +static bool tux_nb02_i8042_filter(unsigned char data,
>> +                  unsigned char str,
>> +                  struct serio *port,
>> +                  __always_unused void *context)
>> +{
>> +    static u8 seq_pos;
>> +
>> +    if (unlikely(str & I8042_STR_AUXDATA))
>> +        return false;
>> +
>> +    /* Replace touchpad toggle key sequence with a singular press of 
>> the
>> +     * F21-key.
>> +     */
>> +    if (unlikely(data == tux_nb02_touchp_toggle_seq[seq_pos])) {
>> +        ++seq_pos;
>> +        if (seq_pos == ARRAY_SIZE(tux_nb02_touchp_toggle_seq)) {
>> +            seq_pos = 0;
>> +            serio_interrupt(port, 0x6c, 0); // F21 down
>> +            serio_interrupt(port, 0xec, 0); // F21 up
>> +        }
>> +        return true;
>> +    }
>> +
>> +    /* Ignore bogus scancode produced by the FN-key. Reuse seq_pos 
>> as first
>> +     * byte of that is just the "extended"-byte.
>> +     */
>> +    if (unlikely(seq_pos == 1 && (data == 0x78 || data == 0xf8))) {
>> +        seq_pos = 0;
>> +        return true;
>> +    }
>> +
>> +    /* Replay skipped sequence bytes if it did not finish and it was 
>> not a
>> +     * FN-key press.
>> +     */
>> +    if (unlikely(seq_pos)) {
>> +        for (u8 i; i < seq_pos; ++i)
>> +            serio_interrupt(port, tux_nb02_touchp_toggle_seq[i], 0);
>> +        seq_pos = 0;
>> +    }
>> +
>> +    return false;
>> +}
>> +
>> +static const struct dmi_system_id tux_nb02_dmi_string_match[] 
>> __initconst = {
>> +    {
>> +        .matches = {
>> +            DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
>> +            DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "NB02"),
>> +        },
>> +    },
>> +    { }
>> +};
>> +
>> +static int __init tux_nb02_plat_init(void)
>> +{
>> +    if (!dmi_check_system(tux_nb02_dmi_string_match))
>> +        return -ENODEV;
>> +
>> +    return i8042_install_filter(tux_nb02_i8042_filter, NULL);
>> +}
>> +
>> +static void __exit tux_nb02_plat_exit(void)
>> +{
>> +    i8042_remove_filter(tux_nb02_i8042_filter);
>> +}
>> +
>> +module_init(tux_nb02_plat_init);
>> +module_exit(tux_nb02_plat_exit);
>> +
>> +MODULE_ALIAS("dmi:*:svnTUXEDO:*:rvnNB02:*");
>> +
>> +MODULE_DESCRIPTION("TUXEDO NB02 Platform");
>> +MODULE_AUTHOR("Werner Sembach <wse@tuxedocomputers.com>");
>> +MODULE_LICENSE("GPL");
>
Armin Wolf March 5, 2025, 1:01 a.m. UTC | #3
Am 03.03.25 um 20:04 schrieb Werner Sembach:

> This small driver does 2 things:
>
> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
> F21 to conform with established userspace defaults. Note that the
> Hangaku/Zenkaku scancode used here is usually unused, with real
> Hangaku/Zenkaku keys using the tilde scancode.
>
> It suppresses the reserved scancode produced by pressing the FN-key on its
> own, which fixes a warning spamming the dmesg log otherwise.
>
> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
> ---
>   MAINTAINERS                                 |  6 ++
>   drivers/platform/x86/Kconfig                |  2 +
>   drivers/platform/x86/Makefile               |  3 +
>   drivers/platform/x86/tuxedo/Kbuild          |  6 ++
>   drivers/platform/x86/tuxedo/Kconfig         |  6 ++
>   drivers/platform/x86/tuxedo/nb02/Kbuild     |  7 ++
>   drivers/platform/x86/tuxedo/nb02/Kconfig    | 15 ++++
>   drivers/platform/x86/tuxedo/nb02/platform.c | 94 +++++++++++++++++++++
>   8 files changed, 139 insertions(+)
>   create mode 100644 drivers/platform/x86/tuxedo/Kbuild
>   create mode 100644 drivers/platform/x86/tuxedo/Kconfig
>   create mode 100644 drivers/platform/x86/tuxedo/nb02/Kbuild
>   create mode 100644 drivers/platform/x86/tuxedo/nb02/Kconfig
>   create mode 100644 drivers/platform/x86/tuxedo/nb02/platform.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4ff26fa94895d..d3fbbcef813b0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -24178,6 +24178,12 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git turbostat
>   F:	tools/power/x86/turbostat/
>   F:	tools/testing/selftests/turbostat/
>
> +TUXEDO DRIVERS
> +M:	Werner Sembach <wse@tuxedocomputers.com>
> +L:	platform-driver-x86@vger.kernel.org
> +S:	Supported
> +F:	drivers/platform/x86/tuxedo/
> +
>   TW5864 VIDEO4LINUX DRIVER
>   M:	Bluecherry Maintainers <maintainers@bluecherrydvr.com>
>   M:	Andrey Utkin <andrey.utkin@corp.bluecherry.net>
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index 0258dd879d64b..9b78a1255c08e 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -1199,3 +1199,5 @@ config P2SB
>   	  The main purpose of this library is to unhide P2SB device in case
>   	  firmware kept it hidden on some platforms in order to access devices
>   	  behind it.
> +
> +source "drivers/platform/x86/tuxedo/Kconfig"
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index e1b1429470674..1562dcd7ad9a5 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -153,3 +153,6 @@ obj-$(CONFIG_WINMATE_FM07_KEYS)		+= winmate-fm07-keys.o
>
>   # SEL
>   obj-$(CONFIG_SEL3350_PLATFORM)		+= sel3350-platform.o
> +
> +# TUXEDO
> +obj-y					+= tuxedo/
> diff --git a/drivers/platform/x86/tuxedo/Kbuild b/drivers/platform/x86/tuxedo/Kbuild
> new file mode 100644
> index 0000000000000..e9c4243d438ba
> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/Kbuild
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# TUXEDO X86 Platform Specific Drivers
> +#
> +
> +obj-y	+= nb02/
> diff --git a/drivers/platform/x86/tuxedo/Kconfig b/drivers/platform/x86/tuxedo/Kconfig
> new file mode 100644
> index 0000000000000..e463f92135780
> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/Kconfig
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# TUXEDO X86 Platform Specific Drivers
> +#
> +
> +source "drivers/platform/x86/tuxedo/nb02/Kconfig"
> diff --git a/drivers/platform/x86/tuxedo/nb02/Kbuild b/drivers/platform/x86/tuxedo/nb02/Kbuild
> new file mode 100644
> index 0000000000000..8624a012cd683
> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/nb02/Kbuild
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# TUXEDO X86 Platform Specific Drivers
> +#
> +
> +tuxedo_nb02_platform-y			:= platform.o
> +obj-$(CONFIG_TUXEDO_NB02_PLATFORM)	+= tuxedo_nb02_platform.o
> diff --git a/drivers/platform/x86/tuxedo/nb02/Kconfig b/drivers/platform/x86/tuxedo/nb02/Kconfig
> new file mode 100644
> index 0000000000000..bed56276b9b36
> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/nb02/Kconfig
> @@ -0,0 +1,15 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# TUXEDO X86 Platform Specific Drivers
> +#
> +
> +menuconfig TUXEDO_NB02_PLATFORM
> +	tristate "TUXEDO NB02 Platform Driver"
> +	help
> +	  This driver implements miscellaneous things found on TUXEDO Notebooks
> +	  with board vendor NB02. For the time being this is only remapping the
> +	  touchpad toggle key to something supported by most Linux distros
> +	  out-of-the-box and suppressing an unsupported scancode from the
> +	  FN-key.
> +
> +	  When compiled as a module it will be called tuxedo_nb02_platform.
> diff --git a/drivers/platform/x86/tuxedo/nb02/platform.c b/drivers/platform/x86/tuxedo/nb02/platform.c
> new file mode 100644
> index 0000000000000..68d83b9b4c2f5
> --- /dev/null
> +++ b/drivers/platform/x86/tuxedo/nb02/platform.c
> @@ -0,0 +1,94 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2025 Werner Sembach wse@tuxedocomputers.com
> + */
> +
> +#include <linux/dmi.h>
> +#include <linux/i8042.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/serio.h>
> +
> +static u8 tux_nb02_touchp_toggle_seq[] = {

Hi,

please make this const.

> +	0xe0, 0x5b, // Super down
> +	0x1d,       // Control down
> +	0x76,       // Zenkaku/Hankaku down
> +	0xf6,       // Zenkaku/Hankaku up
> +	0x9d,       // Control up
> +	0xe0, 0xdb  // Super up
> +};
> +
> +static bool tux_nb02_i8042_filter(unsigned char data,
> +				  unsigned char str,
> +				  struct serio *port,
> +				  __always_unused void *context)
> +{
> +	static u8 seq_pos;
> +
> +	if (unlikely(str & I8042_STR_AUXDATA))
> +		return false;
> +
> +	/* Replace touchpad toggle key sequence with a singular press of the
> +	 * F21-key.
> +	 */
> +	if (unlikely(data == tux_nb02_touchp_toggle_seq[seq_pos])) {
> +		++seq_pos;
> +		if (seq_pos == ARRAY_SIZE(tux_nb02_touchp_toggle_seq)) {
> +			seq_pos = 0;
> +			serio_interrupt(port, 0x6c, 0); // F21 down
> +			serio_interrupt(port, 0xec, 0); // F21 up
> +		}
> +		return true;
> +	}
> +
> +	/* Ignore bogus scancode produced by the FN-key. Reuse seq_pos as first
> +	 * byte of that is just the "extended"-byte.
> +	 */
> +	if (unlikely(seq_pos == 1 && (data == 0x78 || data == 0xf8))) {
> +		seq_pos = 0;
> +		return true;
> +	}
> +
> +	/* Replay skipped sequence bytes if it did not finish and it was not a
> +	 * FN-key press.
> +	 */
> +	if (unlikely(seq_pos)) {
> +		for (u8 i; i < seq_pos; ++i)
> +			serio_interrupt(port, tux_nb02_touchp_toggle_seq[i], 0);
> +		seq_pos = 0;
> +	}
> +
> +	return false;
> +}
> +
> +static const struct dmi_system_id tux_nb02_dmi_string_match[] __initconst = {
> +	{
> +		.matches = {
> +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
> +			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "NB02"),
> +		},
> +	},
> +	{ }
> +};
> +
> +static int __init tux_nb02_plat_init(void)
> +{
> +	if (!dmi_check_system(tux_nb02_dmi_string_match))
> +		return -ENODEV;
> +
> +	return i8042_install_filter(tux_nb02_i8042_filter, NULL);
> +}
> +
> +static void __exit tux_nb02_plat_exit(void)
> +{
> +	i8042_remove_filter(tux_nb02_i8042_filter);
> +}
> +
> +module_init(tux_nb02_plat_init);
> +module_exit(tux_nb02_plat_exit);
> +
> +MODULE_ALIAS("dmi:*:svnTUXEDO:*:rvnNB02:*");

Please use MODULE_DEVICE_TABLE(dmi, tux_nb02_dmi_string_match) instead.

Otherwise the driver seems to be OK to me.

Thanks,
Armin Wolf

> +
> +MODULE_DESCRIPTION("TUXEDO NB02 Platform");
> +MODULE_AUTHOR("Werner Sembach <wse@tuxedocomputers.com>");
> +MODULE_LICENSE("GPL");
Hans de Goede March 5, 2025, 11:25 a.m. UTC | #4
Hi Werner,

On 3-Mar-25 8:04 PM, Werner Sembach wrote:
> This small driver does 2 things:
> 
> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
> F21 to conform with established userspace defaults. Note that the
> Hangaku/Zenkaku scancode used here is usually unused, with real
> Hangaku/Zenkaku keys using the tilde scancode.

So this control + super + scancode 0x76 sending is also seen on
quite a few other laptops and I think we need a generic fix for this.

I recently noticed that KDE's keyboard-shortcut settings actually has
a  control + super + Hangaku/Zenkaku -> touchpad-toggle key binding
in its default bindings (IIRC). But that cannot work because xkb actually
has no mapping for evdev code 85 / KEY_ZENKAKUHANKAKU if you look in:

/usr/share/X11/xkb/keycodes/evdev and then look for 93 (*) you will
find no mapping. I think this KDE default binding may be from a long
time ago when this did work. Or maybe KDE uses the FOO part of KEY_FOO
as symbolic when there is no xkb mapping ?

*) 85 + 8 all codes there are shifted up 8 compared to the KEY_FOO
defines because codes 0-7 are reserved for modifier.

I hit the same issue years ago on "T-boa Tbook air" laptop and
their I fixed this by mapping Hangaku/Zenkaku -> f21 in
/lib/udev/hwdb.d/60-keyboard.hwdb :

###########################################################
# T-bao
###########################################################

evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:*
 KEYBOARD_KEY_76=f21                                    # Touchpad toggle

+ teaching GNOME to also accept Ctrl + Super + XF86TouchpadToggle
as touchpad-toggle:

https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/blob/master/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in?ref_type=heads#L577

Notice that system76 has the same hwdb key mapping for their
Pangolin 12 model which I presume also has something like e.g.
a clevo as base model.

So for now to fix the touchpad on this TUXEDO NB02 you should
simply add a hwdb entry like the above entries.

Longer term I think the right fix for the touchpad toggle for
all laptops which do this would be to make GNOME do what KDE does
and change the touchpad-toggle-static keybinding list which
currently is:

['XF86TouchpadToggle', '<Ctrl><Super>XF86TouchpadToggle']

to:

['XF86TouchpadToggle', '<Ctrl><Super>XF86TouchpadToggle', '<Ctrl><Super>"Something"']

Where "Something" would then be the new mapping. Or maybe just teach
atkbd or xkb or hwdb to map scancode 0x76 to TouchpadToggle by
default then at least in GNOME this will work OOTB and for KDE
a default binding of '<Ctrl><Super>XF86TouchpadToggle'] -> touchpad-toggle
should probably be added there.

> It suppresses the reserved scancode produced by pressing the FN-key on its
> own, which fixes a warning spamming the dmesg log otherwise.

Can you not also suppress this by mapping the key to "unknown" in hwdb?

Regards,

Hans
Werner Sembach March 5, 2025, 12:07 p.m. UTC | #5
Am 05.03.25 um 12:25 schrieb Hans de Goede:
> Hi Werner,
>
> On 3-Mar-25 8:04 PM, Werner Sembach wrote:
>> This small driver does 2 things:
>>
>> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
>> F21 to conform with established userspace defaults. Note that the
>> Hangaku/Zenkaku scancode used here is usually unused, with real
>> Hangaku/Zenkaku keys using the tilde scancode.
> So this control + super + scancode 0x76 sending is also seen on
> quite a few other laptops and I think we need a generic fix for this.
>
> I recently noticed that KDE's keyboard-shortcut settings actually has
> a  control + super + Hangaku/Zenkaku -> touchpad-toggle key binding
> in its default bindings (IIRC). But that cannot work because xkb actually
> has no mapping for evdev code 85 / KEY_ZENKAKUHANKAKU if you look in:
>
> /usr/share/X11/xkb/keycodes/evdev and then look for 93 (*) you will
> find no mapping. I think this KDE default binding may be from a long
> time ago when this did work. Or maybe KDE uses the FOO part of KEY_FOO
> as symbolic when there is no xkb mapping ?

It does not work on X11, but it does work on Wayland (there xev also sees the 
Zenkaku/Hankaku keypress). Don't ask me why.

Also: Other DEs don't have this binding.

>
> *) 85 + 8 all codes there are shifted up 8 compared to the KEY_FOO
> defines because codes 0-7 are reserved for modifier.
>
> I hit the same issue years ago on "T-boa Tbook air" laptop and
> their I fixed this by mapping Hangaku/Zenkaku -> f21 in
> /lib/udev/hwdb.d/60-keyboard.hwdb :
>
> ###########################################################
> # T-bao
> ###########################################################
>
> evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:*
>   KEYBOARD_KEY_76=f21                                    # Touchpad toggle
>
> + teaching GNOME to also accept Ctrl + Super + XF86TouchpadToggle
> as touchpad-toggle:
>
> https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/blob/master/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in?ref_type=heads#L577

Yeah KDE would need a similar fix and other DEs probably too. I hoped for a 
generic fix that does not need adjustments in so many projects.

My first try was to do it on the XKB level but on Wayland the RedirectKey action 
is not implemented 
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/794#note_2803713 
(and probably wont be even in the future 
https://github.com/xkbcommon/libxkbcommon/issues/18#issuecomment-72728366) so I 
can't "unpress" control and super.

If it is a more general issue, why not fix it on a more general level in the 
kernel? Maybe a generic filter applyable via a command line quirk and/or a quirk 
list?

>
> Notice that system76 has the same hwdb key mapping for their
> Pangolin 12 model which I presume also has something like e.g.
> a clevo as base model.
>
> So for now to fix the touchpad on this TUXEDO NB02 you should
> simply add a hwdb entry like the above entries.
>
> Longer term I think the right fix for the touchpad toggle for
> all laptops which do this would be to make GNOME do what KDE does
> and change the touchpad-toggle-static keybinding list which
> currently is:
>
> ['XF86TouchpadToggle', '<Ctrl><Super>XF86TouchpadToggle']
>
> to:
>
> ['XF86TouchpadToggle', '<Ctrl><Super>XF86TouchpadToggle', '<Ctrl><Super>"Something"']
>
> Where "Something" would then be the new mapping. Or maybe just teach
> atkbd or xkb or hwdb to map scancode 0x76 to TouchpadToggle by
> default then at least in GNOME this will work OOTB and for KDE
> a default binding of '<Ctrl><Super>XF86TouchpadToggle'] -> touchpad-toggle
> should probably be added there.
>
>> It suppresses the reserved scancode produced by pressing the FN-key on its
>> own, which fixes a warning spamming the dmesg log otherwise.
> Can you not also suppress this by mapping the key to "unknown" in hwdb?
Maybe, I didn't try. Was convenient to just do it here since I already had the 
filter. Will look into it once it is decided what to do with the touchpad toggle 
issue.
>
> Regards,
>
> Hans
>
>
Werner Sembach March 5, 2025, 12:07 p.m. UTC | #6
Am 05.03.25 um 02:01 schrieb Armin Wolf:
> Am 03.03.25 um 20:04 schrieb Werner Sembach:
>
>> This small driver does 2 things:
>>
>> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
>> F21 to conform with established userspace defaults. Note that the
>> Hangaku/Zenkaku scancode used here is usually unused, with real
>> Hangaku/Zenkaku keys using the tilde scancode.
>>
>> It suppresses the reserved scancode produced by pressing the FN-key on its
>> own, which fixes a warning spamming the dmesg log otherwise.
>>
>> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
>> ---
>>   MAINTAINERS                                 |  6 ++
>>   drivers/platform/x86/Kconfig                |  2 +
>>   drivers/platform/x86/Makefile               |  3 +
>>   drivers/platform/x86/tuxedo/Kbuild          |  6 ++
>>   drivers/platform/x86/tuxedo/Kconfig         |  6 ++
>>   drivers/platform/x86/tuxedo/nb02/Kbuild     |  7 ++
>>   drivers/platform/x86/tuxedo/nb02/Kconfig    | 15 ++++
>>   drivers/platform/x86/tuxedo/nb02/platform.c | 94 +++++++++++++++++++++
>>   8 files changed, 139 insertions(+)
>>   create mode 100644 drivers/platform/x86/tuxedo/Kbuild
>>   create mode 100644 drivers/platform/x86/tuxedo/Kconfig
>>   create mode 100644 drivers/platform/x86/tuxedo/nb02/Kbuild
>>   create mode 100644 drivers/platform/x86/tuxedo/nb02/Kconfig
>>   create mode 100644 drivers/platform/x86/tuxedo/nb02/platform.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 4ff26fa94895d..d3fbbcef813b0 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -24178,6 +24178,12 @@ T:    git 
>> git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git turbostat
>>   F:    tools/power/x86/turbostat/
>>   F:    tools/testing/selftests/turbostat/
>>
>> +TUXEDO DRIVERS
>> +M:    Werner Sembach <wse@tuxedocomputers.com>
>> +L:    platform-driver-x86@vger.kernel.org
>> +S:    Supported
>> +F:    drivers/platform/x86/tuxedo/
>> +
>>   TW5864 VIDEO4LINUX DRIVER
>>   M:    Bluecherry Maintainers <maintainers@bluecherrydvr.com>
>>   M:    Andrey Utkin <andrey.utkin@corp.bluecherry.net>
>> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
>> index 0258dd879d64b..9b78a1255c08e 100644
>> --- a/drivers/platform/x86/Kconfig
>> +++ b/drivers/platform/x86/Kconfig
>> @@ -1199,3 +1199,5 @@ config P2SB
>>         The main purpose of this library is to unhide P2SB device in case
>>         firmware kept it hidden on some platforms in order to access devices
>>         behind it.
>> +
>> +source "drivers/platform/x86/tuxedo/Kconfig"
>> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
>> index e1b1429470674..1562dcd7ad9a5 100644
>> --- a/drivers/platform/x86/Makefile
>> +++ b/drivers/platform/x86/Makefile
>> @@ -153,3 +153,6 @@ obj-$(CONFIG_WINMATE_FM07_KEYS)        += 
>> winmate-fm07-keys.o
>>
>>   # SEL
>>   obj-$(CONFIG_SEL3350_PLATFORM)        += sel3350-platform.o
>> +
>> +# TUXEDO
>> +obj-y                    += tuxedo/
>> diff --git a/drivers/platform/x86/tuxedo/Kbuild 
>> b/drivers/platform/x86/tuxedo/Kbuild
>> new file mode 100644
>> index 0000000000000..e9c4243d438ba
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/Kbuild
>> @@ -0,0 +1,6 @@
>> +# SPDX-License-Identifier: GPL-2.0-or-later
>> +#
>> +# TUXEDO X86 Platform Specific Drivers
>> +#
>> +
>> +obj-y    += nb02/
>> diff --git a/drivers/platform/x86/tuxedo/Kconfig 
>> b/drivers/platform/x86/tuxedo/Kconfig
>> new file mode 100644
>> index 0000000000000..e463f92135780
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/Kconfig
>> @@ -0,0 +1,6 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +#
>> +# TUXEDO X86 Platform Specific Drivers
>> +#
>> +
>> +source "drivers/platform/x86/tuxedo/nb02/Kconfig"
>> diff --git a/drivers/platform/x86/tuxedo/nb02/Kbuild 
>> b/drivers/platform/x86/tuxedo/nb02/Kbuild
>> new file mode 100644
>> index 0000000000000..8624a012cd683
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/nb02/Kbuild
>> @@ -0,0 +1,7 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +#
>> +# TUXEDO X86 Platform Specific Drivers
>> +#
>> +
>> +tuxedo_nb02_platform-y            := platform.o
>> +obj-$(CONFIG_TUXEDO_NB02_PLATFORM)    += tuxedo_nb02_platform.o
>> diff --git a/drivers/platform/x86/tuxedo/nb02/Kconfig 
>> b/drivers/platform/x86/tuxedo/nb02/Kconfig
>> new file mode 100644
>> index 0000000000000..bed56276b9b36
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/nb02/Kconfig
>> @@ -0,0 +1,15 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +#
>> +# TUXEDO X86 Platform Specific Drivers
>> +#
>> +
>> +menuconfig TUXEDO_NB02_PLATFORM
>> +    tristate "TUXEDO NB02 Platform Driver"
>> +    help
>> +      This driver implements miscellaneous things found on TUXEDO Notebooks
>> +      with board vendor NB02. For the time being this is only remapping the
>> +      touchpad toggle key to something supported by most Linux distros
>> +      out-of-the-box and suppressing an unsupported scancode from the
>> +      FN-key.
>> +
>> +      When compiled as a module it will be called tuxedo_nb02_platform.
>> diff --git a/drivers/platform/x86/tuxedo/nb02/platform.c 
>> b/drivers/platform/x86/tuxedo/nb02/platform.c
>> new file mode 100644
>> index 0000000000000..68d83b9b4c2f5
>> --- /dev/null
>> +++ b/drivers/platform/x86/tuxedo/nb02/platform.c
>> @@ -0,0 +1,94 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (C) 2025 Werner Sembach wse@tuxedocomputers.com
>> + */
>> +
>> +#include <linux/dmi.h>
>> +#include <linux/i8042.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/serio.h>
>> +
>> +static u8 tux_nb02_touchp_toggle_seq[] = {
>
> Hi,
>
> please make this const.
kk
>
>> +    0xe0, 0x5b, // Super down
>> +    0x1d,       // Control down
>> +    0x76,       // Zenkaku/Hankaku down
>> +    0xf6,       // Zenkaku/Hankaku up
>> +    0x9d,       // Control up
>> +    0xe0, 0xdb  // Super up
>> +};
>> +
>> +static bool tux_nb02_i8042_filter(unsigned char data,
>> +                  unsigned char str,
>> +                  struct serio *port,
>> +                  __always_unused void *context)
>> +{
>> +    static u8 seq_pos;
>> +
>> +    if (unlikely(str & I8042_STR_AUXDATA))
>> +        return false;
>> +
>> +    /* Replace touchpad toggle key sequence with a singular press of the
>> +     * F21-key.
>> +     */
>> +    if (unlikely(data == tux_nb02_touchp_toggle_seq[seq_pos])) {
>> +        ++seq_pos;
>> +        if (seq_pos == ARRAY_SIZE(tux_nb02_touchp_toggle_seq)) {
>> +            seq_pos = 0;
>> +            serio_interrupt(port, 0x6c, 0); // F21 down
>> +            serio_interrupt(port, 0xec, 0); // F21 up
>> +        }
>> +        return true;
>> +    }
>> +
>> +    /* Ignore bogus scancode produced by the FN-key. Reuse seq_pos as first
>> +     * byte of that is just the "extended"-byte.
>> +     */
>> +    if (unlikely(seq_pos == 1 && (data == 0x78 || data == 0xf8))) {
>> +        seq_pos = 0;
>> +        return true;
>> +    }
>> +
>> +    /* Replay skipped sequence bytes if it did not finish and it was not a
>> +     * FN-key press.
>> +     */
>> +    if (unlikely(seq_pos)) {
>> +        for (u8 i; i < seq_pos; ++i)
>> +            serio_interrupt(port, tux_nb02_touchp_toggle_seq[i], 0);
>> +        seq_pos = 0;
>> +    }
>> +
>> +    return false;
>> +}
>> +
>> +static const struct dmi_system_id tux_nb02_dmi_string_match[] __initconst = {
>> +    {
>> +        .matches = {
>> +            DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
>> +            DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "NB02"),
>> +        },
>> +    },
>> +    { }
>> +};
>> +
>> +static int __init tux_nb02_plat_init(void)
>> +{
>> +    if (!dmi_check_system(tux_nb02_dmi_string_match))
>> +        return -ENODEV;
>> +
>> +    return i8042_install_filter(tux_nb02_i8042_filter, NULL);
>> +}
>> +
>> +static void __exit tux_nb02_plat_exit(void)
>> +{
>> +    i8042_remove_filter(tux_nb02_i8042_filter);
>> +}
>> +
>> +module_init(tux_nb02_plat_init);
>> +module_exit(tux_nb02_plat_exit);
>> +
>> +MODULE_ALIAS("dmi:*:svnTUXEDO:*:rvnNB02:*");
>
> Please use MODULE_DEVICE_TABLE(dmi, tux_nb02_dmi_string_match) instead.
kk
>
> Otherwise the driver seems to be OK to me.
>
> Thanks,
> Armin Wolf
>
>> +
>> +MODULE_DESCRIPTION("TUXEDO NB02 Platform");
>> +MODULE_AUTHOR("Werner Sembach <wse@tuxedocomputers.com>");
>> +MODULE_LICENSE("GPL");
Hans de Goede March 5, 2025, 2:18 p.m. UTC | #7
Hi Werner,

On 5-Mar-25 1:07 PM, Werner Sembach wrote:
> 
> Am 05.03.25 um 12:25 schrieb Hans de Goede:
>> Hi Werner,
>>
>> On 3-Mar-25 8:04 PM, Werner Sembach wrote:
>>> This small driver does 2 things:
>>>
>>> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
>>> F21 to conform with established userspace defaults. Note that the
>>> Hangaku/Zenkaku scancode used here is usually unused, with real
>>> Hangaku/Zenkaku keys using the tilde scancode.
>> So this control + super + scancode 0x76 sending is also seen on
>> quite a few other laptops and I think we need a generic fix for this.
>>
>> I recently noticed that KDE's keyboard-shortcut settings actually has
>> a  control + super + Hangaku/Zenkaku -> touchpad-toggle key binding
>> in its default bindings (IIRC). But that cannot work because xkb actually
>> has no mapping for evdev code 85 / KEY_ZENKAKUHANKAKU if you look in:
>>
>> /usr/share/X11/xkb/keycodes/evdev and then look for 93 (*) you will
>> find no mapping. I think this KDE default binding may be from a long
>> time ago when this did work. Or maybe KDE uses the FOO part of KEY_FOO
>> as symbolic when there is no xkb mapping ?
> 
> It does not work on X11, but it does work on Wayland (there xev also sees the Zenkaku/Hankaku keypress). Don't ask me why.

Interesting, so in xev under Wayland you see something like this
on release:

    state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,

With there actually being a keysym of "Zenkaku_Hankaku" there ?

Because that is not working on Wayland on my laptop with the same
issue (after disabling the hwdb mapping) and I don't understand
how that could work at all given that /usr/share/X11/xkb/keycodes/evdev
has no mapping for EV keycode 85 (93 in that file) ?

> Also: Other DEs don't have this binding.

Yes that is an issue, but see below.

>> *) 85 + 8 all codes there are shifted up 8 compared to the KEY_FOO
>> defines because codes 0-7 are reserved for modifier.
>>
>> I hit the same issue years ago on "T-boa Tbook air" laptop and
>> their I fixed this by mapping Hangaku/Zenkaku -> f21 in
>> /lib/udev/hwdb.d/60-keyboard.hwdb :
>>
>> ###########################################################
>> # T-bao
>> ###########################################################
>>
>> evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:*
>>   KEYBOARD_KEY_76=f21                                    # Touchpad toggle
>>
>> + teaching GNOME to also accept Ctrl + Super + XF86TouchpadToggle
>> as touchpad-toggle:
>>
>> https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/blob/master/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in?ref_type=heads#L577
> 
> Yeah KDE would need a similar fix and other DEs probably too. I hoped for a generic fix that does not need adjustments in so many projects.
> 
> My first try was to do it on the XKB level but on Wayland the RedirectKey action is not implemented https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/794#note_2803713 (and probably wont be even in the future https://github.com/xkbcommon/libxkbcommon/issues/18#issuecomment-72728366) so I can't "unpress" control and super.
> 
> If it is a more general issue, why not fix it on a more general level in the kernel? Maybe a generic filter applyable via a command line quirk and/or a quirk list?

The problem is that filtering keys with modifiers like you are doing
here just does not work.

Your filter is seriously messing with the timing of the keypresses
which can be a real issue when not actually using the toggle touchpad
hotkey.

Lets say the user is playing a game and has mapped super to
one of the fire buttons and is using an in game weapon with
some sort of auto-repeat firing.

And your seqpos variable likely is 0 when super gets pressed,
now the keyboard sends 0xe0, 0x5b which your filter filters
out, and the user keeps super pressed because they expect
the weapon to start firing on auto-repeat. But the super
press is never send until super is released or another key
is pressed so things don't work.

Likewise if the DE, an app or accessibility settings want to
differentiate between a short and a long super press all
presses now become super (pun not intended) short because
you insert the press directly in front of the release, losing
any timing information about how long the key was pressed.

This is why using an i8042 filter for filtering key-combinations
(and the EC emulates a key-combination here) can never work reliably.

OTOH desktop environments already allow having Ctrl+Super+something
keybindings for DE actions. So we can re-use the tried and trusted
modifier handling in the DE to deal with combi part leaving just
the issue of mapping PS/2 scancode 0x76 aka evdev code
85 / KEY_ZENKAKUHANKAKU to something usable by the DE.

ATM both GNOME and KDE already have support for
Ctrl+Super+something for touchpad-toggle except that KDE expects
a "Zenkaku_Hankaku" keysym where as GNOME expects "XF86TouchpadToggle"
arguably the GNOME solution is slightly better because Japanese
keyboard layouts already use/send the "Zenkaku_Hankaku" keysym
unrelated to touchpad-toggle use. And I don't know what happens
when pressing ctrl+super+Zenkaku_Hankaku while using a Japanese
layout.

I think maybe we just need to patch atkbd.c at the kernel to
map scancode 0x76 -> KEY_TOUCHPAD_TOGGLE since normal PS/2
keyboards never generate 0x76, this would lose the mapping to
KEY_ZENKAKUHANKAKU but since /usr/share/X11/xkb/keycodes/evdev
does not even map KEY_ZENKAKUHANKAKU I don't think loosing that
mapping will do a big deal.

So I think that going with the evdev mapping + teaching KDE
that Ctrl+Super+XF86TouchpadToggle is just XF86TouchpadToggle
is the best way forward to solve this once and for all.

>>> It suppresses the reserved scancode produced by pressing the FN-key on its
>>> own, which fixes a warning spamming the dmesg log otherwise.
>> Can you not also suppress this by mapping the key to "unknown" in hwdb?
> Maybe, I didn't try. Was convenient to just do it here since I already had the filter. Will look into it once it is decided what to do with the touchpad toggle issue.

Please give using hwdb for this a try.

Regards,

Hans
Werner Sembach March 5, 2025, 3:41 p.m. UTC | #8
Hi Hans,

Am 05.03.25 um 15:18 schrieb Hans de Goede:
> Hi Werner,
>
> On 5-Mar-25 1:07 PM, Werner Sembach wrote:
>> Am 05.03.25 um 12:25 schrieb Hans de Goede:
>>> Hi Werner,
>>>
>>> On 3-Mar-25 8:04 PM, Werner Sembach wrote:
>>>> This small driver does 2 things:
>>>>
>>>> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
>>>> F21 to conform with established userspace defaults. Note that the
>>>> Hangaku/Zenkaku scancode used here is usually unused, with real
>>>> Hangaku/Zenkaku keys using the tilde scancode.
>>> So this control + super + scancode 0x76 sending is also seen on
>>> quite a few other laptops and I think we need a generic fix for this.
>>>
>>> I recently noticed that KDE's keyboard-shortcut settings actually has
>>> a  control + super + Hangaku/Zenkaku -> touchpad-toggle key binding
>>> in its default bindings (IIRC). But that cannot work because xkb actually
>>> has no mapping for evdev code 85 / KEY_ZENKAKUHANKAKU if you look in:
>>>
>>> /usr/share/X11/xkb/keycodes/evdev and then look for 93 (*) you will
>>> find no mapping. I think this KDE default binding may be from a long
>>> time ago when this did work. Or maybe KDE uses the FOO part of KEY_FOO
>>> as symbolic when there is no xkb mapping ?
>> It does not work on X11, but it does work on Wayland (there xev also sees the Zenkaku/Hankaku keypress). Don't ask me why.
> Interesting, so in xev under Wayland you see something like this
> on release:
>
>      state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
>
> With there actually being a keysym of "Zenkaku_Hankaku" there ?

No. Sorry I got it a little bit wrong above, I didn't know it exactly anymore 
and had to retest:


With the keyboard shortcut deactivated, xev on wayland shows this:

KeyPress event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 246681, (83,3), root:(1273,701),
     state 0x0, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
     XLookupString gives 0 bytes:
     XmbLookupString gives 0 bytes:
     XFilterEvent returns: False

KeyPress event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 246682, (83,3), root:(1273,701),
     state 0x40, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
     XLookupString gives 0 bytes:
     XmbLookupString gives 0 bytes:
     XFilterEvent returns: False

KeyPress event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 246686, (83,3), root:(1273,701),
     state 0x44, keycode 93 (keysym 0x0, NoSymbol), same_screen YES,
     XLookupString gives 0 bytes:
     XmbLookupString gives 0 bytes:
     XFilterEvent returns: False

KeyRelease event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 246690, (83,3), root:(1273,701),
     state 0x44, keycode 93 (keysym 0x0, NoSymbol), same_screen YES,
     XLookupString gives 0 bytes:
     XFilterEvent returns: False

KeyRelease event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 246696, (83,3), root:(1273,701),
     state 0x44, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
     XLookupString gives 0 bytes:
     XFilterEvent returns: False

KeyRelease event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 246703, (83,3), root:(1273,701),
     state 0x40, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
     XLookupString gives 0 bytes:
     XFilterEvent returns: False


With the shortcut active, xev on wayland shows this (and the shortcut works):

KeyPress event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 365034, (83,3), root:(1273,701),
     state 0x0, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
     XLookupString gives 0 bytes:
     XmbLookupString gives 0 bytes:
     XFilterEvent returns: False

KeyPress event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 365036, (83,3), root:(1273,701),
     state 0x40, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
     XLookupString gives 0 bytes:
     XmbLookupString gives 0 bytes:
     XFilterEvent returns: False

KeyRelease event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 365060, (83,3), root:(1273,701),
     state 0x44, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
     XLookupString gives 0 bytes:
     XFilterEvent returns: False

KeyRelease event, serial 39, synthetic NO, window 0x1200001,
     root 0x4f7, subw 0x0, time 365060, (83,3), root:(1273,701),
     state 0x40, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
     XLookupString gives 0 bytes:
     XFilterEvent returns: False

>
> Because that is not working on Wayland on my laptop with the same
> issue (after disabling the hwdb mapping) and I don't understand
> how that could work at all given that /usr/share/X11/xkb/keycodes/evdev
> has no mapping for EV keycode 85 (93 in that file) ?
>
>> Also: Other DEs don't have this binding.
> Yes that is an issue, but see below.
>
>>> *) 85 + 8 all codes there are shifted up 8 compared to the KEY_FOO
>>> defines because codes 0-7 are reserved for modifier.
>>>
>>> I hit the same issue years ago on "T-boa Tbook air" laptop and
>>> their I fixed this by mapping Hangaku/Zenkaku -> f21 in
>>> /lib/udev/hwdb.d/60-keyboard.hwdb :
>>>
>>> ###########################################################
>>> # T-bao
>>> ###########################################################
>>>
>>> evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:*
>>>    KEYBOARD_KEY_76=f21                                    # Touchpad toggle
>>>
>>> + teaching GNOME to also accept Ctrl + Super + XF86TouchpadToggle
>>> as touchpad-toggle:
>>>
>>> https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/blob/master/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in?ref_type=heads#L577
>> Yeah KDE would need a similar fix and other DEs probably too. I hoped for a generic fix that does not need adjustments in so many projects.
>>
>> My first try was to do it on the XKB level but on Wayland the RedirectKey action is not implemented https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/794#note_2803713 (and probably wont be even in the future https://github.com/xkbcommon/libxkbcommon/issues/18#issuecomment-72728366) so I can't "unpress" control and super.
>>
>> If it is a more general issue, why not fix it on a more general level in the kernel? Maybe a generic filter applyable via a command line quirk and/or a quirk list?
> The problem is that filtering keys with modifiers like you are doing
> here just does not work.
>
> Your filter is seriously messing with the timing of the keypresses
> which can be a real issue when not actually using the toggle touchpad
> hotkey.
>
> Lets say the user is playing a game and has mapped super to
> one of the fire buttons and is using an in game weapon with
> some sort of auto-repeat firing.
>
> And your seqpos variable likely is 0 when super gets pressed,
> now the keyboard sends 0xe0, 0x5b which your filter filters
> out, and the user keeps super pressed because they expect
> the weapon to start firing on auto-repeat. But the super
> press is never send until super is released or another key
> is pressed so things don't work.
>
> Likewise if the DE, an app or accessibility settings want to
> differentiate between a short and a long super press all
> presses now become super (pun not intended) short because
> you insert the press directly in front of the release, losing
> any timing information about how long the key was pressed.
>
> This is why using an i8042 filter for filtering key-combinations
> (and the EC emulates a key-combination here) can never work reliably.
Ok, thought I had a clean solution, but doesn't seems so xD.
>
> OTOH desktop environments already allow having Ctrl+Super+something
> keybindings for DE actions. So we can re-use the tried and trusted
> modifier handling in the DE to deal with combi part leaving just
> the issue of mapping PS/2 scancode 0x76 aka evdev code
> 85 / KEY_ZENKAKUHANKAKU to something usable by the DE.
>
> ATM both GNOME and KDE already have support for
> Ctrl+Super+something for touchpad-toggle except that KDE expects
> a "Zenkaku_Hankaku" keysym where as GNOME expects "XF86TouchpadToggle"
> arguably the GNOME solution is slightly better because Japanese
> keyboard layouts already use/send the "Zenkaku_Hankaku" keysym
> unrelated to touchpad-toggle use. And I don't know what happens
> when pressing ctrl+super+Zenkaku_Hankaku while using a Japanese
> layout.
When I interpret the xkb-config correctly, JIS keyboards use the tilde 
scancode/keycode for the physical zenkaku/hankaku keys, at least in the default 
config HZTG (henkaku/zankaku toggle) is aliased to TLDE
>
> I think maybe we just need to patch atkbd.c at the kernel to
> map scancode 0x76 -> KEY_TOUCHPAD_TOGGLE since normal PS/2
> keyboards never generate 0x76, this would lose the mapping to
> KEY_ZENKAKUHANKAKU but since /usr/share/X11/xkb/keycodes/evdev
> does not even map KEY_ZENKAKUHANKAKU I don't think loosing that
> mapping will do a big deal.

At least from kernel side this would be a very small patch, are there any 
objections to it?

If not I make a patch for it and create a KDE issue.

>
> So I think that going with the evdev mapping + teaching KDE
> that Ctrl+Super+XF86TouchpadToggle is just XF86TouchpadToggle
> is the best way forward to solve this once and for all.
>
>>>> It suppresses the reserved scancode produced by pressing the FN-key on its
>>>> own, which fixes a warning spamming the dmesg log otherwise.
>>> Can you not also suppress this by mapping the key to "unknown" in hwdb?
>> Maybe, I didn't try. Was convenient to just do it here since I already had the filter. Will look into it once it is decided what to do with the touchpad toggle issue.
> Please give using hwdb for this a try.

kk will do later

Best regards,

Werner

>
> Regards,
>
> Hans
>
>
Hans de Goede March 6, 2025, 2:46 p.m. UTC | #9
Hi Werner,

On 5-Mar-25 4:41 PM, Werner Sembach wrote:
> Hi Hans,
> 
> Am 05.03.25 um 15:18 schrieb Hans de Goede:
>> Hi Werner,
>>
>> On 5-Mar-25 1:07 PM, Werner Sembach wrote:
>>> Am 05.03.25 um 12:25 schrieb Hans de Goede:
>>>> Hi Werner,
>>>>
>>>> On 3-Mar-25 8:04 PM, Werner Sembach wrote:
>>>>> This small driver does 2 things:
>>>>>
>>>>> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
>>>>> F21 to conform with established userspace defaults. Note that the
>>>>> Hangaku/Zenkaku scancode used here is usually unused, with real
>>>>> Hangaku/Zenkaku keys using the tilde scancode.
>>>> So this control + super + scancode 0x76 sending is also seen on
>>>> quite a few other laptops and I think we need a generic fix for this.
>>>>
>>>> I recently noticed that KDE's keyboard-shortcut settings actually has
>>>> a  control + super + Hangaku/Zenkaku -> touchpad-toggle key binding
>>>> in its default bindings (IIRC). But that cannot work because xkb actually
>>>> has no mapping for evdev code 85 / KEY_ZENKAKUHANKAKU if you look in:
>>>>
>>>> /usr/share/X11/xkb/keycodes/evdev and then look for 93 (*) you will
>>>> find no mapping. I think this KDE default binding may be from a long
>>>> time ago when this did work. Or maybe KDE uses the FOO part of KEY_FOO
>>>> as symbolic when there is no xkb mapping ?
>>> It does not work on X11, but it does work on Wayland (there xev also sees the Zenkaku/Hankaku keypress). Don't ask me why.
>> Interesting, so in xev under Wayland you see something like this
>> on release:
>>
>>      state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
>>
>> With there actually being a keysym of "Zenkaku_Hankaku" there ?
> 
> No. Sorry I got it a little bit wrong above, I didn't know it exactly anymore and had to retest:
> 
> 
> With the keyboard shortcut deactivated, xev on wayland shows this:
> 
> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 246681, (83,3), root:(1273,701),
>     state 0x0, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
>     XLookupString gives 0 bytes:
>     XmbLookupString gives 0 bytes:
>     XFilterEvent returns: False
> 
> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 246682, (83,3), root:(1273,701),
>     state 0x40, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>     XLookupString gives 0 bytes:
>     XmbLookupString gives 0 bytes:
>     XFilterEvent returns: False
> 
> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 246686, (83,3), root:(1273,701),
>     state 0x44, keycode 93 (keysym 0x0, NoSymbol), same_screen YES,
>     XLookupString gives 0 bytes:
>     XmbLookupString gives 0 bytes:
>     XFilterEvent returns: False
> 
> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 246690, (83,3), root:(1273,701),
>     state 0x44, keycode 93 (keysym 0x0, NoSymbol), same_screen YES,
>     XLookupString gives 0 bytes:
>     XFilterEvent returns: False
> 
> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 246696, (83,3), root:(1273,701),
>     state 0x44, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>     XLookupString gives 0 bytes:
>     XFilterEvent returns: False
> 
> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 246703, (83,3), root:(1273,701),
>     state 0x40, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
>     XLookupString gives 0 bytes:
>     XFilterEvent returns: False
> 
> 
> With the shortcut active, xev on wayland shows this (and the shortcut works):
> 
> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 365034, (83,3), root:(1273,701),
>     state 0x0, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
>     XLookupString gives 0 bytes:
>     XmbLookupString gives 0 bytes:
>     XFilterEvent returns: False
> 
> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 365036, (83,3), root:(1273,701),
>     state 0x40, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>     XLookupString gives 0 bytes:
>     XmbLookupString gives 0 bytes:
>     XFilterEvent returns: False
> 
> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 365060, (83,3), root:(1273,701),
>     state 0x44, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>     XLookupString gives 0 bytes:
>     XFilterEvent returns: False
> 
> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>     root 0x4f7, subw 0x0, time 365060, (83,3), root:(1273,701),
>     state 0x40, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
>     XLookupString gives 0 bytes:
>     XFilterEvent returns: False

Ah ok, so in KDE the shortcut somehow works under Wayland despite
the lack of xkb keysym mapping (maybe match on keycode?) and then 
the compositor absorbs / eats the Zenkaku_Hankaku key-press +
release as it does with other compositor handled hotkeys leaving
apps like xev to just see the modifier press/release events
(which the compositor cannot delay / filter for the same reasons
as why an i8042 kbd filter won't work).

>> Because that is not working on Wayland on my laptop with the same
>> issue (after disabling the hwdb mapping) and I don't understand
>> how that could work at all given that /usr/share/X11/xkb/keycodes/evdev
>> has no mapping for EV keycode 85 (93 in that file) ?
>>
>>> Also: Other DEs don't have this binding.
>> Yes that is an issue, but see below.
>>
>>>> *) 85 + 8 all codes there are shifted up 8 compared to the KEY_FOO
>>>> defines because codes 0-7 are reserved for modifier.
>>>>
>>>> I hit the same issue years ago on "T-boa Tbook air" laptop and
>>>> their I fixed this by mapping Hangaku/Zenkaku -> f21 in
>>>> /lib/udev/hwdb.d/60-keyboard.hwdb :
>>>>
>>>> ###########################################################
>>>> # T-bao
>>>> ###########################################################
>>>>
>>>> evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:*
>>>>    KEYBOARD_KEY_76=f21                                    # Touchpad toggle
>>>>
>>>> + teaching GNOME to also accept Ctrl + Super + XF86TouchpadToggle
>>>> as touchpad-toggle:
>>>>
>>>> https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/blob/master/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in?ref_type=heads#L577
>>> Yeah KDE would need a similar fix and other DEs probably too. I hoped for a generic fix that does not need adjustments in so many projects.
>>>
>>> My first try was to do it on the XKB level but on Wayland the RedirectKey action is not implemented https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/794#note_2803713 (and probably wont be even in the future https://github.com/xkbcommon/libxkbcommon/issues/18#issuecomment-72728366) so I can't "unpress" control and super.
>>>
>>> If it is a more general issue, why not fix it on a more general level in the kernel? Maybe a generic filter applyable via a command line quirk and/or a quirk list?
>> The problem is that filtering keys with modifiers like you are doing
>> here just does not work.
>>
>> Your filter is seriously messing with the timing of the keypresses
>> which can be a real issue when not actually using the toggle touchpad
>> hotkey.
>>
>> Lets say the user is playing a game and has mapped super to
>> one of the fire buttons and is using an in game weapon with
>> some sort of auto-repeat firing.
>>
>> And your seqpos variable likely is 0 when super gets pressed,
>> now the keyboard sends 0xe0, 0x5b which your filter filters
>> out, and the user keeps super pressed because they expect
>> the weapon to start firing on auto-repeat. But the super
>> press is never send until super is released or another key
>> is pressed so things don't work.
>>
>> Likewise if the DE, an app or accessibility settings want to
>> differentiate between a short and a long super press all
>> presses now become super (pun not intended) short because
>> you insert the press directly in front of the release, losing
>> any timing information about how long the key was pressed.
>>
>> This is why using an i8042 filter for filtering key-combinations
>> (and the EC emulates a key-combination here) can never work reliably.
> Ok, thought I had a clean solution, but doesn't seems so xD.

Yeah these single key which the EC makes send a whole key sequence
EC level key-bindings are a pain to deal with. Some for some other
keys emulating Windows hotkey presses like "Super + P", but those
are simply send unmodified to the DE to let the DE deal with them.

Sending these unmodified to the DE pretty much is the only thing
we can do.

>> OTOH desktop environments already allow having Ctrl+Super+something
>> keybindings for DE actions. So we can re-use the tried and trusted
>> modifier handling in the DE to deal with combi part leaving just
>> the issue of mapping PS/2 scancode 0x76 aka evdev code
>> 85 / KEY_ZENKAKUHANKAKU to something usable by the DE.
>>
>> ATM both GNOME and KDE already have support for
>> Ctrl+Super+something for touchpad-toggle except that KDE expects
>> a "Zenkaku_Hankaku" keysym where as GNOME expects "XF86TouchpadToggle"
>> arguably the GNOME solution is slightly better because Japanese
>> keyboard layouts already use/send the "Zenkaku_Hankaku" keysym
>> unrelated to touchpad-toggle use. And I don't know what happens
>> when pressing ctrl+super+Zenkaku_Hankaku while using a Japanese
>> layout.
> When I interpret the xkb-config correctly, JIS keyboards use the tilde scancode/keycode for the physical zenkaku/hankaku keys, at least in the default config HZTG (henkaku/zankaku toggle) is aliased to TLDE

Yes I don't think the 0x76 ps/2 scancode is used on any actual
keyboards other then for this toggle touchpad key thing.

>> I think maybe we just need to patch atkbd.c at the kernel to
>> map scancode 0x76 -> KEY_TOUCHPAD_TOGGLE since normal PS/2
>> keyboards never generate 0x76, this would lose the mapping to
>> KEY_ZENKAKUHANKAKU but since /usr/share/X11/xkb/keycodes/evdev
>> does not even map KEY_ZENKAKUHANKAKU I don't think loosing that
>> mapping will do a big deal.
> 
> At least from kernel side this would be a very small patch, are there any objections to it?

Well it would break the currently working touchpad toggle in KDE,
but the same applies to doing the mapping in hwdb.

I think it would be best to just post the patch + create
a KDE issue and then see from there.

Regards,

Hans
Werner Sembach March 6, 2025, 5:43 p.m. UTC | #10
Hi Hans,

Am 06.03.25 um 15:46 schrieb Hans de Goede:
> Hi Werner,
>
> On 5-Mar-25 4:41 PM, Werner Sembach wrote:
>> Hi Hans,
>>
>> Am 05.03.25 um 15:18 schrieb Hans de Goede:
>>> Hi Werner,
>>>
>>> On 5-Mar-25 1:07 PM, Werner Sembach wrote:
>>>> Am 05.03.25 um 12:25 schrieb Hans de Goede:
>>>>> Hi Werner,
>>>>>
>>>>> On 3-Mar-25 8:04 PM, Werner Sembach wrote:
>>>>>> This small driver does 2 things:
>>>>>>
>>>>>> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
>>>>>> F21 to conform with established userspace defaults. Note that the
>>>>>> Hangaku/Zenkaku scancode used here is usually unused, with real
>>>>>> Hangaku/Zenkaku keys using the tilde scancode.
>>>>> So this control + super + scancode 0x76 sending is also seen on
>>>>> quite a few other laptops and I think we need a generic fix for this.
>>>>>
>>>>> I recently noticed that KDE's keyboard-shortcut settings actually has
>>>>> a  control + super + Hangaku/Zenkaku -> touchpad-toggle key binding
>>>>> in its default bindings (IIRC). But that cannot work because xkb actually
>>>>> has no mapping for evdev code 85 / KEY_ZENKAKUHANKAKU if you look in:
>>>>>
>>>>> /usr/share/X11/xkb/keycodes/evdev and then look for 93 (*) you will
>>>>> find no mapping. I think this KDE default binding may be from a long
>>>>> time ago when this did work. Or maybe KDE uses the FOO part of KEY_FOO
>>>>> as symbolic when there is no xkb mapping ?
>>>> It does not work on X11, but it does work on Wayland (there xev also sees the Zenkaku/Hankaku keypress). Don't ask me why.
>>> Interesting, so in xev under Wayland you see something like this
>>> on release:
>>>
>>>       state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
>>>
>>> With there actually being a keysym of "Zenkaku_Hankaku" there ?
>> No. Sorry I got it a little bit wrong above, I didn't know it exactly anymore and had to retest:
>>
>>
>> With the keyboard shortcut deactivated, xev on wayland shows this:
>>
>> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 246681, (83,3), root:(1273,701),
>>      state 0x0, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XmbLookupString gives 0 bytes:
>>      XFilterEvent returns: False
>>
>> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 246682, (83,3), root:(1273,701),
>>      state 0x40, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XmbLookupString gives 0 bytes:
>>      XFilterEvent returns: False
>>
>> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 246686, (83,3), root:(1273,701),
>>      state 0x44, keycode 93 (keysym 0x0, NoSymbol), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XmbLookupString gives 0 bytes:
>>      XFilterEvent returns: False
>>
>> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 246690, (83,3), root:(1273,701),
>>      state 0x44, keycode 93 (keysym 0x0, NoSymbol), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XFilterEvent returns: False
>>
>> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 246696, (83,3), root:(1273,701),
>>      state 0x44, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XFilterEvent returns: False
>>
>> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 246703, (83,3), root:(1273,701),
>>      state 0x40, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XFilterEvent returns: False
>>
>>
>> With the shortcut active, xev on wayland shows this (and the shortcut works):
>>
>> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 365034, (83,3), root:(1273,701),
>>      state 0x0, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XmbLookupString gives 0 bytes:
>>      XFilterEvent returns: False
>>
>> KeyPress event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 365036, (83,3), root:(1273,701),
>>      state 0x40, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XmbLookupString gives 0 bytes:
>>      XFilterEvent returns: False
>>
>> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 365060, (83,3), root:(1273,701),
>>      state 0x44, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XFilterEvent returns: False
>>
>> KeyRelease event, serial 39, synthetic NO, window 0x1200001,
>>      root 0x4f7, subw 0x0, time 365060, (83,3), root:(1273,701),
>>      state 0x40, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
>>      XLookupString gives 0 bytes:
>>      XFilterEvent returns: False
> Ah ok, so in KDE the shortcut somehow works under Wayland despite
> the lack of xkb keysym mapping (maybe match on keycode?) and then
> the compositor absorbs / eats the Zenkaku_Hankaku key-press +
> release as it does with other compositor handled hotkeys leaving
> apps like xev to just see the modifier press/release events
> (which the compositor cannot delay / filter for the same reasons
> as why an i8042 kbd filter won't work).
>
>>> Because that is not working on Wayland on my laptop with the same
>>> issue (after disabling the hwdb mapping) and I don't understand
>>> how that could work at all given that /usr/share/X11/xkb/keycodes/evdev
>>> has no mapping for EV keycode 85 (93 in that file) ?
>>>
>>>> Also: Other DEs don't have this binding.
>>> Yes that is an issue, but see below.
>>>
>>>>> *) 85 + 8 all codes there are shifted up 8 compared to the KEY_FOO
>>>>> defines because codes 0-7 are reserved for modifier.
>>>>>
>>>>> I hit the same issue years ago on "T-boa Tbook air" laptop and
>>>>> their I fixed this by mapping Hangaku/Zenkaku -> f21 in
>>>>> /lib/udev/hwdb.d/60-keyboard.hwdb :
>>>>>
>>>>> ###########################################################
>>>>> # T-bao
>>>>> ###########################################################
>>>>>
>>>>> evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:*
>>>>>     KEYBOARD_KEY_76=f21                                    # Touchpad toggle
>>>>>
>>>>> + teaching GNOME to also accept Ctrl + Super + XF86TouchpadToggle
>>>>> as touchpad-toggle:
>>>>>
>>>>> https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/blob/master/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in?ref_type=heads#L577
>>>> Yeah KDE would need a similar fix and other DEs probably too. I hoped for a generic fix that does not need adjustments in so many projects.
>>>>
>>>> My first try was to do it on the XKB level but on Wayland the RedirectKey action is not implemented https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/794#note_2803713 (and probably wont be even in the future https://github.com/xkbcommon/libxkbcommon/issues/18#issuecomment-72728366) so I can't "unpress" control and super.
>>>>
>>>> If it is a more general issue, why not fix it on a more general level in the kernel? Maybe a generic filter applyable via a command line quirk and/or a quirk list?
>>> The problem is that filtering keys with modifiers like you are doing
>>> here just does not work.
>>>
>>> Your filter is seriously messing with the timing of the keypresses
>>> which can be a real issue when not actually using the toggle touchpad
>>> hotkey.
>>>
>>> Lets say the user is playing a game and has mapped super to
>>> one of the fire buttons and is using an in game weapon with
>>> some sort of auto-repeat firing.
>>>
>>> And your seqpos variable likely is 0 when super gets pressed,
>>> now the keyboard sends 0xe0, 0x5b which your filter filters
>>> out, and the user keeps super pressed because they expect
>>> the weapon to start firing on auto-repeat. But the super
>>> press is never send until super is released or another key
>>> is pressed so things don't work.
>>>
>>> Likewise if the DE, an app or accessibility settings want to
>>> differentiate between a short and a long super press all
>>> presses now become super (pun not intended) short because
>>> you insert the press directly in front of the release, losing
>>> any timing information about how long the key was pressed.
>>>
>>> This is why using an i8042 filter for filtering key-combinations
>>> (and the EC emulates a key-combination here) can never work reliably.
>> Ok, thought I had a clean solution, but doesn't seems so xD.
> Yeah these single key which the EC makes send a whole key sequence
> EC level key-bindings are a pain to deal with. Some for some other
> keys emulating Windows hotkey presses like "Super + P", but those
> are simply send unmodified to the DE to let the DE deal with them.
>
> Sending these unmodified to the DE pretty much is the only thing
> we can do.
>
>>> OTOH desktop environments already allow having Ctrl+Super+something
>>> keybindings for DE actions. So we can re-use the tried and trusted
>>> modifier handling in the DE to deal with combi part leaving just
>>> the issue of mapping PS/2 scancode 0x76 aka evdev code
>>> 85 / KEY_ZENKAKUHANKAKU to something usable by the DE.
>>>
>>> ATM both GNOME and KDE already have support for
>>> Ctrl+Super+something for touchpad-toggle except that KDE expects
>>> a "Zenkaku_Hankaku" keysym where as GNOME expects "XF86TouchpadToggle"
>>> arguably the GNOME solution is slightly better because Japanese
>>> keyboard layouts already use/send the "Zenkaku_Hankaku" keysym
>>> unrelated to touchpad-toggle use. And I don't know what happens
>>> when pressing ctrl+super+Zenkaku_Hankaku while using a Japanese
>>> layout.
>> When I interpret the xkb-config correctly, JIS keyboards use the tilde scancode/keycode for the physical zenkaku/hankaku keys, at least in the default config HZTG (henkaku/zankaku toggle) is aliased to TLDE
> Yes I don't think the 0x76 ps/2 scancode is used on any actual
> keyboards other then for this toggle touchpad key thing.
>
>>> I think maybe we just need to patch atkbd.c at the kernel to
>>> map scancode 0x76 -> KEY_TOUCHPAD_TOGGLE since normal PS/2
>>> keyboards never generate 0x76, this would lose the mapping to
>>> KEY_ZENKAKUHANKAKU but since /usr/share/X11/xkb/keycodes/evdev
>>> does not even map KEY_ZENKAKUHANKAKU I don't think loosing that
>>> mapping will do a big deal.
>> At least from kernel side this would be a very small patch, are there any objections to it?
> Well it would break the currently working touchpad toggle in KDE,
> but the same applies to doing the mapping in hwdb.

So I looked into KDE: They use whatever Qt is doing: 
https://invent.kde.org/plasma/kwin/-/blob/be91df80ef44386f98a831a5f4dfdfd4a3b6e83e/src/plugins/touchpadshortcuts/touchpadshortcuts.cpp#L41

After thinking about it a little bit: If we need to touch multiple userspace 
projects anyway, I tend to not touch the kernel at all. After all: From kernel 
side the key is mapped in a way that both X11 and Wayland can see it (given the 
right xkeyboard-config).

Thought dump below for userspace only solutions:

- Map KEY_ZENKAKUHANKAKU to XF86TouchpadToggle using xkeyboard-config

- Add Qt::ControlModifier | Qt::MetaModifier | Qt::Key_TouchpadToggle to KDE

- Possible regression: If user updates xkb without updating KDE the formerly 
working shortcut stops working

or

- Map KEY_ZENKAKUHANKAKU to Zenkaku_Hankaku using xkeyboard-config

- See if that fixes the X11 binding of KDE

- Add Control + Super + Zenkaku_Hankaku to GNOME

- If user updates xkb without updating GNOME the formerly working shortcut stops 
working

- Possible regression: I tend to the first version as there might be at least a 
change that other DEs work out of the box with it.

Best regards,

Werner

>
> I think it would be best to just post the patch + create
> a KDE issue and then see from there.
>
> Regards,
>
> Hans
>
>
Werner Sembach March 6, 2025, 6:07 p.m. UTC | #11
Hi Hans,

Am 05.03.25 um 15:18 schrieb Hans de Goede:
> Hi Werner,
>
> On 5-Mar-25 1:07 PM, Werner Sembach wrote:
>> Am 05.03.25 um 12:25 schrieb Hans de Goede:
>>> Hi Werner,
>>>
>>> On 3-Mar-25 8:04 PM, Werner Sembach wrote:
>>>> This small driver does 2 things:
>>>>
>>>> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
>>>> F21 to conform with established userspace defaults. Note that the
>>>> Hangaku/Zenkaku scancode used here is usually unused, with real
>>>> Hangaku/Zenkaku keys using the tilde scancode.
>>> So this control + super + scancode 0x76 sending is also seen on
>>> quite a few other laptops and I think we need a generic fix for this.
>>>
>>> I recently noticed that KDE's keyboard-shortcut settings actually has
>>> a  control + super + Hangaku/Zenkaku -> touchpad-toggle key binding
>>> in its default bindings (IIRC). But that cannot work because xkb actually
>>> has no mapping for evdev code 85 / KEY_ZENKAKUHANKAKU if you look in:
>>>
>>> /usr/share/X11/xkb/keycodes/evdev and then look for 93 (*) you will
>>> find no mapping. I think this KDE default binding may be from a long
>>> time ago when this did work. Or maybe KDE uses the FOO part of KEY_FOO
>>> as symbolic when there is no xkb mapping ?
>> It does not work on X11, but it does work on Wayland (there xev also sees the Zenkaku/Hankaku keypress). Don't ask me why.
> Interesting, so in xev under Wayland you see something like this
> on release:
>
>      state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
>
> With there actually being a keysym of "Zenkaku_Hankaku" there ?
>
> Because that is not working on Wayland on my laptop with the same
> issue (after disabling the hwdb mapping) and I don't understand
> how that could work at all given that /usr/share/X11/xkb/keycodes/evdev
> has no mapping for EV keycode 85 (93 in that file) ?
>
>> Also: Other DEs don't have this binding.
> Yes that is an issue, but see below.
>
>>> *) 85 + 8 all codes there are shifted up 8 compared to the KEY_FOO
>>> defines because codes 0-7 are reserved for modifier.
>>>
>>> I hit the same issue years ago on "T-boa Tbook air" laptop and
>>> their I fixed this by mapping Hangaku/Zenkaku -> f21 in
>>> /lib/udev/hwdb.d/60-keyboard.hwdb :
>>>
>>> ###########################################################
>>> # T-bao
>>> ###########################################################
>>>
>>> evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:*
>>>    KEYBOARD_KEY_76=f21                                    # Touchpad toggle
>>>
>>> + teaching GNOME to also accept Ctrl + Super + XF86TouchpadToggle
>>> as touchpad-toggle:
>>>
>>> https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/blob/master/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in?ref_type=heads#L577
>> Yeah KDE would need a similar fix and other DEs probably too. I hoped for a generic fix that does not need adjustments in so many projects.
>>
>> My first try was to do it on the XKB level but on Wayland the RedirectKey action is not implemented https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/794#note_2803713 (and probably wont be even in the future https://github.com/xkbcommon/libxkbcommon/issues/18#issuecomment-72728366) so I can't "unpress" control and super.
>>
>> If it is a more general issue, why not fix it on a more general level in the kernel? Maybe a generic filter applyable via a command line quirk and/or a quirk list?
> The problem is that filtering keys with modifiers like you are doing
> here just does not work.
>
> Your filter is seriously messing with the timing of the keypresses
> which can be a real issue when not actually using the toggle touchpad
> hotkey.
>
> Lets say the user is playing a game and has mapped super to
> one of the fire buttons and is using an in game weapon with
> some sort of auto-repeat firing.
>
> And your seqpos variable likely is 0 when super gets pressed,
> now the keyboard sends 0xe0, 0x5b which your filter filters
> out, and the user keeps super pressed because they expect
> the weapon to start firing on auto-repeat. But the super
> press is never send until super is released or another key
> is pressed so things don't work.
>
> Likewise if the DE, an app or accessibility settings want to
> differentiate between a short and a long super press all
> presses now become super (pun not intended) short because
> you insert the press directly in front of the release, losing
> any timing information about how long the key was pressed.
>
> This is why using an i8042 filter for filtering key-combinations
> (and the EC emulates a key-combination here) can never work reliably.

I just had an idea how this filter could work without running into these issues:

Still listen to the whole key sequence and just suppress the 0x76 and 0xf6. Then 
after the sequence has finished issue a F21 keypress.

Would this fly?

Best regards,

Werner

>
> OTOH desktop environments already allow having Ctrl+Super+something
> keybindings for DE actions. So we can re-use the tried and trusted
> modifier handling in the DE to deal with combi part leaving just
> the issue of mapping PS/2 scancode 0x76 aka evdev code
> 85 / KEY_ZENKAKUHANKAKU to something usable by the DE.
>
> ATM both GNOME and KDE already have support for
> Ctrl+Super+something for touchpad-toggle except that KDE expects
> a "Zenkaku_Hankaku" keysym where as GNOME expects "XF86TouchpadToggle"
> arguably the GNOME solution is slightly better because Japanese
> keyboard layouts already use/send the "Zenkaku_Hankaku" keysym
> unrelated to touchpad-toggle use. And I don't know what happens
> when pressing ctrl+super+Zenkaku_Hankaku while using a Japanese
> layout.
>
> I think maybe we just need to patch atkbd.c at the kernel to
> map scancode 0x76 -> KEY_TOUCHPAD_TOGGLE since normal PS/2
> keyboards never generate 0x76, this would lose the mapping to
> KEY_ZENKAKUHANKAKU but since /usr/share/X11/xkb/keycodes/evdev
> does not even map KEY_ZENKAKUHANKAKU I don't think loosing that
> mapping will do a big deal.
>
> So I think that going with the evdev mapping + teaching KDE
> that Ctrl+Super+XF86TouchpadToggle is just XF86TouchpadToggle
> is the best way forward to solve this once and for all.
>
>>>> It suppresses the reserved scancode produced by pressing the FN-key on its
>>>> own, which fixes a warning spamming the dmesg log otherwise.
>>> Can you not also suppress this by mapping the key to "unknown" in hwdb?
>> Maybe, I didn't try. Was convenient to just do it here since I already had the filter. Will look into it once it is decided what to do with the touchpad toggle issue.
> Please give using hwdb for this a try.
>
> Regards,
>
> Hans
>
>
Werner Sembach March 7, 2025, 5:52 p.m. UTC | #12
Am 05.03.25 um 12:25 schrieb Hans de Goede:
> Hi Werner,
>
> On 3-Mar-25 8:04 PM, Werner Sembach wrote:
>> This small driver does 2 things:
>>
>> It remaps the touchpad toggle key from Control + Super + Hangaku/Zenkaku to
>> F21 to conform with established userspace defaults. Note that the
>> Hangaku/Zenkaku scancode used here is usually unused, with real
>> Hangaku/Zenkaku keys using the tilde scancode.
> So this control + super + scancode 0x76 sending is also seen on
> quite a few other laptops and I think we need a generic fix for this.
>
> I recently noticed that KDE's keyboard-shortcut settings actually has
> a  control + super + Hangaku/Zenkaku -> touchpad-toggle key binding
> in its default bindings (IIRC). But that cannot work because xkb actually
> has no mapping for evdev code 85 / KEY_ZENKAKUHANKAKU if you look in:
>
> /usr/share/X11/xkb/keycodes/evdev and then look for 93 (*) you will
> find no mapping. I think this KDE default binding may be from a long
> time ago when this did work. Or maybe KDE uses the FOO part of KEY_FOO
> as symbolic when there is no xkb mapping ?
>
> *) 85 + 8 all codes there are shifted up 8 compared to the KEY_FOO
> defines because codes 0-7 are reserved for modifier.
>
> I hit the same issue years ago on "T-boa Tbook air" laptop and
> their I fixed this by mapping Hangaku/Zenkaku -> f21 in
> /lib/udev/hwdb.d/60-keyboard.hwdb :
>
> ###########################################################
> # T-bao
> ###########################################################
>
> evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:*
>   KEYBOARD_KEY_76=f21                                    # Touchpad toggle
>
> + teaching GNOME to also accept Ctrl + Super + XF86TouchpadToggle
> as touchpad-toggle:
>
> https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/blob/master/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in?ref_type=heads#L577
>
> Notice that system76 has the same hwdb key mapping for their
> Pangolin 12 model which I presume also has something like e.g.
> a clevo as base model.
>
> So for now to fix the touchpad on this TUXEDO NB02 you should
> simply add a hwdb entry like the above entries.
>
> Longer term I think the right fix for the touchpad toggle for
> all laptops which do this would be to make GNOME do what KDE does
> and change the touchpad-toggle-static keybinding list which
> currently is:
>
> ['XF86TouchpadToggle', '<Ctrl><Super>XF86TouchpadToggle']
>
> to:
>
> ['XF86TouchpadToggle', '<Ctrl><Super>XF86TouchpadToggle', '<Ctrl><Super>"Something"']
>
> Where "Something" would then be the new mapping. Or maybe just teach
> atkbd or xkb or hwdb to map scancode 0x76 to TouchpadToggle by
> default then at least in GNOME this will work OOTB and for KDE
> a default binding of '<Ctrl><Super>XF86TouchpadToggle'] -> touchpad-toggle
> should probably be added there.
>
>> It suppresses the reserved scancode produced by pressing the FN-key on its
>> own, which fixes a warning spamming the dmesg log otherwise.
> Can you not also suppress this by mapping the key to "unknown" in hwdb?
Coming back to this: this doesn't work because hwdb handles keycodes, but the 
message in dmesg is produces because the scancode is not mapped to any keycode 
by default (it is mapped to 0 in atkbd.c).
>
> Regards,
>
> Hans
>
>
diff mbox series

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 4ff26fa94895d..d3fbbcef813b0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -24178,6 +24178,12 @@  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git turbostat
 F:	tools/power/x86/turbostat/
 F:	tools/testing/selftests/turbostat/
 
+TUXEDO DRIVERS
+M:	Werner Sembach <wse@tuxedocomputers.com>
+L:	platform-driver-x86@vger.kernel.org
+S:	Supported
+F:	drivers/platform/x86/tuxedo/
+
 TW5864 VIDEO4LINUX DRIVER
 M:	Bluecherry Maintainers <maintainers@bluecherrydvr.com>
 M:	Andrey Utkin <andrey.utkin@corp.bluecherry.net>
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 0258dd879d64b..9b78a1255c08e 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1199,3 +1199,5 @@  config P2SB
 	  The main purpose of this library is to unhide P2SB device in case
 	  firmware kept it hidden on some platforms in order to access devices
 	  behind it.
+
+source "drivers/platform/x86/tuxedo/Kconfig"
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index e1b1429470674..1562dcd7ad9a5 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -153,3 +153,6 @@  obj-$(CONFIG_WINMATE_FM07_KEYS)		+= winmate-fm07-keys.o
 
 # SEL
 obj-$(CONFIG_SEL3350_PLATFORM)		+= sel3350-platform.o
+
+# TUXEDO
+obj-y					+= tuxedo/
diff --git a/drivers/platform/x86/tuxedo/Kbuild b/drivers/platform/x86/tuxedo/Kbuild
new file mode 100644
index 0000000000000..e9c4243d438ba
--- /dev/null
+++ b/drivers/platform/x86/tuxedo/Kbuild
@@ -0,0 +1,6 @@ 
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# TUXEDO X86 Platform Specific Drivers
+#
+
+obj-y	+= nb02/
diff --git a/drivers/platform/x86/tuxedo/Kconfig b/drivers/platform/x86/tuxedo/Kconfig
new file mode 100644
index 0000000000000..e463f92135780
--- /dev/null
+++ b/drivers/platform/x86/tuxedo/Kconfig
@@ -0,0 +1,6 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# TUXEDO X86 Platform Specific Drivers
+#
+
+source "drivers/platform/x86/tuxedo/nb02/Kconfig"
diff --git a/drivers/platform/x86/tuxedo/nb02/Kbuild b/drivers/platform/x86/tuxedo/nb02/Kbuild
new file mode 100644
index 0000000000000..8624a012cd683
--- /dev/null
+++ b/drivers/platform/x86/tuxedo/nb02/Kbuild
@@ -0,0 +1,7 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# TUXEDO X86 Platform Specific Drivers
+#
+
+tuxedo_nb02_platform-y			:= platform.o
+obj-$(CONFIG_TUXEDO_NB02_PLATFORM)	+= tuxedo_nb02_platform.o
diff --git a/drivers/platform/x86/tuxedo/nb02/Kconfig b/drivers/platform/x86/tuxedo/nb02/Kconfig
new file mode 100644
index 0000000000000..bed56276b9b36
--- /dev/null
+++ b/drivers/platform/x86/tuxedo/nb02/Kconfig
@@ -0,0 +1,15 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# TUXEDO X86 Platform Specific Drivers
+#
+
+menuconfig TUXEDO_NB02_PLATFORM
+	tristate "TUXEDO NB02 Platform Driver"
+	help
+	  This driver implements miscellaneous things found on TUXEDO Notebooks
+	  with board vendor NB02. For the time being this is only remapping the
+	  touchpad toggle key to something supported by most Linux distros
+	  out-of-the-box and suppressing an unsupported scancode from the
+	  FN-key.
+
+	  When compiled as a module it will be called tuxedo_nb02_platform.
diff --git a/drivers/platform/x86/tuxedo/nb02/platform.c b/drivers/platform/x86/tuxedo/nb02/platform.c
new file mode 100644
index 0000000000000..68d83b9b4c2f5
--- /dev/null
+++ b/drivers/platform/x86/tuxedo/nb02/platform.c
@@ -0,0 +1,94 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Werner Sembach wse@tuxedocomputers.com
+ */
+
+#include <linux/dmi.h>
+#include <linux/i8042.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/serio.h>
+
+static u8 tux_nb02_touchp_toggle_seq[] = {
+	0xe0, 0x5b, // Super down
+	0x1d,       // Control down
+	0x76,       // Zenkaku/Hankaku down
+	0xf6,       // Zenkaku/Hankaku up
+	0x9d,       // Control up
+	0xe0, 0xdb  // Super up
+};
+
+static bool tux_nb02_i8042_filter(unsigned char data,
+				  unsigned char str,
+				  struct serio *port,
+				  __always_unused void *context)
+{
+	static u8 seq_pos;
+
+	if (unlikely(str & I8042_STR_AUXDATA))
+		return false;
+
+	/* Replace touchpad toggle key sequence with a singular press of the
+	 * F21-key.
+	 */
+	if (unlikely(data == tux_nb02_touchp_toggle_seq[seq_pos])) {
+		++seq_pos;
+		if (seq_pos == ARRAY_SIZE(tux_nb02_touchp_toggle_seq)) {
+			seq_pos = 0;
+			serio_interrupt(port, 0x6c, 0); // F21 down
+			serio_interrupt(port, 0xec, 0); // F21 up
+		}
+		return true;
+	}
+
+	/* Ignore bogus scancode produced by the FN-key. Reuse seq_pos as first
+	 * byte of that is just the "extended"-byte.
+	 */
+	if (unlikely(seq_pos == 1 && (data == 0x78 || data == 0xf8))) {
+		seq_pos = 0;
+		return true;
+	}
+
+	/* Replay skipped sequence bytes if it did not finish and it was not a
+	 * FN-key press.
+	 */
+	if (unlikely(seq_pos)) {
+		for (u8 i; i < seq_pos; ++i)
+			serio_interrupt(port, tux_nb02_touchp_toggle_seq[i], 0);
+		seq_pos = 0;
+	}
+
+	return false;
+}
+
+static const struct dmi_system_id tux_nb02_dmi_string_match[] __initconst = {
+	{
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
+			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "NB02"),
+		},
+	},
+	{ }
+};
+
+static int __init tux_nb02_plat_init(void)
+{
+	if (!dmi_check_system(tux_nb02_dmi_string_match))
+		return -ENODEV;
+
+	return i8042_install_filter(tux_nb02_i8042_filter, NULL);
+}
+
+static void __exit tux_nb02_plat_exit(void)
+{
+	i8042_remove_filter(tux_nb02_i8042_filter);
+}
+
+module_init(tux_nb02_plat_init);
+module_exit(tux_nb02_plat_exit);
+
+MODULE_ALIAS("dmi:*:svnTUXEDO:*:rvnNB02:*");
+
+MODULE_DESCRIPTION("TUXEDO NB02 Platform");
+MODULE_AUTHOR("Werner Sembach <wse@tuxedocomputers.com>");
+MODULE_LICENSE("GPL");