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>

Reply via email to