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