brintos

brintos / linux-shallow public Read only

0
0
Text · 3.0 KiB · 527d584 Raw
141 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (c) 2022 Benjamin Tissoires3 */4 5#include "vmlinux.h"6#include <bpf/bpf_helpers.h>7#include <bpf/bpf_tracing.h>8#include "hid_bpf_helpers.h"9 10#define HID_UP_BUTTON		0x000911#define HID_GD_WHEEL		0x003812 13SEC("struct_ops/hid_device_event")14int BPF_PROG(hid_event, struct hid_bpf_ctx *hctx)15{16	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);17 18	if (!data)19		return 0; /* EPERM check */20 21	/* Touch */22	data[1] &= 0xfd;23 24	/* X */25	data[4] = 0;26	data[5] = 0;27 28	/* Y */29	data[6] = 0;30	data[7] = 0;31 32	return 0;33}34 35/* 72 == 360 / 5 -> 1 report every 5 degrees */36int resolution = 72;37int physical = 5;38 39struct haptic_syscall_args {40	unsigned int hid;41	int retval;42};43 44static __u8 haptic_data[8];45 46SEC("syscall")47int set_haptic(struct haptic_syscall_args *args)48{49	struct hid_bpf_ctx *ctx;50	const size_t size = sizeof(haptic_data);51	u16 *res;52	int ret;53 54	if (size > sizeof(haptic_data))55		return -7; /* -E2BIG */56 57	ctx = hid_bpf_allocate_context(args->hid);58	if (!ctx)59		return -1; /* EPERM check */60 61	haptic_data[0] = 1;  /* report ID */62 63	ret = hid_bpf_hw_request(ctx, haptic_data, size, HID_FEATURE_REPORT, HID_REQ_GET_REPORT);64 65	bpf_printk("probed/remove event ret value: %d", ret);66	bpf_printk("buf: %02x %02x %02x",67		   haptic_data[0],68		   haptic_data[1],69		   haptic_data[2]);70	bpf_printk("     %02x %02x %02x",71		   haptic_data[3],72		   haptic_data[4],73		   haptic_data[5]);74	bpf_printk("     %02x %02x",75		   haptic_data[6],76		   haptic_data[7]);77 78	/* whenever resolution multiplier is not 3600, we have the fixed report descriptor */79	res = (u16 *)&haptic_data[1];80	if (*res != 3600) {81//		haptic_data[1] = 72; /* resolution multiplier */82//		haptic_data[2] = 0;  /* resolution multiplier */83//		haptic_data[3] = 0;  /* Repeat Count */84		haptic_data[4] = 3;  /* haptic Auto Trigger */85//		haptic_data[5] = 5;  /* Waveform Cutoff Time */86//		haptic_data[6] = 80; /* Retrigger Period */87//		haptic_data[7] = 0;  /* Retrigger Period */88	} else {89		haptic_data[4] = 0;90	}91 92	ret = hid_bpf_hw_request(ctx, haptic_data, size, HID_FEATURE_REPORT, HID_REQ_SET_REPORT);93 94	bpf_printk("set haptic ret value: %d -> %d", ret, haptic_data[4]);95 96	args->retval = ret;97 98	hid_bpf_release_context(ctx);99 100	return 0;101}102 103/* Convert REL_DIAL into REL_WHEEL */104SEC("struct_ops/hid_rdesc_fixup")105int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx)106{107	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */);108	__u16 *res, *phys;109 110	if (!data)111		return 0; /* EPERM check */112 113	/* Convert TOUCH into a button */114	data[31] = HID_UP_BUTTON;115	data[33] = 2;116 117	/* Convert REL_DIAL into REL_WHEEL */118	data[45] = HID_GD_WHEEL;119 120	/* Change Resolution Multiplier */121	phys = (__u16 *)&data[61];122	*phys = physical;123	res = (__u16 *)&data[66];124	*res = resolution;125 126	/* Convert X,Y from Abs to Rel */127	data[88] = 0x06;128	data[98] = 0x06;129 130	return 0;131}132 133SEC(".struct_ops.link")134struct hid_bpf_ops surface_dial = {135	.hid_rdesc_fixup = (void *)hid_rdesc_fixup,136	.hid_device_event = (void *)hid_event,137};138 139char _license[] SEC("license") = "GPL";140u32 _version SEC("version") = 1;141