samples/hid/hid_surface_dial.bpf.c

Source file repositories/reference/linux-study-clean/samples/hid/hid_surface_dial.bpf.c

File Facts

System
Linux kernel
Corpus path
samples/hid/hid_surface_dial.bpf.c
Extension
.c
Size
3119 bytes
Lines
141
Domain
Support Tooling And Documentation
Bucket
samples
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

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] = 0x06;
	data[98] = 0x06;

Annotation

Implementation Notes