Merge branch 'for-5.19/uclogic' into for-linus
[sfrench/cifs-2.6.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
21 /* Fixed WP4030U report descriptor */
22 __u8 uclogic_rdesc_wp4030u_fixed_arr[] = {
23         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
24         0x09, 0x01,         /*  Usage (Digitizer),                  */
25         0xA1, 0x01,         /*  Collection (Application),           */
26         0x85, 0x09,         /*      Report ID (9),                  */
27         0x09, 0x20,         /*      Usage (Stylus),                 */
28         0xA0,               /*      Collection (Physical),          */
29         0x75, 0x01,         /*          Report Size (1),            */
30         0x09, 0x42,         /*          Usage (Tip Switch),         */
31         0x09, 0x44,         /*          Usage (Barrel Switch),      */
32         0x09, 0x46,         /*          Usage (Tablet Pick),        */
33         0x14,               /*          Logical Minimum (0),        */
34         0x25, 0x01,         /*          Logical Maximum (1),        */
35         0x95, 0x03,         /*          Report Count (3),           */
36         0x81, 0x02,         /*          Input (Variable),           */
37         0x95, 0x05,         /*          Report Count (5),           */
38         0x81, 0x01,         /*          Input (Constant),           */
39         0x75, 0x10,         /*          Report Size (16),           */
40         0x95, 0x01,         /*          Report Count (1),           */
41         0x14,               /*          Logical Minimum (0),        */
42         0xA4,               /*          Push,                       */
43         0x05, 0x01,         /*          Usage Page (Desktop),       */
44         0x55, 0xFD,         /*          Unit Exponent (-3),         */
45         0x65, 0x13,         /*          Unit (Inch),                */
46         0x34,               /*          Physical Minimum (0),       */
47         0x09, 0x30,         /*          Usage (X),                  */
48         0x46, 0xA0, 0x0F,   /*          Physical Maximum (4000),    */
49         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
50         0x81, 0x02,         /*          Input (Variable),           */
51         0x09, 0x31,         /*          Usage (Y),                  */
52         0x46, 0xB8, 0x0B,   /*          Physical Maximum (3000),    */
53         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
54         0x81, 0x02,         /*          Input (Variable),           */
55         0xB4,               /*          Pop,                        */
56         0x09, 0x30,         /*          Usage (Tip Pressure),       */
57         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
58         0x81, 0x02,         /*          Input (Variable),           */
59         0xC0,               /*      End Collection,                 */
60         0xC0                /*  End Collection                      */
61 };
62
63 const size_t uclogic_rdesc_wp4030u_fixed_size =
64                         sizeof(uclogic_rdesc_wp4030u_fixed_arr);
65
66 /* Fixed WP5540U report descriptor */
67 __u8 uclogic_rdesc_wp5540u_fixed_arr[] = {
68         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
69         0x09, 0x01,         /*  Usage (Digitizer),                  */
70         0xA1, 0x01,         /*  Collection (Application),           */
71         0x85, 0x09,         /*      Report ID (9),                  */
72         0x09, 0x20,         /*      Usage (Stylus),                 */
73         0xA0,               /*      Collection (Physical),          */
74         0x75, 0x01,         /*          Report Size (1),            */
75         0x09, 0x42,         /*          Usage (Tip Switch),         */
76         0x09, 0x44,         /*          Usage (Barrel Switch),      */
77         0x09, 0x46,         /*          Usage (Tablet Pick),        */
78         0x14,               /*          Logical Minimum (0),        */
79         0x25, 0x01,         /*          Logical Maximum (1),        */
80         0x95, 0x03,         /*          Report Count (3),           */
81         0x81, 0x02,         /*          Input (Variable),           */
82         0x95, 0x05,         /*          Report Count (5),           */
83         0x81, 0x01,         /*          Input (Constant),           */
84         0x75, 0x10,         /*          Report Size (16),           */
85         0x95, 0x01,         /*          Report Count (1),           */
86         0x14,               /*          Logical Minimum (0),        */
87         0xA4,               /*          Push,                       */
88         0x05, 0x01,         /*          Usage Page (Desktop),       */
89         0x55, 0xFD,         /*          Unit Exponent (-3),         */
90         0x65, 0x13,         /*          Unit (Inch),                */
91         0x34,               /*          Physical Minimum (0),       */
92         0x09, 0x30,         /*          Usage (X),                  */
93         0x46, 0x7C, 0x15,   /*          Physical Maximum (5500),    */
94         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
95         0x81, 0x02,         /*          Input (Variable),           */
96         0x09, 0x31,         /*          Usage (Y),                  */
97         0x46, 0xA0, 0x0F,   /*          Physical Maximum (4000),    */
98         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
99         0x81, 0x02,         /*          Input (Variable),           */
100         0xB4,               /*          Pop,                        */
101         0x09, 0x30,         /*          Usage (Tip Pressure),       */
102         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
103         0x81, 0x02,         /*          Input (Variable),           */
104         0xC0,               /*      End Collection,                 */
105         0xC0,               /*  End Collection,                     */
106         0x05, 0x01,         /*  Usage Page (Desktop),               */
107         0x09, 0x02,         /*  Usage (Mouse),                      */
108         0xA1, 0x01,         /*  Collection (Application),           */
109         0x85, 0x08,         /*      Report ID (8),                  */
110         0x09, 0x01,         /*      Usage (Pointer),                */
111         0xA0,               /*      Collection (Physical),          */
112         0x75, 0x01,         /*          Report Size (1),            */
113         0x05, 0x09,         /*          Usage Page (Button),        */
114         0x19, 0x01,         /*          Usage Minimum (01h),        */
115         0x29, 0x03,         /*          Usage Maximum (03h),        */
116         0x14,               /*          Logical Minimum (0),        */
117         0x25, 0x01,         /*          Logical Maximum (1),        */
118         0x95, 0x03,         /*          Report Count (3),           */
119         0x81, 0x02,         /*          Input (Variable),           */
120         0x95, 0x05,         /*          Report Count (5),           */
121         0x81, 0x01,         /*          Input (Constant),           */
122         0x05, 0x01,         /*          Usage Page (Desktop),       */
123         0x75, 0x08,         /*          Report Size (8),            */
124         0x09, 0x30,         /*          Usage (X),                  */
125         0x09, 0x31,         /*          Usage (Y),                  */
126         0x15, 0x81,         /*          Logical Minimum (-127),     */
127         0x25, 0x7F,         /*          Logical Maximum (127),      */
128         0x95, 0x02,         /*          Report Count (2),           */
129         0x81, 0x06,         /*          Input (Variable, Relative), */
130         0x09, 0x38,         /*          Usage (Wheel),              */
131         0x15, 0xFF,         /*          Logical Minimum (-1),       */
132         0x25, 0x01,         /*          Logical Maximum (1),        */
133         0x95, 0x01,         /*          Report Count (1),           */
134         0x81, 0x06,         /*          Input (Variable, Relative), */
135         0x81, 0x01,         /*          Input (Constant),           */
136         0xC0,               /*      End Collection,                 */
137         0xC0                /*  End Collection                      */
138 };
139
140 const size_t uclogic_rdesc_wp5540u_fixed_size =
141                         sizeof(uclogic_rdesc_wp5540u_fixed_arr);
142
143 /* Fixed WP8060U report descriptor */
144 __u8 uclogic_rdesc_wp8060u_fixed_arr[] = {
145         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
146         0x09, 0x01,         /*  Usage (Digitizer),                  */
147         0xA1, 0x01,         /*  Collection (Application),           */
148         0x85, 0x09,         /*      Report ID (9),                  */
149         0x09, 0x20,         /*      Usage (Stylus),                 */
150         0xA0,               /*      Collection (Physical),          */
151         0x75, 0x01,         /*          Report Size (1),            */
152         0x09, 0x42,         /*          Usage (Tip Switch),         */
153         0x09, 0x44,         /*          Usage (Barrel Switch),      */
154         0x09, 0x46,         /*          Usage (Tablet Pick),        */
155         0x14,               /*          Logical Minimum (0),        */
156         0x25, 0x01,         /*          Logical Maximum (1),        */
157         0x95, 0x03,         /*          Report Count (3),           */
158         0x81, 0x02,         /*          Input (Variable),           */
159         0x95, 0x05,         /*          Report Count (5),           */
160         0x81, 0x01,         /*          Input (Constant),           */
161         0x75, 0x10,         /*          Report Size (16),           */
162         0x95, 0x01,         /*          Report Count (1),           */
163         0x14,               /*          Logical Minimum (0),        */
164         0xA4,               /*          Push,                       */
165         0x05, 0x01,         /*          Usage Page (Desktop),       */
166         0x55, 0xFD,         /*          Unit Exponent (-3),         */
167         0x65, 0x13,         /*          Unit (Inch),                */
168         0x34,               /*          Physical Minimum (0),       */
169         0x09, 0x30,         /*          Usage (X),                  */
170         0x46, 0x40, 0x1F,   /*          Physical Maximum (8000),    */
171         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
172         0x81, 0x02,         /*          Input (Variable),           */
173         0x09, 0x31,         /*          Usage (Y),                  */
174         0x46, 0x70, 0x17,   /*          Physical Maximum (6000),    */
175         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
176         0x81, 0x02,         /*          Input (Variable),           */
177         0xB4,               /*          Pop,                        */
178         0x09, 0x30,         /*          Usage (Tip Pressure),       */
179         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
180         0x81, 0x02,         /*          Input (Variable),           */
181         0xC0,               /*      End Collection,                 */
182         0xC0,               /*  End Collection,                     */
183         0x05, 0x01,         /*  Usage Page (Desktop),               */
184         0x09, 0x02,         /*  Usage (Mouse),                      */
185         0xA1, 0x01,         /*  Collection (Application),           */
186         0x85, 0x08,         /*      Report ID (8),                  */
187         0x09, 0x01,         /*      Usage (Pointer),                */
188         0xA0,               /*      Collection (Physical),          */
189         0x75, 0x01,         /*          Report Size (1),            */
190         0x05, 0x09,         /*          Usage Page (Button),        */
191         0x19, 0x01,         /*          Usage Minimum (01h),        */
192         0x29, 0x03,         /*          Usage Maximum (03h),        */
193         0x14,               /*          Logical Minimum (0),        */
194         0x25, 0x01,         /*          Logical Maximum (1),        */
195         0x95, 0x03,         /*          Report Count (3),           */
196         0x81, 0x02,         /*          Input (Variable),           */
197         0x95, 0x05,         /*          Report Count (5),           */
198         0x81, 0x01,         /*          Input (Constant),           */
199         0x05, 0x01,         /*          Usage Page (Desktop),       */
200         0x75, 0x08,         /*          Report Size (8),            */
201         0x09, 0x30,         /*          Usage (X),                  */
202         0x09, 0x31,         /*          Usage (Y),                  */
203         0x15, 0x81,         /*          Logical Minimum (-127),     */
204         0x25, 0x7F,         /*          Logical Maximum (127),      */
205         0x95, 0x02,         /*          Report Count (2),           */
206         0x81, 0x06,         /*          Input (Variable, Relative), */
207         0x09, 0x38,         /*          Usage (Wheel),              */
208         0x15, 0xFF,         /*          Logical Minimum (-1),       */
209         0x25, 0x01,         /*          Logical Maximum (1),        */
210         0x95, 0x01,         /*          Report Count (1),           */
211         0x81, 0x06,         /*          Input (Variable, Relative), */
212         0x81, 0x01,         /*          Input (Constant),           */
213         0xC0,               /*      End Collection,                 */
214         0xC0                /*  End Collection                      */
215 };
216
217 const size_t uclogic_rdesc_wp8060u_fixed_size =
218                         sizeof(uclogic_rdesc_wp8060u_fixed_arr);
219
220 /* Fixed WP1062 report descriptor */
221 __u8 uclogic_rdesc_wp1062_fixed_arr[] = {
222         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
223         0x09, 0x01,         /*  Usage (Digitizer),                  */
224         0xA1, 0x01,         /*  Collection (Application),           */
225         0x85, 0x09,         /*      Report ID (9),                  */
226         0x09, 0x20,         /*      Usage (Stylus),                 */
227         0xA0,               /*      Collection (Physical),          */
228         0x75, 0x01,         /*          Report Size (1),            */
229         0x09, 0x42,         /*          Usage (Tip Switch),         */
230         0x09, 0x44,         /*          Usage (Barrel Switch),      */
231         0x09, 0x46,         /*          Usage (Tablet Pick),        */
232         0x14,               /*          Logical Minimum (0),        */
233         0x25, 0x01,         /*          Logical Maximum (1),        */
234         0x95, 0x03,         /*          Report Count (3),           */
235         0x81, 0x02,         /*          Input (Variable),           */
236         0x95, 0x04,         /*          Report Count (4),           */
237         0x81, 0x01,         /*          Input (Constant),           */
238         0x09, 0x32,         /*          Usage (In Range),           */
239         0x95, 0x01,         /*          Report Count (1),           */
240         0x81, 0x02,         /*          Input (Variable),           */
241         0x75, 0x10,         /*          Report Size (16),           */
242         0x95, 0x01,         /*          Report Count (1),           */
243         0x14,               /*          Logical Minimum (0),        */
244         0xA4,               /*          Push,                       */
245         0x05, 0x01,         /*          Usage Page (Desktop),       */
246         0x55, 0xFD,         /*          Unit Exponent (-3),         */
247         0x65, 0x13,         /*          Unit (Inch),                */
248         0x34,               /*          Physical Minimum (0),       */
249         0x09, 0x30,         /*          Usage (X),                  */
250         0x46, 0x10, 0x27,   /*          Physical Maximum (10000),   */
251         0x26, 0x20, 0x4E,   /*          Logical Maximum (20000),    */
252         0x81, 0x02,         /*          Input (Variable),           */
253         0x09, 0x31,         /*          Usage (Y),                  */
254         0x46, 0xB7, 0x19,   /*          Physical Maximum (6583),    */
255         0x26, 0x6E, 0x33,   /*          Logical Maximum (13166),    */
256         0x81, 0x02,         /*          Input (Variable),           */
257         0xB4,               /*          Pop,                        */
258         0x09, 0x30,         /*          Usage (Tip Pressure),       */
259         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
260         0x81, 0x02,         /*          Input (Variable),           */
261         0xC0,               /*      End Collection,                 */
262         0xC0                /*  End Collection                      */
263 };
264
265 const size_t uclogic_rdesc_wp1062_fixed_size =
266                         sizeof(uclogic_rdesc_wp1062_fixed_arr);
267
268 /* Fixed PF1209 report descriptor */
269 __u8 uclogic_rdesc_pf1209_fixed_arr[] = {
270         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
271         0x09, 0x01,         /*  Usage (Digitizer),                  */
272         0xA1, 0x01,         /*  Collection (Application),           */
273         0x85, 0x09,         /*      Report ID (9),                  */
274         0x09, 0x20,         /*      Usage (Stylus),                 */
275         0xA0,               /*      Collection (Physical),          */
276         0x75, 0x01,         /*          Report Size (1),            */
277         0x09, 0x42,         /*          Usage (Tip Switch),         */
278         0x09, 0x44,         /*          Usage (Barrel Switch),      */
279         0x09, 0x46,         /*          Usage (Tablet Pick),        */
280         0x14,               /*          Logical Minimum (0),        */
281         0x25, 0x01,         /*          Logical Maximum (1),        */
282         0x95, 0x03,         /*          Report Count (3),           */
283         0x81, 0x02,         /*          Input (Variable),           */
284         0x95, 0x05,         /*          Report Count (5),           */
285         0x81, 0x01,         /*          Input (Constant),           */
286         0x75, 0x10,         /*          Report Size (16),           */
287         0x95, 0x01,         /*          Report Count (1),           */
288         0x14,               /*          Logical Minimum (0),        */
289         0xA4,               /*          Push,                       */
290         0x05, 0x01,         /*          Usage Page (Desktop),       */
291         0x55, 0xFD,         /*          Unit Exponent (-3),         */
292         0x65, 0x13,         /*          Unit (Inch),                */
293         0x34,               /*          Physical Minimum (0),       */
294         0x09, 0x30,         /*          Usage (X),                  */
295         0x46, 0xE0, 0x2E,   /*          Physical Maximum (12000),   */
296         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
297         0x81, 0x02,         /*          Input (Variable),           */
298         0x09, 0x31,         /*          Usage (Y),                  */
299         0x46, 0x28, 0x23,   /*          Physical Maximum (9000),    */
300         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
301         0x81, 0x02,         /*          Input (Variable),           */
302         0xB4,               /*          Pop,                        */
303         0x09, 0x30,         /*          Usage (Tip Pressure),       */
304         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
305         0x81, 0x02,         /*          Input (Variable),           */
306         0xC0,               /*      End Collection,                 */
307         0xC0,               /*  End Collection,                     */
308         0x05, 0x01,         /*  Usage Page (Desktop),               */
309         0x09, 0x02,         /*  Usage (Mouse),                      */
310         0xA1, 0x01,         /*  Collection (Application),           */
311         0x85, 0x08,         /*      Report ID (8),                  */
312         0x09, 0x01,         /*      Usage (Pointer),                */
313         0xA0,               /*      Collection (Physical),          */
314         0x75, 0x01,         /*          Report Size (1),            */
315         0x05, 0x09,         /*          Usage Page (Button),        */
316         0x19, 0x01,         /*          Usage Minimum (01h),        */
317         0x29, 0x03,         /*          Usage Maximum (03h),        */
318         0x14,               /*          Logical Minimum (0),        */
319         0x25, 0x01,         /*          Logical Maximum (1),        */
320         0x95, 0x03,         /*          Report Count (3),           */
321         0x81, 0x02,         /*          Input (Variable),           */
322         0x95, 0x05,         /*          Report Count (5),           */
323         0x81, 0x01,         /*          Input (Constant),           */
324         0x05, 0x01,         /*          Usage Page (Desktop),       */
325         0x75, 0x08,         /*          Report Size (8),            */
326         0x09, 0x30,         /*          Usage (X),                  */
327         0x09, 0x31,         /*          Usage (Y),                  */
328         0x15, 0x81,         /*          Logical Minimum (-127),     */
329         0x25, 0x7F,         /*          Logical Maximum (127),      */
330         0x95, 0x02,         /*          Report Count (2),           */
331         0x81, 0x06,         /*          Input (Variable, Relative), */
332         0x09, 0x38,         /*          Usage (Wheel),              */
333         0x15, 0xFF,         /*          Logical Minimum (-1),       */
334         0x25, 0x01,         /*          Logical Maximum (1),        */
335         0x95, 0x01,         /*          Report Count (1),           */
336         0x81, 0x06,         /*          Input (Variable, Relative), */
337         0x81, 0x01,         /*          Input (Constant),           */
338         0xC0,               /*      End Collection,                 */
339         0xC0                /*  End Collection                      */
340 };
341
342 const size_t uclogic_rdesc_pf1209_fixed_size =
343                         sizeof(uclogic_rdesc_pf1209_fixed_arr);
344
345 /* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */
346 __u8 uclogic_rdesc_twhl850_fixed0_arr[] = {
347         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
348         0x09, 0x01,         /*  Usage (Digitizer),                  */
349         0xA1, 0x01,         /*  Collection (Application),           */
350         0x85, 0x09,         /*      Report ID (9),                  */
351         0x09, 0x20,         /*      Usage (Stylus),                 */
352         0xA0,               /*      Collection (Physical),          */
353         0x14,               /*          Logical Minimum (0),        */
354         0x25, 0x01,         /*          Logical Maximum (1),        */
355         0x75, 0x01,         /*          Report Size (1),            */
356         0x95, 0x03,         /*          Report Count (3),           */
357         0x09, 0x42,         /*          Usage (Tip Switch),         */
358         0x09, 0x44,         /*          Usage (Barrel Switch),      */
359         0x09, 0x46,         /*          Usage (Tablet Pick),        */
360         0x81, 0x02,         /*          Input (Variable),           */
361         0x81, 0x03,         /*          Input (Constant, Variable), */
362         0x95, 0x01,         /*          Report Count (1),           */
363         0x09, 0x32,         /*          Usage (In Range),           */
364         0x81, 0x02,         /*          Input (Variable),           */
365         0x81, 0x03,         /*          Input (Constant, Variable), */
366         0x75, 0x10,         /*          Report Size (16),           */
367         0xA4,               /*          Push,                       */
368         0x05, 0x01,         /*          Usage Page (Desktop),       */
369         0x65, 0x13,         /*          Unit (Inch),                */
370         0x55, 0xFD,         /*          Unit Exponent (-3),         */
371         0x34,               /*          Physical Minimum (0),       */
372         0x09, 0x30,         /*          Usage (X),                  */
373         0x46, 0x40, 0x1F,   /*          Physical Maximum (8000),    */
374         0x26, 0x00, 0x7D,   /*          Logical Maximum (32000),    */
375         0x81, 0x02,         /*          Input (Variable),           */
376         0x09, 0x31,         /*          Usage (Y),                  */
377         0x46, 0x88, 0x13,   /*          Physical Maximum (5000),    */
378         0x26, 0x20, 0x4E,   /*          Logical Maximum (20000),    */
379         0x81, 0x02,         /*          Input (Variable),           */
380         0xB4,               /*          Pop,                        */
381         0x09, 0x30,         /*          Usage (Tip Pressure),       */
382         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
383         0x81, 0x02,         /*          Input (Variable),           */
384         0xC0,               /*      End Collection,                 */
385         0xC0                /*  End Collection                      */
386 };
387
388 const size_t uclogic_rdesc_twhl850_fixed0_size =
389                         sizeof(uclogic_rdesc_twhl850_fixed0_arr);
390
391 /* Fixed PID 0522 tablet report descriptor, interface 1 (mouse) */
392 __u8 uclogic_rdesc_twhl850_fixed1_arr[] = {
393         0x05, 0x01,         /*  Usage Page (Desktop),               */
394         0x09, 0x02,         /*  Usage (Mouse),                      */
395         0xA1, 0x01,         /*  Collection (Application),           */
396         0x85, 0x01,         /*      Report ID (1),                  */
397         0x09, 0x01,         /*      Usage (Pointer),                */
398         0xA0,               /*      Collection (Physical),          */
399         0x05, 0x09,         /*          Usage Page (Button),        */
400         0x75, 0x01,         /*          Report Size (1),            */
401         0x95, 0x03,         /*          Report Count (3),           */
402         0x19, 0x01,         /*          Usage Minimum (01h),        */
403         0x29, 0x03,         /*          Usage Maximum (03h),        */
404         0x14,               /*          Logical Minimum (0),        */
405         0x25, 0x01,         /*          Logical Maximum (1),        */
406         0x81, 0x02,         /*          Input (Variable),           */
407         0x95, 0x05,         /*          Report Count (5),           */
408         0x81, 0x03,         /*          Input (Constant, Variable), */
409         0x05, 0x01,         /*          Usage Page (Desktop),       */
410         0x09, 0x30,         /*          Usage (X),                  */
411         0x09, 0x31,         /*          Usage (Y),                  */
412         0x16, 0x00, 0x80,   /*          Logical Minimum (-32768),   */
413         0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
414         0x75, 0x10,         /*          Report Size (16),           */
415         0x95, 0x02,         /*          Report Count (2),           */
416         0x81, 0x06,         /*          Input (Variable, Relative), */
417         0x09, 0x38,         /*          Usage (Wheel),              */
418         0x15, 0xFF,         /*          Logical Minimum (-1),       */
419         0x25, 0x01,         /*          Logical Maximum (1),        */
420         0x95, 0x01,         /*          Report Count (1),           */
421         0x75, 0x08,         /*          Report Size (8),            */
422         0x81, 0x06,         /*          Input (Variable, Relative), */
423         0x81, 0x03,         /*          Input (Constant, Variable), */
424         0xC0,               /*      End Collection,                 */
425         0xC0                /*  End Collection                      */
426 };
427
428 const size_t uclogic_rdesc_twhl850_fixed1_size =
429                         sizeof(uclogic_rdesc_twhl850_fixed1_arr);
430
431 /* Fixed PID 0522 tablet report descriptor, interface 2 (frame buttons) */
432 __u8 uclogic_rdesc_twhl850_fixed2_arr[] = {
433         0x05, 0x01,         /*  Usage Page (Desktop),               */
434         0x09, 0x06,         /*  Usage (Keyboard),                   */
435         0xA1, 0x01,         /*  Collection (Application),           */
436         0x85, 0x03,         /*      Report ID (3),                  */
437         0x05, 0x07,         /*      Usage Page (Keyboard),          */
438         0x14,               /*      Logical Minimum (0),            */
439         0x19, 0xE0,         /*      Usage Minimum (KB Leftcontrol), */
440         0x29, 0xE7,         /*      Usage Maximum (KB Right GUI),   */
441         0x25, 0x01,         /*      Logical Maximum (1),            */
442         0x75, 0x01,         /*      Report Size (1),                */
443         0x95, 0x08,         /*      Report Count (8),               */
444         0x81, 0x02,         /*      Input (Variable),               */
445         0x18,               /*      Usage Minimum (None),           */
446         0x29, 0xFF,         /*      Usage Maximum (FFh),            */
447         0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
448         0x75, 0x08,         /*      Report Size (8),                */
449         0x95, 0x06,         /*      Report Count (6),               */
450         0x80,               /*      Input,                          */
451         0xC0                /*  End Collection                      */
452 };
453
454 const size_t uclogic_rdesc_twhl850_fixed2_size =
455                         sizeof(uclogic_rdesc_twhl850_fixed2_arr);
456
457 /* Fixed TWHA60 report descriptor, interface 0 (stylus) */
458 __u8 uclogic_rdesc_twha60_fixed0_arr[] = {
459         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
460         0x09, 0x01,         /*  Usage (Digitizer),                  */
461         0xA1, 0x01,         /*  Collection (Application),           */
462         0x85, 0x09,         /*      Report ID (9),                  */
463         0x09, 0x20,         /*      Usage (Stylus),                 */
464         0xA0,               /*      Collection (Physical),          */
465         0x75, 0x01,         /*          Report Size (1),            */
466         0x09, 0x42,         /*          Usage (Tip Switch),         */
467         0x09, 0x44,         /*          Usage (Barrel Switch),      */
468         0x09, 0x46,         /*          Usage (Tablet Pick),        */
469         0x14,               /*          Logical Minimum (0),        */
470         0x25, 0x01,         /*          Logical Maximum (1),        */
471         0x95, 0x03,         /*          Report Count (3),           */
472         0x81, 0x02,         /*          Input (Variable),           */
473         0x95, 0x04,         /*          Report Count (4),           */
474         0x81, 0x01,         /*          Input (Constant),           */
475         0x09, 0x32,         /*          Usage (In Range),           */
476         0x95, 0x01,         /*          Report Count (1),           */
477         0x81, 0x02,         /*          Input (Variable),           */
478         0x75, 0x10,         /*          Report Size (16),           */
479         0x95, 0x01,         /*          Report Count (1),           */
480         0x14,               /*          Logical Minimum (0),        */
481         0xA4,               /*          Push,                       */
482         0x05, 0x01,         /*          Usage Page (Desktop),       */
483         0x55, 0xFD,         /*          Unit Exponent (-3),         */
484         0x65, 0x13,         /*          Unit (Inch),                */
485         0x34,               /*          Physical Minimum (0),       */
486         0x09, 0x30,         /*          Usage (X),                  */
487         0x46, 0x10, 0x27,   /*          Physical Maximum (10000),   */
488         0x27, 0x3F, 0x9C,
489                 0x00, 0x00, /*          Logical Maximum (39999),    */
490         0x81, 0x02,         /*          Input (Variable),           */
491         0x09, 0x31,         /*          Usage (Y),                  */
492         0x46, 0x6A, 0x18,   /*          Physical Maximum (6250),    */
493         0x26, 0xA7, 0x61,   /*          Logical Maximum (24999),    */
494         0x81, 0x02,         /*          Input (Variable),           */
495         0xB4,               /*          Pop,                        */
496         0x09, 0x30,         /*          Usage (Tip Pressure),       */
497         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
498         0x81, 0x02,         /*          Input (Variable),           */
499         0xC0,               /*      End Collection,                 */
500         0xC0                /*  End Collection                      */
501 };
502
503 const size_t uclogic_rdesc_twha60_fixed0_size =
504                         sizeof(uclogic_rdesc_twha60_fixed0_arr);
505
506 /* Fixed TWHA60 report descriptor, interface 1 (frame buttons) */
507 __u8 uclogic_rdesc_twha60_fixed1_arr[] = {
508         0x05, 0x01, /*  Usage Page (Desktop),       */
509         0x09, 0x06, /*  Usage (Keyboard),           */
510         0xA1, 0x01, /*  Collection (Application),   */
511         0x85, 0x05, /*      Report ID (5),          */
512         0x05, 0x07, /*      Usage Page (Keyboard),  */
513         0x14,       /*      Logical Minimum (0),    */
514         0x25, 0x01, /*      Logical Maximum (1),    */
515         0x75, 0x01, /*      Report Size (1),        */
516         0x95, 0x08, /*      Report Count (8),       */
517         0x81, 0x01, /*      Input (Constant),       */
518         0x95, 0x0C, /*      Report Count (12),      */
519         0x19, 0x3A, /*      Usage Minimum (KB F1),  */
520         0x29, 0x45, /*      Usage Maximum (KB F12), */
521         0x81, 0x02, /*      Input (Variable),       */
522         0x95, 0x0C, /*      Report Count (12),      */
523         0x19, 0x68, /*      Usage Minimum (KB F13), */
524         0x29, 0x73, /*      Usage Maximum (KB F24), */
525         0x81, 0x02, /*      Input (Variable),       */
526         0x95, 0x08, /*      Report Count (8),       */
527         0x81, 0x01, /*      Input (Constant),       */
528         0xC0        /*  End Collection              */
529 };
530
531 const size_t uclogic_rdesc_twha60_fixed1_size =
532                         sizeof(uclogic_rdesc_twha60_fixed1_arr);
533
534 /* Fixed report descriptor template for (tweaked) v1 pen reports */
535 const __u8 uclogic_rdesc_v1_pen_template_arr[] = {
536         0x05, 0x0D,             /*  Usage Page (Digitizer),                 */
537         0x09, 0x01,             /*  Usage (Digitizer),                      */
538         0xA1, 0x01,             /*  Collection (Application),               */
539         0x85, 0x07,             /*      Report ID (7),                      */
540         0x09, 0x20,             /*      Usage (Stylus),                     */
541         0xA0,                   /*      Collection (Physical),              */
542         0x14,                   /*          Logical Minimum (0),            */
543         0x25, 0x01,             /*          Logical Maximum (1),            */
544         0x75, 0x01,             /*          Report Size (1),                */
545         0x09, 0x42,             /*          Usage (Tip Switch),             */
546         0x09, 0x44,             /*          Usage (Barrel Switch),          */
547         0x09, 0x46,             /*          Usage (Tablet Pick),            */
548         0x95, 0x03,             /*          Report Count (3),               */
549         0x81, 0x02,             /*          Input (Variable),               */
550         0x95, 0x03,             /*          Report Count (3),               */
551         0x81, 0x03,             /*          Input (Constant, Variable),     */
552         0x09, 0x32,             /*          Usage (In Range),               */
553         0x95, 0x01,             /*          Report Count (1),               */
554         0x81, 0x02,             /*          Input (Variable),               */
555         0x95, 0x01,             /*          Report Count (1),               */
556         0x81, 0x03,             /*          Input (Constant, Variable),     */
557         0x75, 0x10,             /*          Report Size (16),               */
558         0x95, 0x01,             /*          Report Count (1),               */
559         0xA4,                   /*          Push,                           */
560         0x05, 0x01,             /*          Usage Page (Desktop),           */
561         0x65, 0x13,             /*          Unit (Inch),                    */
562         0x55, 0xFD,             /*          Unit Exponent (-3),             */
563         0x34,                   /*          Physical Minimum (0),           */
564         0x09, 0x30,             /*          Usage (X),                      */
565         0x27, UCLOGIC_RDESC_PEN_PH(X_LM),
566                                 /*          Logical Maximum (PLACEHOLDER),  */
567         0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
568                                 /*          Physical Maximum (PLACEHOLDER), */
569         0x81, 0x02,             /*          Input (Variable),               */
570         0x09, 0x31,             /*          Usage (Y),                      */
571         0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
572                                 /*          Logical Maximum (PLACEHOLDER),  */
573         0x47, UCLOGIC_RDESC_PEN_PH(Y_PM),
574                                 /*          Physical Maximum (PLACEHOLDER), */
575         0x81, 0x02,             /*          Input (Variable),               */
576         0xB4,                   /*          Pop,                            */
577         0x09, 0x30,             /*          Usage (Tip Pressure),           */
578         0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
579                                 /*          Logical Maximum (PLACEHOLDER),  */
580         0x81, 0x02,             /*          Input (Variable),               */
581         0xC0,                   /*      End Collection,                     */
582         0xC0                    /*  End Collection                          */
583 };
584
585 const size_t uclogic_rdesc_v1_pen_template_size =
586                         sizeof(uclogic_rdesc_v1_pen_template_arr);
587
588 /* Fixed report descriptor template for (tweaked) v2 pen reports */
589 const __u8 uclogic_rdesc_v2_pen_template_arr[] = {
590         0x05, 0x0D,             /*  Usage Page (Digitizer),                 */
591         0x09, 0x01,             /*  Usage (Digitizer),                      */
592         0xA1, 0x01,             /*  Collection (Application),               */
593         0x85, 0x08,             /*      Report ID (8),                      */
594         0x09, 0x20,             /*      Usage (Stylus),                     */
595         0xA0,                   /*      Collection (Physical),              */
596         0x14,                   /*          Logical Minimum (0),            */
597         0x25, 0x01,             /*          Logical Maximum (1),            */
598         0x75, 0x01,             /*          Report Size (1),                */
599         0x09, 0x42,             /*          Usage (Tip Switch),             */
600         0x09, 0x44,             /*          Usage (Barrel Switch),          */
601         0x09, 0x46,             /*          Usage (Tablet Pick),            */
602         0x95, 0x03,             /*          Report Count (3),               */
603         0x81, 0x02,             /*          Input (Variable),               */
604         0x95, 0x03,             /*          Report Count (3),               */
605         0x81, 0x03,             /*          Input (Constant, Variable),     */
606         0x09, 0x32,             /*          Usage (In Range),               */
607         0x95, 0x01,             /*          Report Count (1),               */
608         0x81, 0x02,             /*          Input (Variable),               */
609         0x95, 0x01,             /*          Report Count (1),               */
610         0x81, 0x03,             /*          Input (Constant, Variable),     */
611         0x95, 0x01,             /*          Report Count (1),               */
612         0xA4,                   /*          Push,                           */
613         0x05, 0x01,             /*          Usage Page (Desktop),           */
614         0x65, 0x13,             /*          Unit (Inch),                    */
615         0x55, 0xFD,             /*          Unit Exponent (-3),             */
616         0x75, 0x18,             /*          Report Size (24),               */
617         0x34,                   /*          Physical Minimum (0),           */
618         0x09, 0x30,             /*          Usage (X),                      */
619         0x27, UCLOGIC_RDESC_PEN_PH(X_LM),
620                                 /*          Logical Maximum (PLACEHOLDER),  */
621         0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
622                                 /*          Physical Maximum (PLACEHOLDER), */
623         0x81, 0x02,             /*          Input (Variable),               */
624         0x09, 0x31,             /*          Usage (Y),                      */
625         0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
626                                 /*          Logical Maximum (PLACEHOLDER),  */
627         0x47, UCLOGIC_RDESC_PEN_PH(Y_PM),
628                                 /*          Physical Maximum (PLACEHOLDER), */
629         0x81, 0x02,             /*          Input (Variable),               */
630         0xB4,                   /*          Pop,                            */
631         0x09, 0x30,             /*          Usage (Tip Pressure),           */
632         0x75, 0x10,             /*          Report Size (16),               */
633         0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
634                                 /*          Logical Maximum (PLACEHOLDER),  */
635         0x81, 0x02,             /*          Input (Variable),               */
636         0x54,                   /*          Unit Exponent (0),              */
637         0x65, 0x14,             /*          Unit (Degrees),                 */
638         0x35, 0xC4,             /*          Physical Minimum (-60),         */
639         0x45, 0x3C,             /*          Physical Maximum (60),          */
640         0x15, 0xC4,             /*          Logical Minimum (-60),          */
641         0x25, 0x3C,             /*          Logical Maximum (60),           */
642         0x75, 0x08,             /*          Report Size (8),                */
643         0x95, 0x02,             /*          Report Count (2),               */
644         0x09, 0x3D,             /*          Usage (X Tilt),                 */
645         0x09, 0x3E,             /*          Usage (Y Tilt),                 */
646         0x81, 0x02,             /*          Input (Variable),               */
647         0xC0,                   /*      End Collection,                     */
648         0xC0                    /*  End Collection                          */
649 };
650
651 const size_t uclogic_rdesc_v2_pen_template_size =
652                         sizeof(uclogic_rdesc_v2_pen_template_arr);
653
654 /*
655  * Expand to the contents of a generic frame buttons report descriptor.
656  *
657  * @_id:        The report ID to use.
658  * @_size:      Size of the report to pad to, including report ID, bytes.
659  */
660 #define UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(_id, _size) \
661         0x05, 0x01,     /*  Usage Page (Desktop),               */ \
662         0x09, 0x07,     /*  Usage (Keypad),                     */ \
663         0xA1, 0x01,     /*  Collection (Application),           */ \
664         0x85, (_id),    /*      Report ID (_id),                */ \
665         0x14,           /*      Logical Minimum (0),            */ \
666         0x25, 0x01,     /*      Logical Maximum (1),            */ \
667         0x75, 0x01,     /*      Report Size (1),                */ \
668         0x05, 0x0D,     /*      Usage Page (Digitizer),         */ \
669         0x09, 0x39,     /*      Usage (Tablet Function Keys),   */ \
670         0xA0,           /*      Collection (Physical),          */ \
671         0x09, 0x44,     /*          Usage (Barrel Switch),      */ \
672         0x95, 0x01,     /*          Report Count (1),           */ \
673         0x81, 0x02,     /*          Input (Variable),           */ \
674         0x05, 0x01,     /*          Usage Page (Desktop),       */ \
675         0x09, 0x30,     /*          Usage (X),                  */ \
676         0x09, 0x31,     /*          Usage (Y),                  */ \
677         0x95, 0x02,     /*          Report Count (2),           */ \
678         0x81, 0x02,     /*          Input (Variable),           */ \
679         0x95, 0x15,     /*          Report Count (21),          */ \
680         0x81, 0x01,     /*          Input (Constant),           */ \
681         0x05, 0x09,     /*          Usage Page (Button),        */ \
682         0x19, 0x01,     /*          Usage Minimum (01h),        */ \
683         0x29, 0x0A,     /*          Usage Maximum (0Ah),        */ \
684         0x95, 0x0A,     /*          Report Count (10),          */ \
685         0x81, 0x02,     /*          Input (Variable),           */ \
686         0xC0,           /*      End Collection,                 */ \
687         0x05, 0x01,     /*      Usage Page (Desktop),           */ \
688         0x09, 0x05,     /*      Usage (Gamepad),                */ \
689         0xA0,           /*      Collection (Physical),          */ \
690         0x05, 0x09,     /*          Usage Page (Button),        */ \
691         0x19, 0x01,     /*          Usage Minimum (01h),        */ \
692         0x29, 0x03,     /*          Usage Maximum (03h),        */ \
693         0x95, 0x03,     /*          Report Count (3),           */ \
694         0x81, 0x02,     /*          Input (Variable),           */ \
695         0x95, ((_size) * 8 - 45),                                  \
696                         /*          Report Count (padding),     */ \
697         0x81, 0x01,     /*          Input (Constant),           */ \
698         0xC0,           /*      End Collection,                 */ \
699         0xC0            /*  End Collection                      */
700
701 /* Fixed report descriptor for (tweaked) v1 frame reports */
702 const __u8 uclogic_rdesc_v1_frame_arr[] = {
703         UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8)
704 };
705 const size_t uclogic_rdesc_v1_frame_size =
706                         sizeof(uclogic_rdesc_v1_frame_arr);
707
708 /* Fixed report descriptor for (tweaked) v2 frame button reports */
709 const __u8 uclogic_rdesc_v2_frame_buttons_arr[] = {
710         UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID,
711                                           12)
712 };
713 const size_t uclogic_rdesc_v2_frame_buttons_size =
714                         sizeof(uclogic_rdesc_v2_frame_buttons_arr);
715
716 /* Fixed report descriptor for (tweaked) v2 frame touch ring reports */
717 const __u8 uclogic_rdesc_v2_frame_touch_ring_arr[] = {
718         0x05, 0x01,         /*  Usage Page (Desktop),               */
719         0x09, 0x07,         /*  Usage (Keypad),                     */
720         0xA1, 0x01,         /*  Collection (Application),           */
721         0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID,
722                             /*      Report ID (TOUCH_ID),           */
723         0x14,               /*      Logical Minimum (0),            */
724         0x05, 0x0D,         /*      Usage Page (Digitizer),         */
725         0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
726         0xA0,               /*      Collection (Physical),          */
727         0x25, 0x01,         /*          Logical Maximum (1),        */
728         0x75, 0x01,         /*          Report Size (1),            */
729         0x05, 0x09,         /*          Usage Page (Button),        */
730         0x09, 0x01,         /*          Usage (01h),                */
731         0x95, 0x01,         /*          Report Count (1),           */
732         0x81, 0x02,         /*          Input (Variable),           */
733         0x95, 0x07,         /*          Report Count (7),           */
734         0x81, 0x01,         /*          Input (Constant),           */
735         0x75, 0x08,         /*          Report Size (8),            */
736         0x95, 0x02,         /*          Report Count (2),           */
737         0x81, 0x01,         /*          Input (Constant),           */
738         0x05, 0x0D,         /*          Usage Page (Digitizer),     */
739         0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
740         0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
741         0x95, 0x01,         /*          Report Count (1),           */
742         0x81, 0x02,         /*          Input (Variable),           */
743         0x05, 0x01,         /*          Usage Page (Desktop),       */
744         0x09, 0x38,         /*          Usage (Wheel),              */
745         0x95, 0x01,         /*          Report Count (1),           */
746         0x15, 0x00,         /*          Logical Minimum (0),        */
747         0x25, 0x0B,         /*          Logical Maximum (11),       */
748         0x81, 0x02,         /*          Input (Variable),           */
749         0x09, 0x30,         /*          Usage (X),                  */
750         0x09, 0x31,         /*          Usage (Y),                  */
751         0x14,               /*          Logical Minimum (0),        */
752         0x25, 0x01,         /*          Logical Maximum (1),        */
753         0x75, 0x01,         /*          Report Size (1),            */
754         0x95, 0x02,         /*          Report Count (2),           */
755         0x81, 0x02,         /*          Input (Variable),           */
756         0x95, 0x2E,         /*          Report Count (46),          */
757         0x81, 0x01,         /*          Input (Constant),           */
758         0xC0,               /*      End Collection,                 */
759         0xC0                /*  End Collection                      */
760 };
761 const size_t uclogic_rdesc_v2_frame_touch_ring_size =
762                         sizeof(uclogic_rdesc_v2_frame_touch_ring_arr);
763
764 /* Fixed report descriptor for (tweaked) v2 frame touch strip reports */
765 const __u8 uclogic_rdesc_v2_frame_touch_strip_arr[] = {
766         0x05, 0x01,         /*  Usage Page (Desktop),               */
767         0x09, 0x07,         /*  Usage (Keypad),                     */
768         0xA1, 0x01,         /*  Collection (Application),           */
769         0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID,
770                             /*      Report ID (TOUCH_ID),           */
771         0x14,               /*      Logical Minimum (0),            */
772         0x05, 0x0D,         /*      Usage Page (Digitizer),         */
773         0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
774         0xA0,               /*      Collection (Physical),          */
775         0x25, 0x01,         /*          Logical Maximum (1),        */
776         0x75, 0x01,         /*          Report Size (1),            */
777         0x05, 0x09,         /*          Usage Page (Button),        */
778         0x09, 0x01,         /*          Usage (01h),                */
779         0x95, 0x01,         /*          Report Count (1),           */
780         0x81, 0x02,         /*          Input (Variable),           */
781         0x95, 0x07,         /*          Report Count (7),           */
782         0x81, 0x01,         /*          Input (Constant),           */
783         0x75, 0x08,         /*          Report Size (8),            */
784         0x95, 0x02,         /*          Report Count (2),           */
785         0x81, 0x01,         /*          Input (Constant),           */
786         0x05, 0x0D,         /*          Usage Page (Digitizer),     */
787         0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
788         0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
789         0x95, 0x01,         /*          Report Count (1),           */
790         0x81, 0x02,         /*          Input (Variable),           */
791         0x05, 0x01,         /*          Usage Page (Desktop),       */
792         0x09, 0x38,         /*          Usage (Wheel),              */
793         0x95, 0x01,         /*          Report Count (1),           */
794         0x15, 0x00,         /*          Logical Minimum (0),        */
795         0x25, 0x07,         /*          Logical Maximum (7),        */
796         0x81, 0x02,         /*          Input (Variable),           */
797         0x09, 0x30,         /*          Usage (X),                  */
798         0x09, 0x31,         /*          Usage (Y),                  */
799         0x14,               /*          Logical Minimum (0),        */
800         0x25, 0x01,         /*          Logical Maximum (1),        */
801         0x75, 0x01,         /*          Report Size (1),            */
802         0x95, 0x02,         /*          Report Count (2),           */
803         0x81, 0x02,         /*          Input (Variable),           */
804         0x95, 0x2E,         /*          Report Count (46),          */
805         0x81, 0x01,         /*          Input (Constant),           */
806         0xC0,               /*      End Collection,                 */
807         0xC0                /*  End Collection                      */
808 };
809 const size_t uclogic_rdesc_v2_frame_touch_strip_size =
810                         sizeof(uclogic_rdesc_v2_frame_touch_strip_arr);
811
812 /* Fixed report descriptor for (tweaked) v2 frame dial reports */
813 const __u8 uclogic_rdesc_v2_frame_dial_arr[] = {
814         0x05, 0x01,         /*  Usage Page (Desktop),               */
815         0x09, 0x07,         /*  Usage (Keypad),                     */
816         0xA1, 0x01,         /*  Collection (Application),           */
817         0x85, UCLOGIC_RDESC_V2_FRAME_DIAL_ID,
818                             /*      Report ID (DIAL_ID),            */
819         0x14,               /*      Logical Minimum (0),            */
820         0x05, 0x0D,         /*      Usage Page (Digitizer),         */
821         0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
822         0xA0,               /*      Collection (Physical),          */
823         0x25, 0x01,         /*          Logical Maximum (1),        */
824         0x75, 0x01,         /*          Report Size (1),            */
825         0x95, 0x01,         /*          Report Count (1),           */
826         0x81, 0x01,         /*          Input (Constant),           */
827         0x05, 0x09,         /*          Usage Page (Button),        */
828         0x09, 0x01,         /*          Usage (01h),                */
829         0x95, 0x01,         /*          Report Count (1),           */
830         0x81, 0x02,         /*          Input (Variable),           */
831         0x95, 0x06,         /*          Report Count (6),           */
832         0x81, 0x01,         /*          Input (Constant),           */
833         0x75, 0x08,         /*          Report Size (8),            */
834         0x95, 0x02,         /*          Report Count (2),           */
835         0x81, 0x01,         /*          Input (Constant),           */
836         0x05, 0x0D,         /*          Usage Page (Digitizer),     */
837         0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
838         0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
839         0x95, 0x01,         /*          Report Count (1),           */
840         0x81, 0x02,         /*          Input (Variable),           */
841         0x05, 0x01,         /*          Usage Page (Desktop),       */
842         0x09, 0x38,         /*          Usage (Wheel),              */
843         0x95, 0x01,         /*          Report Count (1),           */
844         0x15, 0xFF,         /*          Logical Minimum (-1),       */
845         0x25, 0x01,         /*          Logical Maximum (1),        */
846         0x81, 0x06,         /*          Input (Variable, Relative), */
847         0x09, 0x30,         /*          Usage (X),                  */
848         0x09, 0x31,         /*          Usage (Y),                  */
849         0x14,               /*          Logical Minimum (0),        */
850         0x25, 0x01,         /*          Logical Maximum (1),        */
851         0x75, 0x01,         /*          Report Size (1),            */
852         0x95, 0x02,         /*          Report Count (2),           */
853         0x81, 0x02,         /*          Input (Variable),           */
854         0x95, 0x2E,         /*          Report Count (46),          */
855         0x81, 0x01,         /*          Input (Constant),           */
856         0xC0,               /*      End Collection,                 */
857         0xC0                /*  End Collection                      */
858 };
859 const size_t uclogic_rdesc_v2_frame_dial_size =
860                         sizeof(uclogic_rdesc_v2_frame_dial_arr);
861
862 /* Fixed report descriptor for Ugee EX07 frame */
863 const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
864         0x05, 0x01,             /*  Usage Page (Desktop),                   */
865         0x09, 0x07,             /*  Usage (Keypad),                         */
866         0xA1, 0x01,             /*  Collection (Application),               */
867         0x85, 0x06,             /*      Report ID (6),                      */
868         0x05, 0x0D,             /*      Usage Page (Digitizer),             */
869         0x09, 0x39,             /*      Usage (Tablet Function Keys),       */
870         0xA0,                   /*      Collection (Physical),              */
871         0x05, 0x09,             /*          Usage Page (Button),            */
872         0x75, 0x01,             /*          Report Size (1),                */
873         0x19, 0x03,             /*          Usage Minimum (03h),            */
874         0x29, 0x06,             /*          Usage Maximum (06h),            */
875         0x95, 0x04,             /*          Report Count (4),               */
876         0x81, 0x02,             /*          Input (Variable),               */
877         0x95, 0x1A,             /*          Report Count (26),              */
878         0x81, 0x03,             /*          Input (Constant, Variable),     */
879         0x19, 0x01,             /*          Usage Minimum (01h),            */
880         0x29, 0x02,             /*          Usage Maximum (02h),            */
881         0x95, 0x02,             /*          Report Count (2),               */
882         0x81, 0x02,             /*          Input (Variable),               */
883         0xC0,                   /*      End Collection,                     */
884         0xC0                    /*  End Collection                          */
885 };
886 const size_t uclogic_rdesc_ugee_ex07_frame_size =
887                         sizeof(uclogic_rdesc_ugee_ex07_frame_arr);
888
889 /* Fixed report descriptor for Ugee G5 frame controls */
890 const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = {
891         0x05, 0x01,         /*  Usage Page (Desktop),               */
892         0x09, 0x07,         /*  Usage (Keypad),                     */
893         0xA1, 0x01,         /*  Collection (Application),           */
894         0x85, 0x06,         /*      Report ID (6),                  */
895         0x05, 0x0D,         /*      Usage Page (Digitizer),         */
896         0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
897         0xA0,               /*      Collection (Physical),          */
898         0x14,               /*          Logical Minimum (0),        */
899         0x25, 0x01,         /*          Logical Maximum (1),        */
900         0x05, 0x01,         /*          Usage Page (Desktop),       */
901         0x05, 0x09,         /*          Usage Page (Button),        */
902         0x19, 0x01,         /*          Usage Minimum (01h),        */
903         0x29, 0x05,         /*          Usage Maximum (05h),        */
904         0x75, 0x01,         /*          Report Size (1),            */
905         0x95, 0x05,         /*          Report Count (5),           */
906         0x81, 0x02,         /*          Input (Variable),           */
907         0x75, 0x01,         /*          Report Size (1),            */
908         0x95, 0x03,         /*          Report Count (3),           */
909         0x81, 0x01,         /*          Input (Constant),           */
910         0x05, 0x0D,         /*          Usage Page (Digitizer),     */
911         0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
912         0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
913         0x75, 0x08,         /*          Report Size (8),            */
914         0x95, 0x01,         /*          Report Count (1),           */
915         0x81, 0x02,         /*          Input (Variable),           */
916         0x25, 0x01,         /*          Logical Maximum (1),        */
917         0x09, 0x44,         /*          Usage (Barrel Switch),      */
918         0x75, 0x01,         /*          Report Size (1),            */
919         0x95, 0x01,         /*          Report Count (1),           */
920         0x81, 0x02,         /*          Input (Variable),           */
921         0x05, 0x01,         /*          Usage Page (Desktop),       */
922         0x09, 0x30,         /*          Usage (X),                  */
923         0x09, 0x31,         /*          Usage (Y),                  */
924         0x75, 0x01,         /*          Report Size (1),            */
925         0x95, 0x02,         /*          Report Count (2),           */
926         0x81, 0x02,         /*          Input (Variable),           */
927         0x75, 0x01,         /*          Report Size (1),            */
928         0x95, 0x0B,         /*          Report Count (11),          */
929         0x81, 0x01,         /*          Input (Constant),           */
930         0x05, 0x01,         /*          Usage Page (Desktop),       */
931         0x09, 0x38,         /*          Usage (Wheel),              */
932         0x15, 0xFF,         /*          Logical Minimum (-1),       */
933         0x25, 0x01,         /*          Logical Maximum (1),        */
934         0x75, 0x02,         /*          Report Size (2),            */
935         0x95, 0x01,         /*          Report Count (1),           */
936         0x81, 0x06,         /*          Input (Variable, Relative), */
937         0xC0,               /*      End Collection,                 */
938         0xC0                /*  End Collection                      */
939 };
940 const size_t uclogic_rdesc_ugee_g5_frame_size =
941                         sizeof(uclogic_rdesc_ugee_g5_frame_arr);
942
943 /* Fixed report descriptor for XP-Pen Deco 01 frame controls */
944 const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = {
945         0x05, 0x01, /*  Usage Page (Desktop),               */
946         0x09, 0x07, /*  Usage (Keypad),                     */
947         0xA1, 0x01, /*  Collection (Application),           */
948         0x85, 0x06, /*      Report ID (6),                  */
949         0x14,       /*      Logical Minimum (0),            */
950         0x25, 0x01, /*      Logical Maximum (1),            */
951         0x75, 0x01, /*      Report Size (1),                */
952         0x05, 0x0D, /*      Usage Page (Digitizer),         */
953         0x09, 0x39, /*      Usage (Tablet Function Keys),   */
954         0xA0,       /*      Collection (Physical),          */
955         0x05, 0x09, /*          Usage Page (Button),        */
956         0x19, 0x01, /*          Usage Minimum (01h),        */
957         0x29, 0x08, /*          Usage Maximum (08h),        */
958         0x95, 0x08, /*          Report Count (8),           */
959         0x81, 0x02, /*          Input (Variable),           */
960         0x05, 0x0D, /*          Usage Page (Digitizer),     */
961         0x09, 0x44, /*          Usage (Barrel Switch),      */
962         0x95, 0x01, /*          Report Count (1),           */
963         0x81, 0x02, /*          Input (Variable),           */
964         0x05, 0x01, /*          Usage Page (Desktop),       */
965         0x09, 0x30, /*          Usage (X),                  */
966         0x09, 0x31, /*          Usage (Y),                  */
967         0x95, 0x02, /*          Report Count (2),           */
968         0x81, 0x02, /*          Input (Variable),           */
969         0x95, 0x15, /*          Report Count (21),          */
970         0x81, 0x01, /*          Input (Constant),           */
971         0xC0,       /*      End Collection,                 */
972         0xC0        /*  End Collection                      */
973 };
974
975 const size_t uclogic_rdesc_xppen_deco01_frame_size =
976                         sizeof(uclogic_rdesc_xppen_deco01_frame_arr);
977
978 /**
979  * uclogic_rdesc_template_apply() - apply report descriptor parameters to a
980  * report descriptor template, creating a report descriptor. Copies the
981  * template over to the new report descriptor and replaces every occurrence of
982  * UCLOGIC_RDESC_PH_HEAD, followed by an index byte, with the value from the
983  * parameter list at that index.
984  *
985  * @template_ptr:       Pointer to the template buffer.
986  * @template_size:      Size of the template buffer.
987  * @param_list:         List of template parameters.
988  * @param_num:          Number of parameters in the list.
989  *
990  * Returns:
991  *      Kmalloc-allocated pointer to the created report descriptor,
992  *      or NULL if allocation failed.
993  */
994 __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
995                                    size_t template_size,
996                                    const s32 *param_list,
997                                    size_t param_num)
998 {
999         static const __u8 head[] = {UCLOGIC_RDESC_PH_HEAD};
1000         __u8 *rdesc_ptr;
1001         __u8 *p;
1002         s32 v;
1003
1004         rdesc_ptr = kmemdup(template_ptr, template_size, GFP_KERNEL);
1005         if (rdesc_ptr == NULL)
1006                 return NULL;
1007
1008         for (p = rdesc_ptr; p + sizeof(head) < rdesc_ptr + template_size;) {
1009                 if (memcmp(p, head, sizeof(head)) == 0 &&
1010                     p[sizeof(head)] < param_num) {
1011                         v = param_list[p[sizeof(head)]];
1012                         put_unaligned(cpu_to_le32(v), (s32 *)p);
1013                         p += sizeof(head) + 1;
1014                 } else {
1015                         p++;
1016                 }
1017         }
1018
1019         return rdesc_ptr;
1020 }