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 24 /** 25 * uclogic_params_pen_inrange_to_str() - Convert a pen in-range reporting type 26 * to a string. 27 * @inrange: The in-range reporting type to convert. 28 * 29 * Return: 30 * * The string representing the type, or 31 * * %NULL if the type is unknown. 32 */ 33 static const char *uclogic_params_pen_inrange_to_str( 34 enum uclogic_params_pen_inrange inrange) 35 { 36 switch (inrange) { 37 case UCLOGIC_PARAMS_PEN_INRANGE_NORMAL: 38 return "normal"; 39 case UCLOGIC_PARAMS_PEN_INRANGE_INVERTED: 40 return "inverted"; 41 case UCLOGIC_PARAMS_PEN_INRANGE_NONE: 42 return "none"; 43 default: 44 return NULL; 45 } 46 } 47 48 /** 49 * uclogic_params_pen_hid_dbg() - Dump tablet interface pen parameters 50 * @hdev: The HID device the pen parameters describe. 51 * @pen: The pen parameters to dump. 52 * 53 * Dump tablet interface pen parameters with hid_dbg(). The dump is indented 54 * with a tab. 55 */ 56 static void uclogic_params_pen_hid_dbg(const struct hid_device *hdev, 57 const struct uclogic_params_pen *pen) 58 { 59 size_t i; 60 61 hid_dbg(hdev, "\t.usage_invalid = %s\n", 62 (pen->usage_invalid ? "true" : "false")); 63 hid_dbg(hdev, "\t.desc_ptr = %p\n", pen->desc_ptr); 64 hid_dbg(hdev, "\t.desc_size = %u\n", pen->desc_size); 65 hid_dbg(hdev, "\t.id = %u\n", pen->id); 66 hid_dbg(hdev, "\t.subreport_list = {\n"); 67 for (i = 0; i < ARRAY_SIZE(pen->subreport_list); i++) { 68 hid_dbg(hdev, "\t\t{0x%02hhx, %hhu}%s\n", 69 pen->subreport_list[i].value, 70 pen->subreport_list[i].id, 71 i < (ARRAY_SIZE(pen->subreport_list) - 1) ? "," : ""); 72 } 73 hid_dbg(hdev, "\t}\n"); 74 hid_dbg(hdev, "\t.inrange = %s\n", 75 uclogic_params_pen_inrange_to_str(pen->inrange)); 76 hid_dbg(hdev, "\t.fragmented_hires = %s\n", 77 (pen->fragmented_hires ? "true" : "false")); 78 hid_dbg(hdev, "\t.tilt_y_flipped = %s\n", 79 (pen->tilt_y_flipped ? "true" : "false")); 80 } 81 82 /** 83 * uclogic_params_frame_hid_dbg() - Dump tablet interface frame parameters 84 * @hdev: The HID device the pen parameters describe. 85 * @frame: The frame parameters to dump. 86 * 87 * Dump tablet interface frame parameters with hid_dbg(). The dump is 88 * indented with two tabs. 89 */ 90 static void uclogic_params_frame_hid_dbg( 91 const struct hid_device *hdev, 92 const struct uclogic_params_frame *frame) 93 { 94 hid_dbg(hdev, "\t\t.desc_ptr = %p\n", frame->desc_ptr); 95 hid_dbg(hdev, "\t\t.desc_size = %u\n", frame->desc_size); 96 hid_dbg(hdev, "\t\t.id = %u\n", frame->id); 97 hid_dbg(hdev, "\t\t.suffix = %s\n", frame->suffix); 98 hid_dbg(hdev, "\t\t.re_lsb = %u\n", frame->re_lsb); 99 hid_dbg(hdev, "\t\t.dev_id_byte = %u\n", frame->dev_id_byte); 100 hid_dbg(hdev, "\t\t.touch_byte = %u\n", frame->touch_byte); 101 hid_dbg(hdev, "\t\t.touch_max = %hhd\n", frame->touch_max); 102 hid_dbg(hdev, "\t\t.touch_flip_at = %hhd\n", 103 frame->touch_flip_at); 104 hid_dbg(hdev, "\t\t.bitmap_dial_byte = %u\n", 105 frame->bitmap_dial_byte); 106 hid_dbg(hdev, "\t\t.bitmap_second_dial_destination_byte = %u\n", 107 frame->bitmap_second_dial_destination_byte); 108 } 109 110 /** 111 * uclogic_params_hid_dbg() - Dump tablet interface parameters 112 * @hdev: The HID device the parameters describe. 113 * @params: The parameters to dump. 114 * 115 * Dump tablet interface parameters with hid_dbg(). 116 */ 117 void uclogic_params_hid_dbg(const struct hid_device *hdev, 118 const struct uclogic_params *params) 119 { 120 size_t i; 121 122 hid_dbg(hdev, ".invalid = %s\n", 123 params->invalid ? "true" : "false"); 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 pen_y_lm = get_unaligned_le16(str_desc + 4); 1127 frame_num_buttons = str_desc[6]; 1128 *frame_type = str_desc[7]; 1129 pen_pressure_lm = get_unaligned_le16(str_desc + 8); 1130 1131 resolution = get_unaligned_le16(str_desc + 10); 1132 if (resolution == 0) { 1133 pen_x_pm = 0; 1134 pen_y_pm = 0; 1135 } else { 1136 pen_x_pm = pen_x_lm * 1000 / resolution; 1137 pen_y_pm = pen_y_lm * 1000 / resolution; 1138 } 1139 1140 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = pen_x_lm; 1141 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = pen_x_pm; 1142 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = pen_y_lm; 1143 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = pen_y_pm; 1144 desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = pen_pressure_lm; 1145 desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = frame_num_buttons; 1146 1147 return 0; 1148 } 1149 1150 /** 1151 * uclogic_params_ugee_v2_init_frame_buttons() - initialize a UGEE v2 frame with 1152 * buttons. 1153 * @p: Parameters to fill in, cannot be NULL. 1154 * @desc_params: Device description params list. 1155 * @desc_params_size: Size of the description params list. 1156 * 1157 * Returns: 1158 * Zero, if successful. A negative errno code on error. 1159 */ 1160 static int uclogic_params_ugee_v2_init_frame_buttons(struct uclogic_params *p, 1161 const s32 *desc_params, 1162 size_t desc_params_size) 1163 { 1164 __u8 *rdesc_frame = NULL; 1165 int rc = 0; 1166 1167 if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM) 1168 return -EINVAL; 1169 1170 rdesc_frame = uclogic_rdesc_template_apply( 1171 uclogic_rdesc_ugee_v2_frame_btn_template_arr, 1172 uclogic_rdesc_ugee_v2_frame_btn_template_size, 1173 desc_params, UCLOGIC_RDESC_PH_ID_NUM); 1174 if (!rdesc_frame) 1175 return -ENOMEM; 1176 1177 rc = uclogic_params_frame_init_with_desc(&p->frame_list[0], 1178 rdesc_frame, 1179 uclogic_rdesc_ugee_v2_frame_btn_template_size, 1180 UCLOGIC_RDESC_V1_FRAME_ID); 1181 kfree(rdesc_frame); 1182 return rc; 1183 } 1184 1185 /** 1186 * uclogic_params_ugee_v2_init_frame_dial() - initialize a UGEE v2 frame with a 1187 * bitmap dial. 1188 * @p: Parameters to fill in, cannot be NULL. 1189 * @desc_params: Device description params list. 1190 * @desc_params_size: Size of the description params list. 1191 * 1192 * Returns: 1193 * Zero, if successful. A negative errno code on error. 1194 */ 1195 static int uclogic_params_ugee_v2_init_frame_dial(struct uclogic_params *p, 1196 const s32 *desc_params, 1197 size_t desc_params_size) 1198 { 1199 __u8 *rdesc_frame = NULL; 1200 int rc = 0; 1201 1202 if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM) 1203 return -EINVAL; 1204 1205 rdesc_frame = uclogic_rdesc_template_apply( 1206 uclogic_rdesc_ugee_v2_frame_dial_template_arr, 1207 uclogic_rdesc_ugee_v2_frame_dial_template_size, 1208 desc_params, UCLOGIC_RDESC_PH_ID_NUM); 1209 if (!rdesc_frame) 1210 return -ENOMEM; 1211 1212 rc = uclogic_params_frame_init_with_desc(&p->frame_list[0], 1213 rdesc_frame, 1214 uclogic_rdesc_ugee_v2_frame_dial_template_size, 1215 UCLOGIC_RDESC_V1_FRAME_ID); 1216 kfree(rdesc_frame); 1217 if (rc) 1218 return rc; 1219 1220 p->frame_list[0].bitmap_dial_byte = 7; 1221 return 0; 1222 } 1223 1224 /** 1225 * uclogic_params_ugee_v2_init_frame_mouse() - initialize a UGEE v2 frame with a 1226 * mouse. 1227 * @p: Parameters to fill in, cannot be NULL. 1228 * 1229 * Returns: 1230 * Zero, if successful. A negative errno code on error. 1231 */ 1232 static int uclogic_params_ugee_v2_init_frame_mouse(struct uclogic_params *p) 1233 { 1234 int rc = 0; 1235 1236 if (!p) 1237 return -EINVAL; 1238 1239 rc = uclogic_params_frame_init_with_desc(&p->frame_list[1], 1240 uclogic_rdesc_ugee_v2_frame_mouse_template_arr, 1241 uclogic_rdesc_ugee_v2_frame_mouse_template_size, 1242 UCLOGIC_RDESC_V1_FRAME_ID); 1243 return rc; 1244 } 1245 1246 /** 1247 * uclogic_params_ugee_v2_has_battery() - check whether a UGEE v2 device has 1248 * battery or not. 1249 * @hdev: The HID device of the tablet interface. 1250 * 1251 * Returns: 1252 * True if the device has battery, false otherwise. 1253 */ 1254 static bool uclogic_params_ugee_v2_has_battery(struct hid_device *hdev) 1255 { 1256 struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); 1257 1258 if (drvdata->quirks & UCLOGIC_BATTERY_QUIRK) 1259 return true; 1260 1261 /* The XP-PEN Deco LW vendor, product and version are identical to the 1262 * Deco L. The only difference reported by their firmware is the product 1263 * name. Add a quirk to support battery reporting on the wireless 1264 * version. 1265 */ 1266 if (hdev->vendor == USB_VENDOR_ID_UGEE && 1267 hdev->product == USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) { 1268 struct usb_device *udev = hid_to_usb_dev(hdev); 1269 1270 if (strstarts(udev->product, "Deco LW")) 1271 return true; 1272 } 1273 1274 return false; 1275 } 1276 1277 /** 1278 * uclogic_params_ugee_v2_init_battery() - initialize UGEE v2 battery reporting. 1279 * @hdev: The HID device of the tablet interface, cannot be NULL. 1280 * @p: Parameters to fill in, cannot be NULL. 1281 * 1282 * Returns: 1283 * Zero, if successful. A negative errno code on error. 1284 */ 1285 static int uclogic_params_ugee_v2_init_battery(struct hid_device *hdev, 1286 struct uclogic_params *p) 1287 { 1288 int rc = 0; 1289 1290 if (!hdev || !p) 1291 return -EINVAL; 1292 1293 /* Some tablets contain invalid characters in hdev->uniq, throwing a 1294 * "hwmon: '<name>' is not a valid name attribute, please fix" error. 1295 * Use the device vendor and product IDs instead. 1296 */ 1297 snprintf(hdev->uniq, sizeof(hdev->uniq), "%x-%x", hdev->vendor, 1298 hdev->product); 1299 1300 rc = uclogic_params_frame_init_with_desc(&p->frame_list[1], 1301 uclogic_rdesc_ugee_v2_battery_template_arr, 1302 uclogic_rdesc_ugee_v2_battery_template_size, 1303 UCLOGIC_RDESC_UGEE_V2_BATTERY_ID); 1304 if (rc) 1305 return rc; 1306 1307 p->frame_list[1].suffix = "Battery"; 1308 p->pen.subreport_list[1].value = 0xf2; 1309 p->pen.subreport_list[1].id = UCLOGIC_RDESC_UGEE_V2_BATTERY_ID; 1310 1311 return rc; 1312 } 1313 1314 /** 1315 * uclogic_params_ugee_v2_reconnect_work() - When a wireless tablet looses 1316 * connection to the USB dongle and reconnects, either because of its physical 1317 * distance or because it was switches off and on using the frame's switch, 1318 * uclogic_probe_interface() needs to be called again to enable the tablet. 1319 * 1320 * @work: The work that triggered this function. 1321 */ 1322 static void uclogic_params_ugee_v2_reconnect_work(struct work_struct *work) 1323 { 1324 struct uclogic_raw_event_hook *event_hook; 1325 1326 event_hook = container_of(work, struct uclogic_raw_event_hook, work); 1327 uclogic_probe_interface(event_hook->hdev, uclogic_ugee_v2_probe_arr, 1328 uclogic_ugee_v2_probe_size, 1329 uclogic_ugee_v2_probe_endpoint); 1330 } 1331 1332 /** 1333 * uclogic_params_ugee_v2_init_event_hooks() - initialize the list of events 1334 * to be hooked for UGEE v2 devices. 1335 * @hdev: The HID device of the tablet interface to initialize and get 1336 * parameters from. 1337 * @p: Parameters to fill in, cannot be NULL. 1338 * 1339 * Returns: 1340 * Zero, if successful. A negative errno code on error. 1341 */ 1342 static int uclogic_params_ugee_v2_init_event_hooks(struct hid_device *hdev, 1343 struct uclogic_params *p) 1344 { 1345 struct uclogic_raw_event_hook *event_hook; 1346 static const __u8 reconnect_event[] = { 1347 /* Event received on wireless tablet reconnection */ 1348 0x02, 0xF8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1349 }; 1350 1351 if (!p) 1352 return -EINVAL; 1353 1354 /* The reconnection event is only received if the tablet has battery */ 1355 if (!uclogic_params_ugee_v2_has_battery(hdev)) 1356 return 0; 1357 1358 p->event_hooks = kzalloc(sizeof(*p->event_hooks), GFP_KERNEL); 1359 if (!p->event_hooks) 1360 return -ENOMEM; 1361 1362 INIT_LIST_HEAD(&p->event_hooks->list); 1363 1364 event_hook = kzalloc(sizeof(*event_hook), GFP_KERNEL); 1365 if (!event_hook) 1366 return -ENOMEM; 1367 1368 INIT_WORK(&event_hook->work, uclogic_params_ugee_v2_reconnect_work); 1369 event_hook->hdev = hdev; 1370 event_hook->size = ARRAY_SIZE(reconnect_event); 1371 event_hook->event = kmemdup(reconnect_event, event_hook->size, GFP_KERNEL); 1372 if (!event_hook->event) 1373 return -ENOMEM; 1374 1375 list_add_tail(&event_hook->list, &p->event_hooks->list); 1376 1377 return 0; 1378 } 1379 1380 /** 1381 * uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by 1382 * discovering their parameters. 1383 * 1384 * These tables, internally designed as v2 to differentiate them from older 1385 * models, expect a payload of magic data in orther to be switched to the fully 1386 * functional mode and expose their parameters in a similar way to the 1387 * information present in uclogic_params_pen_init_v1() but with some 1388 * differences. 1389 * 1390 * @params: Parameters to fill in (to be cleaned with 1391 * uclogic_params_cleanup()). Not modified in case of error. 1392 * Cannot be NULL. 1393 * @hdev: The HID device of the tablet interface to initialize and get 1394 * parameters from. Cannot be NULL. 1395 * 1396 * Returns: 1397 * Zero, if successful. A negative errno code on error. 1398 */ 1399 static int uclogic_params_ugee_v2_init(struct uclogic_params *params, 1400 struct hid_device *hdev) 1401 { 1402 int rc = 0; 1403 struct uclogic_drvdata *drvdata; 1404 struct usb_interface *iface; 1405 __u8 bInterfaceNumber; 1406 const int str_desc_len = 12; 1407 __u8 *str_desc = NULL; 1408 __u8 *rdesc_pen = NULL; 1409 s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM]; 1410 enum uclogic_params_frame_type frame_type; 1411 /* The resulting parameters (noop) */ 1412 struct uclogic_params p = {0, }; 1413 1414 if (!params || !hdev) { 1415 rc = -EINVAL; 1416 goto cleanup; 1417 } 1418 1419 drvdata = hid_get_drvdata(hdev); 1420 iface = to_usb_interface(hdev->dev.parent); 1421 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; 1422 1423 if (bInterfaceNumber == 0) { 1424 rc = uclogic_params_ugee_v2_init_frame_mouse(&p); 1425 if (rc) 1426 goto cleanup; 1427 1428 goto output; 1429 } 1430 1431 if (bInterfaceNumber != 2) { 1432 uclogic_params_init_invalid(&p); 1433 goto output; 1434 } 1435 1436 /* 1437 * Initialize the interface by sending magic data. 1438 * The specific data was discovered by sniffing the Windows driver 1439 * traffic. 1440 */ 1441 rc = uclogic_probe_interface(hdev, uclogic_ugee_v2_probe_arr, 1442 uclogic_ugee_v2_probe_size, 1443 uclogic_ugee_v2_probe_endpoint); 1444 if (rc) { 1445 uclogic_params_init_invalid(&p); 1446 goto output; 1447 } 1448 1449 /* 1450 * Read the string descriptor containing pen and frame parameters. 1451 * The specific string descriptor and data were discovered by sniffing 1452 * the Windows driver traffic. 1453 */ 1454 rc = uclogic_params_get_str_desc(&str_desc, hdev, 100, str_desc_len); 1455 if (rc != str_desc_len) { 1456 hid_err(hdev, "failed retrieving pen and frame parameters: %d\n", rc); 1457 uclogic_params_init_invalid(&p); 1458 goto output; 1459 } 1460 1461 rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len, 1462 desc_params, 1463 ARRAY_SIZE(desc_params), 1464 &frame_type); 1465 if (rc) 1466 goto cleanup; 1467 1468 kfree(str_desc); 1469 str_desc = NULL; 1470 1471 /* Initialize the pen interface */ 1472 rdesc_pen = uclogic_rdesc_template_apply( 1473 uclogic_rdesc_ugee_v2_pen_template_arr, 1474 uclogic_rdesc_ugee_v2_pen_template_size, 1475 desc_params, ARRAY_SIZE(desc_params)); 1476 if (!rdesc_pen) { 1477 rc = -ENOMEM; 1478 goto cleanup; 1479 } 1480 1481 p.pen.desc_ptr = rdesc_pen; 1482 p.pen.desc_size = uclogic_rdesc_ugee_v2_pen_template_size; 1483 p.pen.id = 0x02; 1484 p.pen.subreport_list[0].value = 0xf0; 1485 p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID; 1486 1487 /* Initialize the frame interface */ 1488 if (drvdata->quirks & UCLOGIC_MOUSE_FRAME_QUIRK) 1489 frame_type = UCLOGIC_PARAMS_FRAME_MOUSE; 1490 1491 switch (frame_type) { 1492 case UCLOGIC_PARAMS_FRAME_DIAL: 1493 case UCLOGIC_PARAMS_FRAME_MOUSE: 1494 rc = uclogic_params_ugee_v2_init_frame_dial(&p, desc_params, 1495 ARRAY_SIZE(desc_params)); 1496 break; 1497 case UCLOGIC_PARAMS_FRAME_BUTTONS: 1498 default: 1499 rc = uclogic_params_ugee_v2_init_frame_buttons(&p, desc_params, 1500 ARRAY_SIZE(desc_params)); 1501 break; 1502 } 1503 1504 if (rc) 1505 goto cleanup; 1506 1507 /* Initialize the battery interface*/ 1508 if (uclogic_params_ugee_v2_has_battery(hdev)) { 1509 rc = uclogic_params_ugee_v2_init_battery(hdev, &p); 1510 if (rc) { 1511 hid_err(hdev, "error initializing battery: %d\n", rc); 1512 goto cleanup; 1513 } 1514 } 1515 1516 /* Create a list of raw events to be ignored */ 1517 rc = uclogic_params_ugee_v2_init_event_hooks(hdev, &p); 1518 if (rc) { 1519 hid_err(hdev, "error initializing event hook list: %d\n", rc); 1520 goto cleanup; 1521 } 1522 1523 output: 1524 /* Output parameters */ 1525 memcpy(params, &p, sizeof(*params)); 1526 memset(&p, 0, sizeof(p)); 1527 rc = 0; 1528 cleanup: 1529 kfree(str_desc); 1530 uclogic_params_cleanup(&p); 1531 return rc; 1532 } 1533 1534 /* 1535 * uclogic_params_init_ugee_xppen_pro_22r() - Initializes a UGEE XP-Pen Pro 22R tablet device. 1536 * 1537 * @hdev: The HID device of the tablet interface to initialize and get 1538 * parameters from. Cannot be NULL. 1539 * @params: Parameters to fill in (to be cleaned with 1540 * uclogic_params_cleanup()). Not modified in case of error. 1541 * Cannot be NULL. 1542 * 1543 * Returns: 1544 * Zero, if successful. A negative errno code on error. 1545 */ 1546 static int uclogic_params_init_ugee_xppen_pro_22r(struct uclogic_params *params, 1547 struct hid_device *hdev, 1548 const u8 rdesc_frame_arr[], 1549 const size_t rdesc_frame_size) 1550 { 1551 int rc = 0; 1552 struct usb_interface *iface; 1553 __u8 bInterfaceNumber; 1554 const int str_desc_len = 12; 1555 u8 *str_desc = NULL; 1556 __u8 *rdesc_pen = NULL; 1557 s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM]; 1558 enum uclogic_params_frame_type frame_type; 1559 /* The resulting parameters (noop) */ 1560 struct uclogic_params p = {0, }; 1561 1562 if (!hdev || !params) { 1563 rc = -EINVAL; 1564 goto cleanup; 1565 } 1566 1567 iface = to_usb_interface(hdev->dev.parent); 1568 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; 1569 1570 /* Ignore non-pen interfaces */ 1571 if (bInterfaceNumber != 2) { 1572 rc = -EINVAL; 1573 uclogic_params_init_invalid(&p); 1574 goto cleanup; 1575 } 1576 1577 /* 1578 * Initialize the interface by sending magic data. 1579 * This magic data is the same as other UGEE v2 tablets. 1580 */ 1581 rc = uclogic_probe_interface(hdev, 1582 uclogic_ugee_v2_probe_arr, 1583 uclogic_ugee_v2_probe_size, 1584 uclogic_ugee_v2_probe_endpoint); 1585 if (rc) { 1586 uclogic_params_init_invalid(&p); 1587 goto cleanup; 1588 } 1589 1590 /** 1591 * Read the string descriptor containing pen and frame parameters. 1592 * These are slightly different than typical UGEE v2 devices. 1593 */ 1594 rc = uclogic_params_get_str_desc(&str_desc, hdev, 100, str_desc_len); 1595 if (rc != str_desc_len) { 1596 rc = (rc < 0) ? rc : -EINVAL; 1597 hid_err(hdev, "failed retrieving pen and frame parameters: %d\n", rc); 1598 uclogic_params_init_invalid(&p); 1599 goto cleanup; 1600 } 1601 1602 rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len, 1603 desc_params, 1604 ARRAY_SIZE(desc_params), 1605 &frame_type); 1606 if (rc) 1607 goto cleanup; 1608 1609 // str_desc doesn't report the correct amount of buttons, so manually fix it 1610 desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 20; 1611 1612 kfree(str_desc); 1613 str_desc = NULL; 1614 1615 /* Initialize the pen interface */ 1616 rdesc_pen = uclogic_rdesc_template_apply( 1617 uclogic_rdesc_ugee_v2_pen_template_arr, 1618 uclogic_rdesc_ugee_v2_pen_template_size, 1619 desc_params, ARRAY_SIZE(desc_params)); 1620 if (!rdesc_pen) { 1621 rc = -ENOMEM; 1622 goto cleanup; 1623 } 1624 1625 p.pen.desc_ptr = rdesc_pen; 1626 p.pen.desc_size = uclogic_rdesc_ugee_v2_pen_template_size; 1627 p.pen.id = 0x02; 1628 p.pen.subreport_list[0].value = 0xf0; 1629 p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID; 1630 1631 /* Initialize the frame interface */ 1632 rc = uclogic_params_frame_init_with_desc( 1633 &p.frame_list[0], 1634 rdesc_frame_arr, 1635 rdesc_frame_size, 1636 UCLOGIC_RDESC_V1_FRAME_ID); 1637 if (rc < 0) { 1638 hid_err(hdev, "initializing frame params failed: %d\n", rc); 1639 goto cleanup; 1640 } 1641 1642 p.frame_list[0].bitmap_dial_byte = 7; 1643 p.frame_list[0].bitmap_second_dial_destination_byte = 8; 1644 1645 /* Output parameters */ 1646 memcpy(params, &p, sizeof(*params)); 1647 memset(&p, 0, sizeof(p)); 1648 cleanup: 1649 kfree(str_desc); 1650 uclogic_params_cleanup(&p); 1651 return rc; 1652 } 1653 1654 /** 1655 * uclogic_params_init() - initialize a tablet interface and discover its 1656 * parameters. 1657 * 1658 * @params: Parameters to fill in (to be cleaned with 1659 * uclogic_params_cleanup()). Not modified in case of error. 1660 * Cannot be NULL. 1661 * @hdev: The HID device of the tablet interface to initialize and get 1662 * parameters from. Cannot be NULL. Must be using the USB low-level 1663 * driver, i.e. be an actual USB tablet. 1664 * 1665 * Returns: 1666 * Zero, if successful. A negative errno code on error. 1667 */ 1668 int uclogic_params_init(struct uclogic_params *params, 1669 struct hid_device *hdev) 1670 { 1671 int rc; 1672 struct usb_device *udev; 1673 __u8 bNumInterfaces; 1674 struct usb_interface *iface; 1675 __u8 bInterfaceNumber; 1676 bool found; 1677 /* The resulting parameters (noop) */ 1678 struct uclogic_params p = {0, }; 1679 1680 /* Check arguments */ 1681 if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) { 1682 rc = -EINVAL; 1683 goto cleanup; 1684 } 1685 1686 udev = hid_to_usb_dev(hdev); 1687 bNumInterfaces = udev->config->desc.bNumInterfaces; 1688 iface = to_usb_interface(hdev->dev.parent); 1689 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; 1690 1691 /* 1692 * Set replacement report descriptor if the original matches the 1693 * specified size. Otherwise keep interface unchanged. 1694 */ 1695 #define WITH_OPT_DESC(_orig_desc_token, _new_desc_token) \ 1696 uclogic_params_init_with_opt_desc( \ 1697 &p, hdev, \ 1698 UCLOGIC_RDESC_##_orig_desc_token##_SIZE, \ 1699 uclogic_rdesc_##_new_desc_token##_arr, \ 1700 uclogic_rdesc_##_new_desc_token##_size) 1701 1702 #define VID_PID(_vid, _pid) \ 1703 (((__u32)(_vid) << 16) | ((__u32)(_pid) & U16_MAX)) 1704 1705 /* 1706 * Handle specific interfaces for specific tablets. 1707 * 1708 * Observe the following logic: 1709 * 1710 * If the interface is recognized as producing certain useful input: 1711 * Mark interface as valid. 1712 * Output interface parameters. 1713 * Else, if the interface is recognized as *not* producing any useful 1714 * input: 1715 * Mark interface as invalid. 1716 * Else: 1717 * Mark interface as valid. 1718 * Output noop parameters. 1719 * 1720 * Rule of thumb: it is better to disable a broken interface than let 1721 * it spew garbage input. 1722 */ 1723 1724 switch (VID_PID(hdev->vendor, hdev->product)) { 1725 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1726 USB_DEVICE_ID_UCLOGIC_TABLET_PF1209): 1727 rc = WITH_OPT_DESC(PF1209_ORIG, pf1209_fixed); 1728 if (rc != 0) 1729 goto cleanup; 1730 break; 1731 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1732 USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U): 1733 rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp4030u_fixed); 1734 if (rc != 0) 1735 goto cleanup; 1736 break; 1737 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1738 USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U): 1739 if (hdev->dev_rsize == UCLOGIC_RDESC_WP5540U_V2_ORIG_SIZE) { 1740 if (bInterfaceNumber == 0) { 1741 /* Try to probe v1 pen parameters */ 1742 rc = uclogic_params_pen_init_v1(&p.pen, 1743 &found, hdev); 1744 if (rc != 0) { 1745 hid_err(hdev, 1746 "pen probing failed: %d\n", 1747 rc); 1748 goto cleanup; 1749 } 1750 if (!found) { 1751 hid_warn(hdev, 1752 "pen parameters not found"); 1753 } 1754 } else { 1755 uclogic_params_init_invalid(&p); 1756 } 1757 } else { 1758 rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp5540u_fixed); 1759 if (rc != 0) 1760 goto cleanup; 1761 } 1762 break; 1763 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1764 USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U): 1765 rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp8060u_fixed); 1766 if (rc != 0) 1767 goto cleanup; 1768 break; 1769 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1770 USB_DEVICE_ID_UCLOGIC_TABLET_WP1062): 1771 rc = WITH_OPT_DESC(WP1062_ORIG, wp1062_fixed); 1772 if (rc != 0) 1773 goto cleanup; 1774 break; 1775 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1776 USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850): 1777 switch (bInterfaceNumber) { 1778 case 0: 1779 rc = WITH_OPT_DESC(TWHL850_ORIG0, twhl850_fixed0); 1780 if (rc != 0) 1781 goto cleanup; 1782 break; 1783 case 1: 1784 rc = WITH_OPT_DESC(TWHL850_ORIG1, twhl850_fixed1); 1785 if (rc != 0) 1786 goto cleanup; 1787 break; 1788 case 2: 1789 rc = WITH_OPT_DESC(TWHL850_ORIG2, twhl850_fixed2); 1790 if (rc != 0) 1791 goto cleanup; 1792 break; 1793 } 1794 break; 1795 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1796 USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60): 1797 /* 1798 * If it is not a three-interface version, which is known to 1799 * respond to initialization. 1800 */ 1801 if (bNumInterfaces != 3) { 1802 switch (bInterfaceNumber) { 1803 case 0: 1804 rc = WITH_OPT_DESC(TWHA60_ORIG0, 1805 twha60_fixed0); 1806 if (rc != 0) 1807 goto cleanup; 1808 break; 1809 case 1: 1810 rc = WITH_OPT_DESC(TWHA60_ORIG1, 1811 twha60_fixed1); 1812 if (rc != 0) 1813 goto cleanup; 1814 break; 1815 } 1816 break; 1817 } 1818 fallthrough; 1819 case VID_PID(USB_VENDOR_ID_HUION, 1820 USB_DEVICE_ID_HUION_TABLET): 1821 case VID_PID(USB_VENDOR_ID_HUION, 1822 USB_DEVICE_ID_HUION_TABLET2): 1823 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1824 USB_DEVICE_ID_HUION_TABLET): 1825 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1826 USB_DEVICE_ID_YIYNOVA_TABLET): 1827 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1828 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_81): 1829 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1830 USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3): 1831 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1832 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_45): 1833 case VID_PID(USB_VENDOR_ID_UCLOGIC, 1834 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_47): 1835 rc = uclogic_params_huion_init(&p, hdev); 1836 if (rc != 0) 1837 goto cleanup; 1838 break; 1839 case VID_PID(USB_VENDOR_ID_UGTIZER, 1840 USB_DEVICE_ID_UGTIZER_TABLET_GP0610): 1841 case VID_PID(USB_VENDOR_ID_UGTIZER, 1842 USB_DEVICE_ID_UGTIZER_TABLET_GT5040): 1843 case VID_PID(USB_VENDOR_ID_UGEE, 1844 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540): 1845 case VID_PID(USB_VENDOR_ID_UGEE, 1846 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640): 1847 case VID_PID(USB_VENDOR_ID_UGEE, 1848 USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06): 1849 case VID_PID(USB_VENDOR_ID_UGEE, 1850 USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720): 1851 /* If this is the pen interface */ 1852 if (bInterfaceNumber == 1) { 1853 /* Probe v1 pen parameters */ 1854 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev); 1855 if (rc != 0) { 1856 hid_err(hdev, "pen probing failed: %d\n", rc); 1857 goto cleanup; 1858 } 1859 if (!found) { 1860 hid_warn(hdev, "pen parameters not found"); 1861 uclogic_params_init_invalid(&p); 1862 } 1863 } else { 1864 uclogic_params_init_invalid(&p); 1865 } 1866 break; 1867 case VID_PID(USB_VENDOR_ID_UGEE, 1868 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01): 1869 /* If this is the pen and frame interface */ 1870 if (bInterfaceNumber == 1) { 1871 /* Probe v1 pen parameters */ 1872 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev); 1873 if (rc != 0) { 1874 hid_err(hdev, "pen probing failed: %d\n", rc); 1875 goto cleanup; 1876 } 1877 /* Initialize frame parameters */ 1878 rc = uclogic_params_frame_init_with_desc( 1879 &p.frame_list[0], 1880 uclogic_rdesc_xppen_deco01_frame_arr, 1881 uclogic_rdesc_xppen_deco01_frame_size, 1882 0); 1883 if (rc != 0) 1884 goto cleanup; 1885 } else { 1886 uclogic_params_init_invalid(&p); 1887 } 1888 break; 1889 case VID_PID(USB_VENDOR_ID_UGEE, 1890 USB_DEVICE_ID_UGEE_PARBLO_A610_PRO): 1891 case VID_PID(USB_VENDOR_ID_UGEE, 1892 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01_V2): 1893 case VID_PID(USB_VENDOR_ID_UGEE, 1894 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L): 1895 case VID_PID(USB_VENDOR_ID_UGEE, 1896 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_MW): 1897 case VID_PID(USB_VENDOR_ID_UGEE, 1898 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S): 1899 case VID_PID(USB_VENDOR_ID_UGEE, 1900 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW): 1901 rc = uclogic_params_ugee_v2_init(&p, hdev); 1902 if (rc != 0) 1903 goto cleanup; 1904 break; 1905 case VID_PID(USB_VENDOR_ID_TRUST, 1906 USB_DEVICE_ID_TRUST_PANORA_TABLET): 1907 case VID_PID(USB_VENDOR_ID_UGEE, 1908 USB_DEVICE_ID_UGEE_TABLET_G5): 1909 /* Ignore non-pen interfaces */ 1910 if (bInterfaceNumber != 1) { 1911 uclogic_params_init_invalid(&p); 1912 break; 1913 } 1914 1915 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev); 1916 if (rc != 0) { 1917 hid_err(hdev, "pen probing failed: %d\n", rc); 1918 goto cleanup; 1919 } else if (found) { 1920 rc = uclogic_params_frame_init_with_desc( 1921 &p.frame_list[0], 1922 uclogic_rdesc_ugee_g5_frame_arr, 1923 uclogic_rdesc_ugee_g5_frame_size, 1924 UCLOGIC_RDESC_UGEE_G5_FRAME_ID); 1925 if (rc != 0) { 1926 hid_err(hdev, 1927 "failed creating frame parameters: %d\n", 1928 rc); 1929 goto cleanup; 1930 } 1931 p.frame_list[0].re_lsb = 1932 UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB; 1933 p.frame_list[0].dev_id_byte = 1934 UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE; 1935 } else { 1936 hid_warn(hdev, "pen parameters not found"); 1937 uclogic_params_init_invalid(&p); 1938 } 1939 1940 break; 1941 case VID_PID(USB_VENDOR_ID_UGEE, 1942 USB_DEVICE_ID_UGEE_TABLET_EX07S): 1943 /* Ignore non-pen interfaces */ 1944 if (bInterfaceNumber != 1) { 1945 uclogic_params_init_invalid(&p); 1946 break; 1947 } 1948 1949 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev); 1950 if (rc != 0) { 1951 hid_err(hdev, "pen probing failed: %d\n", rc); 1952 goto cleanup; 1953 } else if (found) { 1954 rc = uclogic_params_frame_init_with_desc( 1955 &p.frame_list[0], 1956 uclogic_rdesc_ugee_ex07_frame_arr, 1957 uclogic_rdesc_ugee_ex07_frame_size, 1958 0); 1959 if (rc != 0) { 1960 hid_err(hdev, 1961 "failed creating frame parameters: %d\n", 1962 rc); 1963 goto cleanup; 1964 } 1965 } else { 1966 hid_warn(hdev, "pen parameters not found"); 1967 uclogic_params_init_invalid(&p); 1968 } 1969 1970 break; 1971 case VID_PID(USB_VENDOR_ID_UGEE, 1972 USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO): 1973 rc = uclogic_params_init_ugee_xppen_pro_22r(&p, 1974 hdev, 1975 uclogic_rdesc_xppen_artist_22r_pro_frame_arr, 1976 uclogic_rdesc_xppen_artist_22r_pro_frame_size); 1977 if (rc != 0) 1978 goto cleanup; 1979 1980 break; 1981 } 1982 1983 #undef VID_PID 1984 #undef WITH_OPT_DESC 1985 1986 /* Output parameters */ 1987 memcpy(params, &p, sizeof(*params)); 1988 memset(&p, 0, sizeof(p)); 1989 rc = 0; 1990 cleanup: 1991 uclogic_params_cleanup(&p); 1992 return rc; 1993 } 1994 1995 #ifdef CONFIG_HID_KUNIT_TEST 1996 #include "hid-uclogic-params-test.c" 1997 #endif 1998