xref: /linux/drivers/hid/bpf/progs/Huion__Kamvas-Pro-19.bpf.c (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
19f1bf4c2SBenjamin Tissoires // SPDX-License-Identifier: GPL-2.0-only
29f1bf4c2SBenjamin Tissoires /* Copyright (c) 2024 Benjamin Tissoires
39f1bf4c2SBenjamin Tissoires  */
49f1bf4c2SBenjamin Tissoires 
59f1bf4c2SBenjamin Tissoires #include "vmlinux.h"
69f1bf4c2SBenjamin Tissoires #include "hid_bpf.h"
79f1bf4c2SBenjamin Tissoires #include "hid_bpf_helpers.h"
89f1bf4c2SBenjamin Tissoires #include <bpf/bpf_tracing.h>
99f1bf4c2SBenjamin Tissoires 
109f1bf4c2SBenjamin Tissoires #define VID_HUION 0x256C
119f1bf4c2SBenjamin Tissoires #define PID_KAMVAS_PRO_19 0x006B
129f1bf4c2SBenjamin Tissoires #define NAME_KAMVAS_PRO_19 "HUION Huion Tablet_GT1902"
139f1bf4c2SBenjamin Tissoires 
149f1bf4c2SBenjamin Tissoires #define TEST_PREFIX "uhid test "
159f1bf4c2SBenjamin Tissoires 
169f1bf4c2SBenjamin Tissoires HID_BPF_CONFIG(
179f1bf4c2SBenjamin Tissoires 	HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, VID_HUION, PID_KAMVAS_PRO_19),
189f1bf4c2SBenjamin Tissoires );
199f1bf4c2SBenjamin Tissoires 
209f1bf4c2SBenjamin Tissoires bool prev_was_out_of_range;
219f1bf4c2SBenjamin Tissoires bool in_eraser_mode;
229f1bf4c2SBenjamin Tissoires 
239f1bf4c2SBenjamin Tissoires /*
249f1bf4c2SBenjamin Tissoires  * We need to amend the report descriptor for the following:
259f1bf4c2SBenjamin Tissoires  * - the second button is reported through Secondary Tip Switch instead of Secondary Barrel Switch
269f1bf4c2SBenjamin Tissoires  * - the third button is reported through Invert, and we need some room to report it.
279f1bf4c2SBenjamin Tissoires  *
289f1bf4c2SBenjamin Tissoires  */
299f1bf4c2SBenjamin Tissoires static const __u8 fixed_rdesc[] = {
309f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    // Usage Page (Digitizers)             0
319f1bf4c2SBenjamin Tissoires 	0x09, 0x02,                    // Usage (Pen)                         2
329f1bf4c2SBenjamin Tissoires 	0xa1, 0x01,                    // Collection (Application)            4
339f1bf4c2SBenjamin Tissoires 	0x85, 0x0a,                    //  Report ID (10)                     6
349f1bf4c2SBenjamin Tissoires 	0x09, 0x20,                    //  Usage (Stylus)                     8
359f1bf4c2SBenjamin Tissoires 	0xa1, 0x01,                    //  Collection (Application)           10
369f1bf4c2SBenjamin Tissoires 	0x09, 0x42,                    //   Usage (Tip Switch)                12
379f1bf4c2SBenjamin Tissoires 	0x09, 0x44,                    //   Usage (Barrel Switch)             14
389f1bf4c2SBenjamin Tissoires 	0x09, 0x5a,                    //   Usage (Secondary Barrel Switch)   16 /* changed from Secondary Tip Switch */
399f1bf4c2SBenjamin Tissoires 	0x09, 0x3c,                    //   Usage (Invert)                    18
409f1bf4c2SBenjamin Tissoires 	0x09, 0x45,                    //   Usage (Eraser)                    20
419f1bf4c2SBenjamin Tissoires 	0x15, 0x00,                    //   Logical Minimum (0)               22
429f1bf4c2SBenjamin Tissoires 	0x25, 0x01,                    //   Logical Maximum (1)               24
439f1bf4c2SBenjamin Tissoires 	0x75, 0x01,                    //   Report Size (1)                   26
44*531a1cc6SBenjamin Tissoires 	0x95, 0x05,                    //   Report Count (5)                  28 /* changed (was 6) */
459f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              30
469f1bf4c2SBenjamin Tissoires 	0x05, 0x09,                    //   Usage Page (Button)                  /* inserted */
479f1bf4c2SBenjamin Tissoires 	0x09, 0x4a,                    //   Usage (0x4a)                         /* inserted to be translated as input usage 0x149: BTN_STYLUS3 */
489f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                     /* inserted */
499f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)                 /* inserted */
509f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    //   Usage Page (Digitizers)              /* inserted */
519f1bf4c2SBenjamin Tissoires 	0x09, 0x32,                    //   Usage (In Range)                  32
529f1bf4c2SBenjamin Tissoires 	0x75, 0x01,                    //   Report Size (1)                   34
539f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  36
549f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              38
559f1bf4c2SBenjamin Tissoires 	0x81, 0x03,                    //   Input (Cnst,Var,Abs)              40
569f1bf4c2SBenjamin Tissoires 	0x05, 0x01,                    //   Usage Page (Generic Desktop)      42
579f1bf4c2SBenjamin Tissoires 	0x09, 0x30,                    //   Usage (X)                         44
589f1bf4c2SBenjamin Tissoires 	0x09, 0x31,                    //   Usage (Y)                         46
599f1bf4c2SBenjamin Tissoires 	0x55, 0x0d,                    //   Unit Exponent (-3)                48
609f1bf4c2SBenjamin Tissoires 	0x65, 0x33,                    //   Unit (EnglishLinear: in³)         50
619f1bf4c2SBenjamin Tissoires 	0x26, 0xff, 0x7f,              //   Logical Maximum (32767)           52
629f1bf4c2SBenjamin Tissoires 	0x35, 0x00,                    //   Physical Minimum (0)              55
639f1bf4c2SBenjamin Tissoires 	0x46, 0x00, 0x08,              //   Physical Maximum (2048)           57
649f1bf4c2SBenjamin Tissoires 	0x75, 0x10,                    //   Report Size (16)                  60
659f1bf4c2SBenjamin Tissoires 	0x95, 0x02,                    //   Report Count (2)                  62
669f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              64
679f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    //   Usage Page (Digitizers)           66
689f1bf4c2SBenjamin Tissoires 	0x09, 0x30,                    //   Usage (Tip Pressure)              68
699f1bf4c2SBenjamin Tissoires 	0x26, 0xff, 0x3f,              //   Logical Maximum (16383)           70
709f1bf4c2SBenjamin Tissoires 	0x75, 0x10,                    //   Report Size (16)                  73
719f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  75
729f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              77
739f1bf4c2SBenjamin Tissoires 	0x09, 0x3d,                    //   Usage (X Tilt)                    79
749f1bf4c2SBenjamin Tissoires 	0x09, 0x3e,                    //   Usage (Y Tilt)                    81
759f1bf4c2SBenjamin Tissoires 	0x15, 0xa6,                    //   Logical Minimum (-90)             83
769f1bf4c2SBenjamin Tissoires 	0x25, 0x5a,                    //   Logical Maximum (90)              85
779f1bf4c2SBenjamin Tissoires 	0x75, 0x08,                    //   Report Size (8)                   87
789f1bf4c2SBenjamin Tissoires 	0x95, 0x02,                    //   Report Count (2)                  89
799f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              91
809f1bf4c2SBenjamin Tissoires 	0xc0,                          //  End Collection                     93
819f1bf4c2SBenjamin Tissoires 	0xc0,                          // End Collection                      94
829f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    // Usage Page (Digitizers)             95
839f1bf4c2SBenjamin Tissoires 	0x09, 0x04,                    // Usage (Touch Screen)                97
849f1bf4c2SBenjamin Tissoires 	0xa1, 0x01,                    // Collection (Application)            99
859f1bf4c2SBenjamin Tissoires 	0x85, 0x04,                    //  Report ID (4)                      101
869f1bf4c2SBenjamin Tissoires 	0x09, 0x22,                    //  Usage (Finger)                     103
879f1bf4c2SBenjamin Tissoires 	0xa1, 0x02,                    //  Collection (Logical)               105
889f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    //   Usage Page (Digitizers)           107
899f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  109
909f1bf4c2SBenjamin Tissoires 	0x75, 0x06,                    //   Report Size (6)                   111
919f1bf4c2SBenjamin Tissoires 	0x09, 0x51,                    //   Usage (Contact Id)                113
929f1bf4c2SBenjamin Tissoires 	0x15, 0x00,                    //   Logical Minimum (0)               115
939f1bf4c2SBenjamin Tissoires 	0x25, 0x3f,                    //   Logical Maximum (63)              117
949f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              119
959f1bf4c2SBenjamin Tissoires 	0x09, 0x42,                    //   Usage (Tip Switch)                121
969f1bf4c2SBenjamin Tissoires 	0x25, 0x01,                    //   Logical Maximum (1)               123
979f1bf4c2SBenjamin Tissoires 	0x75, 0x01,                    //   Report Size (1)                   125
989f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  127
999f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              129
1009f1bf4c2SBenjamin Tissoires 	0x75, 0x01,                    //   Report Size (1)                   131
1019f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  133
1029f1bf4c2SBenjamin Tissoires 	0x81, 0x03,                    //   Input (Cnst,Var,Abs)              135
1039f1bf4c2SBenjamin Tissoires 	0x05, 0x01,                    //   Usage Page (Generic Desktop)      137
1049f1bf4c2SBenjamin Tissoires 	0x75, 0x10,                    //   Report Size (16)                  139
1059f1bf4c2SBenjamin Tissoires 	0x55, 0x0e,                    //   Unit Exponent (-2)                141
1069f1bf4c2SBenjamin Tissoires 	0x65, 0x11,                    //   Unit (SILinear: cm)               143
1079f1bf4c2SBenjamin Tissoires 	0x09, 0x30,                    //   Usage (X)                         145
1089f1bf4c2SBenjamin Tissoires 	0x26, 0xff, 0x7f,              //   Logical Maximum (32767)           147
1099f1bf4c2SBenjamin Tissoires 	0x35, 0x00,                    //   Physical Minimum (0)              150
1109f1bf4c2SBenjamin Tissoires 	0x46, 0x15, 0x0c,              //   Physical Maximum (3093)           152
1119f1bf4c2SBenjamin Tissoires 	0x81, 0x42,                    //   Input (Data,Var,Abs,Null)         155
1129f1bf4c2SBenjamin Tissoires 	0x09, 0x31,                    //   Usage (Y)                         157
1139f1bf4c2SBenjamin Tissoires 	0x26, 0xff, 0x7f,              //   Logical Maximum (32767)           159
1149f1bf4c2SBenjamin Tissoires 	0x46, 0xcb, 0x06,              //   Physical Maximum (1739)           162
1159f1bf4c2SBenjamin Tissoires 	0x81, 0x42,                    //   Input (Data,Var,Abs,Null)         165
1169f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    //   Usage Page (Digitizers)           167
1179f1bf4c2SBenjamin Tissoires 	0x09, 0x30,                    //   Usage (Tip Pressure)              169
1189f1bf4c2SBenjamin Tissoires 	0x26, 0xff, 0x1f,              //   Logical Maximum (8191)            171
1199f1bf4c2SBenjamin Tissoires 	0x75, 0x10,                    //   Report Size (16)                  174
1209f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  176
1219f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              178
1229f1bf4c2SBenjamin Tissoires 	0xc0,                          //  End Collection                     180
1239f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    //  Usage Page (Digitizers)            181
1249f1bf4c2SBenjamin Tissoires 	0x09, 0x22,                    //  Usage (Finger)                     183
1259f1bf4c2SBenjamin Tissoires 	0xa1, 0x02,                    //  Collection (Logical)               185
1269f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    //   Usage Page (Digitizers)           187
1279f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  189
1289f1bf4c2SBenjamin Tissoires 	0x75, 0x06,                    //   Report Size (6)                   191
1299f1bf4c2SBenjamin Tissoires 	0x09, 0x51,                    //   Usage (Contact Id)                193
1309f1bf4c2SBenjamin Tissoires 	0x15, 0x00,                    //   Logical Minimum (0)               195
1319f1bf4c2SBenjamin Tissoires 	0x25, 0x3f,                    //   Logical Maximum (63)              197
1329f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              199
1339f1bf4c2SBenjamin Tissoires 	0x09, 0x42,                    //   Usage (Tip Switch)                201
1349f1bf4c2SBenjamin Tissoires 	0x25, 0x01,                    //   Logical Maximum (1)               203
1359f1bf4c2SBenjamin Tissoires 	0x75, 0x01,                    //   Report Size (1)                   205
1369f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  207
1379f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              209
1389f1bf4c2SBenjamin Tissoires 	0x75, 0x01,                    //   Report Size (1)                   211
1399f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  213
1409f1bf4c2SBenjamin Tissoires 	0x81, 0x03,                    //   Input (Cnst,Var,Abs)              215
1419f1bf4c2SBenjamin Tissoires 	0x05, 0x01,                    //   Usage Page (Generic Desktop)      217
1429f1bf4c2SBenjamin Tissoires 	0x75, 0x10,                    //   Report Size (16)                  219
1439f1bf4c2SBenjamin Tissoires 	0x55, 0x0e,                    //   Unit Exponent (-2)                221
1449f1bf4c2SBenjamin Tissoires 	0x65, 0x11,                    //   Unit (SILinear: cm)               223
1459f1bf4c2SBenjamin Tissoires 	0x09, 0x30,                    //   Usage (X)                         225
1469f1bf4c2SBenjamin Tissoires 	0x26, 0xff, 0x7f,              //   Logical Maximum (32767)           227
1479f1bf4c2SBenjamin Tissoires 	0x35, 0x00,                    //   Physical Minimum (0)              230
1489f1bf4c2SBenjamin Tissoires 	0x46, 0x15, 0x0c,              //   Physical Maximum (3093)           232
1499f1bf4c2SBenjamin Tissoires 	0x81, 0x42,                    //   Input (Data,Var,Abs,Null)         235
1509f1bf4c2SBenjamin Tissoires 	0x09, 0x31,                    //   Usage (Y)                         237
1519f1bf4c2SBenjamin Tissoires 	0x26, 0xff, 0x7f,              //   Logical Maximum (32767)           239
1529f1bf4c2SBenjamin Tissoires 	0x46, 0xcb, 0x06,              //   Physical Maximum (1739)           242
1539f1bf4c2SBenjamin Tissoires 	0x81, 0x42,                    //   Input (Data,Var,Abs,Null)         245
1549f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    //   Usage Page (Digitizers)           247
1559f1bf4c2SBenjamin Tissoires 	0x09, 0x30,                    //   Usage (Tip Pressure)              249
1569f1bf4c2SBenjamin Tissoires 	0x26, 0xff, 0x1f,              //   Logical Maximum (8191)            251
1579f1bf4c2SBenjamin Tissoires 	0x75, 0x10,                    //   Report Size (16)                  254
1589f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //   Report Count (1)                  256
1599f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //   Input (Data,Var,Abs)              258
1609f1bf4c2SBenjamin Tissoires 	0xc0,                          //  End Collection                     260
1619f1bf4c2SBenjamin Tissoires 	0x05, 0x0d,                    //  Usage Page (Digitizers)            261
1629f1bf4c2SBenjamin Tissoires 	0x09, 0x56,                    //  Usage (Scan Time)                  263
1639f1bf4c2SBenjamin Tissoires 	0x55, 0x00,                    //  Unit Exponent (0)                  265
1649f1bf4c2SBenjamin Tissoires 	0x65, 0x00,                    //  Unit (None)                        267
1659f1bf4c2SBenjamin Tissoires 	0x27, 0xff, 0xff, 0xff, 0x7f,  //  Logical Maximum (2147483647)       269
1669f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //  Report Count (1)                   274
1679f1bf4c2SBenjamin Tissoires 	0x75, 0x20,                    //  Report Size (32)                   276
1689f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //  Input (Data,Var,Abs)               278
1699f1bf4c2SBenjamin Tissoires 	0x09, 0x54,                    //  Usage (Contact Count)              280
1709f1bf4c2SBenjamin Tissoires 	0x25, 0x7f,                    //  Logical Maximum (127)              282
1719f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //  Report Count (1)                   284
1729f1bf4c2SBenjamin Tissoires 	0x75, 0x08,                    //  Report Size (8)                    286
1739f1bf4c2SBenjamin Tissoires 	0x81, 0x02,                    //  Input (Data,Var,Abs)               288
1749f1bf4c2SBenjamin Tissoires 	0x75, 0x08,                    //  Report Size (8)                    290
1759f1bf4c2SBenjamin Tissoires 	0x95, 0x08,                    //  Report Count (8)                   292
1769f1bf4c2SBenjamin Tissoires 	0x81, 0x03,                    //  Input (Cnst,Var,Abs)               294
1779f1bf4c2SBenjamin Tissoires 	0x85, 0x05,                    //  Report ID (5)                      296
1789f1bf4c2SBenjamin Tissoires 	0x09, 0x55,                    //  Usage (Contact Max)                298
1799f1bf4c2SBenjamin Tissoires 	0x25, 0x0a,                    //  Logical Maximum (10)               300
1809f1bf4c2SBenjamin Tissoires 	0x75, 0x08,                    //  Report Size (8)                    302
1819f1bf4c2SBenjamin Tissoires 	0x95, 0x01,                    //  Report Count (1)                   304
1829f1bf4c2SBenjamin Tissoires 	0xb1, 0x02,                    //  Feature (Data,Var,Abs)             306
1839f1bf4c2SBenjamin Tissoires 	0x06, 0x00, 0xff,              //  Usage Page (Vendor Defined Page 1) 308
1849f1bf4c2SBenjamin Tissoires 	0x09, 0xc5,                    //  Usage (Vendor Usage 0xc5)          311
1859f1bf4c2SBenjamin Tissoires 	0x85, 0x06,                    //  Report ID (6)                      313
1869f1bf4c2SBenjamin Tissoires 	0x15, 0x00,                    //  Logical Minimum (0)                315
1879f1bf4c2SBenjamin Tissoires 	0x26, 0xff, 0x00,              //  Logical Maximum (255)              317
1889f1bf4c2SBenjamin Tissoires 	0x75, 0x08,                    //  Report Size (8)                    320
1899f1bf4c2SBenjamin Tissoires 	0x96, 0x00, 0x01,              //  Report Count (256)                 322
1909f1bf4c2SBenjamin Tissoires 	0xb1, 0x02,                    //  Feature (Data,Var,Abs)             325
1919f1bf4c2SBenjamin Tissoires 	0xc0,                          // End Collection                      327
192*531a1cc6SBenjamin Tissoires 	/* New in Firmware Version: HUION_M220_240524 */
193*531a1cc6SBenjamin Tissoires 	0x05, 0x01,                    // Usage Page (Generic Desktop)            328
194*531a1cc6SBenjamin Tissoires 	0x09, 0x01,                    // Usage (Pointer)                         330
195*531a1cc6SBenjamin Tissoires 	0xa1, 0x01,                    // Collection (Application)                332
196*531a1cc6SBenjamin Tissoires 	0x09, 0x01,                    //   Usage (Pointer)                       334
197*531a1cc6SBenjamin Tissoires 	0xa1, 0x00,                    //   Collection (Physical)                 336
198*531a1cc6SBenjamin Tissoires 	0x05, 0x09,                    //     Usage Page (Button)                 338
199*531a1cc6SBenjamin Tissoires 	0x19, 0x01,                    //     UsageMinimum (1)                    340
200*531a1cc6SBenjamin Tissoires 	0x29, 0x03,                    //     UsageMaximum (3)                    342
201*531a1cc6SBenjamin Tissoires 	0x15, 0x00,                    //     Logical Minimum (0)                 344
202*531a1cc6SBenjamin Tissoires 	0x25, 0x01,                    //     Logical Maximum (1)                 346
203*531a1cc6SBenjamin Tissoires 	0x85, 0x02,                    //     Report ID (2)                       348
204*531a1cc6SBenjamin Tissoires 	0x95, 0x03,                    //     Report Count (3)                    350
205*531a1cc6SBenjamin Tissoires 	0x75, 0x01,                    //     Report Size (1)                     352
206*531a1cc6SBenjamin Tissoires 	0x81, 0x02,                    //     Input (Data,Var,Abs)                354
207*531a1cc6SBenjamin Tissoires 	0x95, 0x01,                    //     Report Count (1)                    356
208*531a1cc6SBenjamin Tissoires 	0x75, 0x05,                    //     Report Size (5)                     358
209*531a1cc6SBenjamin Tissoires 	0x81, 0x01,                    //     Input (Cnst,Arr,Abs)                360
210*531a1cc6SBenjamin Tissoires 	0x05, 0x01,                    //     Usage Page (Generic Desktop)        362
211*531a1cc6SBenjamin Tissoires 	0x09, 0x30,                    //     Usage (X)                           364
212*531a1cc6SBenjamin Tissoires 	0x09, 0x31,                    //     Usage (Y)                           366
213*531a1cc6SBenjamin Tissoires 	0x15, 0x81,                    //     Logical Minimum (-127)              368
214*531a1cc6SBenjamin Tissoires 	0x25, 0x7f,                    //     Logical Maximum (127)               370
215*531a1cc6SBenjamin Tissoires 	0x75, 0x08,                    //     Report Size (8)                     372
216*531a1cc6SBenjamin Tissoires 	0x95, 0x02,                    //     Report Count (2)                    374
217*531a1cc6SBenjamin Tissoires 	0x81, 0x06,                    //     Input (Data,Var,Rel)                376
218*531a1cc6SBenjamin Tissoires 	0x95, 0x04,                    //     Report Count (4)                    378
219*531a1cc6SBenjamin Tissoires 	0x75, 0x08,                    //     Report Size (8)                     380
220*531a1cc6SBenjamin Tissoires 	0x81, 0x01,                    //     Input (Cnst,Arr,Abs)                382
221*531a1cc6SBenjamin Tissoires 	0xc0,                          //   End Collection                        384
222*531a1cc6SBenjamin Tissoires 	0xc0,                          // End Collection                          385
223*531a1cc6SBenjamin Tissoires 	0x05, 0x0d,                    // Usage Page (Digitizers)                 386
224*531a1cc6SBenjamin Tissoires 	0x09, 0x05,                    // Usage (Touch Pad)                       388
225*531a1cc6SBenjamin Tissoires 	0xa1, 0x01,                    // Collection (Application)                390
226*531a1cc6SBenjamin Tissoires 	0x06, 0x00, 0xff,              //   Usage Page (Vendor Defined Page FF00) 392
227*531a1cc6SBenjamin Tissoires 	0x09, 0x0c,                    //   Usage (Vendor Usage 0x0c)             395
228*531a1cc6SBenjamin Tissoires 	0x15, 0x00,                    //   Logical Minimum (0)                   397
229*531a1cc6SBenjamin Tissoires 	0x26, 0xff, 0x00,              //   Logical Maximum (255)                 399
230*531a1cc6SBenjamin Tissoires 	0x75, 0x08,                    //   Report Size (8)                       402
231*531a1cc6SBenjamin Tissoires 	0x95, 0x10,                    //   Report Count (16)                     404
232*531a1cc6SBenjamin Tissoires 	0x85, 0x3f,                    //   Report ID (63)                        406
233*531a1cc6SBenjamin Tissoires 	0x81, 0x22,                    //   Input (Data,Var,Abs,NoPref)           408
234*531a1cc6SBenjamin Tissoires 	0xc0,                          // End Collection                          410
235*531a1cc6SBenjamin Tissoires 	0x06, 0x00, 0xff,              // Usage Page (Vendor Defined Page FF00)   411
236*531a1cc6SBenjamin Tissoires 	0x09, 0x0c,                    // Usage (Vendor Usage 0x0c)               414
237*531a1cc6SBenjamin Tissoires 	0xa1, 0x01,                    // Collection (Application)                416
238*531a1cc6SBenjamin Tissoires 	0x06, 0x00, 0xff,              //   Usage Page (Vendor Defined Page FF00) 418
239*531a1cc6SBenjamin Tissoires 	0x09, 0x0c,                    //   Usage (Vendor Usage 0x0c)             421
240*531a1cc6SBenjamin Tissoires 	0x15, 0x00,                    //   Logical Minimum (0)                   423
241*531a1cc6SBenjamin Tissoires 	0x26, 0xff, 0x00,              //   Logical Maximum (255)                 425
242*531a1cc6SBenjamin Tissoires 	0x85, 0x44,                    //   Report ID (68)                        428
243*531a1cc6SBenjamin Tissoires 	0x75, 0x08,                    //   Report Size (8)                       430
244*531a1cc6SBenjamin Tissoires 	0x96, 0x6b, 0x05,              //   Report Count (1387)                   432
245*531a1cc6SBenjamin Tissoires 	0x81, 0x00,                    //   Input (Data,Arr,Abs)                  435
246*531a1cc6SBenjamin Tissoires 	0xc0,                          // End Collection                          437
2479f1bf4c2SBenjamin Tissoires };
2489f1bf4c2SBenjamin Tissoires 
249*531a1cc6SBenjamin Tissoires #define PRE_240524_RDESC_SIZE 328
250*531a1cc6SBenjamin Tissoires #define PRE_240524_RDESC_FIXED_SIZE 338 /* The original bits of the descriptor */
251*531a1cc6SBenjamin Tissoires #define FW_240524_RDESC_SIZE 438
252*531a1cc6SBenjamin Tissoires #define FW_240524_RDESC_FIXED_SIZE sizeof(fixed_rdesc)
253*531a1cc6SBenjamin Tissoires 
SEC(HID_BPF_RDESC_FIXUP)254df67602fSBenjamin Tissoires SEC(HID_BPF_RDESC_FIXUP)
2559f1bf4c2SBenjamin Tissoires int BPF_PROG(hid_fix_rdesc_huion_kamvas_pro_19, struct hid_bpf_ctx *hctx)
2569f1bf4c2SBenjamin Tissoires {
2579f1bf4c2SBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, HID_MAX_DESCRIPTOR_SIZE /* size */);
2589f1bf4c2SBenjamin Tissoires 
2599f1bf4c2SBenjamin Tissoires 	if (!data)
2609f1bf4c2SBenjamin Tissoires 		return 0; /* EPERM check */
2619f1bf4c2SBenjamin Tissoires 
262*531a1cc6SBenjamin Tissoires 	if (hctx->size == FW_240524_RDESC_SIZE) {
263*531a1cc6SBenjamin Tissoires 		__builtin_memcpy(data, fixed_rdesc, FW_240524_RDESC_FIXED_SIZE);
2649f1bf4c2SBenjamin Tissoires 		return sizeof(fixed_rdesc);
2659f1bf4c2SBenjamin Tissoires 	}
2669f1bf4c2SBenjamin Tissoires 
267*531a1cc6SBenjamin Tissoires 	__builtin_memcpy(data, fixed_rdesc, PRE_240524_RDESC_FIXED_SIZE);
268*531a1cc6SBenjamin Tissoires 
269*531a1cc6SBenjamin Tissoires 	return PRE_240524_RDESC_FIXED_SIZE;
270*531a1cc6SBenjamin Tissoires }
271*531a1cc6SBenjamin Tissoires 
2729f1bf4c2SBenjamin Tissoires /*
2739f1bf4c2SBenjamin Tissoires  * This tablet reports the 3rd button through invert, but this conflict
2749f1bf4c2SBenjamin Tissoires  * with the normal eraser mode.
2759f1bf4c2SBenjamin Tissoires  * Fortunately, before entering eraser mode, (so Invert = 1),
2769f1bf4c2SBenjamin Tissoires  * the tablet always sends an out-of-proximity event.
2779f1bf4c2SBenjamin Tissoires  * So we can detect that single event and:
2789f1bf4c2SBenjamin Tissoires  * - if there was none but the invert bit was toggled: this is the
2799f1bf4c2SBenjamin Tissoires  *   third button
2809f1bf4c2SBenjamin Tissoires  * - if there was this out-of-proximity event, we are entering
2819f1bf4c2SBenjamin Tissoires  *   eraser mode, and we will until the next out-of-proximity.
2829f1bf4c2SBenjamin Tissoires  */
SEC(HID_BPF_DEVICE_EVENT)283df67602fSBenjamin Tissoires SEC(HID_BPF_DEVICE_EVENT)
2849f1bf4c2SBenjamin Tissoires int BPF_PROG(kamvas_pro_19_fix_3rd_button, struct hid_bpf_ctx *hctx)
2859f1bf4c2SBenjamin Tissoires {
2869f1bf4c2SBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 10 /* size */);
2879f1bf4c2SBenjamin Tissoires 
2889f1bf4c2SBenjamin Tissoires 	if (!data)
2899f1bf4c2SBenjamin Tissoires 		return 0; /* EPERM check */
2909f1bf4c2SBenjamin Tissoires 
2919f1bf4c2SBenjamin Tissoires 	if (data[0] != 0x0a) /* not the pen report ID */
2929f1bf4c2SBenjamin Tissoires 		return 0;
2939f1bf4c2SBenjamin Tissoires 
2949f1bf4c2SBenjamin Tissoires 	/* stylus is out of range */
2959f1bf4c2SBenjamin Tissoires 	if (!(data[1] & 0x40)) {
2969f1bf4c2SBenjamin Tissoires 		prev_was_out_of_range = true;
2979f1bf4c2SBenjamin Tissoires 		in_eraser_mode = false;
2989f1bf4c2SBenjamin Tissoires 		return 0;
2999f1bf4c2SBenjamin Tissoires 	}
3009f1bf4c2SBenjamin Tissoires 
3019f1bf4c2SBenjamin Tissoires 	/* going into eraser mode (Invert = 1) only happens after an
3029f1bf4c2SBenjamin Tissoires 	 * out of range event
3039f1bf4c2SBenjamin Tissoires 	 */
3049f1bf4c2SBenjamin Tissoires 	if (prev_was_out_of_range && (data[1] & 0x18))
3059f1bf4c2SBenjamin Tissoires 		in_eraser_mode = true;
3069f1bf4c2SBenjamin Tissoires 
3079f1bf4c2SBenjamin Tissoires 	/* eraser mode works fine */
3089f1bf4c2SBenjamin Tissoires 	if (in_eraser_mode)
3099f1bf4c2SBenjamin Tissoires 		return 0;
3109f1bf4c2SBenjamin Tissoires 
3119f1bf4c2SBenjamin Tissoires 	/* copy the Invert bit reported for the 3rd button in bit 7 */
3129f1bf4c2SBenjamin Tissoires 	if (data[1] & 0x08)
3139f1bf4c2SBenjamin Tissoires 		data[1] |= 0x20;
3149f1bf4c2SBenjamin Tissoires 
3159f1bf4c2SBenjamin Tissoires 	/* clear Invert bit now that it was copied */
3169f1bf4c2SBenjamin Tissoires 	data[1] &= 0xf7;
3179f1bf4c2SBenjamin Tissoires 
3189f1bf4c2SBenjamin Tissoires 	prev_was_out_of_range = false;
3199f1bf4c2SBenjamin Tissoires 
3209f1bf4c2SBenjamin Tissoires 	return 0;
3219f1bf4c2SBenjamin Tissoires }
3229f1bf4c2SBenjamin Tissoires 
32350fe0fc6SBenjamin Tissoires HID_BPF_OPS(huion_Kamvas_pro_19) = {
32450fe0fc6SBenjamin Tissoires 	.hid_rdesc_fixup = (void *)hid_fix_rdesc_huion_kamvas_pro_19,
32550fe0fc6SBenjamin Tissoires 	.hid_device_event = (void *)kamvas_pro_19_fix_3rd_button,
32650fe0fc6SBenjamin Tissoires };
32750fe0fc6SBenjamin Tissoires 
3289f1bf4c2SBenjamin Tissoires SEC("syscall")
probe(struct hid_bpf_probe_args * ctx)3299f1bf4c2SBenjamin Tissoires int probe(struct hid_bpf_probe_args *ctx)
3309f1bf4c2SBenjamin Tissoires {
331*531a1cc6SBenjamin Tissoires 
332*531a1cc6SBenjamin Tissoires 	ctx->retval = !((ctx->rdesc_size == PRE_240524_RDESC_SIZE) ||
333*531a1cc6SBenjamin Tissoires 			(ctx->rdesc_size == FW_240524_RDESC_SIZE));
3349f1bf4c2SBenjamin Tissoires 	if (ctx->retval)
3359f1bf4c2SBenjamin Tissoires 		ctx->retval = -EINVAL;
3369f1bf4c2SBenjamin Tissoires 
3379f1bf4c2SBenjamin Tissoires 	/* ensure the kernel isn't fixed already */
3389f1bf4c2SBenjamin Tissoires 	if (ctx->rdesc[17] != 0x43) /* Secondary Tip Switch */
3399f1bf4c2SBenjamin Tissoires 		ctx->retval = -EINVAL;
3409f1bf4c2SBenjamin Tissoires 
3419f1bf4c2SBenjamin Tissoires 	struct hid_bpf_ctx *hctx = hid_bpf_allocate_context(ctx->hid);
3429f1bf4c2SBenjamin Tissoires 
3439f1bf4c2SBenjamin Tissoires 	if (!hctx) {
3449f1bf4c2SBenjamin Tissoires 		return ctx->retval = -EINVAL;
3459f1bf4c2SBenjamin Tissoires 		return 0;
3469f1bf4c2SBenjamin Tissoires 	}
3479f1bf4c2SBenjamin Tissoires 
3489f1bf4c2SBenjamin Tissoires 	const char *name = hctx->hid->name;
3499f1bf4c2SBenjamin Tissoires 
3509f1bf4c2SBenjamin Tissoires 	/* strip out TEST_PREFIX */
3519f1bf4c2SBenjamin Tissoires 	if (!__builtin_memcmp(name, TEST_PREFIX, sizeof(TEST_PREFIX) - 1))
3529f1bf4c2SBenjamin Tissoires 		name += sizeof(TEST_PREFIX) - 1;
3539f1bf4c2SBenjamin Tissoires 
3549f1bf4c2SBenjamin Tissoires 	if (__builtin_memcmp(name, NAME_KAMVAS_PRO_19, sizeof(NAME_KAMVAS_PRO_19)))
3559f1bf4c2SBenjamin Tissoires 		ctx->retval = -EINVAL;
3569f1bf4c2SBenjamin Tissoires 
3579f1bf4c2SBenjamin Tissoires 	hid_bpf_release_context(hctx);
3589f1bf4c2SBenjamin Tissoires 
3599f1bf4c2SBenjamin Tissoires 	return 0;
3609f1bf4c2SBenjamin Tissoires }
3619f1bf4c2SBenjamin Tissoires 
3629f1bf4c2SBenjamin Tissoires char _license[] SEC("license") = "GPL";
363