1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * HID driver for UC-Logic devices not fully compliant with HID standard 4 * - tablet initialization and parameter retrieval 5 * 6 * Copyright (c) 2018 Nikolai Kondrashov 7 */ 8 9 /* 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the Free 12 * Software Foundation; either version 2 of the License, or (at your option) 13 * any later version. 14 */ 15 16 #include "hid-uclogic-params.h" 17 #include "hid-uclogic-rdesc.h" 18 #include "usbhid/usbhid.h" 19 #include "hid-ids.h" 20 #include <linux/ctype.h> 21 #include <linux/string.h> 22 #include <linux/unaligned.h> 23 #include <linux/string_choices.h> 24 25 /** 26 * uclogic_params_pen_inrange_to_str() - Convert a pen in-range reporting type 27 * to a string. 28 * @inrange: The in-range reporting type to convert. 29 * 30 * Return: 31 * * The string representing the type, or 32 * * %NULL if the type is unknown. 33 */ 34 static const char *uclogic_params_pen_inrange_to_str( 35 enum uclogic_params_pen_inrange inrange) 36 { 37 switch (inrange) { 38 case UCLOGIC_PARAMS_PEN_INRANGE_NORMAL: 39 return "normal"; 40 case UCLOGIC_PARAMS_PEN_INRANGE_INVERTED: 41 return "inverted"; 42 case UCLOGIC_PARAMS_PEN_INRANGE_NONE: 43 return "none"; 44 default: 45 return NULL; 46 } 47 } 48 49 /** 50 * uclogic_params_pen_hid_dbg() - Dump tablet interface pen parameters 51 * @hdev: The HID device the pen parameters describe. 52 * @pen: The pen parameters to dump. 53 * 54 * Dump tablet interface pen parameters with hid_dbg(). The dump is indented 55 * with a tab. 56 */ 57 static void uclogic_params_pen_hid_dbg(const struct hid_device *hdev, 58 const struct uclogic_params_pen *pen) 59 { 60 size_t i; 61 62 hid_dbg(hdev, "\t.usage_invalid = %s\n", 63 str_true_false(pen->usage_invalid)); 64 hid_dbg(hdev, "\t.desc_ptr = %p\n", pen->desc_ptr); 65 hid_dbg(hdev, "\t.desc_size = %u\n", pen->desc_size); 66 hid_dbg(hdev, "\t.id = %u\n", pen->id); 67 hid_dbg(hdev, "\t.subreport_list = {\n"); 68 for (i = 0; i < ARRAY_SIZE(pen->subreport_list); i++) { 69 hid_dbg(hdev, "\t\t{0x%02hhx, %hhu}%s\n", 70 pen->subreport_list[i].value, 71 pen->subreport_list[i].id, 72 i < (ARRAY_SIZE(pen->subreport_list) - 1) ? "," : ""); 73 } 74 hid_dbg(hdev, "\t}\n"); 75 hid_dbg(hdev, "\t.inrange = %s\n", 76 uclogic_params_pen_inrange_to_str(pen->inrange)); 77 hid_dbg(hdev, "\t.fragmented_hires = %s\n", 78 str_true_false(pen->fragmented_hires)); 79 hid_dbg(hdev, "\t.tilt_y_flipped = %s\n", 80 str_true_false(pen->tilt_y_flipped)); 81 } 82 83 /** 84 * uclogic_params_frame_hid_dbg() - Dump tablet interface frame parameters 85 * @hdev: The HID device the pen parameters describe. 86 * @frame: The frame parameters to dump. 87 * 88 * Dump tablet interface frame parameters with hid_dbg(). The dump is 89 * indented with two tabs. 90 */ 91 static void uclogic_params_frame_hid_dbg( 92 const struct hid_device *hdev, 93 const struct uclogic_params_frame *frame) 94 { 95 hid_dbg(hdev, "\t\t.desc_ptr = %p\n", frame->desc_ptr); 96 hid_dbg(hdev, "\t\t.desc_size = %u\n", frame->desc_size); 97 hid_dbg(hdev, "\t\t.id = %u\n", frame->id); 98 hid_dbg(hdev, "\t\t.suffix = %s\n", frame->suffix); 99 hid_dbg(hdev, "\t\t.re_lsb = %u\n", frame->re_lsb); 100 hid_dbg(hdev, "\t\t.dev_id_byte = %u\n", frame->dev_id_byte); 101 hid_dbg(hdev, "\t\t.touch_byte = %u\n", frame->touch_byte); 102 hid_dbg(hdev, "\t\t.touch_max = %hhd\n", frame->touch_max); 103 hid_dbg(hdev, "\t\t.touch_flip_at = %hhd\n", 104 frame->touch_flip_at); 105 hid_dbg(hdev, "\t\t.bitmap_dial_byte = %u\n", 106 frame->bitmap_dial_byte); 107 hid_dbg(hdev, "\t\t.bitmap_second_dial_destination_byte = %u\n", 108 frame->bitmap_second_dial_destination_byte); 109 } 110 111 /** 112 * uclogic_params_hid_dbg() - Dump tablet interface parameters 113 * @hdev: The HID device the parameters describe. 114 * @params: The parameters to dump. 115 * 116 * Dump tablet interface parameters with hid_dbg(). 117 */ 118 void uclogic_params_hid_dbg(const struct hid_device *hdev, 119 const struct uclogic_params *params) 120 { 121 size_t i; 122 123 hid_dbg(hdev, ".invalid = %s\n", str_true_false(params->invalid)); 124 hid_dbg(hdev, ".desc_ptr = %p\n", params->desc_ptr); 125 hid_dbg(hdev, ".desc_size = %u\n", params->desc_size); 126 hid_dbg(hdev, ".pen = {\n"); 127 uclogic_params_pen_hid_dbg(hdev, ¶ms->pen); 128 hid_dbg(hdev, "\t}\n"); 129 hid_dbg(hdev, ".frame_list = {\n"); 130 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) { 131 hid_dbg(hdev, "\t{\n"); 132 uclogic_params_frame_hid_dbg(hdev, ¶ms->frame_list[i]); 133 hid_dbg(hdev, "\t}%s\n", 134 i < (ARRAY_SIZE(params->frame_list) - 1) ? "," : ""); 135 } 136 hid_dbg(hdev, "}\n"); 137 } 138 139 /** 140 * uclogic_params_get_str_desc - retrieve a string descriptor from a HID 141 * device interface, putting it into a kmalloc-allocated buffer as is, without 142 * character encoding conversion. 143 * 144 * @pbuf: Location for the kmalloc-allocated buffer pointer containing 145 * the retrieved descriptor. Not modified in case of error. 146 * Can be NULL to have retrieved descriptor discarded. 147 * @hdev: The HID device of the tablet interface to retrieve the string 148 * descriptor from. Cannot be NULL. 149 * @idx: Index of the string descriptor to request from the device. 150 * @len: Length of the buffer to allocate and the data to retrieve. 151 * 152 * Returns: 153 * number of bytes retrieved (<= len), 154 * -EPIPE, if the descriptor was not found, or 155 * another negative errno code in case of other error. 156 */ 157 static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev, 158 __u8 idx, size_t len) 159 { 160 int rc; 161 struct usb_device *udev; 162 __u8 *buf = NULL; 163 164 /* Check arguments */ 165 if (hdev == NULL) { 166 rc = -EINVAL; 167 goto cleanup; 168 } 169 170 udev = hid_to_usb_dev(hdev); 171 172 buf = kmalloc(len, GFP_KERNEL); 173 if (buf == NULL) { 174 rc = -ENOMEM; 175 goto cleanup; 176 } 177 178 rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 179 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 180 (USB_DT_STRING << 8) + idx, 181 0x0409, buf, len, 182 USB_CTRL_GET_TIMEOUT); 183 if (rc == -EPIPE) { 184 hid_dbg(hdev, "string descriptor #%hhu not found\n", idx); 185 goto cleanup; 186 } else if (rc < 0) { 187 hid_err(hdev, 188 "failed retrieving string descriptor #%u: %d\n", 189 idx, rc); 190 goto cleanup; 191 } 192 193 if (pbuf != NULL) { 194 *pbuf = buf; 195 buf = NULL; 196 } 197 198 cleanup: 199 kfree(buf); 200 return rc; 201 } 202 203 /** 204 * uclogic_params_pen_cleanup - free resources used by struct 205 * uclogic_params_pen (tablet interface's pen input parameters). 206 * Can be called repeatedly. 207 * 208 * @pen: Pen input parameters to cleanup. Cannot be NULL. 209 */ 210 static void uclogic_params_pen_cleanup(struct uclogic_params_pen *pen) 211 { 212 kfree(pen->desc_ptr); 213 memset(pen, 0, sizeof(*pen)); 214 } 215 216 /** 217 * uclogic_params_pen_init_v1() - initialize tablet interface pen 218 * input and retrieve its parameters from the device, using v1 protocol. 219 * 220 * @pen: Pointer to the pen parameters to initialize (to be 221 * cleaned up with uclogic_params_pen_cleanup()). Not modified in 222 * case of error, or if parameters are not found. Cannot be NULL. 223 * @pfound: Location for a flag which is set to true if the parameters 224 * were found, and to false if not (e.g. device was 225 * incompatible). Not modified in case of error. Cannot be NULL. 226 * @hdev: The HID device of the tablet interface to initialize and get 227 * parameters from. Cannot be NULL. 228 * 229 * Returns: 230 * Zero, if successful. A negative errno code on error. 231 */ 232 static int uclogic_params_pen_init_v1(struct uclogic_params_pen *pen, 233 bool *pfound, 234 struct hid_device *hdev) 235 { 236 int rc; 237 bool found = false; 238 /* Buffer for (part of) the string descriptor */ 239 __u8 *buf = NULL; 240 /* Minimum descriptor length required, maximum seen so far is 18 */ 241 const int len = 12; 242 s32 resolution; 243 /* Pen report descriptor template parameters */ 244 s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM]; 245 __u8 *desc_ptr = NULL; 246 247 /* Check arguments */ 248 if (pen == NULL || pfound == NULL || hdev == NULL) { 249 rc = -EINVAL; 250 goto cleanup; 251 } 252 253 /* 254 * Read string descriptor containing pen input parameters. 255 * The specific string descriptor and data were discovered by sniffing 256 * the Windows driver traffic. 257 * NOTE: This enables fully-functional tablet mode. 258 */ 259 rc = uclogic_params_get_str_desc(&buf, hdev, 100, len); 260 if (rc == -EPIPE) { 261 hid_dbg(hdev, 262 "string descriptor with pen parameters not found, assuming not compatible\n"); 263 goto finish; 264 } else if (rc < 0) { 265 hid_err(hdev, "failed retrieving pen parameters: %d\n", rc); 266 goto cleanup; 267 } else if (rc != len) { 268 hid_dbg(hdev, 269 "string descriptor with pen parameters has invalid length (got %d, expected %d), assuming not compatible\n", 270 rc, len); 271 goto finish; 272 } 273 274 /* 275 * Fill report descriptor parameters from the string descriptor 276 */ 277 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 278 get_unaligned_le16(buf + 2); 279 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 280 get_unaligned_le16(buf + 4); 281 desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 282 get_unaligned_le16(buf + 8); 283 resolution = get_unaligned_le16(buf + 10); 284 if (resolution == 0) { 285 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0; 286 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0; 287 } else { 288 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 289 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 / 290 resolution; 291 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 292 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 / 293 resolution; 294 } 295 kfree(buf); 296 buf = NULL; 297 298 /* 299 * Generate pen report descriptor 300 */ 301 desc_ptr = uclogic_rdesc_template_apply( 302 uclogic_rdesc_v1_pen_template_arr, 303 uclogic_rdesc_v1_pen_template_size, 304 desc_params, ARRAY_SIZE(desc_params)); 305 if (desc_ptr == NULL) { 306 rc = -ENOMEM; 307 goto cleanup; 308 } 309 310 /* 311 * Fill-in the parameters 312 */ 313 memset(pen, 0, sizeof(*pen)); 314 pen->desc_ptr = desc_ptr; 315 desc_ptr = NULL; 316 pen->desc_size = uclogic_rdesc_v1_pen_template_size; 317 pen->id = UCLOGIC_RDESC_V1_PEN_ID; 318 pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_INVERTED; 319 found = true; 320 finish: 321 *pfound = found; 322 rc = 0; 323 cleanup: 324 kfree(desc_ptr); 325 kfree(buf); 326 return rc; 327 } 328 329 /** 330 * uclogic_params_get_le24() - get a 24-bit little-endian number from a 331 * buffer. 332 * 333 * @p: The pointer to the number buffer. 334 * 335 * Returns: 336 * The retrieved number 337 */ 338 static s32 uclogic_params_get_le24(const void *p) 339 { 340 const __u8 *b = p; 341 return b[0] | (b[1] << 8UL) | (b[2] << 16UL); 342 } 343 344 /** 345 * uclogic_params_pen_init_v2() - initialize tablet interface pen 346 * input and retrieve its parameters from the device, using v2 protocol. 347 * 348 * @pen: Pointer to the pen parameters to initialize (to be 349 * cleaned up with uclogic_params_pen_cleanup()). Not 350 * modified in case of error, or if parameters are not 351 * found. Cannot be NULL. 352 * @pfound: Location for a flag which is set to true if the 353 * parameters were found, and to false if not (e.g. 354 * device was incompatible). Not modified in case of 355 * error. Cannot be NULL. 356 * @pparams_ptr: Location for a kmalloc'ed pointer to the retrieved raw 357 * parameters, which could be used to identify the tablet 358 * to some extent. Should be freed with kfree after use. 359 * NULL, if not needed. Not modified in case of error. 360 * Only set if *pfound is set to true. 361 * @pparams_len: Location for the length of the retrieved raw 362 * parameters. NULL, if not needed. Not modified in case 363 * of error. Only set if *pfound is set to true. 364 * @hdev: The HID device of the tablet interface to initialize 365 * and get parameters from. Cannot be NULL. 366 * 367 * Returns: 368 * Zero, if successful. A negative errno code on error. 369 */ 370 static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen, 371 bool *pfound, 372 __u8 **pparams_ptr, 373 size_t *pparams_len, 374 struct hid_device *hdev) 375 { 376 int rc; 377 bool found = false; 378 /* Buffer for (part of) the parameter string descriptor */ 379 __u8 *buf = NULL; 380 /* Parameter string descriptor required length */ 381 const int params_len_min = 18; 382 /* Parameter string descriptor accepted length */ 383 const int params_len_max = 32; 384 /* Parameter string descriptor received length */ 385 int params_len; 386 size_t i; 387 s32 resolution; 388 /* Pen report descriptor template parameters */ 389 s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM]; 390 __u8 *desc_ptr = NULL; 391 392 /* Check arguments */ 393 if (pen == NULL || pfound == NULL || hdev == NULL) { 394 rc = -EINVAL; 395 goto cleanup; 396 } 397 398 /* 399 * Read string descriptor containing pen input parameters. 400 * The specific string descriptor and data were discovered by sniffing 401 * the Windows driver traffic. 402 * NOTE: This enables fully-functional tablet mode. 403 */ 404 rc = uclogic_params_get_str_desc(&buf, hdev, 200, params_len_max); 405 if (rc == -EPIPE) { 406 hid_dbg(hdev, 407 "string descriptor with pen parameters not found, assuming not compatible\n"); 408 goto finish; 409 } else if (rc < 0) { 410 hid_err(hdev, "failed retrieving pen parameters: %d\n", rc); 411 goto cleanup; 412 } else if (rc < params_len_min) { 413 hid_dbg(hdev, 414 "string descriptor with pen parameters is too short (got %d, expected at least %d), assuming not compatible\n", 415 rc, params_len_min); 416 goto finish; 417 } 418 419 params_len = rc; 420 421 /* 422 * Check it's not just a catch-all UTF-16LE-encoded ASCII 423 * string (such as the model name) some tablets put into all 424 * unknown string descriptors. 425 */ 426 for (i = 2; 427 i < params_len && 428 (buf[i] >= 0x20 && buf[i] < 0x7f && buf[i + 1] == 0); 429 i += 2); 430 if (i >= params_len) { 431 hid_dbg(hdev, 432 "string descriptor with pen parameters seems to contain only text, assuming not compatible\n"); 433 goto finish; 434 } 435 436 /* 437 * Fill report descriptor parameters from the string descriptor 438 */ 439 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 440 uclogic_params_get_le24(buf + 2); 441 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 442 uclogic_params_get_le24(buf + 5); 443 desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 444 get_unaligned_le16(buf + 8); 445 resolution = get_unaligned_le16(buf + 10); 446 if (resolution == 0) { 447 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0; 448 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0; 449 } else { 450 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 451 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 / 452 resolution; 453 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 454 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 / 455 resolution; 456 } 457 458 /* 459 * Generate pen report descriptor 460 */ 461 desc_ptr = uclogic_rdesc_template_apply( 462 uclogic_rdesc_v2_pen_template_arr, 463 uclogic_rdesc_v2_pen_template_size, 464 desc_params, ARRAY_SIZE(desc_params)); 465 if (desc_ptr == NULL) { 466 rc = -ENOMEM; 467 goto cleanup; 468 } 469 470 /* 471 * Fill-in the parameters 472 */ 473 memset(pen, 0, sizeof(*pen)); 474 pen->desc_ptr = desc_ptr; 475 desc_ptr = NULL; 476 pen->desc_size = uclogic_rdesc_v2_pen_template_size; 477 pen->id = UCLOGIC_RDESC_V2_PEN_ID; 478 pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_NONE; 479 pen->fragmented_hires = true; 480 pen->tilt_y_flipped = true; 481 found = true; 482 if (pparams_ptr != NULL) { 483 *pparams_ptr = buf; 484 buf = NULL; 485 } 486 if (pparams_len != NULL) 487 *pparams_len = params_len; 488 489 finish: 490 *pfound = found; 491 rc = 0; 492 cleanup: 493 kfree(desc_ptr); 494 kfree(buf); 495 return rc; 496 } 497 498 /** 499 * uclogic_params_frame_cleanup - free resources used by struct 500 * uclogic_params_frame (tablet interface's frame controls input parameters). 501 * Can be called repeatedly. 502 * 503 * @frame: Frame controls input parameters to cleanup. Cannot be NULL. 504 */ 505 static void uclogic_params_frame_cleanup(struct uclogic_params_frame *frame) 506 { 507 kfree(frame->desc_ptr); 508 memset(frame, 0, sizeof(*frame)); 509 } 510 511 /** 512 * uclogic_params_frame_init_with_desc() - initialize tablet's frame control 513 * parameters with a static report descriptor. 514 * 515 * @frame: Pointer to the frame parameters to initialize (to be cleaned 516 * up with uclogic_params_frame_cleanup()). Not modified in case 517 * of error. Cannot be NULL. 518 * @desc_ptr: Report descriptor pointer. Can be NULL, if desc_size is zero. 519 * @desc_size: Report descriptor size. 520 * @id: Report ID used for frame reports, if they should be tweaked, 521 * zero if not. 522 * 523 * Returns: 524 * Zero, if successful. A negative errno code on error. 525 */ 526 static int uclogic_params_frame_init_with_desc( 527 struct uclogic_params_frame *frame, 528 const __u8 *desc_ptr, 529 size_t desc_size, 530 unsigned int id) 531 { 532 __u8 *copy_desc_ptr; 533 534 if (frame == NULL || (desc_ptr == NULL && desc_size != 0)) 535 return -EINVAL; 536 537 copy_desc_ptr = kmemdup(desc_ptr, desc_size, GFP_KERNEL); 538 if (copy_desc_ptr == NULL) 539 return -ENOMEM; 540 541 memset(frame, 0, sizeof(*frame)); 542 frame->desc_ptr = copy_desc_ptr; 543 frame->desc_size = desc_size; 544 frame->id = id; 545 return 0; 546 } 547 548 /** 549 * uclogic_params_frame_init_v1() - initialize v1 tablet interface frame 550 * controls. 551 * 552 * @frame: Pointer to the frame parameters to initialize (to be cleaned 553 * up with uclogic_params_frame_cleanup()). Not modified in case 554 * of error, or if parameters are not found. Cannot be NULL. 555 * @pfound: Location for a flag which is set to true if the parameters 556 * were found, and to false if not (e.g. device was 557 * incompatible). Not modified in case of error. Cannot be NULL. 558 * @hdev: The HID device of the tablet interface to initialize and get 559 * parameters from. Cannot be NULL. 560 * 561 * Returns: 562 * Zero, if successful. A negative errno code on error. 563 */ 564 static int uclogic_params_frame_init_v1(struct uclogic_params_frame *frame, 565 bool *pfound, 566 struct hid_device *hdev) 567 { 568 int rc; 569 bool found = false; 570 struct usb_device *usb_dev; 571 char *str_buf = NULL; 572 const size_t str_len = 16; 573 574 /* Check arguments */ 575 if (frame == NULL || pfound == NULL || hdev == NULL) { 576 rc = -EINVAL; 577 goto cleanup; 578 } 579 580 usb_dev = hid_to_usb_dev(hdev); 581 582 /* 583 * Enable generic button mode 584 */ 585 str_buf = kzalloc(str_len, GFP_KERNEL); 586 if (str_buf == NULL) { 587 rc = -ENOMEM; 588 goto cleanup; 589 } 590 591 rc = usb_string(usb_dev, 123, str_buf, str_len); 592 if (rc == -EPIPE) { 593 hid_dbg(hdev, 594 "generic button -enabling string descriptor not found\n"); 595 } else if (rc < 0) { 596 goto cleanup; 597 } else if (strncmp(str_buf, "HK On", rc) != 0) { 598 hid_dbg(hdev, 599 "invalid response to enabling generic buttons: \"%s\"\n", 600 str_buf); 601 } else { 602 hid_dbg(hdev, "generic buttons enabled\n"); 603 rc = uclogic_params_frame_init_with_desc( 604 frame, 605 uclogic_rdesc_v1_frame_arr, 606 uclogic_rdesc_v1_frame_size, 607 UCLOGIC_RDESC_V1_FRAME_ID); 608 if (rc != 0) 609 goto cleanup; 610 found = true; 611 } 612 613 *pfound = found; 614 rc = 0; 615 cleanup: 616 kfree(str_buf); 617 return rc; 618 } 619 620 /** 621 * uclogic_params_cleanup_event_hooks - free resources used by the list of raw 622 * event hooks. 623 * Can be called repeatedly. 624 * 625 * @params: Input parameters to cleanup. Cannot be NULL. 626 */ 627 static void uclogic_params_cleanup_event_hooks(struct uclogic_params *params) 628 { 629 struct uclogic_raw_event_hook *curr, *n; 630 631 if (!params || !params->event_hooks) 632 return; 633 634 list_for_each_entry_safe(curr, n, ¶ms->event_hooks->list, list) { 635 cancel_work_sync(&curr->work); 636 list_del(&curr->list); 637 kfree(curr->event); 638 kfree(curr); 639 } 640 641 kfree(params->event_hooks); 642 params->event_hooks = NULL; 643 } 644 645 /** 646 * uclogic_params_cleanup - free resources used by struct uclogic_params 647 * (tablet interface's parameters). 648 * Can be called repeatedly. 649 * 650 * @params: Input parameters to cleanup. Cannot be NULL. 651 */ 652 void uclogic_params_cleanup(struct uclogic_params *params) 653 { 654 if (!params->invalid) { 655 size_t i; 656 kfree(params->desc_ptr); 657 uclogic_params_pen_cleanup(¶ms->pen); 658 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) 659 uclogic_params_frame_cleanup(¶ms->frame_list[i]); 660 661 uclogic_params_cleanup_event_hooks(params); 662 memset(params, 0, sizeof(*params)); 663 } 664 } 665 666 /** 667 * uclogic_params_get_desc() - Get a replacement report descriptor for a 668 * tablet's interface. 669 * 670 * @params: The parameters of a tablet interface to get report 671 * descriptor for. Cannot be NULL. 672 * @pdesc: Location for the resulting, kmalloc-allocated report 673 * descriptor pointer, or for NULL, if there's no replacement 674 * report descriptor. Not modified in case of error. Cannot be 675 * NULL. 676 * @psize: Location for the resulting report descriptor size, not set if 677 * there's no replacement report descriptor. Not modified in case 678 * of error. Cannot be NULL. 679 * 680 * Returns: 681 * Zero, if successful. 682 * -EINVAL, if invalid arguments are supplied. 683 * -ENOMEM, if failed to allocate memory. 684 */ 685 int uclogic_params_get_desc(const struct uclogic_params *params, 686 const __u8 **pdesc, 687 unsigned int *psize) 688 { 689 int rc = -ENOMEM; 690 bool present = false; 691 unsigned int size = 0; 692 __u8 *desc = NULL; 693 size_t i; 694 695 /* Check arguments */ 696 if (params == NULL || pdesc == NULL || psize == NULL) 697 return -EINVAL; 698 699 /* Concatenate descriptors */ 700 #define ADD_DESC(_desc_ptr, _desc_size) \ 701 do { \ 702 unsigned int new_size; \ 703 __u8 *new_desc; \ 704 if ((_desc_ptr) == NULL) { \ 705 break; \ 706 } \ 707 new_size = size + (_desc_size); \ 708 new_desc = krealloc(desc, new_size, GFP_KERNEL); \ 709 if (new_desc == NULL) { \ 710 goto cleanup; \ 711 } \ 712 memcpy(new_desc + size, (_desc_ptr), (_desc_size)); \ 713 desc = new_desc; \ 714 size = new_size; \ 715 present = true; \ 716 } while (0) 717 718 ADD_DESC(params->desc_ptr, params->desc_size); 719 ADD_DESC(params->pen.desc_ptr, params->pen.desc_size); 720 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) { 721 ADD_DESC(params->frame_list[i].desc_ptr, 722 params->frame_list[i].desc_size); 723 } 724 725 #undef ADD_DESC 726 727 if (present) { 728 *pdesc = desc; 729 *psize = size; 730 desc = NULL; 731 } 732 rc = 0; 733 cleanup: 734 kfree(desc); 735 return rc; 736 } 737 738 /** 739 * uclogic_params_init_invalid() - initialize tablet interface parameters, 740 * specifying the interface is invalid. 741 * 742 * @params: Parameters to initialize (to be cleaned with 743 * uclogic_params_cleanup()). Cannot be NULL. 744 */ 745 static void uclogic_params_init_invalid(struct uclogic_params *params) 746 { 747 params->invalid = true; 748 } 749 750 /** 751 * uclogic_params_init_with_opt_desc() - initialize tablet interface 752 * parameters with an optional replacement report descriptor. Only modify 753 * report descriptor, if the original report descriptor matches the expected 754 * size. 755 * 756 * @params: Parameters to initialize (to be cleaned with 757 * uclogic_params_cleanup()). Not modified in case of 758 * error. Cannot be NULL. 759 * @hdev: The HID device of the tablet interface create the 760 * parameters for. Cannot be NULL. 761 * @orig_desc_size: Expected size of the original report descriptor to 762 * be replaced. 763 * @desc_ptr: Pointer to the replacement report descriptor. 764 * Can be NULL, if desc_size is zero. 765 * @desc_size: Size of the replacement report descriptor. 766 * 767 * Returns: 768 * Zero, if successful. -EINVAL if an invalid argument was passed. 769 * -ENOMEM, if failed to allocate memory. 770 */ 771 static int uclogic_params_init_with_opt_desc(struct uclogic_params *params, 772 struct hid_device *hdev, 773 unsigned int orig_desc_size, 774 const __u8 *desc_ptr, 775 unsigned int desc_size) 776 { 777 __u8 *desc_copy_ptr = NULL; 778 unsigned int desc_copy_size; 779 int rc; 780 781 /* Check arguments */ 782 if (params == NULL || hdev == NULL || 783 (desc_ptr == NULL && desc_size != 0)) { 784 rc = -EINVAL; 785 goto cleanup; 786 } 787 788 /* Replace report descriptor, if it matches */ 789 if (hdev->dev_rsize == orig_desc_size) { 790 hid_dbg(hdev, 791 "device report descriptor matches the expected size, replacing\n"); 792 desc_copy_ptr = kmemdup(desc_ptr, desc_size, GFP_KERNEL); 793 if (desc_copy_ptr == NULL) { 794 rc = -ENOMEM; 795 goto cleanup; 796 } 797 desc_copy_size = desc_size; 798 } else { 799 hid_dbg(hdev, 800 "device report descriptor doesn't match the expected size (%u != %u), preserving\n", 801 hdev->dev_rsize, orig_desc_size); 802 desc_copy_ptr = NULL; 803 desc_copy_size = 0; 804 } 805 806 /* Output parameters */ 807 memset(params, 0, sizeof(*params)); 808 params->desc_ptr = desc_copy_ptr; 809 desc_copy_ptr = NULL; 810 params->desc_size = desc_copy_size; 811 812 rc = 0; 813 cleanup: 814 kfree(desc_copy_ptr); 815 return rc; 816 } 817 818 /** 819 * uclogic_params_huion_init() - initialize a Huion tablet interface and discover 820 * its parameters. 821 * 822 * @params: Parameters to fill in (to be cleaned with 823 * uclogic_params_cleanup()). Not modified in case of error. 824 * Cannot be NULL. 825 * @hdev: The HID device of the tablet interface to initialize and get 826 * parameters from. Cannot be NULL. 827 * 828 * Returns: 829 * Zero, if successful. A negative errno code on error. 830 */ 831 static int uclogic_params_huion_init(struct uclogic_params *params, 832 struct hid_device *hdev) 833 { 834 int rc; 835 struct usb_device *udev; 836 struct usb_interface *iface; 837 __u8 bInterfaceNumber; 838 bool found; 839 /* The resulting parameters (noop) */ 840 struct uclogic_params p = {0, }; 841 static const char transition_ver[] = "HUION_T153_160607"; 842 char *ver_ptr = NULL; 843 const size_t ver_len = sizeof(transition_ver) + 1; 844 __u8 *params_ptr = NULL; 845 size_t params_len = 0; 846 /* Parameters string descriptor of a model with touch ring (HS610) */ 847 static const __u8 touch_ring_model_params_buf[] = { 848 0x13, 0x03, 0x70, 0xC6, 0x00, 0x06, 0x7C, 0x00, 849 0xFF, 0x1F, 0xD8, 0x13, 0x03, 0x0D, 0x10, 0x01, 850 0x04, 0x3C, 0x3E 851 }; 852 853 /* Check arguments */ 854 if (params == NULL || hdev == NULL) { 855 rc = -EINVAL; 856 goto cleanup; 857 } 858 859 udev = hid_to_usb_dev(hdev); 860 iface = to_usb_interface(hdev->dev.parent); 861 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; 862 863 /* If it's a custom keyboard interface */ 864 if (bInterfaceNumber == 1) { 865 /* Keep everything intact, but mark pen usage invalid */ 866 p.pen.usage_invalid = true; 867 goto output; 868 /* Else, if it's not a pen interface */ 869 } else if (bInterfaceNumber != 0) { 870 uclogic_params_init_invalid(&p); 871 goto output; 872 } 873 874 /* Try to get firmware version */ 875 ver_ptr = kzalloc(ver_len, GFP_KERNEL); 876 if (ver_ptr == NULL) { 877 rc = -ENOMEM; 878 goto cleanup; 879 } 880 rc = usb_string(udev, 201, ver_ptr, ver_len); 881 if (rc == -EPIPE) { 882 *ver_ptr = '\0'; 883 } else if (rc < 0) { 884 hid_err(hdev, 885 "failed retrieving Huion firmware version: %d\n", rc); 886 goto cleanup; 887 } 888 889 /* The firmware is used in userspace as unique identifier */ 890 strscpy(hdev->uniq, ver_ptr, sizeof(hdev->uniq)); 891 892 /* If this is a transition firmware */ 893 if (strcmp(ver_ptr, transition_ver) == 0) { 894 hid_dbg(hdev, 895 "transition firmware detected, not probing pen v2 parameters\n"); 896 } else { 897 /* Try to probe v2 pen parameters */ 898 rc = uclogic_params_pen_init_v2(&p.pen, &found, 899 ¶ms_ptr, ¶ms_len, 900 hdev); 901 if (rc != 0) { 902 hid_err(hdev, 903 "failed probing pen v2 parameters: %d\n", rc); 904 goto cleanup; 905 } else if (found) { 906 hid_dbg(hdev, "pen v2 parameters found\n"); 907 /* Create v2 frame button parameters */ 908 rc = uclogic_params_frame_init_with_desc( 909 &p.frame_list[0], 910 uclogic_rdesc_v2_frame_buttons_arr, 911 uclogic_rdesc_v2_frame_buttons_size, 912 UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID); 913 if (rc != 0) { 914 hid_err(hdev, 915 "failed creating v2 frame button parameters: %d\n", 916 rc); 917 goto cleanup; 918 } 919 920 /* Link from pen sub-report */ 921 p.pen.subreport_list[0].value = 0xe0; 922 p.pen.subreport_list[0].id = 923 UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID; 924 925 /* If this is the model with touch ring */ 926 if (params_ptr != NULL && 927 params_len == sizeof(touch_ring_model_params_buf) && 928 memcmp(params_ptr, touch_ring_model_params_buf, 929 params_len) == 0) { 930 /* Create touch ring parameters */ 931 rc = uclogic_params_frame_init_with_desc( 932 &p.frame_list[1], 933 uclogic_rdesc_v2_frame_touch_ring_arr, 934 uclogic_rdesc_v2_frame_touch_ring_size, 935 UCLOGIC_RDESC_V2_FRAME_TOUCH_ID); 936 if (rc != 0) { 937 hid_err(hdev, 938 "failed creating v2 frame touch ring parameters: %d\n", 939 rc); 940 goto cleanup; 941 } 942 p.frame_list[1].suffix = "Touch Ring"; 943 p.frame_list[1].dev_id_byte = 944 UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE; 945 p.frame_list[1].touch_byte = 5; 946 p.frame_list[1].touch_max = 12; 947 p.frame_list[1].touch_flip_at = 7; 948 } else { 949 /* Create touch strip parameters */ 950 rc = uclogic_params_frame_init_with_desc( 951 &p.frame_list[1], 952 uclogic_rdesc_v2_frame_touch_strip_arr, 953 uclogic_rdesc_v2_frame_touch_strip_size, 954 UCLOGIC_RDESC_V2_FRAME_TOUCH_ID); 955 if (rc != 0) { 956 hid_err(hdev, 957 "failed creating v2 frame touch strip parameters: %d\n", 958 rc); 959 goto cleanup; 960 } 961 p.frame_list[1].suffix = "Touch Strip"; 962 p.frame_list[1].dev_id_byte = 963 UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE; 964 p.frame_list[1].touch_byte = 5; 965 p.frame_list[1].touch_max = 8; 966 } 967 968 /* Link from pen sub-report */ 969 p.pen.subreport_list[1].value = 0xf0; 970 p.pen.subreport_list[1].id = 971 UCLOGIC_RDESC_V2_FRAME_TOUCH_ID; 972 973 /* Create v2 frame dial parameters */ 974 rc = uclogic_params_frame_init_with_desc( 975 &p.frame_list[2], 976 uclogic_rdesc_v2_frame_dial_arr, 977 uclogic_rdesc_v2_frame_dial_size, 978 UCLOGIC_RDESC_V2_FRAME_DIAL_ID); 979 if (rc != 0) { 980 hid_err(hdev, 981 "failed creating v2 frame dial parameters: %d\n", 982 rc); 983 goto cleanup; 984 } 985 p.frame_list[2].suffix = "Dial"; 986 p.frame_list[2].dev_id_byte = 987 UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE; 988 p.frame_list[2].bitmap_dial_byte = 5; 989 990 /* Link from pen sub-report */ 991 p.pen.subreport_list[2].value = 0xf1; 992 p.pen.subreport_list[2].id = 993 UCLOGIC_RDESC_V2_FRAME_DIAL_ID; 994 995 goto output; 996 } 997 hid_dbg(hdev, "pen v2 parameters not found\n"); 998 } 999 1000 /* Try to probe v1 pen parameters */ 1001 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev); 1002 if (rc != 0) { 1003 hid_err(hdev, 1004 "failed probing pen v1 parameters: %d\n", rc); 1005 goto cleanup; 1006 } else if (found) { 1007 hid_dbg(hdev, "pen v1 parameters found\n"); 1008 /* Try to probe v1 frame */ 1009 rc = uclogic_params_frame_init_v1(&p.frame_list[0], 1010 &found, hdev); 1011 if (rc != 0) { 1012 hid_err(hdev, "v1 frame probing failed: %d\n", rc); 1013 goto cleanup; 1014 } 1015 hid_dbg(hdev, "frame v1 parameters%s found\n", 1016 (found ? "" : " not")); 1017 if (found) { 1018 /* Link frame button subreports from pen reports */ 1019 p.pen.subreport_list[0].value = 0xe0; 1020 p.pen.subreport_list[0].id = 1021 UCLOGIC_RDESC_V1_FRAME_ID; 1022 } 1023 goto output; 1024 } 1025 hid_dbg(hdev, "pen v1 parameters not found\n"); 1026 1027 uclogic_params_init_invalid(&p); 1028 1029 output: 1030 /* Output parameters */ 1031 memcpy(params, &p, sizeof(*params)); 1032 memset(&p, 0, sizeof(p)); 1033 rc = 0; 1034 cleanup: 1035 kfree(params_ptr); 1036 kfree(ver_ptr); 1037 uclogic_params_cleanup(&p); 1038 return rc; 1039 } 1040 1041 /** 1042 * uclogic_probe_interface() - some tablets, like the Parblo A610 PLUS V2 or 1043 * the XP-PEN Deco Mini 7, need to be initialized by sending them magic data. 1044 * 1045 * @hdev: The HID device of the tablet interface to initialize and get 1046 * parameters from. Cannot be NULL. 1047 * @magic_arr: The magic data that should be sent to probe the interface. 1048 * Cannot be NULL. 1049 * @magic_size: Size of the magic data. 1050 * @endpoint: Endpoint where the magic data should be sent. 1051 * 1052 * Returns: 1053 * Zero, if successful. A negative errno code on error. 1054 */ 1055 static int uclogic_probe_interface(struct hid_device *hdev, const u8 *magic_arr, 1056 size_t magic_size, int endpoint) 1057 { 1058 struct usb_device *udev; 1059 unsigned int pipe = 0; 1060 int sent; 1061 u8 *buf = NULL; 1062 int rc = 0; 1063 1064 if (!hdev || !magic_arr) { 1065 rc = -EINVAL; 1066 goto cleanup; 1067 } 1068 1069 buf = kmemdup(magic_arr, magic_size, GFP_KERNEL); 1070 if (!buf) { 1071 rc = -ENOMEM; 1072 goto cleanup; 1073 } 1074 1075 udev = hid_to_usb_dev(hdev); 1076 pipe = usb_sndintpipe(udev, endpoint); 1077 1078 rc = usb_interrupt_msg(udev, pipe, buf, magic_size, &sent, 1000); 1079 if (rc || sent != magic_size) { 1080 hid_err(hdev, "Interface probing failed: %d\n", rc); 1081 rc = -1; 1082 goto cleanup; 1083 } 1084 1085 rc = 0; 1086 cleanup: 1087 kfree(buf); 1088 return rc; 1089 } 1090 1091 /** 1092 * uclogic_params_parse_ugee_v2_desc - parse the string descriptor containing 1093 * pen and frame parameters returned by UGEE v2 devices. 1094 * 1095 * @str_desc: String descriptor, cannot be NULL. 1096 * @str_desc_size: Size of the string descriptor. 1097 * @desc_params: Output description params list. 1098 * @desc_params_size: Size of the output description params list. 1099 * @frame_type: Output frame type. 1100 * 1101 * Returns: 1102 * Zero, if successful. A negative errno code on error. 1103 */ 1104 static int uclogic_params_parse_ugee_v2_desc(const __u8 *str_desc, 1105 size_t str_desc_size, 1106 s32 *desc_params, 1107 size_t desc_params_size, 1108 enum uclogic_params_frame_type *frame_type) 1109 { 1110 s32 pen_x_lm, pen_y_lm; 1111 s32 pen_x_pm, pen_y_pm; 1112 s32 pen_pressure_lm; 1113 s32 frame_num_buttons; 1114 s32 resolution; 1115 1116 /* Minimum descriptor length required, maximum seen so far is 14 */ 1117 const int min_str_desc_size = 12; 1118 1119 if (!str_desc || str_desc_size < min_str_desc_size) 1120 return -EINVAL; 1121 1122 if (desc_params_size != UCLOGIC_RDESC_PH_ID_NUM) 1123 return -EINVAL; 1124 1125 pen_x_lm = get_unaligned_le16(str_desc + 2); 1126 if (str_desc_size > 12) 1127 pen_x_lm += (u8)str_desc[12] << 16; 1128 1129 pen_y_lm = get_unaligned_le16(str_desc + 4); 1130 frame_num_buttons = str_desc[6]; 1131 *frame_type = str_desc[7]; 1132 pen_pressure_lm = get_unaligned_le16(str_desc + 8); 1133 1134 resolution = get_unaligned_le16(str_desc + 10); 1135 if (resolution == 0) { 1136 pen_x_pm = 0; 1137 pen_y_pm = 0; 1138 } else { 1139 pen_x_pm = pen_x_lm * 1000 / resolution; 1140 pen_y_pm = pen_y_lm * 1000 / resolution; 1141 } 1142 1143 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = pen_x_lm; 1144 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = pen_x_pm; 1145 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = pen_y_lm; 1146 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = pen_y_pm; 1147 desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = pen_pressure_lm; 1148 desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = frame_num_buttons; 1149 1150 return 0; 1151 } 1152 1153 /** 1154 * uclogic_params_ugee_v2_init_frame_buttons() - initialize a UGEE v2 frame with 1155 * buttons. 1156 * @p: Parameters to fill in, cannot be NULL. 1157 * @desc_params: Device description params list. 1158 * @desc_params_size: Size of the description params list. 1159 * 1160 * Returns: 1161 * Zero, if successful. A negative errno code on error. 1162 */ 1163 static int uclogic_params_ugee_v2_init_frame_buttons(struct uclogic_params *p, 1164 const s32 *desc_params, 1165 size_t desc_params_size) 1166 { 1167 __u8 *rdesc_frame = NULL; 1168 int rc = 0; 1169 1170 if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM) 1171 return -EINVAL; 1172 1173 rdesc_frame = uclogic_rdesc_template_apply( 1174 uclogic_rdesc_ugee_v2_frame_btn_template_arr, 1175 uclogic_rdesc_ugee_v2_frame_btn_template_size, 1176 desc_params, UCLOGIC_RDESC_PH_ID_NUM); 1177 if (!rdesc_frame) 1178 return -ENOMEM; 1179 1180 rc = uclogic_params_frame_init_with_desc(&p->frame_list[0], 1181 rdesc_frame, 1182 uclogic_rdesc_ugee_v2_frame_btn_template_size, 1183 UCLOGIC_RDESC_V1_FRAME_ID); 1184 kfree(rdesc_frame); 1185 return rc; 1186 } 1187 1188 /** 1189 * uclogic_params_ugee_v2_init_frame_dial() - initialize a UGEE v2 frame with a 1190 * bitmap dial. 1191 * @p: Parameters to fill in, cannot be NULL. 1192 * @desc_params: Device description params list. 1193 * @desc_params_size: Size of the description params list. 1194 * 1195 * Returns: 1196 * Zero, if successful. A negative errno code on error. 1197 */ 1198 static int uclogic_params_ugee_v2_init_frame_dial(struct uclogic_params *p, 1199 const s32 *desc_params, 1200 size_t desc_params_size) 1201 { 1202 __u8 *rdesc_frame = NULL; 1203 int rc = 0; 1204 1205 if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM) 1206 return -EINVAL; 1207 1208 rdesc_frame = uclogic_rdesc_template_apply( 1209 uclogic_rdesc_ugee_v2_frame_dial_template_arr, 1210 uclogic_rdesc_ugee_v2_frame_dial_template_size, 1211 desc_params, UCLOGIC_RDESC_PH_ID_NUM); 1212 if (!rdesc_frame) 1213 return -ENOMEM; 1214 1215 rc = uclogic_params_frame_init_with_desc(&p->frame_list[0], 1216 rdesc_frame, 1217 uclogic_rdesc_ugee_v2_frame_dial_template_size, 1218 UCLOGIC_RDESC_V1_FRAME_ID); 1219 kfree(rdesc_frame); 1220 if (rc) 1221 return rc; 1222 1223 p->frame_list[0].bitmap_dial_byte = 7; 1224 return 0; 1225 } 1226 1227 /** 1228 * uclogic_params_ugee_v2_init_frame_mouse() - initialize a UGEE v2 frame with a 1229 * mouse. 1230 * @p: Parameters to fill in, cannot be NULL. 1231 * 1232 * Returns: 1233 * Zero, if successful. A negative errno code on error. 1234 */ 1235 static int uclogic_params_ugee_v2_init_frame_mouse(struct uclogic_params *p) 1236 { 1237 int rc = 0; 1238 1239 if (!p) 1240 return -EINVAL; 1241 1242 rc = uclogic_params_frame_init_with_desc(&p->frame_list[1], 1243 uclogic_rdesc_ugee_v2_frame_mouse_template_arr, 1244 uclogic_rdesc_ugee_v2_frame_mouse_template_size, 1245 UCLOGIC_RDESC_V1_FRAME_ID); 1246 return rc; 1247 } 1248 1249 /** 1250 * uclogic_params_ugee_v2_has_battery() - check whether a UGEE v2 device has 1251 * battery or not. 1252 * @hdev: The HID device of the tablet interface. 1253 * 1254 * Returns: 1255 * True if the device has battery, false otherwise. 1256 */ 1257 static bool uclogic_params_ugee_v2_has_battery(struct hid_device *hdev) 1258 { 1259 struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); 1260 1261 if (drvdata->quirks & UCLOGIC_BATTERY_QUIRK) 1262 return true; 1263 1264 /* The XP-PEN Deco LW vendor, product and version are identical to the 1265 * Deco L. The only difference reported by their firmware is the product 1266 * name. Add a quirk to support battery reporting on the wireless 1267 * version. 1268 */ 1269 if (hdev->vendor == USB_VENDOR_ID_UGEE && 1270 hdev->product == USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) { 1271 struct usb_device *udev = hid_to_usb_dev(hdev); 1272 1273 if (strstarts(udev->product, "Deco LW")) 1274 return true; 1275 } 1276 1277 return false; 1278 } 1279 1280 /** 1281 * uclogic_params_ugee_v2_init_battery() - initialize UGEE v2 battery reporting. 1282 * @hdev: The HID device of the tablet interface, cannot be NULL. 1283 * @p: Parameters to fill in, cannot be NULL. 1284 * 1285 * Returns: 1286 * Zero, if successful. A negative errno code on error. 1287 */ 1288 static int uclogic_params_ugee_v2_init_battery(struct hid_device *hdev, 1289 struct uclogic_params *p) 1290 { 1291 int rc = 0; 1292 1293 if (!hdev || !p) 1294 return -EINVAL; 1295 1296 /* Some tablets contain invalid characters in hdev->uniq, throwing a 1297 * "hwmon: '<name>' is not a valid name attribute, please fix" error. 1298 * Use the device vendor and product IDs instead. 1299 */ 1300 snprintf(hdev->uniq, sizeof(hdev->uniq), "%x-%x", hdev->vendor, 1301 hdev->product); 1302 1303 rc = uclogic_params_frame_init_with_desc(&p->frame_list[1], 1304 uclogic_rdesc_ugee_v2_battery_template_arr, 1305 uclogic_rdesc_ugee_v2_battery_template_size, 1306 UCLOGIC_RDESC_UGEE_V2_BATTERY_ID); 1307 if (rc) 1308 return rc; 1309 1310 p->frame_list[1].suffix = "Battery"; 1311 p->pen.subreport_list[1].value = 0xf2; 1312 p->pen.subreport_list[1].id = UCLOGIC_RDESC_UGEE_V2_BATTERY_ID; 1313 1314 return rc; 1315 } 1316 1317 /** 1318 * uclogic_params_ugee_v2_reconnect_work() - When a wireless tablet looses 1319 * connection to the USB dongle and reconnects, either because of its physical 1320 * distance or because it was switches off and on using the frame's switch, 1321 * uclogic_probe_interface() needs to be called again to enable the tablet. 1322 * 1323 * @work: The work that triggered this function. 1324 */ 1325 static void uclogic_params_ugee_v2_reconnect_work(struct work_struct *work) 1326 { 1327 struct uclogic_raw_event_hook *event_hook; 1328 1329 event_hook = container_of(work, struct uclogic_raw_event_hook, work); 1330 uclogic_probe_interface(event_hook->hdev, uclogic_ugee_v2_probe_arr, 1331 uclogic_ugee_v2_probe_size, 1332 uclogic_ugee_v2_probe_endpoint); 1333 } 1334 1335 /** 1336 * uclogic_params_ugee_v2_init_event_hooks() - initialize the list of events 1337 * to be hooked for UGEE v2 devices. 1338 * @hdev: The HID device of the tablet interface to initialize and get 1339 * parameters from. 1340 * @p: Parameters to fill in, cannot be NULL. 1341 * 1342 * Returns: 1343 * Zero, if successful. A negative errno code on error. 1344 */ 1345 static int uclogic_params_ugee_v2_init_event_hooks(struct hid_device *hdev, 1346 struct uclogic_params *p) 1347 { 1348 struct uclogic_raw_event_hook *event_hook; 1349 static const __u8 reconnect_event[] = { 1350 /* Event received on wireless tablet reconnection */ 1351 0x02, 0xF8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1352 }; 1353 1354 if (!p) 1355 return -EINVAL; 1356 1357 /* The reconnection event is only received if the tablet has battery */ 1358 if (!uclogic_params_ugee_v2_has_battery(hdev)) 1359 return 0; 1360 1361 p->event_hooks = kzalloc(sizeof(*p->event_hooks), GFP_KERNEL); 1362 if (!p->event_hooks) 1363 return -ENOMEM; 1364 1365 INIT_LIST_HEAD(&p->event_hooks->list); 1366 1367 event_hook = kzalloc(sizeof(*event_hook), GFP_KERNEL); 1368 if (!event_hook) 1369 return -ENOMEM; 1370 1371 INIT_WORK(&event_hook->work, uclogic_params_ugee_v2_reconnect_work); 1372 event_hook->hdev = hdev; 1373 event_hook->size = ARRAY_SIZE(reconnect_event); 1374 event_hook->event = kmemdup(reconnect_event, event_hook->size, GFP_KERNEL); 1375 if (!event_hook->event) { 1376 kfree(event_hook); 1377 return -ENOMEM; 1378 } 1379 1380 list_add_tail(&event_hook->list, &p->event_hooks->list); 1381 1382 return 0; 1383 } 1384 1385 /** 1386 * uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by 1387 * discovering their parameters. 1388 * 1389 * These tables, internally designed as v2 to differentiate them from older 1390 * models, expect a payload of magic data in orther to be switched to the fully 1391 * functional mode and expose their parameters in a similar way to the 1392 * information present in uclogic_params_pen_init_v1() but with some 1393 * differences. 1394 * 1395 * @params: Parameters to fill in (to be cleaned with 1396 * uclogic_params_cleanup()). Not modified in case of error. 1397 * Cannot be NULL. 1398 * @hdev: The HID device of the tablet interface to initialize and get 1399 * parameters from. Cannot be NULL. 1400 * 1401 * Returns: 1402 * Zero, if successful. A negative errno code on error. 1403 */ 1404 static int uclogic_params_ugee_v2_init(struct uclogic_params *params, 1405 struct hid_device *hdev) 1406 { 1407 int rc = 0; 1408 struct uclogic_drvdata *drvdata; 1409 struct usb_interface *iface; 1410 __u8 bInterfaceNumber; 1411 const int str_desc_len = 12; 1412 __u8 *str_desc = NULL; 1413 __u8 *rdesc_pen = NULL; 1414 s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM]; 1415 enum uclogic_params_frame_type frame_type; 1416 /* The resulting parameters (noop) */ 1417 struct uclogic_params p = {0, }; 1418 1419 if (!params || !hdev) { 1420 rc = -EINVAL; 1421 goto cleanup; 1422 } 1423 1424 drvdata = hid_get_drvdata(hdev); 1425 iface = to_usb_interface(hdev->dev.parent); 1426 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; 1427 1428 if (bInterfaceNumber == 0) { 1429 rc = uclogic_params_ugee_v2_init_frame_mouse(&p); 1430 if (rc) 1431 goto cleanup; 1432 1433 goto output; 1434 } 1435 1436 if (bInterfaceNumber != 2) { 1437 uclogic_params_init_invalid(&p); 1438 goto output; 1439 } 1440 1441 /* 1442 * Initialize the interface by sending magic data. 1443 * The specific data was discovered by sniffing the Windows driver 1444 * traffic. 1445 */ 1446 rc = uclogic_probe_interface(hdev, uclogic_ugee_v2_probe_arr, 1447 uclogic_ugee_v2_probe_size, 1448 uclogic_ugee_v2_probe_endpoint); 1449 if (rc) { 1450 uclogic_params_init_invalid(&p); 1451 goto output; 1452 } 1453 1454 /* 1455 * Read the string descriptor containing pen and frame parameters. 1456 * The specific string descriptor and data were discovered by sniffing 1457 * the Windows driver traffic. 1458 */ 1459 rc = uclogic_params_get_str_desc(&str_desc, hdev, 100, str_desc_len); 1460 if (rc != str_desc_len) { 1461 hid_err(hdev, "failed retrieving pen and frame parameters: %d\n", rc); 1462 uclogic_params_init_invalid(&p); 1463 goto output; 1464 } 1465 1466 rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len, 1467 desc_params, 1468 ARRAY_SIZE(desc_params), 1469 &frame_type); 1470 if (rc) 1471 goto cleanup; 1472 1473 kfree(str_desc); 1474 str_desc = NULL; 1475 1476 /* Initialize the pen interface */ 1477 rdesc_pen = uclogic_rdesc_template_apply( 1478 uclogic_rdesc_ugee_v2_pen_template_arr, 1479 uclogic_rdesc_ugee_v2_pen_template_size, 1480 desc_params, ARRAY_SIZE(desc_params)); 1481 if (!rdesc_pen) { 1482 rc = -ENOMEM; 1483 goto cleanup; 1484 } 1485 1486 p.pen.desc_ptr = rdesc_pen; 1487 p.pen.desc_size = uclogic_rdesc_ugee_v2_pen_template_size; 1488 p.pen.id = 0x02; 1489 p.pen.subreport_list[0].value = 0xf0; 1490 p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID; 1491 1492 /* Initialize the frame interface */ 1493 if (drvdata->quirks & UCLOGIC_MOUSE_FRAME_QUIRK) 1494 frame_type = UCLOGIC_PARAMS_FRAME_MOUSE; 1495 1496 switch (frame_type) { 1497 case UCLOGIC_PARAMS_FRAME_DIAL: 1498 case UCLOGIC_PARAMS_FRAME_MOUSE: 1499 rc = uclogic_params_ugee_v2_init_frame_dial(&p, desc_params, 1500 ARRAY_SIZE(desc_params)); 1501 break; 1502 case UCLOGIC_PARAMS_FRAME_BUTTONS: 1503 default: 1504 rc = uclogic_params_ugee_v2_init_frame_buttons(&p, desc_params, 1505 ARRAY_SIZE(desc_params)); 1506 break; 1507 } 1508 1509 if (rc) 1510 goto cleanup; 1511 1512 /* Initialize the battery interface*/ 1513 if (uclogic_params_ugee_v2_has_battery(hdev)) { 1514 rc = uclogic_params_ugee_v2_init_battery(hdev, &p); 1515 if (rc) { 1516 hid_err(hdev, "error initializing battery: %d\n", rc); 1517 goto cleanup; 1518 } 1519 } 1520 1521 /* Create a list of raw events to be ignored */ 1522 rc = uclogic_params_ugee_v2_init_event_hooks(hdev, &p); 1523 if (rc) { 1524 hid_err(hdev, "error initializing event hook list: %d\n", rc); 1525 goto cleanup; 1526 } 1527 1528 output: 1529 /* Output parameters */ 1530 memcpy(params, &p, sizeof(*params)); 1531 memset(&p, 0, sizeof(p)); 1532 rc = 0; 1533 cleanup: 1534 kfree(str_desc); 1535 uclogic_params_cleanup(&p); 1536 return rc; 1537 } 1538 1539 /* 1540 * uclogic_params_init_ugee_xppen_pro() - Initializes a UGEE XP-Pen Pro tablet device. 1541 * 1542 * @hdev: The HID device of the tablet interface to initialize and get 1543 * parameters from. Cannot be NULL. 1544 * @params: Parameters to fill in (to be cleaned with 1545 * uclogic_params_cleanup()). Not modified in case of error. 1546 * Cannot be NULL. 1547 * 1548 * Returns: 1549 * Zero, if successful. A negative errno code on error. 1550 */ 1551 static int uclogic_params_init_ugee_xppen_pro(struct uclogic_params *params, 1552 struct hid_device *hdev, 1553 const u8 rdesc_pen_arr[], 1554 const size_t rdesc_pen_size, 1555 const u8 rdesc_frame_arr[], 1556 const size_t rdesc_frame_size, 1557 size_t str_desc_len) 1558 { 1559 int rc = 0; 1560 struct usb_interface *iface; 1561 __u8 bInterfaceNumber; 1562 u8 *str_desc = NULL; 1563 __u8 *rdesc_pen = NULL; 1564 s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM]; 1565 enum uclogic_params_frame_type frame_type; 1566 /* The resulting parameters (noop) */ 1567 struct uclogic_params p = {0, }; 1568 1569 if (!hdev || !params) { 1570 rc = -EINVAL; 1571 goto cleanup; 1572 } 1573 1574 iface = to_usb_interface(hdev->dev.parent); 1575 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; 1576 1577 /* Ignore non-pen interfaces */ 1578 if (bInterfaceNumber != 2) { 1579 rc = -EINVAL; 1580 uclogic_params_init_invalid(&p); 1581 goto cleanup; 1582 } 1583 1584 /* 1585 * Initialize the interface by sending magic data. 1586 * This magic data is the same as other UGEE v2 tablets. 1587 */ 1588 rc = uclogic_probe_interface(hdev, 1589 uclogic_ugee_v2_probe_arr, 1590 uclogic_ugee_v2_probe_size, 1591 uclogic_ugee_v2_probe_endpoint); 1592 if (rc) { 1593 uclogic_params_init_invalid(&p); 1594 goto cleanup; 1595 } 1596 1597 /** 1598 * Read the string descriptor containing pen and frame parameters. 1599 * These are slightly different than typical UGEE v2 devices. 1600 */ 1601 rc = uclogic_params_get_str_desc(&str_desc, hdev, 100, str_desc_len); 1602 if (rc != str_desc_len) { 1603 rc = (rc < 0) ? rc : -EINVAL; 1604 hid_err(hdev, "failed retrieving pen and frame parameters: %d\n", rc); 1605 uclogic_params_init_invalid(&p); 1606 goto cleanup; 1607 } 1608 1609 rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len, 1610 desc_params, 1611 ARRAY_SIZE(desc_params), 1612 &frame_type); 1613 if (rc) 1614 goto cleanup; 1615 1616 // str_desc doesn't report the correct amount of buttons, so manually fix it 1617 desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 20; 1618 1619 kfree(str_desc); 1620 str_desc = NULL; 1621 1622 /* Initialize the pen interface */ 1623 rdesc_pen = uclogic_rdesc_template_apply( 1624 rdesc_pen_arr, 1625 rdesc_pen_size, 1626 desc_params, ARRAY_SIZE(desc_params)); 1627 if (!rdesc_pen) { 1628 rc = -ENOMEM; 1629 goto cleanup; 1630 } 1631 1632 p.pen.desc_ptr = rdesc_pen; 1633 p.pen.desc_size = rdesc_pen_size; 1634 p.pen.id = 0x02; 1635 p.pen.subreport_list[0].value = 0xf0; 1636 p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID; 1637 1638 /* Initialize the frame interface */ 1639 rc = uclogic_params_frame_init_with_desc( 1640 &p.frame_list[0], 1641 rdesc_frame_arr, 1642 rdesc_frame_size, 1643 UCLOGIC_RDESC_V1_FRAME_ID); 1644 if (rc < 0) { 1645 hid_err(hdev, "initializing frame params failed: %d\n", rc); 1646 goto cleanup; 1647 } 1648 1649 p.frame_list[0].bitmap_dial_byte = 7; 1650 p.frame_list[0].bitmap_second_dial_destination_byte = 8; 1651 1652 /* Output parameters */ 1653 memcpy(params, &p, sizeof(*params)); 1654 memset(&p, 0, sizeof(p)); 1655 cleanup: 1656 kfree(str_desc); 1657 uclogic_params_cleanup(&p); 1658 return rc; 1659 } 1660 1661 /** 1662 * uclogic_params_init() - initialize a tablet interface and discover its 1663 * parameters. 1664 * 1665 * @params: Parameters to fill in (to be cleaned with 1666 * uclogic_params_cleanup()). Not modified in case of error. 1667 * Cannot be NULL. 1668 * @hdev: The HID device of the tablet interface to initialize and get 1669 * parameters from. Cannot be NULL. Must be using the USB low-level 1670 * driver, i.e. be an actual USB tablet. 1671 * 1672 * Returns: 1673 * Zero, if successful. A negative errno code on error. 1674 */ 1675 int uclogic_params_init(struct uclogic_params *params, 1676 struct hid_device *hdev) 1677 { 1678 int rc; 1679 struct usb_device *udev; 1680 __u8 bNumInterfaces; 1681 struct usb_interface *iface; 1682 __u8 bInterfaceNumber; 1683 bool found; 1684 /* The resulting parameters (noop) */ 1685 struct uclogic_params p = {0, }; 1686 1687 /* Check arguments */ 1688 if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) { 1689 rc = -EINVAL; 1690 goto cleanup; 1691 } 1692 1693 udev = hid_to_usb_dev(hdev); 1694 bNumInterfaces = udev->config->desc.bNumInterfaces; 1695 iface = to_usb_interface(hdev->dev.parent); 1696 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; 1697 1698 /* 1699 * Set replacement report descriptor if the original matches the 1700 * specified size. Otherwise keep interface unchanged. 1701 */ 1702 #define WITH_OPT_DESC(_orig_desc_token, _new_desc_token) \ 1703 uclogic_params_init_with_opt_desc( \ 1704 &p, hdev, \ 1705 UCLOGIC_RDESC_##_orig_desc_token##_SIZE, \ 1706 uclogic_rdesc_##_new_desc_token##_arr, \ 1707 uclogic_rdesc_##_new_desc_token##_size) 1708 1709 #define VID_PID(_vid, _pid) \ 1710 (((__u32)(_vid) << 16) | ((__u32)(_pid) & U16_MAX)) 1711 1712 /* 1713 * Handle specific interfaces for specific tablets. 1714 * 1715 * Observe the following logic: 1716 * 1717 * If the interface is recognized as producing certain useful input: 1718 * Mark interface as valid. 1719 * Output interface parameters. 1720 * Else, if the interface is recognized as *not* producing any useful 1721 * input: 1722 * Mark interface as invalid. 1723 * Else: 1724 * Mark interface as valid. 1725 * Output noop parameters. 1726 * 1727 * Rule of thumb: it is better to disable a broken interface than let 1728 * it spew garbage input. 1729 */ 1730 1731 switch (VID_PID(hdev->vendor, hdev->product)) { 1732 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1733 USB_DEVICE_ID_UCLOGIC_TABLET_PF1209): 1734 rc = WITH_OPT_DESC(PF1209_ORIG, pf1209_fixed); 1735 if (rc != 0) 1736 goto cleanup; 1737 break; 1738 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1739 USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U): 1740 rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp4030u_fixed); 1741 if (rc != 0) 1742 goto cleanup; 1743 break; 1744 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1745 USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U): 1746 if (hdev->dev_rsize == UCLOGIC_RDESC_WP5540U_V2_ORIG_SIZE) { 1747 if (bInterfaceNumber == 0) { 1748 /* Try to probe v1 pen parameters */ 1749 rc = uclogic_params_pen_init_v1(&p.pen, 1750 &found, hdev); 1751 if (rc != 0) { 1752 hid_err(hdev, 1753 "pen probing failed: %d\n", 1754 rc); 1755 goto cleanup; 1756 } 1757 if (!found) { 1758 hid_warn(hdev, 1759 "pen parameters not found"); 1760 } 1761 } else { 1762 uclogic_params_init_invalid(&p); 1763 } 1764 } else { 1765 rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp5540u_fixed); 1766 if (rc != 0) 1767 goto cleanup; 1768 } 1769 break; 1770 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1771 USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U): 1772 rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp8060u_fixed); 1773 if (rc != 0) 1774 goto cleanup; 1775 break; 1776 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1777 USB_DEVICE_ID_UCLOGIC_TABLET_WP1062): 1778 rc = WITH_OPT_DESC(WP1062_ORIG, wp1062_fixed); 1779 if (rc != 0) 1780 goto cleanup; 1781 break; 1782 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1783 USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850): 1784 switch (bInterfaceNumber) { 1785 case 0: 1786 rc = WITH_OPT_DESC(TWHL850_ORIG0, twhl850_fixed0); 1787 if (rc != 0) 1788 goto cleanup; 1789 break; 1790 case 1: 1791 rc = WITH_OPT_DESC(TWHL850_ORIG1, twhl850_fixed1); 1792 if (rc != 0) 1793 goto cleanup; 1794 break; 1795 case 2: 1796 rc = WITH_OPT_DESC(TWHL850_ORIG2, twhl850_fixed2); 1797 if (rc != 0) 1798 goto cleanup; 1799 break; 1800 } 1801 break; 1802 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1803 USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60): 1804 /* 1805 * If it is not a three-interface version, which is known to 1806 * respond to initialization. 1807 */ 1808 if (bNumInterfaces != 3) { 1809 switch (bInterfaceNumber) { 1810 case 0: 1811 rc = WITH_OPT_DESC(TWHA60_ORIG0, 1812 twha60_fixed0); 1813 if (rc != 0) 1814 goto cleanup; 1815 break; 1816 case 1: 1817 rc = WITH_OPT_DESC(TWHA60_ORIG1, 1818 twha60_fixed1); 1819 if (rc != 0) 1820 goto cleanup; 1821 break; 1822 } 1823 break; 1824 } 1825 fallthrough; 1826 case VID_PID(USB_VENDOR_ID_HUION, 1827 USB_DEVICE_ID_HUION_TABLET): 1828 case VID_PID(USB_VENDOR_ID_HUION, 1829 USB_DEVICE_ID_HUION_TABLET2): 1830 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1831 USB_DEVICE_ID_HUION_TABLET): 1832 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1833 USB_DEVICE_ID_YIYNOVA_TABLET): 1834 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1835 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_81): 1836 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1837 USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3): 1838 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1839 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_45): 1840 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1841 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_47): 1842 rc = uclogic_params_huion_init(&p, hdev); 1843 if (rc != 0) 1844 goto cleanup; 1845 break; 1846 case VID_PID(USB_VENDOR_ID_UGTIZER, 1847 USB_DEVICE_ID_UGTIZER_TABLET_GP0610): 1848 case VID_PID(USB_VENDOR_ID_UGTIZER, 1849 USB_DEVICE_ID_UGTIZER_TABLET_GT5040): 1850 case VID_PID(USB_VENDOR_ID_UGEE, 1851 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540): 1852 case VID_PID(USB_VENDOR_ID_UGEE, 1853 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640): 1854 case VID_PID(USB_VENDOR_ID_UGEE, 1855 USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06): 1856 case VID_PID(USB_VENDOR_ID_UGEE, 1857 USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720): 1858 /* If this is the pen interface */ 1859 if (bInterfaceNumber == 1) { 1860 /* Probe v1 pen parameters */ 1861 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev); 1862 if (rc != 0) { 1863 hid_err(hdev, "pen probing failed: %d\n", rc); 1864 goto cleanup; 1865 } 1866 if (!found) { 1867 hid_warn(hdev, "pen parameters not found"); 1868 uclogic_params_init_invalid(&p); 1869 } 1870 } else { 1871 uclogic_params_init_invalid(&p); 1872 } 1873 break; 1874 case VID_PID(USB_VENDOR_ID_UGEE, 1875 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01): 1876 /* If this is the pen and frame interface */ 1877 if (bInterfaceNumber == 1) { 1878 /* Probe v1 pen parameters */ 1879 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev); 1880 if (rc != 0) { 1881 hid_err(hdev, "pen probing failed: %d\n", rc); 1882 goto cleanup; 1883 } 1884 /* Initialize frame parameters */ 1885 rc = uclogic_params_frame_init_with_desc( 1886 &p.frame_list[0], 1887 uclogic_rdesc_xppen_deco01_frame_arr, 1888 uclogic_rdesc_xppen_deco01_frame_size, 1889 0); 1890 if (rc != 0) 1891 goto cleanup; 1892 } else { 1893 uclogic_params_init_invalid(&p); 1894 } 1895 break; 1896 case VID_PID(USB_VENDOR_ID_UGEE, 1897 USB_DEVICE_ID_UGEE_PARBLO_A610_PRO): 1898 case VID_PID(USB_VENDOR_ID_UGEE, 1899 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01_V2): 1900 case VID_PID(USB_VENDOR_ID_UGEE, 1901 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L): 1902 case VID_PID(USB_VENDOR_ID_UGEE, 1903 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_MW): 1904 case VID_PID(USB_VENDOR_ID_UGEE, 1905 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S): 1906 case VID_PID(USB_VENDOR_ID_UGEE, 1907 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW): 1908 rc = uclogic_params_ugee_v2_init(&p, hdev); 1909 if (rc != 0) 1910 goto cleanup; 1911 break; 1912 case VID_PID(USB_VENDOR_ID_TRUST, 1913 USB_DEVICE_ID_TRUST_PANORA_TABLET): 1914 case VID_PID(USB_VENDOR_ID_UGEE, 1915 USB_DEVICE_ID_UGEE_TABLET_G5): 1916 /* Ignore non-pen interfaces */ 1917 if (bInterfaceNumber != 1) { 1918 uclogic_params_init_invalid(&p); 1919 break; 1920 } 1921 1922 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev); 1923 if (rc != 0) { 1924 hid_err(hdev, "pen probing failed: %d\n", rc); 1925 goto cleanup; 1926 } else if (found) { 1927 rc = uclogic_params_frame_init_with_desc( 1928 &p.frame_list[0], 1929 uclogic_rdesc_ugee_g5_frame_arr, 1930 uclogic_rdesc_ugee_g5_frame_size, 1931 UCLOGIC_RDESC_UGEE_G5_FRAME_ID); 1932 if (rc != 0) { 1933 hid_err(hdev, 1934 "failed creating frame parameters: %d\n", 1935 rc); 1936 goto cleanup; 1937 } 1938 p.frame_list[0].re_lsb = 1939 UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB; 1940 p.frame_list[0].dev_id_byte = 1941 UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE; 1942 } else { 1943 hid_warn(hdev, "pen parameters not found"); 1944 uclogic_params_init_invalid(&p); 1945 } 1946 1947 break; 1948 case VID_PID(USB_VENDOR_ID_UGEE, 1949 USB_DEVICE_ID_UGEE_TABLET_EX07S): 1950 /* Ignore non-pen interfaces */ 1951 if (bInterfaceNumber != 1) { 1952 uclogic_params_init_invalid(&p); 1953 break; 1954 } 1955 1956 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev); 1957 if (rc != 0) { 1958 hid_err(hdev, "pen probing failed: %d\n", rc); 1959 goto cleanup; 1960 } else if (found) { 1961 rc = uclogic_params_frame_init_with_desc( 1962 &p.frame_list[0], 1963 uclogic_rdesc_ugee_ex07_frame_arr, 1964 uclogic_rdesc_ugee_ex07_frame_size, 1965 0); 1966 if (rc != 0) { 1967 hid_err(hdev, 1968 "failed creating frame parameters: %d\n", 1969 rc); 1970 goto cleanup; 1971 } 1972 } else { 1973 hid_warn(hdev, "pen parameters not found"); 1974 uclogic_params_init_invalid(&p); 1975 } 1976 1977 break; 1978 case VID_PID(USB_VENDOR_ID_UGEE, 1979 USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO): 1980 rc = uclogic_params_init_ugee_xppen_pro(&p, 1981 hdev, 1982 uclogic_rdesc_ugee_v2_pen_template_arr, 1983 uclogic_rdesc_ugee_v2_pen_template_size, 1984 uclogic_rdesc_xppen_artist_22r_pro_frame_arr, 1985 uclogic_rdesc_xppen_artist_22r_pro_frame_size, 1986 12); 1987 if (rc != 0) 1988 goto cleanup; 1989 1990 break; 1991 case VID_PID(USB_VENDOR_ID_UGEE, 1992 USB_DEVICE_ID_UGEE_XPPEN_TABLET_24_PRO): 1993 rc = uclogic_params_init_ugee_xppen_pro(&p, 1994 hdev, 1995 uclogic_rdesc_xppen_artist_24_pro_pen_template_arr, 1996 uclogic_rdesc_xppen_artist_24_pro_pen_template_size, 1997 uclogic_rdesc_xppen_artist_24_pro_frame_arr, 1998 uclogic_rdesc_xppen_artist_24_pro_frame_size, 1999 14); 2000 2001 // The 24 Pro has a fragmented X Coord. 2002 p.pen.fragmented_hires2 = true; 2003 2004 if (rc != 0) 2005 goto cleanup; 2006 2007 break; 2008 } 2009 2010 #undef VID_PID 2011 #undef WITH_OPT_DESC 2012 2013 /* Output parameters */ 2014 memcpy(params, &p, sizeof(*params)); 2015 memset(&p, 0, sizeof(p)); 2016 rc = 0; 2017 cleanup: 2018 uclogic_params_cleanup(&p); 2019 return rc; 2020 } 2021 2022 #ifdef CONFIG_HID_KUNIT_TEST 2023 #include "hid-uclogic-params-test.c" 2024 #endif 2025