Linux Audio

Check our new training course

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