1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * HID driver for UC-Logic devices not fully compliant with HID standard 4 * - original and fixed report descriptors 5 * 6 * Copyright (c) 2010-2017 Nikolai Kondrashov 7 * Copyright (c) 2013 Martin Rusko 8 */ 9 10 /* 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License as published by the Free 13 * Software Foundation; either version 2 of the License, or (at your option) 14 * any later version. 15 */ 16 17 #include "hid-uclogic-rdesc.h" 18 #include <linux/slab.h> 19 #include <asm/unaligned.h> 20 21 /* Fixed WP4030U report descriptor */ 22 __u8 uclogic_rdesc_wp4030u_fixed_arr[] = { 23 0x05, 0x0D, /* Usage Page (Digitizer), */ 24 0x09, 0x02, /* Usage (Pen), */ 25 0xA1, 0x01, /* Collection (Application), */ 26 0x85, 0x09, /* Report ID (9), */ 27 0x09, 0x20, /* Usage (Stylus), */ 28 0xA0, /* Collection (Physical), */ 29 0x75, 0x01, /* Report Size (1), */ 30 0x09, 0x42, /* Usage (Tip Switch), */ 31 0x09, 0x44, /* Usage (Barrel Switch), */ 32 0x09, 0x46, /* Usage (Tablet Pick), */ 33 0x14, /* Logical Minimum (0), */ 34 0x25, 0x01, /* Logical Maximum (1), */ 35 0x95, 0x03, /* Report Count (3), */ 36 0x81, 0x02, /* Input (Variable), */ 37 0x95, 0x05, /* Report Count (5), */ 38 0x81, 0x01, /* Input (Constant), */ 39 0x75, 0x10, /* Report Size (16), */ 40 0x95, 0x01, /* Report Count (1), */ 41 0x14, /* Logical Minimum (0), */ 42 0xA4, /* Push, */ 43 0x05, 0x01, /* Usage Page (Desktop), */ 44 0x55, 0xFD, /* Unit Exponent (-3), */ 45 0x65, 0x13, /* Unit (Inch), */ 46 0x34, /* Physical Minimum (0), */ 47 0x09, 0x30, /* Usage (X), */ 48 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */ 49 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 50 0x81, 0x02, /* Input (Variable), */ 51 0x09, 0x31, /* Usage (Y), */ 52 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */ 53 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 54 0x81, 0x02, /* Input (Variable), */ 55 0xB4, /* Pop, */ 56 0x09, 0x30, /* Usage (Tip Pressure), */ 57 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 58 0x81, 0x02, /* Input (Variable), */ 59 0xC0, /* End Collection, */ 60 0xC0 /* End Collection */ 61 }; 62 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, 0x02, /* Usage (Pen), */ 70 0xA1, 0x01, /* Collection (Application), */ 71 0x85, 0x09, /* Report ID (9), */ 72 0x09, 0x20, /* Usage (Stylus), */ 73 0xA0, /* Collection (Physical), */ 74 0x75, 0x01, /* Report Size (1), */ 75 0x09, 0x42, /* Usage (Tip Switch), */ 76 0x09, 0x44, /* Usage (Barrel Switch), */ 77 0x09, 0x46, /* Usage (Tablet Pick), */ 78 0x14, /* Logical Minimum (0), */ 79 0x25, 0x01, /* Logical Maximum (1), */ 80 0x95, 0x03, /* Report Count (3), */ 81 0x81, 0x02, /* Input (Variable), */ 82 0x95, 0x05, /* Report Count (5), */ 83 0x81, 0x01, /* Input (Constant), */ 84 0x75, 0x10, /* Report Size (16), */ 85 0x95, 0x01, /* Report Count (1), */ 86 0x14, /* Logical Minimum (0), */ 87 0xA4, /* Push, */ 88 0x05, 0x01, /* Usage Page (Desktop), */ 89 0x55, 0xFD, /* Unit Exponent (-3), */ 90 0x65, 0x13, /* Unit (Inch), */ 91 0x34, /* Physical Minimum (0), */ 92 0x09, 0x30, /* Usage (X), */ 93 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */ 94 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 95 0x81, 0x02, /* Input (Variable), */ 96 0x09, 0x31, /* Usage (Y), */ 97 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */ 98 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 99 0x81, 0x02, /* Input (Variable), */ 100 0xB4, /* Pop, */ 101 0x09, 0x30, /* Usage (Tip Pressure), */ 102 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 103 0x81, 0x02, /* Input (Variable), */ 104 0xC0, /* End Collection, */ 105 0xC0, /* End Collection, */ 106 0x05, 0x01, /* Usage Page (Desktop), */ 107 0x09, 0x02, /* Usage (Mouse), */ 108 0xA1, 0x01, /* Collection (Application), */ 109 0x85, 0x08, /* Report ID (8), */ 110 0x09, 0x01, /* Usage (Pointer), */ 111 0xA0, /* Collection (Physical), */ 112 0x75, 0x01, /* Report Size (1), */ 113 0x05, 0x09, /* Usage Page (Button), */ 114 0x19, 0x01, /* Usage Minimum (01h), */ 115 0x29, 0x03, /* Usage Maximum (03h), */ 116 0x14, /* Logical Minimum (0), */ 117 0x25, 0x01, /* Logical Maximum (1), */ 118 0x95, 0x03, /* Report Count (3), */ 119 0x81, 0x02, /* Input (Variable), */ 120 0x95, 0x05, /* Report Count (5), */ 121 0x81, 0x01, /* Input (Constant), */ 122 0x05, 0x01, /* Usage Page (Desktop), */ 123 0x75, 0x08, /* Report Size (8), */ 124 0x09, 0x30, /* Usage (X), */ 125 0x09, 0x31, /* Usage (Y), */ 126 0x15, 0x81, /* Logical Minimum (-127), */ 127 0x25, 0x7F, /* Logical Maximum (127), */ 128 0x95, 0x02, /* Report Count (2), */ 129 0x81, 0x06, /* Input (Variable, Relative), */ 130 0x09, 0x38, /* Usage (Wheel), */ 131 0x15, 0xFF, /* Logical Minimum (-1), */ 132 0x25, 0x01, /* Logical Maximum (1), */ 133 0x95, 0x01, /* Report Count (1), */ 134 0x81, 0x06, /* Input (Variable, Relative), */ 135 0x81, 0x01, /* Input (Constant), */ 136 0xC0, /* End Collection, */ 137 0xC0 /* End Collection */ 138 }; 139 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, 0x02, /* Usage (Pen), */ 147 0xA1, 0x01, /* Collection (Application), */ 148 0x85, 0x09, /* Report ID (9), */ 149 0x09, 0x20, /* Usage (Stylus), */ 150 0xA0, /* Collection (Physical), */ 151 0x75, 0x01, /* Report Size (1), */ 152 0x09, 0x42, /* Usage (Tip Switch), */ 153 0x09, 0x44, /* Usage (Barrel Switch), */ 154 0x09, 0x46, /* Usage (Tablet Pick), */ 155 0x14, /* Logical Minimum (0), */ 156 0x25, 0x01, /* Logical Maximum (1), */ 157 0x95, 0x03, /* Report Count (3), */ 158 0x81, 0x02, /* Input (Variable), */ 159 0x95, 0x05, /* Report Count (5), */ 160 0x81, 0x01, /* Input (Constant), */ 161 0x75, 0x10, /* Report Size (16), */ 162 0x95, 0x01, /* Report Count (1), */ 163 0x14, /* Logical Minimum (0), */ 164 0xA4, /* Push, */ 165 0x05, 0x01, /* Usage Page (Desktop), */ 166 0x55, 0xFD, /* Unit Exponent (-3), */ 167 0x65, 0x13, /* Unit (Inch), */ 168 0x34, /* Physical Minimum (0), */ 169 0x09, 0x30, /* Usage (X), */ 170 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ 171 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 172 0x81, 0x02, /* Input (Variable), */ 173 0x09, 0x31, /* Usage (Y), */ 174 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ 175 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 176 0x81, 0x02, /* Input (Variable), */ 177 0xB4, /* Pop, */ 178 0x09, 0x30, /* Usage (Tip Pressure), */ 179 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 180 0x81, 0x02, /* Input (Variable), */ 181 0xC0, /* End Collection, */ 182 0xC0, /* End Collection, */ 183 0x05, 0x01, /* Usage Page (Desktop), */ 184 0x09, 0x02, /* Usage (Mouse), */ 185 0xA1, 0x01, /* Collection (Application), */ 186 0x85, 0x08, /* Report ID (8), */ 187 0x09, 0x01, /* Usage (Pointer), */ 188 0xA0, /* Collection (Physical), */ 189 0x75, 0x01, /* Report Size (1), */ 190 0x05, 0x09, /* Usage Page (Button), */ 191 0x19, 0x01, /* Usage Minimum (01h), */ 192 0x29, 0x03, /* Usage Maximum (03h), */ 193 0x14, /* Logical Minimum (0), */ 194 0x25, 0x01, /* Logical Maximum (1), */ 195 0x95, 0x03, /* Report Count (3), */ 196 0x81, 0x02, /* Input (Variable), */ 197 0x95, 0x05, /* Report Count (5), */ 198 0x81, 0x01, /* Input (Constant), */ 199 0x05, 0x01, /* Usage Page (Desktop), */ 200 0x75, 0x08, /* Report Size (8), */ 201 0x09, 0x30, /* Usage (X), */ 202 0x09, 0x31, /* Usage (Y), */ 203 0x15, 0x81, /* Logical Minimum (-127), */ 204 0x25, 0x7F, /* Logical Maximum (127), */ 205 0x95, 0x02, /* Report Count (2), */ 206 0x81, 0x06, /* Input (Variable, Relative), */ 207 0x09, 0x38, /* Usage (Wheel), */ 208 0x15, 0xFF, /* Logical Minimum (-1), */ 209 0x25, 0x01, /* Logical Maximum (1), */ 210 0x95, 0x01, /* Report Count (1), */ 211 0x81, 0x06, /* Input (Variable, Relative), */ 212 0x81, 0x01, /* Input (Constant), */ 213 0xC0, /* End Collection, */ 214 0xC0 /* End Collection */ 215 }; 216 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, 0x02, /* Usage (Pen), */ 224 0xA1, 0x01, /* Collection (Application), */ 225 0x85, 0x09, /* Report ID (9), */ 226 0x09, 0x20, /* Usage (Stylus), */ 227 0xA0, /* Collection (Physical), */ 228 0x75, 0x01, /* Report Size (1), */ 229 0x09, 0x42, /* Usage (Tip Switch), */ 230 0x09, 0x44, /* Usage (Barrel Switch), */ 231 0x09, 0x46, /* Usage (Tablet Pick), */ 232 0x14, /* Logical Minimum (0), */ 233 0x25, 0x01, /* Logical Maximum (1), */ 234 0x95, 0x03, /* Report Count (3), */ 235 0x81, 0x02, /* Input (Variable), */ 236 0x95, 0x04, /* Report Count (4), */ 237 0x81, 0x01, /* Input (Constant), */ 238 0x09, 0x32, /* Usage (In Range), */ 239 0x95, 0x01, /* Report Count (1), */ 240 0x81, 0x02, /* Input (Variable), */ 241 0x75, 0x10, /* Report Size (16), */ 242 0x95, 0x01, /* Report Count (1), */ 243 0x14, /* Logical Minimum (0), */ 244 0xA4, /* Push, */ 245 0x05, 0x01, /* Usage Page (Desktop), */ 246 0x55, 0xFD, /* Unit Exponent (-3), */ 247 0x65, 0x13, /* Unit (Inch), */ 248 0x34, /* Physical Minimum (0), */ 249 0x09, 0x30, /* Usage (X), */ 250 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ 251 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ 252 0x81, 0x02, /* Input (Variable), */ 253 0x09, 0x31, /* Usage (Y), */ 254 0x46, 0xB7, 0x19, /* Physical Maximum (6583), */ 255 0x26, 0x6E, 0x33, /* Logical Maximum (13166), */ 256 0x81, 0x02, /* Input (Variable), */ 257 0xB4, /* Pop, */ 258 0x09, 0x30, /* Usage (Tip Pressure), */ 259 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 260 0x81, 0x02, /* Input (Variable), */ 261 0xC0, /* End Collection, */ 262 0xC0 /* End Collection */ 263 }; 264 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, 0x02, /* Usage (Pen), */ 272 0xA1, 0x01, /* Collection (Application), */ 273 0x85, 0x09, /* Report ID (9), */ 274 0x09, 0x20, /* Usage (Stylus), */ 275 0xA0, /* Collection (Physical), */ 276 0x75, 0x01, /* Report Size (1), */ 277 0x09, 0x42, /* Usage (Tip Switch), */ 278 0x09, 0x44, /* Usage (Barrel Switch), */ 279 0x09, 0x46, /* Usage (Tablet Pick), */ 280 0x14, /* Logical Minimum (0), */ 281 0x25, 0x01, /* Logical Maximum (1), */ 282 0x95, 0x03, /* Report Count (3), */ 283 0x81, 0x02, /* Input (Variable), */ 284 0x95, 0x05, /* Report Count (5), */ 285 0x81, 0x01, /* Input (Constant), */ 286 0x75, 0x10, /* Report Size (16), */ 287 0x95, 0x01, /* Report Count (1), */ 288 0x14, /* Logical Minimum (0), */ 289 0xA4, /* Push, */ 290 0x05, 0x01, /* Usage Page (Desktop), */ 291 0x55, 0xFD, /* Unit Exponent (-3), */ 292 0x65, 0x13, /* Unit (Inch), */ 293 0x34, /* Physical Minimum (0), */ 294 0x09, 0x30, /* Usage (X), */ 295 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */ 296 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 297 0x81, 0x02, /* Input (Variable), */ 298 0x09, 0x31, /* Usage (Y), */ 299 0x46, 0x28, 0x23, /* Physical Maximum (9000), */ 300 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 301 0x81, 0x02, /* Input (Variable), */ 302 0xB4, /* Pop, */ 303 0x09, 0x30, /* Usage (Tip Pressure), */ 304 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 305 0x81, 0x02, /* Input (Variable), */ 306 0xC0, /* End Collection, */ 307 0xC0, /* End Collection, */ 308 0x05, 0x01, /* Usage Page (Desktop), */ 309 0x09, 0x02, /* Usage (Mouse), */ 310 0xA1, 0x01, /* Collection (Application), */ 311 0x85, 0x08, /* Report ID (8), */ 312 0x09, 0x01, /* Usage (Pointer), */ 313 0xA0, /* Collection (Physical), */ 314 0x75, 0x01, /* Report Size (1), */ 315 0x05, 0x09, /* Usage Page (Button), */ 316 0x19, 0x01, /* Usage Minimum (01h), */ 317 0x29, 0x03, /* Usage Maximum (03h), */ 318 0x14, /* Logical Minimum (0), */ 319 0x25, 0x01, /* Logical Maximum (1), */ 320 0x95, 0x03, /* Report Count (3), */ 321 0x81, 0x02, /* Input (Variable), */ 322 0x95, 0x05, /* Report Count (5), */ 323 0x81, 0x01, /* Input (Constant), */ 324 0x05, 0x01, /* Usage Page (Desktop), */ 325 0x75, 0x08, /* Report Size (8), */ 326 0x09, 0x30, /* Usage (X), */ 327 0x09, 0x31, /* Usage (Y), */ 328 0x15, 0x81, /* Logical Minimum (-127), */ 329 0x25, 0x7F, /* Logical Maximum (127), */ 330 0x95, 0x02, /* Report Count (2), */ 331 0x81, 0x06, /* Input (Variable, Relative), */ 332 0x09, 0x38, /* Usage (Wheel), */ 333 0x15, 0xFF, /* Logical Minimum (-1), */ 334 0x25, 0x01, /* Logical Maximum (1), */ 335 0x95, 0x01, /* Report Count (1), */ 336 0x81, 0x06, /* Input (Variable, Relative), */ 337 0x81, 0x01, /* Input (Constant), */ 338 0xC0, /* End Collection, */ 339 0xC0 /* End Collection */ 340 }; 341 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, 0x02, /* Usage (Pen), */ 349 0xA1, 0x01, /* Collection (Application), */ 350 0x85, 0x09, /* Report ID (9), */ 351 0x09, 0x20, /* Usage (Stylus), */ 352 0xA0, /* Collection (Physical), */ 353 0x14, /* Logical Minimum (0), */ 354 0x25, 0x01, /* Logical Maximum (1), */ 355 0x75, 0x01, /* Report Size (1), */ 356 0x95, 0x03, /* Report Count (3), */ 357 0x09, 0x42, /* Usage (Tip Switch), */ 358 0x09, 0x44, /* Usage (Barrel Switch), */ 359 0x09, 0x46, /* Usage (Tablet Pick), */ 360 0x81, 0x02, /* Input (Variable), */ 361 0x81, 0x03, /* Input (Constant, Variable), */ 362 0x95, 0x01, /* Report Count (1), */ 363 0x09, 0x32, /* Usage (In Range), */ 364 0x81, 0x02, /* Input (Variable), */ 365 0x81, 0x03, /* Input (Constant, Variable), */ 366 0x75, 0x10, /* Report Size (16), */ 367 0xA4, /* Push, */ 368 0x05, 0x01, /* Usage Page (Desktop), */ 369 0x65, 0x13, /* Unit (Inch), */ 370 0x55, 0xFD, /* Unit Exponent (-3), */ 371 0x34, /* Physical Minimum (0), */ 372 0x09, 0x30, /* Usage (X), */ 373 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ 374 0x26, 0x00, 0x7D, /* Logical Maximum (32000), */ 375 0x81, 0x02, /* Input (Variable), */ 376 0x09, 0x31, /* Usage (Y), */ 377 0x46, 0x88, 0x13, /* Physical Maximum (5000), */ 378 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ 379 0x81, 0x02, /* Input (Variable), */ 380 0xB4, /* Pop, */ 381 0x09, 0x30, /* Usage (Tip Pressure), */ 382 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 383 0x81, 0x02, /* Input (Variable), */ 384 0xC0, /* End Collection, */ 385 0xC0 /* End Collection */ 386 }; 387 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, 0x02, /* Usage (Pen), */ 461 0xA1, 0x01, /* Collection (Application), */ 462 0x85, 0x09, /* Report ID (9), */ 463 0x09, 0x20, /* Usage (Stylus), */ 464 0xA0, /* Collection (Physical), */ 465 0x75, 0x01, /* Report Size (1), */ 466 0x09, 0x42, /* Usage (Tip Switch), */ 467 0x09, 0x44, /* Usage (Barrel Switch), */ 468 0x09, 0x46, /* Usage (Tablet Pick), */ 469 0x14, /* Logical Minimum (0), */ 470 0x25, 0x01, /* Logical Maximum (1), */ 471 0x95, 0x03, /* Report Count (3), */ 472 0x81, 0x02, /* Input (Variable), */ 473 0x95, 0x04, /* Report Count (4), */ 474 0x81, 0x01, /* Input (Constant), */ 475 0x09, 0x32, /* Usage (In Range), */ 476 0x95, 0x01, /* Report Count (1), */ 477 0x81, 0x02, /* Input (Variable), */ 478 0x75, 0x10, /* Report Size (16), */ 479 0x95, 0x01, /* Report Count (1), */ 480 0x14, /* Logical Minimum (0), */ 481 0xA4, /* Push, */ 482 0x05, 0x01, /* Usage Page (Desktop), */ 483 0x55, 0xFD, /* Unit Exponent (-3), */ 484 0x65, 0x13, /* Unit (Inch), */ 485 0x34, /* Physical Minimum (0), */ 486 0x09, 0x30, /* Usage (X), */ 487 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ 488 0x27, 0x3F, 0x9C, 489 0x00, 0x00, /* Logical Maximum (39999), */ 490 0x81, 0x02, /* Input (Variable), */ 491 0x09, 0x31, /* Usage (Y), */ 492 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */ 493 0x26, 0xA7, 0x61, /* Logical Maximum (24999), */ 494 0x81, 0x02, /* Input (Variable), */ 495 0xB4, /* Pop, */ 496 0x09, 0x30, /* Usage (Tip Pressure), */ 497 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 498 0x81, 0x02, /* Input (Variable), */ 499 0xC0, /* End Collection, */ 500 0xC0 /* End Collection */ 501 }; 502 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_pen_v1_template_arr[] = { 536 0x05, 0x0D, /* Usage Page (Digitizer), */ 537 0x09, 0x02, /* Usage (Pen), */ 538 0xA1, 0x01, /* Collection (Application), */ 539 0x85, 0x07, /* Report ID (7), */ 540 0x09, 0x20, /* Usage (Stylus), */ 541 0xA0, /* Collection (Physical), */ 542 0x14, /* Logical Minimum (0), */ 543 0x25, 0x01, /* Logical Maximum (1), */ 544 0x75, 0x01, /* Report Size (1), */ 545 0x09, 0x42, /* Usage (Tip Switch), */ 546 0x09, 0x44, /* Usage (Barrel Switch), */ 547 0x09, 0x46, /* Usage (Tablet Pick), */ 548 0x95, 0x03, /* Report Count (3), */ 549 0x81, 0x02, /* Input (Variable), */ 550 0x95, 0x03, /* Report Count (3), */ 551 0x81, 0x03, /* Input (Constant, Variable), */ 552 0x09, 0x32, /* Usage (In Range), */ 553 0x95, 0x01, /* Report Count (1), */ 554 0x81, 0x02, /* Input (Variable), */ 555 0x95, 0x01, /* Report Count (1), */ 556 0x81, 0x03, /* Input (Constant, Variable), */ 557 0x75, 0x10, /* Report Size (16), */ 558 0x95, 0x01, /* Report Count (1), */ 559 0xA4, /* Push, */ 560 0x05, 0x01, /* Usage Page (Desktop), */ 561 0x65, 0x13, /* Unit (Inch), */ 562 0x55, 0xFD, /* Unit Exponent (-3), */ 563 0x34, /* Physical Minimum (0), */ 564 0x09, 0x30, /* Usage (X), */ 565 0x27, UCLOGIC_RDESC_PEN_PH(X_LM), 566 /* Logical Maximum (PLACEHOLDER), */ 567 0x47, UCLOGIC_RDESC_PEN_PH(X_PM), 568 /* Physical Maximum (PLACEHOLDER), */ 569 0x81, 0x02, /* Input (Variable), */ 570 0x09, 0x31, /* Usage (Y), */ 571 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM), 572 /* Logical Maximum (PLACEHOLDER), */ 573 0x47, UCLOGIC_RDESC_PEN_PH(Y_PM), 574 /* Physical Maximum (PLACEHOLDER), */ 575 0x81, 0x02, /* Input (Variable), */ 576 0xB4, /* Pop, */ 577 0x09, 0x30, /* Usage (Tip Pressure), */ 578 0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM), 579 /* Logical Maximum (PLACEHOLDER), */ 580 0x81, 0x02, /* Input (Variable), */ 581 0xC0, /* End Collection, */ 582 0xC0 /* End Collection */ 583 }; 584 585 const size_t uclogic_rdesc_pen_v1_template_size = 586 sizeof(uclogic_rdesc_pen_v1_template_arr); 587 588 /* Fixed report descriptor template for (tweaked) v2 pen reports */ 589 const __u8 uclogic_rdesc_pen_v2_template_arr[] = { 590 0x05, 0x0D, /* Usage Page (Digitizer), */ 591 0x09, 0x02, /* Usage (Pen), */ 592 0xA1, 0x01, /* Collection (Application), */ 593 0x85, 0x08, /* Report ID (8), */ 594 0x09, 0x20, /* Usage (Stylus), */ 595 0xA0, /* Collection (Physical), */ 596 0x14, /* Logical Minimum (0), */ 597 0x25, 0x01, /* Logical Maximum (1), */ 598 0x75, 0x01, /* Report Size (1), */ 599 0x09, 0x42, /* Usage (Tip Switch), */ 600 0x09, 0x44, /* Usage (Barrel Switch), */ 601 0x09, 0x46, /* Usage (Tablet Pick), */ 602 0x95, 0x03, /* Report Count (3), */ 603 0x81, 0x02, /* Input (Variable), */ 604 0x95, 0x03, /* Report Count (3), */ 605 0x81, 0x03, /* Input (Constant, Variable), */ 606 0x09, 0x32, /* Usage (In Range), */ 607 0x95, 0x01, /* Report Count (1), */ 608 0x81, 0x02, /* Input (Variable), */ 609 0x95, 0x01, /* Report Count (1), */ 610 0x81, 0x03, /* Input (Constant, Variable), */ 611 0x95, 0x01, /* Report Count (1), */ 612 0xA4, /* Push, */ 613 0x05, 0x01, /* Usage Page (Desktop), */ 614 0x65, 0x13, /* Unit (Inch), */ 615 0x55, 0xFD, /* Unit Exponent (-3), */ 616 0x75, 0x18, /* Report Size (24), */ 617 0x34, /* Physical Minimum (0), */ 618 0x09, 0x30, /* Usage (X), */ 619 0x27, UCLOGIC_RDESC_PEN_PH(X_LM), 620 /* Logical Maximum (PLACEHOLDER), */ 621 0x47, UCLOGIC_RDESC_PEN_PH(X_PM), 622 /* Physical Maximum (PLACEHOLDER), */ 623 0x81, 0x02, /* Input (Variable), */ 624 0x09, 0x31, /* Usage (Y), */ 625 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM), 626 /* Logical Maximum (PLACEHOLDER), */ 627 0x47, UCLOGIC_RDESC_PEN_PH(Y_PM), 628 /* Physical Maximum (PLACEHOLDER), */ 629 0x81, 0x02, /* Input (Variable), */ 630 0xB4, /* Pop, */ 631 0x09, 0x30, /* Usage (Tip Pressure), */ 632 0x75, 0x10, /* Report Size (16), */ 633 0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM), 634 /* Logical Maximum (PLACEHOLDER), */ 635 0x81, 0x02, /* Input (Variable), */ 636 0x81, 0x03, /* Input (Constant, Variable), */ 637 0xC0, /* End Collection, */ 638 0xC0 /* End Collection */ 639 }; 640 641 const size_t uclogic_rdesc_pen_v2_template_size = 642 sizeof(uclogic_rdesc_pen_v2_template_arr); 643 644 /** 645 * Expand to the contents of a generic buttonpad report descriptor. 646 * 647 * @_padding: Padding from the end of button bits at bit 44, until 648 * the end of the report, in bits. 649 */ 650 #define UCLOGIC_RDESC_BUTTONPAD_BYTES(_padding) \ 651 0x05, 0x01, /* Usage Page (Desktop), */ \ 652 0x09, 0x07, /* Usage (Keypad), */ \ 653 0xA1, 0x01, /* Collection (Application), */ \ 654 0x85, 0xF7, /* Report ID (247), */ \ 655 0x14, /* Logical Minimum (0), */ \ 656 0x25, 0x01, /* Logical Maximum (1), */ \ 657 0x75, 0x01, /* Report Size (1), */ \ 658 0x05, 0x0D, /* Usage Page (Digitizer), */ \ 659 0x09, 0x39, /* Usage (Tablet Function Keys), */ \ 660 0xA0, /* Collection (Physical), */ \ 661 0x09, 0x44, /* Usage (Barrel Switch), */ \ 662 0x95, 0x01, /* Report Count (1), */ \ 663 0x81, 0x02, /* Input (Variable), */ \ 664 0x05, 0x01, /* Usage Page (Desktop), */ \ 665 0x09, 0x30, /* Usage (X), */ \ 666 0x09, 0x31, /* Usage (Y), */ \ 667 0x95, 0x02, /* Report Count (2), */ \ 668 0x81, 0x02, /* Input (Variable), */ \ 669 0x95, 0x15, /* Report Count (21), */ \ 670 0x81, 0x01, /* Input (Constant), */ \ 671 0x05, 0x09, /* Usage Page (Button), */ \ 672 0x19, 0x01, /* Usage Minimum (01h), */ \ 673 0x29, 0x0A, /* Usage Maximum (0Ah), */ \ 674 0x95, 0x0A, /* Report Count (10), */ \ 675 0x81, 0x02, /* Input (Variable), */ \ 676 0xC0, /* End Collection, */ \ 677 0x05, 0x01, /* Usage Page (Desktop), */ \ 678 0x09, 0x05, /* Usage (Gamepad), */ \ 679 0xA0, /* Collection (Physical), */ \ 680 0x05, 0x09, /* Usage Page (Button), */ \ 681 0x19, 0x01, /* Usage Minimum (01h), */ \ 682 0x29, 0x02, /* Usage Maximum (02h), */ \ 683 0x95, 0x02, /* Report Count (2), */ \ 684 0x81, 0x02, /* Input (Variable), */ \ 685 0x95, _padding, /* Report Count (_padding), */ \ 686 0x81, 0x01, /* Input (Constant), */ \ 687 0xC0, /* End Collection, */ \ 688 0xC0 /* End Collection */ 689 690 /* Fixed report descriptor for (tweaked) v1 buttonpad reports */ 691 const __u8 uclogic_rdesc_buttonpad_v1_arr[] = { 692 UCLOGIC_RDESC_BUTTONPAD_BYTES(20) 693 }; 694 const size_t uclogic_rdesc_buttonpad_v1_size = 695 sizeof(uclogic_rdesc_buttonpad_v1_arr); 696 697 /* Fixed report descriptor for (tweaked) v2 buttonpad reports */ 698 const __u8 uclogic_rdesc_buttonpad_v2_arr[] = { 699 UCLOGIC_RDESC_BUTTONPAD_BYTES(52) 700 }; 701 const size_t uclogic_rdesc_buttonpad_v2_size = 702 sizeof(uclogic_rdesc_buttonpad_v2_arr); 703 704 /* Fixed report descriptor for Ugee EX07 buttonpad */ 705 const __u8 uclogic_rdesc_ugee_ex07_buttonpad_arr[] = { 706 0x05, 0x01, /* Usage Page (Desktop), */ 707 0x09, 0x07, /* Usage (Keypad), */ 708 0xA1, 0x01, /* Collection (Application), */ 709 0x85, 0x06, /* Report ID (6), */ 710 0x05, 0x0D, /* Usage Page (Digitizer), */ 711 0x09, 0x39, /* Usage (Tablet Function Keys), */ 712 0xA0, /* Collection (Physical), */ 713 0x05, 0x09, /* Usage Page (Button), */ 714 0x75, 0x01, /* Report Size (1), */ 715 0x19, 0x03, /* Usage Minimum (03h), */ 716 0x29, 0x06, /* Usage Maximum (06h), */ 717 0x95, 0x04, /* Report Count (4), */ 718 0x81, 0x02, /* Input (Variable), */ 719 0x95, 0x1A, /* Report Count (26), */ 720 0x81, 0x03, /* Input (Constant, Variable), */ 721 0x19, 0x01, /* Usage Minimum (01h), */ 722 0x29, 0x02, /* Usage Maximum (02h), */ 723 0x95, 0x02, /* Report Count (2), */ 724 0x81, 0x02, /* Input (Variable), */ 725 0xC0, /* End Collection, */ 726 0xC0 /* End Collection */ 727 }; 728 const size_t uclogic_rdesc_ugee_ex07_buttonpad_size = 729 sizeof(uclogic_rdesc_ugee_ex07_buttonpad_arr); 730 731 /* Fixed report descriptor for Ugee G5 frame controls */ 732 const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = { 733 0x05, 0x01, /* Usage Page (Desktop), */ 734 0x09, 0x07, /* Usage (Keypad), */ 735 0xA1, 0x01, /* Collection (Application), */ 736 0x85, 0x06, /* Report ID (6), */ 737 0x05, 0x0D, /* Usage Page (Digitizer), */ 738 0x09, 0x39, /* Usage (Tablet Function Keys), */ 739 0xA0, /* Collection (Physical), */ 740 0x14, /* Logical Minimum (0), */ 741 0x25, 0x01, /* Logical Maximum (1), */ 742 0x05, 0x01, /* Usage Page (Desktop), */ 743 0x05, 0x09, /* Usage Page (Button), */ 744 0x19, 0x01, /* Usage Minimum (01h), */ 745 0x29, 0x05, /* Usage Maximum (05h), */ 746 0x75, 0x01, /* Report Size (1), */ 747 0x95, 0x05, /* Report Count (5), */ 748 0x81, 0x02, /* Input (Variable), */ 749 0x75, 0x01, /* Report Size (1), */ 750 0x95, 0x03, /* Report Count (3), */ 751 0x81, 0x01, /* Input (Constant), */ 752 0x05, 0x0D, /* Usage Page (Digitizer), */ 753 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 754 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 755 0x75, 0x08, /* Report Size (8), */ 756 0x95, 0x01, /* Report Count (1), */ 757 0x81, 0x02, /* Input (Variable), */ 758 0x25, 0x01, /* Logical Maximum (1), */ 759 0x09, 0x44, /* Usage (Barrel Switch), */ 760 0x75, 0x01, /* Report Size (1), */ 761 0x95, 0x01, /* Report Count (1), */ 762 0x81, 0x02, /* Input (Variable), */ 763 0x05, 0x01, /* Usage Page (Desktop), */ 764 0x09, 0x30, /* Usage (X), */ 765 0x09, 0x31, /* Usage (Y), */ 766 0x75, 0x01, /* Report Size (1), */ 767 0x95, 0x02, /* Report Count (2), */ 768 0x81, 0x02, /* Input (Variable), */ 769 0x75, 0x01, /* Report Size (1), */ 770 0x95, 0x0B, /* Report Count (11), */ 771 0x81, 0x01, /* Input (Constant), */ 772 0x05, 0x01, /* Usage Page (Desktop), */ 773 0x09, 0x38, /* Usage (Wheel), */ 774 0x15, 0xFF, /* Logical Minimum (-1), */ 775 0x25, 0x01, /* Logical Maximum (1), */ 776 0x75, 0x02, /* Report Size (2), */ 777 0x95, 0x01, /* Report Count (1), */ 778 0x81, 0x06, /* Input (Variable, Relative), */ 779 0xC0, /* End Collection, */ 780 0xC0 /* End Collection */ 781 }; 782 const size_t uclogic_rdesc_ugee_g5_frame_size = 783 sizeof(uclogic_rdesc_ugee_g5_frame_arr); 784 785 /* Fixed report descriptor for XP-Pen Deco 01 frame controls */ 786 const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = { 787 0x05, 0x01, /* Usage Page (Desktop), */ 788 0x09, 0x07, /* Usage (Keypad), */ 789 0xA1, 0x01, /* Collection (Application), */ 790 0x85, 0x06, /* Report ID (6), */ 791 0x14, /* Logical Minimum (0), */ 792 0x25, 0x01, /* Logical Maximum (1), */ 793 0x75, 0x01, /* Report Size (1), */ 794 0x05, 0x0D, /* Usage Page (Digitizer), */ 795 0x09, 0x39, /* Usage (Tablet Function Keys), */ 796 0xA0, /* Collection (Physical), */ 797 0x05, 0x09, /* Usage Page (Button), */ 798 0x19, 0x01, /* Usage Minimum (01h), */ 799 0x29, 0x08, /* Usage Maximum (08h), */ 800 0x95, 0x08, /* Report Count (8), */ 801 0x81, 0x02, /* Input (Variable), */ 802 0x05, 0x0D, /* Usage Page (Digitizer), */ 803 0x09, 0x44, /* Usage (Barrel Switch), */ 804 0x95, 0x01, /* Report Count (1), */ 805 0x81, 0x02, /* Input (Variable), */ 806 0x05, 0x01, /* Usage Page (Desktop), */ 807 0x09, 0x30, /* Usage (X), */ 808 0x09, 0x31, /* Usage (Y), */ 809 0x95, 0x02, /* Report Count (2), */ 810 0x81, 0x02, /* Input (Variable), */ 811 0x95, 0x15, /* Report Count (21), */ 812 0x81, 0x01, /* Input (Constant), */ 813 0xC0, /* End Collection, */ 814 0xC0 /* End Collection */ 815 }; 816 817 const size_t uclogic_rdesc_xppen_deco01_frame_size = 818 sizeof(uclogic_rdesc_xppen_deco01_frame_arr); 819 820 /** 821 * uclogic_rdesc_template_apply() - apply report descriptor parameters to a 822 * report descriptor template, creating a report descriptor. Copies the 823 * template over to the new report descriptor and replaces every occurrence of 824 * UCLOGIC_RDESC_PH_HEAD, followed by an index byte, with the value from the 825 * parameter list at that index. 826 * 827 * @template_ptr: Pointer to the template buffer. 828 * @template_size: Size of the template buffer. 829 * @param_list: List of template parameters. 830 * @param_num: Number of parameters in the list. 831 * 832 * Returns: 833 * Kmalloc-allocated pointer to the created report descriptor, 834 * or NULL if allocation failed. 835 */ 836 __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr, 837 size_t template_size, 838 const s32 *param_list, 839 size_t param_num) 840 { 841 static const __u8 head[] = {UCLOGIC_RDESC_PH_HEAD}; 842 __u8 *rdesc_ptr; 843 __u8 *p; 844 s32 v; 845 846 rdesc_ptr = kmemdup(template_ptr, template_size, GFP_KERNEL); 847 if (rdesc_ptr == NULL) 848 return NULL; 849 850 for (p = rdesc_ptr; p + sizeof(head) < rdesc_ptr + template_size;) { 851 if (memcmp(p, head, sizeof(head)) == 0 && 852 p[sizeof(head)] < param_num) { 853 v = param_list[p[sizeof(head)]]; 854 put_unaligned(cpu_to_le32(v), (s32 *)p); 855 p += sizeof(head) + 1; 856 } else { 857 p++; 858 } 859 } 860 861 return rdesc_ptr; 862 } 863