1248 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * HID driver for UC-Logic devices not fully compliant with HID standard4 * - original and fixed report descriptors5 *6 * Copyright (c) 2010-2017 Nikolai Kondrashov7 * Copyright (c) 2013 Martin Rusko8 */9 10/*11 * This program is free software; you can redistribute it and/or modify it12 * under the terms of the GNU General Public License as published by the Free13 * 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 */23const __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 64const size_t uclogic_rdesc_wp4030u_fixed_size =65 sizeof(uclogic_rdesc_wp4030u_fixed_arr);66 67/* Fixed WP5540U report descriptor */68const __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 141const size_t uclogic_rdesc_wp5540u_fixed_size =142 sizeof(uclogic_rdesc_wp5540u_fixed_arr);143 144/* Fixed WP8060U report descriptor */145const __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 218const size_t uclogic_rdesc_wp8060u_fixed_size =219 sizeof(uclogic_rdesc_wp8060u_fixed_arr);220 221/* Fixed WP1062 report descriptor */222const __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 266const size_t uclogic_rdesc_wp1062_fixed_size =267 sizeof(uclogic_rdesc_wp1062_fixed_arr);268 269/* Fixed PF1209 report descriptor */270const __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 343const 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) */347const __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 389const 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) */393const __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 429const 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) */433const __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 455const size_t uclogic_rdesc_twhl850_fixed2_size =456 sizeof(uclogic_rdesc_twhl850_fixed2_arr);457 458/* Fixed TWHA60 report descriptor, interface 0 (stylus) */459const __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 504const size_t uclogic_rdesc_twha60_fixed0_size =505 sizeof(uclogic_rdesc_twha60_fixed0_arr);506 507/* Fixed TWHA60 report descriptor, interface 1 (frame buttons) */508const __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 532const 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 */536const __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 586const 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 */590const __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 652const 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 */703const __u8 uclogic_rdesc_v1_frame_arr[] = {704 UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8)705};706const 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 */710const __u8 uclogic_rdesc_v2_frame_buttons_arr[] = {711 UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID,712 12)713};714const 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 */718const __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};762const 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 */766const __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};811const 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 */815const __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};861const size_t uclogic_rdesc_v2_frame_dial_size =862 sizeof(uclogic_rdesc_v2_frame_dial_arr);863 864const __u8 uclogic_ugee_v2_probe_arr[] = {865 0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00866};867const size_t uclogic_ugee_v2_probe_size = sizeof(uclogic_ugee_v2_probe_arr);868const int uclogic_ugee_v2_probe_endpoint = 0x03;869 870/* Fixed report descriptor template for UGEE v2 pen reports */871const __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};940const 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) */944const __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};969const 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) */973const __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};1009const 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) */1013const __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};1043const 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 */1047const __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};1077const 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 */1081const __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};1104const 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 */1108const __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};1158const 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 */1162const __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 1193const 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 a1198 * report descriptor template, creating a report descriptor. Copies the1199 * template over to the new report descriptor and replaces every occurrence of1200 * the template placeholders, followed by an index byte, with the value from the1201 * 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}1247EXPORT_SYMBOL_IF_KUNIT(uclogic_rdesc_template_apply);1248