xref: /linux/drivers/hid/bpf/progs/Huion__Kamvas13Gen3.bpf.c (revision 24f171c7e145f43b9f187578e89b0982ce87e54c)
1*5f2e058dSBenjamin Tissoires // SPDX-License-Identifier: GPL-2.0-only
2*5f2e058dSBenjamin Tissoires /* Copyright (c) 2025 Nicholas LaPointe
3*5f2e058dSBenjamin Tissoires  */
4*5f2e058dSBenjamin Tissoires 
5*5f2e058dSBenjamin Tissoires #include "vmlinux.h"
6*5f2e058dSBenjamin Tissoires #include "hid_bpf.h"
7*5f2e058dSBenjamin Tissoires #include "hid_bpf_helpers.h"
8*5f2e058dSBenjamin Tissoires #include "hid_report_helpers.h"
9*5f2e058dSBenjamin Tissoires #include <bpf/bpf_tracing.h>
10*5f2e058dSBenjamin Tissoires 
11*5f2e058dSBenjamin Tissoires #define VID_HUION 0x256c
12*5f2e058dSBenjamin Tissoires #define PID_KAMVAS13_GEN3 0x2008
13*5f2e058dSBenjamin Tissoires 
14*5f2e058dSBenjamin Tissoires #define VENDOR_DESCRIPTOR_LENGTH 36
15*5f2e058dSBenjamin Tissoires #define TABLET_DESCRIPTOR_LENGTH 368
16*5f2e058dSBenjamin Tissoires #define WHEEL_DESCRIPTOR_LENGTH 108
17*5f2e058dSBenjamin Tissoires 
18*5f2e058dSBenjamin Tissoires #define VENDOR_REPORT_ID 8
19*5f2e058dSBenjamin Tissoires #define VENDOR_REPORT_LENGTH 14
20*5f2e058dSBenjamin Tissoires 
21*5f2e058dSBenjamin Tissoires #define VENDOR_REPORT_SUBTYPE_PEN 0x08
22*5f2e058dSBenjamin Tissoires #define VENDOR_REPORT_SUBTYPE_PEN_OUT 0x00
23*5f2e058dSBenjamin Tissoires #define VENDOR_REPORT_SUBTYPE_BUTTONS 0x0e
24*5f2e058dSBenjamin Tissoires #define VENDOR_REPORT_SUBTYPE_WHEELS 0x0f
25*5f2e058dSBenjamin Tissoires 
26*5f2e058dSBenjamin Tissoires /* For the reports that we create ourselves */
27*5f2e058dSBenjamin Tissoires #define CUSTOM_PAD_REPORT_ID 9
28*5f2e058dSBenjamin Tissoires 
29*5f2e058dSBenjamin Tissoires HID_BPF_CONFIG(
30*5f2e058dSBenjamin Tissoires 	HID_DEVICE(BUS_USB, HID_GROUP_ANY, VID_HUION, PID_KAMVAS13_GEN3),
31*5f2e058dSBenjamin Tissoires );
32*5f2e058dSBenjamin Tissoires 
33*5f2e058dSBenjamin Tissoires 
34*5f2e058dSBenjamin Tissoires /*
35*5f2e058dSBenjamin Tissoires  * This tablet can send reports using one of two different data formats,
36*5f2e058dSBenjamin Tissoires  * depending on what "mode" the tablet is in.
37*5f2e058dSBenjamin Tissoires  *
38*5f2e058dSBenjamin Tissoires  * By default, the tablet will send reports that can be decoded using its
39*5f2e058dSBenjamin Tissoires  * included HID descriptors (descriptors 1 and 2, shown below).
40*5f2e058dSBenjamin Tissoires  * This mode will be called "firmware mode" throughout this file.
41*5f2e058dSBenjamin Tissoires  *
42*5f2e058dSBenjamin Tissoires  * The HID descriptor that describes pen events in firmware mode (descriptor 1)
43*5f2e058dSBenjamin Tissoires  * has multiple bugs:
44*5f2e058dSBenjamin Tissoires  *	* "Secondary Tip Switch" instead of "Secondary Barrel Switch"
45*5f2e058dSBenjamin Tissoires  *	* "Invert" instead of (or potentially shared with) third barrel button
46*5f2e058dSBenjamin Tissoires  *	* Specified tablet area of 2048 in³ instead of 293.8 x 165.2mm
47*5f2e058dSBenjamin Tissoires  *	* Specified tilt range of -90 to +90 instead of -60 to +60
48*5f2e058dSBenjamin Tissoires  *
49*5f2e058dSBenjamin Tissoires  * While these can be easily patched up by editing the descriptor, a larger
50*5f2e058dSBenjamin Tissoires  * problem with the firmware mode exists: it is impossible to tell which of the
51*5f2e058dSBenjamin Tissoires  * two wheels are being rotated (or having their central button pressed).
52*5f2e058dSBenjamin Tissoires  *
53*5f2e058dSBenjamin Tissoires  *
54*5f2e058dSBenjamin Tissoires  * By using a tool such as huion-switcher (https://github.com/whot/huion-switcher),
55*5f2e058dSBenjamin Tissoires  * the tablet can be made to send reports using a proprietary format that is not
56*5f2e058dSBenjamin Tissoires  * adequately described by its relevant descriptor (descriptor 0, shown below).
57*5f2e058dSBenjamin Tissoires  * This mode will be called "vendor mode" throughout this file.
58*5f2e058dSBenjamin Tissoires  *
59*5f2e058dSBenjamin Tissoires  * The reports sent while in vendor mode allow for proper decoding of the wheels.
60*5f2e058dSBenjamin Tissoires  *
61*5f2e058dSBenjamin Tissoires  * For simplicity and maximum functionality, this BPF focuses strictly on
62*5f2e058dSBenjamin Tissoires  * enabling one to make use of the vendor mode.
63*5f2e058dSBenjamin Tissoires  */
64*5f2e058dSBenjamin Tissoires 
65*5f2e058dSBenjamin Tissoires /*
66*5f2e058dSBenjamin Tissoires  * DESCRIPTORS
67*5f2e058dSBenjamin Tissoires  *	DESCRIPTOR 0
68*5f2e058dSBenjamin Tissoires  *		#   0x06, 0x00, 0xff,              // Usage Page (Vendor Defined Page FF00)     0
69*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x01,                    // Usage (Vendor Usage 0x01)                 3
70*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x01,                    // Collection (Application)                  5
71*5f2e058dSBenjamin Tissoires  *		# ┅ 0x85, 0x08,                    //   Report ID (8)                           7
72*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x68,                    //   Report Size (104)                       9
73*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //   Report Count (1)                        11
74*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x01,                    //   Usage (Vendor Usage 0x01)               13
75*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //   Input (Data,Var,Abs)                    15
76*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          // End Collection                            17
77*5f2e058dSBenjamin Tissoires  *		#   0x06, 0x00, 0xff,              // Usage Page (Vendor Defined Page FF00)     18
78*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x01,                    // Usage (Vendor Usage 0x01)                 21
79*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x01,                    // Collection (Application)                  23
80*5f2e058dSBenjamin Tissoires  *		# ┅ 0x85, 0x16,                    //   Report ID (22)                          25
81*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //   Report Size (8)                         27
82*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x07,                    //   Report Count (7)                        29
83*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x01,                    //   Usage (Vendor Usage 0x01)               31
84*5f2e058dSBenjamin Tissoires  *		# ║ 0xb1, 0x02,                    //   Feature (Data,Var,Abs)                  33
85*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          // End Collection                            35
86*5f2e058dSBenjamin Tissoires  *		R: 36 06 00 ff 09 01 a1 01 85 08 75 68 95 01 09 01 81 02 c0 06 00 ff 09 01 a1 01 85 16 75 08 95 07 09 01 b1 02 c0
87*5f2e058dSBenjamin Tissoires  *		N: HUION Huion Tablet_GS1333
88*5f2e058dSBenjamin Tissoires  *		I: 3 256c 2008
89*5f2e058dSBenjamin Tissoires  *
90*5f2e058dSBenjamin Tissoires  *	DESCRIPTOR 1
91*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    // Usage Page (Digitizers)                   0
92*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x02,                    // Usage (Pen)                               2
93*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x01,                    // Collection (Application)                  4
94*5f2e058dSBenjamin Tissoires  *		# ┅ 0x85, 0x0a,                    //   Report ID (10)                          6
95*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x20,                    //   Usage (Stylus)                          8
96*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x01,                    //   Collection (Application)                10
97*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x42,                    //     Usage (Tip Switch)                    12
98*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x44,                    //     Usage (Barrel Switch)                 14
99*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x43,                    //     Usage (Secondary Tip Switch)          16
100*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x3c,                    //     Usage (Invert)                        18
101*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x45,                    //     Usage (Eraser)                        20
102*5f2e058dSBenjamin Tissoires  *		#   0x15, 0x00,                    //     Logical Minimum (0)                   22
103*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x01,                    //     Logical Maximum (1)                   24
104*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x01,                    //     Report Size (1)                       26
105*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x06,                    //     Report Count (6)                      28
106*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  30
107*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x32,                    //     Usage (In Range)                      32
108*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x01,                    //     Report Size (1)                       34
109*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      36
110*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  38
111*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x03,                    //     Input (Cnst,Var,Abs)                  40
112*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x01,                    //     Usage Page (Generic Desktop)          42
113*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x30,                    //     Usage (X)                             44
114*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x31,                    //     Usage (Y)                             46
115*5f2e058dSBenjamin Tissoires  *		#   0x55, 0x0d,                    //     Unit Exponent (-3)                    48
116*5f2e058dSBenjamin Tissoires  *		#   0x65, 0x33,                    //     Unit (EnglishLinear: in³)             50
117*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x7f,              //     Logical Maximum (32767)               52
118*5f2e058dSBenjamin Tissoires  *		#   0x35, 0x00,                    //     Physical Minimum (0)                  55
119*5f2e058dSBenjamin Tissoires  *		#   0x46, 0x00, 0x08,              //     Physical Maximum (2048)               57
120*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x10,                    //     Report Size (16)                      60
121*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x02,                    //     Report Count (2)                      62
122*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  64
123*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    //     Usage Page (Digitizers)               66
124*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x30,                    //     Usage (Tip Pressure)                  68
125*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x3f,              //     Logical Maximum (16383)               70
126*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x10,                    //     Report Size (16)                      73
127*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      75
128*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  77
129*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x3d,                    //     Usage (X Tilt)                        79
130*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x3e,                    //     Usage (Y Tilt)                        81
131*5f2e058dSBenjamin Tissoires  *		#   0x15, 0xa6,                    //     Logical Minimum (-90)                 83
132*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x5a,                    //     Logical Maximum (90)                  85
133*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //     Report Size (8)                       87
134*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x02,                    //     Report Count (2)                      89
135*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  91
136*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          //   End Collection                          93
137*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          // End Collection                            94
138*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    // Usage Page (Digitizers)                   95
139*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x04,                    // Usage (Touch Screen)                      97
140*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x01,                    // Collection (Application)                  99
141*5f2e058dSBenjamin Tissoires  *		# ┅ 0x85, 0x04,                    //   Report ID (4)                           101
142*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x22,                    //   Usage (Finger)                          103
143*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x02,                    //   Collection (Logical)                    105
144*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    //     Usage Page (Digitizers)               107
145*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      109
146*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x06,                    //     Report Size (6)                       111
147*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x51,                    //     Usage (Contact Identifier)            113
148*5f2e058dSBenjamin Tissoires  *		#   0x15, 0x00,                    //     Logical Minimum (0)                   115
149*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x3f,                    //     Logical Maximum (63)                  117
150*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  119
151*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x42,                    //     Usage (Tip Switch)                    121
152*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x01,                    //     Logical Maximum (1)                   123
153*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x01,                    //     Report Size (1)                       125
154*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      127
155*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  129
156*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x01,                    //     Report Size (1)                       131
157*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      133
158*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x03,                    //     Input (Cnst,Var,Abs)                  135
159*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x01,                    //     Usage Page (Generic Desktop)          137
160*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x10,                    //     Report Size (16)                      139
161*5f2e058dSBenjamin Tissoires  *		#   0x55, 0x0e,                    //     Unit Exponent (-2)                    141
162*5f2e058dSBenjamin Tissoires  *		#   0x65, 0x11,                    //     Unit (SILinear: cm)                   143
163*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x30,                    //     Usage (X)                             145
164*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x7f,              //     Logical Maximum (32767)               147
165*5f2e058dSBenjamin Tissoires  *		#   0x35, 0x00,                    //     Physical Minimum (0)                  150
166*5f2e058dSBenjamin Tissoires  *		#   0x46, 0x15, 0x0c,              //     Physical Maximum (3093)               152
167*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x42,                    //     Input (Data,Var,Abs,Null)             155
168*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x31,                    //     Usage (Y)                             157
169*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x7f,              //     Logical Maximum (32767)               159
170*5f2e058dSBenjamin Tissoires  *		#   0x46, 0xcb, 0x06,              //     Physical Maximum (1739)               162
171*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x42,                    //     Input (Data,Var,Abs,Null)             165
172*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    //     Usage Page (Digitizers)               167
173*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x30,                    //     Usage (Tip Pressure)                  169
174*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x1f,              //     Logical Maximum (8191)                171
175*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x10,                    //     Report Size (16)                      174
176*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      176
177*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  178
178*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          //   End Collection                          180
179*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    //   Usage Page (Digitizers)                 181
180*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x22,                    //   Usage (Finger)                          183
181*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x02,                    //   Collection (Logical)                    185
182*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    //     Usage Page (Digitizers)               187
183*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      189
184*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x06,                    //     Report Size (6)                       191
185*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x51,                    //     Usage (Contact Identifier)            193
186*5f2e058dSBenjamin Tissoires  *		#   0x15, 0x00,                    //     Logical Minimum (0)                   195
187*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x3f,                    //     Logical Maximum (63)                  197
188*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  199
189*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x42,                    //     Usage (Tip Switch)                    201
190*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x01,                    //     Logical Maximum (1)                   203
191*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x01,                    //     Report Size (1)                       205
192*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      207
193*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  209
194*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x01,                    //     Report Size (1)                       211
195*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      213
196*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x03,                    //     Input (Cnst,Var,Abs)                  215
197*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x01,                    //     Usage Page (Generic Desktop)          217
198*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x10,                    //     Report Size (16)                      219
199*5f2e058dSBenjamin Tissoires  *		#   0x55, 0x0e,                    //     Unit Exponent (-2)                    221
200*5f2e058dSBenjamin Tissoires  *		#   0x65, 0x11,                    //     Unit (SILinear: cm)                   223
201*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x30,                    //     Usage (X)                             225
202*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x7f,              //     Logical Maximum (32767)               227
203*5f2e058dSBenjamin Tissoires  *		#   0x35, 0x00,                    //     Physical Minimum (0)                  230
204*5f2e058dSBenjamin Tissoires  *		#   0x46, 0x15, 0x0c,              //     Physical Maximum (3093)               232
205*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x42,                    //     Input (Data,Var,Abs,Null)             235
206*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x31,                    //     Usage (Y)                             237
207*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x7f,              //     Logical Maximum (32767)               239
208*5f2e058dSBenjamin Tissoires  *		#   0x46, 0xcb, 0x06,              //     Physical Maximum (1739)               242
209*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x42,                    //     Input (Data,Var,Abs,Null)             245
210*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    //     Usage Page (Digitizers)               247
211*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x30,                    //     Usage (Tip Pressure)                  249
212*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x1f,              //     Logical Maximum (8191)                251
213*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x10,                    //     Report Size (16)                      254
214*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      256
215*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //     Input (Data,Var,Abs)                  258
216*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          //   End Collection                          260
217*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    //   Usage Page (Digitizers)                 261
218*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x56,                    //   Usage (Scan Time)                       263
219*5f2e058dSBenjamin Tissoires  *		#   0x55, 0x00,                    //   Unit Exponent (0)                       265
220*5f2e058dSBenjamin Tissoires  *		#   0x65, 0x00,                    //   Unit (None)                             267
221*5f2e058dSBenjamin Tissoires  *		#   0x27, 0xff, 0xff, 0xff, 0x7f,  //   Logical Maximum (2147483647)            269
222*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //   Report Count (1)                        274
223*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x20,                    //   Report Size (32)                        276
224*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //   Input (Data,Var,Abs)                    278
225*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x54,                    //   Usage (Contact Count)                   280
226*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x7f,                    //   Logical Maximum (127)                   282
227*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //   Report Count (1)                        284
228*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //   Report Size (8)                         286
229*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //   Input (Data,Var,Abs)                    288
230*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //   Report Size (8)                         290
231*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x08,                    //   Report Count (8)                        292
232*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x03,                    //   Input (Cnst,Var,Abs)                    294
233*5f2e058dSBenjamin Tissoires  *		# ┅ 0x85, 0x05,                    //   Report ID (5)                           296
234*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x55,                    //   Usage (Contact Count Maximum)           298
235*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x0a,                    //   Logical Maximum (10)                    300
236*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //   Report Size (8)                         302
237*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //   Report Count (1)                        304
238*5f2e058dSBenjamin Tissoires  *		# ║ 0xb1, 0x02,                    //   Feature (Data,Var,Abs)                  306
239*5f2e058dSBenjamin Tissoires  *		#   0x06, 0x00, 0xff,              //   Usage Page (Vendor Defined Page FF00)   308
240*5f2e058dSBenjamin Tissoires  *		#   0x09, 0xc5,                    //   Usage (Vendor Usage 0xc5)               311
241*5f2e058dSBenjamin Tissoires  *		# ┅ 0x85, 0x06,                    //   Report ID (6)                           313
242*5f2e058dSBenjamin Tissoires  *		#   0x15, 0x00,                    //   Logical Minimum (0)                     315
243*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x00,              //   Logical Maximum (255)                   317
244*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //   Report Size (8)                         320
245*5f2e058dSBenjamin Tissoires  *		#   0x96, 0x00, 0x01,              //   Report Count (256)                      322
246*5f2e058dSBenjamin Tissoires  *		# ║ 0xb1, 0x02,                    //   Feature (Data,Var,Abs)                  325
247*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          // End Collection                            327
248*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x01,                    // Usage Page (Generic Desktop)              328
249*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x06,                    // Usage (Keyboard)                          330
250*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x01,                    // Collection (Application)                  332
251*5f2e058dSBenjamin Tissoires  *		# ┅ 0x85, 0x03,                    //   Report ID (3)                           334
252*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x07,                    //   Usage Page (Keyboard/Keypad)            336
253*5f2e058dSBenjamin Tissoires  *		#   0x19, 0xe0,                    //   UsageMinimum (224)                      338
254*5f2e058dSBenjamin Tissoires  *		#   0x29, 0xe7,                    //   UsageMaximum (231)                      340
255*5f2e058dSBenjamin Tissoires  *		#   0x15, 0x00,                    //   Logical Minimum (0)                     342
256*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x01,                    //   Logical Maximum (1)                     344
257*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x01,                    //   Report Size (1)                         346
258*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x08,                    //   Report Count (8)                        348
259*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //   Input (Data,Var,Abs)                    350
260*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x07,                    //   Usage Page (Keyboard/Keypad)            352
261*5f2e058dSBenjamin Tissoires  *		#   0x19, 0x00,                    //   UsageMinimum (0)                        354
262*5f2e058dSBenjamin Tissoires  *		#   0x29, 0xff,                    //   UsageMaximum (255)                      356
263*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x00,              //   Logical Maximum (255)                   358
264*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //   Report Size (8)                         361
265*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x06,                    //   Report Count (6)                        363
266*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x00,                    //   Input (Data,Arr,Abs)                    365
267*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          // End Collection                            367
268*5f2e058dSBenjamin Tissoires  *		R: 368 05 0d 09 02 a1 01 85 0a 09 20 a1 01 09 42 09 44 09 43 09 3c 09 45 15 00 25 01 75 01 95 06 81 02 09 32 75 01 95 01 81 02 81 03 05 01 09 30 09 31 55 0d 65 33 26 ff 7f 35 00 46 00 08 75 10 95 02 81 02 05 0d 09 30 26 ff 3f 75 10 95 01 81 02 09 3d 09 3e 15 a6 25 5a 75 08 95 02 81 02 c0 c0 05 0d 09 04 a1 01 85 04 09 22 a1 02 05 0d 95 01 75 06 09 51 15 00 25 3f 81 02 09 42 25 01 75 01 95 01 81 02 75 01 95 01 81 03 05 01 75 10 55 0e 65 11 09 30 26 ff 7f 35 00 46 15 0c 81 42 09 31 26 ff 7f 46 cb 06 81 42 05 0d 09 30 26 ff 1f 75 10 95 01 81 02 c0 05 0d 09 22 a1 02 05 0d 95 01 75 06 09 51 15 00 25 3f 81 02 09 42 25 01 75 01 95 01 81 02 75 01 95 01 81 03 05 01 75 10 55 0e 65 11 09 30 26 ff 7f 35 00 46 15 0c 81 42 09 31 26 ff 7f 46 cb 06 81 42 05 0d 09 30 26 ff 1f 75 10 95 01 81 02 c0 05 0d 09 56 55 00 65 00 27 ff ff ff 7f 95 01 75 20 81 02 09 54 25 7f 95 01 75 08 81 02 75 08 95 08 81 03 85 05 09 55 25 0a 75 08 95 01 b1 02 06 00 ff 09 c5 85 06 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 01 09 06 a1 01 85 03 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 81 02 05 07 19 00 29 ff 26 ff 00 75 08 95 06 81 00 c0
269*5f2e058dSBenjamin Tissoires  *		N: HUION Huion Tablet_GS1333
270*5f2e058dSBenjamin Tissoires  *		I: 3 256c 2008
271*5f2e058dSBenjamin Tissoires  *
272*5f2e058dSBenjamin Tissoires  *	DESCRIPTOR 2
273*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x01,                    // Usage Page (Generic Desktop)              0
274*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x0e,                    // Usage (System Multi-Axis Controller)      2
275*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x01,                    // Collection (Application)                  4
276*5f2e058dSBenjamin Tissoires  *		# ┅ 0x85, 0x11,                    //   Report ID (17)                          6
277*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    //   Usage Page (Digitizers)                 8
278*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x21,                    //   Usage (Puck)                            10
279*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x02,                    //   Collection (Logical)                    12
280*5f2e058dSBenjamin Tissoires  *		#   0x15, 0x00,                    //     Logical Minimum (0)                   14
281*5f2e058dSBenjamin Tissoires  *		#   0x25, 0x01,                    //     Logical Maximum (1)                   16
282*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x01,                    //     Report Size (1)                       18
283*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //     Report Count (1)                      20
284*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x00,                    //     Collection (Physical)                 22
285*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x09,                    //       Usage Page (Button)                 24
286*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x01,                    //       Usage (Button 1)                    26
287*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //       Input (Data,Var,Abs)                28
288*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x0d,                    //       Usage Page (Digitizers)             30
289*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x33,                    //       Usage (Touch)                       32
290*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x02,                    //       Input (Data,Var,Abs)                34
291*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x06,                    //       Report Count (6)                    36
292*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x03,                    //       Input (Cnst,Var,Abs)                38
293*5f2e058dSBenjamin Tissoires  *		#   0xa1, 0x02,                    //       Collection (Logical)                40
294*5f2e058dSBenjamin Tissoires  *		#   0x05, 0x01,                    //         Usage Page (Generic Desktop)      42
295*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x37,                    //         Usage (Dial)                      44
296*5f2e058dSBenjamin Tissoires  *		#   0x16, 0x00, 0x80,              //         Logical Minimum (-32768)          46
297*5f2e058dSBenjamin Tissoires  *		#   0x26, 0xff, 0x7f,              //         Logical Maximum (32767)           49
298*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x10,                    //         Report Size (16)                  52
299*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //         Report Count (1)                  54
300*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x06,                    //         Input (Data,Var,Rel)              56
301*5f2e058dSBenjamin Tissoires  *		#   0x35, 0x00,                    //         Physical Minimum (0)              58
302*5f2e058dSBenjamin Tissoires  *		#   0x46, 0x10, 0x0e,              //         Physical Maximum (3600)           60
303*5f2e058dSBenjamin Tissoires  *		#   0x15, 0x00,                    //         Logical Minimum (0)               63
304*5f2e058dSBenjamin Tissoires  *		#   0x26, 0x10, 0x0e,              //         Logical Maximum (3600)            65
305*5f2e058dSBenjamin Tissoires  *		#   0x09, 0x48,                    //         Usage (Resolution Multiplier)     68
306*5f2e058dSBenjamin Tissoires  *		# ║ 0xb1, 0x02,                    //         Feature (Data,Var,Abs)            70
307*5f2e058dSBenjamin Tissoires  *		#   0x45, 0x00,                    //         Physical Maximum (0)              72
308*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          //       End Collection                      74
309*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //       Report Size (8)                     75
310*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //       Report Count (1)                    77
311*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x01,                    //       Input (Cnst,Arr,Abs)                79
312*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //       Report Size (8)                     81
313*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //       Report Count (1)                    83
314*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x01,                    //       Input (Cnst,Arr,Abs)                85
315*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //       Report Size (8)                     87
316*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //       Report Count (1)                    89
317*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x01,                    //       Input (Cnst,Arr,Abs)                91
318*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //       Report Size (8)                     93
319*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //       Report Count (1)                    95
320*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x01,                    //       Input (Cnst,Arr,Abs)                97
321*5f2e058dSBenjamin Tissoires  *		#   0x75, 0x08,                    //       Report Size (8)                     99
322*5f2e058dSBenjamin Tissoires  *		#   0x95, 0x01,                    //       Report Count (1)                    101
323*5f2e058dSBenjamin Tissoires  *		# ┇ 0x81, 0x01,                    //       Input (Cnst,Arr,Abs)                103
324*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          //     End Collection                        105
325*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          //   End Collection                          106
326*5f2e058dSBenjamin Tissoires  *		#   0xc0,                          // End Collection                            107
327*5f2e058dSBenjamin Tissoires  *		R: 108 05 01 09 0e a1 01 85 11 05 0d 09 21 a1 02 15 00 25 01 75 01 95 01 a1 00 05 09 09 01 81 02 05 0d 09 33 81 02 95 06 81 03 a1 02 05 01 09 37 16 00 80 26 ff 7f 75 10 95 01 81 06 35 00 46 10 0e 15 00 26 10 0e 09 48 b1 02 45 00 c0 75 08 95 01 81 01 75 08 95 01 81 01 75 08 95 01 81 01 75 08 95 01 81 01 75 08 95 01 81 01 c0 c0 c0
328*5f2e058dSBenjamin Tissoires  *		N: HUION Huion Tablet_GS1333
329*5f2e058dSBenjamin Tissoires  *		I: 3 256c 2008
330*5f2e058dSBenjamin Tissoires  *
331*5f2e058dSBenjamin Tissoires  *
332*5f2e058dSBenjamin Tissoires  *
333*5f2e058dSBenjamin Tissoires  *
334*5f2e058dSBenjamin Tissoires  *
335*5f2e058dSBenjamin Tissoires  *
336*5f2e058dSBenjamin Tissoires  *
337*5f2e058dSBenjamin Tissoires  *
338*5f2e058dSBenjamin Tissoires  * VENDOR MODE
339*5f2e058dSBenjamin Tissoires  *	HUION_FIRMWARE_ID="HUION_M22c_240606"
340*5f2e058dSBenjamin Tissoires  *	HUION_MAGIC_BYTES="140388e500108100ff3fd8130307008008004010"
341*5f2e058dSBenjamin Tissoires  *
342*5f2e058dSBenjamin Tissoires  *	MAGIC BYTES
343*5f2e058dSBenjamin Tissoires  *	          [LogicalMaximum, X]    [LogicalMaximum, Y]    [LogicalMaximum, Pressure] [  LPI]
344*5f2e058dSBenjamin Tissoires  *	    14 03 [            88 e5] 00 [            10 81] 00 [                   ff 3f] [d8 13] 03 07 00 80 08 00 40 10
345*5f2e058dSBenjamin Tissoires  *
346*5f2e058dSBenjamin Tissoires  *
347*5f2e058dSBenjamin Tissoires  *	HIDRAW 0
348*5f2e058dSBenjamin Tissoires  *		DESCRIPTIONS
349*5f2e058dSBenjamin Tissoires  *			report_subtype = (data[1] >> 4) & 0x0f
350*5f2e058dSBenjamin Tissoires  *
351*5f2e058dSBenjamin Tissoires  *			REPORT SUBTYPES
352*5f2e058dSBenjamin Tissoires  *				0x0e		Buttons
353*5f2e058dSBenjamin Tissoires  *							(data[4] & 0x01)	button 1
354*5f2e058dSBenjamin Tissoires  *							(data[4] & 0x02)	button 2
355*5f2e058dSBenjamin Tissoires  *							(data[4] & 0x04)	button 3
356*5f2e058dSBenjamin Tissoires  *							(data[4] & 0x08)	button 4
357*5f2e058dSBenjamin Tissoires  *							(data[4] & 0x10)	button 5
358*5f2e058dSBenjamin Tissoires  *							(data[4] & 0x20)	button 6 (top wheel button)
359*5f2e058dSBenjamin Tissoires  *							(data[4] & 0x40)	button 7 (bottom wheel button)
360*5f2e058dSBenjamin Tissoires  *
361*5f2e058dSBenjamin Tissoires  *							All tablet buttons release with the same report:
362*5f2e058dSBenjamin Tissoires  *								08 e0 01 01 00 00 00 00 00 00 00 00 00 00
363*5f2e058dSBenjamin Tissoires  *
364*5f2e058dSBenjamin Tissoires  *							Despite data[4] looking like a bit field, only one button
365*5f2e058dSBenjamin Tissoires  *							can be unambiguously tracked at a time.
366*5f2e058dSBenjamin Tissoires  *							(See NOTES ON SIMULTANEOUS BUTTON HOLDS at the end of this
367*5f2e058dSBenjamin Tissoires  *							comment for examples of the confusion this can create.)
368*5f2e058dSBenjamin Tissoires  *
369*5f2e058dSBenjamin Tissoires  *							All buttons, with the exceptions of 6 and 7, will repeatedly
370*5f2e058dSBenjamin Tissoires  *							report a press event approximately every 225ms while held.
371*5f2e058dSBenjamin Tissoires  *
372*5f2e058dSBenjamin Tissoires  *				0x0f		Wheels
373*5f2e058dSBenjamin Tissoires  *							data[3] == 1: top wheel
374*5f2e058dSBenjamin Tissoires  *							data[3] == 2: bottom wheel
375*5f2e058dSBenjamin Tissoires  *							data[5] == 1: clockwise
376*5f2e058dSBenjamin Tissoires  *							data[5] == 2: counter-clockwise
377*5f2e058dSBenjamin Tissoires  *
378*5f2e058dSBenjamin Tissoires  *				0x08/0x00	Pen
379*5f2e058dSBenjamin Tissoires  *							report_subtype == 0x08: in-range
380*5f2e058dSBenjamin Tissoires  *							report_subtype == 0x00: out-of-range
381*5f2e058dSBenjamin Tissoires  *								For clarity, this is also equivalent to:
382*5f2e058dSBenjamin Tissoires  *									(data[1] & 0x80)	in-range
383*5f2e058dSBenjamin Tissoires  *
384*5f2e058dSBenjamin Tissoires  *							Switches
385*5f2e058dSBenjamin Tissoires  *								(data[1] & 0x01)	tip switch
386*5f2e058dSBenjamin Tissoires  *								(data[1] & 0x02)	barrel switch
387*5f2e058dSBenjamin Tissoires  *								(data[1] & 0x04)	secondary barrel switch
388*5f2e058dSBenjamin Tissoires  *								(data[1] & 0x08)	third barrel switch
389*5f2e058dSBenjamin Tissoires  *
390*5f2e058dSBenjamin Tissoires  *								Unfortunately, I don't have a pen with an eraser, so I can't
391*5f2e058dSBenjamin Tissoires  *								confirm where the invert and eraser bits reside.
392*5f2e058dSBenjamin Tissoires  *								If we guess using the definitions from HID descriptor 1,
393*5f2e058dSBenjamin Tissoires  *								then they might be...
394*5f2e058dSBenjamin Tissoires  *									(data[1] & 0x08)	invert (conflicts with third barrel switch)
395*5f2e058dSBenjamin Tissoires  *									(data[1] & 0x10)	eraser
396*5f2e058dSBenjamin Tissoires  *
397*5f2e058dSBenjamin Tissoires  *							data[2], data[3]	X (little-endian, maximum 0xe588)
398*5f2e058dSBenjamin Tissoires  *
399*5f2e058dSBenjamin Tissoires  *							data[4], data[5]	Y (little-endian, maximum 0x8110)
400*5f2e058dSBenjamin Tissoires  *
401*5f2e058dSBenjamin Tissoires  *							data[6], data[7]	Pressure (little-endian, maximum 0x3fff)
402*5f2e058dSBenjamin Tissoires  *
403*5f2e058dSBenjamin Tissoires  *							data[10]		X tilt	(signed, -60 to +60)
404*5f2e058dSBenjamin Tissoires  *							data[11]		Y tilt	(signed, -60 to +60, inverted)
405*5f2e058dSBenjamin Tissoires  *
406*5f2e058dSBenjamin Tissoires  *
407*5f2e058dSBenjamin Tissoires  *		EXAMPLE REPORTS
408*5f2e058dSBenjamin Tissoires  *			Top wheel button, press, hold, then release
409*5f2e058dSBenjamin Tissoires  *				E: 000000.000040 14 08 e0 01 01 20 00 00 00 00 00 00 00 00 00
410*5f2e058dSBenjamin Tissoires  *				E: 000001.531559 14 08 e0 01 01 00 00 00 00 00 00 00 00 00 00
411*5f2e058dSBenjamin Tissoires  *
412*5f2e058dSBenjamin Tissoires  *			Bottom wheel button, press, hold, then release
413*5f2e058dSBenjamin Tissoires  *				E: 000002.787603 14 08 e0 01 01 40 00 00 00 00 00 00 00 00 00
414*5f2e058dSBenjamin Tissoires  *				E: 000004.215609 14 08 e0 01 01 00 00 00 00 00 00 00 00 00 00
415*5f2e058dSBenjamin Tissoires  *
416*5f2e058dSBenjamin Tissoires  *
417*5f2e058dSBenjamin Tissoires  *			Top wheel rotation, one detent CW
418*5f2e058dSBenjamin Tissoires  *				E: 000194.003899 14 08 f1 01 01 00 01 00 00 00 00 00 00 00 00
419*5f2e058dSBenjamin Tissoires  *
420*5f2e058dSBenjamin Tissoires  *			Top wheel rotation, one detent CCW
421*5f2e058dSBenjamin Tissoires  *				E: 000194.997812 14 08 f1 01 01 00 02 00 00 00 00 00 00 00 00
422*5f2e058dSBenjamin Tissoires  *
423*5f2e058dSBenjamin Tissoires  *			Bottom wheel rotation, one detent CW
424*5f2e058dSBenjamin Tissoires  *				E: 000196.693840 14 08 f1 01 02 00 01 00 00 00 00 00 00 00 00
425*5f2e058dSBenjamin Tissoires  *
426*5f2e058dSBenjamin Tissoires  *			Bottom wheel rotation, one detent CCW
427*5f2e058dSBenjamin Tissoires  *				E: 000197.757895 14 08 f1 01 02 00 02 00 00 00 00 00 00 00 00
428*5f2e058dSBenjamin Tissoires  *
429*5f2e058dSBenjamin Tissoires  *
430*5f2e058dSBenjamin Tissoires  *			Button 1, press, hold, then release
431*5f2e058dSBenjamin Tissoires  *				E: 000000.000149 14 08 e0 01 01 01 00 00 00 00 00 00 00 00 00 < press
432*5f2e058dSBenjamin Tissoires  *				E: 000000.447598 14 08 e0 01 01 01 00 00 00 00 00 00 00 00 00 < starting to auto-repeat, every ~225ms
433*5f2e058dSBenjamin Tissoires  *				E: 000000.673586 14 08 e0 01 01 01 00 00 00 00 00 00 00 00 00
434*5f2e058dSBenjamin Tissoires  *				E: 000000.900582 14 08 e0 01 01 01 00 00 00 00 00 00 00 00 00
435*5f2e058dSBenjamin Tissoires  *				E: 000001.126703 14 08 e0 01 01 01 00 00 00 00 00 00 00 00 00
436*5f2e058dSBenjamin Tissoires  *				E: 000001.347706 14 08 e0 01 01 01 00 00 00 00 00 00 00 00 00
437*5f2e058dSBenjamin Tissoires  *				E: 000001.533721 14 08 e0 01 01 00 00 00 00 00 00 00 00 00 00 < release
438*5f2e058dSBenjamin Tissoires  *
439*5f2e058dSBenjamin Tissoires  *			Button 2, press, hold, then release
440*5f2e058dSBenjamin Tissoires  *				E: 000003.304735 14 08 e0 01 01 02 00 00 00 00 00 00 00 00 00 < press
441*5f2e058dSBenjamin Tissoires  *				E: 000003.746743 14 08 e0 01 01 02 00 00 00 00 00 00 00 00 00 < starting to auto-repeat, every ~225ms
442*5f2e058dSBenjamin Tissoires  *				E: 000003.973741 14 08 e0 01 01 02 00 00 00 00 00 00 00 00 00
443*5f2e058dSBenjamin Tissoires  *				E: 000004.199832 14 08 e0 01 01 02 00 00 00 00 00 00 00 00 00
444*5f2e058dSBenjamin Tissoires  *				E: 000004.426732 14 08 e0 01 01 02 00 00 00 00 00 00 00 00 00
445*5f2e058dSBenjamin Tissoires  *				E: 000004.647738 14 08 e0 01 01 02 00 00 00 00 00 00 00 00 00
446*5f2e058dSBenjamin Tissoires  *				E: 000004.874733 14 08 e0 01 01 02 00 00 00 00 00 00 00 00 00
447*5f2e058dSBenjamin Tissoires  *				E: 000004.930713 14 08 e0 01 01 00 00 00 00 00 00 00 00 00 00 < release
448*5f2e058dSBenjamin Tissoires  *
449*5f2e058dSBenjamin Tissoires  *			Button 3, press, hold, then release
450*5f2e058dSBenjamin Tissoires  *				E: 000006.650346 14 08 e0 01 01 04 00 00 00 00 00 00 00 00 00 < press
451*5f2e058dSBenjamin Tissoires  *				E: 000007.051782 14 08 e0 01 01 04 00 00 00 00 00 00 00 00 00 < starting to auto-repeat, every ~225ms
452*5f2e058dSBenjamin Tissoires  *				E: 000007.273738 14 08 e0 01 01 04 00 00 00 00 00 00 00 00 00
453*5f2e058dSBenjamin Tissoires  *				E: 000007.499794 14 08 e0 01 01 04 00 00 00 00 00 00 00 00 00
454*5f2e058dSBenjamin Tissoires  *				E: 000007.726725 14 08 e0 01 01 04 00 00 00 00 00 00 00 00 00
455*5f2e058dSBenjamin Tissoires  *				E: 000007.947765 14 08 e0 01 01 04 00 00 00 00 00 00 00 00 00
456*5f2e058dSBenjamin Tissoires  *				E: 000008.174755 14 08 e0 01 01 04 00 00 00 00 00 00 00 00 00
457*5f2e058dSBenjamin Tissoires  *				E: 000008.328786 14 08 e0 01 01 00 00 00 00 00 00 00 00 00 00 < release
458*5f2e058dSBenjamin Tissoires  *
459*5f2e058dSBenjamin Tissoires  *			Button 4, press, hold, then release
460*5f2e058dSBenjamin Tissoires  *				E: 000009.893820 14 08 e0 01 01 08 00 00 00 00 00 00 00 00 00 < press
461*5f2e058dSBenjamin Tissoires  *				E: 000010.274781 14 08 e0 01 01 08 00 00 00 00 00 00 00 00 00 < starting to auto-repeat, every ~225ms
462*5f2e058dSBenjamin Tissoires  *				E: 000010.500931 14 08 e0 01 01 08 00 00 00 00 00 00 00 00 00
463*5f2e058dSBenjamin Tissoires  *				E: 000010.722777 14 08 e0 01 01 08 00 00 00 00 00 00 00 00 00
464*5f2e058dSBenjamin Tissoires  *				E: 000010.948778 14 08 e0 01 01 08 00 00 00 00 00 00 00 00 00
465*5f2e058dSBenjamin Tissoires  *				E: 000011.175799 14 08 e0 01 01 08 00 00 00 00 00 00 00 00 00
466*5f2e058dSBenjamin Tissoires  *				E: 000011.401153 14 08 e0 01 01 08 00 00 00 00 00 00 00 00 00
467*5f2e058dSBenjamin Tissoires  *				E: 000011.432114 14 08 e0 01 01 00 00 00 00 00 00 00 00 00 00 < release
468*5f2e058dSBenjamin Tissoires  *
469*5f2e058dSBenjamin Tissoires  *			Button 5, press, hold, then release
470*5f2e058dSBenjamin Tissoires  *				E: 000013.007778 14 08 e0 01 01 10 00 00 00 00 00 00 00 00 00 < press
471*5f2e058dSBenjamin Tissoires  *				E: 000013.424741 14 08 e0 01 01 10 00 00 00 00 00 00 00 00 00 < starting to auto-repeat, every ~225ms
472*5f2e058dSBenjamin Tissoires  *				E: 000013.651715 14 08 e0 01 01 10 00 00 00 00 00 00 00 00 00
473*5f2e058dSBenjamin Tissoires  *				E: 000013.872763 14 08 e0 01 01 10 00 00 00 00 00 00 00 00 00
474*5f2e058dSBenjamin Tissoires  *				E: 000014.099789 14 08 e0 01 01 10 00 00 00 00 00 00 00 00 00
475*5f2e058dSBenjamin Tissoires  *				E: 000014.325734 14 08 e0 01 01 10 00 00 00 00 00 00 00 00 00
476*5f2e058dSBenjamin Tissoires  *				E: 000014.438080 14 08 e0 01 01 00 00 00 00 00 00 00 00 00 00 < release
477*5f2e058dSBenjamin Tissoires  *
478*5f2e058dSBenjamin Tissoires  *
479*5f2e058dSBenjamin Tissoires  *			Pen: Top-left, then out of range
480*5f2e058dSBenjamin Tissoires  *				E: 000368.572184 14 08 80 00 00 00 00 00 00 00 00 fb ed 03 00
481*5f2e058dSBenjamin Tissoires  *				E: 000368.573030 14 08 00 00 00 00 00 00 00 00 00 fb ed 03 00
482*5f2e058dSBenjamin Tissoires  *
483*5f2e058dSBenjamin Tissoires  *			Pen: Bottom-right, then out of range
484*5f2e058dSBenjamin Tissoires  *				E: 000544.433185 14 08 80 88 e5 10 81 00 00 00 00 00 00 03 00
485*5f2e058dSBenjamin Tissoires  *				E: 000544.434183 14 08 00 88 e5 10 81 00 00 00 00 00 00 03 00
486*5f2e058dSBenjamin Tissoires  *
487*5f2e058dSBenjamin Tissoires  *			Pen: Max Y tilt (tip of pen points down)
488*5f2e058dSBenjamin Tissoires  *				E: 000002.231927 14 08 80 f5 5d 6c 36 00 00 00 00 09 3c 03 00
489*5f2e058dSBenjamin Tissoires  *
490*5f2e058dSBenjamin Tissoires  *			Pen: Min Y Tilt (tip of pen points up)
491*5f2e058dSBenjamin Tissoires  *				E: 000657.593338 14 08 80 5f 69 fa 2c 00 00 00 00 fe c4 03 00
492*5f2e058dSBenjamin Tissoires  *
493*5f2e058dSBenjamin Tissoires  *			Pen: Max X tilt (tip of pen points left)
494*5f2e058dSBenjamin Tissoires  *				E: 000742.246503 14 08 80 2a 4f c4 38 00 00 00 00 3c ed 03 00
495*5f2e058dSBenjamin Tissoires  *
496*5f2e058dSBenjamin Tissoires  *			Pen: Min X Tilt (tip of pen points right)
497*5f2e058dSBenjamin Tissoires  *				E: 000776.404446 14 08 00 18 85 7c 3b 00 00 00 00 c4 ed 03 00
498*5f2e058dSBenjamin Tissoires  *
499*5f2e058dSBenjamin Tissoires  *			Pen: Tip switch, max pressure, then low pressure
500*5f2e058dSBenjamin Tissoires  *				E: 001138.935675 14 08 81 d2 66 04 40 ff 3f 00 00 00 08 03 00
501*5f2e058dSBenjamin Tissoires  *
502*5f2e058dSBenjamin Tissoires  *				E: 001142.403715 14 08 81 9d 69 47 3e 82 04 00 00 00 07 03 00
503*5f2e058dSBenjamin Tissoires  *
504*5f2e058dSBenjamin Tissoires  *			Pen: Barrel switch
505*5f2e058dSBenjamin Tissoires  *				E: 001210.645652 14 08 82 0d 72 ea 2b 00 00 00 00 db c4 03 00
506*5f2e058dSBenjamin Tissoires  *
507*5f2e058dSBenjamin Tissoires  *			Pen: Secondary barrel switch
508*5f2e058dSBenjamin Tissoires  *				E: 001211.519729 14 08 84 2c 71 51 2b 00 00 00 00 da c4 03 00
509*5f2e058dSBenjamin Tissoires  *
510*5f2e058dSBenjamin Tissoires  *			Pen: Third switch
511*5f2e058dSBenjamin Tissoires  *				E: 001212.443722 14 08 88 1d 72 df 2b 00 00 00 00 dc c4 03 00
512*5f2e058dSBenjamin Tissoires  *
513*5f2e058dSBenjamin Tissoires  *
514*5f2e058dSBenjamin Tissoires  *	HIDRAW 1
515*5f2e058dSBenjamin Tissoires  *		No reports
516*5f2e058dSBenjamin Tissoires  *
517*5f2e058dSBenjamin Tissoires  *
518*5f2e058dSBenjamin Tissoires  *	HIDRAW 2
519*5f2e058dSBenjamin Tissoires  *		No reports
520*5f2e058dSBenjamin Tissoires  *
521*5f2e058dSBenjamin Tissoires  *
522*5f2e058dSBenjamin Tissoires  *
523*5f2e058dSBenjamin Tissoires  *
524*5f2e058dSBenjamin Tissoires  *
525*5f2e058dSBenjamin Tissoires  *
526*5f2e058dSBenjamin Tissoires  *
527*5f2e058dSBenjamin Tissoires  *
528*5f2e058dSBenjamin Tissoires  * FIRMWARE MODE
529*5f2e058dSBenjamin Tissoires  *	HIDRAW 0
530*5f2e058dSBenjamin Tissoires  *		No reports
531*5f2e058dSBenjamin Tissoires  *
532*5f2e058dSBenjamin Tissoires  *
533*5f2e058dSBenjamin Tissoires  *	HIDRAW 1
534*5f2e058dSBenjamin Tissoires  *		EXAMPLE REPORTS
535*5f2e058dSBenjamin Tissoires  *			Top wheel button, *release*
536*5f2e058dSBenjamin Tissoires  *				E: 000067.043739 8 03 00 00 00 00 00 00 00
537*5f2e058dSBenjamin Tissoires  *
538*5f2e058dSBenjamin Tissoires  *			Bottom wheel button, *release*
539*5f2e058dSBenjamin Tissoires  *				E: 000068.219161 8 03 00 00 00 00 00 00 00
540*5f2e058dSBenjamin Tissoires  *
541*5f2e058dSBenjamin Tissoires  *
542*5f2e058dSBenjamin Tissoires  *			Button 1, press, then release
543*5f2e058dSBenjamin Tissoires  *				E: 000163.767870 8 03 00 05 00 00 00 00 00
544*5f2e058dSBenjamin Tissoires  *				E: 000165.969193 8 03 00 00 00 00 00 00 00
545*5f2e058dSBenjamin Tissoires  *
546*5f2e058dSBenjamin Tissoires  *			Button 2, press, then release
547*5f2e058dSBenjamin Tissoires  *				E: 000261.728935 8 03 05 11 00 00 00 00 00
548*5f2e058dSBenjamin Tissoires  *				E: 000262.956220 8 03 00 00 00 00 00 00 00
549*5f2e058dSBenjamin Tissoires  *
550*5f2e058dSBenjamin Tissoires  *			Button 3, press, then release
551*5f2e058dSBenjamin Tissoires  *				E: 000289.127881 8 03 01 16 00 00 00 00 00
552*5f2e058dSBenjamin Tissoires  *				E: 000290.014594 8 03 00 00 00 00 00 00 00
553*5f2e058dSBenjamin Tissoires  *
554*5f2e058dSBenjamin Tissoires  *			Button 4, press, then release
555*5f2e058dSBenjamin Tissoires  *				E: 000303.025839 8 03 00 2c 00 00 00 00 00
556*5f2e058dSBenjamin Tissoires  *				E: 000303.994479 8 03 00 00 00 00 00 00 00
557*5f2e058dSBenjamin Tissoires  *
558*5f2e058dSBenjamin Tissoires  *			Button 5, press, then release
559*5f2e058dSBenjamin Tissoires  *				E: 000315.500835 8 03 05 1d 00 00 00 00 00
560*5f2e058dSBenjamin Tissoires  *				E: 000316.603274 8 03 00 00 00 00 00 00 00
561*5f2e058dSBenjamin Tissoires  *
562*5f2e058dSBenjamin Tissoires  *			BUTTON SUMMARY
563*5f2e058dSBenjamin Tissoires  *					1	E: 000163.767870 8 03 00 05 00 00 00 00 00   Keyboard: B
564*5f2e058dSBenjamin Tissoires  *					2	E: 000261.728935 8 03 05 11 00 00 00 00 00   Keyboard: LCtrl+LAlt N
565*5f2e058dSBenjamin Tissoires  *					3	E: 000289.127881 8 03 01 16 00 00 00 00 00   Keyboard: LCtrl S
566*5f2e058dSBenjamin Tissoires  *					4	E: 000303.025839 8 03 00 2c 00 00 00 00 00   Keyboard: Space
567*5f2e058dSBenjamin Tissoires  *					5	E: 000315.500835 8 03 05 1d 00 00 00 00 00   Keyboard: LCtrl+LAlt
568*5f2e058dSBenjamin Tissoires  *
569*5f2e058dSBenjamin Tissoires  *					All buttons (including the wheel buttons) release the same way:
570*5f2e058dSBenjamin Tissoires  *						03 00 00 00 00 00 00 00
571*5f2e058dSBenjamin Tissoires  *
572*5f2e058dSBenjamin Tissoires  *
573*5f2e058dSBenjamin Tissoires  *			Pen: Top-left, then out of range
574*5f2e058dSBenjamin Tissoires  *				E: 000063.196828 10 0a c0 00 00 00 00 00 00 00 02
575*5f2e058dSBenjamin Tissoires  *				E: 000063.197762 10 0a 00 00 00 00 00 00 00 00 02
576*5f2e058dSBenjamin Tissoires  *
577*5f2e058dSBenjamin Tissoires  *			Pen: Bottom-right, then out of range
578*5f2e058dSBenjamin Tissoires  *				E: 000197.123138 10 0a c0 ff 7f ff 7f 00 00 00 00
579*5f2e058dSBenjamin Tissoires  *				E: 000197.124915 10 0a 00 ff 7f ff 7f 00 00 00 00
580*5f2e058dSBenjamin Tissoires  *
581*5f2e058dSBenjamin Tissoires  *			Pen: Max Y Tilt (tip of pen points up)
582*5f2e058dSBenjamin Tissoires  *				E: 000291.399541 10 0a c0 19 32 0b 58 00 00 00 3c
583*5f2e058dSBenjamin Tissoires  *
584*5f2e058dSBenjamin Tissoires  *			Pen: Min Y tilt (tip of pen points down)
585*5f2e058dSBenjamin Tissoires  *				E: 000340.888288 10 0a c0 85 40 89 6e 00 00 17 c4
586*5f2e058dSBenjamin Tissoires  *
587*5f2e058dSBenjamin Tissoires  *			Pen: Max X tilt (tip of pen points left)
588*5f2e058dSBenjamin Tissoires  *				E: 000165.575115 10 0a c0 a7 34 99 42 00 00 3c f4
589*5f2e058dSBenjamin Tissoires  *
590*5f2e058dSBenjamin Tissoires  *			Pen: Min X Tilt (tip of pen points right)
591*5f2e058dSBenjamin Tissoires  *				E: 000129.507883 10 0a c0 ea 4b 08 40 00 00 c4 1a
592*5f2e058dSBenjamin Tissoires  *
593*5f2e058dSBenjamin Tissoires  *			Pen: Tip switch, max pressure, then low pressure
594*5f2e058dSBenjamin Tissoires  *				E: 000242.077160 10 0a c1 7e 3c 12 31 ff 3f 03 fd
595*5f2e058dSBenjamin Tissoires  *
596*5f2e058dSBenjamin Tissoires  *				E: 000339.139188 10 0a c1 ee 3a 9e 32 b5 00 06 f6
597*5f2e058dSBenjamin Tissoires  *
598*5f2e058dSBenjamin Tissoires  *			Pen: Barrel switch
599*5f2e058dSBenjamin Tissoires  *				E: 000037.949777 10 0a c2 5c 28 47 2a 00 00 f6 3c
600*5f2e058dSBenjamin Tissoires  *
601*5f2e058dSBenjamin Tissoires  *			Pen: Secondary barrel switch
602*5f2e058dSBenjamin Tissoires  *				E: 000038.320840 10 0a c4 e4 27 fd 29 00 00 f3 38
603*5f2e058dSBenjamin Tissoires  *
604*5f2e058dSBenjamin Tissoires  *			Pen: Third switch
605*5f2e058dSBenjamin Tissoires  *				E: 000038.923822 10 0a c8 97 27 5f 29 00 00 f2 33
606*5f2e058dSBenjamin Tissoires  *
607*5f2e058dSBenjamin Tissoires  *
608*5f2e058dSBenjamin Tissoires  *	HIDRAW 2
609*5f2e058dSBenjamin Tissoires  *		EXAMPLE REPORTS
610*5f2e058dSBenjamin Tissoires  *			Either wheel rotation, one detent CW
611*5f2e058dSBenjamin Tissoires  *				E: 000097.276573 9 11 00 01 00 00 00 00 00 00
612*5f2e058dSBenjamin Tissoires  *
613*5f2e058dSBenjamin Tissoires  *			Either wheel rotation, one detent CCW
614*5f2e058dSBenjamin Tissoires  *				E: 000153.416538 9 11 00 ff ff 00 00 00 00 00
615*5f2e058dSBenjamin Tissoires  *
616*5f2e058dSBenjamin Tissoires  *			Either wheel rotation, increasing rotation speed CW
617*5f2e058dSBenjamin Tissoires  *				(Note that the wheels on my particular tablet may be
618*5f2e058dSBenjamin Tissoires  *				 damaged, so the false rotation direction changes
619*5f2e058dSBenjamin Tissoires  *				 that can be observed might not happen on other units.)
620*5f2e058dSBenjamin Tissoires  *				E: 000210.514925 9 11 00 01 00 00 00 00 00 00
621*5f2e058dSBenjamin Tissoires  *				E: 000210.725718 9 11 00 01 00 00 00 00 00 00
622*5f2e058dSBenjamin Tissoires  *				E: 000210.924009 9 11 00 01 00 00 00 00 00 00
623*5f2e058dSBenjamin Tissoires  *				E: 000211.205629 9 11 00 01 00 00 00 00 00 00
624*5f2e058dSBenjamin Tissoires  *				E: 000211.280521 9 11 00 0b 00 00 00 00 00 00
625*5f2e058dSBenjamin Tissoires  *				E: 000211.340121 9 11 00 0e 00 00 00 00 00 00
626*5f2e058dSBenjamin Tissoires  *				E: 000211.404018 9 11 00 0d 00 00 00 00 00 00
627*5f2e058dSBenjamin Tissoires  *				E: 000211.462060 9 11 00 0e 00 00 00 00 00 00
628*5f2e058dSBenjamin Tissoires  *				E: 000211.544886 9 11 00 0a 00 00 00 00 00 00
629*5f2e058dSBenjamin Tissoires  *				E: 000211.606130 9 11 00 0d 00 00 00 00 00 00
630*5f2e058dSBenjamin Tissoires  *				E: 000211.674560 9 11 00 0c 00 00 00 00 00 00
631*5f2e058dSBenjamin Tissoires  *				E: 000211.712039 9 11 00 16 00 00 00 00 00 00
632*5f2e058dSBenjamin Tissoires  *				E: 000211.748076 9 11 00 17 00 00 00 00 00 00
633*5f2e058dSBenjamin Tissoires  *				E: 000211.786016 9 11 00 17 00 00 00 00 00 00
634*5f2e058dSBenjamin Tissoires  *				E: 000211.832960 9 11 00 11 00 00 00 00 00 00
635*5f2e058dSBenjamin Tissoires  *				E: 000211.874081 9 11 00 14 00 00 00 00 00 00
636*5f2e058dSBenjamin Tissoires  *				E: 000211.925094 9 11 00 10 00 00 00 00 00 00
637*5f2e058dSBenjamin Tissoires  *				E: 000211.959048 9 11 00 18 00 00 00 00 00 00
638*5f2e058dSBenjamin Tissoires  *				E: 000212.006937 9 11 00 11 00 00 00 00 00 00
639*5f2e058dSBenjamin Tissoires  *				E: 000212.050055 9 11 00 13 00 00 00 00 00 00
640*5f2e058dSBenjamin Tissoires  *				E: 000212.091947 9 11 00 14 00 00 00 00 00 00
641*5f2e058dSBenjamin Tissoires  *				E: 000212.122989 9 11 00 1a 00 00 00 00 00 00
642*5f2e058dSBenjamin Tissoires  *				E: 000212.160866 9 11 00 16 00 00 00 00 00 00
643*5f2e058dSBenjamin Tissoires  *				E: 000212.194002 9 11 00 19 00 00 00 00 00 00
644*5f2e058dSBenjamin Tissoires  *				E: 000212.242249 9 11 00 11 00 00 00 00 00 00
645*5f2e058dSBenjamin Tissoires  *				E: 000212.278061 9 11 00 18 00 00 00 00 00 00
646*5f2e058dSBenjamin Tissoires  *				E: 000212.328899 9 11 00 10 00 00 00 00 00 00
647*5f2e058dSBenjamin Tissoires  *				E: 000212.354005 9 11 00 22 00 00 00 00 00 00
648*5f2e058dSBenjamin Tissoires  *				E: 000212.398995 9 11 00 12 00 00 00 00 00 00
649*5f2e058dSBenjamin Tissoires  *				E: 000212.432050 9 11 00 19 00 00 00 00 00 00
650*5f2e058dSBenjamin Tissoires  *				E: 000212.471164 9 11 00 16 00 00 00 00 00 00
651*5f2e058dSBenjamin Tissoires  *				E: 000212.507047 9 11 00 17 00 00 00 00 00 00
652*5f2e058dSBenjamin Tissoires  *				E: 000212.540964 9 11 00 19 00 00 00 00 00 00
653*5f2e058dSBenjamin Tissoires  *				E: 000212.567942 9 11 00 1f 00 00 00 00 00 00
654*5f2e058dSBenjamin Tissoires  *				E: 000212.610007 9 11 00 14 00 00 00 00 00 00
655*5f2e058dSBenjamin Tissoires  *				E: 000212.641101 9 11 00 1b 00 00 00 00 00 00
656*5f2e058dSBenjamin Tissoires  *				E: 000212.674113 9 11 00 19 00 00 00 00 00 00
657*5f2e058dSBenjamin Tissoires  *				E: 000212.674909 9 11 00 01 00 00 00 00 00 00
658*5f2e058dSBenjamin Tissoires  *				E: 000212.677062 9 11 00 00 02 00 00 00 00 00
659*5f2e058dSBenjamin Tissoires  *				E: 000212.679048 9 11 00 55 01 00 00 00 00 00
660*5f2e058dSBenjamin Tissoires  *				E: 000212.682166 9 11 00 55 01 00 00 00 00 00
661*5f2e058dSBenjamin Tissoires  *				E: 000212.682788 9 11 00 ff ff 00 00 00 00 00
662*5f2e058dSBenjamin Tissoires  *				E: 000212.683899 9 11 00 01 00 00 00 00 00 00
663*5f2e058dSBenjamin Tissoires  *				E: 000212.685827 9 11 00 67 fe 00 00 00 00 00
664*5f2e058dSBenjamin Tissoires  *				E: 000212.686941 9 11 00 00 08 00 00 00 00 00
665*5f2e058dSBenjamin Tissoires  *				E: 000212.727840 9 11 00 14 00 00 00 00 00 00
666*5f2e058dSBenjamin Tissoires  *				E: 000212.772884 9 11 00 13 00 00 00 00 00 00
667*5f2e058dSBenjamin Tissoires  *				E: 000212.810975 9 11 00 16 00 00 00 00 00 00
668*5f2e058dSBenjamin Tissoires  *				E: 000212.811793 9 11 00 00 08 00 00 00 00 00
669*5f2e058dSBenjamin Tissoires  *				E: 000212.812683 9 11 00 01 00 00 00 00 00 00
670*5f2e058dSBenjamin Tissoires  *				E: 000212.813905 9 11 00 01 00 00 00 00 00 00
671*5f2e058dSBenjamin Tissoires  *				E: 000212.814909 9 11 00 00 04 00 00 00 00 00
672*5f2e058dSBenjamin Tissoires  *				E: 000212.816942 9 11 00 01 00 00 00 00 00 00
673*5f2e058dSBenjamin Tissoires  *				E: 000212.817851 9 11 00 ff ff 00 00 00 00 00
674*5f2e058dSBenjamin Tissoires  *				E: 000212.818752 9 11 00 01 00 00 00 00 00 00
675*5f2e058dSBenjamin Tissoires  *				E: 000212.819910 9 11 00 56 fd 00 00 00 00 00
676*5f2e058dSBenjamin Tissoires  *				E: 000212.820781 9 11 00 ff ff 00 00 00 00 00
677*5f2e058dSBenjamin Tissoires  *				E: 000212.821811 9 11 00 00 04 00 00 00 00 00
678*5f2e058dSBenjamin Tissoires  *				E: 000212.822920 9 11 00 00 08 00 00 00 00 00
679*5f2e058dSBenjamin Tissoires  *				E: 000212.823861 9 11 00 00 02 00 00 00 00 00
680*5f2e058dSBenjamin Tissoires  *				E: 000212.828781 9 11 00 ba 00 00 00 00 00 00
681*5f2e058dSBenjamin Tissoires  *				E: 000212.874097 9 11 00 12 00 00 00 00 00 00
682*5f2e058dSBenjamin Tissoires  *				E: 000212.874872 9 11 00 00 fc 00 00 00 00 00
683*5f2e058dSBenjamin Tissoires  *				E: 000212.876136 9 11 00 00 fc 00 00 00 00 00
684*5f2e058dSBenjamin Tissoires  *				E: 000212.877036 9 11 00 00 f8 00 00 00 00 00
685*5f2e058dSBenjamin Tissoires  *				E: 000212.877993 9 11 00 00 f8 00 00 00 00 00
686*5f2e058dSBenjamin Tissoires  *				E: 000212.879748 9 11 00 01 00 00 00 00 00 00
687*5f2e058dSBenjamin Tissoires  *				E: 000212.880728 9 11 00 01 00 00 00 00 00 00
688*5f2e058dSBenjamin Tissoires  *				E: 000212.881956 9 11 00 00 04 00 00 00 00 00
689*5f2e058dSBenjamin Tissoires  *				E: 000212.885065 9 11 00 ff ff 00 00 00 00 00
690*5f2e058dSBenjamin Tissoires  *				E: 000212.917060 9 11 00 1a 00 00 00 00 00 00
691*5f2e058dSBenjamin Tissoires  *				E: 000212.936458 9 11 00 2d 00 00 00 00 00 00
692*5f2e058dSBenjamin Tissoires  *				E: 000212.957860 9 11 00 25 00 00 00 00 00 00
693*5f2e058dSBenjamin Tissoires  *				E: 000212.984019 9 11 00 20 00 00 00 00 00 00
694*5f2e058dSBenjamin Tissoires  *				E: 000213.017915 9 11 00 19 00 00 00 00 00 00
695*5f2e058dSBenjamin Tissoires  *				E: 000213.039973 9 11 00 27 00 00 00 00 00 00
696*5f2e058dSBenjamin Tissoires  *				E: 000213.065933 9 11 00 21 00 00 00 00 00 00
697*5f2e058dSBenjamin Tissoires  *				E: 000213.085807 9 11 00 28 00 00 00 00 00 00
698*5f2e058dSBenjamin Tissoires  *				E: 000213.108888 9 11 00 25 00 00 00 00 00 00
699*5f2e058dSBenjamin Tissoires  *				E: 000213.129726 9 11 00 29 00 00 00 00 00 00
700*5f2e058dSBenjamin Tissoires  *				E: 000213.172043 9 11 00 14 00 00 00 00 00 00
701*5f2e058dSBenjamin Tissoires  *				E: 000213.195873 9 11 00 23 00 00 00 00 00 00
702*5f2e058dSBenjamin Tissoires  *				E: 000213.222884 9 11 00 20 00 00 00 00 00 00
703*5f2e058dSBenjamin Tissoires  *				E: 000213.243220 9 11 00 2a 00 00 00 00 00 00
704*5f2e058dSBenjamin Tissoires  *				E: 000213.266778 9 11 00 24 00 00 00 00 00 00
705*5f2e058dSBenjamin Tissoires  *				E: 000213.285951 9 11 00 2b 00 00 00 00 00 00
706*5f2e058dSBenjamin Tissoires  *				E: 000213.306045 9 11 00 2a 00 00 00 00 00 00
707*5f2e058dSBenjamin Tissoires  *				E: 000213.306796 9 11 00 ff ff 00 00 00 00 00
708*5f2e058dSBenjamin Tissoires  *				E: 000213.307755 9 11 00 ff ff 00 00 00 00 00
709*5f2e058dSBenjamin Tissoires  *				E: 000213.308820 9 11 00 ff ff 00 00 00 00 00
710*5f2e058dSBenjamin Tissoires  *				E: 000213.309971 9 11 00 ff ff 00 00 00 00 00
711*5f2e058dSBenjamin Tissoires  *				E: 000213.310980 9 11 00 01 00 00 00 00 00 00
712*5f2e058dSBenjamin Tissoires  *				E: 000213.311853 9 11 00 01 00 00 00 00 00 00
713*5f2e058dSBenjamin Tissoires  *				E: 000213.312861 9 11 00 aa 02 00 00 00 00 00
714*5f2e058dSBenjamin Tissoires  *				E: 000213.313884 9 11 00 00 f8 00 00 00 00 00
715*5f2e058dSBenjamin Tissoires  *				E: 000213.315111 9 11 00 ff ff 00 00 00 00 00
716*5f2e058dSBenjamin Tissoires  *				E: 000213.315992 9 11 00 01 00 00 00 00 00 00
717*5f2e058dSBenjamin Tissoires  *				E: 000213.316955 9 11 00 00 08 00 00 00 00 00
718*5f2e058dSBenjamin Tissoires  *				E: 000213.346065 9 11 00 1d 00 00 00 00 00 00
719*5f2e058dSBenjamin Tissoires  *				E: 000213.346963 9 11 00 ff ff 00 00 00 00 00
720*5f2e058dSBenjamin Tissoires  *				E: 000213.347874 9 11 00 00 08 00 00 00 00 00
721*5f2e058dSBenjamin Tissoires  *				E: 000213.348736 9 11 00 00 08 00 00 00 00 00
722*5f2e058dSBenjamin Tissoires  *				E: 000213.349795 9 11 00 00 04 00 00 00 00 00
723*5f2e058dSBenjamin Tissoires  *				E: 000213.350791 9 11 00 01 00 00 00 00 00 00
724*5f2e058dSBenjamin Tissoires  *				E: 000213.351791 9 11 00 01 00 00 00 00 00 00
725*5f2e058dSBenjamin Tissoires  *				E: 000213.352729 9 11 00 00 f8 00 00 00 00 00
726*5f2e058dSBenjamin Tissoires  *				E: 000213.353811 9 11 00 01 00 00 00 00 00 00
727*5f2e058dSBenjamin Tissoires  *				E: 000213.354755 9 11 00 00 f8 00 00 00 00 00
728*5f2e058dSBenjamin Tissoires  *				E: 000213.355795 9 11 00 00 f8 00 00 00 00 00
729*5f2e058dSBenjamin Tissoires  *				E: 000213.356813 9 11 00 01 00 00 00 00 00 00
730*5f2e058dSBenjamin Tissoires  *				E: 000213.357817 9 11 00 00 04 00 00 00 00 00
731*5f2e058dSBenjamin Tissoires  *				E: 000213.393838 9 11 00 17 00 00 00 00 00 00
732*5f2e058dSBenjamin Tissoires  *				E: 000213.394719 9 11 00 00 04 00 00 00 00 00
733*5f2e058dSBenjamin Tissoires  *				E: 000213.395682 9 11 00 00 08 00 00 00 00 00
734*5f2e058dSBenjamin Tissoires  *				E: 000213.396679 9 11 00 00 04 00 00 00 00 00
735*5f2e058dSBenjamin Tissoires  *				E: 000213.397651 9 11 00 00 fc 00 00 00 00 00
736*5f2e058dSBenjamin Tissoires  *				E: 000213.398661 9 11 00 ff ff 00 00 00 00 00
737*5f2e058dSBenjamin Tissoires  *				E: 000213.400308 9 11 00 56 fd 00 00 00 00 00
738*5f2e058dSBenjamin Tissoires  *				E: 000213.400909 9 11 00 00 f8 00 00 00 00 00
739*5f2e058dSBenjamin Tissoires  *				E: 000213.401837 9 11 00 01 00 00 00 00 00 00
740*5f2e058dSBenjamin Tissoires  *
741*5f2e058dSBenjamin Tissoires  *			Either wheel rotation, increasing rotation speed CCW
742*5f2e058dSBenjamin Tissoires  *				(Note that the wheels on my particular tablet may be
743*5f2e058dSBenjamin Tissoires  *				 damaged, so the false rotation direction changes
744*5f2e058dSBenjamin Tissoires  *				 that can be observed might not happen on other units.)
745*5f2e058dSBenjamin Tissoires  *				E: 000040.527820 9 11 00 ff ff 00 00 00 00 00
746*5f2e058dSBenjamin Tissoires  *				E: 000040.816644 9 11 00 ff ff 00 00 00 00 00
747*5f2e058dSBenjamin Tissoires  *				E: 000040.880423 9 11 00 f3 ff 00 00 00 00 00
748*5f2e058dSBenjamin Tissoires  *				E: 000040.882570 9 11 00 ff ff 00 00 00 00 00
749*5f2e058dSBenjamin Tissoires  *				E: 000040.883381 9 11 00 ff ff 00 00 00 00 00
750*5f2e058dSBenjamin Tissoires  *				E: 000040.885463 9 11 00 aa 02 00 00 00 00 00
751*5f2e058dSBenjamin Tissoires  *				E: 000040.924106 9 11 00 ea ff 00 00 00 00 00
752*5f2e058dSBenjamin Tissoires  *				E: 000041.006155 9 11 00 f6 ff 00 00 00 00 00
753*5f2e058dSBenjamin Tissoires  *				E: 000041.085799 9 11 00 f6 ff 00 00 00 00 00
754*5f2e058dSBenjamin Tissoires  *				E: 000041.168492 9 11 00 f6 ff 00 00 00 00 00
755*5f2e058dSBenjamin Tissoires  *				E: 000041.233453 9 11 00 f3 ff 00 00 00 00 00
756*5f2e058dSBenjamin Tissoires  *				E: 000041.296641 9 11 00 f3 ff 00 00 00 00 00
757*5f2e058dSBenjamin Tissoires  *				E: 000041.370302 9 11 00 f5 ff 00 00 00 00 00
758*5f2e058dSBenjamin Tissoires  *				E: 000041.437410 9 11 00 f4 ff 00 00 00 00 00
759*5f2e058dSBenjamin Tissoires  *				E: 000041.474514 9 11 00 e9 ff 00 00 00 00 00
760*5f2e058dSBenjamin Tissoires  *				E: 000041.522171 9 11 00 ef ff 00 00 00 00 00
761*5f2e058dSBenjamin Tissoires  *				E: 000041.568160 9 11 00 ee ff 00 00 00 00 00
762*5f2e058dSBenjamin Tissoires  *				E: 000041.608146 9 11 00 ec ff 00 00 00 00 00
763*5f2e058dSBenjamin Tissoires  *				E: 000041.627132 9 11 00 d3 ff 00 00 00 00 00
764*5f2e058dSBenjamin Tissoires  *				E: 000041.656151 9 11 00 e3 ff 00 00 00 00 00
765*5f2e058dSBenjamin Tissoires  *				E: 000041.682264 9 11 00 e0 ff 00 00 00 00 00
766*5f2e058dSBenjamin Tissoires  *				E: 000041.714186 9 11 00 e6 ff 00 00 00 00 00
767*5f2e058dSBenjamin Tissoires  *				E: 000041.740339 9 11 00 e0 ff 00 00 00 00 00
768*5f2e058dSBenjamin Tissoires  *				E: 000041.772087 9 11 00 e5 ff 00 00 00 00 00
769*5f2e058dSBenjamin Tissoires  *				E: 000041.801093 9 11 00 e3 ff 00 00 00 00 00
770*5f2e058dSBenjamin Tissoires  *				E: 000041.834051 9 11 00 e7 ff 00 00 00 00 00
771*5f2e058dSBenjamin Tissoires  *				E: 000041.863094 9 11 00 e3 ff 00 00 00 00 00
772*5f2e058dSBenjamin Tissoires  *				E: 000041.901016 9 11 00 ea ff 00 00 00 00 00
773*5f2e058dSBenjamin Tissoires  *				E: 000041.901956 9 11 00 00 04 00 00 00 00 00
774*5f2e058dSBenjamin Tissoires  *				E: 000041.902837 9 11 00 00 fe 00 00 00 00 00
775*5f2e058dSBenjamin Tissoires  *				E: 000041.903927 9 11 00 01 00 00 00 00 00 00
776*5f2e058dSBenjamin Tissoires  *				E: 000041.905066 9 11 00 01 00 00 00 00 00 00
777*5f2e058dSBenjamin Tissoires  *				E: 000041.907214 9 11 00 00 fe 00 00 00 00 00
778*5f2e058dSBenjamin Tissoires  *				E: 000041.909011 9 11 00 01 00 00 00 00 00 00
779*5f2e058dSBenjamin Tissoires  *				E: 000041.909953 9 11 00 01 00 00 00 00 00 00
780*5f2e058dSBenjamin Tissoires  *				E: 000041.910917 9 11 00 00 08 00 00 00 00 00
781*5f2e058dSBenjamin Tissoires  *				E: 000041.913280 9 11 00 00 fe 00 00 00 00 00
782*5f2e058dSBenjamin Tissoires  *				E: 000041.914121 9 11 00 56 fd 00 00 00 00 00
783*5f2e058dSBenjamin Tissoires  *				E: 000041.915346 9 11 00 ff ff 00 00 00 00 00
784*5f2e058dSBenjamin Tissoires  *				E: 000041.962101 9 11 00 ee ff 00 00 00 00 00
785*5f2e058dSBenjamin Tissoires  *				E: 000041.964062 9 11 00 56 fd 00 00 00 00 00
786*5f2e058dSBenjamin Tissoires  *				E: 000041.964978 9 11 00 00 fc 00 00 00 00 00
787*5f2e058dSBenjamin Tissoires  *				E: 000041.968058 9 11 00 24 01 00 00 00 00 00
788*5f2e058dSBenjamin Tissoires  *				E: 000041.968880 9 11 00 56 fd 00 00 00 00 00
789*5f2e058dSBenjamin Tissoires  *				E: 000041.970977 9 11 00 aa 02 00 00 00 00 00
790*5f2e058dSBenjamin Tissoires  *				E: 000041.971932 9 11 00 ff ff 00 00 00 00 00
791*5f2e058dSBenjamin Tissoires  *				E: 000041.972943 9 11 00 01 00 00 00 00 00 00
792*5f2e058dSBenjamin Tissoires  *				E: 000041.975291 9 11 00 ff ff 00 00 00 00 00
793*5f2e058dSBenjamin Tissoires  *				E: 000041.978274 9 11 00 01 00 00 00 00 00 00
794*5f2e058dSBenjamin Tissoires  *				E: 000042.035079 9 11 00 01 00 00 00 00 00 00
795*5f2e058dSBenjamin Tissoires  *				E: 000042.041283 9 11 00 ff ff 00 00 00 00 00
796*5f2e058dSBenjamin Tissoires  *				E: 000042.042057 9 11 00 00 04 00 00 00 00 00
797*5f2e058dSBenjamin Tissoires  *				E: 000042.045169 9 11 00 ff ff 00 00 00 00 00
798*5f2e058dSBenjamin Tissoires  *				E: 000042.051242 9 11 00 ff ff 00 00 00 00 00
799*5f2e058dSBenjamin Tissoires  *				E: 000042.056099 9 11 00 63 ff 00 00 00 00 00
800*5f2e058dSBenjamin Tissoires  *				E: 000042.106329 9 11 00 ef ff 00 00 00 00 00
801*5f2e058dSBenjamin Tissoires  *				E: 000042.108601 9 11 00 ff ff 00 00 00 00 00
802*5f2e058dSBenjamin Tissoires  *				E: 000042.116259 9 11 00 6b 00 00 00 00 00 00
803*5f2e058dSBenjamin Tissoires  *				E: 000042.119140 9 11 00 55 01 00 00 00 00 00
804*5f2e058dSBenjamin Tissoires  *				E: 000042.126101 9 11 00 88 ff 00 00 00 00 00
805*5f2e058dSBenjamin Tissoires  *				E: 000042.158009 9 11 00 e6 ff 00 00 00 00 00
806*5f2e058dSBenjamin Tissoires  *				E: 000042.172108 9 11 00 be ff 00 00 00 00 00
807*5f2e058dSBenjamin Tissoires  *				E: 000042.207417 9 11 00 e8 ff 00 00 00 00 00
808*5f2e058dSBenjamin Tissoires  *				E: 000042.223155 9 11 00 cc ff 00 00 00 00 00
809*5f2e058dSBenjamin Tissoires  *				E: 000042.255185 9 11 00 e6 ff 00 00 00 00 00
810*5f2e058dSBenjamin Tissoires  *				E: 000042.276280 9 11 00 d7 ff 00 00 00 00 00
811*5f2e058dSBenjamin Tissoires  *				E: 000042.302128 9 11 00 e0 ff 00 00 00 00 00
812*5f2e058dSBenjamin Tissoires  *				E: 000042.317423 9 11 00 c8 ff 00 00 00 00 00
813*5f2e058dSBenjamin Tissoires  *				E: 000042.345226 9 11 00 e1 ff 00 00 00 00 00
814*5f2e058dSBenjamin Tissoires  *				E: 000042.357243 9 11 00 bc ff 00 00 00 00 00
815*5f2e058dSBenjamin Tissoires  *				E: 000042.381308 9 11 00 dc ff 00 00 00 00 00
816*5f2e058dSBenjamin Tissoires  *				E: 000042.383180 9 11 00 dc fe 00 00 00 00 00
817*5f2e058dSBenjamin Tissoires  *				E: 000042.412288 9 11 00 e3 ff 00 00 00 00 00
818*5f2e058dSBenjamin Tissoires  *				E: 000042.451216 9 11 00 eb ff 00 00 00 00 00
819*5f2e058dSBenjamin Tissoires  *				E: 000042.478372 9 11 00 e0 ff 00 00 00 00 00
820*5f2e058dSBenjamin Tissoires  *				E: 000042.502116 9 11 00 dd ff 00 00 00 00 00
821*5f2e058dSBenjamin Tissoires  *				E: 000042.520105 9 11 00 d3 ff 00 00 00 00 00
822*5f2e058dSBenjamin Tissoires  *				E: 000042.540345 9 11 00 d6 ff 00 00 00 00 00
823*5f2e058dSBenjamin Tissoires  *				E: 000042.541021 9 11 00 00 08 00 00 00 00 00
824*5f2e058dSBenjamin Tissoires  *				E: 000042.542009 9 11 00 01 00 00 00 00 00 00
825*5f2e058dSBenjamin Tissoires  *				E: 000042.543045 9 11 00 00 04 00 00 00 00 00
826*5f2e058dSBenjamin Tissoires  *				E: 000042.544279 9 11 00 ff ff 00 00 00 00 00
827*5f2e058dSBenjamin Tissoires  *				E: 000042.545097 9 11 00 ff ff 00 00 00 00 00
828*5f2e058dSBenjamin Tissoires  *				E: 000042.546074 9 11 00 00 08 00 00 00 00 00
829*5f2e058dSBenjamin Tissoires  *				E: 000042.547237 9 11 00 00 08 00 00 00 00 00
830*5f2e058dSBenjamin Tissoires  *				E: 000042.548029 9 11 00 ff ff 00 00 00 00 00
831*5f2e058dSBenjamin Tissoires  *				E: 000042.549304 9 11 00 00 f8 00 00 00 00 00
832*5f2e058dSBenjamin Tissoires  *				E: 000042.553123 9 11 00 00 ff 00 00 00 00 00
833*5f2e058dSBenjamin Tissoires  *				E: 000042.581186 9 11 00 e1 ff 00 00 00 00 00
834*5f2e058dSBenjamin Tissoires  *				E: 000042.582238 9 11 00 00 f8 00 00 00 00 00
835*5f2e058dSBenjamin Tissoires  *				E: 000042.583150 9 11 00 00 fc 00 00 00 00 00
836*5f2e058dSBenjamin Tissoires  *				E: 000042.584273 9 11 00 00 f8 00 00 00 00 00
837*5f2e058dSBenjamin Tissoires  *				E: 000042.585019 9 11 00 00 fc 00 00 00 00 00
838*5f2e058dSBenjamin Tissoires  *				E: 000042.586059 9 11 00 01 00 00 00 00 00 00
839*5f2e058dSBenjamin Tissoires  *				E: 000042.589012 9 11 00 67 fe 00 00 00 00 00
840*5f2e058dSBenjamin Tissoires  *				E: 000042.590066 9 11 00 00 fc 00 00 00 00 00
841*5f2e058dSBenjamin Tissoires  *				E: 000042.592916 9 11 00 dc fe 00 00 00 00 00
842*5f2e058dSBenjamin Tissoires  *				E: 000042.621124 9 11 00 e1 ff 00 00 00 00 00
843*5f2e058dSBenjamin Tissoires  *				E: 000042.622092 9 11 00 ff ff 00 00 00 00 00
844*5f2e058dSBenjamin Tissoires  *				E: 000042.623069 9 11 00 01 00 00 00 00 00 00
845*5f2e058dSBenjamin Tissoires  *				E: 000042.624030 9 11 00 ff ff 00 00 00 00 00
846*5f2e058dSBenjamin Tissoires  *				E: 000042.625006 9 11 00 00 08 00 00 00 00 00
847*5f2e058dSBenjamin Tissoires  *				E: 000042.626068 9 11 00 00 04 00 00 00 00 00
848*5f2e058dSBenjamin Tissoires  *				E: 000042.626876 9 11 00 00 08 00 00 00 00 00
849*5f2e058dSBenjamin Tissoires  *				E: 000042.628392 9 11 00 00 08 00 00 00 00 00
850*5f2e058dSBenjamin Tissoires  *				E: 000042.628918 9 11 00 01 00 00 00 00 00 00
851*5f2e058dSBenjamin Tissoires  *				E: 000042.630009 9 11 00 ff ff 00 00 00 00 00
852*5f2e058dSBenjamin Tissoires  *				E: 000042.631934 9 11 00 00 fe 00 00 00 00 00
853*5f2e058dSBenjamin Tissoires  *				E: 000042.656285 9 11 00 dd ff 00 00 00 00 00
854*5f2e058dSBenjamin Tissoires  *				E: 000042.659870 9 11 00 cc 00 00 00 00 00 00
855*5f2e058dSBenjamin Tissoires  *				E: 000042.666128 9 11 00 9d 00 00 00 00 00 00
856*5f2e058dSBenjamin Tissoires  *				E: 000042.672458 9 11 00 80 ff 00 00 00 00 00
857*5f2e058dSBenjamin Tissoires  *				E: 000042.696106 9 11 00 dc ff 00 00 00 00 00
858*5f2e058dSBenjamin Tissoires  *				E: 000042.705129 9 11 00 61 00 00 00 00 00 00
859*5f2e058dSBenjamin Tissoires  *				E: 000042.731303 9 11 00 e0 ff 00 00 00 00 00
860*5f2e058dSBenjamin Tissoires  *				E: 000042.741278 9 11 00 ab ff 00 00 00 00 00
861*5f2e058dSBenjamin Tissoires  *				E: 000042.788181 9 11 00 ee ff 00 00 00 00 00
862*5f2e058dSBenjamin Tissoires  *				E: 000042.810441 9 11 00 db ff 00 00 00 00 00
863*5f2e058dSBenjamin Tissoires  *				E: 000042.838073 9 11 00 e1 ff 00 00 00 00 00
864*5f2e058dSBenjamin Tissoires  *				E: 000042.852235 9 11 00 c4 ff 00 00 00 00 00
865*5f2e058dSBenjamin Tissoires  *				E: 000042.882290 9 11 00 e4 ff 00 00 00 00 00
866*5f2e058dSBenjamin Tissoires  *
867*5f2e058dSBenjamin Tissoires  *			Either wheel button, press, hold, then release
868*5f2e058dSBenjamin Tissoires  *				E: 000202.084982 9 11 02 00 00 00 00 00 00 00
869*5f2e058dSBenjamin Tissoires  *				E: 000202.090172 9 11 03 00 00 00 00 00 00 00
870*5f2e058dSBenjamin Tissoires  *				E: 000202.094139 9 11 03 00 00 00 00 00 00 00
871*5f2e058dSBenjamin Tissoires  *				E: 000202.099172 9 11 03 00 00 00 00 00 00 00
872*5f2e058dSBenjamin Tissoires  *				E: 000202.105055 9 11 03 00 00 00 00 00 00 00
873*5f2e058dSBenjamin Tissoires  *				E: 000202.109132 9 11 03 00 00 00 00 00 00 00
874*5f2e058dSBenjamin Tissoires  *				E: 000202.114185 9 11 03 00 00 00 00 00 00 00
875*5f2e058dSBenjamin Tissoires  *				E: 000202.119212 9 11 03 00 00 00 00 00 00 00
876*5f2e058dSBenjamin Tissoires  *				E: 000202.124264 9 11 03 00 00 00 00 00 00 00
877*5f2e058dSBenjamin Tissoires  *				E: 000202.130147 9 11 03 00 00 00 00 00 00 00
878*5f2e058dSBenjamin Tissoires  *				E: 000202.135138 9 11 03 00 00 00 00 00 00 00
879*5f2e058dSBenjamin Tissoires  *				E: 000202.140072 9 11 03 00 00 00 00 00 00 00
880*5f2e058dSBenjamin Tissoires  *				E: 000202.145146 9 11 03 00 00 00 00 00 00 00
881*5f2e058dSBenjamin Tissoires  *				E: 000202.150157 9 11 03 00 00 00 00 00 00 00
882*5f2e058dSBenjamin Tissoires  *				E: 000202.155339 9 11 03 00 00 00 00 00 00 00
883*5f2e058dSBenjamin Tissoires  *				E: 000202.160064 9 11 03 00 00 00 00 00 00 00
884*5f2e058dSBenjamin Tissoires  *				E: 000202.165026 9 11 03 00 00 00 00 00 00 00
885*5f2e058dSBenjamin Tissoires  *				E: 000202.170037 9 11 03 00 00 00 00 00 00 00
886*5f2e058dSBenjamin Tissoires  *				E: 000202.175154 9 11 03 00 00 00 00 00 00 00
887*5f2e058dSBenjamin Tissoires  *				E: 000202.180044 9 11 03 00 00 00 00 00 00 00
888*5f2e058dSBenjamin Tissoires  *				E: 000202.186280 9 11 03 00 00 00 00 00 00 00
889*5f2e058dSBenjamin Tissoires  *				E: 000202.191281 9 11 03 00 00 00 00 00 00 00
890*5f2e058dSBenjamin Tissoires  *				E: 000202.196106 9 11 03 00 00 00 00 00 00 00
891*5f2e058dSBenjamin Tissoires  *				E: 000202.201083 9 11 03 00 00 00 00 00 00 00
892*5f2e058dSBenjamin Tissoires  *				E: 000202.206166 9 11 03 00 00 00 00 00 00 00
893*5f2e058dSBenjamin Tissoires  *				E: 000202.211084 9 11 03 00 00 00 00 00 00 00
894*5f2e058dSBenjamin Tissoires  *				E: 000202.216175 9 11 03 00 00 00 00 00 00 00
895*5f2e058dSBenjamin Tissoires  *				E: 000202.221036 9 11 03 00 00 00 00 00 00 00
896*5f2e058dSBenjamin Tissoires  *				E: 000202.226271 9 11 03 00 00 00 00 00 00 00
897*5f2e058dSBenjamin Tissoires  *				E: 000202.231150 9 11 03 00 00 00 00 00 00 00
898*5f2e058dSBenjamin Tissoires  *				E: 000202.235924 9 11 03 00 00 00 00 00 00 00
899*5f2e058dSBenjamin Tissoires  *				E: 000202.242046 9 11 03 00 00 00 00 00 00 00
900*5f2e058dSBenjamin Tissoires  *				E: 000202.247164 9 11 03 00 00 00 00 00 00 00
901*5f2e058dSBenjamin Tissoires  *				E: 000202.252359 9 11 03 00 00 00 00 00 00 00
902*5f2e058dSBenjamin Tissoires  *				E: 000202.257295 9 11 03 00 00 00 00 00 00 00
903*5f2e058dSBenjamin Tissoires  *				E: 000202.262167 9 11 03 00 00 00 00 00 00 00
904*5f2e058dSBenjamin Tissoires  *				E: 000202.267081 9 11 03 00 00 00 00 00 00 00
905*5f2e058dSBenjamin Tissoires  *				E: 000202.272175 9 11 03 00 00 00 00 00 00 00
906*5f2e058dSBenjamin Tissoires  *				E: 000202.277085 9 11 03 00 00 00 00 00 00 00
907*5f2e058dSBenjamin Tissoires  *				E: 000202.282596 9 11 03 00 00 00 00 00 00 00
908*5f2e058dSBenjamin Tissoires  *				E: 000202.287078 9 11 03 00 00 00 00 00 00 00
909*5f2e058dSBenjamin Tissoires  *				E: 000202.292191 9 11 03 00 00 00 00 00 00 00
910*5f2e058dSBenjamin Tissoires  *				E: 000202.298196 9 11 03 00 00 00 00 00 00 00
911*5f2e058dSBenjamin Tissoires  *				E: 000202.303004 9 11 03 00 00 00 00 00 00 00
912*5f2e058dSBenjamin Tissoires  *				E: 000202.308113 9 11 03 00 00 00 00 00 00 00
913*5f2e058dSBenjamin Tissoires  *				E: 000202.313079 9 11 03 00 00 00 00 00 00 00
914*5f2e058dSBenjamin Tissoires  *				E: 000202.318243 9 11 03 00 00 00 00 00 00 00
915*5f2e058dSBenjamin Tissoires  *				E: 000202.323309 9 11 03 00 00 00 00 00 00 00
916*5f2e058dSBenjamin Tissoires  *				E: 000202.328190 9 11 03 00 00 00 00 00 00 00
917*5f2e058dSBenjamin Tissoires  *				E: 000202.333050 9 11 03 00 00 00 00 00 00 00
918*5f2e058dSBenjamin Tissoires  *				E: 000202.338162 9 11 03 00 00 00 00 00 00 00
919*5f2e058dSBenjamin Tissoires  *				E: 000202.343022 9 11 03 00 00 00 00 00 00 00
920*5f2e058dSBenjamin Tissoires  *				E: 000202.348113 9 11 03 00 00 00 00 00 00 00
921*5f2e058dSBenjamin Tissoires  *				E: 000202.354133 9 11 03 00 00 00 00 00 00 00
922*5f2e058dSBenjamin Tissoires  *				E: 000202.359132 9 11 03 00 00 00 00 00 00 00
923*5f2e058dSBenjamin Tissoires  *				E: 000202.364053 9 11 03 00 00 00 00 00 00 00
924*5f2e058dSBenjamin Tissoires  *				E: 000202.369034 9 11 03 00 00 00 00 00 00 00
925*5f2e058dSBenjamin Tissoires  *				E: 000202.374144 9 11 03 00 00 00 00 00 00 00
926*5f2e058dSBenjamin Tissoires  *				E: 000202.379027 9 11 03 00 00 00 00 00 00 00
927*5f2e058dSBenjamin Tissoires  *				E: 000202.384238 9 11 03 00 00 00 00 00 00 00
928*5f2e058dSBenjamin Tissoires  *				E: 000202.389249 9 11 03 00 00 00 00 00 00 00
929*5f2e058dSBenjamin Tissoires  *				E: 000202.394049 9 11 03 00 00 00 00 00 00 00
930*5f2e058dSBenjamin Tissoires  *				E: 000202.398949 9 11 03 00 00 00 00 00 00 00
931*5f2e058dSBenjamin Tissoires  *				E: 000202.404203 9 11 03 00 00 00 00 00 00 00
932*5f2e058dSBenjamin Tissoires  *				E: 000202.410098 9 11 03 00 00 00 00 00 00 00
933*5f2e058dSBenjamin Tissoires  *				E: 000202.415237 9 11 00 00 00 00 00 00 00 00
934*5f2e058dSBenjamin Tissoires  *
935*5f2e058dSBenjamin Tissoires  *
936*5f2e058dSBenjamin Tissoires  *			Top wheel button press and release while holding bottom wheel button
937*5f2e058dSBenjamin Tissoires  *				(The reverse action (a bottom wheel button press while holding the top wheel button) is invisible.)
938*5f2e058dSBenjamin Tissoires  *				E: 000071.126966 9 11 03 00 00 00 00 00 00 00
939*5f2e058dSBenjamin Tissoires  *				E: 000071.133117 9 11 03 00 00 00 00 00 00 00
940*5f2e058dSBenjamin Tissoires  *				E: 000071.137481 9 11 03 00 00 00 00 00 00 00
941*5f2e058dSBenjamin Tissoires  *				E: 000071.142036 9 11 03 00 00 00 00 00 00 00
942*5f2e058dSBenjamin Tissoires  *				E: 000071.147027 9 11 03 00 00 00 00 00 00 00
943*5f2e058dSBenjamin Tissoires  *				E: 000071.151988 9 11 03 00 00 00 00 00 00 00
944*5f2e058dSBenjamin Tissoires  *				E: 000071.157945 9 11 03 00 00 00 00 00 00 00
945*5f2e058dSBenjamin Tissoires  *				E: 000071.163657 9 11 03 00 00 00 00 00 00 00
946*5f2e058dSBenjamin Tissoires  *				E: 000071.168240 9 11 03 00 00 00 00 00 00 00
947*5f2e058dSBenjamin Tissoires  *				E: 000071.173109 9 11 02 00 00 00 00 00 00 00 < top wheel button press?
948*5f2e058dSBenjamin Tissoires  *				E: 000071.178119 9 11 03 00 00 00 00 00 00 00
949*5f2e058dSBenjamin Tissoires  *				E: 000071.183046 9 11 03 00 00 00 00 00 00 00
950*5f2e058dSBenjamin Tissoires  *				E: 000071.187983 9 11 03 00 00 00 00 00 00 00
951*5f2e058dSBenjamin Tissoires  *				E: 000071.192996 9 11 03 00 00 00 00 00 00 00
952*5f2e058dSBenjamin Tissoires  *				E: 000071.198341 9 11 03 00 00 00 00 00 00 00
953*5f2e058dSBenjamin Tissoires  *				E: 000071.203122 9 11 03 00 00 00 00 00 00 00
954*5f2e058dSBenjamin Tissoires  *				E: 000071.208998 9 11 03 00 00 00 00 00 00 00
955*5f2e058dSBenjamin Tissoires  *				E: 000071.214037 9 11 03 00 00 00 00 00 00 00
956*5f2e058dSBenjamin Tissoires  *				E: 000071.218945 9 11 03 00 00 00 00 00 00 00
957*5f2e058dSBenjamin Tissoires  *				E: 000071.223835 9 11 03 00 00 00 00 00 00 00
958*5f2e058dSBenjamin Tissoires  *				E: 000071.228987 9 11 03 00 00 00 00 00 00 00
959*5f2e058dSBenjamin Tissoires  *				E: 000071.234082 9 11 03 00 00 00 00 00 00 00
960*5f2e058dSBenjamin Tissoires  *				E: 000071.239028 9 11 03 00 00 00 00 00 00 00
961*5f2e058dSBenjamin Tissoires  *				E: 000071.244307 9 11 00 00 00 00 00 00 00 00 < top wheel button release?
962*5f2e058dSBenjamin Tissoires  *				E: 000071.245867 9 11 03 00 00 00 00 00 00 00 < continued hold of bottom button
963*5f2e058dSBenjamin Tissoires  *				E: 000071.249959 9 11 03 00 00 00 00 00 00 00
964*5f2e058dSBenjamin Tissoires  *				E: 000071.255032 9 11 03 00 00 00 00 00 00 00
965*5f2e058dSBenjamin Tissoires  *				E: 000071.259972 9 11 03 00 00 00 00 00 00 00
966*5f2e058dSBenjamin Tissoires  *				E: 000071.265409 9 11 03 00 00 00 00 00 00 00
967*5f2e058dSBenjamin Tissoires  *				E: 000071.270156 9 11 03 00 00 00 00 00 00 00
968*5f2e058dSBenjamin Tissoires  *				E: 000071.275530 9 11 03 00 00 00 00 00 00 00
969*5f2e058dSBenjamin Tissoires  *				E: 000071.279975 9 11 03 00 00 00 00 00 00 00
970*5f2e058dSBenjamin Tissoires  *				E: 000071.285046 9 11 03 00 00 00 00 00 00 00
971*5f2e058dSBenjamin Tissoires  *				E: 000071.290906 9 11 03 00 00 00 00 00 00 00
972*5f2e058dSBenjamin Tissoires  *				E: 000071.296146 9 11 03 00 00 00 00 00 00 00
973*5f2e058dSBenjamin Tissoires  *				E: 000071.301288 9 11 03 00 00 00 00 00 00 00
974*5f2e058dSBenjamin Tissoires  *
975*5f2e058dSBenjamin Tissoires  *			Top wheel button hold while top wheel rotate CCW
976*5f2e058dSBenjamin Tissoires  *				(I did not test the other combinations of this)
977*5f2e058dSBenjamin Tissoires  *				E: 000022.253144 9 11 03 00 00 00 00 00 00 00
978*5f2e058dSBenjamin Tissoires  *				E: 000022.258157 9 11 03 00 00 00 00 00 00 00
979*5f2e058dSBenjamin Tissoires  *				E: 000022.262011 9 11 00 ff ff 00 00 00 00 00
980*5f2e058dSBenjamin Tissoires  *				E: 000022.264015 9 11 03 00 00 00 00 00 00 00
981*5f2e058dSBenjamin Tissoires  *				E: 000022.268976 9 11 03 00 00 00 00 00 00 00
982*5f2e058dSBenjamin Tissoires  *
983*5f2e058dSBenjamin Tissoires  *
984*5f2e058dSBenjamin Tissoires  *
985*5f2e058dSBenjamin Tissoires  *
986*5f2e058dSBenjamin Tissoires  *
987*5f2e058dSBenjamin Tissoires  *
988*5f2e058dSBenjamin Tissoires  *
989*5f2e058dSBenjamin Tissoires  *
990*5f2e058dSBenjamin Tissoires  * NOTES ON SIMULTANEOUS BUTTON HOLDS
991*5f2e058dSBenjamin Tissoires  *	(applies to vendor mode only)
992*5f2e058dSBenjamin Tissoires  *	Value replacements for ease of reading:
993*5f2e058dSBenjamin Tissoires  *		.7 = 0x40 (button 7, a wheel button)
994*5f2e058dSBenjamin Tissoires  *		.1 = 0x01 (button 1, a pad button)
995*5f2e058dSBenjamin Tissoires  *		rr = 0x00 (no buttons pressed)
996*5f2e058dSBenjamin Tissoires  *
997*5f2e058dSBenjamin Tissoires  *	Press 7
998*5f2e058dSBenjamin Tissoires  *	Press 1
999*5f2e058dSBenjamin Tissoires  *	Release 7
1000*5f2e058dSBenjamin Tissoires  *	Release 1
1001*5f2e058dSBenjamin Tissoires  *		B: 000000.000152 42 08 e0 01 01    .7 00 00 00 00 00 00 00 00 00
1002*5f2e058dSBenjamin Tissoires  *		B: 000000.781784 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1003*5f2e058dSBenjamin Tissoires  *		B: 000000.869845 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1004*5f2e058dSBenjamin Tissoires  *		B: 000001.095688 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1005*5f2e058dSBenjamin Tissoires  *		B: 000001.322635 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1006*5f2e058dSBenjamin Tissoires  *		B: 000001.543643 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1007*5f2e058dSBenjamin Tissoires  *		B: 000001.770652 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1008*5f2e058dSBenjamin Tissoires  *		B: 000001.885659 42 08 e0 01 01    rr 00 00 00 00 00 00 00 00 00	release of 7
1009*5f2e058dSBenjamin Tissoires  *		B: 000001.993620 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1010*5f2e058dSBenjamin Tissoires  *		B: 000002.220671 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1011*5f2e058dSBenjamin Tissoires  *		B: 000002.446589 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1012*5f2e058dSBenjamin Tissoires  *		B: 000002.672559 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1013*5f2e058dSBenjamin Tissoires  *		B: 000002.765183 42 08 e0 01 01    rr 00 00 00 00 00 00 00 00 00	release of 1
1014*5f2e058dSBenjamin Tissoires  *
1015*5f2e058dSBenjamin Tissoires  *	Press 7
1016*5f2e058dSBenjamin Tissoires  *	Press 1
1017*5f2e058dSBenjamin Tissoires  *	Release 1
1018*5f2e058dSBenjamin Tissoires  *	Release 7
1019*5f2e058dSBenjamin Tissoires  *		B: 000017.071517 42 08 e0 01 01    .7 00 00 00 00 00 00 00 00 00
1020*5f2e058dSBenjamin Tissoires  *		B: 000018.270461 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1021*5f2e058dSBenjamin Tissoires  *		B: 000018.419486 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1022*5f2e058dSBenjamin Tissoires  *		B: 000018.646438 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1023*5f2e058dSBenjamin Tissoires  *		B: 000018.872493 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1024*5f2e058dSBenjamin Tissoires  *		B: 000019.094422 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1025*5f2e058dSBenjamin Tissoires  *		B: 000019.320488 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1026*5f2e058dSBenjamin Tissoires  *		B: 000020.360505 42 08 e0 01 01    rr 00 00 00 00 00 00 00 00 00	release of 1 is not reported until 7 is released, then both are rapidly reported
1027*5f2e058dSBenjamin Tissoires  *		B: 000020.361091 42 08 e0 01 01    rr 00 00 00 00 00 00 00 00 00
1028*5f2e058dSBenjamin Tissoires  *
1029*5f2e058dSBenjamin Tissoires  *	Press 1
1030*5f2e058dSBenjamin Tissoires  *	Press 7
1031*5f2e058dSBenjamin Tissoires  *	Release 7
1032*5f2e058dSBenjamin Tissoires  *	Release 1
1033*5f2e058dSBenjamin Tissoires  *		B: 000031.516315 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1034*5f2e058dSBenjamin Tissoires  *		B: 000031.922299 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1035*5f2e058dSBenjamin Tissoires  *		B: 000032.144165 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1036*5f2e058dSBenjamin Tissoires  *		B: 000032.370262 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1037*5f2e058dSBenjamin Tissoires  *		B: 000032.396242 42 08 e0 01 01    .7 00 00 00 00 00 00 00 00 00
1038*5f2e058dSBenjamin Tissoires  *		B: 000032.597270 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1039*5f2e058dSBenjamin Tissoires  *		B: 000032.818187 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1040*5f2e058dSBenjamin Tissoires  *		B: 000033.045143 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1041*5f2e058dSBenjamin Tissoires  *		B: 000033.267535 42 08 e0 01 01    rr 00 00 00 00 00 00 00 00 00	release of 7
1042*5f2e058dSBenjamin Tissoires  *		B: 000033.272602 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1043*5f2e058dSBenjamin Tissoires  *		B: 000033.494246 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1044*5f2e058dSBenjamin Tissoires  *		B: 000033.721266 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1045*5f2e058dSBenjamin Tissoires  *		B: 000033.947237 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1046*5f2e058dSBenjamin Tissoires  *		B: 000034.169294 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1047*5f2e058dSBenjamin Tissoires  *		B: 000034.183585 42 08 e0 01 01    rr 00 00 00 00 00 00 00 00 00	release of 1
1048*5f2e058dSBenjamin Tissoires  *
1049*5f2e058dSBenjamin Tissoires  *	Press 1
1050*5f2e058dSBenjamin Tissoires  *	Press 7
1051*5f2e058dSBenjamin Tissoires  *	Release 1
1052*5f2e058dSBenjamin Tissoires  *	Release 7
1053*5f2e058dSBenjamin Tissoires  *		B: 000056.628429 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1054*5f2e058dSBenjamin Tissoires  *		B: 000057.046348 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1055*5f2e058dSBenjamin Tissoires  *		B: 000057.272044 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1056*5f2e058dSBenjamin Tissoires  *		B: 000057.494434 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1057*5f2e058dSBenjamin Tissoires  *		B: 000057.601224 42 08 e0 01 01    .7 00 00 00 00 00 00 00 00 00
1058*5f2e058dSBenjamin Tissoires  *		B: 000057.719262 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1059*5f2e058dSBenjamin Tissoires  *		B: 000057.946941 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1060*5f2e058dSBenjamin Tissoires  *		B: 000058.172346 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1061*5f2e058dSBenjamin Tissoires  *		B: 000058.393994 42 08 e0 01 01    .1 00 00 00 00 00 00 00 00 00
1062*5f2e058dSBenjamin Tissoires  *		B: 000059.434576 42 08 e0 01 01    rr 00 00 00 00 00 00 00 00 00	release of 1 is not reported until 7 is released, then both are rapidly reported
1063*5f2e058dSBenjamin Tissoires  *		B: 000059.435857 42 08 e0 01 01    rr 00 00 00 00 00 00 00 00 00
1064*5f2e058dSBenjamin Tissoires  */
1065*5f2e058dSBenjamin Tissoires 
1066*5f2e058dSBenjamin Tissoires 
1067*5f2e058dSBenjamin Tissoires /* Filled in by udev-hid-bpf */
1068*5f2e058dSBenjamin Tissoires char UDEV_PROP_HUION_FIRMWARE_ID[64];
1069*5f2e058dSBenjamin Tissoires 
1070*5f2e058dSBenjamin Tissoires char EXPECTED_FIRMWARE_ID[] = "HUION_M22c_";
1071*5f2e058dSBenjamin Tissoires 
1072*5f2e058dSBenjamin Tissoires __u8 last_button_state;
1073*5f2e058dSBenjamin Tissoires 
1074*5f2e058dSBenjamin Tissoires static const __u8 disabled_rdesc_tablet[] = {
1075*5f2e058dSBenjamin Tissoires 	FixedSizeVendorReport(28)	/* Input report 4 */
1076*5f2e058dSBenjamin Tissoires };
1077*5f2e058dSBenjamin Tissoires 
1078*5f2e058dSBenjamin Tissoires static const __u8 disabled_rdesc_wheel[] = {
1079*5f2e058dSBenjamin Tissoires 	FixedSizeVendorReport(9)	/* Input report 17 */
1080*5f2e058dSBenjamin Tissoires };
1081*5f2e058dSBenjamin Tissoires 
1082*5f2e058dSBenjamin Tissoires static const __u8 fixed_rdesc_vendor[] = {
1083*5f2e058dSBenjamin Tissoires 	UsagePage_Digitizers
1084*5f2e058dSBenjamin Tissoires 	Usage_Dig_Pen
1085*5f2e058dSBenjamin Tissoires 	CollectionApplication(
1086*5f2e058dSBenjamin Tissoires 		ReportId(VENDOR_REPORT_ID)
1087*5f2e058dSBenjamin Tissoires 		UsagePage_Digitizers
1088*5f2e058dSBenjamin Tissoires 		Usage_Dig_Pen
1089*5f2e058dSBenjamin Tissoires 		CollectionPhysical(
1090*5f2e058dSBenjamin Tissoires 			/*
1091*5f2e058dSBenjamin Tissoires 			 * I have only examined the tablet's behavior while using
1092*5f2e058dSBenjamin Tissoires 			 * the PW600L pen, which does not have an eraser.
1093*5f2e058dSBenjamin Tissoires 			 * Because of this, I don't know where the Eraser and Invert
1094*5f2e058dSBenjamin Tissoires 			 * bits will go, or if they work as one would expect.
1095*5f2e058dSBenjamin Tissoires 			 *
1096*5f2e058dSBenjamin Tissoires 			 * For the time being, there is no expectation that a pen
1097*5f2e058dSBenjamin Tissoires 			 * with an eraser will work without modifications here.
1098*5f2e058dSBenjamin Tissoires 			 */
1099*5f2e058dSBenjamin Tissoires 			ReportSize(1)
1100*5f2e058dSBenjamin Tissoires 			LogicalMinimum_i8(0)
1101*5f2e058dSBenjamin Tissoires 			LogicalMaximum_i8(1)
1102*5f2e058dSBenjamin Tissoires 			ReportCount(3)
1103*5f2e058dSBenjamin Tissoires 			Usage_Dig_TipSwitch
1104*5f2e058dSBenjamin Tissoires 			Usage_Dig_BarrelSwitch
1105*5f2e058dSBenjamin Tissoires 			Usage_Dig_SecondaryBarrelSwitch
1106*5f2e058dSBenjamin Tissoires 			Input(Var|Abs)
1107*5f2e058dSBenjamin Tissoires 			PushPop(
1108*5f2e058dSBenjamin Tissoires 				ReportCount(1)
1109*5f2e058dSBenjamin Tissoires 				UsagePage_Button
1110*5f2e058dSBenjamin Tissoires 				Usage_i8(0x4a)	/* (BTN_STYLUS3 + 1) & 0xff */
1111*5f2e058dSBenjamin Tissoires 				Input(Var|Abs)
1112*5f2e058dSBenjamin Tissoires 			)
1113*5f2e058dSBenjamin Tissoires 			ReportCount(3)
1114*5f2e058dSBenjamin Tissoires 			Input(Const)
1115*5f2e058dSBenjamin Tissoires 			ReportCount(1)
1116*5f2e058dSBenjamin Tissoires 			Usage_Dig_InRange
1117*5f2e058dSBenjamin Tissoires 			Input(Var|Abs)
1118*5f2e058dSBenjamin Tissoires 			ReportSize(16)
1119*5f2e058dSBenjamin Tissoires 			ReportCount(1)
1120*5f2e058dSBenjamin Tissoires 			PushPop(
1121*5f2e058dSBenjamin Tissoires 				UsagePage_GenericDesktop
1122*5f2e058dSBenjamin Tissoires 				Unit(cm)
1123*5f2e058dSBenjamin Tissoires 				UnitExponent(-2)
1124*5f2e058dSBenjamin Tissoires 				LogicalMinimum_i16(0)
1125*5f2e058dSBenjamin Tissoires 				PhysicalMinimum_i16(0)
1126*5f2e058dSBenjamin Tissoires 				/*
1127*5f2e058dSBenjamin Tissoires 				 * The tablet has a logical maximum of 58760 x 33040
1128*5f2e058dSBenjamin Tissoires 				 * and a claimed resolution of 5080 LPI (200 L/mm)
1129*5f2e058dSBenjamin Tissoires 				 * This works out to a physical maximum of
1130*5f2e058dSBenjamin Tissoires 				 * 293.8 x 165.2mm, which matches Huion's advertised
1131*5f2e058dSBenjamin Tissoires 				 * active area dimensions from
1132*5f2e058dSBenjamin Tissoires 				 * https://www.huion.com/products/pen_display/Kamvas/kamvas-13-gen-3.html
1133*5f2e058dSBenjamin Tissoires 				 */
1134*5f2e058dSBenjamin Tissoires 				LogicalMaximum_i16(58760)
1135*5f2e058dSBenjamin Tissoires 				PhysicalMaximum_i16(2938)
1136*5f2e058dSBenjamin Tissoires 				Usage_GD_X
1137*5f2e058dSBenjamin Tissoires 				Input(Var|Abs)
1138*5f2e058dSBenjamin Tissoires 				LogicalMaximum_i16(33040)
1139*5f2e058dSBenjamin Tissoires 				PhysicalMaximum_i16(1652)
1140*5f2e058dSBenjamin Tissoires 				Usage_GD_Y
1141*5f2e058dSBenjamin Tissoires 				Input(Var|Abs)
1142*5f2e058dSBenjamin Tissoires 			)
1143*5f2e058dSBenjamin Tissoires 			LogicalMinimum_i16(0)
1144*5f2e058dSBenjamin Tissoires 			LogicalMaximum_i16(16383)
1145*5f2e058dSBenjamin Tissoires 			Usage_Dig_TipPressure
1146*5f2e058dSBenjamin Tissoires 			Input(Var|Abs)
1147*5f2e058dSBenjamin Tissoires 			ReportCount(1)
1148*5f2e058dSBenjamin Tissoires 			Input(Const)
1149*5f2e058dSBenjamin Tissoires 			ReportSize(8)
1150*5f2e058dSBenjamin Tissoires 			ReportCount(2)
1151*5f2e058dSBenjamin Tissoires 			PushPop(
1152*5f2e058dSBenjamin Tissoires 				Unit(deg)
1153*5f2e058dSBenjamin Tissoires 				UnitExponent(0)
1154*5f2e058dSBenjamin Tissoires 				LogicalMinimum_i8(-60)
1155*5f2e058dSBenjamin Tissoires 				PhysicalMinimum_i8(-60)
1156*5f2e058dSBenjamin Tissoires 				LogicalMaximum_i8(60)
1157*5f2e058dSBenjamin Tissoires 				PhysicalMaximum_i8(60)
1158*5f2e058dSBenjamin Tissoires 				Usage_Dig_XTilt
1159*5f2e058dSBenjamin Tissoires 				Usage_Dig_YTilt
1160*5f2e058dSBenjamin Tissoires 				Input(Var|Abs)
1161*5f2e058dSBenjamin Tissoires 			)
1162*5f2e058dSBenjamin Tissoires 		)
1163*5f2e058dSBenjamin Tissoires 	)
1164*5f2e058dSBenjamin Tissoires 	UsagePage_GenericDesktop
1165*5f2e058dSBenjamin Tissoires 	Usage_GD_Keypad
1166*5f2e058dSBenjamin Tissoires 	CollectionApplication(
1167*5f2e058dSBenjamin Tissoires 		ReportId(CUSTOM_PAD_REPORT_ID)
1168*5f2e058dSBenjamin Tissoires 		LogicalMinimum_i8(0)
1169*5f2e058dSBenjamin Tissoires 		LogicalMaximum_i8(1)
1170*5f2e058dSBenjamin Tissoires 		UsagePage_Digitizers
1171*5f2e058dSBenjamin Tissoires 		Usage_Dig_TabletFunctionKeys
1172*5f2e058dSBenjamin Tissoires 		CollectionPhysical(
1173*5f2e058dSBenjamin Tissoires 			/*
1174*5f2e058dSBenjamin Tissoires 			 * The first 3 bytes are somewhat vestigial and will
1175*5f2e058dSBenjamin Tissoires 			 * always be set to zero. Their presence here is needed
1176*5f2e058dSBenjamin Tissoires 			 * to ensure that this device will be detected as a
1177*5f2e058dSBenjamin Tissoires 			 * tablet pad by software that otherwise wouldn't know
1178*5f2e058dSBenjamin Tissoires 			 * any better.
1179*5f2e058dSBenjamin Tissoires 			 */
1180*5f2e058dSBenjamin Tissoires 			/* (data[1] & 0x01)	barrel switch */
1181*5f2e058dSBenjamin Tissoires 			ReportSize(1)
1182*5f2e058dSBenjamin Tissoires 			ReportCount(1)
1183*5f2e058dSBenjamin Tissoires 			Usage_Dig_BarrelSwitch
1184*5f2e058dSBenjamin Tissoires 			Input(Var|Abs)
1185*5f2e058dSBenjamin Tissoires 			ReportCount(7)
1186*5f2e058dSBenjamin Tissoires 			Input(Const)
1187*5f2e058dSBenjamin Tissoires 			/* data[2]	X */
1188*5f2e058dSBenjamin Tissoires 			/* data[3]	Y */
1189*5f2e058dSBenjamin Tissoires 			ReportSize(8)
1190*5f2e058dSBenjamin Tissoires 			ReportCount(2)
1191*5f2e058dSBenjamin Tissoires 			UsagePage_GenericDesktop
1192*5f2e058dSBenjamin Tissoires 			Usage_GD_X
1193*5f2e058dSBenjamin Tissoires 			Usage_GD_Y
1194*5f2e058dSBenjamin Tissoires 			Input(Var|Abs)
1195*5f2e058dSBenjamin Tissoires 			/*
1196*5f2e058dSBenjamin Tissoires 			 * (data[4] & 0x01)	button 1
1197*5f2e058dSBenjamin Tissoires 			 * (data[4] & 0x02)	button 2
1198*5f2e058dSBenjamin Tissoires 			 * (data[4] & 0x04)	button 3
1199*5f2e058dSBenjamin Tissoires 			 * (data[4] & 0x08)	button 4
1200*5f2e058dSBenjamin Tissoires 			 * (data[4] & 0x10)	button 5
1201*5f2e058dSBenjamin Tissoires 			 * (data[4] & 0x20)	button 6 (top wheel button)
1202*5f2e058dSBenjamin Tissoires 			 * (data[4] & 0x40)	button 7 (bottom wheel button)
1203*5f2e058dSBenjamin Tissoires 			 */
1204*5f2e058dSBenjamin Tissoires 			ReportSize(1)
1205*5f2e058dSBenjamin Tissoires 			ReportCount(7)
1206*5f2e058dSBenjamin Tissoires 			UsagePage_Button
1207*5f2e058dSBenjamin Tissoires 			UsageMinimum_i8(1)
1208*5f2e058dSBenjamin Tissoires 			UsageMaximum_i8(7)
1209*5f2e058dSBenjamin Tissoires 			Input(Var|Abs)
1210*5f2e058dSBenjamin Tissoires 			ReportCount(1)
1211*5f2e058dSBenjamin Tissoires 			Input(Const)
1212*5f2e058dSBenjamin Tissoires 			/* data[5]	top wheel (signed, positive clockwise) */
1213*5f2e058dSBenjamin Tissoires 			ReportSize(8)
1214*5f2e058dSBenjamin Tissoires 			ReportCount(1)
1215*5f2e058dSBenjamin Tissoires 			UsagePage_GenericDesktop
1216*5f2e058dSBenjamin Tissoires 			Usage_GD_Wheel
1217*5f2e058dSBenjamin Tissoires 			LogicalMinimum_i8(-1)
1218*5f2e058dSBenjamin Tissoires 			LogicalMaximum_i8(1)
1219*5f2e058dSBenjamin Tissoires 			Input(Var|Rel)
1220*5f2e058dSBenjamin Tissoires 			/* data[6]	bottom wheel (signed, positive clockwise) */
1221*5f2e058dSBenjamin Tissoires 			UsagePage_Consumer
1222*5f2e058dSBenjamin Tissoires 			Usage_Con_ACPan
1223*5f2e058dSBenjamin Tissoires 			Input(Var|Rel)
1224*5f2e058dSBenjamin Tissoires 		)
1225*5f2e058dSBenjamin Tissoires 		/*
1226*5f2e058dSBenjamin Tissoires 		 * The kernel will drop reports that are bigger than the
1227*5f2e058dSBenjamin Tissoires 		 * largest report specified in the HID descriptor.
1228*5f2e058dSBenjamin Tissoires 		 * Therefore, our modified descriptor needs to have at least one
1229*5f2e058dSBenjamin Tissoires 		 * HID report that is as long as, or longer than, the largest
1230*5f2e058dSBenjamin Tissoires 		 * report in the original descriptor.
1231*5f2e058dSBenjamin Tissoires 		 *
1232*5f2e058dSBenjamin Tissoires 		 * This macro expands to a no-op report that is padded to the
1233*5f2e058dSBenjamin Tissoires 		 * provided length.
1234*5f2e058dSBenjamin Tissoires 		 */
1235*5f2e058dSBenjamin Tissoires 		FixedSizeVendorReport(VENDOR_REPORT_LENGTH)
1236*5f2e058dSBenjamin Tissoires 	)
1237*5f2e058dSBenjamin Tissoires };
1238*5f2e058dSBenjamin Tissoires 
1239*5f2e058dSBenjamin Tissoires SEC(HID_BPF_RDESC_FIXUP)
1240*5f2e058dSBenjamin Tissoires int BPF_PROG(hid_fix_rdesc_huion_kamvas13_gen3, struct hid_bpf_ctx *hid_ctx)
1241*5f2e058dSBenjamin Tissoires {
1242*5f2e058dSBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, HID_MAX_DESCRIPTOR_SIZE /* size */);
1243*5f2e058dSBenjamin Tissoires 	__s32 rdesc_size = hid_ctx->size;
1244*5f2e058dSBenjamin Tissoires 	__u8 have_fw_id;
1245*5f2e058dSBenjamin Tissoires 
1246*5f2e058dSBenjamin Tissoires 	if (!data)
1247*5f2e058dSBenjamin Tissoires 		return 0; /* EPERM check */
1248*5f2e058dSBenjamin Tissoires 
1249*5f2e058dSBenjamin Tissoires 	have_fw_id = __builtin_memcmp(UDEV_PROP_HUION_FIRMWARE_ID,
1250*5f2e058dSBenjamin Tissoires 					EXPECTED_FIRMWARE_ID,
1251*5f2e058dSBenjamin Tissoires 					sizeof(EXPECTED_FIRMWARE_ID) - 1) == 0;
1252*5f2e058dSBenjamin Tissoires 
1253*5f2e058dSBenjamin Tissoires 	if (have_fw_id) {
1254*5f2e058dSBenjamin Tissoires 		/*
1255*5f2e058dSBenjamin Tissoires 		 * Tablet should be in vendor mode.
1256*5f2e058dSBenjamin Tissoires 		 * Disable the unused devices
1257*5f2e058dSBenjamin Tissoires 		 */
1258*5f2e058dSBenjamin Tissoires 		if (rdesc_size == TABLET_DESCRIPTOR_LENGTH) {
1259*5f2e058dSBenjamin Tissoires 			__builtin_memcpy(data, disabled_rdesc_tablet,
1260*5f2e058dSBenjamin Tissoires 					 sizeof(disabled_rdesc_tablet));
1261*5f2e058dSBenjamin Tissoires 			return sizeof(disabled_rdesc_tablet);
1262*5f2e058dSBenjamin Tissoires 		}
1263*5f2e058dSBenjamin Tissoires 
1264*5f2e058dSBenjamin Tissoires 		if (rdesc_size == WHEEL_DESCRIPTOR_LENGTH) {
1265*5f2e058dSBenjamin Tissoires 			__builtin_memcpy(data, disabled_rdesc_wheel,
1266*5f2e058dSBenjamin Tissoires 					 sizeof(disabled_rdesc_wheel));
1267*5f2e058dSBenjamin Tissoires 			return sizeof(disabled_rdesc_wheel);
1268*5f2e058dSBenjamin Tissoires 		}
1269*5f2e058dSBenjamin Tissoires 	}
1270*5f2e058dSBenjamin Tissoires 
1271*5f2e058dSBenjamin Tissoires 	/*
1272*5f2e058dSBenjamin Tissoires 	 * Regardless of which mode the tablet is in, always fix the vendor
1273*5f2e058dSBenjamin Tissoires 	 * descriptor in case the udev property just happened to not be set
1274*5f2e058dSBenjamin Tissoires 	 */
1275*5f2e058dSBenjamin Tissoires 	if (rdesc_size == VENDOR_DESCRIPTOR_LENGTH) {
1276*5f2e058dSBenjamin Tissoires 		__builtin_memcpy(data, fixed_rdesc_vendor, sizeof(fixed_rdesc_vendor));
1277*5f2e058dSBenjamin Tissoires 		return sizeof(fixed_rdesc_vendor);
1278*5f2e058dSBenjamin Tissoires 	}
1279*5f2e058dSBenjamin Tissoires 
1280*5f2e058dSBenjamin Tissoires 	return 0;
1281*5f2e058dSBenjamin Tissoires }
1282*5f2e058dSBenjamin Tissoires 
1283*5f2e058dSBenjamin Tissoires SEC(HID_BPF_DEVICE_EVENT)
1284*5f2e058dSBenjamin Tissoires int BPF_PROG(hid_fix_event_huion_kamvas13_gen3, struct hid_bpf_ctx *hid_ctx)
1285*5f2e058dSBenjamin Tissoires {
1286*5f2e058dSBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, VENDOR_REPORT_LENGTH /* size */);
1287*5f2e058dSBenjamin Tissoires 
1288*5f2e058dSBenjamin Tissoires 	if (!data)
1289*5f2e058dSBenjamin Tissoires 		return 0; /* EPERM check */
1290*5f2e058dSBenjamin Tissoires 
1291*5f2e058dSBenjamin Tissoires 	/* Handle vendor reports only */
1292*5f2e058dSBenjamin Tissoires 	if (hid_ctx->size != VENDOR_REPORT_LENGTH)
1293*5f2e058dSBenjamin Tissoires 		return 0;
1294*5f2e058dSBenjamin Tissoires 	if (data[0] != VENDOR_REPORT_ID)
1295*5f2e058dSBenjamin Tissoires 		return 0;
1296*5f2e058dSBenjamin Tissoires 
1297*5f2e058dSBenjamin Tissoires 	__u8 report_subtype = (data[1] >> 4) & 0x0f;
1298*5f2e058dSBenjamin Tissoires 
1299*5f2e058dSBenjamin Tissoires 	if (report_subtype == VENDOR_REPORT_SUBTYPE_PEN ||
1300*5f2e058dSBenjamin Tissoires 	    report_subtype == VENDOR_REPORT_SUBTYPE_PEN_OUT) {
1301*5f2e058dSBenjamin Tissoires 		/* Invert Y tilt */
1302*5f2e058dSBenjamin Tissoires 		data[11] = -data[11];
1303*5f2e058dSBenjamin Tissoires 
1304*5f2e058dSBenjamin Tissoires 	} else if (report_subtype == VENDOR_REPORT_SUBTYPE_BUTTONS ||
1305*5f2e058dSBenjamin Tissoires 		   report_subtype == VENDOR_REPORT_SUBTYPE_WHEELS) {
1306*5f2e058dSBenjamin Tissoires 		struct pad_report {
1307*5f2e058dSBenjamin Tissoires 			__u8 report_id;
1308*5f2e058dSBenjamin Tissoires 			__u8 btn_stylus:1;
1309*5f2e058dSBenjamin Tissoires 			__u8 padding:7;
1310*5f2e058dSBenjamin Tissoires 			__u8 x;
1311*5f2e058dSBenjamin Tissoires 			__u8 y;
1312*5f2e058dSBenjamin Tissoires 			__u8 buttons;
1313*5f2e058dSBenjamin Tissoires 			__s8 top_wheel;
1314*5f2e058dSBenjamin Tissoires 			__s8 bottom_wheel;
1315*5f2e058dSBenjamin Tissoires 		} __attribute__((packed)) *pad_report;
1316*5f2e058dSBenjamin Tissoires 
1317*5f2e058dSBenjamin Tissoires 		__s8 top_wheel = 0;
1318*5f2e058dSBenjamin Tissoires 		__s8 bottom_wheel = 0;
1319*5f2e058dSBenjamin Tissoires 
1320*5f2e058dSBenjamin Tissoires 		switch (report_subtype) {
1321*5f2e058dSBenjamin Tissoires 		case VENDOR_REPORT_SUBTYPE_WHEELS:
1322*5f2e058dSBenjamin Tissoires 			/*
1323*5f2e058dSBenjamin Tissoires 			 * The wheel direction byte is 1 for clockwise rotation
1324*5f2e058dSBenjamin Tissoires 			 * and 2 for counter-clockwise.
1325*5f2e058dSBenjamin Tissoires 			 * Change it to 1 and -1, respectively.
1326*5f2e058dSBenjamin Tissoires 			 */
1327*5f2e058dSBenjamin Tissoires 			switch (data[3]) {
1328*5f2e058dSBenjamin Tissoires 			case 1:
1329*5f2e058dSBenjamin Tissoires 				top_wheel = (data[5] == 1) ? 1 : -1;
1330*5f2e058dSBenjamin Tissoires 				break;
1331*5f2e058dSBenjamin Tissoires 			case 2:
1332*5f2e058dSBenjamin Tissoires 				bottom_wheel = (data[5] == 1) ? 1 : -1;
1333*5f2e058dSBenjamin Tissoires 				break;
1334*5f2e058dSBenjamin Tissoires 			}
1335*5f2e058dSBenjamin Tissoires 			break;
1336*5f2e058dSBenjamin Tissoires 
1337*5f2e058dSBenjamin Tissoires 		case VENDOR_REPORT_SUBTYPE_BUTTONS:
1338*5f2e058dSBenjamin Tissoires 			/*
1339*5f2e058dSBenjamin Tissoires 			 * If a button is already being held, ignore any new
1340*5f2e058dSBenjamin Tissoires 			 * button event unless it's a release.
1341*5f2e058dSBenjamin Tissoires 			 *
1342*5f2e058dSBenjamin Tissoires 			 * The tablet only cleanly handles one button being held
1343*5f2e058dSBenjamin Tissoires 			 * at a time, and trying to hold multiple buttons
1344*5f2e058dSBenjamin Tissoires 			 * (particularly wheel+pad buttons) can result in sequences
1345*5f2e058dSBenjamin Tissoires 			 * of reports that look like imaginary presses and releases.
1346*5f2e058dSBenjamin Tissoires 			 *
1347*5f2e058dSBenjamin Tissoires 			 * This is an imperfect way to filter out some of these
1348*5f2e058dSBenjamin Tissoires 			 * reports.
1349*5f2e058dSBenjamin Tissoires 			 */
1350*5f2e058dSBenjamin Tissoires 			if (last_button_state != 0x00 && data[4] != 0x00)
1351*5f2e058dSBenjamin Tissoires 				break;
1352*5f2e058dSBenjamin Tissoires 
1353*5f2e058dSBenjamin Tissoires 			last_button_state = data[4];
1354*5f2e058dSBenjamin Tissoires 			break;
1355*5f2e058dSBenjamin Tissoires 		}
1356*5f2e058dSBenjamin Tissoires 
1357*5f2e058dSBenjamin Tissoires 
1358*5f2e058dSBenjamin Tissoires 		pad_report = (struct pad_report *)data;
1359*5f2e058dSBenjamin Tissoires 
1360*5f2e058dSBenjamin Tissoires 		pad_report->report_id = CUSTOM_PAD_REPORT_ID;
1361*5f2e058dSBenjamin Tissoires 		pad_report->btn_stylus = 0;
1362*5f2e058dSBenjamin Tissoires 		pad_report->x = 0;
1363*5f2e058dSBenjamin Tissoires 		pad_report->y = 0;
1364*5f2e058dSBenjamin Tissoires 		pad_report->buttons = last_button_state;
1365*5f2e058dSBenjamin Tissoires 		pad_report->top_wheel = top_wheel;
1366*5f2e058dSBenjamin Tissoires 		pad_report->bottom_wheel = bottom_wheel;
1367*5f2e058dSBenjamin Tissoires 
1368*5f2e058dSBenjamin Tissoires 		return sizeof(struct pad_report);
1369*5f2e058dSBenjamin Tissoires 	}
1370*5f2e058dSBenjamin Tissoires 
1371*5f2e058dSBenjamin Tissoires 	return 0;
1372*5f2e058dSBenjamin Tissoires }
1373*5f2e058dSBenjamin Tissoires 
1374*5f2e058dSBenjamin Tissoires HID_BPF_OPS(huion_kamvas13_gen3) = {
1375*5f2e058dSBenjamin Tissoires 	.hid_device_event = (void *)hid_fix_event_huion_kamvas13_gen3,
1376*5f2e058dSBenjamin Tissoires 	.hid_rdesc_fixup = (void *)hid_fix_rdesc_huion_kamvas13_gen3,
1377*5f2e058dSBenjamin Tissoires };
1378*5f2e058dSBenjamin Tissoires 
1379*5f2e058dSBenjamin Tissoires SEC("syscall")
1380*5f2e058dSBenjamin Tissoires int probe(struct hid_bpf_probe_args *ctx)
1381*5f2e058dSBenjamin Tissoires {
1382*5f2e058dSBenjamin Tissoires 	switch (ctx->rdesc_size) {
1383*5f2e058dSBenjamin Tissoires 	case VENDOR_DESCRIPTOR_LENGTH:
1384*5f2e058dSBenjamin Tissoires 	case TABLET_DESCRIPTOR_LENGTH:
1385*5f2e058dSBenjamin Tissoires 	case WHEEL_DESCRIPTOR_LENGTH:
1386*5f2e058dSBenjamin Tissoires 		ctx->retval = 0;
1387*5f2e058dSBenjamin Tissoires 		break;
1388*5f2e058dSBenjamin Tissoires 	default:
1389*5f2e058dSBenjamin Tissoires 		ctx->retval = -EINVAL;
1390*5f2e058dSBenjamin Tissoires 	}
1391*5f2e058dSBenjamin Tissoires 
1392*5f2e058dSBenjamin Tissoires 	return 0;
1393*5f2e058dSBenjamin Tissoires }
1394*5f2e058dSBenjamin Tissoires 
1395*5f2e058dSBenjamin Tissoires char _license[] SEC("license") = "GPL";
1396