Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  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
 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, 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
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, 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
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, 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
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, 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
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, 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
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, 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
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_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
585const 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 */
589const __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
641const 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 */
691const __u8 uclogic_rdesc_buttonpad_v1_arr[] = {
692	UCLOGIC_RDESC_BUTTONPAD_BYTES(20)
693};
694const size_t uclogic_rdesc_buttonpad_v1_size =
695			sizeof(uclogic_rdesc_buttonpad_v1_arr);
696
697/* Fixed report descriptor for (tweaked) v2 buttonpad reports */
698const __u8 uclogic_rdesc_buttonpad_v2_arr[] = {
699	UCLOGIC_RDESC_BUTTONPAD_BYTES(52)
700};
701const size_t uclogic_rdesc_buttonpad_v2_size =
702			sizeof(uclogic_rdesc_buttonpad_v2_arr);
703
704/* Fixed report descriptor for Ugee EX07 buttonpad */
705const __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};
728const 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 */
732const __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};
782const 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 */
786const __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
817const 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}