]> Git Repo - linux.git/blob - drivers/hid/hid-uclogic-rdesc.c
x86/kaslr: Expose and use the end of the physical memory address space
[linux.git] / drivers / hid / hid-uclogic-rdesc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  HID driver for UC-Logic devices not fully compliant with HID standard
4  *  - original and fixed report descriptors
5  *
6  *  Copyright (c) 2010-2017 Nikolai Kondrashov
7  *  Copyright (c) 2013 Martin Rusko
8  */
9
10 /*
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License as published by the Free
13  * Software Foundation; either version 2 of the License, or (at your option)
14  * any later version.
15  */
16
17 #include "hid-uclogic-rdesc.h"
18 #include <linux/slab.h>
19 #include <asm/unaligned.h>
20 #include <kunit/visibility.h>
21
22 /* Fixed WP4030U report descriptor */
23 __u8 uclogic_rdesc_wp4030u_fixed_arr[] = {
24         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
25         0x09, 0x01,         /*  Usage (Digitizer),                  */
26         0xA1, 0x01,         /*  Collection (Application),           */
27         0x85, 0x09,         /*      Report ID (9),                  */
28         0x09, 0x20,         /*      Usage (Stylus),                 */
29         0xA0,               /*      Collection (Physical),          */
30         0x75, 0x01,         /*          Report Size (1),            */
31         0x09, 0x42,         /*          Usage (Tip Switch),         */
32         0x09, 0x44,         /*          Usage (Barrel Switch),      */
33         0x09, 0x46,         /*          Usage (Tablet Pick),        */
34         0x14,               /*          Logical Minimum (0),        */
35         0x25, 0x01,         /*          Logical Maximum (1),        */
36         0x95, 0x03,         /*          Report Count (3),           */
37         0x81, 0x02,         /*          Input (Variable),           */
38         0x95, 0x05,         /*          Report Count (5),           */
39         0x81, 0x01,         /*          Input (Constant),           */
40         0x75, 0x10,         /*          Report Size (16),           */
41         0x95, 0x01,         /*          Report Count (1),           */
42         0x14,               /*          Logical Minimum (0),        */
43         0xA4,               /*          Push,                       */
44         0x05, 0x01,         /*          Usage Page (Desktop),       */
45         0x55, 0xFD,         /*          Unit Exponent (-3),         */
46         0x65, 0x13,         /*          Unit (Inch),                */
47         0x34,               /*          Physical Minimum (0),       */
48         0x09, 0x30,         /*          Usage (X),                  */
49         0x46, 0xA0, 0x0F,   /*          Physical Maximum (4000),    */
50         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
51         0x81, 0x02,         /*          Input (Variable),           */
52         0x09, 0x31,         /*          Usage (Y),                  */
53         0x46, 0xB8, 0x0B,   /*          Physical Maximum (3000),    */
54         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
55         0x81, 0x02,         /*          Input (Variable),           */
56         0xB4,               /*          Pop,                        */
57         0x09, 0x30,         /*          Usage (Tip Pressure),       */
58         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
59         0x81, 0x02,         /*          Input (Variable),           */
60         0xC0,               /*      End Collection,                 */
61         0xC0                /*  End Collection                      */
62 };
63
64 const size_t uclogic_rdesc_wp4030u_fixed_size =
65                         sizeof(uclogic_rdesc_wp4030u_fixed_arr);
66
67 /* Fixed WP5540U report descriptor */
68 __u8 uclogic_rdesc_wp5540u_fixed_arr[] = {
69         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
70         0x09, 0x01,         /*  Usage (Digitizer),                  */
71         0xA1, 0x01,         /*  Collection (Application),           */
72         0x85, 0x09,         /*      Report ID (9),                  */
73         0x09, 0x20,         /*      Usage (Stylus),                 */
74         0xA0,               /*      Collection (Physical),          */
75         0x75, 0x01,         /*          Report Size (1),            */
76         0x09, 0x42,         /*          Usage (Tip Switch),         */
77         0x09, 0x44,         /*          Usage (Barrel Switch),      */
78         0x09, 0x46,         /*          Usage (Tablet Pick),        */
79         0x14,               /*          Logical Minimum (0),        */
80         0x25, 0x01,         /*          Logical Maximum (1),        */
81         0x95, 0x03,         /*          Report Count (3),           */
82         0x81, 0x02,         /*          Input (Variable),           */
83         0x95, 0x05,         /*          Report Count (5),           */
84         0x81, 0x01,         /*          Input (Constant),           */
85         0x75, 0x10,         /*          Report Size (16),           */
86         0x95, 0x01,         /*          Report Count (1),           */
87         0x14,               /*          Logical Minimum (0),        */
88         0xA4,               /*          Push,                       */
89         0x05, 0x01,         /*          Usage Page (Desktop),       */
90         0x55, 0xFD,         /*          Unit Exponent (-3),         */
91         0x65, 0x13,         /*          Unit (Inch),                */
92         0x34,               /*          Physical Minimum (0),       */
93         0x09, 0x30,         /*          Usage (X),                  */
94         0x46, 0x7C, 0x15,   /*          Physical Maximum (5500),    */
95         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
96         0x81, 0x02,         /*          Input (Variable),           */
97         0x09, 0x31,         /*          Usage (Y),                  */
98         0x46, 0xA0, 0x0F,   /*          Physical Maximum (4000),    */
99         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
100         0x81, 0x02,         /*          Input (Variable),           */
101         0xB4,               /*          Pop,                        */
102         0x09, 0x30,         /*          Usage (Tip Pressure),       */
103         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
104         0x81, 0x02,         /*          Input (Variable),           */
105         0xC0,               /*      End Collection,                 */
106         0xC0,               /*  End Collection,                     */
107         0x05, 0x01,         /*  Usage Page (Desktop),               */
108         0x09, 0x02,         /*  Usage (Mouse),                      */
109         0xA1, 0x01,         /*  Collection (Application),           */
110         0x85, 0x08,         /*      Report ID (8),                  */
111         0x09, 0x01,         /*      Usage (Pointer),                */
112         0xA0,               /*      Collection (Physical),          */
113         0x75, 0x01,         /*          Report Size (1),            */
114         0x05, 0x09,         /*          Usage Page (Button),        */
115         0x19, 0x01,         /*          Usage Minimum (01h),        */
116         0x29, 0x03,         /*          Usage Maximum (03h),        */
117         0x14,               /*          Logical Minimum (0),        */
118         0x25, 0x01,         /*          Logical Maximum (1),        */
119         0x95, 0x03,         /*          Report Count (3),           */
120         0x81, 0x02,         /*          Input (Variable),           */
121         0x95, 0x05,         /*          Report Count (5),           */
122         0x81, 0x01,         /*          Input (Constant),           */
123         0x05, 0x01,         /*          Usage Page (Desktop),       */
124         0x75, 0x08,         /*          Report Size (8),            */
125         0x09, 0x30,         /*          Usage (X),                  */
126         0x09, 0x31,         /*          Usage (Y),                  */
127         0x15, 0x81,         /*          Logical Minimum (-127),     */
128         0x25, 0x7F,         /*          Logical Maximum (127),      */
129         0x95, 0x02,         /*          Report Count (2),           */
130         0x81, 0x06,         /*          Input (Variable, Relative), */
131         0x09, 0x38,         /*          Usage (Wheel),              */
132         0x15, 0xFF,         /*          Logical Minimum (-1),       */
133         0x25, 0x01,         /*          Logical Maximum (1),        */
134         0x95, 0x01,         /*          Report Count (1),           */
135         0x81, 0x06,         /*          Input (Variable, Relative), */
136         0x81, 0x01,         /*          Input (Constant),           */
137         0xC0,               /*      End Collection,                 */
138         0xC0                /*  End Collection                      */
139 };
140
141 const size_t uclogic_rdesc_wp5540u_fixed_size =
142                         sizeof(uclogic_rdesc_wp5540u_fixed_arr);
143
144 /* Fixed WP8060U report descriptor */
145 __u8 uclogic_rdesc_wp8060u_fixed_arr[] = {
146         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
147         0x09, 0x01,         /*  Usage (Digitizer),                  */
148         0xA1, 0x01,         /*  Collection (Application),           */
149         0x85, 0x09,         /*      Report ID (9),                  */
150         0x09, 0x20,         /*      Usage (Stylus),                 */
151         0xA0,               /*      Collection (Physical),          */
152         0x75, 0x01,         /*          Report Size (1),            */
153         0x09, 0x42,         /*          Usage (Tip Switch),         */
154         0x09, 0x44,         /*          Usage (Barrel Switch),      */
155         0x09, 0x46,         /*          Usage (Tablet Pick),        */
156         0x14,               /*          Logical Minimum (0),        */
157         0x25, 0x01,         /*          Logical Maximum (1),        */
158         0x95, 0x03,         /*          Report Count (3),           */
159         0x81, 0x02,         /*          Input (Variable),           */
160         0x95, 0x05,         /*          Report Count (5),           */
161         0x81, 0x01,         /*          Input (Constant),           */
162         0x75, 0x10,         /*          Report Size (16),           */
163         0x95, 0x01,         /*          Report Count (1),           */
164         0x14,               /*          Logical Minimum (0),        */
165         0xA4,               /*          Push,                       */
166         0x05, 0x01,         /*          Usage Page (Desktop),       */
167         0x55, 0xFD,         /*          Unit Exponent (-3),         */
168         0x65, 0x13,         /*          Unit (Inch),                */
169         0x34,               /*          Physical Minimum (0),       */
170         0x09, 0x30,         /*          Usage (X),                  */
171         0x46, 0x40, 0x1F,   /*          Physical Maximum (8000),    */
172         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
173         0x81, 0x02,         /*          Input (Variable),           */
174         0x09, 0x31,         /*          Usage (Y),                  */
175         0x46, 0x70, 0x17,   /*          Physical Maximum (6000),    */
176         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
177         0x81, 0x02,         /*          Input (Variable),           */
178         0xB4,               /*          Pop,                        */
179         0x09, 0x30,         /*          Usage (Tip Pressure),       */
180         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
181         0x81, 0x02,         /*          Input (Variable),           */
182         0xC0,               /*      End Collection,                 */
183         0xC0,               /*  End Collection,                     */
184         0x05, 0x01,         /*  Usage Page (Desktop),               */
185         0x09, 0x02,         /*  Usage (Mouse),                      */
186         0xA1, 0x01,         /*  Collection (Application),           */
187         0x85, 0x08,         /*      Report ID (8),                  */
188         0x09, 0x01,         /*      Usage (Pointer),                */
189         0xA0,               /*      Collection (Physical),          */
190         0x75, 0x01,         /*          Report Size (1),            */
191         0x05, 0x09,         /*          Usage Page (Button),        */
192         0x19, 0x01,         /*          Usage Minimum (01h),        */
193         0x29, 0x03,         /*          Usage Maximum (03h),        */
194         0x14,               /*          Logical Minimum (0),        */
195         0x25, 0x01,         /*          Logical Maximum (1),        */
196         0x95, 0x03,         /*          Report Count (3),           */
197         0x81, 0x02,         /*          Input (Variable),           */
198         0x95, 0x05,         /*          Report Count (5),           */
199         0x81, 0x01,         /*          Input (Constant),           */
200         0x05, 0x01,         /*          Usage Page (Desktop),       */
201         0x75, 0x08,         /*          Report Size (8),            */
202         0x09, 0x30,         /*          Usage (X),                  */
203         0x09, 0x31,         /*          Usage (Y),                  */
204         0x15, 0x81,         /*          Logical Minimum (-127),     */
205         0x25, 0x7F,         /*          Logical Maximum (127),      */
206         0x95, 0x02,         /*          Report Count (2),           */
207         0x81, 0x06,         /*          Input (Variable, Relative), */
208         0x09, 0x38,         /*          Usage (Wheel),              */
209         0x15, 0xFF,         /*          Logical Minimum (-1),       */
210         0x25, 0x01,         /*          Logical Maximum (1),        */
211         0x95, 0x01,         /*          Report Count (1),           */
212         0x81, 0x06,         /*          Input (Variable, Relative), */
213         0x81, 0x01,         /*          Input (Constant),           */
214         0xC0,               /*      End Collection,                 */
215         0xC0                /*  End Collection                      */
216 };
217
218 const size_t uclogic_rdesc_wp8060u_fixed_size =
219                         sizeof(uclogic_rdesc_wp8060u_fixed_arr);
220
221 /* Fixed WP1062 report descriptor */
222 __u8 uclogic_rdesc_wp1062_fixed_arr[] = {
223         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
224         0x09, 0x01,         /*  Usage (Digitizer),                  */
225         0xA1, 0x01,         /*  Collection (Application),           */
226         0x85, 0x09,         /*      Report ID (9),                  */
227         0x09, 0x20,         /*      Usage (Stylus),                 */
228         0xA0,               /*      Collection (Physical),          */
229         0x75, 0x01,         /*          Report Size (1),            */
230         0x09, 0x42,         /*          Usage (Tip Switch),         */
231         0x09, 0x44,         /*          Usage (Barrel Switch),      */
232         0x09, 0x46,         /*          Usage (Tablet Pick),        */
233         0x14,               /*          Logical Minimum (0),        */
234         0x25, 0x01,         /*          Logical Maximum (1),        */
235         0x95, 0x03,         /*          Report Count (3),           */
236         0x81, 0x02,         /*          Input (Variable),           */
237         0x95, 0x04,         /*          Report Count (4),           */
238         0x81, 0x01,         /*          Input (Constant),           */
239         0x09, 0x32,         /*          Usage (In Range),           */
240         0x95, 0x01,         /*          Report Count (1),           */
241         0x81, 0x02,         /*          Input (Variable),           */
242         0x75, 0x10,         /*          Report Size (16),           */
243         0x95, 0x01,         /*          Report Count (1),           */
244         0x14,               /*          Logical Minimum (0),        */
245         0xA4,               /*          Push,                       */
246         0x05, 0x01,         /*          Usage Page (Desktop),       */
247         0x55, 0xFD,         /*          Unit Exponent (-3),         */
248         0x65, 0x13,         /*          Unit (Inch),                */
249         0x34,               /*          Physical Minimum (0),       */
250         0x09, 0x30,         /*          Usage (X),                  */
251         0x46, 0x10, 0x27,   /*          Physical Maximum (10000),   */
252         0x26, 0x20, 0x4E,   /*          Logical Maximum (20000),    */
253         0x81, 0x02,         /*          Input (Variable),           */
254         0x09, 0x31,         /*          Usage (Y),                  */
255         0x46, 0xB7, 0x19,   /*          Physical Maximum (6583),    */
256         0x26, 0x6E, 0x33,   /*          Logical Maximum (13166),    */
257         0x81, 0x02,         /*          Input (Variable),           */
258         0xB4,               /*          Pop,                        */
259         0x09, 0x30,         /*          Usage (Tip Pressure),       */
260         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
261         0x81, 0x02,         /*          Input (Variable),           */
262         0xC0,               /*      End Collection,                 */
263         0xC0                /*  End Collection                      */
264 };
265
266 const size_t uclogic_rdesc_wp1062_fixed_size =
267                         sizeof(uclogic_rdesc_wp1062_fixed_arr);
268
269 /* Fixed PF1209 report descriptor */
270 __u8 uclogic_rdesc_pf1209_fixed_arr[] = {
271         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
272         0x09, 0x01,         /*  Usage (Digitizer),                  */
273         0xA1, 0x01,         /*  Collection (Application),           */
274         0x85, 0x09,         /*      Report ID (9),                  */
275         0x09, 0x20,         /*      Usage (Stylus),                 */
276         0xA0,               /*      Collection (Physical),          */
277         0x75, 0x01,         /*          Report Size (1),            */
278         0x09, 0x42,         /*          Usage (Tip Switch),         */
279         0x09, 0x44,         /*          Usage (Barrel Switch),      */
280         0x09, 0x46,         /*          Usage (Tablet Pick),        */
281         0x14,               /*          Logical Minimum (0),        */
282         0x25, 0x01,         /*          Logical Maximum (1),        */
283         0x95, 0x03,         /*          Report Count (3),           */
284         0x81, 0x02,         /*          Input (Variable),           */
285         0x95, 0x05,         /*          Report Count (5),           */
286         0x81, 0x01,         /*          Input (Constant),           */
287         0x75, 0x10,         /*          Report Size (16),           */
288         0x95, 0x01,         /*          Report Count (1),           */
289         0x14,               /*          Logical Minimum (0),        */
290         0xA4,               /*          Push,                       */
291         0x05, 0x01,         /*          Usage Page (Desktop),       */
292         0x55, 0xFD,         /*          Unit Exponent (-3),         */
293         0x65, 0x13,         /*          Unit (Inch),                */
294         0x34,               /*          Physical Minimum (0),       */
295         0x09, 0x30,         /*          Usage (X),                  */
296         0x46, 0xE0, 0x2E,   /*          Physical Maximum (12000),   */
297         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
298         0x81, 0x02,         /*          Input (Variable),           */
299         0x09, 0x31,         /*          Usage (Y),                  */
300         0x46, 0x28, 0x23,   /*          Physical Maximum (9000),    */
301         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
302         0x81, 0x02,         /*          Input (Variable),           */
303         0xB4,               /*          Pop,                        */
304         0x09, 0x30,         /*          Usage (Tip Pressure),       */
305         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
306         0x81, 0x02,         /*          Input (Variable),           */
307         0xC0,               /*      End Collection,                 */
308         0xC0,               /*  End Collection,                     */
309         0x05, 0x01,         /*  Usage Page (Desktop),               */
310         0x09, 0x02,         /*  Usage (Mouse),                      */
311         0xA1, 0x01,         /*  Collection (Application),           */
312         0x85, 0x08,         /*      Report ID (8),                  */
313         0x09, 0x01,         /*      Usage (Pointer),                */
314         0xA0,               /*      Collection (Physical),          */
315         0x75, 0x01,         /*          Report Size (1),            */
316         0x05, 0x09,         /*          Usage Page (Button),        */
317         0x19, 0x01,         /*          Usage Minimum (01h),        */
318         0x29, 0x03,         /*          Usage Maximum (03h),        */
319         0x14,               /*          Logical Minimum (0),        */
320         0x25, 0x01,         /*          Logical Maximum (1),        */
321         0x95, 0x03,         /*          Report Count (3),           */
322         0x81, 0x02,         /*          Input (Variable),           */
323         0x95, 0x05,         /*          Report Count (5),           */
324         0x81, 0x01,         /*          Input (Constant),           */
325         0x05, 0x01,         /*          Usage Page (Desktop),       */
326         0x75, 0x08,         /*          Report Size (8),            */
327         0x09, 0x30,         /*          Usage (X),                  */
328         0x09, 0x31,         /*          Usage (Y),                  */
329         0x15, 0x81,         /*          Logical Minimum (-127),     */
330         0x25, 0x7F,         /*          Logical Maximum (127),      */
331         0x95, 0x02,         /*          Report Count (2),           */
332         0x81, 0x06,         /*          Input (Variable, Relative), */
333         0x09, 0x38,         /*          Usage (Wheel),              */
334         0x15, 0xFF,         /*          Logical Minimum (-1),       */
335         0x25, 0x01,         /*          Logical Maximum (1),        */
336         0x95, 0x01,         /*          Report Count (1),           */
337         0x81, 0x06,         /*          Input (Variable, Relative), */
338         0x81, 0x01,         /*          Input (Constant),           */
339         0xC0,               /*      End Collection,                 */
340         0xC0                /*  End Collection                      */
341 };
342
343 const size_t uclogic_rdesc_pf1209_fixed_size =
344                         sizeof(uclogic_rdesc_pf1209_fixed_arr);
345
346 /* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */
347 __u8 uclogic_rdesc_twhl850_fixed0_arr[] = {
348         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
349         0x09, 0x01,         /*  Usage (Digitizer),                  */
350         0xA1, 0x01,         /*  Collection (Application),           */
351         0x85, 0x09,         /*      Report ID (9),                  */
352         0x09, 0x20,         /*      Usage (Stylus),                 */
353         0xA0,               /*      Collection (Physical),          */
354         0x14,               /*          Logical Minimum (0),        */
355         0x25, 0x01,         /*          Logical Maximum (1),        */
356         0x75, 0x01,         /*          Report Size (1),            */
357         0x95, 0x03,         /*          Report Count (3),           */
358         0x09, 0x42,         /*          Usage (Tip Switch),         */
359         0x09, 0x44,         /*          Usage (Barrel Switch),      */
360         0x09, 0x46,         /*          Usage (Tablet Pick),        */
361         0x81, 0x02,         /*          Input (Variable),           */
362         0x81, 0x03,         /*          Input (Constant, Variable), */
363         0x95, 0x01,         /*          Report Count (1),           */
364         0x09, 0x32,         /*          Usage (In Range),           */
365         0x81, 0x02,         /*          Input (Variable),           */
366         0x81, 0x03,         /*          Input (Constant, Variable), */
367         0x75, 0x10,         /*          Report Size (16),           */
368         0xA4,               /*          Push,                       */
369         0x05, 0x01,         /*          Usage Page (Desktop),       */
370         0x65, 0x13,         /*          Unit (Inch),                */
371         0x55, 0xFD,         /*          Unit Exponent (-3),         */
372         0x34,               /*          Physical Minimum (0),       */
373         0x09, 0x30,         /*          Usage (X),                  */
374         0x46, 0x40, 0x1F,   /*          Physical Maximum (8000),    */
375         0x26, 0x00, 0x7D,   /*          Logical Maximum (32000),    */
376         0x81, 0x02,         /*          Input (Variable),           */
377         0x09, 0x31,         /*          Usage (Y),                  */
378         0x46, 0x88, 0x13,   /*          Physical Maximum (5000),    */
379         0x26, 0x20, 0x4E,   /*          Logical Maximum (20000),    */
380         0x81, 0x02,         /*          Input (Variable),           */
381         0xB4,               /*          Pop,                        */
382         0x09, 0x30,         /*          Usage (Tip Pressure),       */
383         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
384         0x81, 0x02,         /*          Input (Variable),           */
385         0xC0,               /*      End Collection,                 */
386         0xC0                /*  End Collection                      */
387 };
388
389 const size_t uclogic_rdesc_twhl850_fixed0_size =
390                         sizeof(uclogic_rdesc_twhl850_fixed0_arr);
391
392 /* Fixed PID 0522 tablet report descriptor, interface 1 (mouse) */
393 __u8 uclogic_rdesc_twhl850_fixed1_arr[] = {
394         0x05, 0x01,         /*  Usage Page (Desktop),               */
395         0x09, 0x02,         /*  Usage (Mouse),                      */
396         0xA1, 0x01,         /*  Collection (Application),           */
397         0x85, 0x01,         /*      Report ID (1),                  */
398         0x09, 0x01,         /*      Usage (Pointer),                */
399         0xA0,               /*      Collection (Physical),          */
400         0x05, 0x09,         /*          Usage Page (Button),        */
401         0x75, 0x01,         /*          Report Size (1),            */
402         0x95, 0x03,         /*          Report Count (3),           */
403         0x19, 0x01,         /*          Usage Minimum (01h),        */
404         0x29, 0x03,         /*          Usage Maximum (03h),        */
405         0x14,               /*          Logical Minimum (0),        */
406         0x25, 0x01,         /*          Logical Maximum (1),        */
407         0x81, 0x02,         /*          Input (Variable),           */
408         0x95, 0x05,         /*          Report Count (5),           */
409         0x81, 0x03,         /*          Input (Constant, Variable), */
410         0x05, 0x01,         /*          Usage Page (Desktop),       */
411         0x09, 0x30,         /*          Usage (X),                  */
412         0x09, 0x31,         /*          Usage (Y),                  */
413         0x16, 0x00, 0x80,   /*          Logical Minimum (-32768),   */
414         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
415         0x75, 0x10,         /*          Report Size (16),           */
416         0x95, 0x02,         /*          Report Count (2),           */
417         0x81, 0x06,         /*          Input (Variable, Relative), */
418         0x09, 0x38,         /*          Usage (Wheel),              */
419         0x15, 0xFF,         /*          Logical Minimum (-1),       */
420         0x25, 0x01,         /*          Logical Maximum (1),        */
421         0x95, 0x01,         /*          Report Count (1),           */
422         0x75, 0x08,         /*          Report Size (8),            */
423         0x81, 0x06,         /*          Input (Variable, Relative), */
424         0x81, 0x03,         /*          Input (Constant, Variable), */
425         0xC0,               /*      End Collection,                 */
426         0xC0                /*  End Collection                      */
427 };
428
429 const size_t uclogic_rdesc_twhl850_fixed1_size =
430                         sizeof(uclogic_rdesc_twhl850_fixed1_arr);
431
432 /* Fixed PID 0522 tablet report descriptor, interface 2 (frame buttons) */
433 __u8 uclogic_rdesc_twhl850_fixed2_arr[] = {
434         0x05, 0x01,         /*  Usage Page (Desktop),               */
435         0x09, 0x06,         /*  Usage (Keyboard),                   */
436         0xA1, 0x01,         /*  Collection (Application),           */
437         0x85, 0x03,         /*      Report ID (3),                  */
438         0x05, 0x07,         /*      Usage Page (Keyboard),          */
439         0x14,               /*      Logical Minimum (0),            */
440         0x19, 0xE0,         /*      Usage Minimum (KB Leftcontrol), */
441         0x29, 0xE7,         /*      Usage Maximum (KB Right GUI),   */
442         0x25, 0x01,         /*      Logical Maximum (1),            */
443         0x75, 0x01,         /*      Report Size (1),                */
444         0x95, 0x08,         /*      Report Count (8),               */
445         0x81, 0x02,         /*      Input (Variable),               */
446         0x18,               /*      Usage Minimum (None),           */
447         0x29, 0xFF,         /*      Usage Maximum (FFh),            */
448         0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
449         0x75, 0x08,         /*      Report Size (8),                */
450         0x95, 0x06,         /*      Report Count (6),               */
451         0x80,               /*      Input,                          */
452         0xC0                /*  End Collection                      */
453 };
454
455 const size_t uclogic_rdesc_twhl850_fixed2_size =
456                         sizeof(uclogic_rdesc_twhl850_fixed2_arr);
457
458 /* Fixed TWHA60 report descriptor, interface 0 (stylus) */
459 __u8 uclogic_rdesc_twha60_fixed0_arr[] = {
460         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
461         0x09, 0x01,         /*  Usage (Digitizer),                  */
462         0xA1, 0x01,         /*  Collection (Application),           */
463         0x85, 0x09,         /*      Report ID (9),                  */
464         0x09, 0x20,         /*      Usage (Stylus),                 */
465         0xA0,               /*      Collection (Physical),          */
466         0x75, 0x01,         /*          Report Size (1),            */
467         0x09, 0x42,         /*          Usage (Tip Switch),         */
468         0x09, 0x44,         /*          Usage (Barrel Switch),      */
469         0x09, 0x46,         /*          Usage (Tablet Pick),        */
470         0x14,               /*          Logical Minimum (0),        */
471         0x25, 0x01,         /*          Logical Maximum (1),        */
472         0x95, 0x03,         /*          Report Count (3),           */
473         0x81, 0x02,         /*          Input (Variable),           */
474         0x95, 0x04,         /*          Report Count (4),           */
475         0x81, 0x01,         /*          Input (Constant),           */
476         0x09, 0x32,         /*          Usage (In Range),           */
477         0x95, 0x01,         /*          Report Count (1),           */
478         0x81, 0x02,         /*          Input (Variable),           */
479         0x75, 0x10,         /*          Report Size (16),           */
480         0x95, 0x01,         /*          Report Count (1),           */
481         0x14,               /*          Logical Minimum (0),        */
482         0xA4,               /*          Push,                       */
483         0x05, 0x01,         /*          Usage Page (Desktop),       */
484         0x55, 0xFD,         /*          Unit Exponent (-3),         */
485         0x65, 0x13,         /*          Unit (Inch),                */
486         0x34,               /*          Physical Minimum (0),       */
487         0x09, 0x30,         /*          Usage (X),                  */
488         0x46, 0x10, 0x27,   /*          Physical Maximum (10000),   */
489         0x27, 0x3F, 0x9C,
490                 0x00, 0x00, /*          Logical Maximum (39999),    */
491         0x81, 0x02,         /*          Input (Variable),           */
492         0x09, 0x31,         /*          Usage (Y),                  */
493         0x46, 0x6A, 0x18,   /*          Physical Maximum (6250),    */
494         0x26, 0xA7, 0x61,   /*          Logical Maximum (24999),    */
495         0x81, 0x02,         /*          Input (Variable),           */
496         0xB4,               /*          Pop,                        */
497         0x09, 0x30,         /*          Usage (Tip Pressure),       */
498         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
499         0x81, 0x02,         /*          Input (Variable),           */
500         0xC0,               /*      End Collection,                 */
501         0xC0                /*  End Collection                      */
502 };
503
504 const size_t uclogic_rdesc_twha60_fixed0_size =
505                         sizeof(uclogic_rdesc_twha60_fixed0_arr);
506
507 /* Fixed TWHA60 report descriptor, interface 1 (frame buttons) */
508 __u8 uclogic_rdesc_twha60_fixed1_arr[] = {
509         0x05, 0x01, /*  Usage Page (Desktop),       */
510         0x09, 0x06, /*  Usage (Keyboard),           */
511         0xA1, 0x01, /*  Collection (Application),   */
512         0x85, 0x05, /*      Report ID (5),          */
513         0x05, 0x07, /*      Usage Page (Keyboard),  */
514         0x14,       /*      Logical Minimum (0),    */
515         0x25, 0x01, /*      Logical Maximum (1),    */
516         0x75, 0x01, /*      Report Size (1),        */
517         0x95, 0x08, /*      Report Count (8),       */
518         0x81, 0x01, /*      Input (Constant),       */
519         0x95, 0x0C, /*      Report Count (12),      */
520         0x19, 0x3A, /*      Usage Minimum (KB F1),  */
521         0x29, 0x45, /*      Usage Maximum (KB F12), */
522         0x81, 0x02, /*      Input (Variable),       */
523         0x95, 0x0C, /*      Report Count (12),      */
524         0x19, 0x68, /*      Usage Minimum (KB F13), */
525         0x29, 0x73, /*      Usage Maximum (KB F24), */
526         0x81, 0x02, /*      Input (Variable),       */
527         0x95, 0x08, /*      Report Count (8),       */
528         0x81, 0x01, /*      Input (Constant),       */
529         0xC0        /*  End Collection              */
530 };
531
532 const size_t uclogic_rdesc_twha60_fixed1_size =
533                         sizeof(uclogic_rdesc_twha60_fixed1_arr);
534
535 /* Fixed report descriptor template for (tweaked) v1 pen reports */
536 const __u8 uclogic_rdesc_v1_pen_template_arr[] = {
537         0x05, 0x0D,             /*  Usage Page (Digitizer),                 */
538         0x09, 0x01,             /*  Usage (Digitizer),                      */
539         0xA1, 0x01,             /*  Collection (Application),               */
540         0x85, 0x07,             /*      Report ID (7),                      */
541         0x09, 0x20,             /*      Usage (Stylus),                     */
542         0xA0,                   /*      Collection (Physical),              */
543         0x14,                   /*          Logical Minimum (0),            */
544         0x25, 0x01,             /*          Logical Maximum (1),            */
545         0x75, 0x01,             /*          Report Size (1),                */
546         0x09, 0x42,             /*          Usage (Tip Switch),             */
547         0x09, 0x44,             /*          Usage (Barrel Switch),          */
548         0x09, 0x46,             /*          Usage (Tablet Pick),            */
549         0x95, 0x03,             /*          Report Count (3),               */
550         0x81, 0x02,             /*          Input (Variable),               */
551         0x95, 0x03,             /*          Report Count (3),               */
552         0x81, 0x03,             /*          Input (Constant, Variable),     */
553         0x09, 0x32,             /*          Usage (In Range),               */
554         0x95, 0x01,             /*          Report Count (1),               */
555         0x81, 0x02,             /*          Input (Variable),               */
556         0x95, 0x01,             /*          Report Count (1),               */
557         0x81, 0x03,             /*          Input (Constant, Variable),     */
558         0x75, 0x10,             /*          Report Size (16),               */
559         0x95, 0x01,             /*          Report Count (1),               */
560         0xA4,                   /*          Push,                           */
561         0x05, 0x01,             /*          Usage Page (Desktop),           */
562         0x65, 0x13,             /*          Unit (Inch),                    */
563         0x55, 0xFD,             /*          Unit Exponent (-3),             */
564         0x34,                   /*          Physical Minimum (0),           */
565         0x09, 0x30,             /*          Usage (X),                      */
566         0x27, UCLOGIC_RDESC_PEN_PH(X_LM),
567                                 /*          Logical Maximum (PLACEHOLDER),  */
568         0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
569                                 /*          Physical Maximum (PLACEHOLDER), */
570         0x81, 0x02,             /*          Input (Variable),               */
571         0x09, 0x31,             /*          Usage (Y),                      */
572         0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
573                                 /*          Logical Maximum (PLACEHOLDER),  */
574         0x47, UCLOGIC_RDESC_PEN_PH(Y_PM),
575                                 /*          Physical Maximum (PLACEHOLDER), */
576         0x81, 0x02,             /*          Input (Variable),               */
577         0xB4,                   /*          Pop,                            */
578         0x09, 0x30,             /*          Usage (Tip Pressure),           */
579         0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
580                                 /*          Logical Maximum (PLACEHOLDER),  */
581         0x81, 0x02,             /*          Input (Variable),               */
582         0xC0,                   /*      End Collection,                     */
583         0xC0                    /*  End Collection                          */
584 };
585
586 const size_t uclogic_rdesc_v1_pen_template_size =
587                         sizeof(uclogic_rdesc_v1_pen_template_arr);
588
589 /* Fixed report descriptor template for (tweaked) v2 pen reports */
590 const __u8 uclogic_rdesc_v2_pen_template_arr[] = {
591         0x05, 0x0D,             /*  Usage Page (Digitizer),                 */
592         0x09, 0x01,             /*  Usage (Digitizer),                      */
593         0xA1, 0x01,             /*  Collection (Application),               */
594         0x85, 0x08,             /*      Report ID (8),                      */
595         0x09, 0x20,             /*      Usage (Stylus),                     */
596         0xA0,                   /*      Collection (Physical),              */
597         0x14,                   /*          Logical Minimum (0),            */
598         0x25, 0x01,             /*          Logical Maximum (1),            */
599         0x75, 0x01,             /*          Report Size (1),                */
600         0x09, 0x42,             /*          Usage (Tip Switch),             */
601         0x09, 0x44,             /*          Usage (Barrel Switch),          */
602         0x09, 0x46,             /*          Usage (Tablet Pick),            */
603         0x95, 0x03,             /*          Report Count (3),               */
604         0x81, 0x02,             /*          Input (Variable),               */
605         0x95, 0x03,             /*          Report Count (3),               */
606         0x81, 0x03,             /*          Input (Constant, Variable),     */
607         0x09, 0x32,             /*          Usage (In Range),               */
608         0x95, 0x01,             /*          Report Count (1),               */
609         0x81, 0x02,             /*          Input (Variable),               */
610         0x95, 0x01,             /*          Report Count (1),               */
611         0x81, 0x03,             /*          Input (Constant, Variable),     */
612         0x95, 0x01,             /*          Report Count (1),               */
613         0xA4,                   /*          Push,                           */
614         0x05, 0x01,             /*          Usage Page (Desktop),           */
615         0x65, 0x13,             /*          Unit (Inch),                    */
616         0x55, 0xFD,             /*          Unit Exponent (-3),             */
617         0x75, 0x18,             /*          Report Size (24),               */
618         0x34,                   /*          Physical Minimum (0),           */
619         0x09, 0x30,             /*          Usage (X),                      */
620         0x27, UCLOGIC_RDESC_PEN_PH(X_LM),
621                                 /*          Logical Maximum (PLACEHOLDER),  */
622         0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
623                                 /*          Physical Maximum (PLACEHOLDER), */
624         0x81, 0x02,             /*          Input (Variable),               */
625         0x09, 0x31,             /*          Usage (Y),                      */
626         0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
627                                 /*          Logical Maximum (PLACEHOLDER),  */
628         0x47, UCLOGIC_RDESC_PEN_PH(Y_PM),
629                                 /*          Physical Maximum (PLACEHOLDER), */
630         0x81, 0x02,             /*          Input (Variable),               */
631         0xB4,                   /*          Pop,                            */
632         0x09, 0x30,             /*          Usage (Tip Pressure),           */
633         0x75, 0x10,             /*          Report Size (16),               */
634         0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
635                                 /*          Logical Maximum (PLACEHOLDER),  */
636         0x81, 0x02,             /*          Input (Variable),               */
637         0x54,                   /*          Unit Exponent (0),              */
638         0x65, 0x14,             /*          Unit (Degrees),                 */
639         0x35, 0xC4,             /*          Physical Minimum (-60),         */
640         0x45, 0x3C,             /*          Physical Maximum (60),          */
641         0x15, 0xC4,             /*          Logical Minimum (-60),          */
642         0x25, 0x3C,             /*          Logical Maximum (60),           */
643         0x75, 0x08,             /*          Report Size (8),                */
644         0x95, 0x02,             /*          Report Count (2),               */
645         0x09, 0x3D,             /*          Usage (X Tilt),                 */
646         0x09, 0x3E,             /*          Usage (Y Tilt),                 */
647         0x81, 0x02,             /*          Input (Variable),               */
648         0xC0,                   /*      End Collection,                     */
649         0xC0                    /*  End Collection                          */
650 };
651
652 const size_t uclogic_rdesc_v2_pen_template_size =
653                         sizeof(uclogic_rdesc_v2_pen_template_arr);
654
655 /*
656  * Expand to the contents of a generic frame buttons report descriptor.
657  *
658  * @_id:        The report ID to use.
659  * @_size:      Size of the report to pad to, including report ID, bytes.
660  */
661 #define UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(_id, _size) \
662         0x05, 0x01,     /*  Usage Page (Desktop),               */ \
663         0x09, 0x07,     /*  Usage (Keypad),                     */ \
664         0xA1, 0x01,     /*  Collection (Application),           */ \
665         0x85, (_id),    /*      Report ID (_id),                */ \
666         0x14,           /*      Logical Minimum (0),            */ \
667         0x25, 0x01,     /*      Logical Maximum (1),            */ \
668         0x75, 0x01,     /*      Report Size (1),                */ \
669         0x05, 0x0D,     /*      Usage Page (Digitizer),         */ \
670         0x09, 0x39,     /*      Usage (Tablet Function Keys),   */ \
671         0xA0,           /*      Collection (Physical),          */ \
672         0x09, 0x44,     /*          Usage (Barrel Switch),      */ \
673         0x95, 0x01,     /*          Report Count (1),           */ \
674         0x81, 0x02,     /*          Input (Variable),           */ \
675         0x05, 0x01,     /*          Usage Page (Desktop),       */ \
676         0x09, 0x30,     /*          Usage (X),                  */ \
677         0x09, 0x31,     /*          Usage (Y),                  */ \
678         0x95, 0x02,     /*          Report Count (2),           */ \
679         0x81, 0x02,     /*          Input (Variable),           */ \
680         0x95, 0x15,     /*          Report Count (21),          */ \
681         0x81, 0x01,     /*          Input (Constant),           */ \
682         0x05, 0x09,     /*          Usage Page (Button),        */ \
683         0x19, 0x01,     /*          Usage Minimum (01h),        */ \
684         0x29, 0x0A,     /*          Usage Maximum (0Ah),        */ \
685         0x95, 0x0A,     /*          Report Count (10),          */ \
686         0x81, 0x02,     /*          Input (Variable),           */ \
687         0xC0,           /*      End Collection,                 */ \
688         0x05, 0x01,     /*      Usage Page (Desktop),           */ \
689         0x09, 0x05,     /*      Usage (Gamepad),                */ \
690         0xA0,           /*      Collection (Physical),          */ \
691         0x05, 0x09,     /*          Usage Page (Button),        */ \
692         0x19, 0x01,     /*          Usage Minimum (01h),        */ \
693         0x29, 0x0A,     /*          Usage Maximum (0Ah),        */ \
694         0x95, 0x0A,     /*          Report Count (10),          */ \
695         0x81, 0x02,     /*          Input (Variable),           */ \
696         0x95, ((_size) * 8 - 52),                                  \
697                         /*          Report Count (padding),     */ \
698         0x81, 0x01,     /*          Input (Constant),           */ \
699         0xC0,           /*      End Collection,                 */ \
700         0xC0            /*  End Collection                      */
701
702 /* Fixed report descriptor for (tweaked) v1 frame reports */
703 const __u8 uclogic_rdesc_v1_frame_arr[] = {
704         UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8)
705 };
706 const size_t uclogic_rdesc_v1_frame_size =
707                         sizeof(uclogic_rdesc_v1_frame_arr);
708
709 /* Fixed report descriptor for (tweaked) v2 frame button reports */
710 const __u8 uclogic_rdesc_v2_frame_buttons_arr[] = {
711         UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID,
712                                           12)
713 };
714 const size_t uclogic_rdesc_v2_frame_buttons_size =
715                         sizeof(uclogic_rdesc_v2_frame_buttons_arr);
716
717 /* Fixed report descriptor for (tweaked) v2 frame touch ring reports */
718 const __u8 uclogic_rdesc_v2_frame_touch_ring_arr[] = {
719         0x05, 0x01,         /*  Usage Page (Desktop),               */
720         0x09, 0x07,         /*  Usage (Keypad),                     */
721         0xA1, 0x01,         /*  Collection (Application),           */
722         0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID,
723                             /*      Report ID (TOUCH_ID),           */
724         0x14,               /*      Logical Minimum (0),            */
725         0x05, 0x0D,         /*      Usage Page (Digitizer),         */
726         0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
727         0xA0,               /*      Collection (Physical),          */
728         0x25, 0x01,         /*          Logical Maximum (1),        */
729         0x75, 0x01,         /*          Report Size (1),            */
730         0x05, 0x09,         /*          Usage Page (Button),        */
731         0x09, 0x01,         /*          Usage (01h),                */
732         0x95, 0x01,         /*          Report Count (1),           */
733         0x81, 0x02,         /*          Input (Variable),           */
734         0x95, 0x07,         /*          Report Count (7),           */
735         0x81, 0x01,         /*          Input (Constant),           */
736         0x75, 0x08,         /*          Report Size (8),            */
737         0x95, 0x02,         /*          Report Count (2),           */
738         0x81, 0x01,         /*          Input (Constant),           */
739         0x05, 0x0D,         /*          Usage Page (Digitizer),     */
740         0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
741         0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
742         0x95, 0x01,         /*          Report Count (1),           */
743         0x81, 0x02,         /*          Input (Variable),           */
744         0x05, 0x01,         /*          Usage Page (Desktop),       */
745         0x09, 0x38,         /*          Usage (Wheel),              */
746         0x95, 0x01,         /*          Report Count (1),           */
747         0x15, 0x00,         /*          Logical Minimum (0),        */
748         0x25, 0x0B,         /*          Logical Maximum (11),       */
749         0x81, 0x02,         /*          Input (Variable),           */
750         0x09, 0x30,         /*          Usage (X),                  */
751         0x09, 0x31,         /*          Usage (Y),                  */
752         0x14,               /*          Logical Minimum (0),        */
753         0x25, 0x01,         /*          Logical Maximum (1),        */
754         0x75, 0x01,         /*          Report Size (1),            */
755         0x95, 0x02,         /*          Report Count (2),           */
756         0x81, 0x02,         /*          Input (Variable),           */
757         0x95, 0x2E,         /*          Report Count (46),          */
758         0x81, 0x01,         /*          Input (Constant),           */
759         0xC0,               /*      End Collection,                 */
760         0xC0                /*  End Collection                      */
761 };
762 const size_t uclogic_rdesc_v2_frame_touch_ring_size =
763                         sizeof(uclogic_rdesc_v2_frame_touch_ring_arr);
764
765 /* Fixed report descriptor for (tweaked) v2 frame touch strip reports */
766 const __u8 uclogic_rdesc_v2_frame_touch_strip_arr[] = {
767         0x05, 0x01,         /*  Usage Page (Desktop),               */
768         0x09, 0x07,         /*  Usage (Keypad),                     */
769         0xA1, 0x01,         /*  Collection (Application),           */
770         0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID,
771                             /*      Report ID (TOUCH_ID),           */
772         0x14,               /*      Logical Minimum (0),            */
773         0x05, 0x0D,         /*      Usage Page (Digitizer),         */
774         0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
775         0xA0,               /*      Collection (Physical),          */
776         0x25, 0x01,         /*          Logical Maximum (1),        */
777         0x75, 0x01,         /*          Report Size (1),            */
778         0x05, 0x09,         /*          Usage Page (Button),        */
779         0x09, 0x01,         /*          Usage (01h),                */
780         0x95, 0x01,         /*          Report Count (1),           */
781         0x81, 0x02,         /*          Input (Variable),           */
782         0x95, 0x07,         /*          Report Count (7),           */
783         0x81, 0x01,         /*          Input (Constant),           */
784         0x75, 0x08,         /*          Report Size (8),            */
785         0x95, 0x02,         /*          Report Count (2),           */
786         0x81, 0x01,         /*          Input (Constant),           */
787         0x05, 0x0D,         /*          Usage Page (Digitizer),     */
788         0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
789         0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
790         0x95, 0x01,         /*          Report Count (1),           */
791         0x81, 0x02,         /*          Input (Variable),           */
792         0x05, 0x01,         /*          Usage Page (Desktop),       */
793         0x09, 0x33,         /*          Usage (Rx),                 */
794         0x09, 0x34,         /*          Usage (Ry),                 */
795         0x95, 0x01,         /*          Report Count (1),           */
796         0x15, 0x00,         /*          Logical Minimum (0),        */
797         0x25, 0x07,         /*          Logical Maximum (7),        */
798         0x81, 0x02,         /*          Input (Variable),           */
799         0x09, 0x30,         /*          Usage (X),                  */
800         0x09, 0x31,         /*          Usage (Y),                  */
801         0x14,               /*          Logical Minimum (0),        */
802         0x25, 0x01,         /*          Logical Maximum (1),        */
803         0x75, 0x01,         /*          Report Size (1),            */
804         0x95, 0x02,         /*          Report Count (2),           */
805         0x81, 0x02,         /*          Input (Variable),           */
806         0x95, 0x2E,         /*          Report Count (46),          */
807         0x81, 0x01,         /*          Input (Constant),           */
808         0xC0,               /*      End Collection,                 */
809         0xC0                /*  End Collection                      */
810 };
811 const size_t uclogic_rdesc_v2_frame_touch_strip_size =
812                         sizeof(uclogic_rdesc_v2_frame_touch_strip_arr);
813
814 /* Fixed report descriptor for (tweaked) v2 frame dial reports */
815 const __u8 uclogic_rdesc_v2_frame_dial_arr[] = {
816         0x05, 0x01,         /*  Usage Page (Desktop),               */
817         0x09, 0x07,         /*  Usage (Keypad),                     */
818         0xA1, 0x01,         /*  Collection (Application),           */
819         0x85, UCLOGIC_RDESC_V2_FRAME_DIAL_ID,
820                             /*      Report ID (DIAL_ID),            */
821         0x14,               /*      Logical Minimum (0),            */
822         0x05, 0x0D,         /*      Usage Page (Digitizer),         */
823         0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
824         0xA0,               /*      Collection (Physical),          */
825         0x25, 0x01,         /*          Logical Maximum (1),        */
826         0x75, 0x01,         /*          Report Size (1),            */
827         0x95, 0x01,         /*          Report Count (1),           */
828         0x81, 0x01,         /*          Input (Constant),           */
829         0x05, 0x09,         /*          Usage Page (Button),        */
830         0x09, 0x01,         /*          Usage (01h),                */
831         0x95, 0x01,         /*          Report Count (1),           */
832         0x81, 0x02,         /*          Input (Variable),           */
833         0x95, 0x06,         /*          Report Count (6),           */
834         0x81, 0x01,         /*          Input (Constant),           */
835         0x75, 0x08,         /*          Report Size (8),            */
836         0x95, 0x02,         /*          Report Count (2),           */
837         0x81, 0x01,         /*          Input (Constant),           */
838         0x05, 0x0D,         /*          Usage Page (Digitizer),     */
839         0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
840         0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
841         0x95, 0x01,         /*          Report Count (1),           */
842         0x81, 0x02,         /*          Input (Variable),           */
843         0x05, 0x01,         /*          Usage Page (Desktop),       */
844         0x09, 0x38,         /*          Usage (Wheel),              */
845         0x95, 0x01,         /*          Report Count (1),           */
846         0x15, 0xFF,         /*          Logical Minimum (-1),       */
847         0x25, 0x01,         /*          Logical Maximum (1),        */
848         0x81, 0x06,         /*          Input (Variable, Relative), */
849         0x09, 0x30,         /*          Usage (X),                  */
850         0x09, 0x31,         /*          Usage (Y),                  */
851         0x14,               /*          Logical Minimum (0),        */
852         0x25, 0x01,         /*          Logical Maximum (1),        */
853         0x75, 0x01,         /*          Report Size (1),            */
854         0x95, 0x02,         /*          Report Count (2),           */
855         0x81, 0x02,         /*          Input (Variable),           */
856         0x95, 0x2E,         /*          Report Count (46),          */
857         0x81, 0x01,         /*          Input (Constant),           */
858         0xC0,               /*      End Collection,                 */
859         0xC0                /*  End Collection                      */
860 };
861 const size_t uclogic_rdesc_v2_frame_dial_size =
862                         sizeof(uclogic_rdesc_v2_frame_dial_arr);
863
864 const __u8 uclogic_ugee_v2_probe_arr[] = {
865         0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
866 };
867 const size_t uclogic_ugee_v2_probe_size = sizeof(uclogic_ugee_v2_probe_arr);
868 const int uclogic_ugee_v2_probe_endpoint = 0x03;
869
870 /* Fixed report descriptor template for UGEE v2 pen reports */
871 const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[] = {
872         0x05, 0x0d,         /*  Usage Page (Digitizers),                */
873         0x09, 0x01,         /*  Usage (Digitizer),                      */
874         0xa1, 0x01,         /*  Collection (Application),               */
875         0x85, 0x02,         /*      Report ID (2),                      */
876         0x09, 0x20,         /*      Usage (Stylus),                     */
877         0xa1, 0x00,         /*      Collection (Physical),              */
878         0x09, 0x42,         /*          Usage (Tip Switch),             */
879         0x09, 0x44,         /*          Usage (Barrel Switch),          */
880         0x09, 0x46,         /*          Usage (Tablet Pick),            */
881         0x75, 0x01,         /*          Report Size (1),                */
882         0x95, 0x03,         /*          Report Count (3),               */
883         0x14,               /*          Logical Minimum (0),            */
884         0x25, 0x01,         /*          Logical Maximum (1),            */
885         0x81, 0x02,         /*          Input (Variable),               */
886         0x95, 0x02,         /*          Report Count (2),               */
887         0x81, 0x03,         /*          Input (Constant, Variable),     */
888         0x09, 0x32,         /*          Usage (In Range),               */
889         0x95, 0x01,         /*          Report Count (1),               */
890         0x81, 0x02,         /*          Input (Variable),               */
891         0x95, 0x02,         /*          Report Count (2),               */
892         0x81, 0x03,         /*          Input (Constant, Variable),     */
893         0x75, 0x10,         /*          Report Size (16),               */
894         0x95, 0x01,         /*          Report Count (1),               */
895         0x35, 0x00,         /*          Physical Minimum (0),           */
896         0xa4,               /*          Push,                           */
897         0x05, 0x01,         /*          Usage Page (Desktop),           */
898         0x09, 0x30,         /*          Usage (X),                      */
899         0x65, 0x13,         /*          Unit (Inch),                    */
900         0x55, 0x0d,         /*          Unit Exponent (-3),             */
901         0x27, UCLOGIC_RDESC_PEN_PH(X_LM),
902                             /*          Logical Maximum (PLACEHOLDER),  */
903         0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
904                             /*          Physical Maximum (PLACEHOLDER), */
905         0x81, 0x02,         /*          Input (Variable),               */
906         0x09, 0x31,         /*          Usage (Y),                      */
907         0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
908                             /*          Logical Maximum (PLACEHOLDER),  */
909         0x47, UCLOGIC_RDESC_PEN_PH(Y_PM),
910                             /*          Physical Maximum (PLACEHOLDER), */
911         0x81, 0x02,         /*          Input (Variable),               */
912         0xb4,               /*          Pop,                            */
913         0x09, 0x30,         /*          Usage (Tip Pressure),           */
914         0x45, 0x00,         /*          Physical Maximum (0),           */
915         0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
916                             /*          Logical Maximum (PLACEHOLDER),  */
917         0x75, 0x0D,         /*          Report Size (13),               */
918         0x95, 0x01,         /*          Report Count (1),               */
919         0x81, 0x02,         /*          Input (Variable),               */
920         0x75, 0x01,         /*          Report Size (1),                */
921         0x95, 0x03,         /*          Report Count (3),               */
922         0x81, 0x01,         /*          Input (Constant),               */
923         0x09, 0x3d,         /*          Usage (X Tilt),                 */
924         0x35, 0xC3,         /*          Physical Minimum (-61),         */
925         0x45, 0x3C,         /*          Physical Maximum (60),          */
926         0x15, 0xC3,         /*          Logical Minimum (-61),          */
927         0x25, 0x3C,         /*          Logical Maximum (60),           */
928         0x75, 0x08,         /*          Report Size (8),                */
929         0x95, 0x01,         /*          Report Count (1),               */
930         0x81, 0x02,         /*          Input (Variable),               */
931         0x09, 0x3e,         /*          Usage (Y Tilt),                 */
932         0x35, 0xC3,         /*          Physical Minimum (-61),         */
933         0x45, 0x3C,         /*          Physical Maximum (60),          */
934         0x15, 0xC3,         /*          Logical Minimum (-61),          */
935         0x25, 0x3C,         /*          Logical Maximum (60),           */
936         0x81, 0x02,         /*          Input (Variable),               */
937         0xc0,               /*      End Collection,                     */
938         0xc0,               /*  End Collection                          */
939 };
940 const size_t uclogic_rdesc_ugee_v2_pen_template_size =
941                         sizeof(uclogic_rdesc_ugee_v2_pen_template_arr);
942
943 /* Fixed report descriptor template for UGEE v2 frame reports (buttons only) */
944 const __u8 uclogic_rdesc_ugee_v2_frame_btn_template_arr[] = {
945         0x05, 0x01,         /*  Usage Page (Desktop),                   */
946         0x09, 0x07,         /*  Usage (Keypad),                         */
947         0xA1, 0x01,         /*  Collection (Application),               */
948         0x85, UCLOGIC_RDESC_V1_FRAME_ID,
949                             /*      Report ID,                          */
950         0x05, 0x0D,         /*      Usage Page (Digitizer),             */
951         0x09, 0x39,         /*      Usage (Tablet Function Keys),       */
952         0xA0,               /*      Collection (Physical),              */
953         0x75, 0x01,         /*          Report Size (1),                */
954         0x95, 0x08,         /*          Report Count (8),               */
955         0x81, 0x01,         /*          Input (Constant),               */
956         0x05, 0x09,         /*          Usage Page (Button),            */
957         0x19, 0x01,         /*          Usage Minimum (01h),            */
958         UCLOGIC_RDESC_FRAME_PH_BTN,
959                             /*          Usage Maximum (PLACEHOLDER),    */
960         0x95, 0x0A,         /*          Report Count (10),              */
961         0x14,               /*          Logical Minimum (0),            */
962         0x25, 0x01,         /*          Logical Maximum (1),            */
963         0x81, 0x02,         /*          Input (Variable),               */
964         0x95, 0x46,         /*          Report Count (70),              */
965         0x81, 0x01,         /*          Input (Constant),               */
966         0xC0,               /*      End Collection,                     */
967         0xC0                /*  End Collection                          */
968 };
969 const size_t uclogic_rdesc_ugee_v2_frame_btn_template_size =
970                         sizeof(uclogic_rdesc_ugee_v2_frame_btn_template_arr);
971
972 /* Fixed report descriptor template for UGEE v2 frame reports (dial) */
973 const __u8 uclogic_rdesc_ugee_v2_frame_dial_template_arr[] = {
974         0x05, 0x01,         /*  Usage Page (Desktop),                   */
975         0x09, 0x07,         /*  Usage (Keypad),                         */
976         0xA1, 0x01,         /*  Collection (Application),               */
977         0x85, UCLOGIC_RDESC_V1_FRAME_ID,
978                             /*      Report ID,                          */
979         0x05, 0x0D,         /*      Usage Page (Digitizer),             */
980         0x09, 0x39,         /*      Usage (Tablet Function Keys),       */
981         0xA0,               /*      Collection (Physical),              */
982         0x75, 0x01,         /*          Report Size (1),                */
983         0x95, 0x08,         /*          Report Count (8),               */
984         0x81, 0x01,         /*          Input (Constant),               */
985         0x05, 0x09,         /*          Usage Page (Button),            */
986         0x19, 0x01,         /*          Usage Minimum (01h),            */
987         UCLOGIC_RDESC_FRAME_PH_BTN,
988                             /*          Usage Maximum (PLACEHOLDER),    */
989         0x95, 0x0A,         /*          Report Count (10),              */
990         0x14,               /*          Logical Minimum (0),            */
991         0x25, 0x01,         /*          Logical Maximum (1),            */
992         0x81, 0x02,         /*          Input (Variable),               */
993         0x95, 0x06,         /*          Report Count (6),               */
994         0x81, 0x01,         /*          Input (Constant),               */
995         0x75, 0x08,         /*          Report Size (8),                */
996         0x95, 0x03,         /*          Report Count (3),               */
997         0x81, 0x01,         /*          Input (Constant),               */
998         0x05, 0x01,         /*          Usage Page (Desktop),           */
999         0x09, 0x38,         /*          Usage (Wheel),                  */
1000         0x95, 0x01,         /*          Report Count (1),               */
1001         0x15, 0xFF,         /*          Logical Minimum (-1),           */
1002         0x25, 0x01,         /*          Logical Maximum (1),            */
1003         0x81, 0x06,         /*          Input (Variable, Relative),     */
1004         0x95, 0x02,         /*          Report Count (2),               */
1005         0x81, 0x01,         /*          Input (Constant),               */
1006         0xC0,               /*      End Collection,                     */
1007         0xC0                /*  End Collection                          */
1008 };
1009 const size_t uclogic_rdesc_ugee_v2_frame_dial_template_size =
1010                         sizeof(uclogic_rdesc_ugee_v2_frame_dial_template_arr);
1011
1012 /* Fixed report descriptor template for UGEE v2 frame reports (mouse) */
1013 const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[] = {
1014         0x05, 0x01,         /*  Usage Page (Desktop),                   */
1015         0x09, 0x02,         /*  Usage (Mouse),                          */
1016         0xA1, 0x01,         /*  Collection (Application),               */
1017         0x85, 0x01,         /*      Report ID (1),                      */
1018         0x05, 0x01,         /*      Usage Page (Pointer),               */
1019         0xA0,               /*      Collection (Physical),              */
1020         0x75, 0x01,         /*          Report Size (1),                */
1021         0x95, 0x02,         /*          Report Count (2),               */
1022         0x05, 0x09,         /*          Usage Page (Button),            */
1023         0x19, 0x01,         /*          Usage Minimum (01h),            */
1024         0x29, 0x02,         /*          Usage Maximum (02h),            */
1025         0x14,               /*          Logical Minimum (0),            */
1026         0x25, 0x01,         /*          Logical Maximum (1),            */
1027         0x81, 0x02,         /*          Input (Variable),               */
1028         0x95, 0x06,         /*          Report Count (6),               */
1029         0x81, 0x01,         /*          Input (Constant),               */
1030         0x05, 0x01,         /*          Usage Page (Generic Desktop),   */
1031         0x09, 0x30,         /*          Usage (X),                      */
1032         0x09, 0x31,         /*          Usage (Y),                      */
1033         0x75, 0x10,         /*          Report Size (16),               */
1034         0x95, 0x02,         /*          Report Count (2),               */
1035         0x16, 0x00, 0x80,   /*          Logical Minimum (-32768),       */
1036         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),        */
1037         0x81, 0x06,         /*          Input (Variable, Relative),     */
1038         0x95, 0x01,         /*          Report Count (1),               */
1039         0x81, 0x01,         /*          Input (Constant),               */
1040         0xC0,               /*      End Collection,                     */
1041         0xC0                /*  End Collection                          */
1042 };
1043 const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size =
1044                         sizeof(uclogic_rdesc_ugee_v2_frame_mouse_template_arr);
1045
1046 /* Fixed report descriptor template for UGEE v2 battery reports */
1047 const __u8 uclogic_rdesc_ugee_v2_battery_template_arr[] = {
1048         0x05, 0x01,         /*  Usage Page (Desktop),                   */
1049         0x09, 0x07,         /*  Usage (Keypad),                         */
1050         0xA1, 0x01,         /*  Collection (Application),               */
1051         0x85, UCLOGIC_RDESC_UGEE_V2_BATTERY_ID,
1052                             /*      Report ID,                          */
1053         0x75, 0x08,         /*      Report Size (8),                    */
1054         0x95, 0x02,         /*      Report Count (2),                   */
1055         0x81, 0x01,         /*      Input (Constant),                   */
1056         0x05, 0x84,         /*      Usage Page (Power Device),          */
1057         0x05, 0x85,         /*      Usage Page (Battery System),        */
1058         0x09, 0x65,         /*      Usage Page (AbsoluteStateOfCharge), */
1059         0x75, 0x08,         /*      Report Size (8),                    */
1060         0x95, 0x01,         /*      Report Count (1),                   */
1061         0x15, 0x00,         /*      Logical Minimum (0),                */
1062         0x26, 0xff, 0x00,   /*      Logical Maximum (255),              */
1063         0x81, 0x02,         /*      Input (Variable),                   */
1064         0x75, 0x01,         /*      Report Size (1),                    */
1065         0x95, 0x01,         /*      Report Count (1),                   */
1066         0x15, 0x00,         /*      Logical Minimum (0),                */
1067         0x25, 0x01,         /*      Logical Maximum (1),                */
1068         0x09, 0x44,         /*      Usage Page (Charging),              */
1069         0x81, 0x02,         /*      Input (Variable),                   */
1070         0x95, 0x07,         /*      Report Count (7),                   */
1071         0x81, 0x01,         /*      Input (Constant),                   */
1072         0x75, 0x08,         /*      Report Size (8),                    */
1073         0x95, 0x07,         /*      Report Count (7),                   */
1074         0x81, 0x01,         /*      Input (Constant),                   */
1075         0xC0                /*  End Collection                          */
1076 };
1077 const size_t uclogic_rdesc_ugee_v2_battery_template_size =
1078                         sizeof(uclogic_rdesc_ugee_v2_battery_template_arr);
1079
1080 /* Fixed report descriptor for Ugee EX07 frame */
1081 const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
1082         0x05, 0x01,             /*  Usage Page (Desktop),                   */
1083         0x09, 0x07,             /*  Usage (Keypad),                         */
1084         0xA1, 0x01,             /*  Collection (Application),               */
1085         0x85, 0x06,             /*      Report ID (6),                      */
1086         0x05, 0x0D,             /*      Usage Page (Digitizer),             */
1087         0x09, 0x39,             /*      Usage (Tablet Function Keys),       */
1088         0xA0,                   /*      Collection (Physical),              */
1089         0x05, 0x09,             /*          Usage Page (Button),            */
1090         0x75, 0x01,             /*          Report Size (1),                */
1091         0x19, 0x03,             /*          Usage Minimum (03h),            */
1092         0x29, 0x06,             /*          Usage Maximum (06h),            */
1093         0x95, 0x04,             /*          Report Count (4),               */
1094         0x81, 0x02,             /*          Input (Variable),               */
1095         0x95, 0x1A,             /*          Report Count (26),              */
1096         0x81, 0x03,             /*          Input (Constant, Variable),     */
1097         0x19, 0x01,             /*          Usage Minimum (01h),            */
1098         0x29, 0x02,             /*          Usage Maximum (02h),            */
1099         0x95, 0x02,             /*          Report Count (2),               */
1100         0x81, 0x02,             /*          Input (Variable),               */
1101         0xC0,                   /*      End Collection,                     */
1102         0xC0                    /*  End Collection                          */
1103 };
1104 const size_t uclogic_rdesc_ugee_ex07_frame_size =
1105                         sizeof(uclogic_rdesc_ugee_ex07_frame_arr);
1106
1107 /* Fixed report descriptor for Ugee G5 frame controls */
1108 const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = {
1109         0x05, 0x01,         /*  Usage Page (Desktop),               */
1110         0x09, 0x07,         /*  Usage (Keypad),                     */
1111         0xA1, 0x01,         /*  Collection (Application),           */
1112         0x85, 0x06,         /*      Report ID (6),                  */
1113         0x05, 0x0D,         /*      Usage Page (Digitizer),         */
1114         0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
1115         0xA0,               /*      Collection (Physical),          */
1116         0x14,               /*          Logical Minimum (0),        */
1117         0x25, 0x01,         /*          Logical Maximum (1),        */
1118         0x05, 0x01,         /*          Usage Page (Desktop),       */
1119         0x05, 0x09,         /*          Usage Page (Button),        */
1120         0x19, 0x01,         /*          Usage Minimum (01h),        */
1121         0x29, 0x05,         /*          Usage Maximum (05h),        */
1122         0x75, 0x01,         /*          Report Size (1),            */
1123         0x95, 0x05,         /*          Report Count (5),           */
1124         0x81, 0x02,         /*          Input (Variable),           */
1125         0x75, 0x01,         /*          Report Size (1),            */
1126         0x95, 0x03,         /*          Report Count (3),           */
1127         0x81, 0x01,         /*          Input (Constant),           */
1128         0x05, 0x0D,         /*          Usage Page (Digitizer),     */
1129         0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
1130         0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
1131         0x75, 0x08,         /*          Report Size (8),            */
1132         0x95, 0x01,         /*          Report Count (1),           */
1133         0x81, 0x02,         /*          Input (Variable),           */
1134         0x25, 0x01,         /*          Logical Maximum (1),        */
1135         0x09, 0x44,         /*          Usage (Barrel Switch),      */
1136         0x75, 0x01,         /*          Report Size (1),            */
1137         0x95, 0x01,         /*          Report Count (1),           */
1138         0x81, 0x02,         /*          Input (Variable),           */
1139         0x05, 0x01,         /*          Usage Page (Desktop),       */
1140         0x09, 0x30,         /*          Usage (X),                  */
1141         0x09, 0x31,         /*          Usage (Y),                  */
1142         0x75, 0x01,         /*          Report Size (1),            */
1143         0x95, 0x02,         /*          Report Count (2),           */
1144         0x81, 0x02,         /*          Input (Variable),           */
1145         0x75, 0x01,         /*          Report Size (1),            */
1146         0x95, 0x0B,         /*          Report Count (11),          */
1147         0x81, 0x01,         /*          Input (Constant),           */
1148         0x05, 0x01,         /*          Usage Page (Desktop),       */
1149         0x09, 0x38,         /*          Usage (Wheel),              */
1150         0x15, 0xFF,         /*          Logical Minimum (-1),       */
1151         0x25, 0x01,         /*          Logical Maximum (1),        */
1152         0x75, 0x02,         /*          Report Size (2),            */
1153         0x95, 0x01,         /*          Report Count (1),           */
1154         0x81, 0x06,         /*          Input (Variable, Relative), */
1155         0xC0,               /*      End Collection,                 */
1156         0xC0                /*  End Collection                      */
1157 };
1158 const size_t uclogic_rdesc_ugee_g5_frame_size =
1159                         sizeof(uclogic_rdesc_ugee_g5_frame_arr);
1160
1161 /* Fixed report descriptor for XP-Pen Deco 01 frame controls */
1162 const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = {
1163         0x05, 0x01, /*  Usage Page (Desktop),               */
1164         0x09, 0x07, /*  Usage (Keypad),                     */
1165         0xA1, 0x01, /*  Collection (Application),           */
1166         0x85, 0x06, /*      Report ID (6),                  */
1167         0x14,       /*      Logical Minimum (0),            */
1168         0x25, 0x01, /*      Logical Maximum (1),            */
1169         0x75, 0x01, /*      Report Size (1),                */
1170         0x05, 0x0D, /*      Usage Page (Digitizer),         */
1171         0x09, 0x39, /*      Usage (Tablet Function Keys),   */
1172         0xA0,       /*      Collection (Physical),          */
1173         0x05, 0x09, /*          Usage Page (Button),        */
1174         0x19, 0x01, /*          Usage Minimum (01h),        */
1175         0x29, 0x08, /*          Usage Maximum (08h),        */
1176         0x95, 0x08, /*          Report Count (8),           */
1177         0x81, 0x02, /*          Input (Variable),           */
1178         0x05, 0x0D, /*          Usage Page (Digitizer),     */
1179         0x09, 0x44, /*          Usage (Barrel Switch),      */
1180         0x95, 0x01, /*          Report Count (1),           */
1181         0x81, 0x02, /*          Input (Variable),           */
1182         0x05, 0x01, /*          Usage Page (Desktop),       */
1183         0x09, 0x30, /*          Usage (X),                  */
1184         0x09, 0x31, /*          Usage (Y),                  */
1185         0x95, 0x02, /*          Report Count (2),           */
1186         0x81, 0x02, /*          Input (Variable),           */
1187         0x95, 0x15, /*          Report Count (21),          */
1188         0x81, 0x01, /*          Input (Constant),           */
1189         0xC0,       /*      End Collection,                 */
1190         0xC0        /*  End Collection                      */
1191 };
1192
1193 const size_t uclogic_rdesc_xppen_deco01_frame_size =
1194                         sizeof(uclogic_rdesc_xppen_deco01_frame_arr);
1195
1196 /**
1197  * uclogic_rdesc_template_apply() - apply report descriptor parameters to a
1198  * report descriptor template, creating a report descriptor. Copies the
1199  * template over to the new report descriptor and replaces every occurrence of
1200  * the template placeholders, followed by an index byte, with the value from the
1201  * parameter list at that index.
1202  *
1203  * @template_ptr:       Pointer to the template buffer.
1204  * @template_size:      Size of the template buffer.
1205  * @param_list:         List of template parameters.
1206  * @param_num:          Number of parameters in the list.
1207  *
1208  * Returns:
1209  *      Kmalloc-allocated pointer to the created report descriptor,
1210  *      or NULL if allocation failed.
1211  */
1212 __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
1213                                    size_t template_size,
1214                                    const s32 *param_list,
1215                                    size_t param_num)
1216 {
1217         static const __u8 btn_head[] = {UCLOGIC_RDESC_FRAME_PH_BTN_HEAD};
1218         static const __u8 pen_head[] = {UCLOGIC_RDESC_PEN_PH_HEAD};
1219         __u8 *rdesc_ptr;
1220         __u8 *p;
1221         s32 v;
1222
1223         rdesc_ptr = kmemdup(template_ptr, template_size, GFP_KERNEL);
1224         if (rdesc_ptr == NULL)
1225                 return NULL;
1226
1227         for (p = rdesc_ptr; p + sizeof(btn_head) < rdesc_ptr + template_size;) {
1228                 if (p + sizeof(pen_head) < rdesc_ptr + template_size &&
1229                     memcmp(p, pen_head, sizeof(pen_head)) == 0 &&
1230                     p[sizeof(pen_head)] < param_num) {
1231                         v = param_list[p[sizeof(pen_head)]];
1232                         put_unaligned((__force u32)cpu_to_le32(v), (s32 *)p);
1233                         p += sizeof(pen_head) + 1;
1234                 } else if (memcmp(p, btn_head, sizeof(btn_head)) == 0 &&
1235                            p[sizeof(btn_head)] < param_num) {
1236                         v = param_list[p[sizeof(btn_head)]];
1237                         put_unaligned((__u8)0x2A, p); /* Usage Maximum */
1238                         put_unaligned((__force u16)cpu_to_le16(v), (s16 *)(p + 1));
1239                         p += sizeof(btn_head) + 1;
1240                 } else {
1241                         p++;
1242                 }
1243         }
1244
1245         return rdesc_ptr;
1246 }
1247 EXPORT_SYMBOL_IF_KUNIT(uclogic_rdesc_template_apply);
This page took 0.108643 seconds and 4 git commands to generate.