xref: /linux/drivers/hid/bpf/progs/hid_report_descriptor_helpers.h (revision d97e7d7c304f87419921f740743f7baa99f40539)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* Copyright (c) 2022 Benjamin Tissoires
3  */
4 
5 #ifndef __HID_REPORT_DESCRIPTOR_HELPERS_H
6 #define __HID_REPORT_DESCRIPTOR_HELPERS_H
7 
8 #include "vmlinux.h"
9 
10 /* Compiler attributes */
11 #ifndef __packed
12 #define __packed __attribute__((packed))
13 #endif
14 
15 #ifndef __maybe_unused
16 #define __maybe_unused __attribute__((__unused__))
17 #endif
18 
19 /* Report Descriptor Structures */
20 #define HID_MAX_COLLECTIONS 32
21 #define HID_MAX_FIELDS 64
22 #define HID_MAX_REPORTS 16
23 
24 enum hid_rdesc_field_type {
25 	HID_FIELD_VARIABLE = 0,
26 	HID_FIELD_ARRAY = 1,
27 	HID_FIELD_CONSTANT = 2,
28 };
29 
30 struct hid_rdesc_collection {
31 	__u16 usage_page;
32 	__u16 usage_id;
33 	__u8 collection_type;
34 } __packed;
35 
36 struct hid_rdesc_field {
37 	__u8 field_type;        /* enum hid_rdesc_field_type */
38 	__u8 num_collections;
39 	__u16 bits_start;
40 	__u16 bits_end;
41 	__u16 usage_page;
42 	union {
43 		__u16 usage_id;       /* For Variable fields */
44 		struct __packed {     /* For Array fields */
45 			__u16 usage_minimum;
46 			__u16 usage_maximum;
47 		};
48 	};
49 	__s32 logical_minimum;
50 	__s32 logical_maximum;
51 	struct {
52 		__u8 is_relative:1;             /* Data is relative to previous value */
53 		__u8 wraps:1;                   /* Value wraps around (e.g., rotary encoder) */
54 		__u8 is_nonlinear:1;            /* Non-linear relationship between logical/physical */
55 		__u8 has_no_preferred_state:1;  /* No rest position (e.g., free-floating joystick) */
56 		__u8 has_null_state:1;          /* Can report null/no-data values */
57 		__u8 is_volatile:1;             /* Volatile (Output/Feature) - NOT POPULATED, always 0 */
58 		__u8 is_buffered_bytes:1;       /* Fixed-size byte stream vs bitfield */
59 		__u8 reserved:1;                /* Reserved for future use */
60 	} flags;
61 	struct hid_rdesc_collection collections[HID_MAX_COLLECTIONS];
62 } __packed;
63 
64 struct hid_rdesc_report {
65 	__u8 report_id;         /* 0 means no report ID */
66 	__u16 size_in_bits;
67 	__u8 num_fields;
68 	struct hid_rdesc_field fields[HID_MAX_FIELDS];
69 } __packed;
70 
71 struct hid_rdesc_descriptor {
72 	__u8 num_input_reports;
73 	__u8 num_output_reports;
74 	__u8 num_feature_reports;
75 	struct hid_rdesc_report input_reports[HID_MAX_REPORTS];
76 	struct hid_rdesc_report output_reports[HID_MAX_REPORTS];
77 	struct hid_rdesc_report feature_reports[HID_MAX_REPORTS];
78 } __packed;
79 
80 #endif /* __HID_REPORT_DESCRIPTOR_HELPERS_H */
81