File Index
Files and directories
Sign in
FILE

FR-TEC__Raptor-Mach-2.bpf.c

File preview with syntax highlighting.

linux-6.19.14/drivers/hid/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/* Copyright (c) 2024 Benjamin Tissoires
  3 */
  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        0x11C0
 11#define PID_RAPTOR_MACH_2 0x5606
 12
 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 descriptor
 19 *
 20 * static const __u8 fixed_rdesc[] = {
 21 *     0x05, 0x01,                    // Usage Page (Generic Desktop)        0
 22 *     0x09, 0x04,                    // Usage (Joystick)                    2
 23 *     0xa1, 0x01,                    // Collection (Application)            4
 24 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       6
 25 *     0x85, 0x01,                    //  Report ID (1)                      8
 26 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       10
 27 *     0x09, 0x30,                    //  Usage (X)                          12
 28 *     0x75, 0x10,                    //  Report Size (16)                   14
 29 *     0x95, 0x01,                    //  Report Count (1)                   16
 30 *     0x15, 0x00,                    //  Logical Minimum (0)                18
 31 *     0x26, 0xff, 0x07,              //  Logical Maximum (2047)             20
 32 *     0x46, 0xff, 0x07,              //  Physical Maximum (2047)            23
 33 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               26
 34 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       28
 35 *     0x09, 0x31,                    //  Usage (Y)                          30
 36 *     0x75, 0x10,                    //  Report Size (16)                   32
 37 *     0x95, 0x01,                    //  Report Count (1)                   34
 38 *     0x15, 0x00,                    //  Logical Minimum (0)                36
 39 *     0x26, 0xff, 0x07,              //  Logical Maximum (2047)             38
 40 *     0x46, 0xff, 0x07,              //  Physical Maximum (2047)            41
 41 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               44
 42 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       46
 43 *     0x09, 0x33,                    //  Usage (Rx)                         48
 44 *     0x75, 0x10,                    //  Report Size (16)                   50
 45 *     0x95, 0x01,                    //  Report Count (1)                   52
 46 *     0x15, 0x00,                    //  Logical Minimum (0)                54
 47 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             56
 48 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            59
 49 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               62
 50 *     0x05, 0x00,                    //  Usage Page (Undefined)             64
 51 *     0x09, 0x00,                    //  Usage (Undefined)                  66
 52 *     0x75, 0x10,                    //  Report Size (16)                   68
 53 *     0x95, 0x01,                    //  Report Count (1)                   70
 54 *     0x15, 0x00,                    //  Logical Minimum (0)                72
 55 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             74
 56 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            77
 57 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               80
 58 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       82
 59 *     0x09, 0x32,                    //  Usage (Z)                          84
 60 *     0x75, 0x10,                    //  Report Size (16)                   86
 61 *     0x95, 0x01,                    //  Report Count (1)                   88
 62 *     0x15, 0x00,                    //  Logical Minimum (0)                90
 63 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             92
 64 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            95
 65 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               98
 66 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       100
 67 *     0x09, 0x35,                    //  Usage (Rz)                         102
 68 *     0x75, 0x10,                    //  Report Size (16)                   104
 69 *     0x95, 0x01,                    //  Report Count (1)                   106
 70 *     0x15, 0x00,                    //  Logical Minimum (0)                108
 71 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             110
 72 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            113
 73 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               116
 74 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       118
 75 *     0x09, 0x34,                    //  Usage (Ry)                         120
 76 *     0x75, 0x10,                    //  Report Size (16)                   122
 77 *     0x95, 0x01,                    //  Report Count (1)                   124
 78 *     0x15, 0x00,                    //  Logical Minimum (0)                126
 79 *     0x26, 0xff, 0x07,              //  Logical Maximum (2047)             128
 80 *     0x46, 0xff, 0x07,              //  Physical Maximum (2047)            131
 81 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               134
 82 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       136
 83 *     0x09, 0x36,                    //  Usage (Slider)                     138
 84 *     0x75, 0x10,                    //  Report Size (16)                   140
 85 *     0x95, 0x01,                    //  Report Count (1)                   142
 86 *     0x15, 0x00,                    //  Logical Minimum (0)                144
 87 *     0x26, 0xff, 0x03,              //  Logical Maximum (1023)             146
 88 *     0x46, 0xff, 0x03,              //  Physical Maximum (1023)            149
 89 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               152
 90 *     0x05, 0x09,                    //  Usage Page (Button)                154
 91 *     0x19, 0x01,                    //  Usage Minimum (1)                  156
 92 *     0x2a, 0x1d, 0x00,              //  Usage Maximum (29)                 158
 93 *     0x15, 0x00,                    //  Logical Minimum (0)                161
 94 *     0x25, 0x01,                    //  Logical Maximum (1)                163
 95 *     0x75, 0x01,                    //  Report Size (1)                    165
 96 *     0x96, 0x80, 0x00,              //  Report Count (128)                 167
 97 *     0x81, 0x02,                    //  Input (Data,Var,Abs)               170
 98 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       172
 99 *     0x09, 0x39,                    //  Usage (Hat switch)                 174
100 *     0x26, 0x07, 0x00,              //  Logical Maximum (7)                176 // changed (was 239)
101 *     0x46, 0x68, 0x01,              //  Physical Maximum (360)             179
102 *     0x65, 0x14,                    //  Unit (EnglishRotation: deg)        182
103 *     0x75, 0x10,                    //  Report Size (16)                   184
104 *     0x95, 0x01,                    //  Report Count (1)                   186
105 *     0x81, 0x42,                    //  Input (Data,Var,Abs,Null)          188
106 *     0x05, 0x01,                    //  Usage Page (Generic Desktop)       190
107 *     0x09, 0x00,                    //  Usage (Undefined)                  192
108 *     0x75, 0x08,                    //  Report Size (8)                    194
109 *     0x95, 0x1d,                    //  Report Count (29)                  196
110 *     0x81, 0x01,                    //  Input (Cnst,Arr,Abs)               198
111 *     0x15, 0x00,                    //  Logical Minimum (0)                200
112 *     0x26, 0xef, 0x00,              //  Logical Maximum (239)              202
113 *     0x85, 0x58,                    //  Report ID (88)                     205
114 *     0x26, 0xff, 0x00,              //  Logical Maximum (255)              207
115 *     0x46, 0xff, 0x00,              //  Physical Maximum (255)             210
116 *     0x75, 0x08,                    //  Report Size (8)                    213
117 *     0x95, 0x3f,                    //  Report Count (63)                  215
118 *     0x09, 0x00,                    //  Usage (Undefined)                  217
119 *     0x91, 0x02,                    //  Output (Data,Var,Abs)              219
120 *     0x85, 0x59,                    //  Report ID (89)                     221
121 *     0x75, 0x08,                    //  Report Size (8)                    223
122 *     0x95, 0x80,                    //  Report Count (128)                 225
123 *     0x09, 0x00,                    //  Usage (Undefined)                  227
124 *     0xb1, 0x02,                    //  Feature (Data,Var,Abs)             229
125 *     0xc0,                          // End Collection                      231
126 * };
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 but
132 *   the kernel expects the logical max to stick into a signed 8 bits
133 *   integer. We thus divide it by 30 to match what other joysticks are
134 *   doing
135 */
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) needs
151 * to be reduced to a single 8 bit signed integer. So we
152 * 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";
~/ Read-only file preview.