The branch main has been updated by obiwac: URL: https://cgit.FreeBSD.org/src/commit/?id=e2d56447b3a9d2ef9bd0b80c3aaa69e681f4be0f
commit e2d56447b3a9d2ef9bd0b80c3aaa69e681f4be0f Author: Aymeric Wibo <[email protected]> AuthorDate: 2026-06-25 02:03:36 +0000 Commit: Aymeric Wibo <[email protected]> CommitDate: 2026-07-09 07:27:07 +0000 hrfkill: Add driver to report RFKILL button press This driver only reports the RFKILL button presses. This is needed for the "airplane" key on some Framework laptops. Reviewed by: wulf, ziaee Event: Halifax Hackathon 202606 Location: vishwin@'s car Co-authored-by: Daniel Shaefer Sponsored by: Framework Computer Inc Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D57838 --- share/man/man4/Makefile | 1 + share/man/man4/hidbus.4 | 1 + share/man/man4/hrfkill.4 | 82 +++++++++++++++++++++++++++++ sys/conf/NOTES | 1 + sys/conf/files | 1 + sys/dev/hid/hid.h | 2 + sys/dev/hid/hrfkill.c | 111 +++++++++++++++++++++++++++++++++++++++ sys/modules/hid/Makefile | 1 + sys/modules/hid/hrfkill/Makefile | 8 +++ 9 files changed, 208 insertions(+) diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 56b50d39d6f4..9bee23f1df8f 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -222,6 +222,7 @@ MAN= aac.4 \ ${_hptmv.4} \ ${_hptnr.4} \ ${_hptrr.4} \ + hrfkill.4 \ hsctrl.4 \ htu21.4 \ ${_hv_kvp.4} \ diff --git a/share/man/man4/hidbus.4 b/share/man/man4/hidbus.4 index f8ebaca8d659..e336eb5eb9b9 100644 --- a/share/man/man4/hidbus.4 +++ b/share/man/man4/hidbus.4 @@ -83,6 +83,7 @@ Default is 0. .Xr hms 4 , .Xr hmt 4 , .Xr hpen 4 , +.Xr hrfkill 4 , .Xr hsctrl 4 , .Xr hskbd 4 , .Xr iichid 4 , diff --git a/share/man/man4/hrfkill.4 b/share/man/man4/hrfkill.4 new file mode 100644 index 000000000000..c1d3b73b28b2 --- /dev/null +++ b/share/man/man4/hrfkill.4 @@ -0,0 +1,82 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2026 The FreeBSD Foundation +.\" +.\" Portions of this software were developed by Aymeric Wibo +.\" <[email protected]> under sponsorship from the FreeBSD Foundation. +.\" +.Dd June 24, 2026 +.Dt HRFKILL 4 +.Os +.Sh NAME +.Nm hrfkill +.Nd HID radio control driver +.Sh SYNOPSIS +.Cd device hrfkill +.Cd device hid +.Cd device hidbus +.Cd device hidmap +.Cd device evdev +In +.Xr loader.conf 5 : +.Cd hrfkill_load="YES" +.Sh DESCRIPTION +The +.Nm +driver provides support for HID wireless radio control buttons, +most often found as an +.Qq airplane mode +or RFKILL toggle on laptop keyboards, and presents them to applications over the +.Ar evdev +interface. +.Sh HARDWARE +The +.Nm +driver supports HID radio control buttons and airplane mode keys +on devices such as: +.Pp +.Bl -bullet -compact +.It +Framework Laptop Keyboard +.El +.Sh FILES +.Bl -tag -width /dev/input/event* -compact +.It Pa /dev/input/event* +input event device node +.El +.Sh SEE ALSO +.Xr hidbus 4 , +.Xr hsctrl 4 +.Sh HISTORY +The +.Nm +driver first appeared in +.Fx 16.0 . +.Sh AUTHORS +The +.Nm +driver was written by +.An Aymeric Wibo Aq Mt [email protected] +under sponsorship from the FreeBSD Foundation and by +.An Daniel Shaefer Aq Mt [email protected] +under sponsorship from Framework Computer Inc. +.Sh CAVEATS +Currently, +.Nm +only handles radio button reporting. +The HID Generic Desktop radio control page also defines radio switches and +status LEDs; support for these should be added in a future revision of the +driver. +.Pp +.Fx +does not yet have a generic RFKILL framework analogous to the one found in +Linux. +As a result, +.Nm +can only report radio button events to userspace via +.Ar evdev ; +the kernel itself has no mechanism to act on these events to block or unblock +wireless devices. +A future RFKILL framework would allow the driver to integrate directly with +network interfaces and block transmitters in response to hardware events. diff --git a/sys/conf/NOTES b/sys/conf/NOTES index c7931db374c7..7b253927e9a8 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2435,6 +2435,7 @@ device hkbd # HID keyboard device hms # HID mouse device hmt # HID multitouch (MS-compatible) device hpen # Generic pen driver +device hrfkill # RFKILL driver device hsctrl # System controls device ps4dshock # Sony PS4 DualShock 4 gamepad driver device u2f # FIDO/U2F authenticator diff --git a/sys/conf/files b/sys/conf/files index 09d4ff70e322..86dbd83e21d9 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1801,6 +1801,7 @@ dev/hid/hkbd.c optional hkbd dev/hid/hms.c optional hms dev/hid/hmt.c optional hmt hconf dev/hid/hpen.c optional hpen +dev/hid/hrfkill.c optional hrfkill dev/hid/hsctrl.c optional hsctrl dev/hid/ietp.c optional ietp dev/hid/ps4dshock.c optional ps4dshock diff --git a/sys/dev/hid/hid.h b/sys/dev/hid/hid.h index f164e48341ed..848657a7b768 100644 --- a/sys/dev/hid/hid.h +++ b/sys/dev/hid/hid.h @@ -74,6 +74,7 @@ #define HUG_KEYBOARD 0x0006 #define HUG_KEYPAD 0x0007 #define HUG_MULTIAXIS_CNTROLLER 0x0008 +#define HUG_RADIO_CONTROL 0x000c #define HUG_X 0x0030 #define HUG_Y 0x0031 #define HUG_Z 0x0032 @@ -116,6 +117,7 @@ #define HUG_D_PAD_RIGHT 0x0092 #define HUG_D_PAD_LEFT 0x0093 #define HUG_APPLE_EJECT 0x00b8 +#define HUG_RADIO_BUTTON 0x00c6 /* Usages Digitizers */ #define HUD_UNDEFINED 0x0000 diff --git a/sys/dev/hid/hrfkill.c b/sys/dev/hid/hrfkill.c new file mode 100644 index 000000000000..279d04c54f6e --- /dev/null +++ b/sys/dev/hid/hrfkill.c @@ -0,0 +1,111 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 The FreeBSD Foundation + * Copyright (c) 2026 Framework Computer Inc + * + * This software was developed by Aymeric Wibo <[email protected]> + * under sponsorship from the FreeBSD Foundation. + * + * Portions of this software were developed by Daniel Schaefer + * <[email protected]> under sponsorship from Framework Computer Inc. + */ + +#include "opt_hid.h" + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/module.h> + +#include <dev/evdev/evdev.h> +#include <dev/evdev/input.h> + +#include <dev/hid/hid.h> +#include <dev/hid/hidbus.h> +#include <dev/hid/hidmap.h> + +/* + * Reference document: + * https://www.usb.org/sites/default/files/hutrr40radiohidusagesfinal_0.pdf + */ + +static hidmap_cb_t hrfkill_cb; + +static const struct hidmap_item hrfkill_map[] = { + { HIDMAP_REL_CB(HUP_GENERIC_DESKTOP, HUG_RADIO_BUTTON, &hrfkill_cb) }, +}; + +static const struct hid_device_id hrfkill_devs[] = { + { HID_TLC(HUP_GENERIC_DESKTOP, HUG_RADIO_CONTROL) }, +}; + +/* + * Synthesize key-down + key-up for the wireless radio button, + * which only reports a relative pulse (value=1) on press. + * The firmware latches value=1 and never resets it, so we + * track the last value via HIDMAP_CB_UDATA64 and only fire + * on the 0 -> non-zero transition. + */ +static int +hrfkill_cb(HIDMAP_CB_ARGS) +{ + struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV(); + int32_t last; + + switch (HIDMAP_CB_GET_STATE()) { + case HIDMAP_CB_IS_ATTACHING: + evdev_support_event(evdev, EV_KEY); + evdev_support_key(evdev, KEY_RFKILL); + HIDMAP_CB_UDATA64 = 0; + break; + case HIDMAP_CB_IS_RUNNING: + last = (int32_t)HIDMAP_CB_UDATA64; + HIDMAP_CB_UDATA64 = (uint64_t)ctx.data; + if (ctx.data == 0 || ctx.data == last) + return (ENOMSG); + evdev_push_key(evdev, KEY_RFKILL, 1); + evdev_push_key(evdev, KEY_RFKILL, 0); + break; + default: + break; + } + + return (0); +} + +static int +hrfkill_probe(device_t dev) +{ + return (HIDMAP_PROBE(device_get_softc(dev), dev, + hrfkill_devs, hrfkill_map, "RFKILL Switch")); +} + +static int +hrfkill_attach(device_t dev) +{ + return (hidmap_attach(device_get_softc(dev))); +} + +static int +hrfkill_detach(device_t dev) +{ + return (hidmap_detach(device_get_softc(dev))); +} + +static device_method_t hrfkill_methods[] = { + DEVMETHOD(device_probe, hrfkill_probe), + DEVMETHOD(device_attach, hrfkill_attach), + DEVMETHOD(device_detach, hrfkill_detach), + + DEVMETHOD_END +}; + +DEFINE_CLASS_0(hrfkill, hrfkill_driver, hrfkill_methods, sizeof(struct hidmap)); +DRIVER_MODULE(hrfkill, hidbus, hrfkill_driver, NULL, NULL); +MODULE_DEPEND(hrfkill, hid, 1, 1, 1); +MODULE_DEPEND(hrfkill, hidbus, 1, 1, 1); +MODULE_DEPEND(hrfkill, hidmap, 1, 1, 1); +MODULE_DEPEND(hrfkill, evdev, 1, 1, 1); +MODULE_VERSION(hrfkill, 1); +HID_PNP_INFO(hrfkill_devs); diff --git a/sys/modules/hid/Makefile b/sys/modules/hid/Makefile index a32b9326647e..c6d856c45ed1 100644 --- a/sys/modules/hid/Makefile +++ b/sys/modules/hid/Makefile @@ -15,6 +15,7 @@ SUBDIR += \ hms \ hmt \ hpen \ + hrfkill \ hsctrl \ ietp \ ps4dshock \ diff --git a/sys/modules/hid/hrfkill/Makefile b/sys/modules/hid/hrfkill/Makefile new file mode 100644 index 000000000000..e6c46696fb7d --- /dev/null +++ b/sys/modules/hid/hrfkill/Makefile @@ -0,0 +1,8 @@ +.PATH: ${SRCTOP}/sys/dev/hid + +KMOD= hrfkill +SRCS= hrfkill.c +SRCS+= opt_kbd.h +SRCS+= bus_if.h device_if.h + +.include <bsd.kmod.mk>
