1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * HID driver for UC-Logic devices not fully compliant with HID standard 4 * - original and fixed report descriptors 5 * 6 * Copyright (c) 2010-2017 Nikolai Kondrashov 7 * Copyright (c) 2013 Martin Rusko 8 */ 9 10 /* 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License as published by the Free 13 * Software Foundation; either version 2 of the License, or (at your option) 14 * any later version. 15 */ 16 17 #include "hid-uclogic-rdesc.h" 18 #include <linux/slab.h> 19 #include <asm/unaligned.h> 20 21 /* Fixed WP4030U report descriptor */ 22 __u8 uclogic_rdesc_wp4030u_fixed_arr[] = { 23 0x05, 0x0D, /* Usage Page (Digitizer), */ 24 0x09, 0x01, /* Usage (Digitizer), */ 25 0xA1, 0x01, /* Collection (Application), */ 26 0x85, 0x09, /* Report ID (9), */ 27 0x09, 0x20, /* Usage (Stylus), */ 28 0xA0, /* Collection (Physical), */ 29 0x75, 0x01, /* Report Size (1), */ 30 0x09, 0x42, /* Usage (Tip Switch), */ 31 0x09, 0x44, /* Usage (Barrel Switch), */ 32 0x09, 0x46, /* Usage (Tablet Pick), */ 33 0x14, /* Logical Minimum (0), */ 34 0x25, 0x01, /* Logical Maximum (1), */ 35 0x95, 0x03, /* Report Count (3), */ 36 0x81, 0x02, /* Input (Variable), */ 37 0x95, 0x05, /* Report Count (5), */ 38 0x81, 0x01, /* Input (Constant), */ 39 0x75, 0x10, /* Report Size (16), */ 40 0x95, 0x01, /* Report Count (1), */ 41 0x14, /* Logical Minimum (0), */ 42 0xA4, /* Push, */ 43 0x05, 0x01, /* Usage Page (Desktop), */ 44 0x55, 0xFD, /* Unit Exponent (-3), */ 45 0x65, 0x13, /* Unit (Inch), */ 46 0x34, /* Physical Minimum (0), */ 47 0x09, 0x30, /* Usage (X), */ 48 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */ 49 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 50 0x81, 0x02, /* Input (Variable), */ 51 0x09, 0x31, /* Usage (Y), */ 52 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */ 53 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 54 0x81, 0x02, /* Input (Variable), */ 55 0xB4, /* Pop, */ 56 0x09, 0x30, /* Usage (Tip Pressure), */ 57 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 58 0x81, 0x02, /* Input (Variable), */ 59 0xC0, /* End Collection, */ 60 0xC0 /* End Collection */ 61 }; 62 63 const size_t uclogic_rdesc_wp4030u_fixed_size = 64 sizeof(uclogic_rdesc_wp4030u_fixed_arr); 65 66 /* Fixed WP5540U report descriptor */ 67 __u8 uclogic_rdesc_wp5540u_fixed_arr[] = { 68 0x05, 0x0D, /* Usage Page (Digitizer), */ 69 0x09, 0x01, /* Usage (Digitizer), */ 70 0xA1, 0x01, /* Collection (Application), */ 71 0x85, 0x09, /* Report ID (9), */ 72 0x09, 0x20, /* Usage (Stylus), */ 73 0xA0, /* Collection (Physical), */ 74 0x75, 0x01, /* Report Size (1), */ 75 0x09, 0x42, /* Usage (Tip Switch), */ 76 0x09, 0x44, /* Usage (Barrel Switch), */ 77 0x09, 0x46, /* Usage (Tablet Pick), */ 78 0x14, /* Logical Minimum (0), */ 79 0x25, 0x01, /* Logical Maximum (1), */ 80 0x95, 0x03, /* Report Count (3), */ 81 0x81, 0x02, /* Input (Variable), */ 82 0x95, 0x05, /* Report Count (5), */ 83 0x81, 0x01, /* Input (Constant), */ 84 0x75, 0x10, /* Report Size (16), */ 85 0x95, 0x01, /* Report Count (1), */ 86 0x14, /* Logical Minimum (0), */ 87 0xA4, /* Push, */ 88 0x05, 0x01, /* Usage Page (Desktop), */ 89 0x55, 0xFD, /* Unit Exponent (-3), */ 90 0x65, 0x13, /* Unit (Inch), */ 91 0x34, /* Physical Minimum (0), */ 92 0x09, 0x30, /* Usage (X), */ 93 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */ 94 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 95 0x81, 0x02, /* Input (Variable), */ 96 0x09, 0x31, /* Usage (Y), */ 97 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */ 98 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 99 0x81, 0x02, /* Input (Variable), */ 100 0xB4, /* Pop, */ 101 0x09, 0x30, /* Usage (Tip Pressure), */ 102 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 103 0x81, 0x02, /* Input (Variable), */ 104 0xC0, /* End Collection, */ 105 0xC0, /* End Collection, */ 106 0x05, 0x01, /* Usage Page (Desktop), */ 107 0x09, 0x02, /* Usage (Mouse), */ 108 0xA1, 0x01, /* Collection (Application), */ 109 0x85, 0x08, /* Report ID (8), */ 110 0x09, 0x01, /* Usage (Pointer), */ 111 0xA0, /* Collection (Physical), */ 112 0x75, 0x01, /* Report Size (1), */ 113 0x05, 0x09, /* Usage Page (Button), */ 114 0x19, 0x01, /* Usage Minimum (01h), */ 115 0x29, 0x03, /* Usage Maximum (03h), */ 116 0x14, /* Logical Minimum (0), */ 117 0x25, 0x01, /* Logical Maximum (1), */ 118 0x95, 0x03, /* Report Count (3), */ 119 0x81, 0x02, /* Input (Variable), */ 120 0x95, 0x05, /* Report Count (5), */ 121 0x81, 0x01, /* Input (Constant), */ 122 0x05, 0x01, /* Usage Page (Desktop), */ 123 0x75, 0x08, /* Report Size (8), */ 124 0x09, 0x30, /* Usage (X), */ 125 0x09, 0x31, /* Usage (Y), */ 126 0x15, 0x81, /* Logical Minimum (-127), */ 127 0x25, 0x7F, /* Logical Maximum (127), */ 128 0x95, 0x02, /* Report Count (2), */ 129 0x81, 0x06, /* Input (Variable, Relative), */ 130 0x09, 0x38, /* Usage (Wheel), */ 131 0x15, 0xFF, /* Logical Minimum (-1), */ 132 0x25, 0x01, /* Logical Maximum (1), */ 133 0x95, 0x01, /* Report Count (1), */ 134 0x81, 0x06, /* Input (Variable, Relative), */ 135 0x81, 0x01, /* Input (Constant), */ 136 0xC0, /* End Collection, */ 137 0xC0 /* End Collection */ 138 }; 139 140 const size_t uclogic_rdesc_wp5540u_fixed_size = 141 sizeof(uclogic_rdesc_wp5540u_fixed_arr); 142 143 /* Fixed WP8060U report descriptor */ 144 __u8 uclogic_rdesc_wp8060u_fixed_arr[] = { 145 0x05, 0x0D, /* Usage Page (Digitizer), */ 146 0x09, 0x01, /* Usage (Digitizer), */ 147 0xA1, 0x01, /* Collection (Application), */ 148 0x85, 0x09, /* Report ID (9), */ 149 0x09, 0x20, /* Usage (Stylus), */ 150 0xA0, /* Collection (Physical), */ 151 0x75, 0x01, /* Report Size (1), */ 152 0x09, 0x42, /* Usage (Tip Switch), */ 153 0x09, 0x44, /* Usage (Barrel Switch), */ 154 0x09, 0x46, /* Usage (Tablet Pick), */ 155 0x14, /* Logical Minimum (0), */ 156 0x25, 0x01, /* Logical Maximum (1), */ 157 0x95, 0x03, /* Report Count (3), */ 158 0x81, 0x02, /* Input (Variable), */ 159 0x95, 0x05, /* Report Count (5), */ 160 0x81, 0x01, /* Input (Constant), */ 161 0x75, 0x10, /* Report Size (16), */ 162 0x95, 0x01, /* Report Count (1), */ 163 0x14, /* Logical Minimum (0), */ 164 0xA4, /* Push, */ 165 0x05, 0x01, /* Usage Page (Desktop), */ 166 0x55, 0xFD, /* Unit Exponent (-3), */ 167 0x65, 0x13, /* Unit (Inch), */ 168 0x34, /* Physical Minimum (0), */ 169 0x09, 0x30, /* Usage (X), */ 170 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ 171 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 172 0x81, 0x02, /* Input (Variable), */ 173 0x09, 0x31, /* Usage (Y), */ 174 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ 175 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 176 0x81, 0x02, /* Input (Variable), */ 177 0xB4, /* Pop, */ 178 0x09, 0x30, /* Usage (Tip Pressure), */ 179 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 180 0x81, 0x02, /* Input (Variable), */ 181 0xC0, /* End Collection, */ 182 0xC0, /* End Collection, */ 183 0x05, 0x01, /* Usage Page (Desktop), */ 184 0x09, 0x02, /* Usage (Mouse), */ 185 0xA1, 0x01, /* Collection (Application), */ 186 0x85, 0x08, /* Report ID (8), */ 187 0x09, 0x01, /* Usage (Pointer), */ 188 0xA0, /* Collection (Physical), */ 189 0x75, 0x01, /* Report Size (1), */ 190 0x05, 0x09, /* Usage Page (Button), */ 191 0x19, 0x01, /* Usage Minimum (01h), */ 192 0x29, 0x03, /* Usage Maximum (03h), */ 193 0x14, /* Logical Minimum (0), */ 194 0x25, 0x01, /* Logical Maximum (1), */ 195 0x95, 0x03, /* Report Count (3), */ 196 0x81, 0x02, /* Input (Variable), */ 197 0x95, 0x05, /* Report Count (5), */ 198 0x81, 0x01, /* Input (Constant), */ 199 0x05, 0x01, /* Usage Page (Desktop), */ 200 0x75, 0x08, /* Report Size (8), */ 201 0x09, 0x30, /* Usage (X), */ 202 0x09, 0x31, /* Usage (Y), */ 203 0x15, 0x81, /* Logical Minimum (-127), */ 204 0x25, 0x7F, /* Logical Maximum (127), */ 205 0x95, 0x02, /* Report Count (2), */ 206 0x81, 0x06, /* Input (Variable, Relative), */ 207 0x09, 0x38, /* Usage (Wheel), */ 208 0x15, 0xFF, /* Logical Minimum (-1), */ 209 0x25, 0x01, /* Logical Maximum (1), */ 210 0x95, 0x01, /* Report Count (1), */ 211 0x81, 0x06, /* Input (Variable, Relative), */ 212 0x81, 0x01, /* Input (Constant), */ 213 0xC0, /* End Collection, */ 214 0xC0 /* End Collection */ 215 }; 216 217 const size_t uclogic_rdesc_wp8060u_fixed_size = 218 sizeof(uclogic_rdesc_wp8060u_fixed_arr); 219 220 /* Fixed WP1062 report descriptor */ 221 __u8 uclogic_rdesc_wp1062_fixed_arr[] = { 222 0x05, 0x0D, /* Usage Page (Digitizer), */ 223 0x09, 0x01, /* Usage (Digitizer), */ 224 0xA1, 0x01, /* Collection (Application), */ 225 0x85, 0x09, /* Report ID (9), */ 226 0x09, 0x20, /* Usage (Stylus), */ 227 0xA0, /* Collection (Physical), */ 228 0x75, 0x01, /* Report Size (1), */ 229 0x09, 0x42, /* Usage (Tip Switch), */ 230 0x09, 0x44, /* Usage (Barrel Switch), */ 231 0x09, 0x46, /* Usage (Tablet Pick), */ 232 0x14, /* Logical Minimum (0), */ 233 0x25, 0x01, /* Logical Maximum (1), */ 234 0x95, 0x03, /* Report Count (3), */ 235 0x81, 0x02, /* Input (Variable), */ 236 0x95, 0x04, /* Report Count (4), */ 237 0x81, 0x01, /* Input (Constant), */ 238 0x09, 0x32, /* Usage (In Range), */ 239 0x95, 0x01, /* Report Count (1), */ 240 0x81, 0x02, /* Input (Variable), */ 241 0x75, 0x10, /* Report Size (16), */ 242 0x95, 0x01, /* Report Count (1), */ 243 0x14, /* Logical Minimum (0), */ 244 0xA4, /* Push, */ 245 0x05, 0x01, /* Usage Page (Desktop), */ 246 0x55, 0xFD, /* Unit Exponent (-3), */ 247 0x65, 0x13, /* Unit (Inch), */ 248 0x34, /* Physical Minimum (0), */ 249 0x09, 0x30, /* Usage (X), */ 250 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ 251 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ 252 0x81, 0x02, /* Input (Variable), */ 253 0x09, 0x31, /* Usage (Y), */ 254 0x46, 0xB7, 0x19, /* Physical Maximum (6583), */ 255 0x26, 0x6E, 0x33, /* Logical Maximum (13166), */ 256 0x81, 0x02, /* Input (Variable), */ 257 0xB4, /* Pop, */ 258 0x09, 0x30, /* Usage (Tip Pressure), */ 259 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 260 0x81, 0x02, /* Input (Variable), */ 261 0xC0, /* End Collection, */ 262 0xC0 /* End Collection */ 263 }; 264 265 const size_t uclogic_rdesc_wp1062_fixed_size = 266 sizeof(uclogic_rdesc_wp1062_fixed_arr); 267 268 /* Fixed PF1209 report descriptor */ 269 __u8 uclogic_rdesc_pf1209_fixed_arr[] = { 270 0x05, 0x0D, /* Usage Page (Digitizer), */ 271 0x09, 0x01, /* Usage (Digitizer), */ 272 0xA1, 0x01, /* Collection (Application), */ 273 0x85, 0x09, /* Report ID (9), */ 274 0x09, 0x20, /* Usage (Stylus), */ 275 0xA0, /* Collection (Physical), */ 276 0x75, 0x01, /* Report Size (1), */ 277 0x09, 0x42, /* Usage (Tip Switch), */ 278 0x09, 0x44, /* Usage (Barrel Switch), */ 279 0x09, 0x46, /* Usage (Tablet Pick), */ 280 0x14, /* Logical Minimum (0), */ 281 0x25, 0x01, /* Logical Maximum (1), */ 282 0x95, 0x03, /* Report Count (3), */ 283 0x81, 0x02, /* Input (Variable), */ 284 0x95, 0x05, /* Report Count (5), */ 285 0x81, 0x01, /* Input (Constant), */ 286 0x75, 0x10, /* Report Size (16), */ 287 0x95, 0x01, /* Report Count (1), */ 288 0x14, /* Logical Minimum (0), */ 289 0xA4, /* Push, */ 290 0x05, 0x01, /* Usage Page (Desktop), */ 291 0x55, 0xFD, /* Unit Exponent (-3), */ 292 0x65, 0x13, /* Unit (Inch), */ 293 0x34, /* Physical Minimum (0), */ 294 0x09, 0x30, /* Usage (X), */ 295 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */ 296 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 297 0x81, 0x02, /* Input (Variable), */ 298 0x09, 0x31, /* Usage (Y), */ 299 0x46, 0x28, 0x23, /* Physical Maximum (9000), */ 300 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 301 0x81, 0x02, /* Input (Variable), */ 302 0xB4, /* Pop, */ 303 0x09, 0x30, /* Usage (Tip Pressure), */ 304 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 305 0x81, 0x02, /* Input (Variable), */ 306 0xC0, /* End Collection, */ 307 0xC0, /* End Collection, */ 308 0x05, 0x01, /* Usage Page (Desktop), */ 309 0x09, 0x02, /* Usage (Mouse), */ 310 0xA1, 0x01, /* Collection (Application), */ 311 0x85, 0x08, /* Report ID (8), */ 312 0x09, 0x01, /* Usage (Pointer), */ 313 0xA0, /* Collection (Physical), */ 314 0x75, 0x01, /* Report Size (1), */ 315 0x05, 0x09, /* Usage Page (Button), */ 316 0x19, 0x01, /* Usage Minimum (01h), */ 317 0x29, 0x03, /* Usage Maximum (03h), */ 318 0x14, /* Logical Minimum (0), */ 319 0x25, 0x01, /* Logical Maximum (1), */ 320 0x95, 0x03, /* Report Count (3), */ 321 0x81, 0x02, /* Input (Variable), */ 322 0x95, 0x05, /* Report Count (5), */ 323 0x81, 0x01, /* Input (Constant), */ 324 0x05, 0x01, /* Usage Page (Desktop), */ 325 0x75, 0x08, /* Report Size (8), */ 326 0x09, 0x30, /* Usage (X), */ 327 0x09, 0x31, /* Usage (Y), */ 328 0x15, 0x81, /* Logical Minimum (-127), */ 329 0x25, 0x7F, /* Logical Maximum (127), */ 330 0x95, 0x02, /* Report Count (2), */ 331 0x81, 0x06, /* Input (Variable, Relative), */ 332 0x09, 0x38, /* Usage (Wheel), */ 333 0x15, 0xFF, /* Logical Minimum (-1), */ 334 0x25, 0x01, /* Logical Maximum (1), */ 335 0x95, 0x01, /* Report Count (1), */ 336 0x81, 0x06, /* Input (Variable, Relative), */ 337 0x81, 0x01, /* Input (Constant), */ 338 0xC0, /* End Collection, */ 339 0xC0 /* End Collection */ 340 }; 341 342 const size_t uclogic_rdesc_pf1209_fixed_size = 343 sizeof(uclogic_rdesc_pf1209_fixed_arr); 344 345 /* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */ 346 __u8 uclogic_rdesc_twhl850_fixed0_arr[] = { 347 0x05, 0x0D, /* Usage Page (Digitizer), */ 348 0x09, 0x01, /* Usage (Digitizer), */ 349 0xA1, 0x01, /* Collection (Application), */ 350 0x85, 0x09, /* Report ID (9), */ 351 0x09, 0x20, /* Usage (Stylus), */ 352 0xA0, /* Collection (Physical), */ 353 0x14, /* Logical Minimum (0), */ 354 0x25, 0x01, /* Logical Maximum (1), */ 355 0x75, 0x01, /* Report Size (1), */ 356 0x95, 0x03, /* Report Count (3), */ 357 0x09, 0x42, /* Usage (Tip Switch), */ 358 0x09, 0x44, /* Usage (Barrel Switch), */ 359 0x09, 0x46, /* Usage (Tablet Pick), */ 360 0x81, 0x02, /* Input (Variable), */ 361 0x81, 0x03, /* Input (Constant, Variable), */ 362 0x95, 0x01, /* Report Count (1), */ 363 0x09, 0x32, /* Usage (In Range), */ 364 0x81, 0x02, /* Input (Variable), */ 365 0x81, 0x03, /* Input (Constant, Variable), */ 366 0x75, 0x10, /* Report Size (16), */ 367 0xA4, /* Push, */ 368 0x05, 0x01, /* Usage Page (Desktop), */ 369 0x65, 0x13, /* Unit (Inch), */ 370 0x55, 0xFD, /* Unit Exponent (-3), */ 371 0x34, /* Physical Minimum (0), */ 372 0x09, 0x30, /* Usage (X), */ 373 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ 374 0x26, 0x00, 0x7D, /* Logical Maximum (32000), */ 375 0x81, 0x02, /* Input (Variable), */ 376 0x09, 0x31, /* Usage (Y), */ 377 0x46, 0x88, 0x13, /* Physical Maximum (5000), */ 378 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ 379 0x81, 0x02, /* Input (Variable), */ 380 0xB4, /* Pop, */ 381 0x09, 0x30, /* Usage (Tip Pressure), */ 382 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 383 0x81, 0x02, /* Input (Variable), */ 384 0xC0, /* End Collection, */ 385 0xC0 /* End Collection */ 386 }; 387 388 const size_t uclogic_rdesc_twhl850_fixed0_size = 389 sizeof(uclogic_rdesc_twhl850_fixed0_arr); 390 391 /* Fixed PID 0522 tablet report descriptor, interface 1 (mouse) */ 392 __u8 uclogic_rdesc_twhl850_fixed1_arr[] = { 393 0x05, 0x01, /* Usage Page (Desktop), */ 394 0x09, 0x02, /* Usage (Mouse), */ 395 0xA1, 0x01, /* Collection (Application), */ 396 0x85, 0x01, /* Report ID (1), */ 397 0x09, 0x01, /* Usage (Pointer), */ 398 0xA0, /* Collection (Physical), */ 399 0x05, 0x09, /* Usage Page (Button), */ 400 0x75, 0x01, /* Report Size (1), */ 401 0x95, 0x03, /* Report Count (3), */ 402 0x19, 0x01, /* Usage Minimum (01h), */ 403 0x29, 0x03, /* Usage Maximum (03h), */ 404 0x14, /* Logical Minimum (0), */ 405 0x25, 0x01, /* Logical Maximum (1), */ 406 0x81, 0x02, /* Input (Variable), */ 407 0x95, 0x05, /* Report Count (5), */ 408 0x81, 0x03, /* Input (Constant, Variable), */ 409 0x05, 0x01, /* Usage Page (Desktop), */ 410 0x09, 0x30, /* Usage (X), */ 411 0x09, 0x31, /* Usage (Y), */ 412 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 413 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 414 0x75, 0x10, /* Report Size (16), */ 415 0x95, 0x02, /* Report Count (2), */ 416 0x81, 0x06, /* Input (Variable, Relative), */ 417 0x09, 0x38, /* Usage (Wheel), */ 418 0x15, 0xFF, /* Logical Minimum (-1), */ 419 0x25, 0x01, /* Logical Maximum (1), */ 420 0x95, 0x01, /* Report Count (1), */ 421 0x75, 0x08, /* Report Size (8), */ 422 0x81, 0x06, /* Input (Variable, Relative), */ 423 0x81, 0x03, /* Input (Constant, Variable), */ 424 0xC0, /* End Collection, */ 425 0xC0 /* End Collection */ 426 }; 427 428 const size_t uclogic_rdesc_twhl850_fixed1_size = 429 sizeof(uclogic_rdesc_twhl850_fixed1_arr); 430 431 /* Fixed PID 0522 tablet report descriptor, interface 2 (frame buttons) */ 432 __u8 uclogic_rdesc_twhl850_fixed2_arr[] = { 433 0x05, 0x01, /* Usage Page (Desktop), */ 434 0x09, 0x06, /* Usage (Keyboard), */ 435 0xA1, 0x01, /* Collection (Application), */ 436 0x85, 0x03, /* Report ID (3), */ 437 0x05, 0x07, /* Usage Page (Keyboard), */ 438 0x14, /* Logical Minimum (0), */ 439 0x19, 0xE0, /* Usage Minimum (KB Leftcontrol), */ 440 0x29, 0xE7, /* Usage Maximum (KB Right GUI), */ 441 0x25, 0x01, /* Logical Maximum (1), */ 442 0x75, 0x01, /* Report Size (1), */ 443 0x95, 0x08, /* Report Count (8), */ 444 0x81, 0x02, /* Input (Variable), */ 445 0x18, /* Usage Minimum (None), */ 446 0x29, 0xFF, /* Usage Maximum (FFh), */ 447 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 448 0x75, 0x08, /* Report Size (8), */ 449 0x95, 0x06, /* Report Count (6), */ 450 0x80, /* Input, */ 451 0xC0 /* End Collection */ 452 }; 453 454 const size_t uclogic_rdesc_twhl850_fixed2_size = 455 sizeof(uclogic_rdesc_twhl850_fixed2_arr); 456 457 /* Fixed TWHA60 report descriptor, interface 0 (stylus) */ 458 __u8 uclogic_rdesc_twha60_fixed0_arr[] = { 459 0x05, 0x0D, /* Usage Page (Digitizer), */ 460 0x09, 0x01, /* Usage (Digitizer), */ 461 0xA1, 0x01, /* Collection (Application), */ 462 0x85, 0x09, /* Report ID (9), */ 463 0x09, 0x20, /* Usage (Stylus), */ 464 0xA0, /* Collection (Physical), */ 465 0x75, 0x01, /* Report Size (1), */ 466 0x09, 0x42, /* Usage (Tip Switch), */ 467 0x09, 0x44, /* Usage (Barrel Switch), */ 468 0x09, 0x46, /* Usage (Tablet Pick), */ 469 0x14, /* Logical Minimum (0), */ 470 0x25, 0x01, /* Logical Maximum (1), */ 471 0x95, 0x03, /* Report Count (3), */ 472 0x81, 0x02, /* Input (Variable), */ 473 0x95, 0x04, /* Report Count (4), */ 474 0x81, 0x01, /* Input (Constant), */ 475 0x09, 0x32, /* Usage (In Range), */ 476 0x95, 0x01, /* Report Count (1), */ 477 0x81, 0x02, /* Input (Variable), */ 478 0x75, 0x10, /* Report Size (16), */ 479 0x95, 0x01, /* Report Count (1), */ 480 0x14, /* Logical Minimum (0), */ 481 0xA4, /* Push, */ 482 0x05, 0x01, /* Usage Page (Desktop), */ 483 0x55, 0xFD, /* Unit Exponent (-3), */ 484 0x65, 0x13, /* Unit (Inch), */ 485 0x34, /* Physical Minimum (0), */ 486 0x09, 0x30, /* Usage (X), */ 487 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ 488 0x27, 0x3F, 0x9C, 489 0x00, 0x00, /* Logical Maximum (39999), */ 490 0x81, 0x02, /* Input (Variable), */ 491 0x09, 0x31, /* Usage (Y), */ 492 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */ 493 0x26, 0xA7, 0x61, /* Logical Maximum (24999), */ 494 0x81, 0x02, /* Input (Variable), */ 495 0xB4, /* Pop, */ 496 0x09, 0x30, /* Usage (Tip Pressure), */ 497 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 498 0x81, 0x02, /* Input (Variable), */ 499 0xC0, /* End Collection, */ 500 0xC0 /* End Collection */ 501 }; 502 503 const size_t uclogic_rdesc_twha60_fixed0_size = 504 sizeof(uclogic_rdesc_twha60_fixed0_arr); 505 506 /* Fixed TWHA60 report descriptor, interface 1 (frame buttons) */ 507 __u8 uclogic_rdesc_twha60_fixed1_arr[] = { 508 0x05, 0x01, /* Usage Page (Desktop), */ 509 0x09, 0x06, /* Usage (Keyboard), */ 510 0xA1, 0x01, /* Collection (Application), */ 511 0x85, 0x05, /* Report ID (5), */ 512 0x05, 0x07, /* Usage Page (Keyboard), */ 513 0x14, /* Logical Minimum (0), */ 514 0x25, 0x01, /* Logical Maximum (1), */ 515 0x75, 0x01, /* Report Size (1), */ 516 0x95, 0x08, /* Report Count (8), */ 517 0x81, 0x01, /* Input (Constant), */ 518 0x95, 0x0C, /* Report Count (12), */ 519 0x19, 0x3A, /* Usage Minimum (KB F1), */ 520 0x29, 0x45, /* Usage Maximum (KB F12), */ 521 0x81, 0x02, /* Input (Variable), */ 522 0x95, 0x0C, /* Report Count (12), */ 523 0x19, 0x68, /* Usage Minimum (KB F13), */ 524 0x29, 0x73, /* Usage Maximum (KB F24), */ 525 0x81, 0x02, /* Input (Variable), */ 526 0x95, 0x08, /* Report Count (8), */ 527 0x81, 0x01, /* Input (Constant), */ 528 0xC0 /* End Collection */ 529 }; 530 531 const size_t uclogic_rdesc_twha60_fixed1_size = 532 sizeof(uclogic_rdesc_twha60_fixed1_arr); 533 534 /* Fixed report descriptor template for (tweaked) v1 pen reports */ 535 const __u8 uclogic_rdesc_v1_pen_template_arr[] = { 536 0x05, 0x0D, /* Usage Page (Digitizer), */ 537 0x09, 0x01, /* Usage (Digitizer), */ 538 0xA1, 0x01, /* Collection (Application), */ 539 0x85, 0x07, /* Report ID (7), */ 540 0x09, 0x20, /* Usage (Stylus), */ 541 0xA0, /* Collection (Physical), */ 542 0x14, /* Logical Minimum (0), */ 543 0x25, 0x01, /* Logical Maximum (1), */ 544 0x75, 0x01, /* Report Size (1), */ 545 0x09, 0x42, /* Usage (Tip Switch), */ 546 0x09, 0x44, /* Usage (Barrel Switch), */ 547 0x09, 0x46, /* Usage (Tablet Pick), */ 548 0x95, 0x03, /* Report Count (3), */ 549 0x81, 0x02, /* Input (Variable), */ 550 0x95, 0x03, /* Report Count (3), */ 551 0x81, 0x03, /* Input (Constant, Variable), */ 552 0x09, 0x32, /* Usage (In Range), */ 553 0x95, 0x01, /* Report Count (1), */ 554 0x81, 0x02, /* Input (Variable), */ 555 0x95, 0x01, /* Report Count (1), */ 556 0x81, 0x03, /* Input (Constant, Variable), */ 557 0x75, 0x10, /* Report Size (16), */ 558 0x95, 0x01, /* Report Count (1), */ 559 0xA4, /* Push, */ 560 0x05, 0x01, /* Usage Page (Desktop), */ 561 0x65, 0x13, /* Unit (Inch), */ 562 0x55, 0xFD, /* Unit Exponent (-3), */ 563 0x34, /* Physical Minimum (0), */ 564 0x09, 0x30, /* Usage (X), */ 565 0x27, UCLOGIC_RDESC_PEN_PH(X_LM), 566 /* Logical Maximum (PLACEHOLDER), */ 567 0x47, UCLOGIC_RDESC_PEN_PH(X_PM), 568 /* Physical Maximum (PLACEHOLDER), */ 569 0x81, 0x02, /* Input (Variable), */ 570 0x09, 0x31, /* Usage (Y), */ 571 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM), 572 /* Logical Maximum (PLACEHOLDER), */ 573 0x47, UCLOGIC_RDESC_PEN_PH(Y_PM), 574 /* Physical Maximum (PLACEHOLDER), */ 575 0x81, 0x02, /* Input (Variable), */ 576 0xB4, /* Pop, */ 577 0x09, 0x30, /* Usage (Tip Pressure), */ 578 0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM), 579 /* Logical Maximum (PLACEHOLDER), */ 580 0x81, 0x02, /* Input (Variable), */ 581 0xC0, /* End Collection, */ 582 0xC0 /* End Collection */ 583 }; 584 585 const size_t uclogic_rdesc_v1_pen_template_size = 586 sizeof(uclogic_rdesc_v1_pen_template_arr); 587 588 /* Fixed report descriptor template for (tweaked) v2 pen reports */ 589 const __u8 uclogic_rdesc_v2_pen_template_arr[] = { 590 0x05, 0x0D, /* Usage Page (Digitizer), */ 591 0x09, 0x01, /* Usage (Digitizer), */ 592 0xA1, 0x01, /* Collection (Application), */ 593 0x85, 0x08, /* Report ID (8), */ 594 0x09, 0x20, /* Usage (Stylus), */ 595 0xA0, /* Collection (Physical), */ 596 0x14, /* Logical Minimum (0), */ 597 0x25, 0x01, /* Logical Maximum (1), */ 598 0x75, 0x01, /* Report Size (1), */ 599 0x09, 0x42, /* Usage (Tip Switch), */ 600 0x09, 0x44, /* Usage (Barrel Switch), */ 601 0x09, 0x46, /* Usage (Tablet Pick), */ 602 0x95, 0x03, /* Report Count (3), */ 603 0x81, 0x02, /* Input (Variable), */ 604 0x95, 0x03, /* Report Count (3), */ 605 0x81, 0x03, /* Input (Constant, Variable), */ 606 0x09, 0x32, /* Usage (In Range), */ 607 0x95, 0x01, /* Report Count (1), */ 608 0x81, 0x02, /* Input (Variable), */ 609 0x95, 0x01, /* Report Count (1), */ 610 0x81, 0x03, /* Input (Constant, Variable), */ 611 0x95, 0x01, /* Report Count (1), */ 612 0xA4, /* Push, */ 613 0x05, 0x01, /* Usage Page (Desktop), */ 614 0x65, 0x13, /* Unit (Inch), */ 615 0x55, 0xFD, /* Unit Exponent (-3), */ 616 0x75, 0x18, /* Report Size (24), */ 617 0x34, /* Physical Minimum (0), */ 618 0x09, 0x30, /* Usage (X), */ 619 0x27, UCLOGIC_RDESC_PEN_PH(X_LM), 620 /* Logical Maximum (PLACEHOLDER), */ 621 0x47, UCLOGIC_RDESC_PEN_PH(X_PM), 622 /* Physical Maximum (PLACEHOLDER), */ 623 0x81, 0x02, /* Input (Variable), */ 624 0x09, 0x31, /* Usage (Y), */ 625 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM), 626 /* Logical Maximum (PLACEHOLDER), */ 627 0x47, UCLOGIC_RDESC_PEN_PH(Y_PM), 628 /* Physical Maximum (PLACEHOLDER), */ 629 0x81, 0x02, /* Input (Variable), */ 630 0xB4, /* Pop, */ 631 0x09, 0x30, /* Usage (Tip Pressure), */ 632 0x75, 0x10, /* Report Size (16), */ 633 0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM), 634 /* Logical Maximum (PLACEHOLDER), */ 635 0x81, 0x02, /* Input (Variable), */ 636 0x54, /* Unit Exponent (0), */ 637 0x65, 0x14, /* Unit (Degrees), */ 638 0x35, 0xC4, /* Physical Minimum (-60), */ 639 0x45, 0x3C, /* Physical Maximum (60), */ 640 0x15, 0xC4, /* Logical Minimum (-60), */ 641 0x25, 0x3C, /* Logical Maximum (60), */ 642 0x75, 0x08, /* Report Size (8), */ 643 0x95, 0x02, /* Report Count (2), */ 644 0x09, 0x3D, /* Usage (X Tilt), */ 645 0x09, 0x3E, /* Usage (Y Tilt), */ 646 0x81, 0x02, /* Input (Variable), */ 647 0xC0, /* End Collection, */ 648 0xC0 /* End Collection */ 649 }; 650 651 const size_t uclogic_rdesc_v2_pen_template_size = 652 sizeof(uclogic_rdesc_v2_pen_template_arr); 653 654 /* 655 * Expand to the contents of a generic frame buttons report descriptor. 656 * 657 * @_id: The report ID to use. 658 * @_size: Size of the report to pad to, including report ID, bytes. 659 */ 660 #define UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(_id, _size) \ 661 0x05, 0x01, /* Usage Page (Desktop), */ \ 662 0x09, 0x07, /* Usage (Keypad), */ \ 663 0xA1, 0x01, /* Collection (Application), */ \ 664 0x85, (_id), /* Report ID (_id), */ \ 665 0x14, /* Logical Minimum (0), */ \ 666 0x25, 0x01, /* Logical Maximum (1), */ \ 667 0x75, 0x01, /* Report Size (1), */ \ 668 0x05, 0x0D, /* Usage Page (Digitizer), */ \ 669 0x09, 0x39, /* Usage (Tablet Function Keys), */ \ 670 0xA0, /* Collection (Physical), */ \ 671 0x09, 0x44, /* Usage (Barrel Switch), */ \ 672 0x95, 0x01, /* Report Count (1), */ \ 673 0x81, 0x02, /* Input (Variable), */ \ 674 0x05, 0x01, /* Usage Page (Desktop), */ \ 675 0x09, 0x30, /* Usage (X), */ \ 676 0x09, 0x31, /* Usage (Y), */ \ 677 0x95, 0x02, /* Report Count (2), */ \ 678 0x81, 0x02, /* Input (Variable), */ \ 679 0x95, 0x15, /* Report Count (21), */ \ 680 0x81, 0x01, /* Input (Constant), */ \ 681 0x05, 0x09, /* Usage Page (Button), */ \ 682 0x19, 0x01, /* Usage Minimum (01h), */ \ 683 0x29, 0x0A, /* Usage Maximum (0Ah), */ \ 684 0x95, 0x0A, /* Report Count (10), */ \ 685 0x81, 0x02, /* Input (Variable), */ \ 686 0xC0, /* End Collection, */ \ 687 0x05, 0x01, /* Usage Page (Desktop), */ \ 688 0x09, 0x05, /* Usage (Gamepad), */ \ 689 0xA0, /* Collection (Physical), */ \ 690 0x05, 0x09, /* Usage Page (Button), */ \ 691 0x19, 0x01, /* Usage Minimum (01h), */ \ 692 0x29, 0x03, /* Usage Maximum (03h), */ \ 693 0x95, 0x03, /* Report Count (3), */ \ 694 0x81, 0x02, /* Input (Variable), */ \ 695 0x95, ((_size) * 8 - 45), \ 696 /* Report Count (padding), */ \ 697 0x81, 0x01, /* Input (Constant), */ \ 698 0xC0, /* End Collection, */ \ 699 0xC0 /* End Collection */ 700 701 /* Fixed report descriptor for (tweaked) v1 frame reports */ 702 const __u8 uclogic_rdesc_v1_frame_arr[] = { 703 UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8) 704 }; 705 const size_t uclogic_rdesc_v1_frame_size = 706 sizeof(uclogic_rdesc_v1_frame_arr); 707 708 /* Fixed report descriptor for (tweaked) v2 frame button reports */ 709 const __u8 uclogic_rdesc_v2_frame_buttons_arr[] = { 710 UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID, 711 12) 712 }; 713 const size_t uclogic_rdesc_v2_frame_buttons_size = 714 sizeof(uclogic_rdesc_v2_frame_buttons_arr); 715 716 /* Fixed report descriptor for (tweaked) v2 frame touch ring reports */ 717 const __u8 uclogic_rdesc_v2_frame_touch_ring_arr[] = { 718 0x05, 0x01, /* Usage Page (Desktop), */ 719 0x09, 0x07, /* Usage (Keypad), */ 720 0xA1, 0x01, /* Collection (Application), */ 721 0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID, 722 /* Report ID (TOUCH_ID), */ 723 0x14, /* Logical Minimum (0), */ 724 0x05, 0x0D, /* Usage Page (Digitizer), */ 725 0x09, 0x39, /* Usage (Tablet Function Keys), */ 726 0xA0, /* Collection (Physical), */ 727 0x25, 0x01, /* Logical Maximum (1), */ 728 0x75, 0x01, /* Report Size (1), */ 729 0x05, 0x09, /* Usage Page (Button), */ 730 0x09, 0x01, /* Usage (01h), */ 731 0x95, 0x01, /* Report Count (1), */ 732 0x81, 0x02, /* Input (Variable), */ 733 0x95, 0x07, /* Report Count (7), */ 734 0x81, 0x01, /* Input (Constant), */ 735 0x75, 0x08, /* Report Size (8), */ 736 0x95, 0x02, /* Report Count (2), */ 737 0x81, 0x01, /* Input (Constant), */ 738 0x05, 0x0D, /* Usage Page (Digitizer), */ 739 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 740 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 741 0x95, 0x01, /* Report Count (1), */ 742 0x81, 0x02, /* Input (Variable), */ 743 0x05, 0x01, /* Usage Page (Desktop), */ 744 0x09, 0x38, /* Usage (Wheel), */ 745 0x95, 0x01, /* Report Count (1), */ 746 0x15, 0x00, /* Logical Minimum (0), */ 747 0x25, 0x0B, /* Logical Maximum (11), */ 748 0x81, 0x02, /* Input (Variable), */ 749 0x09, 0x30, /* Usage (X), */ 750 0x09, 0x31, /* Usage (Y), */ 751 0x14, /* Logical Minimum (0), */ 752 0x25, 0x01, /* Logical Maximum (1), */ 753 0x75, 0x01, /* Report Size (1), */ 754 0x95, 0x02, /* Report Count (2), */ 755 0x81, 0x02, /* Input (Variable), */ 756 0x95, 0x2E, /* Report Count (46), */ 757 0x81, 0x01, /* Input (Constant), */ 758 0xC0, /* End Collection, */ 759 0xC0 /* End Collection */ 760 }; 761 const size_t uclogic_rdesc_v2_frame_touch_ring_size = 762 sizeof(uclogic_rdesc_v2_frame_touch_ring_arr); 763 764 /* Fixed report descriptor for (tweaked) v2 frame touch strip reports */ 765 const __u8 uclogic_rdesc_v2_frame_touch_strip_arr[] = { 766 0x05, 0x01, /* Usage Page (Desktop), */ 767 0x09, 0x07, /* Usage (Keypad), */ 768 0xA1, 0x01, /* Collection (Application), */ 769 0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID, 770 /* Report ID (TOUCH_ID), */ 771 0x14, /* Logical Minimum (0), */ 772 0x05, 0x0D, /* Usage Page (Digitizer), */ 773 0x09, 0x39, /* Usage (Tablet Function Keys), */ 774 0xA0, /* Collection (Physical), */ 775 0x25, 0x01, /* Logical Maximum (1), */ 776 0x75, 0x01, /* Report Size (1), */ 777 0x05, 0x09, /* Usage Page (Button), */ 778 0x09, 0x01, /* Usage (01h), */ 779 0x95, 0x01, /* Report Count (1), */ 780 0x81, 0x02, /* Input (Variable), */ 781 0x95, 0x07, /* Report Count (7), */ 782 0x81, 0x01, /* Input (Constant), */ 783 0x75, 0x08, /* Report Size (8), */ 784 0x95, 0x02, /* Report Count (2), */ 785 0x81, 0x01, /* Input (Constant), */ 786 0x05, 0x0D, /* Usage Page (Digitizer), */ 787 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 788 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 789 0x95, 0x01, /* Report Count (1), */ 790 0x81, 0x02, /* Input (Variable), */ 791 0x05, 0x01, /* Usage Page (Desktop), */ 792 0x09, 0x38, /* Usage (Wheel), */ 793 0x95, 0x01, /* Report Count (1), */ 794 0x15, 0x00, /* Logical Minimum (0), */ 795 0x25, 0x07, /* Logical Maximum (7), */ 796 0x81, 0x02, /* Input (Variable), */ 797 0x09, 0x30, /* Usage (X), */ 798 0x09, 0x31, /* Usage (Y), */ 799 0x14, /* Logical Minimum (0), */ 800 0x25, 0x01, /* Logical Maximum (1), */ 801 0x75, 0x01, /* Report Size (1), */ 802 0x95, 0x02, /* Report Count (2), */ 803 0x81, 0x02, /* Input (Variable), */ 804 0x95, 0x2E, /* Report Count (46), */ 805 0x81, 0x01, /* Input (Constant), */ 806 0xC0, /* End Collection, */ 807 0xC0 /* End Collection */ 808 }; 809 const size_t uclogic_rdesc_v2_frame_touch_strip_size = 810 sizeof(uclogic_rdesc_v2_frame_touch_strip_arr); 811 812 /* Fixed report descriptor for (tweaked) v2 frame dial reports */ 813 const __u8 uclogic_rdesc_v2_frame_dial_arr[] = { 814 0x05, 0x01, /* Usage Page (Desktop), */ 815 0x09, 0x07, /* Usage (Keypad), */ 816 0xA1, 0x01, /* Collection (Application), */ 817 0x85, UCLOGIC_RDESC_V2_FRAME_DIAL_ID, 818 /* Report ID (DIAL_ID), */ 819 0x14, /* Logical Minimum (0), */ 820 0x05, 0x0D, /* Usage Page (Digitizer), */ 821 0x09, 0x39, /* Usage (Tablet Function Keys), */ 822 0xA0, /* Collection (Physical), */ 823 0x25, 0x01, /* Logical Maximum (1), */ 824 0x75, 0x01, /* Report Size (1), */ 825 0x95, 0x01, /* Report Count (1), */ 826 0x81, 0x01, /* Input (Constant), */ 827 0x05, 0x09, /* Usage Page (Button), */ 828 0x09, 0x01, /* Usage (01h), */ 829 0x95, 0x01, /* Report Count (1), */ 830 0x81, 0x02, /* Input (Variable), */ 831 0x95, 0x06, /* Report Count (6), */ 832 0x81, 0x01, /* Input (Constant), */ 833 0x75, 0x08, /* Report Size (8), */ 834 0x95, 0x02, /* Report Count (2), */ 835 0x81, 0x01, /* Input (Constant), */ 836 0x05, 0x0D, /* Usage Page (Digitizer), */ 837 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 838 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 839 0x95, 0x01, /* Report Count (1), */ 840 0x81, 0x02, /* Input (Variable), */ 841 0x05, 0x01, /* Usage Page (Desktop), */ 842 0x09, 0x38, /* Usage (Wheel), */ 843 0x95, 0x01, /* Report Count (1), */ 844 0x15, 0xFF, /* Logical Minimum (-1), */ 845 0x25, 0x01, /* Logical Maximum (1), */ 846 0x81, 0x06, /* Input (Variable, Relative), */ 847 0x09, 0x30, /* Usage (X), */ 848 0x09, 0x31, /* Usage (Y), */ 849 0x14, /* Logical Minimum (0), */ 850 0x25, 0x01, /* Logical Maximum (1), */ 851 0x75, 0x01, /* Report Size (1), */ 852 0x95, 0x02, /* Report Count (2), */ 853 0x81, 0x02, /* Input (Variable), */ 854 0x95, 0x2E, /* Report Count (46), */ 855 0x81, 0x01, /* Input (Constant), */ 856 0xC0, /* End Collection, */ 857 0xC0 /* End Collection */ 858 }; 859 const size_t uclogic_rdesc_v2_frame_dial_size = 860 sizeof(uclogic_rdesc_v2_frame_dial_arr); 861 862 const __u8 uclogic_ugee_v2_probe_arr[] = { 863 0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 864 }; 865 const size_t uclogic_ugee_v2_probe_size = sizeof(uclogic_ugee_v2_probe_arr); 866 const int uclogic_ugee_v2_probe_endpoint = 0x03; 867 868 /* Fixed report descriptor template for UGEE v2 pen reports */ 869 const __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 }; 938 const 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) */ 942 const __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 }; 967 const 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) */ 971 const __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 }; 1007 const 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) */ 1011 const __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 }; 1041 const 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 */ 1045 const __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 }; 1075 const 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 */ 1079 const __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 }; 1102 const 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 */ 1106 const __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 }; 1156 const 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 */ 1160 const __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 1191 const size_t uclogic_rdesc_xppen_deco01_frame_size = 1192 sizeof(uclogic_rdesc_xppen_deco01_frame_arr); 1193 1194 /** 1195 * uclogic_rdesc_template_apply() - apply report descriptor parameters to a 1196 * report descriptor template, creating a report descriptor. Copies the 1197 * template over to the new report descriptor and replaces every occurrence of 1198 * the template placeholders, followed by an index byte, with the value from the 1199 * parameter list at that index. 1200 * 1201 * @template_ptr: Pointer to the template buffer. 1202 * @template_size: Size of the template buffer. 1203 * @param_list: List of template parameters. 1204 * @param_num: Number of parameters in the list. 1205 * 1206 * Returns: 1207 * Kmalloc-allocated pointer to the created report descriptor, 1208 * or NULL if allocation failed. 1209 */ 1210 __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr, 1211 size_t template_size, 1212 const s32 *param_list, 1213 size_t param_num) 1214 { 1215 static const __u8 btn_head[] = {UCLOGIC_RDESC_FRAME_PH_BTN_HEAD}; 1216 static const __u8 pen_head[] = {UCLOGIC_RDESC_PEN_PH_HEAD}; 1217 __u8 *rdesc_ptr; 1218 __u8 *p; 1219 s32 v; 1220 1221 rdesc_ptr = kmemdup(template_ptr, template_size, GFP_KERNEL); 1222 if (rdesc_ptr == NULL) 1223 return NULL; 1224 1225 for (p = rdesc_ptr; p + sizeof(btn_head) < rdesc_ptr + template_size;) { 1226 if (p + sizeof(pen_head) < rdesc_ptr + template_size && 1227 memcmp(p, pen_head, sizeof(pen_head)) == 0 && 1228 p[sizeof(pen_head)] < param_num) { 1229 v = param_list[p[sizeof(pen_head)]]; 1230 put_unaligned((__force u32)cpu_to_le32(v), (s32 *)p); 1231 p += sizeof(pen_head) + 1; 1232 } else if (memcmp(p, btn_head, sizeof(btn_head)) == 0 && 1233 p[sizeof(btn_head)] < param_num) { 1234 v = param_list[p[sizeof(btn_head)]]; 1235 put_unaligned((__u8)0x2A, p); /* Usage Maximum */ 1236 put_unaligned((__force u16)cpu_to_le16(v), (s16 *)(p + 1)); 1237 p += sizeof(btn_head) + 1; 1238 } else { 1239 p++; 1240 } 1241 } 1242 1243 return rdesc_ptr; 1244 } 1245