aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Kondratyev <wulf@FreeBSD.org>2020-10-14 22:02:15 +0000
committerVladimir Kondratyev <wulf@FreeBSD.org>2021-01-07 23:18:44 +0000
commitd97d5c0ce89da10c1de150e0555774dec2ed7aed (patch)
treeb57ee644dca1fdefe4ca72eaf43078fafaeced7a
parentafd590d9e56686e179cbbf626ec567aeaaa49199 (diff)
downloadsrc-d97d5c0ce89da10c1de150e0555774dec2ed7aed.tar.gz
src-d97d5c0ce89da10c1de150e0555774dec2ed7aed.zip
hid: Import hidmap-based drivers written by Greg V
This change includes: hpen - Generic / MS Windows compatible HID pen tablet driver. hgame - Generic game controller and joystick driver. xb360gp - Xbox360-compatible game controller driver. Submitted by: Greg V <greg_unrelenting.technology> Reviewed by: hselasky (as part of D27993)
-rw-r--r--share/man/man4/Makefile3
-rw-r--r--share/man/man4/hgame.4105
-rw-r--r--share/man/man4/hpen.4112
-rw-r--r--share/man/man4/xb360gp.498
-rw-r--r--sys/conf/files3
-rw-r--r--sys/dev/hid/hgame.c200
-rw-r--r--sys/dev/hid/hgame.h45
-rw-r--r--sys/dev/hid/hpen.c256
-rw-r--r--sys/dev/hid/xb360gp.c183
-rw-r--r--sys/modules/hid/Makefile5
-rw-r--r--sys/modules/hid/hgame/Makefile9
-rw-r--r--sys/modules/hid/hpen/Makefile9
-rw-r--r--sys/modules/hid/xb360gp/Makefile9
13 files changed, 1036 insertions, 1 deletions
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 60c1b5f19a9b..b905d97d80d0 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -181,6 +181,7 @@ MAN= aac.4 \
h_ertt.4 \
hconf.4 \
hcons.4 \
+ hgame.4 \
hidbus.4 \
hidquirk.4 \
hidraw.4 \
@@ -188,6 +189,7 @@ MAN= aac.4 \
hkbd.4 \
hms.4 \
hmt.4 \
+ hpen.4 \
hpet.4 \
${_hpt27xx.4} \
${_hptiop.4} \
@@ -592,6 +594,7 @@ MAN= aac.4 \
wmt.4 \
${_wpi.4} \
wsp.4 \
+ xb360gp.4 \
${_xen.4} \
xhci.4 \
xl.4 \
diff --git a/share/man/man4/hgame.4 b/share/man/man4/hgame.4
new file mode 100644
index 000000000000..addf14d9f5c5
--- /dev/null
+++ b/share/man/man4/hgame.4
@@ -0,0 +1,105 @@
+.\" Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
+.\"
+.\" 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 14, 2020
+.Dt HGAME 4
+.Os
+.Sh NAME
+.Nm hgame
+.Nd Generic HID game controller (joystick/gamepad) driver
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device hgame"
+.Cd "device hid"
+.Cd "device hidbus"
+.Cd "device hidmap"
+.Cd "device evdev"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+hgame_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for generic game controllers (joysticks/gamepads)
+that attach to the HID transport backend.
+See
+.Xr iichid 4
+or
+.Xr usbhid 4 .
+.Pp
+The
+.Pa /dev/input/event*
+device presents the game controller as a
+.Ar evdev
+type device.
+.Sh SYSCTL VARIABLES
+The following variable is available as both
+.Xr sysctl 8
+variable and
+.Xr loader 8
+tunable:
+.Bl -tag -width indent
+.It Va dev.hgame.X.debug
+Debug output level, where 0 is debugging disabled and larger values increase
+debug message verbosity.
+Default is 0.
+.El
+.Pp
+It's default value is set with
+.Xr loader 8
+tunable:
+.Bl -tag -width indent
+.It Va hw.hid.hgame.debug
+.El
+.Sh FILES
+.Bl -tag -width /dev/input/event* -compact
+.It Pa /dev/input/event*
+input event device node.
+.El
+.Sh SEE ALSO
+.Xr iichid 4 ,
+.Xr usbhid 4
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 13.0.
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Greg V Aq Mt greg@unrelenting.technology .
+.Pp
+This manual page was written by
+.An Vladimir Kondratyev Aq Mt wulf@FreeBSD.org .
diff --git a/share/man/man4/hpen.4 b/share/man/man4/hpen.4
new file mode 100644
index 000000000000..a043169895ec
--- /dev/null
+++ b/share/man/man4/hpen.4
@@ -0,0 +1,112 @@
+.\" Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
+.\"
+.\" 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 14, 2020
+.Dt HPEN 4
+.Os
+.Sh NAME
+.Nm hpen
+.Nd MS Windows compatible HID pen tablet driver
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device hpen"
+.Cd "device hid"
+.Cd "device hidbus"
+.Cd "device hidmap"
+.Cd "device evdev"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+hpen_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for generic MS Windows compatible HID pen tablet
+and digitizer that attach to the HID transport backend.
+See
+.Xr iichid 4
+or
+.Xr usbhid 4 .
+.Pp
+The
+.Pa /dev/input/event*
+device presents the pen as a
+.Ar evdev
+type device.
+.Sh SYSCTL VARIABLES
+The following variable is available as both
+.Xr sysctl 8
+variable and
+.Xr loader 8
+tunable:
+.Bl -tag -width indent
+.It Va dev.hpen.X.debug
+Debug output level, where 0 is debugging disabled and larger values increase
+debug message verbosity.
+Default is 0.
+.El
+.Pp
+It's default value is set with
+.Xr loader 8
+tunable:
+.Bl -tag -width indent
+.It Va hw.hid.hpen.debug
+.El
+.Sh FILES
+.Bl -tag -width /dev/input/event* -compact
+.It Pa /dev/input/event*
+input event device node.
+.El
+.Sh SEE ALSO
+.Xr iichid 4 ,
+.Xr usbhid 4 ,
+.Xr xorg.conf 5 Pq Pa ports/x11/xorg
+.Sh BUGS
+.Nm
+cannot act like
+.Xr sysmouse 4 .
+.Pp
+Pen battery charge level reporting is not supported.
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 13.0.
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Greg V Aq Mt greg@unrelenting.technology .
+.Pp
+This manual page was written by
+.An Vladimir Kondratyev Aq Mt wulf@FreeBSD.org .
diff --git a/share/man/man4/xb360gp.4 b/share/man/man4/xb360gp.4
new file mode 100644
index 000000000000..b19334cc3a0b
--- /dev/null
+++ b/share/man/man4/xb360gp.4
@@ -0,0 +1,98 @@
+.\" Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
+.\"
+.\" 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 16, 2020
+.Dt XB360GP 4
+.Os
+.Sh NAME
+.Nm xb360gp
+.Nd XBox 360 gamepad driver
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device xb360gp"
+.Cd "device hgame"
+.Cd "device hid"
+.Cd "device hidbus"
+.Cd "device hidmap"
+.Cd "device evdev"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+xb360gp_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for XBox 360 gamepad driver.
+.Pp
+The
+.Pa /dev/input/event*
+device presents the game controller as a
+.Ar evdev
+type device.
+.Sh SYSCTL VARIABLES
+The following variable is available as both
+.Xr sysctl 8
+variable and
+.Xr loader 8
+tunable:
+.Bl -tag -width indent
+.It Va dev.xb360gp.X.debug
+Debug output level, where 0 is debugging disabled and larger values increase
+debug message verbosity.
+Default is 0.
+.El
+.Pp
+It's default value is set with
+.Xr loader 8
+tunable:
+.Bl -tag -width indent
+.It Va hw.hid.xb360gp.debug
+.El
+.Sh FILES
+.Bl -tag -width /dev/input/event* -compact
+.It Pa /dev/input/event*
+input event device node.
+.El
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 13.0.
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Greg V Aq Mt greg@unrelenting.technology .
+.Pp
+This manual page was written by
+.An Vladimir Kondratyev Aq Mt wulf@FreeBSD.org .
diff --git a/sys/conf/files b/sys/conf/files
index 31a06150a329..6597d9e471a4 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1817,6 +1817,7 @@ dev/gpio/gpiopps.c optional gpiopps fdt
dev/gpio/ofw_gpiobus.c optional fdt gpio
dev/hid/hconf.c optional hconf
dev/hid/hcons.c optional hcons
+dev/hid/hgame.c optional hgame
dev/hid/hid.c optional hid
dev/hid/hid_if.m optional hid
dev/hid/hidbus.c optional hidbus
@@ -1826,8 +1827,10 @@ dev/hid/hidraw.c optional hidraw
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/hsctrl.c optional hsctrl
dev/hid/ps4dshock.c optional ps4dshock
+dev/hid/xb360gp.c optional xb360gp
dev/hifn/hifn7751.c optional hifn
dev/hptiop/hptiop.c optional hptiop scbus
dev/hwpmc/hwpmc_logging.c optional hwpmc
diff --git a/sys/dev/hid/hgame.c b/sys/dev/hid/hgame.c
new file mode 100644
index 000000000000..099af092a4e5
--- /dev/null
+++ b/sys/dev/hid/hgame.c
@@ -0,0 +1,200 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
+ * Copyright (c) 2020 Greg V <greg@unrelenting.technology>
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Generic HID game controller (joystick/gamepad) driver,
+ */
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+
+#include <dev/evdev/input.h>
+#include <dev/evdev/evdev.h>
+
+#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>
+
+#define HGAME_MAP_BRG(number_from, number_to, code) \
+ { HIDMAP_KEY_RANGE(HUP_BUTTON, number_from, number_to, code) }
+#define HGAME_MAP_ABS(usage, code) \
+ { HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code) }
+#define HGAME_MAP_CRG(usage_from, usage_to, callback) \
+ { HIDMAP_ANY_CB_RANGE(HUP_GENERIC_DESKTOP, \
+ HUG_##usage_from, HUG_##usage_to, callback) }
+#define HGAME_FINALCB(cb) \
+ { HIDMAP_FINAL_CB(&cb) }
+
+static const struct hidmap_item hgame_map[] = {
+ HGAME_MAP_BRG(1, 16, BTN_TRIGGER),
+ HGAME_MAP_ABS(X, ABS_X),
+ HGAME_MAP_ABS(Y, ABS_Y),
+ HGAME_MAP_ABS(Z, ABS_Z),
+ HGAME_MAP_ABS(RX, ABS_RX),
+ HGAME_MAP_ABS(RY, ABS_RY),
+ HGAME_MAP_ABS(RZ, ABS_RZ),
+ HGAME_MAP_ABS(HAT_SWITCH, ABS_HAT0X),
+ HGAME_MAP_CRG(D_PAD_UP, D_PAD_LEFT, hgame_dpad_cb),
+ HGAME_MAP_BRG(17, 57, BTN_TRIGGER_HAPPY),
+ HGAME_FINALCB( hgame_final_cb),
+};
+
+static const struct hid_device_id hgame_devs[] = {
+ { HID_TLC(HUP_GENERIC_DESKTOP, HUG_JOYSTICK),
+ HID_DRIVER_INFO(HUG_JOYSTICK) },
+ { HID_TLC(HUP_GENERIC_DESKTOP, HUG_GAME_PAD),
+ HID_DRIVER_INFO(HUG_GAME_PAD) },
+};
+
+/*
+ * Emulate the hat switch report via the D-pad usages
+ * found on XInput/XBox style devices
+ */
+int
+hgame_dpad_cb(HIDMAP_CB_ARGS)
+{
+ struct hgame_softc *sc = HIDMAP_CB_GET_SOFTC();
+ struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
+ int32_t data;
+
+ switch (HIDMAP_CB_GET_STATE()) {
+ case HIDMAP_CB_IS_ATTACHING:
+ HIDMAP_CB_UDATA64 = HID_GET_USAGE(ctx.hi->usage);
+ evdev_support_event(evdev, EV_ABS);
+ evdev_support_abs(evdev, ABS_HAT0X, -1, 1, 0, 0, 0);
+ evdev_support_abs(evdev, ABS_HAT0Y, -1, 1, 0, 0, 0);
+ break;
+
+ case HIDMAP_CB_IS_RUNNING:
+ data = ctx.data;
+ switch (HIDMAP_CB_UDATA64) {
+ case HUG_D_PAD_UP:
+ if (sc->dpad_down)
+ return (ENOMSG);
+ evdev_push_abs(evdev, ABS_HAT0Y, (data == 0) ? 0 : -1);
+ sc->dpad_up = (data != 0);
+ break;
+ case HUG_D_PAD_DOWN:
+ if (sc->dpad_up)
+ return (ENOMSG);
+ evdev_push_abs(evdev, ABS_HAT0Y, (data == 0) ? 0 : 1);
+ sc->dpad_down = (data != 0);
+ break;
+ case HUG_D_PAD_RIGHT:
+ if (sc->dpad_left)
+ return (ENOMSG);
+ evdev_push_abs(evdev, ABS_HAT0X, (data == 0) ? 0 : 1);
+ sc->dpad_right = (data != 0);
+ break;
+ case HUG_D_PAD_LEFT:
+ if (sc->dpad_right)
+ return (ENOMSG);
+ evdev_push_abs(evdev, ABS_HAT0X, (data == 0) ? 0 : -1);
+ sc->dpad_left = (data != 0);
+ break;
+ }
+ }
+
+ return (0);
+}
+
+int
+hgame_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);
+
+ /* Do not execute callback at interrupt handler and detach */
+ return (ENOSYS);
+}
+
+static int
+hgame_probe(device_t dev)
+{
+ const struct hid_device_info *hw = hid_get_device_info(dev);
+ struct hgame_softc *sc = device_get_softc(dev);
+ int error;
+
+ if (hid_test_quirk(hw, HQ_IS_XBOX360GP))
+ return(ENXIO);
+
+ error = HIDMAP_PROBE(&sc->hm, dev, hgame_devs, hgame_map, NULL);
+ if (error > 0)
+ return (error);
+
+ hidbus_set_desc(dev, hidbus_get_driver_info(dev) == HUG_GAME_PAD ?
+ "Gamepad" : "Joystick");
+
+ return (BUS_PROBE_GENERIC);
+}
+
+
+
+static int
+hgame_attach(device_t dev)
+{
+ struct hgame_softc *sc = device_get_softc(dev);
+
+ return (hidmap_attach(&sc->hm));
+}
+
+static int
+hgame_detach(device_t dev)
+{
+ struct hgame_softc *sc = device_get_softc(dev);
+
+ return (hidmap_detach(&sc->hm));
+}
+
+static devclass_t hgame_devclass;
+static device_method_t hgame_methods[] = {
+ DEVMETHOD(device_probe, hgame_probe),
+ DEVMETHOD(device_attach, hgame_attach),
+ DEVMETHOD(device_detach, hgame_detach),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(hgame, hgame_driver, hgame_methods, sizeof(struct hgame_softc));
+DRIVER_MODULE(hgame, hidbus, hgame_driver, hgame_devclass, NULL, 0);
+MODULE_DEPEND(hgame, hid, 1, 1, 1);
+MODULE_DEPEND(hgame, hidbus, 1, 1, 1);
+MODULE_DEPEND(hgame, hidmap, 1, 1, 1);
+MODULE_DEPEND(hgame, evdev, 1, 1, 1);
+MODULE_VERSION(hgame, 1);
+HID_PNP_INFO(hgame_devs);
diff --git a/sys/dev/hid/hgame.h b/sys/dev/hid/hgame.h
new file mode 100644
index 000000000000..32086ec4923c
--- /dev/null
+++ b/sys/dev/hid/hgame.h
@@ -0,0 +1,45 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
+ * Copyright (c) 2020 Greg V <greg@unrelenting.technology>
+ *
+ * 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.
+ */
+
+#ifndef _HID_HGAME_H_
+#define _HID_HGAME_H_
+
+#include <dev/hid/hidmap.h>
+
+hidmap_cb_t hgame_dpad_cb;
+hidmap_cb_t hgame_final_cb;
+
+struct hgame_softc {
+ struct hidmap hm;
+ bool dpad_up;
+ bool dpad_down;
+ bool dpad_right;
+ bool dpad_left;
+};
+
+#endif /* !_HGAME_H_ */
diff --git a/sys/dev/hid/hpen.c b/sys/dev/hid/hpen.c
new file mode 100644
index 000000000000..430461d87727
--- /dev/null
+++ b/sys/dev/hid/hpen.c
@@ -0,0 +1,256 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2019 Vladimir Kondratyev <wulf@FreeBSD.org>
+ * Copyright (c) 2019 Greg V <greg@unrelenting.technology>
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Generic / MS Windows compatible HID pen tablet driver:
+ * https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/required-hid-top-level-collections
+ *
+ * Tested on: Wacom WCOM50C1 (Google Pixelbook "eve")
+ */
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+
+#include <dev/evdev/input.h>
+#include <dev/evdev/evdev.h>
+
+#include <dev/hid/hid.h>
+#include <dev/hid/hidbus.h>
+#include <dev/hid/hidmap.h>
+#include <dev/hid/hidrdesc.h>
+
+#include "usbdevs.h"
+
+static const uint8_t hpen_graphire_report_descr[] =
+ { HID_GRAPHIRE_REPORT_DESCR() };
+static const uint8_t hpen_graphire3_4x5_report_descr[] =
+ { HID_GRAPHIRE3_4X5_REPORT_DESCR() };
+
+static hidmap_cb_t hpen_battery_strenght_cb;
+static hidmap_cb_t hpen_final_digi_cb;
+static hidmap_cb_t hpen_final_pen_cb;
+
+#define HPEN_MAP_BUT(usage, code) \
+ HIDMAP_KEY(HUP_DIGITIZERS, HUD_##usage, code)
+#define HPEN_MAP_ABS(usage, code) \
+ HIDMAP_ABS(HUP_DIGITIZERS, HUD_##usage, code)
+#define HPEN_MAP_ABS_GD(usage, code) \
+ HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code)
+#define HPEN_MAP_ABS_CB(usage, cb) \
+ HIDMAP_ABS_CB(HUP_DIGITIZERS, HUD_##usage, &cb)
+
+/* Generic map digitizer page map according to hut1_12v2.pdf */
+static const struct hidmap_item hpen_map_digi[] = {
+ { HPEN_MAP_ABS_GD(X, ABS_X), .required = true },
+ { HPEN_MAP_ABS_GD(Y, ABS_Y), .required = true },
+ { HPEN_MAP_ABS( TIP_PRESSURE, ABS_PRESSURE) },
+ { HPEN_MAP_ABS( X_TILT, ABS_TILT_X) },
+ { HPEN_MAP_ABS( Y_TILT, ABS_TILT_Y) },
+ { HPEN_MAP_ABS_CB(BATTERY_STRENGTH, hpen_battery_strenght_cb) },
+ { HPEN_MAP_BUT( TOUCH, BTN_TOUCH) },
+ { HPEN_MAP_BUT( TIP_SWITCH, BTN_TOUCH) },
+ { HPEN_MAP_BUT( SEC_TIP_SWITCH, BTN_TOUCH) },
+ { HPEN_MAP_BUT( IN_RANGE, BTN_TOOL_PEN) },
+ { HPEN_MAP_BUT( BARREL_SWITCH, BTN_STYLUS) },
+ { HPEN_MAP_BUT( INVERT, BTN_TOOL_RUBBER) },
+ { HPEN_MAP_BUT( ERASER, BTN_TOUCH) },
+ { HPEN_MAP_BUT( TABLET_PICK, BTN_STYLUS2) },
+ { HPEN_MAP_BUT( SEC_BARREL_SWITCH,BTN_STYLUS2) },
+ { HIDMAP_FINAL_CB( &hpen_final_digi_cb) },
+};
+
+/* Microsoft-standardized pen support */
+static const struct hidmap_item hpen_map_pen[] = {
+ { HPEN_MAP_ABS_GD(X, ABS_X), .required = true },
+ { HPEN_MAP_ABS_GD(Y, ABS_Y), .required = true },
+ { HPEN_MAP_ABS( TIP_PRESSURE, ABS_PRESSURE), .required = true },
+ { HPEN_MAP_ABS( X_TILT, ABS_TILT_X) },
+ { HPEN_MAP_ABS( Y_TILT, ABS_TILT_Y) },
+ { HPEN_MAP_ABS_CB(BATTERY_STRENGTH, hpen_battery_strenght_cb) },
+ { HPEN_MAP_BUT( TIP_SWITCH, BTN_TOUCH), .required = true },
+ { HPEN_MAP_BUT( IN_RANGE, BTN_TOOL_PEN), .required = true },
+ { HPEN_MAP_BUT( BARREL_SWITCH, BTN_STYLUS) },
+ { HPEN_MAP_BUT( INVERT, BTN_TOOL_RUBBER), .required = true },
+ { HPEN_MAP_BUT( ERASER, BTN_TOUCH), .required = true },
+ { HIDMAP_FINAL_CB( &hpen_final_pen_cb) },
+};
+
+static const struct hid_device_id hpen_devs[] = {
+ { HID_TLC(HUP_DIGITIZERS, HUD_DIGITIZER) },
+ { HID_TLC(HUP_DIGITIZERS, HUD_PEN) },
+};
+
+static int
+hpen_battery_strenght_cb(HIDMAP_CB_ARGS)
+{
+ struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
+ int32_t data;
+
+ switch (HIDMAP_CB_GET_STATE()) {
+ case HIDMAP_CB_IS_ATTACHING:
+ evdev_support_event(evdev, EV_PWR);
+ /* TODO */
+ break;
+ case HIDMAP_CB_IS_RUNNING:
+ data = ctx.data;
+ /* TODO */
+ }
+
+ return (0);
+}
+
+static int
+hpen_final_digi_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_POINTER);
+
+ /* Do not execute callback at interrupt handler and detach */
+ return (ENOSYS);
+}
+
+static int
+hpen_final_pen_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);
+
+ /* Do not execute callback at interrupt handler and detach */
+ return (ENOSYS);
+}
+
+static void
+hpen_identify(driver_t *driver, device_t parent)
+{
+ const struct hid_device_info *hw = hid_get_device_info(parent);
+
+ /* the report descriptor for the Wacom Graphire is broken */
+ if (hw->idBus == BUS_USB && hw->idVendor == USB_VENDOR_WACOM) {
+ switch (hw->idProduct) {
+ case USB_PRODUCT_WACOM_GRAPHIRE:
+ hid_set_report_descr(parent,
+ hpen_graphire_report_descr,
+ sizeof(hpen_graphire_report_descr));
+ break;
+
+ case USB_PRODUCT_WACOM_GRAPHIRE3_4X5:
+ hid_set_report_descr(parent,
+ hpen_graphire3_4x5_report_descr,
+ sizeof(hpen_graphire3_4x5_report_descr));
+ break;
+ }
+ }
+}
+
+static int
+hpen_probe(device_t dev)
+{
+ struct hidmap *hm = device_get_softc(dev);
+ int error;
+ bool is_pen;
+
+ error = HIDBUS_LOOKUP_DRIVER_INFO(dev, hpen_devs);
+ if (error != 0)
+ return (error);
+
+ hidmap_set_dev(hm, dev);
+
+ /* Check if report descriptor belongs to a HID tablet device */
+ is_pen = hidbus_get_usage(dev) == HID_USAGE2(HUP_DIGITIZERS, HUD_PEN);
+ error = is_pen
+ ? HIDMAP_ADD_MAP(hm, hpen_map_pen, NULL)
+ : HIDMAP_ADD_MAP(hm, hpen_map_digi, NULL);
+ if (error != 0)
+ return (error);
+
+ hidbus_set_desc(dev, is_pen ? "Pen" : "Digitizer");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+hpen_attach(device_t dev)
+{
+ const struct hid_device_info *hw = hid_get_device_info(dev);
+ struct hidmap *hm = device_get_softc(dev);
+ int error;
+
+ if (hw->idBus == BUS_USB && hw->idVendor == USB_VENDOR_WACOM &&
+ hw->idProduct == USB_PRODUCT_WACOM_GRAPHIRE3_4X5) {
+ /*
+ * The Graphire3 needs 0x0202 to be written to
+ * feature report ID 2 before it'll start
+ * returning digitizer data.
+ */
+ static const uint8_t reportbuf[3] = {2, 2, 2};
+ error = hid_set_report(dev, reportbuf, sizeof(reportbuf),
+ HID_FEATURE_REPORT, reportbuf[0]);
+ if (error)
+ device_printf(dev, "set feature report failed, "
+ "error=%d (ignored)\n", error);
+ }
+
+ return (hidmap_attach(hm));
+}
+
+static int
+hpen_detach(device_t dev)
+{
+ return (hidmap_detach(device_get_softc(dev)));
+}
+
+
+static devclass_t hpen_devclass;
+static device_method_t hpen_methods[] = {
+ DEVMETHOD(device_identify, hpen_identify),
+ DEVMETHOD(device_probe, hpen_probe),
+ DEVMETHOD(device_attach, hpen_attach),
+ DEVMETHOD(device_detach, hpen_detach),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(hpen, hpen_driver, hpen_methods, sizeof(struct hidmap));
+DRIVER_MODULE(hpen, hidbus, hpen_driver, hpen_devclass, NULL, 0);
+MODULE_DEPEND(hpen, hid, 1, 1, 1);
+MODULE_DEPEND(hpen, hidbus, 1, 1, 1);
+MODULE_DEPEND(hpen, hidmap, 1, 1, 1);
+MODULE_DEPEND(hpen, evdev, 1, 1, 1);
+MODULE_VERSION(hpen, 1);
+HID_PNP_INFO(hpen_devs);
diff --git a/sys/dev/hid/xb360gp.c b/sys/dev/hid/xb360gp.c
new file mode 100644
index 000000000000..f255c110f47c
--- /dev/null
+++ b/sys/dev/hid/xb360gp.c
@@ -0,0 +1,183 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
+ * Copyright (c) 2020 Greg V <greg@unrelenting.technology>
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * XBox 360 gamepad driver thanks to the custom descriptor in usbhid.
+ *
+ * Tested on: SVEN GC-5070 in both XInput (XBox 360) and DirectInput modes
+ */
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+
+#include <dev/evdev/input.h>
+#include <dev/evdev/evdev.h>
+
+#include <dev/hid/hgame.h>
+#include <dev/hid/hid.h>
+#include <dev/hid/hidbus.h>
+#include <dev/hid/hidmap.h>
+#include <dev/hid/hidquirk.h>
+#include <dev/hid/hidrdesc.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+static const uint8_t xb360gp_rdesc[] = {HID_XB360GP_REPORT_DESCR()};
+
+#define XB360GP_MAP_BUT(number, code) \
+ { HIDMAP_KEY(HUP_BUTTON, number, code) }
+#define XB360GP_MAP_ABS(usage, code) \
+ { HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code) }
+#define XB360GP_MAP_ABS_FLT(usage, code) \
+ { HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code), \
+ .fuzz = 16, .flat = 128 }
+#define XB360GP_MAP_ABS_INV(usage, code) \
+ { HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code), \
+ .fuzz = 16, .flat = 128, .invert_value = true }
+#define XB360GP_MAP_CRG(usage_from, usage_to, callback) \
+ { HIDMAP_ANY_CB_RANGE(HUP_GENERIC_DESKTOP, \
+ HUG_##usage_from, HUG_##usage_to, callback) }
+#define XB360GP_FINALCB(cb) \
+ { HIDMAP_FINAL_CB(&cb) }
+
+/* Customized to match usbhid's XBox 360 descriptor */
+static const struct hidmap_item xb360gp_map[] = {
+ XB360GP_MAP_BUT(1, BTN_SOUTH),
+ XB360GP_MAP_BUT(2, BTN_EAST),
+ XB360GP_MAP_BUT(3, BTN_WEST),
+ XB360GP_MAP_BUT(4, BTN_NORTH),
+ XB360GP_MAP_BUT(5, BTN_TL),
+ XB360GP_MAP_BUT(6, BTN_TR),
+ XB360GP_MAP_BUT(7, BTN_SELECT),
+ XB360GP_MAP_BUT(8, BTN_START),
+ XB360GP_MAP_BUT(9, BTN_THUMBL),
+ XB360GP_MAP_BUT(10, BTN_THUMBR),
+ XB360GP_MAP_BUT(11, BTN_MODE),
+ XB360GP_MAP_CRG(D_PAD_UP, D_PAD_LEFT, hgame_dpad_cb),
+ XB360GP_MAP_ABS_FLT(X, ABS_X),
+ XB360GP_MAP_ABS_INV(Y, ABS_Y),
+ XB360GP_MAP_ABS(Z, ABS_Z),
+ XB360GP_MAP_ABS_FLT(RX, ABS_RX),
+ XB360GP_MAP_ABS_INV(RY, ABS_RY),
+ XB360GP_MAP_ABS(RZ, ABS_RZ),
+ XB360GP_FINALCB( hgame_final_cb),
+};
+
+static const STRUCT_USB_HOST_ID xb360gp_devs[] = {
+ /* the Xbox 360 gamepad doesn't use the HID class */
+ {USB_IFACE_CLASS(UICLASS_VENDOR),
+ USB_IFACE_SUBCLASS(UISUBCLASS_XBOX360_CONTROLLER),
+ USB_IFACE_PROTOCOL(UIPROTO_XBOX360_GAMEPAD),},
+};
+
+static void
+xb360gp_identify(driver_t *driver, device_t parent)
+{
+ const struct hid_device_info *hw = hid_get_device_info(parent);
+
+ /* the Xbox 360 gamepad has no report descriptor */
+ if (hid_test_quirk(hw, HQ_IS_XBOX360GP))
+ hid_set_report_descr(parent, xb360gp_rdesc,
+ sizeof(xb360gp_rdesc));
+}
+
+static int
+xb360gp_probe(device_t dev)
+{
+ struct hgame_softc *sc = device_get_softc(dev);
+ const struct hid_device_info *hw = hid_get_device_info(dev);
+ int error;
+
+ if (!hid_test_quirk(hw, HQ_IS_XBOX360GP))
+ return (ENXIO);
+
+ hidmap_set_dev(&sc->hm, dev);
+
+ error = HIDMAP_ADD_MAP(&sc->hm, xb360gp_map, NULL);
+ if (error != 0)
+ return (error);
+
+ device_set_desc(dev, "XBox 360 Gamepad");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+xb360gp_attach(device_t dev)
+{
+ struct hgame_softc *sc = device_get_softc(dev);
+ int error;
+
+ /*
+ * Turn off the four LEDs on the gamepad which
+ * are blinking by default:
+ */
+ static const uint8_t reportbuf[3] = {1, 3, 0};
+ error = hid_set_report(dev, reportbuf, sizeof(reportbuf),
+ HID_OUTPUT_REPORT, 0);
+ if (error)
+ device_printf(dev, "set output report failed, error=%d "
+ "(ignored)\n", error);
+
+ return (hidmap_attach(&sc->hm));
+}
+
+static int
+xb360gp_detach(device_t dev)
+{
+ struct hgame_softc *sc = device_get_softc(dev);
+
+ return (hidmap_detach(&sc->hm));
+}
+
+static devclass_t xb360gp_devclass;
+static device_method_t xb360gp_methods[] = {
+ DEVMETHOD(device_identify, xb360gp_identify),
+ DEVMETHOD(device_probe, xb360gp_probe),
+ DEVMETHOD(device_attach, xb360gp_attach),
+ DEVMETHOD(device_detach, xb360gp_detach),
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(xb360gp, xb360gp_driver, xb360gp_methods,
+ sizeof(struct hgame_softc));
+DRIVER_MODULE(xb360gp, hidbus, xb360gp_driver, xb360gp_devclass, NULL, 0);
+MODULE_DEPEND(xb360gp, hid, 1, 1, 1);
+MODULE_DEPEND(xb360gp, hidbus, 1, 1, 1);
+MODULE_DEPEND(xb360gp, hidmap, 1, 1, 1);
+MODULE_DEPEND(xb360gp, hgame, 1, 1, 1);
+MODULE_DEPEND(xb360gp, evdev, 1, 1, 1);
+MODULE_VERSION(xb360gp, 1);
+USB_PNP_HOST_INFO(xb360gp_devs);
diff --git a/sys/modules/hid/Makefile b/sys/modules/hid/Makefile
index 20ae0b3b9302..7d5515480bc0 100644
--- a/sys/modules/hid/Makefile
+++ b/sys/modules/hid/Makefile
@@ -10,10 +10,13 @@ SUBDIR = \
SUBDIR += \
hconf \
hcons \
+ hgame \
hkbd \
hms \
hmt \
+ hpen \
hsctrl \
- ps4dshock
+ ps4dshock \
+ xb360gp
.include <bsd.subdir.mk>
diff --git a/sys/modules/hid/hgame/Makefile b/sys/modules/hid/hgame/Makefile
new file mode 100644
index 000000000000..38016de4c326
--- /dev/null
+++ b/sys/modules/hid/hgame/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/dev/hid
+
+KMOD= hgame
+SRCS= hgame.c
+SRCS+= bus_if.h device_if.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/hid/hpen/Makefile b/sys/modules/hid/hpen/Makefile
new file mode 100644
index 000000000000..7c485c8fd7ce
--- /dev/null
+++ b/sys/modules/hid/hpen/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/dev/hid
+
+KMOD= hpen
+SRCS= hpen.c
+SRCS+= bus_if.h device_if.h usbdevs.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/hid/xb360gp/Makefile b/sys/modules/hid/xb360gp/Makefile
new file mode 100644
index 000000000000..2b3e012f8491
--- /dev/null
+++ b/sys/modules/hid/xb360gp/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/dev/hid
+
+KMOD= xb360gp
+SRCS= xb360gp.c
+SRCS+= bus_if.h device_if.h opt_usb.h
+
+.include <bsd.kmod.mk>