xref: /linux/drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c (revision d97e7d7c304f87419921f740743f7baa99f40539)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Fix for Trust Philips SPK6327 (145f:024b)
3  * Modifier keys report as Array (0x00) instead of Variable (0x02)
4  * causing LCtrl, LAlt, Super etc. to all act as LShift
5  */
6 #include "vmlinux.h"
7 #include "hid_bpf.h"
8 #include "hid_bpf_helpers.h"
9 #include <bpf/bpf_tracing.h>
10 
11 #define VID_TRUST 0x145F
12 #define PID_SPK6327 0x024B
13 
14 HID_BPF_CONFIG(
15 	HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, VID_TRUST, PID_SPK6327)
16 );
17 
18 SEC(HID_BPF_RDESC_FIXUP)
19 int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx)
20 {
21 	__u8 *data = hid_bpf_get_data(hctx, 0, 4096);
22 
23 	if (!data)
24 		return 0;
25 
26 	/* Fix modifier keys: Input Array (0x00) -> Input Variable (0x02) */
27 	if (data[101] == 0x00)
28 		data[101] = 0x02;
29 
30 	return 0;
31 }
32 
33 HID_BPF_OPS(trust_spk6327) = {
34 	.hid_rdesc_fixup = (void *)hid_fix_rdesc,
35 };
36 
37 SEC("syscall")
38 int probe(struct hid_bpf_probe_args *ctx)
39 {
40 	/* Only apply to interface 1 (169 bytes) not interface 0 (62 bytes) */
41 	if (ctx->rdesc_size == 169)
42 		ctx->retval = 0;
43 	else
44 		ctx->retval = -EINVAL;
45 
46 	return 0;
47 }
48 
49 char _license[] SEC("license") = "GPL";
50