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
63const 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
140const 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
217const 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
265const 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
342const 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
388const 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
428const 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
454const 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
503const 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
531const 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 */
535const __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
585const 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 */
589const __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
651const 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 */
702const __u8 uclogic_rdesc_v1_frame_arr[] = {
703	UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8)
704};
705const 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 */
709const __u8 uclogic_rdesc_v2_frame_buttons_arr[] = {
710	UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID,
711					  12)
712};
713const 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 */
717const __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};
761const 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 */
765const __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};
809const 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 */
813const __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};
859const size_t uclogic_rdesc_v2_frame_dial_size =
860			sizeof(uclogic_rdesc_v2_frame_dial_arr);
861
862const __u8 uclogic_ugee_v2_probe_arr[] = {
863	0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
864};
865const size_t uclogic_ugee_v2_probe_size = sizeof(uclogic_ugee_v2_probe_arr);
866const int uclogic_ugee_v2_probe_endpoint = 0x03;
867
868/* Fixed report descriptor template for UGEE v2 pen reports */
869const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[] = {
870	0x05, 0x0d,         /*  Usage Page (Digitizers),                */
871	0x09, 0x01,         /*  Usage (Digitizer),                      */
872	0xa1, 0x01,         /*  Collection (Application),               */
873	0x85, 0x02,         /*      Report ID (2),                      */
874	0x09, 0x20,         /*      Usage (Stylus),                     */
875	0xa1, 0x00,         /*      Collection (Physical),              */
876	0x09, 0x42,         /*          Usage (Tip Switch),             */
877	0x09, 0x44,         /*          Usage (Barrel Switch),          */
878	0x09, 0x46,         /*          Usage (Tablet Pick),            */
879	0x75, 0x01,         /*          Report Size (1),                */
880	0x95, 0x03,         /*          Report Count (3),               */
881	0x14,               /*          Logical Minimum (0),            */
882	0x25, 0x01,         /*          Logical Maximum (1),            */
883	0x81, 0x02,         /*          Input (Variable),               */
884	0x95, 0x02,         /*          Report Count (2),               */
885	0x81, 0x03,         /*          Input (Constant, Variable),     */
886	0x09, 0x32,         /*          Usage (In Range),               */
887	0x95, 0x01,         /*          Report Count (1),               */
888	0x81, 0x02,         /*          Input (Variable),               */
889	0x95, 0x02,         /*          Report Count (2),               */
890	0x81, 0x03,         /*          Input (Constant, Variable),     */
891	0x75, 0x10,         /*          Report Size (16),               */
892	0x95, 0x01,         /*          Report Count (1),               */
893	0x35, 0x00,         /*          Physical Minimum (0),           */
894	0xa4,               /*          Push,                           */
895	0x05, 0x01,         /*          Usage Page (Desktop),           */
896	0x09, 0x30,         /*          Usage (X),                      */
897	0x65, 0x13,         /*          Unit (Inch),                    */
898	0x55, 0x0d,         /*          Unit Exponent (-3),             */
899	0x27, UCLOGIC_RDESC_PEN_PH(X_LM),
900			    /*          Logical Maximum (PLACEHOLDER),  */
901	0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
902			    /*          Physical Maximum (PLACEHOLDER), */
903	0x81, 0x02,         /*          Input (Variable),               */
904	0x09, 0x31,         /*          Usage (Y),                      */
905	0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
906			    /*          Logical Maximum (PLACEHOLDER),  */
907	0x47, UCLOGIC_RDESC_PEN_PH(Y_PM),
908			    /*          Physical Maximum (PLACEHOLDER), */
909	0x81, 0x02,         /*          Input (Variable),               */
910	0xb4,               /*          Pop,                            */
911	0x09, 0x30,         /*          Usage (Tip Pressure),           */
912	0x45, 0x00,         /*          Physical Maximum (0),           */
913	0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
914			    /*          Logical Maximum (PLACEHOLDER),  */
915	0x75, 0x0D,         /*          Report Size (13),               */
916	0x95, 0x01,         /*          Report Count (1),               */
917	0x81, 0x02,         /*          Input (Variable),               */
918	0x75, 0x01,         /*          Report Size (1),                */
919	0x95, 0x03,         /*          Report Count (3),               */
920	0x81, 0x01,         /*          Input (Constant),               */
921	0x09, 0x3d,         /*          Usage (X Tilt),                 */
922	0x35, 0xC3,         /*          Physical Minimum (-61),         */
923	0x45, 0x3C,         /*          Physical Maximum (60),          */
924	0x15, 0xC3,         /*          Logical Minimum (-61),          */
925	0x25, 0x3C,         /*          Logical Maximum (60),           */
926	0x75, 0x08,         /*          Report Size (8),                */
927	0x95, 0x01,         /*          Report Count (1),               */
928	0x81, 0x02,         /*          Input (Variable),               */
929	0x09, 0x3e,         /*          Usage (Y Tilt),                 */
930	0x35, 0xC3,         /*          Physical Minimum (-61),         */
931	0x45, 0x3C,         /*          Physical Maximum (60),          */
932	0x15, 0xC3,         /*          Logical Minimum (-61),          */
933	0x25, 0x3C,         /*          Logical Maximum (60),           */
934	0x81, 0x02,         /*          Input (Variable),               */
935	0xc0,               /*      End Collection,                     */
936	0xc0,               /*  End Collection                          */
937};
938const size_t uclogic_rdesc_ugee_v2_pen_template_size =
939			sizeof(uclogic_rdesc_ugee_v2_pen_template_arr);
940
941/* Fixed report descriptor template for UGEE v2 frame reports (buttons only) */
942const __u8 uclogic_rdesc_ugee_v2_frame_btn_template_arr[] = {
943	0x05, 0x01,         /*  Usage Page (Desktop),                   */
944	0x09, 0x07,         /*  Usage (Keypad),                         */
945	0xA1, 0x01,         /*  Collection (Application),               */
946	0x85, UCLOGIC_RDESC_V1_FRAME_ID,
947			    /*      Report ID,                          */
948	0x05, 0x0D,         /*      Usage Page (Digitizer),             */
949	0x09, 0x39,         /*      Usage (Tablet Function Keys),       */
950	0xA0,               /*      Collection (Physical),              */
951	0x75, 0x01,         /*          Report Size (1),                */
952	0x95, 0x08,         /*          Report Count (8),               */
953	0x81, 0x01,         /*          Input (Constant),               */
954	0x05, 0x09,         /*          Usage Page (Button),            */
955	0x19, 0x01,         /*          Usage Minimum (01h),            */
956	UCLOGIC_RDESC_FRAME_PH_BTN,
957			    /*          Usage Maximum (PLACEHOLDER),    */
958	0x95, 0x0A,         /*          Report Count (10),              */
959	0x14,               /*          Logical Minimum (0),            */
960	0x25, 0x01,         /*          Logical Maximum (1),            */
961	0x81, 0x02,         /*          Input (Variable),               */
962	0x95, 0x46,         /*          Report Count (70),              */
963	0x81, 0x01,         /*          Input (Constant),               */
964	0xC0,               /*      End Collection,                     */
965	0xC0                /*  End Collection                          */
966};
967const size_t uclogic_rdesc_ugee_v2_frame_btn_template_size =
968			sizeof(uclogic_rdesc_ugee_v2_frame_btn_template_arr);
969
970/* Fixed report descriptor template for UGEE v2 frame reports (dial) */
971const __u8 uclogic_rdesc_ugee_v2_frame_dial_template_arr[] = {
972	0x05, 0x01,         /*  Usage Page (Desktop),                   */
973	0x09, 0x07,         /*  Usage (Keypad),                         */
974	0xA1, 0x01,         /*  Collection (Application),               */
975	0x85, UCLOGIC_RDESC_V1_FRAME_ID,
976			    /*      Report ID,                          */
977	0x05, 0x0D,         /*      Usage Page (Digitizer),             */
978	0x09, 0x39,         /*      Usage (Tablet Function Keys),       */
979	0xA0,               /*      Collection (Physical),              */
980	0x75, 0x01,         /*          Report Size (1),                */
981	0x95, 0x08,         /*          Report Count (8),               */
982	0x81, 0x01,         /*          Input (Constant),               */
983	0x05, 0x09,         /*          Usage Page (Button),            */
984	0x19, 0x01,         /*          Usage Minimum (01h),            */
985	UCLOGIC_RDESC_FRAME_PH_BTN,
986			    /*          Usage Maximum (PLACEHOLDER),    */
987	0x95, 0x0A,         /*          Report Count (10),              */
988	0x14,               /*          Logical Minimum (0),            */
989	0x25, 0x01,         /*          Logical Maximum (1),            */
990	0x81, 0x02,         /*          Input (Variable),               */
991	0x95, 0x06,         /*          Report Count (6),               */
992	0x81, 0x01,         /*          Input (Constant),               */
993	0x75, 0x08,         /*          Report Size (8),                */
994	0x95, 0x03,         /*          Report Count (3),               */
995	0x81, 0x01,         /*          Input (Constant),               */
996	0x05, 0x01,         /*          Usage Page (Desktop),           */
997	0x09, 0x38,         /*          Usage (Wheel),                  */
998	0x95, 0x01,         /*          Report Count (1),               */
999	0x15, 0xFF,         /*          Logical Minimum (-1),           */
1000	0x25, 0x01,         /*          Logical Maximum (1),            */
1001	0x81, 0x06,         /*          Input (Variable, Relative),     */
1002	0x95, 0x02,         /*          Report Count (2),               */
1003	0x81, 0x01,         /*          Input (Constant),               */
1004	0xC0,               /*      End Collection,                     */
1005	0xC0                /*  End Collection                          */
1006};
1007const size_t uclogic_rdesc_ugee_v2_frame_dial_template_size =
1008			sizeof(uclogic_rdesc_ugee_v2_frame_dial_template_arr);
1009
1010/* Fixed report descriptor template for UGEE v2 frame reports (mouse) */
1011const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[] = {
1012	0x05, 0x01,         /*  Usage Page (Desktop),                   */
1013	0x09, 0x02,         /*  Usage (Mouse),                          */
1014	0xA1, 0x01,         /*  Collection (Application),               */
1015	0x85, 0x01,         /*      Report ID (1),                      */
1016	0x05, 0x01,         /*      Usage Page (Pointer),               */
1017	0xA0,               /*      Collection (Physical),              */
1018	0x75, 0x01,         /*          Report Size (1),                */
1019	0x95, 0x02,         /*          Report Count (2),               */
1020	0x05, 0x09,         /*          Usage Page (Button),            */
1021	0x19, 0x01,         /*          Usage Minimum (01h),            */
1022	0x29, 0x02,         /*          Usage Maximum (02h),            */
1023	0x14,               /*          Logical Minimum (0),            */
1024	0x25, 0x01,         /*          Logical Maximum (1),            */
1025	0x81, 0x02,         /*          Input (Variable),               */
1026	0x95, 0x06,         /*          Report Count (6),               */
1027	0x81, 0x01,         /*          Input (Constant),               */
1028	0x05, 0x01,         /*          Usage Page (Generic Desktop),   */
1029	0x09, 0x30,         /*          Usage (X),                      */
1030	0x09, 0x31,         /*          Usage (Y),                      */
1031	0x75, 0x10,         /*          Report Size (16),               */
1032	0x95, 0x02,         /*          Report Count (2),               */
1033	0x16, 0x00, 0x80,   /*          Logical Minimum (-32768),       */
1034	0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),        */
1035	0x81, 0x06,         /*          Input (Variable, Relative),     */
1036	0x95, 0x01,         /*          Report Count (1),               */
1037	0x81, 0x01,         /*          Input (Constant),               */
1038	0xC0,               /*      End Collection,                     */
1039	0xC0                /*  End Collection                          */
1040};
1041const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size =
1042			sizeof(uclogic_rdesc_ugee_v2_frame_mouse_template_arr);
1043
1044/* Fixed report descriptor template for UGEE v2 battery reports */
1045const __u8 uclogic_rdesc_ugee_v2_battery_template_arr[] = {
1046	0x05, 0x01,         /*  Usage Page (Desktop),                   */
1047	0x09, 0x07,         /*  Usage (Keypad),                         */
1048	0xA1, 0x01,         /*  Collection (Application),               */
1049	0x85, UCLOGIC_RDESC_UGEE_V2_BATTERY_ID,
1050			    /*      Report ID,                          */
1051	0x75, 0x08,         /*      Report Size (8),                    */
1052	0x95, 0x02,         /*      Report Count (2),                   */
1053	0x81, 0x01,         /*      Input (Constant),                   */
1054	0x05, 0x84,         /*      Usage Page (Power Device),          */
1055	0x05, 0x85,         /*      Usage Page (Battery System),        */
1056	0x09, 0x65,         /*      Usage Page (AbsoluteStateOfCharge), */
1057	0x75, 0x08,         /*      Report Size (8),                    */
1058	0x95, 0x01,         /*      Report Count (1),                   */
1059	0x15, 0x00,         /*      Logical Minimum (0),                */
1060	0x26, 0xff, 0x00,   /*      Logical Maximum (255),              */
1061	0x81, 0x02,         /*      Input (Variable),                   */
1062	0x75, 0x01,         /*      Report Size (1),                    */
1063	0x95, 0x01,         /*      Report Count (1),                   */
1064	0x15, 0x00,         /*      Logical Minimum (0),                */
1065	0x25, 0x01,         /*      Logical Maximum (1),                */
1066	0x09, 0x44,         /*      Usage Page (Charging),              */
1067	0x81, 0x02,         /*      Input (Variable),                   */
1068	0x95, 0x07,         /*      Report Count (7),                   */
1069	0x81, 0x01,         /*      Input (Constant),                   */
1070	0x75, 0x08,         /*      Report Size (8),                    */
1071	0x95, 0x07,         /*      Report Count (7),                   */
1072	0x81, 0x01,         /*      Input (Constant),                   */
1073	0xC0                /*  End Collection                          */
1074};
1075const size_t uclogic_rdesc_ugee_v2_battery_template_size =
1076			sizeof(uclogic_rdesc_ugee_v2_battery_template_arr);
1077
1078/* Fixed report descriptor for Ugee EX07 frame */
1079const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
1080	0x05, 0x01,             /*  Usage Page (Desktop),                   */
1081	0x09, 0x07,             /*  Usage (Keypad),                         */
1082	0xA1, 0x01,             /*  Collection (Application),               */
1083	0x85, 0x06,             /*      Report ID (6),                      */
1084	0x05, 0x0D,             /*      Usage Page (Digitizer),             */
1085	0x09, 0x39,             /*      Usage (Tablet Function Keys),       */
1086	0xA0,                   /*      Collection (Physical),              */
1087	0x05, 0x09,             /*          Usage Page (Button),            */
1088	0x75, 0x01,             /*          Report Size (1),                */
1089	0x19, 0x03,             /*          Usage Minimum (03h),            */
1090	0x29, 0x06,             /*          Usage Maximum (06h),            */
1091	0x95, 0x04,             /*          Report Count (4),               */
1092	0x81, 0x02,             /*          Input (Variable),               */
1093	0x95, 0x1A,             /*          Report Count (26),              */
1094	0x81, 0x03,             /*          Input (Constant, Variable),     */
1095	0x19, 0x01,             /*          Usage Minimum (01h),            */
1096	0x29, 0x02,             /*          Usage Maximum (02h),            */
1097	0x95, 0x02,             /*          Report Count (2),               */
1098	0x81, 0x02,             /*          Input (Variable),               */
1099	0xC0,                   /*      End Collection,                     */
1100	0xC0                    /*  End Collection                          */
1101};
1102const size_t uclogic_rdesc_ugee_ex07_frame_size =
1103			sizeof(uclogic_rdesc_ugee_ex07_frame_arr);
1104
1105/* Fixed report descriptor for Ugee G5 frame controls */
1106const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = {
1107	0x05, 0x01,         /*  Usage Page (Desktop),               */
1108	0x09, 0x07,         /*  Usage (Keypad),                     */
1109	0xA1, 0x01,         /*  Collection (Application),           */
1110	0x85, 0x06,         /*      Report ID (6),                  */
1111	0x05, 0x0D,         /*      Usage Page (Digitizer),         */
1112	0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
1113	0xA0,               /*      Collection (Physical),          */
1114	0x14,               /*          Logical Minimum (0),        */
1115	0x25, 0x01,         /*          Logical Maximum (1),        */
1116	0x05, 0x01,         /*          Usage Page (Desktop),       */
1117	0x05, 0x09,         /*          Usage Page (Button),        */
1118	0x19, 0x01,         /*          Usage Minimum (01h),        */
1119	0x29, 0x05,         /*          Usage Maximum (05h),        */
1120	0x75, 0x01,         /*          Report Size (1),            */
1121	0x95, 0x05,         /*          Report Count (5),           */
1122	0x81, 0x02,         /*          Input (Variable),           */
1123	0x75, 0x01,         /*          Report Size (1),            */
1124	0x95, 0x03,         /*          Report Count (3),           */
1125	0x81, 0x01,         /*          Input (Constant),           */
1126	0x05, 0x0D,         /*          Usage Page (Digitizer),     */
1127	0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
1128	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
1129	0x75, 0x08,         /*          Report Size (8),            */
1130	0x95, 0x01,         /*          Report Count (1),           */
1131	0x81, 0x02,         /*          Input (Variable),           */
1132	0x25, 0x01,         /*          Logical Maximum (1),        */
1133	0x09, 0x44,         /*          Usage (Barrel Switch),      */
1134	0x75, 0x01,         /*          Report Size (1),            */
1135	0x95, 0x01,         /*          Report Count (1),           */
1136	0x81, 0x02,         /*          Input (Variable),           */
1137	0x05, 0x01,         /*          Usage Page (Desktop),       */
1138	0x09, 0x30,         /*          Usage (X),                  */
1139	0x09, 0x31,         /*          Usage (Y),                  */
1140	0x75, 0x01,         /*          Report Size (1),            */
1141	0x95, 0x02,         /*          Report Count (2),           */
1142	0x81, 0x02,         /*          Input (Variable),           */
1143	0x75, 0x01,         /*          Report Size (1),            */
1144	0x95, 0x0B,         /*          Report Count (11),          */
1145	0x81, 0x01,         /*          Input (Constant),           */
1146	0x05, 0x01,         /*          Usage Page (Desktop),       */
1147	0x09, 0x38,         /*          Usage (Wheel),              */
1148	0x15, 0xFF,         /*          Logical Minimum (-1),       */
1149	0x25, 0x01,         /*          Logical Maximum (1),        */
1150	0x75, 0x02,         /*          Report Size (2),            */
1151	0x95, 0x01,         /*          Report Count (1),           */
1152	0x81, 0x06,         /*          Input (Variable, Relative), */
1153	0xC0,               /*      End Collection,                 */
1154	0xC0                /*  End Collection                      */
1155};
1156const size_t uclogic_rdesc_ugee_g5_frame_size =
1157			sizeof(uclogic_rdesc_ugee_g5_frame_arr);
1158
1159/* Fixed report descriptor for XP-Pen Deco 01 frame controls */
1160const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = {
1161	0x05, 0x01, /*  Usage Page (Desktop),               */
1162	0x09, 0x07, /*  Usage (Keypad),                     */
1163	0xA1, 0x01, /*  Collection (Application),           */
1164	0x85, 0x06, /*      Report ID (6),                  */
1165	0x14,       /*      Logical Minimum (0),            */
1166	0x25, 0x01, /*      Logical Maximum (1),            */
1167	0x75, 0x01, /*      Report Size (1),                */
1168	0x05, 0x0D, /*      Usage Page (Digitizer),         */
1169	0x09, 0x39, /*      Usage (Tablet Function Keys),   */
1170	0xA0,       /*      Collection (Physical),          */
1171	0x05, 0x09, /*          Usage Page (Button),        */
1172	0x19, 0x01, /*          Usage Minimum (01h),        */
1173	0x29, 0x08, /*          Usage Maximum (08h),        */
1174	0x95, 0x08, /*          Report Count (8),           */
1175	0x81, 0x02, /*          Input (Variable),           */
1176	0x05, 0x0D, /*          Usage Page (Digitizer),     */
1177	0x09, 0x44, /*          Usage (Barrel Switch),      */
1178	0x95, 0x01, /*          Report Count (1),           */
1179	0x81, 0x02, /*          Input (Variable),           */
1180	0x05, 0x01, /*          Usage Page (Desktop),       */
1181	0x09, 0x30, /*          Usage (X),                  */
1182	0x09, 0x31, /*          Usage (Y),                  */
1183	0x95, 0x02, /*          Report Count (2),           */
1184	0x81, 0x02, /*          Input (Variable),           */
1185	0x95, 0x15, /*          Report Count (21),          */
1186	0x81, 0x01, /*          Input (Constant),           */
1187	0xC0,       /*      End Collection,                 */
1188	0xC0        /*  End Collection                      */
1189};
1190
1191const size_t uclogic_rdesc_xppen_deco01_frame_size =
1192			sizeof(uclogic_rdesc_xppen_deco01_frame_arr);
1193
1194/**
1195 * uclogic_rdesc_template_apply() - apply report descriptor parameters to a
1196 * report descriptor template, creating a report descriptor. Copies the
1197 * template over to the new report descriptor and replaces every occurrence of
1198 * the template placeholders, followed by an index byte, with the value from the
1199 * parameter list at that index.
1200 *
1201 * @template_ptr:	Pointer to the template buffer.
1202 * @template_size:	Size of the template buffer.
1203 * @param_list:		List of template parameters.
1204 * @param_num:		Number of parameters in the list.
1205 *
1206 * Returns:
1207 *	Kmalloc-allocated pointer to the created report descriptor,
1208 *	or NULL if allocation failed.
1209 */
1210__u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
1211				   size_t template_size,
1212				   const s32 *param_list,
1213				   size_t param_num)
1214{
1215	static const __u8 btn_head[] = {UCLOGIC_RDESC_FRAME_PH_BTN_HEAD};
1216	static const __u8 pen_head[] = {UCLOGIC_RDESC_PEN_PH_HEAD};
1217	__u8 *rdesc_ptr;
1218	__u8 *p;
1219	s32 v;
1220
1221	rdesc_ptr = kmemdup(template_ptr, template_size, GFP_KERNEL);
1222	if (rdesc_ptr == NULL)
1223		return NULL;
1224
1225	for (p = rdesc_ptr; p + sizeof(btn_head) < rdesc_ptr + template_size;) {
1226		if (p + sizeof(pen_head) < rdesc_ptr + template_size &&
1227		    memcmp(p, pen_head, sizeof(pen_head)) == 0 &&
1228		    p[sizeof(pen_head)] < param_num) {
1229			v = param_list[p[sizeof(pen_head)]];
1230			put_unaligned((__force u32)cpu_to_le32(v), (s32 *)p);
1231			p += sizeof(pen_head) + 1;
1232		} else if (memcmp(p, btn_head, sizeof(btn_head)) == 0 &&
1233			   p[sizeof(btn_head)] < param_num) {
1234			v = param_list[p[sizeof(btn_head)]];
1235			put_unaligned((__u8)0x2A, p); /* Usage Maximum */
1236			put_unaligned((__force u16)cpu_to_le16(v), (s16 *)(p + 1));
1237			p += sizeof(btn_head) + 1;
1238		} else {
1239			p++;
1240		}
1241	}
1242
1243	return rdesc_ptr;
1244}
1245