git: e2d56447b3a9 - main - hrfkill: Add driver to report RFKILL button press
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 09 Jul 2026 07:28:27 UTC
The branch main has been updated by obiwac:
URL: https://cgit.FreeBSD.org/src/commit/?id=e2d56447b3a9d2ef9bd0b80c3aaa69e681f4be0f
commit e2d56447b3a9d2ef9bd0b80c3aaa69e681f4be0f
Author: Aymeric Wibo <obiwac@FreeBSD.org>
AuthorDate: 2026-06-25 02:03:36 +0000
Commit: Aymeric Wibo <obiwac@FreeBSD.org>
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
+.\" <obiwac@freebsd.org> 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 obiwac@freebsd.org
+under sponsorship from the FreeBSD Foundation and by
+.An Daniel Shaefer Aq Mt git@danielschaefer.me
+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 <obiwac@freebsd.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Portions of this software were developed by Daniel Schaefer
+ * <git@danielschaefer.me> 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>