Merge remote-tracking branch 'torvalds/master' into perf/core
[linux-2.6-microblaze.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, 0x02,         /*  Usage (Pen),                        */
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, 0x02,         /*  Usage (Pen),                        */
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, 0x02,         /*  Usage (Pen),                        */
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, 0x02,         /*  Usage (Pen),                        */
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, 0x02,         /*  Usage (Pen),                        */
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, 0x02,         /*  Usage (Pen),                        */
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, 0x02,         /*  Usage (Pen),                        */
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_pen_v1_template_arr[] = {
536         0x05, 0x0D,             /*  Usage Page (Digitizer),                 */
537         0x09, 0x02,             /*  Usage (Pen),                            */
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_pen_v1_template_size =
586                         sizeof(uclogic_rdesc_pen_v1_template_arr);
587
588 /* Fixed report descriptor template for (tweaked) v2 pen reports */
589 const __u8 uclogic_rdesc_pen_v2_template_arr[] = {
590         0x05, 0x0D,             /*  Usage Page (Digitizer),                 */
591         0x09, 0x02,             /*  Usage (Pen),                            */
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         0x81, 0x03,             /*          Input (Constant, Variable),     */
637         0xC0,                   /*      End Collection,                     */
638         0xC0                    /*  End Collection                          */
639 };
640
641 const size_t uclogic_rdesc_pen_v2_template_size =
642                         sizeof(uclogic_rdesc_pen_v2_template_arr);
643
644 /*
645  * Expand to the contents of a generic buttonpad report descriptor.
646  *
647  * @_padding:   Padding from the end of button bits at bit 44, until
648  *              the end of the report, in bits.
649  */
650 #define UCLOGIC_RDESC_BUTTONPAD_BYTES(_padding) \
651         0x05, 0x01,     /*  Usage Page (Desktop),               */ \
652         0x09, 0x07,     /*  Usage (Keypad),                     */ \
653         0xA1, 0x01,     /*  Collection (Application),           */ \
654         0x85, 0xF7,     /*      Report ID (247),                */ \
655         0x14,           /*      Logical Minimum (0),            */ \
656         0x25, 0x01,     /*      Logical Maximum (1),            */ \
657         0x75, 0x01,     /*      Report Size (1),                */ \
658         0x05, 0x0D,     /*      Usage Page (Digitizer),         */ \
659         0x09, 0x39,     /*      Usage (Tablet Function Keys),   */ \
660         0xA0,           /*      Collection (Physical),          */ \
661         0x09, 0x44,     /*          Usage (Barrel Switch),      */ \
662         0x95, 0x01,     /*          Report Count (1),           */ \
663         0x81, 0x02,     /*          Input (Variable),           */ \
664         0x05, 0x01,     /*          Usage Page (Desktop),       */ \
665         0x09, 0x30,     /*          Usage (X),                  */ \
666         0x09, 0x31,     /*          Usage (Y),                  */ \
667         0x95, 0x02,     /*          Report Count (2),           */ \
668         0x81, 0x02,     /*          Input (Variable),           */ \
669         0x95, 0x15,     /*          Report Count (21),          */ \
670         0x81, 0x01,     /*          Input (Constant),           */ \
671         0x05, 0x09,     /*          Usage Page (Button),        */ \
672         0x19, 0x01,     /*          Usage Minimum (01h),        */ \
673         0x29, 0x0A,     /*          Usage Maximum (0Ah),        */ \
674         0x95, 0x0A,     /*          Report Count (10),          */ \
675         0x81, 0x02,     /*          Input (Variable),           */ \
676         0xC0,           /*      End Collection,                 */ \
677         0x05, 0x01,     /*      Usage Page (Desktop),           */ \
678         0x09, 0x05,     /*      Usage (Gamepad),                */ \
679         0xA0,           /*      Collection (Physical),          */ \
680         0x05, 0x09,     /*          Usage Page (Button),        */ \
681         0x19, 0x01,     /*          Usage Minimum (01h),        */ \
682         0x29, 0x02,     /*          Usage Maximum (02h),        */ \
683         0x95, 0x02,     /*          Report Count (2),           */ \
684         0x81, 0x02,     /*          Input (Variable),           */ \
685         0x95, _padding, /*          Report Count (_padding),    */ \
686         0x81, 0x01,     /*          Input (Constant),           */ \
687         0xC0,           /*      End Collection,                 */ \
688         0xC0            /*  End Collection                      */
689
690 /* Fixed report descriptor for (tweaked) v1 buttonpad reports */
691 const __u8 uclogic_rdesc_buttonpad_v1_arr[] = {
692         UCLOGIC_RDESC_BUTTONPAD_BYTES(20)
693 };
694 const size_t uclogic_rdesc_buttonpad_v1_size =
695                         sizeof(uclogic_rdesc_buttonpad_v1_arr);
696
697 /* Fixed report descriptor for (tweaked) v2 buttonpad reports */
698 const __u8 uclogic_rdesc_buttonpad_v2_arr[] = {
699         UCLOGIC_RDESC_BUTTONPAD_BYTES(52)
700 };
701 const size_t uclogic_rdesc_buttonpad_v2_size =
702                         sizeof(uclogic_rdesc_buttonpad_v2_arr);
703
704 /* Fixed report descriptor for Ugee EX07 buttonpad */
705 const __u8 uclogic_rdesc_ugee_ex07_buttonpad_arr[] = {
706         0x05, 0x01,             /*  Usage Page (Desktop),                   */
707         0x09, 0x07,             /*  Usage (Keypad),                         */
708         0xA1, 0x01,             /*  Collection (Application),               */
709         0x85, 0x06,             /*      Report ID (6),                      */
710         0x05, 0x0D,             /*      Usage Page (Digitizer),             */
711         0x09, 0x39,             /*      Usage (Tablet Function Keys),       */
712         0xA0,                   /*      Collection (Physical),              */
713         0x05, 0x09,             /*          Usage Page (Button),            */
714         0x75, 0x01,             /*          Report Size (1),                */
715         0x19, 0x03,             /*          Usage Minimum (03h),            */
716         0x29, 0x06,             /*          Usage Maximum (06h),            */
717         0x95, 0x04,             /*          Report Count (4),               */
718         0x81, 0x02,             /*          Input (Variable),               */
719         0x95, 0x1A,             /*          Report Count (26),              */
720         0x81, 0x03,             /*          Input (Constant, Variable),     */
721         0x19, 0x01,             /*          Usage Minimum (01h),            */
722         0x29, 0x02,             /*          Usage Maximum (02h),            */
723         0x95, 0x02,             /*          Report Count (2),               */
724         0x81, 0x02,             /*          Input (Variable),               */
725         0xC0,                   /*      End Collection,                     */
726         0xC0                    /*  End Collection                          */
727 };
728 const size_t uclogic_rdesc_ugee_ex07_buttonpad_size =
729                         sizeof(uclogic_rdesc_ugee_ex07_buttonpad_arr);
730
731 /* Fixed report descriptor for Ugee G5 frame controls */
732 const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = {
733         0x05, 0x01,         /*  Usage Page (Desktop),               */
734         0x09, 0x07,         /*  Usage (Keypad),                     */
735         0xA1, 0x01,         /*  Collection (Application),           */
736         0x85, 0x06,         /*      Report ID (6),                  */
737         0x05, 0x0D,         /*      Usage Page (Digitizer),         */
738         0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
739         0xA0,               /*      Collection (Physical),          */
740         0x14,               /*          Logical Minimum (0),        */
741         0x25, 0x01,         /*          Logical Maximum (1),        */
742         0x05, 0x01,         /*          Usage Page (Desktop),       */
743         0x05, 0x09,         /*          Usage Page (Button),        */
744         0x19, 0x01,         /*          Usage Minimum (01h),        */
745         0x29, 0x05,         /*          Usage Maximum (05h),        */
746         0x75, 0x01,         /*          Report Size (1),            */
747         0x95, 0x05,         /*          Report Count (5),           */
748         0x81, 0x02,         /*          Input (Variable),           */
749         0x75, 0x01,         /*          Report Size (1),            */
750         0x95, 0x03,         /*          Report Count (3),           */
751         0x81, 0x01,         /*          Input (Constant),           */
752         0x05, 0x0D,         /*          Usage Page (Digitizer),     */
753         0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
754         0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
755         0x75, 0x08,         /*          Report Size (8),            */
756         0x95, 0x01,         /*          Report Count (1),           */
757         0x81, 0x02,         /*          Input (Variable),           */
758         0x25, 0x01,         /*          Logical Maximum (1),        */
759         0x09, 0x44,         /*          Usage (Barrel Switch),      */
760         0x75, 0x01,         /*          Report Size (1),            */
761         0x95, 0x01,         /*          Report Count (1),           */
762         0x81, 0x02,         /*          Input (Variable),           */
763         0x05, 0x01,         /*          Usage Page (Desktop),       */
764         0x09, 0x30,         /*          Usage (X),                  */
765         0x09, 0x31,         /*          Usage (Y),                  */
766         0x75, 0x01,         /*          Report Size (1),            */
767         0x95, 0x02,         /*          Report Count (2),           */
768         0x81, 0x02,         /*          Input (Variable),           */
769         0x75, 0x01,         /*          Report Size (1),            */
770         0x95, 0x0B,         /*          Report Count (11),          */
771         0x81, 0x01,         /*          Input (Constant),           */
772         0x05, 0x01,         /*          Usage Page (Desktop),       */
773         0x09, 0x38,         /*          Usage (Wheel),              */
774         0x15, 0xFF,         /*          Logical Minimum (-1),       */
775         0x25, 0x01,         /*          Logical Maximum (1),        */
776         0x75, 0x02,         /*          Report Size (2),            */
777         0x95, 0x01,         /*          Report Count (1),           */
778         0x81, 0x06,         /*          Input (Variable, Relative), */
779         0xC0,               /*      End Collection,                 */
780         0xC0                /*  End Collection                      */
781 };
782 const size_t uclogic_rdesc_ugee_g5_frame_size =
783                         sizeof(uclogic_rdesc_ugee_g5_frame_arr);
784
785 /* Fixed report descriptor for XP-Pen Deco 01 frame controls */
786 const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = {
787         0x05, 0x01, /*  Usage Page (Desktop),               */
788         0x09, 0x07, /*  Usage (Keypad),                     */
789         0xA1, 0x01, /*  Collection (Application),           */
790         0x85, 0x06, /*      Report ID (6),                  */
791         0x14,       /*      Logical Minimum (0),            */
792         0x25, 0x01, /*      Logical Maximum (1),            */
793         0x75, 0x01, /*      Report Size (1),                */
794         0x05, 0x0D, /*      Usage Page (Digitizer),         */
795         0x09, 0x39, /*      Usage (Tablet Function Keys),   */
796         0xA0,       /*      Collection (Physical),          */
797         0x05, 0x09, /*          Usage Page (Button),        */
798         0x19, 0x01, /*          Usage Minimum (01h),        */
799         0x29, 0x08, /*          Usage Maximum (08h),        */
800         0x95, 0x08, /*          Report Count (8),           */
801         0x81, 0x02, /*          Input (Variable),           */
802         0x05, 0x0D, /*          Usage Page (Digitizer),     */
803         0x09, 0x44, /*          Usage (Barrel Switch),      */
804         0x95, 0x01, /*          Report Count (1),           */
805         0x81, 0x02, /*          Input (Variable),           */
806         0x05, 0x01, /*          Usage Page (Desktop),       */
807         0x09, 0x30, /*          Usage (X),                  */
808         0x09, 0x31, /*          Usage (Y),                  */
809         0x95, 0x02, /*          Report Count (2),           */
810         0x81, 0x02, /*          Input (Variable),           */
811         0x95, 0x15, /*          Report Count (21),          */
812         0x81, 0x01, /*          Input (Constant),           */
813         0xC0,       /*      End Collection,                 */
814         0xC0        /*  End Collection                      */
815 };
816
817 const size_t uclogic_rdesc_xppen_deco01_frame_size =
818                         sizeof(uclogic_rdesc_xppen_deco01_frame_arr);
819
820 /**
821  * uclogic_rdesc_template_apply() - apply report descriptor parameters to a
822  * report descriptor template, creating a report descriptor. Copies the
823  * template over to the new report descriptor and replaces every occurrence of
824  * UCLOGIC_RDESC_PH_HEAD, followed by an index byte, with the value from the
825  * parameter list at that index.
826  *
827  * @template_ptr:       Pointer to the template buffer.
828  * @template_size:      Size of the template buffer.
829  * @param_list:         List of template parameters.
830  * @param_num:          Number of parameters in the list.
831  *
832  * Returns:
833  *      Kmalloc-allocated pointer to the created report descriptor,
834  *      or NULL if allocation failed.
835  */
836 __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
837                                    size_t template_size,
838                                    const s32 *param_list,
839                                    size_t param_num)
840 {
841         static const __u8 head[] = {UCLOGIC_RDESC_PH_HEAD};
842         __u8 *rdesc_ptr;
843         __u8 *p;
844         s32 v;
845
846         rdesc_ptr = kmemdup(template_ptr, template_size, GFP_KERNEL);
847         if (rdesc_ptr == NULL)
848                 return NULL;
849
850         for (p = rdesc_ptr; p + sizeof(head) < rdesc_ptr + template_size;) {
851                 if (memcmp(p, head, sizeof(head)) == 0 &&
852                     p[sizeof(head)] < param_num) {
853                         v = param_list[p[sizeof(head)]];
854                         put_unaligned(cpu_to_le32(v), (s32 *)p);
855                         p += sizeof(head) + 1;
856                 } else {
857                         p++;
858                 }
859         }
860
861         return rdesc_ptr;
862 }