// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2022 Benjamin Tissoires
*/
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "hid_bpf_helpers.h"
#define HID_UP_BUTTON 0 x0009
#define HID_GD_WHEEL 0 x0038
SEC("struct_ops/hid_device_event" )
int BPF_PROG(hid_event, struct hid_bpf_ctx *hctx)
{
__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
if (!data)
return 0 ; /* EPERM check */
/* Touch */
data[1 ] &= 0 xfd;
/* X */
data[4 ] = 0 ;
data[5 ] = 0 ;
/* Y */
data[6 ] = 0 ;
data[7 ] = 0 ;
return 0 ;
}
/* 72 == 360 / 5 -> 1 report every 5 degrees */
int resolution = 72 ;
int physical = 5 ;
struct haptic_syscall_args {
unsigned int hid;
int retval;
};
static __u8 haptic_data[8 ];
SEC("syscall" )
int set_haptic(struct haptic_syscall_args *args)
{
struct hid_bpf_ctx *ctx;
const size_t size = sizeof (haptic_data);
u16 *res;
int ret;
if (size > sizeof (haptic_data))
return -7 ; /* -E2BIG */
ctx = hid_bpf_allocate_context(args->hid);
if (!ctx)
return -1 ; /* EPERM check */
haptic_data[0 ] = 1 ; /* report ID */
ret = hid_bpf_hw_request(ctx, haptic_data, size, HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
bpf_printk("probed/remove event ret value: %d" , ret);
bpf_printk("buf: %02x %02x %02x" ,
haptic_data[0 ],
haptic_data[1 ],
haptic_data[2 ]);
bpf_printk(" %02x %02x %02x" ,
haptic_data[3 ],
haptic_data[4 ],
haptic_data[5 ]);
bpf_printk(" %02x %02x" ,
haptic_data[6 ],
haptic_data[7 ]);
/* whenever resolution multiplier is not 3600, we have the fixed report descriptor */
res = (u16 *)&haptic_data[1 ];
if (*res != 3600 ) {
// haptic_data[1] = 72; /* resolution multiplier */
// haptic_data[2] = 0; /* resolution multiplier */
// haptic_data[3] = 0; /* Repeat Count */
haptic_data[4 ] = 3 ; /* haptic Auto Trigger */
// haptic_data[5] = 5; /* Waveform Cutoff Time */
// haptic_data[6] = 80; /* Retrigger Period */
// haptic_data[7] = 0; /* Retrigger Period */
} else {
haptic_data[4 ] = 0 ;
}
ret = hid_bpf_hw_request(ctx, haptic_data, size, HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
bpf_printk("set haptic ret value: %d -> %d" , ret, haptic_data[4 ]);
args->retval = ret;
hid_bpf_release_context(ctx);
return 0 ;
}
/* Convert REL_DIAL into REL_WHEEL */
SEC("struct_ops/hid_rdesc_fixup" )
int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx)
{
__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */);
__u16 *res, *phys;
if (!data)
return 0 ; /* EPERM check */
/* Convert TOUCH into a button */
data[31 ] = HID_UP_BUTTON;
data[33 ] = 2 ;
/* Convert REL_DIAL into REL_WHEEL */
data[45 ] = HID_GD_WHEEL;
/* Change Resolution Multiplier */
phys = (__u16 *)&data[61 ];
*phys = physical;
res = (__u16 *)&data[66 ];
*res = resolution;
/* Convert X,Y from Abs to Rel */
data[88 ] = 0 x06;
data[98 ] = 0 x06;
return 0 ;
}
SEC(".struct_ops.link" )
struct hid_bpf_ops surface_dial = {
.hid_rdesc_fixup = (void *)hid_rdesc_fixup,
.hid_device_event = (void *)hid_event,
};
char _license[] SEC("license" ) = "GPL" ;
u32 _version SEC("version" ) = 1 ;
Messung V0.5 in Prozent C=92 H=90 G=90
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland