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 <linux/unaligned.h> 20 #include <kunit/visibility.h> 21 22 /* Fixed WP4030U report descriptor */ 23 const __u8 uclogic_rdesc_wp4030u_fixed_arr[] = { 24 0x05, 0x0D, /* Usage Page (Digitizer), */ 25 0x09, 0x01, /* Usage (Digitizer), */ 26 0xA1, 0x01, /* Collection (Application), */ 27 0x85, 0x09, /* Report ID (9), */ 28 0x09, 0x20, /* Usage (Stylus), */ 29 0xA0, /* Collection (Physical), */ 30 0x75, 0x01, /* Report Size (1), */ 31 0x09, 0x42, /* Usage (Tip Switch), */ 32 0x09, 0x44, /* Usage (Barrel Switch), */ 33 0x09, 0x46, /* Usage (Tablet Pick), */ 34 0x14, /* Logical Minimum (0), */ 35 0x25, 0x01, /* Logical Maximum (1), */ 36 0x95, 0x03, /* Report Count (3), */ 37 0x81, 0x02, /* Input (Variable), */ 38 0x95, 0x05, /* Report Count (5), */ 39 0x81, 0x01, /* Input (Constant), */ 40 0x75, 0x10, /* Report Size (16), */ 41 0x95, 0x01, /* Report Count (1), */ 42 0x14, /* Logical Minimum (0), */ 43 0xA4, /* Push, */ 44 0x05, 0x01, /* Usage Page (Desktop), */ 45 0x55, 0xFD, /* Unit Exponent (-3), */ 46 0x65, 0x13, /* Unit (Inch), */ 47 0x34, /* Physical Minimum (0), */ 48 0x09, 0x30, /* Usage (X), */ 49 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */ 50 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 51 0x81, 0x02, /* Input (Variable), */ 52 0x09, 0x31, /* Usage (Y), */ 53 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */ 54 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 55 0x81, 0x02, /* Input (Variable), */ 56 0xB4, /* Pop, */ 57 0x09, 0x30, /* Usage (Tip Pressure), */ 58 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 59 0x81, 0x02, /* Input (Variable), */ 60 0xC0, /* End Collection, */ 61 0xC0 /* End Collection */ 62 }; 63 64 const size_t uclogic_rdesc_wp4030u_fixed_size = 65 sizeof(uclogic_rdesc_wp4030u_fixed_arr); 66 67 /* Fixed WP5540U report descriptor */ 68 const __u8 uclogic_rdesc_wp5540u_fixed_arr[] = { 69 0x05, 0x0D, /* Usage Page (Digitizer), */ 70 0x09, 0x01, /* Usage (Digitizer), */ 71 0xA1, 0x01, /* Collection (Application), */ 72 0x85, 0x09, /* Report ID (9), */ 73 0x09, 0x20, /* Usage (Stylus), */ 74 0xA0, /* Collection (Physical), */ 75 0x75, 0x01, /* Report Size (1), */ 76 0x09, 0x42, /* Usage (Tip Switch), */ 77 0x09, 0x44, /* Usage (Barrel Switch), */ 78 0x09, 0x46, /* Usage (Tablet Pick), */ 79 0x14, /* Logical Minimum (0), */ 80 0x25, 0x01, /* Logical Maximum (1), */ 81 0x95, 0x03, /* Report Count (3), */ 82 0x81, 0x02, /* Input (Variable), */ 83 0x95, 0x05, /* Report Count (5), */ 84 0x81, 0x01, /* Input (Constant), */ 85 0x75, 0x10, /* Report Size (16), */ 86 0x95, 0x01, /* Report Count (1), */ 87 0x14, /* Logical Minimum (0), */ 88 0xA4, /* Push, */ 89 0x05, 0x01, /* Usage Page (Desktop), */ 90 0x55, 0xFD, /* Unit Exponent (-3), */ 91 0x65, 0x13, /* Unit (Inch), */ 92 0x34, /* Physical Minimum (0), */ 93 0x09, 0x30, /* Usage (X), */ 94 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */ 95 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 96 0x81, 0x02, /* Input (Variable), */ 97 0x09, 0x31, /* Usage (Y), */ 98 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */ 99 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 100 0x81, 0x02, /* Input (Variable), */ 101 0xB4, /* Pop, */ 102 0x09, 0x30, /* Usage (Tip Pressure), */ 103 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 104 0x81, 0x02, /* Input (Variable), */ 105 0xC0, /* End Collection, */ 106 0xC0, /* End Collection, */ 107 0x05, 0x01, /* Usage Page (Desktop), */ 108 0x09, 0x02, /* Usage (Mouse), */ 109 0xA1, 0x01, /* Collection (Application), */ 110 0x85, 0x08, /* Report ID (8), */ 111 0x09, 0x01, /* Usage (Pointer), */ 112 0xA0, /* Collection (Physical), */ 113 0x75, 0x01, /* Report Size (1), */ 114 0x05, 0x09, /* Usage Page (Button), */ 115 0x19, 0x01, /* Usage Minimum (01h), */ 116 0x29, 0x03, /* Usage Maximum (03h), */ 117 0x14, /* Logical Minimum (0), */ 118 0x25, 0x01, /* Logical Maximum (1), */ 119 0x95, 0x03, /* Report Count (3), */ 120 0x81, 0x02, /* Input (Variable), */ 121 0x95, 0x05, /* Report Count (5), */ 122 0x81, 0x01, /* Input (Constant), */ 123 0x05, 0x01, /* Usage Page (Desktop), */ 124 0x75, 0x08, /* Report Size (8), */ 125 0x09, 0x30, /* Usage (X), */ 126 0x09, 0x31, /* Usage (Y), */ 127 0x15, 0x81, /* Logical Minimum (-127), */ 128 0x25, 0x7F, /* Logical Maximum (127), */ 129 0x95, 0x02, /* Report Count (2), */ 130 0x81, 0x06, /* Input (Variable, Relative), */ 131 0x09, 0x38, /* Usage (Wheel), */ 132 0x15, 0xFF, /* Logical Minimum (-1), */ 133 0x25, 0x01, /* Logical Maximum (1), */ 134 0x95, 0x01, /* Report Count (1), */ 135 0x81, 0x06, /* Input (Variable, Relative), */ 136 0x81, 0x01, /* Input (Constant), */ 137 0xC0, /* End Collection, */ 138 0xC0 /* End Collection */ 139 }; 140 141 const size_t uclogic_rdesc_wp5540u_fixed_size = 142 sizeof(uclogic_rdesc_wp5540u_fixed_arr); 143 144 /* Fixed WP8060U report descriptor */ 145 const __u8 uclogic_rdesc_wp8060u_fixed_arr[] = { 146 0x05, 0x0D, /* Usage Page (Digitizer), */ 147 0x09, 0x01, /* Usage (Digitizer), */ 148 0xA1, 0x01, /* Collection (Application), */ 149 0x85, 0x09, /* Report ID (9), */ 150 0x09, 0x20, /* Usage (Stylus), */ 151 0xA0, /* Collection (Physical), */ 152 0x75, 0x01, /* Report Size (1), */ 153 0x09, 0x42, /* Usage (Tip Switch), */ 154 0x09, 0x44, /* Usage (Barrel Switch), */ 155 0x09, 0x46, /* Usage (Tablet Pick), */ 156 0x14, /* Logical Minimum (0), */ 157 0x25, 0x01, /* Logical Maximum (1), */ 158 0x95, 0x03, /* Report Count (3), */ 159 0x81, 0x02, /* Input (Variable), */ 160 0x95, 0x05, /* Report Count (5), */ 161 0x81, 0x01, /* Input (Constant), */ 162 0x75, 0x10, /* Report Size (16), */ 163 0x95, 0x01, /* Report Count (1), */ 164 0x14, /* Logical Minimum (0), */ 165 0xA4, /* Push, */ 166 0x05, 0x01, /* Usage Page (Desktop), */ 167 0x55, 0xFD, /* Unit Exponent (-3), */ 168 0x65, 0x13, /* Unit (Inch), */ 169 0x34, /* Physical Minimum (0), */ 170 0x09, 0x30, /* Usage (X), */ 171 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ 172 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 173 0x81, 0x02, /* Input (Variable), */ 174 0x09, 0x31, /* Usage (Y), */ 175 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ 176 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 177 0x81, 0x02, /* Input (Variable), */ 178 0xB4, /* Pop, */ 179 0x09, 0x30, /* Usage (Tip Pressure), */ 180 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 181 0x81, 0x02, /* Input (Variable), */ 182 0xC0, /* End Collection, */ 183 0xC0, /* End Collection, */ 184 0x05, 0x01, /* Usage Page (Desktop), */ 185 0x09, 0x02, /* Usage (Mouse), */ 186 0xA1, 0x01, /* Collection (Application), */ 187 0x85, 0x08, /* Report ID (8), */ 188 0x09, 0x01, /* Usage (Pointer), */ 189 0xA0, /* Collection (Physical), */ 190 0x75, 0x01, /* Report Size (1), */ 191 0x05, 0x09, /* Usage Page (Button), */ 192 0x19, 0x01, /* Usage Minimum (01h), */ 193 0x29, 0x03, /* Usage Maximum (03h), */ 194 0x14, /* Logical Minimum (0), */ 195 0x25, 0x01, /* Logical Maximum (1), */ 196 0x95, 0x03, /* Report Count (3), */ 197 0x81, 0x02, /* Input (Variable), */ 198 0x95, 0x05, /* Report Count (5), */ 199 0x81, 0x01, /* Input (Constant), */ 200 0x05, 0x01, /* Usage Page (Desktop), */ 201 0x75, 0x08, /* Report Size (8), */ 202 0x09, 0x30, /* Usage (X), */ 203 0x09, 0x31, /* Usage (Y), */ 204 0x15, 0x81, /* Logical Minimum (-127), */ 205 0x25, 0x7F, /* Logical Maximum (127), */ 206 0x95, 0x02, /* Report Count (2), */ 207 0x81, 0x06, /* Input (Variable, Relative), */ 208 0x09, 0x38, /* Usage (Wheel), */ 209 0x15, 0xFF, /* Logical Minimum (-1), */ 210 0x25, 0x01, /* Logical Maximum (1), */ 211 0x95, 0x01, /* Report Count (1), */ 212 0x81, 0x06, /* Input (Variable, Relative), */ 213 0x81, 0x01, /* Input (Constant), */ 214 0xC0, /* End Collection, */ 215 0xC0 /* End Collection */ 216 }; 217 218 const size_t uclogic_rdesc_wp8060u_fixed_size = 219 sizeof(uclogic_rdesc_wp8060u_fixed_arr); 220 221 /* Fixed WP1062 report descriptor */ 222 const __u8 uclogic_rdesc_wp1062_fixed_arr[] = { 223 0x05, 0x0D, /* Usage Page (Digitizer), */ 224 0x09, 0x01, /* Usage (Digitizer), */ 225 0xA1, 0x01, /* Collection (Application), */ 226 0x85, 0x09, /* Report ID (9), */ 227 0x09, 0x20, /* Usage (Stylus), */ 228 0xA0, /* Collection (Physical), */ 229 0x75, 0x01, /* Report Size (1), */ 230 0x09, 0x42, /* Usage (Tip Switch), */ 231 0x09, 0x44, /* Usage (Barrel Switch), */ 232 0x09, 0x46, /* Usage (Tablet Pick), */ 233 0x14, /* Logical Minimum (0), */ 234 0x25, 0x01, /* Logical Maximum (1), */ 235 0x95, 0x03, /* Report Count (3), */ 236 0x81, 0x02, /* Input (Variable), */ 237 0x95, 0x04, /* Report Count (4), */ 238 0x81, 0x01, /* Input (Constant), */ 239 0x09, 0x32, /* Usage (In Range), */ 240 0x95, 0x01, /* Report Count (1), */ 241 0x81, 0x02, /* Input (Variable), */ 242 0x75, 0x10, /* Report Size (16), */ 243 0x95, 0x01, /* Report Count (1), */ 244 0x14, /* Logical Minimum (0), */ 245 0xA4, /* Push, */ 246 0x05, 0x01, /* Usage Page (Desktop), */ 247 0x55, 0xFD, /* Unit Exponent (-3), */ 248 0x65, 0x13, /* Unit (Inch), */ 249 0x34, /* Physical Minimum (0), */ 250 0x09, 0x30, /* Usage (X), */ 251 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ 252 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ 253 0x81, 0x02, /* Input (Variable), */ 254 0x09, 0x31, /* Usage (Y), */ 255 0x46, 0xB7, 0x19, /* Physical Maximum (6583), */ 256 0x26, 0x6E, 0x33, /* Logical Maximum (13166), */ 257 0x81, 0x02, /* Input (Variable), */ 258 0xB4, /* Pop, */ 259 0x09, 0x30, /* Usage (Tip Pressure), */ 260 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 261 0x81, 0x02, /* Input (Variable), */ 262 0xC0, /* End Collection, */ 263 0xC0 /* End Collection */ 264 }; 265 266 const size_t uclogic_rdesc_wp1062_fixed_size = 267 sizeof(uclogic_rdesc_wp1062_fixed_arr); 268 269 /* Fixed PF1209 report descriptor */ 270 const __u8 uclogic_rdesc_pf1209_fixed_arr[] = { 271 0x05, 0x0D, /* Usage Page (Digitizer), */ 272 0x09, 0x01, /* Usage (Digitizer), */ 273 0xA1, 0x01, /* Collection (Application), */ 274 0x85, 0x09, /* Report ID (9), */ 275 0x09, 0x20, /* Usage (Stylus), */ 276 0xA0, /* Collection (Physical), */ 277 0x75, 0x01, /* Report Size (1), */ 278 0x09, 0x42, /* Usage (Tip Switch), */ 279 0x09, 0x44, /* Usage (Barrel Switch), */ 280 0x09, 0x46, /* Usage (Tablet Pick), */ 281 0x14, /* Logical Minimum (0), */ 282 0x25, 0x01, /* Logical Maximum (1), */ 283 0x95, 0x03, /* Report Count (3), */ 284 0x81, 0x02, /* Input (Variable), */ 285 0x95, 0x05, /* Report Count (5), */ 286 0x81, 0x01, /* Input (Constant), */ 287 0x75, 0x10, /* Report Size (16), */ 288 0x95, 0x01, /* Report Count (1), */ 289 0x14, /* Logical Minimum (0), */ 290 0xA4, /* Push, */ 291 0x05, 0x01, /* Usage Page (Desktop), */ 292 0x55, 0xFD, /* Unit Exponent (-3), */ 293 0x65, 0x13, /* Unit (Inch), */ 294 0x34, /* Physical Minimum (0), */ 295 0x09, 0x30, /* Usage (X), */ 296 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */ 297 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 298 0x81, 0x02, /* Input (Variable), */ 299 0x09, 0x31, /* Usage (Y), */ 300 0x46, 0x28, 0x23, /* Physical Maximum (9000), */ 301 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 302 0x81, 0x02, /* Input (Variable), */ 303 0xB4, /* Pop, */ 304 0x09, 0x30, /* Usage (Tip Pressure), */ 305 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 306 0x81, 0x02, /* Input (Variable), */ 307 0xC0, /* End Collection, */ 308 0xC0, /* End Collection, */ 309 0x05, 0x01, /* Usage Page (Desktop), */ 310 0x09, 0x02, /* Usage (Mouse), */ 311 0xA1, 0x01, /* Collection (Application), */ 312 0x85, 0x08, /* Report ID (8), */ 313 0x09, 0x01, /* Usage (Pointer), */ 314 0xA0, /* Collection (Physical), */ 315 0x75, 0x01, /* Report Size (1), */ 316 0x05, 0x09, /* Usage Page (Button), */ 317 0x19, 0x01, /* Usage Minimum (01h), */ 318 0x29, 0x03, /* Usage Maximum (03h), */ 319 0x14, /* Logical Minimum (0), */ 320 0x25, 0x01, /* Logical Maximum (1), */ 321 0x95, 0x03, /* Report Count (3), */ 322 0x81, 0x02, /* Input (Variable), */ 323 0x95, 0x05, /* Report Count (5), */ 324 0x81, 0x01, /* Input (Constant), */ 325 0x05, 0x01, /* Usage Page (Desktop), */ 326 0x75, 0x08, /* Report Size (8), */ 327 0x09, 0x30, /* Usage (X), */ 328 0x09, 0x31, /* Usage (Y), */ 329 0x15, 0x81, /* Logical Minimum (-127), */ 330 0x25, 0x7F, /* Logical Maximum (127), */ 331 0x95, 0x02, /* Report Count (2), */ 332 0x81, 0x06, /* Input (Variable, Relative), */ 333 0x09, 0x38, /* Usage (Wheel), */ 334 0x15, 0xFF, /* Logical Minimum (-1), */ 335 0x25, 0x01, /* Logical Maximum (1), */ 336 0x95, 0x01, /* Report Count (1), */ 337 0x81, 0x06, /* Input (Variable, Relative), */ 338 0x81, 0x01, /* Input (Constant), */ 339 0xC0, /* End Collection, */ 340 0xC0 /* End Collection */ 341 }; 342 343 const size_t uclogic_rdesc_pf1209_fixed_size = 344 sizeof(uclogic_rdesc_pf1209_fixed_arr); 345 346 /* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */ 347 const __u8 uclogic_rdesc_twhl850_fixed0_arr[] = { 348 0x05, 0x0D, /* Usage Page (Digitizer), */ 349 0x09, 0x01, /* Usage (Digitizer), */ 350 0xA1, 0x01, /* Collection (Application), */ 351 0x85, 0x09, /* Report ID (9), */ 352 0x09, 0x20, /* Usage (Stylus), */ 353 0xA0, /* Collection (Physical), */ 354 0x14, /* Logical Minimum (0), */ 355 0x25, 0x01, /* Logical Maximum (1), */ 356 0x75, 0x01, /* Report Size (1), */ 357 0x95, 0x03, /* Report Count (3), */ 358 0x09, 0x42, /* Usage (Tip Switch), */ 359 0x09, 0x44, /* Usage (Barrel Switch), */ 360 0x09, 0x46, /* Usage (Tablet Pick), */ 361 0x81, 0x02, /* Input (Variable), */ 362 0x81, 0x03, /* Input (Constant, Variable), */ 363 0x95, 0x01, /* Report Count (1), */ 364 0x09, 0x32, /* Usage (In Range), */ 365 0x81, 0x02, /* Input (Variable), */ 366 0x81, 0x03, /* Input (Constant, Variable), */ 367 0x75, 0x10, /* Report Size (16), */ 368 0xA4, /* Push, */ 369 0x05, 0x01, /* Usage Page (Desktop), */ 370 0x65, 0x13, /* Unit (Inch), */ 371 0x55, 0xFD, /* Unit Exponent (-3), */ 372 0x34, /* Physical Minimum (0), */ 373 0x09, 0x30, /* Usage (X), */ 374 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ 375 0x26, 0x00, 0x7D, /* Logical Maximum (32000), */ 376 0x81, 0x02, /* Input (Variable), */ 377 0x09, 0x31, /* Usage (Y), */ 378 0x46, 0x88, 0x13, /* Physical Maximum (5000), */ 379 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ 380 0x81, 0x02, /* Input (Variable), */ 381 0xB4, /* Pop, */ 382 0x09, 0x30, /* Usage (Tip Pressure), */ 383 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 384 0x81, 0x02, /* Input (Variable), */ 385 0xC0, /* End Collection, */ 386 0xC0 /* End Collection */ 387 }; 388 389 const size_t uclogic_rdesc_twhl850_fixed0_size = 390 sizeof(uclogic_rdesc_twhl850_fixed0_arr); 391 392 /* Fixed PID 0522 tablet report descriptor, interface 1 (mouse) */ 393 const __u8 uclogic_rdesc_twhl850_fixed1_arr[] = { 394 0x05, 0x01, /* Usage Page (Desktop), */ 395 0x09, 0x02, /* Usage (Mouse), */ 396 0xA1, 0x01, /* Collection (Application), */ 397 0x85, 0x01, /* Report ID (1), */ 398 0x09, 0x01, /* Usage (Pointer), */ 399 0xA0, /* Collection (Physical), */ 400 0x05, 0x09, /* Usage Page (Button), */ 401 0x75, 0x01, /* Report Size (1), */ 402 0x95, 0x03, /* Report Count (3), */ 403 0x19, 0x01, /* Usage Minimum (01h), */ 404 0x29, 0x03, /* Usage Maximum (03h), */ 405 0x14, /* Logical Minimum (0), */ 406 0x25, 0x01, /* Logical Maximum (1), */ 407 0x81, 0x02, /* Input (Variable), */ 408 0x95, 0x05, /* Report Count (5), */ 409 0x81, 0x03, /* Input (Constant, Variable), */ 410 0x05, 0x01, /* Usage Page (Desktop), */ 411 0x09, 0x30, /* Usage (X), */ 412 0x09, 0x31, /* Usage (Y), */ 413 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 414 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 415 0x75, 0x10, /* Report Size (16), */ 416 0x95, 0x02, /* Report Count (2), */ 417 0x81, 0x06, /* Input (Variable, Relative), */ 418 0x09, 0x38, /* Usage (Wheel), */ 419 0x15, 0xFF, /* Logical Minimum (-1), */ 420 0x25, 0x01, /* Logical Maximum (1), */ 421 0x95, 0x01, /* Report Count (1), */ 422 0x75, 0x08, /* Report Size (8), */ 423 0x81, 0x06, /* Input (Variable, Relative), */ 424 0x81, 0x03, /* Input (Constant, Variable), */ 425 0xC0, /* End Collection, */ 426 0xC0 /* End Collection */ 427 }; 428 429 const size_t uclogic_rdesc_twhl850_fixed1_size = 430 sizeof(uclogic_rdesc_twhl850_fixed1_arr); 431 432 /* Fixed PID 0522 tablet report descriptor, interface 2 (frame buttons) */ 433 const __u8 uclogic_rdesc_twhl850_fixed2_arr[] = { 434 0x05, 0x01, /* Usage Page (Desktop), */ 435 0x09, 0x06, /* Usage (Keyboard), */ 436 0xA1, 0x01, /* Collection (Application), */ 437 0x85, 0x03, /* Report ID (3), */ 438 0x05, 0x07, /* Usage Page (Keyboard), */ 439 0x14, /* Logical Minimum (0), */ 440 0x19, 0xE0, /* Usage Minimum (KB Leftcontrol), */ 441 0x29, 0xE7, /* Usage Maximum (KB Right GUI), */ 442 0x25, 0x01, /* Logical Maximum (1), */ 443 0x75, 0x01, /* Report Size (1), */ 444 0x95, 0x08, /* Report Count (8), */ 445 0x81, 0x02, /* Input (Variable), */ 446 0x18, /* Usage Minimum (None), */ 447 0x29, 0xFF, /* Usage Maximum (FFh), */ 448 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 449 0x75, 0x08, /* Report Size (8), */ 450 0x95, 0x06, /* Report Count (6), */ 451 0x80, /* Input, */ 452 0xC0 /* End Collection */ 453 }; 454 455 const size_t uclogic_rdesc_twhl850_fixed2_size = 456 sizeof(uclogic_rdesc_twhl850_fixed2_arr); 457 458 /* Fixed TWHA60 report descriptor, interface 0 (stylus) */ 459 const __u8 uclogic_rdesc_twha60_fixed0_arr[] = { 460 0x05, 0x0D, /* Usage Page (Digitizer), */ 461 0x09, 0x01, /* Usage (Digitizer), */ 462 0xA1, 0x01, /* Collection (Application), */ 463 0x85, 0x09, /* Report ID (9), */ 464 0x09, 0x20, /* Usage (Stylus), */ 465 0xA0, /* Collection (Physical), */ 466 0x75, 0x01, /* Report Size (1), */ 467 0x09, 0x42, /* Usage (Tip Switch), */ 468 0x09, 0x44, /* Usage (Barrel Switch), */ 469 0x09, 0x46, /* Usage (Tablet Pick), */ 470 0x14, /* Logical Minimum (0), */ 471 0x25, 0x01, /* Logical Maximum (1), */ 472 0x95, 0x03, /* Report Count (3), */ 473 0x81, 0x02, /* Input (Variable), */ 474 0x95, 0x04, /* Report Count (4), */ 475 0x81, 0x01, /* Input (Constant), */ 476 0x09, 0x32, /* Usage (In Range), */ 477 0x95, 0x01, /* Report Count (1), */ 478 0x81, 0x02, /* Input (Variable), */ 479 0x75, 0x10, /* Report Size (16), */ 480 0x95, 0x01, /* Report Count (1), */ 481 0x14, /* Logical Minimum (0), */ 482 0xA4, /* Push, */ 483 0x05, 0x01, /* Usage Page (Desktop), */ 484 0x55, 0xFD, /* Unit Exponent (-3), */ 485 0x65, 0x13, /* Unit (Inch), */ 486 0x34, /* Physical Minimum (0), */ 487 0x09, 0x30, /* Usage (X), */ 488 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ 489 0x27, 0x3F, 0x9C, 490 0x00, 0x00, /* Logical Maximum (39999), */ 491 0x81, 0x02, /* Input (Variable), */ 492 0x09, 0x31, /* Usage (Y), */ 493 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */ 494 0x26, 0xA7, 0x61, /* Logical Maximum (24999), */ 495 0x81, 0x02, /* Input (Variable), */ 496 0xB4, /* Pop, */ 497 0x09, 0x30, /* Usage (Tip Pressure), */ 498 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 499 0x81, 0x02, /* Input (Variable), */ 500 0xC0, /* End Collection, */ 501 0xC0 /* End Collection */ 502 }; 503 504 const size_t uclogic_rdesc_twha60_fixed0_size = 505 sizeof(uclogic_rdesc_twha60_fixed0_arr); 506 507 /* Fixed TWHA60 report descriptor, interface 1 (frame buttons) */ 508 const __u8 uclogic_rdesc_twha60_fixed1_arr[] = { 509 0x05, 0x01, /* Usage Page (Desktop), */ 510 0x09, 0x06, /* Usage (Keyboard), */ 511 0xA1, 0x01, /* Collection (Application), */ 512 0x85, 0x05, /* Report ID (5), */ 513 0x05, 0x07, /* Usage Page (Keyboard), */ 514 0x14, /* Logical Minimum (0), */ 515 0x25, 0x01, /* Logical Maximum (1), */ 516 0x75, 0x01, /* Report Size (1), */ 517 0x95, 0x08, /* Report Count (8), */ 518 0x81, 0x01, /* Input (Constant), */ 519 0x95, 0x0C, /* Report Count (12), */ 520 0x19, 0x3A, /* Usage Minimum (KB F1), */ 521 0x29, 0x45, /* Usage Maximum (KB F12), */ 522 0x81, 0x02, /* Input (Variable), */ 523 0x95, 0x0C, /* Report Count (12), */ 524 0x19, 0x68, /* Usage Minimum (KB F13), */ 525 0x29, 0x73, /* Usage Maximum (KB F24), */ 526 0x81, 0x02, /* Input (Variable), */ 527 0x95, 0x08, /* Report Count (8), */ 528 0x81, 0x01, /* Input (Constant), */ 529 0xC0 /* End Collection */ 530 }; 531 532 const size_t uclogic_rdesc_twha60_fixed1_size = 533 sizeof(uclogic_rdesc_twha60_fixed1_arr); 534 535 /* Fixed report descriptor template for (tweaked) v1 pen reports */ 536 const __u8 uclogic_rdesc_v1_pen_template_arr[] = { 537 0x05, 0x0D, /* Usage Page (Digitizer), */ 538 0x09, 0x01, /* Usage (Digitizer), */ 539 0xA1, 0x01, /* Collection (Application), */ 540 0x85, 0x07, /* Report ID (7), */ 541 0x09, 0x20, /* Usage (Stylus), */ 542 0xA0, /* Collection (Physical), */ 543 0x14, /* Logical Minimum (0), */ 544 0x25, 0x01, /* Logical Maximum (1), */ 545 0x75, 0x01, /* Report Size (1), */ 546 0x09, 0x42, /* Usage (Tip Switch), */ 547 0x09, 0x44, /* Usage (Barrel Switch), */ 548 0x09, 0x46, /* Usage (Tablet Pick), */ 549 0x95, 0x03, /* Report Count (3), */ 550 0x81, 0x02, /* Input (Variable), */ 551 0x95, 0x03, /* Report Count (3), */ 552 0x81, 0x03, /* Input (Constant, Variable), */ 553 0x09, 0x32, /* Usage (In Range), */ 554 0x95, 0x01, /* Report Count (1), */ 555 0x81, 0x02, /* Input (Variable), */ 556 0x95, 0x01, /* Report Count (1), */ 557 0x81, 0x03, /* Input (Constant, Variable), */ 558 0x75, 0x10, /* Report Size (16), */ 559 0x95, 0x01, /* Report Count (1), */ 560 0xA4, /* Push, */ 561 0x05, 0x01, /* Usage Page (Desktop), */ 562 0x65, 0x13, /* Unit (Inch), */ 563 0x55, 0xFD, /* Unit Exponent (-3), */ 564 0x34, /* Physical Minimum (0), */ 565 0x09, 0x30, /* Usage (X), */ 566 0x27, UCLOGIC_RDESC_PEN_PH(X_LM), 567 /* Logical Maximum (PLACEHOLDER), */ 568 0x47, UCLOGIC_RDESC_PEN_PH(X_PM), 569 /* Physical Maximum (PLACEHOLDER), */ 570 0x81, 0x02, /* Input (Variable), */ 571 0x09, 0x31, /* Usage (Y), */ 572 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM), 573 /* Logical Maximum (PLACEHOLDER), */ 574 0x47, UCLOGIC_RDESC_PEN_PH(Y_PM), 575 /* Physical Maximum (PLACEHOLDER), */ 576 0x81, 0x02, /* Input (Variable), */ 577 0xB4, /* Pop, */ 578 0x09, 0x30, /* Usage (Tip Pressure), */ 579 0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM), 580 /* Logical Maximum (PLACEHOLDER), */ 581 0x81, 0x02, /* Input (Variable), */ 582 0xC0, /* End Collection, */ 583 0xC0 /* End Collection */ 584 }; 585 586 const size_t uclogic_rdesc_v1_pen_template_size = 587 sizeof(uclogic_rdesc_v1_pen_template_arr); 588 589 /* Fixed report descriptor template for (tweaked) v2 pen reports */ 590 const __u8 uclogic_rdesc_v2_pen_template_arr[] = { 591 0x05, 0x0D, /* Usage Page (Digitizer), */ 592 0x09, 0x01, /* Usage (Digitizer), */ 593 0xA1, 0x01, /* Collection (Application), */ 594 0x85, 0x08, /* Report ID (8), */ 595 0x09, 0x20, /* Usage (Stylus), */ 596 0xA0, /* Collection (Physical), */ 597 0x14, /* Logical Minimum (0), */ 598 0x25, 0x01, /* Logical Maximum (1), */ 599 0x75, 0x01, /* Report Size (1), */ 600 0x09, 0x42, /* Usage (Tip Switch), */ 601 0x09, 0x44, /* Usage (Barrel Switch), */ 602 0x09, 0x46, /* Usage (Tablet Pick), */ 603 0x95, 0x03, /* Report Count (3), */ 604 0x81, 0x02, /* Input (Variable), */ 605 0x95, 0x03, /* Report Count (3), */ 606 0x81, 0x03, /* Input (Constant, Variable), */ 607 0x09, 0x32, /* Usage (In Range), */ 608 0x95, 0x01, /* Report Count (1), */ 609 0x81, 0x02, /* Input (Variable), */ 610 0x95, 0x01, /* Report Count (1), */ 611 0x81, 0x03, /* Input (Constant, Variable), */ 612 0x95, 0x01, /* Report Count (1), */ 613 0xA4, /* Push, */ 614 0x05, 0x01, /* Usage Page (Desktop), */ 615 0x65, 0x13, /* Unit (Inch), */ 616 0x55, 0xFD, /* Unit Exponent (-3), */ 617 0x75, 0x18, /* Report Size (24), */ 618 0x34, /* Physical Minimum (0), */ 619 0x09, 0x30, /* Usage (X), */ 620 0x27, UCLOGIC_RDESC_PEN_PH(X_LM), 621 /* Logical Maximum (PLACEHOLDER), */ 622 0x47, UCLOGIC_RDESC_PEN_PH(X_PM), 623 /* Physical Maximum (PLACEHOLDER), */ 624 0x81, 0x02, /* Input (Variable), */ 625 0x09, 0x31, /* Usage (Y), */ 626 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM), 627 /* Logical Maximum (PLACEHOLDER), */ 628 0x47, UCLOGIC_RDESC_PEN_PH(Y_PM), 629 /* Physical Maximum (PLACEHOLDER), */ 630 0x81, 0x02, /* Input (Variable), */ 631 0xB4, /* Pop, */ 632 0x09, 0x30, /* Usage (Tip Pressure), */ 633 0x75, 0x10, /* Report Size (16), */ 634 0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM), 635 /* Logical Maximum (PLACEHOLDER), */ 636 0x81, 0x02, /* Input (Variable), */ 637 0x54, /* Unit Exponent (0), */ 638 0x65, 0x14, /* Unit (Degrees), */ 639 0x35, 0xC4, /* Physical Minimum (-60), */ 640 0x45, 0x3C, /* Physical Maximum (60), */ 641 0x15, 0xC4, /* Logical Minimum (-60), */ 642 0x25, 0x3C, /* Logical Maximum (60), */ 643 0x75, 0x08, /* Report Size (8), */ 644 0x95, 0x02, /* Report Count (2), */ 645 0x09, 0x3D, /* Usage (X Tilt), */ 646 0x09, 0x3E, /* Usage (Y Tilt), */ 647 0x81, 0x02, /* Input (Variable), */ 648 0xC0, /* End Collection, */ 649 0xC0 /* End Collection */ 650 }; 651 652 const size_t uclogic_rdesc_v2_pen_template_size = 653 sizeof(uclogic_rdesc_v2_pen_template_arr); 654 655 /* 656 * Expand to the contents of a generic frame buttons report descriptor. 657 * 658 * @_id: The report ID to use. 659 * @_size: Size of the report to pad to, including report ID, bytes. 660 */ 661 #define UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(_id, _size) \ 662 0x05, 0x01, /* Usage Page (Desktop), */ \ 663 0x09, 0x07, /* Usage (Keypad), */ \ 664 0xA1, 0x01, /* Collection (Application), */ \ 665 0x85, (_id), /* Report ID (_id), */ \ 666 0x14, /* Logical Minimum (0), */ \ 667 0x25, 0x01, /* Logical Maximum (1), */ \ 668 0x75, 0x01, /* Report Size (1), */ \ 669 0x05, 0x0D, /* Usage Page (Digitizer), */ \ 670 0x09, 0x39, /* Usage (Tablet Function Keys), */ \ 671 0xA0, /* Collection (Physical), */ \ 672 0x09, 0x44, /* Usage (Barrel Switch), */ \ 673 0x95, 0x01, /* Report Count (1), */ \ 674 0x81, 0x02, /* Input (Variable), */ \ 675 0x05, 0x01, /* Usage Page (Desktop), */ \ 676 0x09, 0x30, /* Usage (X), */ \ 677 0x09, 0x31, /* Usage (Y), */ \ 678 0x95, 0x02, /* Report Count (2), */ \ 679 0x81, 0x02, /* Input (Variable), */ \ 680 0x95, 0x15, /* Report Count (21), */ \ 681 0x81, 0x01, /* Input (Constant), */ \ 682 0x05, 0x09, /* Usage Page (Button), */ \ 683 0x19, 0x01, /* Usage Minimum (01h), */ \ 684 0x29, 0x0A, /* Usage Maximum (0Ah), */ \ 685 0x95, 0x0A, /* Report Count (10), */ \ 686 0x81, 0x02, /* Input (Variable), */ \ 687 0xC0, /* End Collection, */ \ 688 0x05, 0x01, /* Usage Page (Desktop), */ \ 689 0x09, 0x05, /* Usage (Gamepad), */ \ 690 0xA0, /* Collection (Physical), */ \ 691 0x05, 0x09, /* Usage Page (Button), */ \ 692 0x19, 0x01, /* Usage Minimum (01h), */ \ 693 0x29, 0x0A, /* Usage Maximum (0Ah), */ \ 694 0x95, 0x0A, /* Report Count (10), */ \ 695 0x81, 0x02, /* Input (Variable), */ \ 696 0x95, ((_size) * 8 - 52), \ 697 /* Report Count (padding), */ \ 698 0x81, 0x01, /* Input (Constant), */ \ 699 0xC0, /* End Collection, */ \ 700 0xC0 /* End Collection */ 701 702 /* Fixed report descriptor for (tweaked) v1 frame reports */ 703 const __u8 uclogic_rdesc_v1_frame_arr[] = { 704 UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8) 705 }; 706 const size_t uclogic_rdesc_v1_frame_size = 707 sizeof(uclogic_rdesc_v1_frame_arr); 708 709 /* Fixed report descriptor for (tweaked) v2 frame button reports */ 710 const __u8 uclogic_rdesc_v2_frame_buttons_arr[] = { 711 UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID, 712 12) 713 }; 714 const size_t uclogic_rdesc_v2_frame_buttons_size = 715 sizeof(uclogic_rdesc_v2_frame_buttons_arr); 716 717 /* Fixed report descriptor for (tweaked) v2 frame touch ring reports */ 718 const __u8 uclogic_rdesc_v2_frame_touch_ring_arr[] = { 719 0x05, 0x01, /* Usage Page (Desktop), */ 720 0x09, 0x07, /* Usage (Keypad), */ 721 0xA1, 0x01, /* Collection (Application), */ 722 0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID, 723 /* Report ID (TOUCH_ID), */ 724 0x14, /* Logical Minimum (0), */ 725 0x05, 0x0D, /* Usage Page (Digitizer), */ 726 0x09, 0x39, /* Usage (Tablet Function Keys), */ 727 0xA0, /* Collection (Physical), */ 728 0x25, 0x01, /* Logical Maximum (1), */ 729 0x75, 0x01, /* Report Size (1), */ 730 0x05, 0x09, /* Usage Page (Button), */ 731 0x09, 0x01, /* Usage (01h), */ 732 0x95, 0x01, /* Report Count (1), */ 733 0x81, 0x02, /* Input (Variable), */ 734 0x95, 0x07, /* Report Count (7), */ 735 0x81, 0x01, /* Input (Constant), */ 736 0x75, 0x08, /* Report Size (8), */ 737 0x95, 0x02, /* Report Count (2), */ 738 0x81, 0x01, /* Input (Constant), */ 739 0x05, 0x0D, /* Usage Page (Digitizer), */ 740 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 741 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 742 0x95, 0x01, /* Report Count (1), */ 743 0x81, 0x02, /* Input (Variable), */ 744 0x05, 0x01, /* Usage Page (Desktop), */ 745 0x09, 0x38, /* Usage (Wheel), */ 746 0x95, 0x01, /* Report Count (1), */ 747 0x15, 0x00, /* Logical Minimum (0), */ 748 0x25, 0x0B, /* Logical Maximum (11), */ 749 0x81, 0x02, /* Input (Variable), */ 750 0x09, 0x30, /* Usage (X), */ 751 0x09, 0x31, /* Usage (Y), */ 752 0x14, /* Logical Minimum (0), */ 753 0x25, 0x01, /* Logical Maximum (1), */ 754 0x75, 0x01, /* Report Size (1), */ 755 0x95, 0x02, /* Report Count (2), */ 756 0x81, 0x02, /* Input (Variable), */ 757 0x95, 0x2E, /* Report Count (46), */ 758 0x81, 0x01, /* Input (Constant), */ 759 0xC0, /* End Collection, */ 760 0xC0 /* End Collection */ 761 }; 762 const size_t uclogic_rdesc_v2_frame_touch_ring_size = 763 sizeof(uclogic_rdesc_v2_frame_touch_ring_arr); 764 765 /* Fixed report descriptor for (tweaked) v2 frame touch strip reports */ 766 const __u8 uclogic_rdesc_v2_frame_touch_strip_arr[] = { 767 0x05, 0x01, /* Usage Page (Desktop), */ 768 0x09, 0x07, /* Usage (Keypad), */ 769 0xA1, 0x01, /* Collection (Application), */ 770 0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID, 771 /* Report ID (TOUCH_ID), */ 772 0x14, /* Logical Minimum (0), */ 773 0x05, 0x0D, /* Usage Page (Digitizer), */ 774 0x09, 0x39, /* Usage (Tablet Function Keys), */ 775 0xA0, /* Collection (Physical), */ 776 0x25, 0x01, /* Logical Maximum (1), */ 777 0x75, 0x01, /* Report Size (1), */ 778 0x05, 0x09, /* Usage Page (Button), */ 779 0x09, 0x01, /* Usage (01h), */ 780 0x95, 0x01, /* Report Count (1), */ 781 0x81, 0x02, /* Input (Variable), */ 782 0x95, 0x07, /* Report Count (7), */ 783 0x81, 0x01, /* Input (Constant), */ 784 0x75, 0x08, /* Report Size (8), */ 785 0x95, 0x02, /* Report Count (2), */ 786 0x81, 0x01, /* Input (Constant), */ 787 0x05, 0x0D, /* Usage Page (Digitizer), */ 788 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 789 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 790 0x95, 0x01, /* Report Count (1), */ 791 0x81, 0x02, /* Input (Variable), */ 792 0x05, 0x01, /* Usage Page (Desktop), */ 793 0x09, 0x33, /* Usage (Rx), */ 794 0x09, 0x34, /* Usage (Ry), */ 795 0x95, 0x01, /* Report Count (1), */ 796 0x15, 0x00, /* Logical Minimum (0), */ 797 0x25, 0x07, /* Logical Maximum (7), */ 798 0x81, 0x02, /* Input (Variable), */ 799 0x09, 0x30, /* Usage (X), */ 800 0x09, 0x31, /* Usage (Y), */ 801 0x14, /* Logical Minimum (0), */ 802 0x25, 0x01, /* Logical Maximum (1), */ 803 0x75, 0x01, /* Report Size (1), */ 804 0x95, 0x02, /* Report Count (2), */ 805 0x81, 0x02, /* Input (Variable), */ 806 0x95, 0x2E, /* Report Count (46), */ 807 0x81, 0x01, /* Input (Constant), */ 808 0xC0, /* End Collection, */ 809 0xC0 /* End Collection */ 810 }; 811 const size_t uclogic_rdesc_v2_frame_touch_strip_size = 812 sizeof(uclogic_rdesc_v2_frame_touch_strip_arr); 813 814 /* Fixed report descriptor for (tweaked) v2 frame dial reports */ 815 const __u8 uclogic_rdesc_v2_frame_dial_arr[] = { 816 0x05, 0x01, /* Usage Page (Desktop), */ 817 0x09, 0x07, /* Usage (Keypad), */ 818 0xA1, 0x01, /* Collection (Application), */ 819 0x85, UCLOGIC_RDESC_V2_FRAME_DIAL_ID, 820 /* Report ID (DIAL_ID), */ 821 0x14, /* Logical Minimum (0), */ 822 0x05, 0x0D, /* Usage Page (Digitizer), */ 823 0x09, 0x39, /* Usage (Tablet Function Keys), */ 824 0xA0, /* Collection (Physical), */ 825 0x25, 0x01, /* Logical Maximum (1), */ 826 0x75, 0x01, /* Report Size (1), */ 827 0x95, 0x01, /* Report Count (1), */ 828 0x81, 0x01, /* Input (Constant), */ 829 0x05, 0x09, /* Usage Page (Button), */ 830 0x09, 0x01, /* Usage (01h), */ 831 0x95, 0x01, /* Report Count (1), */ 832 0x81, 0x02, /* Input (Variable), */ 833 0x95, 0x06, /* Report Count (6), */ 834 0x81, 0x01, /* Input (Constant), */ 835 0x75, 0x08, /* Report Size (8), */ 836 0x95, 0x02, /* Report Count (2), */ 837 0x81, 0x01, /* Input (Constant), */ 838 0x05, 0x0D, /* Usage Page (Digitizer), */ 839 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 840 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 841 0x95, 0x01, /* Report Count (1), */ 842 0x81, 0x02, /* Input (Variable), */ 843 0x05, 0x01, /* Usage Page (Desktop), */ 844 0x09, 0x38, /* Usage (Wheel), */ 845 0x95, 0x01, /* Report Count (1), */ 846 0x15, 0xFF, /* Logical Minimum (-1), */ 847 0x25, 0x01, /* Logical Maximum (1), */ 848 0x81, 0x06, /* Input (Variable, Relative), */ 849 0x09, 0x30, /* Usage (X), */ 850 0x09, 0x31, /* Usage (Y), */ 851 0x14, /* Logical Minimum (0), */ 852 0x25, 0x01, /* Logical Maximum (1), */ 853 0x75, 0x01, /* Report Size (1), */ 854 0x95, 0x02, /* Report Count (2), */ 855 0x81, 0x02, /* Input (Variable), */ 856 0x95, 0x2E, /* Report Count (46), */ 857 0x81, 0x01, /* Input (Constant), */ 858 0xC0, /* End Collection, */ 859 0xC0 /* End Collection */ 860 }; 861 const size_t uclogic_rdesc_v2_frame_dial_size = 862 sizeof(uclogic_rdesc_v2_frame_dial_arr); 863 864 const __u8 uclogic_ugee_v2_probe_arr[] = { 865 0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 866 }; 867 const size_t uclogic_ugee_v2_probe_size = sizeof(uclogic_ugee_v2_probe_arr); 868 const int uclogic_ugee_v2_probe_endpoint = 0x03; 869 870 /* Fixed report descriptor template for UGEE v2 pen reports */ 871 const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[] = { 872 0x05, 0x0d, /* Usage Page (Digitizers), */ 873 0x09, 0x01, /* Usage (Digitizer), */ 874 0xa1, 0x01, /* Collection (Application), */ 875 0x85, 0x02, /* Report ID (2), */ 876 0x09, 0x20, /* Usage (Stylus), */ 877 0xa1, 0x00, /* Collection (Physical), */ 878 0x09, 0x42, /* Usage (Tip Switch), */ 879 0x09, 0x44, /* Usage (Barrel Switch), */ 880 0x09, 0x46, /* Usage (Tablet Pick), */ 881 0x75, 0x01, /* Report Size (1), */ 882 0x95, 0x03, /* Report Count (3), */ 883 0x14, /* Logical Minimum (0), */ 884 0x25, 0x01, /* Logical Maximum (1), */ 885 0x81, 0x02, /* Input (Variable), */ 886 0x95, 0x02, /* Report Count (2), */ 887 0x81, 0x03, /* Input (Constant, Variable), */ 888 0x09, 0x32, /* Usage (In Range), */ 889 0x95, 0x01, /* Report Count (1), */ 890 0x81, 0x02, /* Input (Variable), */ 891 0x95, 0x02, /* Report Count (2), */ 892 0x81, 0x03, /* Input (Constant, Variable), */ 893 0x75, 0x10, /* Report Size (16), */ 894 0x95, 0x01, /* Report Count (1), */ 895 0x35, 0x00, /* Physical Minimum (0), */ 896 0xa4, /* Push, */ 897 0x05, 0x01, /* Usage Page (Desktop), */ 898 0x09, 0x30, /* Usage (X), */ 899 0x65, 0x13, /* Unit (Inch), */ 900 0x55, 0x0d, /* Unit Exponent (-3), */ 901 0x27, UCLOGIC_RDESC_PEN_PH(X_LM), 902 /* Logical Maximum (PLACEHOLDER), */ 903 0x47, UCLOGIC_RDESC_PEN_PH(X_PM), 904 /* Physical Maximum (PLACEHOLDER), */ 905 0x81, 0x02, /* Input (Variable), */ 906 0x09, 0x31, /* Usage (Y), */ 907 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM), 908 /* Logical Maximum (PLACEHOLDER), */ 909 0x47, UCLOGIC_RDESC_PEN_PH(Y_PM), 910 /* Physical Maximum (PLACEHOLDER), */ 911 0x81, 0x02, /* Input (Variable), */ 912 0xb4, /* Pop, */ 913 0x09, 0x30, /* Usage (Tip Pressure), */ 914 0x45, 0x00, /* Physical Maximum (0), */ 915 0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM), 916 /* Logical Maximum (PLACEHOLDER), */ 917 0x75, 0x0D, /* Report Size (13), */ 918 0x95, 0x01, /* Report Count (1), */ 919 0x81, 0x02, /* Input (Variable), */ 920 0x75, 0x01, /* Report Size (1), */ 921 0x95, 0x03, /* Report Count (3), */ 922 0x81, 0x01, /* Input (Constant), */ 923 0x09, 0x3d, /* Usage (X 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 0x75, 0x08, /* Report Size (8), */ 929 0x95, 0x01, /* Report Count (1), */ 930 0x81, 0x02, /* Input (Variable), */ 931 0x09, 0x3e, /* Usage (Y Tilt), */ 932 0x35, 0xC3, /* Physical Minimum (-61), */ 933 0x45, 0x3C, /* Physical Maximum (60), */ 934 0x15, 0xC3, /* Logical Minimum (-61), */ 935 0x25, 0x3C, /* Logical Maximum (60), */ 936 0x81, 0x02, /* Input (Variable), */ 937 0xc0, /* End Collection, */ 938 0xc0, /* End Collection */ 939 }; 940 const size_t uclogic_rdesc_ugee_v2_pen_template_size = 941 sizeof(uclogic_rdesc_ugee_v2_pen_template_arr); 942 943 /* Fixed report descriptor template for UGEE v2 frame reports (buttons only) */ 944 const __u8 uclogic_rdesc_ugee_v2_frame_btn_template_arr[] = { 945 0x05, 0x01, /* Usage Page (Desktop), */ 946 0x09, 0x07, /* Usage (Keypad), */ 947 0xA1, 0x01, /* Collection (Application), */ 948 0x85, UCLOGIC_RDESC_V1_FRAME_ID, 949 /* Report ID, */ 950 0x05, 0x0D, /* Usage Page (Digitizer), */ 951 0x09, 0x39, /* Usage (Tablet Function Keys), */ 952 0xA0, /* Collection (Physical), */ 953 0x75, 0x01, /* Report Size (1), */ 954 0x95, 0x08, /* Report Count (8), */ 955 0x81, 0x01, /* Input (Constant), */ 956 0x05, 0x09, /* Usage Page (Button), */ 957 0x19, 0x01, /* Usage Minimum (01h), */ 958 UCLOGIC_RDESC_FRAME_PH_BTN, 959 /* Usage Maximum (PLACEHOLDER), */ 960 0x95, 0x0A, /* Report Count (10), */ 961 0x14, /* Logical Minimum (0), */ 962 0x25, 0x01, /* Logical Maximum (1), */ 963 0x81, 0x02, /* Input (Variable), */ 964 0x95, 0x46, /* Report Count (70), */ 965 0x81, 0x01, /* Input (Constant), */ 966 0xC0, /* End Collection, */ 967 0xC0 /* End Collection */ 968 }; 969 const size_t uclogic_rdesc_ugee_v2_frame_btn_template_size = 970 sizeof(uclogic_rdesc_ugee_v2_frame_btn_template_arr); 971 972 /* Fixed report descriptor template for UGEE v2 frame reports (dial) */ 973 const __u8 uclogic_rdesc_ugee_v2_frame_dial_template_arr[] = { 974 0x05, 0x01, /* Usage Page (Desktop), */ 975 0x09, 0x07, /* Usage (Keypad), */ 976 0xA1, 0x01, /* Collection (Application), */ 977 0x85, UCLOGIC_RDESC_V1_FRAME_ID, 978 /* Report ID, */ 979 0x05, 0x0D, /* Usage Page (Digitizer), */ 980 0x09, 0x39, /* Usage (Tablet Function Keys), */ 981 0xA0, /* Collection (Physical), */ 982 0x75, 0x01, /* Report Size (1), */ 983 0x95, 0x08, /* Report Count (8), */ 984 0x81, 0x01, /* Input (Constant), */ 985 0x05, 0x09, /* Usage Page (Button), */ 986 0x19, 0x01, /* Usage Minimum (01h), */ 987 UCLOGIC_RDESC_FRAME_PH_BTN, 988 /* Usage Maximum (PLACEHOLDER), */ 989 0x95, 0x0A, /* Report Count (10), */ 990 0x14, /* Logical Minimum (0), */ 991 0x25, 0x01, /* Logical Maximum (1), */ 992 0x81, 0x02, /* Input (Variable), */ 993 0x95, 0x06, /* Report Count (6), */ 994 0x81, 0x01, /* Input (Constant), */ 995 0x75, 0x08, /* Report Size (8), */ 996 0x95, 0x03, /* Report Count (3), */ 997 0x81, 0x01, /* Input (Constant), */ 998 0x05, 0x01, /* Usage Page (Desktop), */ 999 0x09, 0x38, /* Usage (Wheel), */ 1000 0x95, 0x01, /* Report Count (1), */ 1001 0x15, 0xFF, /* Logical Minimum (-1), */ 1002 0x25, 0x01, /* Logical Maximum (1), */ 1003 0x81, 0x06, /* Input (Variable, Relative), */ 1004 0x95, 0x02, /* Report Count (2), */ 1005 0x81, 0x01, /* Input (Constant), */ 1006 0xC0, /* End Collection, */ 1007 0xC0 /* End Collection */ 1008 }; 1009 const size_t uclogic_rdesc_ugee_v2_frame_dial_template_size = 1010 sizeof(uclogic_rdesc_ugee_v2_frame_dial_template_arr); 1011 1012 /* Fixed report descriptor template for UGEE v2 frame reports (mouse) */ 1013 const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[] = { 1014 0x05, 0x01, /* Usage Page (Desktop), */ 1015 0x09, 0x02, /* Usage (Mouse), */ 1016 0xA1, 0x01, /* Collection (Application), */ 1017 0x85, 0x01, /* Report ID (1), */ 1018 0x05, 0x01, /* Usage Page (Pointer), */ 1019 0xA0, /* Collection (Physical), */ 1020 0x75, 0x01, /* Report Size (1), */ 1021 0x95, 0x02, /* Report Count (2), */ 1022 0x05, 0x09, /* Usage Page (Button), */ 1023 0x19, 0x01, /* Usage Minimum (01h), */ 1024 0x29, 0x02, /* Usage Maximum (02h), */ 1025 0x14, /* Logical Minimum (0), */ 1026 0x25, 0x01, /* Logical Maximum (1), */ 1027 0x81, 0x02, /* Input (Variable), */ 1028 0x95, 0x06, /* Report Count (6), */ 1029 0x81, 0x01, /* Input (Constant), */ 1030 0x05, 0x01, /* Usage Page (Generic Desktop), */ 1031 0x09, 0x30, /* Usage (X), */ 1032 0x09, 0x31, /* Usage (Y), */ 1033 0x75, 0x10, /* Report Size (16), */ 1034 0x95, 0x02, /* Report Count (2), */ 1035 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 1036 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 1037 0x81, 0x06, /* Input (Variable, Relative), */ 1038 0x95, 0x01, /* Report Count (1), */ 1039 0x81, 0x01, /* Input (Constant), */ 1040 0xC0, /* End Collection, */ 1041 0xC0 /* End Collection */ 1042 }; 1043 const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size = 1044 sizeof(uclogic_rdesc_ugee_v2_frame_mouse_template_arr); 1045 1046 /* Fixed report descriptor template for UGEE v2 battery reports */ 1047 const __u8 uclogic_rdesc_ugee_v2_battery_template_arr[] = { 1048 0x05, 0x01, /* Usage Page (Desktop), */ 1049 0x09, 0x07, /* Usage (Keypad), */ 1050 0xA1, 0x01, /* Collection (Application), */ 1051 0x85, UCLOGIC_RDESC_UGEE_V2_BATTERY_ID, 1052 /* Report ID, */ 1053 0x75, 0x08, /* Report Size (8), */ 1054 0x95, 0x02, /* Report Count (2), */ 1055 0x81, 0x01, /* Input (Constant), */ 1056 0x05, 0x84, /* Usage Page (Power Device), */ 1057 0x05, 0x85, /* Usage Page (Battery System), */ 1058 0x09, 0x65, /* Usage Page (AbsoluteStateOfCharge), */ 1059 0x75, 0x08, /* Report Size (8), */ 1060 0x95, 0x01, /* Report Count (1), */ 1061 0x15, 0x00, /* Logical Minimum (0), */ 1062 0x26, 0xff, 0x00, /* Logical Maximum (255), */ 1063 0x81, 0x02, /* Input (Variable), */ 1064 0x75, 0x01, /* Report Size (1), */ 1065 0x95, 0x01, /* Report Count (1), */ 1066 0x15, 0x00, /* Logical Minimum (0), */ 1067 0x25, 0x01, /* Logical Maximum (1), */ 1068 0x09, 0x44, /* Usage Page (Charging), */ 1069 0x81, 0x02, /* Input (Variable), */ 1070 0x95, 0x07, /* Report Count (7), */ 1071 0x81, 0x01, /* Input (Constant), */ 1072 0x75, 0x08, /* Report Size (8), */ 1073 0x95, 0x07, /* Report Count (7), */ 1074 0x81, 0x01, /* Input (Constant), */ 1075 0xC0 /* End Collection */ 1076 }; 1077 const size_t uclogic_rdesc_ugee_v2_battery_template_size = 1078 sizeof(uclogic_rdesc_ugee_v2_battery_template_arr); 1079 1080 /* Fixed report descriptor for Ugee EX07 frame */ 1081 const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = { 1082 0x05, 0x01, /* Usage Page (Desktop), */ 1083 0x09, 0x07, /* Usage (Keypad), */ 1084 0xA1, 0x01, /* Collection (Application), */ 1085 0x85, 0x06, /* Report ID (6), */ 1086 0x05, 0x0D, /* Usage Page (Digitizer), */ 1087 0x09, 0x39, /* Usage (Tablet Function Keys), */ 1088 0xA0, /* Collection (Physical), */ 1089 0x05, 0x09, /* Usage Page (Button), */ 1090 0x75, 0x01, /* Report Size (1), */ 1091 0x19, 0x03, /* Usage Minimum (03h), */ 1092 0x29, 0x06, /* Usage Maximum (06h), */ 1093 0x95, 0x04, /* Report Count (4), */ 1094 0x81, 0x02, /* Input (Variable), */ 1095 0x95, 0x1A, /* Report Count (26), */ 1096 0x81, 0x03, /* Input (Constant, Variable), */ 1097 0x19, 0x01, /* Usage Minimum (01h), */ 1098 0x29, 0x02, /* Usage Maximum (02h), */ 1099 0x95, 0x02, /* Report Count (2), */ 1100 0x81, 0x02, /* Input (Variable), */ 1101 0xC0, /* End Collection, */ 1102 0xC0 /* End Collection */ 1103 }; 1104 const size_t uclogic_rdesc_ugee_ex07_frame_size = 1105 sizeof(uclogic_rdesc_ugee_ex07_frame_arr); 1106 1107 /* Fixed report descriptor for Ugee G5 frame controls */ 1108 const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = { 1109 0x05, 0x01, /* Usage Page (Desktop), */ 1110 0x09, 0x07, /* Usage (Keypad), */ 1111 0xA1, 0x01, /* Collection (Application), */ 1112 0x85, 0x06, /* Report ID (6), */ 1113 0x05, 0x0D, /* Usage Page (Digitizer), */ 1114 0x09, 0x39, /* Usage (Tablet Function Keys), */ 1115 0xA0, /* Collection (Physical), */ 1116 0x14, /* Logical Minimum (0), */ 1117 0x25, 0x01, /* Logical Maximum (1), */ 1118 0x05, 0x01, /* Usage Page (Desktop), */ 1119 0x05, 0x09, /* Usage Page (Button), */ 1120 0x19, 0x01, /* Usage Minimum (01h), */ 1121 0x29, 0x05, /* Usage Maximum (05h), */ 1122 0x75, 0x01, /* Report Size (1), */ 1123 0x95, 0x05, /* Report Count (5), */ 1124 0x81, 0x02, /* Input (Variable), */ 1125 0x75, 0x01, /* Report Size (1), */ 1126 0x95, 0x03, /* Report Count (3), */ 1127 0x81, 0x01, /* Input (Constant), */ 1128 0x05, 0x0D, /* Usage Page (Digitizer), */ 1129 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 1130 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 1131 0x75, 0x08, /* Report Size (8), */ 1132 0x95, 0x01, /* Report Count (1), */ 1133 0x81, 0x02, /* Input (Variable), */ 1134 0x25, 0x01, /* Logical Maximum (1), */ 1135 0x09, 0x44, /* Usage (Barrel Switch), */ 1136 0x75, 0x01, /* Report Size (1), */ 1137 0x95, 0x01, /* Report Count (1), */ 1138 0x81, 0x02, /* Input (Variable), */ 1139 0x05, 0x01, /* Usage Page (Desktop), */ 1140 0x09, 0x30, /* Usage (X), */ 1141 0x09, 0x31, /* Usage (Y), */ 1142 0x75, 0x01, /* Report Size (1), */ 1143 0x95, 0x02, /* Report Count (2), */ 1144 0x81, 0x02, /* Input (Variable), */ 1145 0x75, 0x01, /* Report Size (1), */ 1146 0x95, 0x0B, /* Report Count (11), */ 1147 0x81, 0x01, /* Input (Constant), */ 1148 0x05, 0x01, /* Usage Page (Desktop), */ 1149 0x09, 0x38, /* Usage (Wheel), */ 1150 0x15, 0xFF, /* Logical Minimum (-1), */ 1151 0x25, 0x01, /* Logical Maximum (1), */ 1152 0x75, 0x02, /* Report Size (2), */ 1153 0x95, 0x01, /* Report Count (1), */ 1154 0x81, 0x06, /* Input (Variable, Relative), */ 1155 0xC0, /* End Collection, */ 1156 0xC0 /* End Collection */ 1157 }; 1158 const size_t uclogic_rdesc_ugee_g5_frame_size = 1159 sizeof(uclogic_rdesc_ugee_g5_frame_arr); 1160 1161 /* Fixed report descriptor for XP-Pen Deco 01 frame controls */ 1162 const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = { 1163 0x05, 0x01, /* Usage Page (Desktop), */ 1164 0x09, 0x07, /* Usage (Keypad), */ 1165 0xA1, 0x01, /* Collection (Application), */ 1166 0x85, 0x06, /* Report ID (6), */ 1167 0x14, /* Logical Minimum (0), */ 1168 0x25, 0x01, /* Logical Maximum (1), */ 1169 0x75, 0x01, /* Report Size (1), */ 1170 0x05, 0x0D, /* Usage Page (Digitizer), */ 1171 0x09, 0x39, /* Usage (Tablet Function Keys), */ 1172 0xA0, /* Collection (Physical), */ 1173 0x05, 0x09, /* Usage Page (Button), */ 1174 0x19, 0x01, /* Usage Minimum (01h), */ 1175 0x29, 0x08, /* Usage Maximum (08h), */ 1176 0x95, 0x08, /* Report Count (8), */ 1177 0x81, 0x02, /* Input (Variable), */ 1178 0x05, 0x0D, /* Usage Page (Digitizer), */ 1179 0x09, 0x44, /* Usage (Barrel Switch), */ 1180 0x95, 0x01, /* Report Count (1), */ 1181 0x81, 0x02, /* Input (Variable), */ 1182 0x05, 0x01, /* Usage Page (Desktop), */ 1183 0x09, 0x30, /* Usage (X), */ 1184 0x09, 0x31, /* Usage (Y), */ 1185 0x95, 0x02, /* Report Count (2), */ 1186 0x81, 0x02, /* Input (Variable), */ 1187 0x95, 0x15, /* Report Count (21), */ 1188 0x81, 0x01, /* Input (Constant), */ 1189 0xC0, /* End Collection, */ 1190 0xC0 /* End Collection */ 1191 }; 1192 1193 const size_t uclogic_rdesc_xppen_deco01_frame_size = 1194 sizeof(uclogic_rdesc_xppen_deco01_frame_arr); 1195 1196 /** 1197 * uclogic_rdesc_template_apply() - apply report descriptor parameters to a 1198 * report descriptor template, creating a report descriptor. Copies the 1199 * template over to the new report descriptor and replaces every occurrence of 1200 * the template placeholders, followed by an index byte, with the value from the 1201 * parameter list at that index. 1202 * 1203 * @template_ptr: Pointer to the template buffer. 1204 * @template_size: Size of the template buffer. 1205 * @param_list: List of template parameters. 1206 * @param_num: Number of parameters in the list. 1207 * 1208 * Returns: 1209 * Kmalloc-allocated pointer to the created report descriptor, 1210 * or NULL if allocation failed. 1211 */ 1212 __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr, 1213 size_t template_size, 1214 const s32 *param_list, 1215 size_t param_num) 1216 { 1217 static const __u8 btn_head[] = {UCLOGIC_RDESC_FRAME_PH_BTN_HEAD}; 1218 static const __u8 pen_head[] = {UCLOGIC_RDESC_PEN_PH_HEAD}; 1219 __u8 *rdesc_ptr; 1220 __u8 *p; 1221 s32 v; 1222 1223 rdesc_ptr = kmemdup(template_ptr, template_size, GFP_KERNEL); 1224 if (rdesc_ptr == NULL) 1225 return NULL; 1226 1227 for (p = rdesc_ptr; p + sizeof(btn_head) < rdesc_ptr + template_size;) { 1228 if (p + sizeof(pen_head) < rdesc_ptr + template_size && 1229 memcmp(p, pen_head, sizeof(pen_head)) == 0 && 1230 p[sizeof(pen_head)] < param_num) { 1231 v = param_list[p[sizeof(pen_head)]]; 1232 put_unaligned((__force u32)cpu_to_le32(v), (s32 *)p); 1233 p += sizeof(pen_head) + 1; 1234 } else if (memcmp(p, btn_head, sizeof(btn_head)) == 0 && 1235 p[sizeof(btn_head)] < param_num) { 1236 v = param_list[p[sizeof(btn_head)]]; 1237 put_unaligned((__u8)0x2A, p); /* Usage Maximum */ 1238 put_unaligned((__force u16)cpu_to_le16(v), (s16 *)(p + 1)); 1239 p += sizeof(btn_head) + 1; 1240 } else { 1241 p++; 1242 } 1243 } 1244 1245 return rdesc_ptr; 1246 } 1247 EXPORT_SYMBOL_IF_KUNIT(uclogic_rdesc_template_apply); 1248