Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F170605220
D56345.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D56345.id.diff
View Options
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -495,6 +495,7 @@
procfs.4 \
proto.4 \
ps4dshock.4 \
+ ps5dsense.4 \
psm.4 \
pst.4 \
pt.4 \
diff --git a/share/man/man4/ps5dsense.4 b/share/man/man4/ps5dsense.4
new file mode 100644
--- /dev/null
+++ b/share/man/man4/ps5dsense.4
@@ -0,0 +1,145 @@
+.\"
+.\" Copyright (c) 2026 Christos Longros <chris.longros@gmail.com>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd August 29, 2026
+.Dt PS5DSENSE 4
+.Os
+.Sh NAME
+.Nm ps5dsense
+.Nd Sony PlayStation 5 DualSense gamepad driver
+.Sh SYNOPSIS
+.Cd device ps5dsense
+.Cd device hid
+.Cd device hidbus
+.Cd device hidmap
+.Cd device evdev
+.Pp
+In
+.Xr sysctl.conf 5 :
+.Cd dev.ps5dsense.%d.led_state
+.Cd dev.ps5dsense.%d.led_color_r
+.Cd dev.ps5dsense.%d.led_color_g
+.Cd dev.ps5dsense.%d.led_color_b
+.Cd dev.ps5dsense.%d.player_leds
+.Pp
+In
+.Xr loader.conf 5 :
+.Cd hw.hid.ps5dsense.debug
+.Cd ps5dsense_load
+.Sh DESCRIPTION
+The
+.Nm
+driver supports the Sony PlayStation 5 DualSense gamepad
+connected over USB,
+and presents it to applications over the
+.Sy evdev
+interface.
+.Pp
+If the appropriate hardware is detected,
+the driver will be loaded automatically by
+.Xr devmatch 8 .
+To load the driver manually at boot time, set the
+.Va ps5dsense_load
+variable to
+.Ar YES
+at the
+.Xr loader 8
+prompt, or add it to
+.Xr loader.conf 5 .
+.Pp
+To give user applications access to the game controller,
+allow user access to the
+.Pa /dev/input/event*
+nodes with inclusion of user in the
+.Em games
+group,
+or with a
+.Xr devfs.rules 5
+ruleset.
+.Pp
+The microphone mute button is reported as
+.Dv KEY_MICMUTE ;
+unlike the vendor driver on other systems,
+.Nm
+does not mute the built-in microphone itself.
+.Sh HARDWARE
+The
+.Nm
+driver supports the following devices:
+.Pp
+.Bl -bullet -compact
+.It
+Sony DualSense wireless controller
+.Pq USB product ID 0x0ce6
+.El
+.Sh SYSCTL VARIABLES
+The following variables are available as
+.Xr sysctl 8
+variables:
+.Bl -tag -width indent
+.It Va dev.ps5dsense.%d.led_state
+Lightbar state,
+where 0 is off and
+1 is on.
+.It Va dev.ps5dsense.%d.led_color_r
+Lightbar color,
+red component.
+.It Va dev.ps5dsense.%d.led_color_g
+Lightbar color,
+green component.
+.It Va dev.ps5dsense.%d.led_color_b
+Lightbar color,
+blue component.
+.It Va dev.ps5dsense.%d.player_leds
+Player indicator LEDs,
+where -1 is off and
+0 to 4 select the player number.
+.El
+.Pp
+The following variable is available as both
+.Xr sysctl 8
+variable and
+.Xr loader 8
+tunable:
+.Bl -tag -width indent
+.It Va hw.hid.ps5dsense.debug
+Debug output level,
+where 0 is debugging disabled and
+larger values increase debug message verbosity.
+Default is 0.
+.El
+.Sh FILES
+.Bl -tag -width "/dev/input/event*" -compact
+.It Pa /dev/input/event*
+input event device
+.Pq Sy evdev
+node
+.El
+.Sh SEE ALSO
+.Xr hgame 4 ,
+.Xr ps4dshock 4 ,
+.Xr usbhid 4 ,
+.Xr devfs.rules 5
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 16.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Christos Longros Aq Mt chris.longros@gmail.com .
+.Sh BUGS
+The
+.Nm
+driver does not support force-feedback events, haptic feedback or the
+adaptive triggers.
+.Pp
+The touchpad and the motion sensors are not decoded.
+The touchpad click is therefore not reported at all.
+.Pp
+Bluetooth operation is not supported.
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2438,6 +2438,7 @@
device hrfkill # RFKILL driver
device hsctrl # System controls
device ps4dshock # Sony PS4 DualShock 4 gamepad driver
+device ps5dsense # Sony PS5 DualSense gamepad driver
device u2f # FIDO/U2F authenticator
options U2F_DROP_UHID_ALIAS # Do not install /dev/uhid alias for
# /dev/u2f/ and rename driver from uhid to u2f
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1816,6 +1816,7 @@
dev/hid/hsctrl.c optional hsctrl
dev/hid/ietp.c optional ietp
dev/hid/ps4dshock.c optional ps4dshock
+dev/hid/ps5dsense.c optional ps5dsense
dev/hid/u2f.c optional u2f
dev/hid/xb360gp.c optional xb360gp
dev/hptiop/hptiop.c optional hptiop scbus
diff --git a/sys/dev/hid/ps5dsense.c b/sys/dev/hid/ps5dsense.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/hid/ps5dsense.c
@@ -0,0 +1,472 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
+ * Copyright (c) 2026 Christos Longros <chris.longros@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Sony PS5 DualSense driver
+ * https://controllers.fandom.com/wiki/Sony_DualSense
+ * https://github.com/torvalds/linux/blob/master/drivers/hid/hid-playstation.c
+ *
+ * Touchpad and motion sensors are not supported yet.
+ */
+
+#include "opt_hid.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/stat.h>
+#include <sys/sx.h>
+#include <sys/sysctl.h>
+
+#include <dev/evdev/input.h>
+#include <dev/evdev/evdev.h>
+
+#define HID_DEBUG_VAR ps5ds_debug
+#include <dev/hid/hgame.h>
+#include <dev/hid/hid.h>
+#include <dev/hid/hidbus.h>
+#include <dev/hid/hidquirk.h>
+#include <dev/hid/hidmap.h>
+#include "usbdevs.h"
+
+#ifdef HID_DEBUG
+static int ps5ds_debug = 1;
+
+static SYSCTL_NODE(_hw_hid, OID_AUTO, ps5dsense, CTLFLAG_RW, 0,
+ "Sony PS5 DualSense Gamepad");
+SYSCTL_INT(_hw_hid_ps5dsense, OID_AUTO, debug, CTLFLAG_RWTUN,
+ &ps5ds_debug, 0, "Debug level");
+#endif
+
+/*
+ * Fixed HID report descriptor. Output is 62 bytes, not 47: shorter reports
+ * are ignored.
+ */
+static const uint8_t ps5ds_rdesc[] = {
+ 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
+ 0x09, 0x05, /* Usage (Game Pad) */
+ 0xA1, 0x01, /* Collection (Application) */
+ 0x85, 0x01, /* Report ID (1) */
+ 0x09, 0x30, /* Usage (X) - left stick X */
+ 0x09, 0x31, /* Usage (Y) - left stick Y */
+ 0x09, 0x33, /* Usage (Rx) - right stick X */
+ 0x09, 0x34, /* Usage (Ry) - right stick Y */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x04, /* Report Count (4) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+ 0x09, 0x32, /* Usage (Z) - L2 trigger */
+ 0x09, 0x35, /* Usage (Rz) - R2 trigger */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x02, /* Report Count (2) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+ 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined 0xFF00) */
+ 0x09, 0x20, /* Usage (0x20) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) - counter */
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x39, /* Usage (Hat switch) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x25, 0x07, /* Logical Maximum (7) */
+ 0x35, 0x00, /* Physical Minimum (0) */
+ 0x46, 0x3B, 0x01, /* Physical Maximum (315) */
+ 0x65, 0x14, /* Unit (Eng Rot: Degree) */
+ 0x75, 0x04, /* Report Size (4) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x81, 0x42, /* Input (Data,Var,Abs,Null State) */
+ 0x65, 0x00, /* Unit (None) */
+ 0x45, 0x00, /* Physical Maximum (0) */
+ 0x05, 0x09, /* Usage Page (Button) */
+ 0x19, 0x01, /* Usage Minimum (0x01) */
+ 0x29, 0x0F, /* Usage Maximum (0x0F) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x25, 0x01, /* Logical Maximum (1) */
+ 0x75, 0x01, /* Report Size (1) */
+ 0x95, 0x0F, /* Report Count (15) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+ 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined 0xFF00) */
+ 0x09, 0x21, /* Usage (0x21) */
+ 0x75, 0x01, /* Report Size (1) */
+ 0x95, 0x0D, /* Report Count (13) */
+ 0x81, 0x03, /* Input (Const) - unused button bits */
+ 0x09, 0x22, /* Usage (0x22) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x34, /* Report Count (52) */
+ 0x81, 0x03, /* Input (Const) - sensors, touchpad */
+ /* Output report (63 bytes total) for LED and rumble control */
+ 0x85, 0x02, /* Report ID (2) */
+ 0x09, 0x23, /* Usage (0x23) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x3E, /* Report Count (62) */
+ 0x91, 0x02, /* Output (Data,Var,Abs) */
+ 0xC0, /* End Collection */
+};
+
+#define PS5DS_OUTPUT_REPORT2_SIZE 63
+
+struct ps5ds_out2 {
+ uint8_t valid_flag0;
+ uint8_t valid_flag1;
+ uint8_t rumble_right;
+ uint8_t rumble_left;
+ uint8_t reserved1[4];
+ uint8_t mute_button_led;
+ uint8_t power_save_control;
+ uint8_t reserved2[28];
+ uint8_t valid_flag2;
+ uint8_t reserved3[2];
+ uint8_t lightbar_setup;
+ uint8_t led_brightness;
+ uint8_t player_leds;
+ uint8_t led_color_r;
+ uint8_t led_color_g;
+ uint8_t led_color_b;
+} __attribute__((packed));
+
+#define PS5DS_FLAG1_LIGHTBAR 0x04
+#define PS5DS_FLAG1_PLAYER_LEDS 0x10
+#define PS5DS_FLAG2_LIGHTBAR_SETUP 0x02
+#define PS5DS_LIGHTBAR_FADE_OUT 0x02
+
+static const uint8_t ps5ds_player_leds[] = {
+ 0x04, /* Player 1: --x-- */
+ 0x0A, /* Player 2: -x-x- */
+ 0x15, /* Player 3: x-x-x */
+ 0x1B, /* Player 4: xx-xx */
+ 0x1F, /* Player 5: xxxxx */
+};
+
+static const struct ps5ds_led {
+ int r;
+ int g;
+ int b;
+} ps5ds_leds[] = {
+ /* The first 4 entries match the PS4, other from Linux driver */
+ { 0x00, 0x00, 0x40 }, /* Blue */
+ { 0x40, 0x00, 0x00 }, /* Red */
+ { 0x00, 0x40, 0x00 }, /* Green */
+ { 0x20, 0x00, 0x20 }, /* Pink */
+ { 0x02, 0x01, 0x00 }, /* Orange */
+ { 0x00, 0x01, 0x01 }, /* Teal */
+ { 0x01, 0x01, 0x01 } /* White */
+};
+
+enum ps5ds_led_state {
+ PS5DS_LED_OFF,
+ PS5DS_LED_ON,
+ PS5DS_LED_CNT,
+};
+
+struct ps5ds_softc {
+ struct hidmap hm;
+
+ struct sx lock;
+ enum ps5ds_led_state led_state;
+ struct ps5ds_led led_color;
+ int player_leds; /* 0-4: player number, -1: off */
+};
+
+#define PS5DS_OFFSET(field) offsetof(struct ps5ds_softc, field)
+enum {
+ PS5DS_SYSCTL_LED_STATE = PS5DS_OFFSET(led_state),
+ PS5DS_SYSCTL_LED_COLOR_R = PS5DS_OFFSET(led_color.r),
+ PS5DS_SYSCTL_LED_COLOR_G = PS5DS_OFFSET(led_color.g),
+ PS5DS_SYSCTL_LED_COLOR_B = PS5DS_OFFSET(led_color.b),
+ PS5DS_SYSCTL_PLAYER_LEDS = PS5DS_OFFSET(player_leds),
+#define PS5DS_SYSCTL_LAST PS5DS_SYSCTL_PLAYER_LEDS
+};
+
+#define PS5DS_MAP_BTN(number, code) \
+ { HIDMAP_KEY(HUP_BUTTON, number, code) }
+#define PS5DS_MAP_ABS(usage, code) \
+ { HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code) }
+#define PS5DS_MAP_FLT(usage, code) \
+ { HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code), .flat = 15 }
+#define PS5DS_MAP_GCB(usage, callback) \
+ { HIDMAP_ANY_CB(HUP_GENERIC_DESKTOP, HUG_##usage, callback) }
+#define PS5DS_FINALCB(cb) \
+ { HIDMAP_FINAL_CB(&cb) }
+
+static hidmap_cb_t ps5ds_final_cb;
+
+static const struct hidmap_item ps5ds_map[] = {
+ PS5DS_MAP_FLT(X, ABS_X),
+ PS5DS_MAP_FLT(Y, ABS_Y),
+ PS5DS_MAP_ABS(Z, ABS_Z),
+ PS5DS_MAP_ABS(RZ, ABS_RZ),
+ PS5DS_MAP_FLT(RX, ABS_RX),
+ PS5DS_MAP_FLT(RY, ABS_RY),
+ PS5DS_MAP_BTN(1, BTN_WEST),
+ PS5DS_MAP_BTN(2, BTN_SOUTH),
+ PS5DS_MAP_BTN(3, BTN_EAST),
+ PS5DS_MAP_BTN(4, BTN_NORTH),
+ PS5DS_MAP_BTN(5, BTN_TL),
+ PS5DS_MAP_BTN(6, BTN_TR),
+ PS5DS_MAP_BTN(7, BTN_TL2),
+ PS5DS_MAP_BTN(8, BTN_TR2),
+ PS5DS_MAP_BTN(9, BTN_SELECT),
+ PS5DS_MAP_BTN(10, BTN_START),
+ PS5DS_MAP_BTN(11, BTN_THUMBL),
+ PS5DS_MAP_BTN(12, BTN_THUMBR),
+ PS5DS_MAP_BTN(13, BTN_MODE),
+ /* Click button is handled by touchpad driver */
+ /* PS5DS_MAP_BTN(14, BTN_LEFT), */
+ /* Linux mutes the microphone in hardware and emits no event */
+ PS5DS_MAP_BTN(15, KEY_MICMUTE),
+ PS5DS_MAP_GCB(HAT_SWITCH, hgame_hat_switch_cb),
+ PS5DS_FINALCB( ps5ds_final_cb),
+};
+
+static const struct hid_device_id ps5ds_devs[] = {
+ { HID_BVP(BUS_USB, USB_VENDOR_SONY, 0x0ce6),
+ HID_TLC(HUP_GENERIC_DESKTOP, HUG_GAME_PAD) },
+};
+
+static int
+ps5ds_final_cb(HIDMAP_CB_ARGS)
+{
+ struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
+
+ if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING) {
+ evdev_support_prop(evdev, INPUT_PROP_DIRECT);
+ evdev_set_cdev_mode(evdev, UID_ROOT, GID_GAMES,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ }
+
+ /* Do not execute callback at interrupt handler and detach */
+ return (ENOSYS);
+}
+
+static int
+ps5ds_write(struct ps5ds_softc *sc)
+{
+ uint8_t buf[PS5DS_OUTPUT_REPORT2_SIZE];
+ bool led_on;
+
+ sx_assert(&sc->lock, SA_XLOCKED);
+
+ memset(buf, 0, sizeof(buf));
+ buf[0] = 0x02;
+ led_on = sc->led_state != PS5DS_LED_OFF;
+ *(struct ps5ds_out2 *)(buf + 1) = (struct ps5ds_out2) {
+ .valid_flag1 = PS5DS_FLAG1_LIGHTBAR | PS5DS_FLAG1_PLAYER_LEDS,
+ .player_leds = sc->player_leds < 0 ?
+ 0 : ps5ds_player_leds[sc->player_leds],
+ .led_color_r = led_on ? sc->led_color.r : 0,
+ .led_color_g = led_on ? sc->led_color.g : 0,
+ .led_color_b = led_on ? sc->led_color.b : 0,
+ };
+
+ return (hid_write(sc->hm.dev, buf, sizeof(buf)));
+}
+
+static int
+ps5ds_blank(struct ps5ds_softc *sc)
+{
+ uint8_t buf[PS5DS_OUTPUT_REPORT2_SIZE];
+
+ memset(buf, 0, sizeof(buf));
+ buf[0] = 0x02;
+ *(struct ps5ds_out2 *)(buf + 1) = (struct ps5ds_out2) {
+ .valid_flag1 = PS5DS_FLAG1_LIGHTBAR | PS5DS_FLAG1_PLAYER_LEDS,
+ .valid_flag2 = PS5DS_FLAG2_LIGHTBAR_SETUP,
+ .lightbar_setup = PS5DS_LIGHTBAR_FADE_OUT,
+ };
+
+ return (hid_write(sc->hm.dev, buf, sizeof(buf)));
+}
+
+static int
+ps5ds_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct ps5ds_softc *sc;
+ int error, arg;
+
+ if (oidp->oid_arg1 == NULL || oidp->oid_arg2 < 0 ||
+ oidp->oid_arg2 > PS5DS_SYSCTL_LAST)
+ return (EINVAL);
+
+ sc = oidp->oid_arg1;
+ sx_xlock(&sc->lock);
+
+ arg = *(int *)((char *)sc + oidp->oid_arg2);
+ error = sysctl_handle_int(oidp, &arg, 0, req);
+
+ if (error || !req->newptr)
+ goto unlock;
+
+ switch (oidp->oid_arg2) {
+ case PS5DS_SYSCTL_LED_STATE:
+ if (arg < 0 || arg >= PS5DS_LED_CNT)
+ error = EINVAL;
+ break;
+ case PS5DS_SYSCTL_LED_COLOR_R:
+ case PS5DS_SYSCTL_LED_COLOR_G:
+ case PS5DS_SYSCTL_LED_COLOR_B:
+ if (arg < 0 || arg > UINT8_MAX)
+ error = EINVAL;
+ break;
+ case PS5DS_SYSCTL_PLAYER_LEDS:
+ if (arg < -1 || arg >= (int)nitems(ps5ds_player_leds))
+ error = EINVAL;
+ break;
+ default:
+ error = EINVAL;
+ }
+
+ if (error == 0) {
+ *(int *)((char *)sc + oidp->oid_arg2) = arg;
+ ps5ds_write(sc);
+ }
+unlock:
+ sx_unlock(&sc->lock);
+
+ return (error);
+}
+
+static void
+ps5ds_identify(driver_t *driver, device_t parent)
+{
+
+ /* Replace the gamepad's rudimentary report descriptor */
+ if (HIDBUS_LOOKUP_ID(parent, ps5ds_devs) != NULL)
+ hid_set_report_descr(parent, ps5ds_rdesc,
+ sizeof(ps5ds_rdesc));
+}
+
+static int
+ps5ds_probe(device_t dev)
+{
+ struct ps5ds_softc *sc = device_get_softc(dev);
+
+ hidmap_set_debug_var(&sc->hm, &HID_DEBUG_VAR);
+ return (
+ HIDMAP_PROBE(&sc->hm, dev, ps5ds_devs, ps5ds_map, NULL)
+ );
+}
+
+static int
+ps5ds_attach(device_t dev)
+{
+ struct ps5ds_softc *sc = device_get_softc(dev);
+ struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
+ struct sysctl_oid *tree = device_get_sysctl_tree(dev);
+ int error, unit;
+
+ sx_init(&sc->lock, "ps5dsense");
+
+ unit = device_get_unit(dev);
+ sc->led_state = PS5DS_LED_ON;
+ sc->led_color = ps5ds_leds[unit % nitems(ps5ds_leds)];
+ sc->player_leds = unit < (int)nitems(ps5ds_player_leds) ? unit : -1;
+
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "led_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
+ PS5DS_SYSCTL_LED_STATE, ps5ds_sysctl, "I",
+ "LED state: 0 - off, 1 - on.");
+
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "led_color_r", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
+ PS5DS_SYSCTL_LED_COLOR_R, ps5ds_sysctl, "I",
+ "Lightbar color. Red component.");
+
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "led_color_g", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
+ PS5DS_SYSCTL_LED_COLOR_G, ps5ds_sysctl, "I",
+ "Lightbar color. Green component.");
+
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "led_color_b", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
+ PS5DS_SYSCTL_LED_COLOR_B, ps5ds_sysctl, "I",
+ "Lightbar color. Blue component.");
+
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "player_leds", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
+ PS5DS_SYSCTL_PLAYER_LEDS, ps5ds_sysctl, "I",
+ "Player indicator LEDs: -1 - off, 0-4 - player number.");
+
+ error = hidmap_attach(&sc->hm);
+ if (error) {
+ sx_destroy(&sc->lock);
+ return (error);
+ }
+
+ sx_xlock(&sc->lock);
+ ps5ds_write(sc);
+ sx_xunlock(&sc->lock);
+
+ return (0);
+}
+
+static int
+ps5ds_detach(device_t dev)
+{
+ struct ps5ds_softc *sc = device_get_softc(dev);
+ int error;
+
+ error = hidmap_detach(&sc->hm);
+ if (error)
+ return (error);
+
+ ps5ds_blank(sc);
+ sx_destroy(&sc->lock);
+
+ return (0);
+}
+
+static device_method_t ps5ds_methods[] = {
+ DEVMETHOD(device_identify, ps5ds_identify),
+ DEVMETHOD(device_probe, ps5ds_probe),
+ DEVMETHOD(device_attach, ps5ds_attach),
+ DEVMETHOD(device_detach, ps5ds_detach),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(ps5dsense, ps5ds_driver, ps5ds_methods,
+ sizeof(struct ps5ds_softc));
+DRIVER_MODULE(ps5dsense, hidbus, ps5ds_driver, NULL, NULL);
+
+MODULE_DEPEND(ps5dsense, hid, 1, 1, 1);
+MODULE_DEPEND(ps5dsense, hidbus, 1, 1, 1);
+MODULE_DEPEND(ps5dsense, hidmap, 1, 1, 1);
+MODULE_DEPEND(ps5dsense, hgame, 1, 1, 1);
+MODULE_DEPEND(ps5dsense, evdev, 1, 1, 1);
+MODULE_VERSION(ps5dsense, 1);
+HID_PNP_INFO(ps5ds_devs);
diff --git a/sys/modules/hid/Makefile b/sys/modules/hid/Makefile
--- a/sys/modules/hid/Makefile
+++ b/sys/modules/hid/Makefile
@@ -20,6 +20,7 @@
hsctrl \
ietp \
ps4dshock \
+ ps5dsense \
u2f \
xb360gp
diff --git a/sys/modules/hid/ps5dsense/Makefile b/sys/modules/hid/ps5dsense/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/hid/ps5dsense/Makefile
@@ -0,0 +1,8 @@
+.PATH: ${SRCTOP}/sys/dev/hid
+
+KMOD= ps5dsense
+SRCS= ps5dsense.c
+SRCS+= opt_hid.h opt_kbd.h
+SRCS+= bus_if.h device_if.h usbdevs.h
+
+.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Sep 6, 2:54 PM (8 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38376616
Default Alt Text
D56345.id.diff (19 KB)
Attached To
Mode
D56345: hid: Add Sony DualSense gamepad driver
Attached
Detach File
Event Timeline
Log In to Comment