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_v1_pen_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_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, 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 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 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_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_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 reports */ 709 const __u8 uclogic_rdesc_v2_frame_arr[] = { 710 UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_V2_FRAME_ID, 12) 711 }; 712 const size_t uclogic_rdesc_v2_frame_size = 713 sizeof(uclogic_rdesc_v2_frame_arr); 714 715 /* Fixed report descriptor for Ugee EX07 frame */ 716 const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = { 717 0x05, 0x01, /* Usage Page (Desktop), */ 718 0x09, 0x07, /* Usage (Keypad), */ 719 0xA1, 0x01, /* Collection (Application), */ 720 0x85, 0x06, /* Report ID (6), */ 721 0x05, 0x0D, /* Usage Page (Digitizer), */ 722 0x09, 0x39, /* Usage (Tablet Function Keys), */ 723 0xA0, /* Collection (Physical), */ 724 0x05, 0x09, /* Usage Page (Button), */ 725 0x75, 0x01, /* Report Size (1), */ 726 0x19, 0x03, /* Usage Minimum (03h), */ 727 0x29, 0x06, /* Usage Maximum (06h), */ 728 0x95, 0x04, /* Report Count (4), */ 729 0x81, 0x02, /* Input (Variable), */ 730 0x95, 0x1A, /* Report Count (26), */ 731 0x81, 0x03, /* Input (Constant, Variable), */ 732 0x19, 0x01, /* Usage Minimum (01h), */ 733 0x29, 0x02, /* Usage Maximum (02h), */ 734 0x95, 0x02, /* Report Count (2), */ 735 0x81, 0x02, /* Input (Variable), */ 736 0xC0, /* End Collection, */ 737 0xC0 /* End Collection */ 738 }; 739 const size_t uclogic_rdesc_ugee_ex07_frame_size = 740 sizeof(uclogic_rdesc_ugee_ex07_frame_arr); 741 742 /* Fixed report descriptor for Ugee G5 frame controls */ 743 const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = { 744 0x05, 0x01, /* Usage Page (Desktop), */ 745 0x09, 0x07, /* Usage (Keypad), */ 746 0xA1, 0x01, /* Collection (Application), */ 747 0x85, 0x06, /* Report ID (6), */ 748 0x05, 0x0D, /* Usage Page (Digitizer), */ 749 0x09, 0x39, /* Usage (Tablet Function Keys), */ 750 0xA0, /* Collection (Physical), */ 751 0x14, /* Logical Minimum (0), */ 752 0x25, 0x01, /* Logical Maximum (1), */ 753 0x05, 0x01, /* Usage Page (Desktop), */ 754 0x05, 0x09, /* Usage Page (Button), */ 755 0x19, 0x01, /* Usage Minimum (01h), */ 756 0x29, 0x05, /* Usage Maximum (05h), */ 757 0x75, 0x01, /* Report Size (1), */ 758 0x95, 0x05, /* Report Count (5), */ 759 0x81, 0x02, /* Input (Variable), */ 760 0x75, 0x01, /* Report Size (1), */ 761 0x95, 0x03, /* Report Count (3), */ 762 0x81, 0x01, /* Input (Constant), */ 763 0x05, 0x0D, /* Usage Page (Digitizer), */ 764 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 765 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 766 0x75, 0x08, /* Report Size (8), */ 767 0x95, 0x01, /* Report Count (1), */ 768 0x81, 0x02, /* Input (Variable), */ 769 0x25, 0x01, /* Logical Maximum (1), */ 770 0x09, 0x44, /* Usage (Barrel Switch), */ 771 0x75, 0x01, /* Report Size (1), */ 772 0x95, 0x01, /* Report Count (1), */ 773 0x81, 0x02, /* Input (Variable), */ 774 0x05, 0x01, /* Usage Page (Desktop), */ 775 0x09, 0x30, /* Usage (X), */ 776 0x09, 0x31, /* Usage (Y), */ 777 0x75, 0x01, /* Report Size (1), */ 778 0x95, 0x02, /* Report Count (2), */ 779 0x81, 0x02, /* Input (Variable), */ 780 0x75, 0x01, /* Report Size (1), */ 781 0x95, 0x0B, /* Report Count (11), */ 782 0x81, 0x01, /* Input (Constant), */ 783 0x05, 0x01, /* Usage Page (Desktop), */ 784 0x09, 0x38, /* Usage (Wheel), */ 785 0x15, 0xFF, /* Logical Minimum (-1), */ 786 0x25, 0x01, /* Logical Maximum (1), */ 787 0x75, 0x02, /* Report Size (2), */ 788 0x95, 0x01, /* Report Count (1), */ 789 0x81, 0x06, /* Input (Variable, Relative), */ 790 0xC0, /* End Collection, */ 791 0xC0 /* End Collection */ 792 }; 793 const size_t uclogic_rdesc_ugee_g5_frame_size = 794 sizeof(uclogic_rdesc_ugee_g5_frame_arr); 795 796 /* Fixed report descriptor for XP-Pen Deco 01 frame controls */ 797 const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = { 798 0x05, 0x01, /* Usage Page (Desktop), */ 799 0x09, 0x07, /* Usage (Keypad), */ 800 0xA1, 0x01, /* Collection (Application), */ 801 0x85, 0x06, /* Report ID (6), */ 802 0x14, /* Logical Minimum (0), */ 803 0x25, 0x01, /* Logical Maximum (1), */ 804 0x75, 0x01, /* Report Size (1), */ 805 0x05, 0x0D, /* Usage Page (Digitizer), */ 806 0x09, 0x39, /* Usage (Tablet Function Keys), */ 807 0xA0, /* Collection (Physical), */ 808 0x05, 0x09, /* Usage Page (Button), */ 809 0x19, 0x01, /* Usage Minimum (01h), */ 810 0x29, 0x08, /* Usage Maximum (08h), */ 811 0x95, 0x08, /* Report Count (8), */ 812 0x81, 0x02, /* Input (Variable), */ 813 0x05, 0x0D, /* Usage Page (Digitizer), */ 814 0x09, 0x44, /* Usage (Barrel Switch), */ 815 0x95, 0x01, /* Report Count (1), */ 816 0x81, 0x02, /* Input (Variable), */ 817 0x05, 0x01, /* Usage Page (Desktop), */ 818 0x09, 0x30, /* Usage (X), */ 819 0x09, 0x31, /* Usage (Y), */ 820 0x95, 0x02, /* Report Count (2), */ 821 0x81, 0x02, /* Input (Variable), */ 822 0x95, 0x15, /* Report Count (21), */ 823 0x81, 0x01, /* Input (Constant), */ 824 0xC0, /* End Collection, */ 825 0xC0 /* End Collection */ 826 }; 827 828 const size_t uclogic_rdesc_xppen_deco01_frame_size = 829 sizeof(uclogic_rdesc_xppen_deco01_frame_arr); 830 831 /** 832 * uclogic_rdesc_template_apply() - apply report descriptor parameters to a 833 * report descriptor template, creating a report descriptor. Copies the 834 * template over to the new report descriptor and replaces every occurrence of 835 * UCLOGIC_RDESC_PH_HEAD, followed by an index byte, with the value from the 836 * parameter list at that index. 837 * 838 * @template_ptr: Pointer to the template buffer. 839 * @template_size: Size of the template buffer. 840 * @param_list: List of template parameters. 841 * @param_num: Number of parameters in the list. 842 * 843 * Returns: 844 * Kmalloc-allocated pointer to the created report descriptor, 845 * or NULL if allocation failed. 846 */ 847 __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr, 848 size_t template_size, 849 const s32 *param_list, 850 size_t param_num) 851 { 852 static const __u8 head[] = {UCLOGIC_RDESC_PH_HEAD}; 853 __u8 *rdesc_ptr; 854 __u8 *p; 855 s32 v; 856 857 rdesc_ptr = kmemdup(template_ptr, template_size, GFP_KERNEL); 858 if (rdesc_ptr == NULL) 859 return NULL; 860 861 for (p = rdesc_ptr; p + sizeof(head) < rdesc_ptr + template_size;) { 862 if (memcmp(p, head, sizeof(head)) == 0 && 863 p[sizeof(head)] < param_num) { 864 v = param_list[p[sizeof(head)]]; 865 put_unaligned(cpu_to_le32(v), (s32 *)p); 866 p += sizeof(head) + 1; 867 } else { 868 p++; 869 } 870 } 871 872 return rdesc_ptr; 873 } 874