brintos

brintos / linux-shallow public Read only

0
0
Text · 10.2 KiB · caec913 Raw
191 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (c) 2024 Benjamin Tissoires3 */4 5#include "vmlinux.h"6#include "hid_bpf.h"7#include "hid_bpf_helpers.h"8#include <bpf/bpf_tracing.h>9 10#define VID_BETOP_2185PC        0x11C011#define PID_RAPTOR_MACH_2 0x560612 13HID_BPF_CONFIG(14	HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, VID_BETOP_2185PC, PID_RAPTOR_MACH_2),15);16 17/*18 * For reference, this is the fixed report descriptor19 *20 * static const __u8 fixed_rdesc[] = {21 *     0x05, 0x01,                    // Usage Page (Generic Desktop)        022 *     0x09, 0x04,                    // Usage (Joystick)                    223 *     0xa1, 0x01,                    // Collection (Application)            424 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       625 *     0x85, 0x01,                    //  Report ID (1)                      826 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       1027 *     0x09, 0x30,                    //  Usage (X)                          1228 *     0x75, 0x10,                    //  Report Size (16)                   1429 *     0x95, 0x01,                    //  Report Count (1)                   1630 *     0x15, 0x00,                    //  Logical Minimum (0)                1831 *     0x26, 0xff, 0x07,              //  Logical Maximum (2047)             2032 *     0x46, 0xff, 0x07,              //  Physical Maximum (2047)            2333 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               2634 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       2835 *     0x09, 0x31,                    //  Usage (Y)                          3036 *     0x75, 0x10,                    //  Report Size (16)                   3237 *     0x95, 0x01,                    //  Report Count (1)                   3438 *     0x15, 0x00,                    //  Logical Minimum (0)                3639 *     0x26, 0xff, 0x07,              //  Logical Maximum (2047)             3840 *     0x46, 0xff, 0x07,              //  Physical Maximum (2047)            4141 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               4442 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       4643 *     0x09, 0x33,                    //  Usage (Rx)                         4844 *     0x75, 0x10,                    //  Report Size (16)                   5045 *     0x95, 0x01,                    //  Report Count (1)                   5246 *     0x15, 0x00,                    //  Logical Minimum (0)                5447 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             5648 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            5949 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               6250 *     0x05, 0x00,                    //  Usage Page (Undefined)             6451 *     0x09, 0x00,                    //  Usage (Undefined)                  6652 *     0x75, 0x10,                    //  Report Size (16)                   6853 *     0x95, 0x01,                    //  Report Count (1)                   7054 *     0x15, 0x00,                    //  Logical Minimum (0)                7255 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             7456 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            7757 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               8058 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       8259 *     0x09, 0x32,                    //  Usage (Z)                          8460 *     0x75, 0x10,                    //  Report Size (16)                   8661 *     0x95, 0x01,                    //  Report Count (1)                   8862 *     0x15, 0x00,                    //  Logical Minimum (0)                9063 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             9264 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            9565 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               9866 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       10067 *     0x09, 0x35,                    //  Usage (Rz)                         10268 *     0x75, 0x10,                    //  Report Size (16)                   10469 *     0x95, 0x01,                    //  Report Count (1)                   10670 *     0x15, 0x00,                    //  Logical Minimum (0)                10871 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             11072 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            11373 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               11674 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       11875 *     0x09, 0x34,                    //  Usage (Ry)                         12076 *     0x75, 0x10,                    //  Report Size (16)                   12277 *     0x95, 0x01,                    //  Report Count (1)                   12478 *     0x15, 0x00,                    //  Logical Minimum (0)                12679 *     0x26, 0xff, 0x07,              //  Logical Maximum (2047)             12880 *     0x46, 0xff, 0x07,              //  Physical Maximum (2047)            13181 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               13482 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       13683 *     0x09, 0x36,                    //  Usage (Slider)                     13884 *     0x75, 0x10,                    //  Report Size (16)                   14085 *     0x95, 0x01,                    //  Report Count (1)                   14286 *     0x15, 0x00,                    //  Logical Minimum (0)                14487 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             14688 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            14989 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               15290 *     0x05, 0x09,                    //  Usage Page (Button)                15491 *     0x19, 0x01,                    //  Usage Minimum (1)                  15692 *     0x2a, 0x1d, 0x00,              //  Usage Maximum (29)                 15893 *     0x15, 0x00,                    //  Logical Minimum (0)                16194 *     0x25, 0x01,                    //  Logical Maximum (1)                16395 *     0x75, 0x01,                    //  Report Size (1)                    16596 *     0x96, 0x80, 0x00,              //  Report Count (128)                 16797 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               17098 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       17299 *     0x09, 0x39,                    //  Usage (Hat switch)                 174100 *     0x26, 0x07, 0x00,              //  Logical Maximum (7)                176 // changed (was 239)101 *     0x46, 0x68, 0x01,              //  Physical Maximum (360)             179102 *     0x65, 0x14,                    //  Unit (EnglishRotation: deg)        182103 *     0x75, 0x10,                    //  Report Size (16)                   184104 *     0x95, 0x01,                    //  Report Count (1)                   186105 *     0x81, 0x42,                    //  Input (Data,Var,Abs,Null)          188106 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       190107 *     0x09, 0x00,                    //  Usage (Undefined)                  192108 *     0x75, 0x08,                    //  Report Size (8)                    194109 *     0x95, 0x1d,                    //  Report Count (29)                  196110 *     0x81, 0x01,                    //  Input (Cnst,Arr,Abs)               198111 *     0x15, 0x00,                    //  Logical Minimum (0)                200112 *     0x26, 0xef, 0x00,              //  Logical Maximum (239)              202113 *     0x85, 0x58,                    //  Report ID (88)                     205114 *     0x26, 0xff, 0x00,              //  Logical Maximum (255)              207115 *     0x46, 0xff, 0x00,              //  Physical Maximum (255)             210116 *     0x75, 0x08,                    //  Report Size (8)                    213117 *     0x95, 0x3f,                    //  Report Count (63)                  215118 *     0x09, 0x00,                    //  Usage (Undefined)                  217119 *     0x91, 0x02,                    //  Output (Data,Var,Abs)              219120 *     0x85, 0x59,                    //  Report ID (89)                     221121 *     0x75, 0x08,                    //  Report Size (8)                    223122 *     0x95, 0x80,                    //  Report Count (128)                 225123 *     0x09, 0x00,                    //  Usage (Undefined)                  227124 *     0xb1, 0x02,                    //  Feature (Data,Var,Abs)             229125 *     0xc0,                          // End Collection                      231126 * };127 */128 129/*130 * We need to amend the report descriptor for the following:131 * - the joystick sends its hat_switch data between 0 and 239 but132 *   the kernel expects the logical max to stick into a signed 8 bits133 *   integer. We thus divide it by 30 to match what other joysticks are134 *   doing135 */136SEC(HID_BPF_RDESC_FIXUP)137int BPF_PROG(hid_fix_rdesc_raptor_mach_2, struct hid_bpf_ctx *hctx)138{139	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, HID_MAX_DESCRIPTOR_SIZE /* size */);140 141	if (!data)142		return 0; /* EPERM check */143 144	data[177] = 0x07;145 146	return 0;147}148 149/*150 * The hat_switch value at offsets 33 and 34 (16 bits) needs151 * to be reduced to a single 8 bit signed integer. So we152 * divide it by 30.153 * Byte 34 is always null, so it is ignored.154 */155SEC(HID_BPF_DEVICE_EVENT)156int BPF_PROG(raptor_mach_2_fix_hat_switch, struct hid_bpf_ctx *hctx)157{158	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 64 /* size */);159 160	if (!data)161		return 0; /* EPERM check */162 163	if (data[0] != 0x01) /* not the joystick report ID */164		return 0;165 166	data[33] /= 30;167 168	return 0;169}170 171HID_BPF_OPS(raptor_mach_2) = {172	.hid_rdesc_fixup = (void *)hid_fix_rdesc_raptor_mach_2,173	.hid_device_event = (void *)raptor_mach_2_fix_hat_switch,174};175 176SEC("syscall")177int probe(struct hid_bpf_probe_args *ctx)178{179	ctx->retval = ctx->rdesc_size != 232;180	if (ctx->retval)181		ctx->retval = -EINVAL;182 183	/* ensure the kernel isn't fixed already */184	if (ctx->rdesc[177] != 0xef) /* Logical Max of 239 */185		ctx->retval = -EINVAL;186 187	return 0;188}189 190char _license[] SEC("license") = "GPL";191