1 // SPDX-License-Identifier: GPL-2.0+
3 * HID driver for UC-Logic devices not fully compliant with HID standard
4 * - tablet initialization and parameter retrieval
6 * Copyright (c) 2018 Nikolai Kondrashov
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)
16 #include "hid-uclogic-params.h"
17 #include "hid-uclogic-rdesc.h"
18 #include "usbhid/usbhid.h"
20 #include <linux/ctype.h>
21 #include <asm/unaligned.h>
24 * uclogic_params_pen_inrange_to_str() - Convert a pen in-range reporting type
26 * @inrange: The in-range reporting type to convert.
29 * * The string representing the type, or
30 * * %NULL if the type is unknown.
32 static const char *uclogic_params_pen_inrange_to_str(
33 enum uclogic_params_pen_inrange inrange)
36 case UCLOGIC_PARAMS_PEN_INRANGE_NORMAL:
38 case UCLOGIC_PARAMS_PEN_INRANGE_INVERTED:
40 case UCLOGIC_PARAMS_PEN_INRANGE_NONE:
48 * uclogic_params_pen_hid_dbg() - Dump tablet interface pen parameters
49 * @hdev: The HID device the pen parameters describe.
50 * @pen: The pen parameters to dump.
52 * Dump tablet interface pen parameters with hid_dbg(). The dump is indented
55 static void uclogic_params_pen_hid_dbg(const struct hid_device *hdev,
56 const struct uclogic_params_pen *pen)
60 hid_dbg(hdev, "\t.usage_invalid = %s\n",
61 (pen->usage_invalid ? "true" : "false"));
62 hid_dbg(hdev, "\t.desc_ptr = %p\n", pen->desc_ptr);
63 hid_dbg(hdev, "\t.desc_size = %u\n", pen->desc_size);
64 hid_dbg(hdev, "\t.id = %u\n", pen->id);
65 hid_dbg(hdev, "\t.subreport_list = {\n");
66 for (i = 0; i < ARRAY_SIZE(pen->subreport_list); i++) {
67 hid_dbg(hdev, "\t\t{0x%02hhx, %hhu}%s\n",
68 pen->subreport_list[i].value,
69 pen->subreport_list[i].id,
70 i < (ARRAY_SIZE(pen->subreport_list) - 1) ? "," : "");
72 hid_dbg(hdev, "\t}\n");
73 hid_dbg(hdev, "\t.inrange = %s\n",
74 uclogic_params_pen_inrange_to_str(pen->inrange));
75 hid_dbg(hdev, "\t.fragmented_hires = %s\n",
76 (pen->fragmented_hires ? "true" : "false"));
77 hid_dbg(hdev, "\t.tilt_y_flipped = %s\n",
78 (pen->tilt_y_flipped ? "true" : "false"));
82 * uclogic_params_frame_hid_dbg() - Dump tablet interface frame parameters
83 * @hdev: The HID device the pen parameters describe.
84 * @frame: The frame parameters to dump.
86 * Dump tablet interface frame parameters with hid_dbg(). The dump is
87 * indented with two tabs.
89 static void uclogic_params_frame_hid_dbg(
90 const struct hid_device *hdev,
91 const struct uclogic_params_frame *frame)
93 hid_dbg(hdev, "\t\t.desc_ptr = %p\n", frame->desc_ptr);
94 hid_dbg(hdev, "\t\t.desc_size = %u\n", frame->desc_size);
95 hid_dbg(hdev, "\t\t.id = %u\n", frame->id);
96 hid_dbg(hdev, "\t\t.suffix = %s\n", frame->suffix);
97 hid_dbg(hdev, "\t\t.re_lsb = %u\n", frame->re_lsb);
98 hid_dbg(hdev, "\t\t.dev_id_byte = %u\n", frame->dev_id_byte);
99 hid_dbg(hdev, "\t\t.touch_byte = %u\n", frame->touch_byte);
100 hid_dbg(hdev, "\t\t.touch_max = %hhd\n", frame->touch_max);
101 hid_dbg(hdev, "\t\t.touch_flip_at = %hhd\n",
102 frame->touch_flip_at);
103 hid_dbg(hdev, "\t\t.bitmap_dial_byte = %u\n",
104 frame->bitmap_dial_byte);
108 * uclogic_params_hid_dbg() - Dump tablet interface parameters
109 * @hdev: The HID device the parameters describe.
110 * @params: The parameters to dump.
112 * Dump tablet interface parameters with hid_dbg().
114 void uclogic_params_hid_dbg(const struct hid_device *hdev,
115 const struct uclogic_params *params)
119 hid_dbg(hdev, ".invalid = %s\n",
120 params->invalid ? "true" : "false");
121 hid_dbg(hdev, ".desc_ptr = %p\n", params->desc_ptr);
122 hid_dbg(hdev, ".desc_size = %u\n", params->desc_size);
123 hid_dbg(hdev, ".pen = {\n");
124 uclogic_params_pen_hid_dbg(hdev, ¶ms->pen);
125 hid_dbg(hdev, "\t}\n");
126 hid_dbg(hdev, ".frame_list = {\n");
127 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
128 hid_dbg(hdev, "\t{\n");
129 uclogic_params_frame_hid_dbg(hdev, ¶ms->frame_list[i]);
130 hid_dbg(hdev, "\t}%s\n",
131 i < (ARRAY_SIZE(params->frame_list) - 1) ? "," : "");
133 hid_dbg(hdev, "}\n");
137 * uclogic_params_get_str_desc - retrieve a string descriptor from a HID
138 * device interface, putting it into a kmalloc-allocated buffer as is, without
139 * character encoding conversion.
141 * @pbuf: Location for the kmalloc-allocated buffer pointer containing
142 * the retrieved descriptor. Not modified in case of error.
143 * Can be NULL to have retrieved descriptor discarded.
144 * @hdev: The HID device of the tablet interface to retrieve the string
145 * descriptor from. Cannot be NULL.
146 * @idx: Index of the string descriptor to request from the device.
147 * @len: Length of the buffer to allocate and the data to retrieve.
150 * number of bytes retrieved (<= len),
151 * -EPIPE, if the descriptor was not found, or
152 * another negative errno code in case of other error.
154 static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev,
155 __u8 idx, size_t len)
158 struct usb_device *udev;
161 /* Check arguments */
167 udev = hid_to_usb_dev(hdev);
169 buf = kmalloc(len, GFP_KERNEL);
175 rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
176 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
177 (USB_DT_STRING << 8) + idx,
179 USB_CTRL_GET_TIMEOUT);
181 hid_dbg(hdev, "string descriptor #%hhu not found\n", idx);
185 "failed retrieving string descriptor #%u: %d\n",
201 * uclogic_params_pen_cleanup - free resources used by struct
202 * uclogic_params_pen (tablet interface's pen input parameters).
203 * Can be called repeatedly.
205 * @pen: Pen input parameters to cleanup. Cannot be NULL.
207 static void uclogic_params_pen_cleanup(struct uclogic_params_pen *pen)
209 kfree(pen->desc_ptr);
210 memset(pen, 0, sizeof(*pen));
214 * uclogic_params_pen_init_v1() - initialize tablet interface pen
215 * input and retrieve its parameters from the device, using v1 protocol.
217 * @pen: Pointer to the pen parameters to initialize (to be
218 * cleaned up with uclogic_params_pen_cleanup()). Not modified in
219 * case of error, or if parameters are not found. Cannot be NULL.
220 * @pfound: Location for a flag which is set to true if the parameters
221 * were found, and to false if not (e.g. device was
222 * incompatible). Not modified in case of error. Cannot be NULL.
223 * @hdev: The HID device of the tablet interface to initialize and get
224 * parameters from. Cannot be NULL.
227 * Zero, if successful. A negative errno code on error.
229 static int uclogic_params_pen_init_v1(struct uclogic_params_pen *pen,
231 struct hid_device *hdev)
235 /* Buffer for (part of) the string descriptor */
237 /* Minimum descriptor length required, maximum seen so far is 18 */
240 /* Pen report descriptor template parameters */
241 s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
242 __u8 *desc_ptr = NULL;
244 /* Check arguments */
245 if (pen == NULL || pfound == NULL || hdev == NULL) {
251 * Read string descriptor containing pen input parameters.
252 * The specific string descriptor and data were discovered by sniffing
253 * the Windows driver traffic.
254 * NOTE: This enables fully-functional tablet mode.
256 rc = uclogic_params_get_str_desc(&buf, hdev, 100, len);
259 "string descriptor with pen parameters not found, assuming not compatible\n");
262 hid_err(hdev, "failed retrieving pen parameters: %d\n", rc);
264 } else if (rc != len) {
266 "string descriptor with pen parameters has invalid length (got %d, expected %d), assuming not compatible\n",
272 * Fill report descriptor parameters from the string descriptor
274 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] =
275 get_unaligned_le16(buf + 2);
276 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] =
277 get_unaligned_le16(buf + 4);
278 desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] =
279 get_unaligned_le16(buf + 8);
280 resolution = get_unaligned_le16(buf + 10);
281 if (resolution == 0) {
282 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0;
283 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0;
285 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] =
286 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 /
288 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] =
289 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
296 * Generate pen report descriptor
298 desc_ptr = uclogic_rdesc_template_apply(
299 uclogic_rdesc_v1_pen_template_arr,
300 uclogic_rdesc_v1_pen_template_size,
301 desc_params, ARRAY_SIZE(desc_params));
302 if (desc_ptr == NULL) {
308 * Fill-in the parameters
310 memset(pen, 0, sizeof(*pen));
311 pen->desc_ptr = desc_ptr;
313 pen->desc_size = uclogic_rdesc_v1_pen_template_size;
314 pen->id = UCLOGIC_RDESC_V1_PEN_ID;
315 pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_INVERTED;
327 * uclogic_params_get_le24() - get a 24-bit little-endian number from a
330 * @p: The pointer to the number buffer.
333 * The retrieved number
335 static s32 uclogic_params_get_le24(const void *p)
338 return b[0] | (b[1] << 8UL) | (b[2] << 16UL);
342 * uclogic_params_pen_init_v2() - initialize tablet interface pen
343 * input and retrieve its parameters from the device, using v2 protocol.
345 * @pen: Pointer to the pen parameters to initialize (to be
346 * cleaned up with uclogic_params_pen_cleanup()). Not
347 * modified in case of error, or if parameters are not
348 * found. Cannot be NULL.
349 * @pfound: Location for a flag which is set to true if the
350 * parameters were found, and to false if not (e.g.
351 * device was incompatible). Not modified in case of
352 * error. Cannot be NULL.
353 * @pparams_ptr: Location for a kmalloc'ed pointer to the retrieved raw
354 * parameters, which could be used to identify the tablet
355 * to some extent. Should be freed with kfree after use.
356 * NULL, if not needed. Not modified in case of error.
357 * Only set if *pfound is set to true.
358 * @pparams_len: Location for the length of the retrieved raw
359 * parameters. NULL, if not needed. Not modified in case
360 * of error. Only set if *pfound is set to true.
361 * @hdev: The HID device of the tablet interface to initialize
362 * and get parameters from. Cannot be NULL.
365 * Zero, if successful. A negative errno code on error.
367 static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
371 struct hid_device *hdev)
375 /* Buffer for (part of) the parameter string descriptor */
377 /* Parameter string descriptor required length */
378 const int params_len_min = 18;
379 /* Parameter string descriptor accepted length */
380 const int params_len_max = 32;
381 /* Parameter string descriptor received length */
385 /* Pen report descriptor template parameters */
386 s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
387 __u8 *desc_ptr = NULL;
389 /* Check arguments */
390 if (pen == NULL || pfound == NULL || hdev == NULL) {
396 * Read string descriptor containing pen input parameters.
397 * The specific string descriptor and data were discovered by sniffing
398 * the Windows driver traffic.
399 * NOTE: This enables fully-functional tablet mode.
401 rc = uclogic_params_get_str_desc(&buf, hdev, 200, params_len_max);
404 "string descriptor with pen parameters not found, assuming not compatible\n");
407 hid_err(hdev, "failed retrieving pen parameters: %d\n", rc);
409 } else if (rc < params_len_min) {
411 "string descriptor with pen parameters is too short (got %d, expected at least %d), assuming not compatible\n",
419 * Check it's not just a catch-all UTF-16LE-encoded ASCII
420 * string (such as the model name) some tablets put into all
421 * unknown string descriptors.
425 (buf[i] >= 0x20 && buf[i] < 0x7f && buf[i + 1] == 0);
427 if (i >= params_len) {
429 "string descriptor with pen parameters seems to contain only text, assuming not compatible\n");
434 * Fill report descriptor parameters from the string descriptor
436 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] =
437 uclogic_params_get_le24(buf + 2);
438 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] =
439 uclogic_params_get_le24(buf + 5);
440 desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] =
441 get_unaligned_le16(buf + 8);
442 resolution = get_unaligned_le16(buf + 10);
443 if (resolution == 0) {
444 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0;
445 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0;
447 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] =
448 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 /
450 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] =
451 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
456 * Generate pen report descriptor
458 desc_ptr = uclogic_rdesc_template_apply(
459 uclogic_rdesc_v2_pen_template_arr,
460 uclogic_rdesc_v2_pen_template_size,
461 desc_params, ARRAY_SIZE(desc_params));
462 if (desc_ptr == NULL) {
468 * Fill-in the parameters
470 memset(pen, 0, sizeof(*pen));
471 pen->desc_ptr = desc_ptr;
473 pen->desc_size = uclogic_rdesc_v2_pen_template_size;
474 pen->id = UCLOGIC_RDESC_V2_PEN_ID;
475 pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_NONE;
476 pen->fragmented_hires = true;
477 pen->tilt_y_flipped = true;
479 if (pparams_ptr != NULL) {
483 if (pparams_len != NULL)
484 *pparams_len = params_len;
496 * uclogic_params_frame_cleanup - free resources used by struct
497 * uclogic_params_frame (tablet interface's frame controls input parameters).
498 * Can be called repeatedly.
500 * @frame: Frame controls input parameters to cleanup. Cannot be NULL.
502 static void uclogic_params_frame_cleanup(struct uclogic_params_frame *frame)
504 kfree(frame->desc_ptr);
505 memset(frame, 0, sizeof(*frame));
509 * uclogic_params_frame_init_with_desc() - initialize tablet's frame control
510 * parameters with a static report descriptor.
512 * @frame: Pointer to the frame parameters to initialize (to be cleaned
513 * up with uclogic_params_frame_cleanup()). Not modified in case
514 * of error. Cannot be NULL.
515 * @desc_ptr: Report descriptor pointer. Can be NULL, if desc_size is zero.
516 * @desc_size: Report descriptor size.
517 * @id: Report ID used for frame reports, if they should be tweaked,
521 * Zero, if successful. A negative errno code on error.
523 static int uclogic_params_frame_init_with_desc(
524 struct uclogic_params_frame *frame,
525 const __u8 *desc_ptr,
531 if (frame == NULL || (desc_ptr == NULL && desc_size != 0))
534 copy_desc_ptr = kmemdup(desc_ptr, desc_size, GFP_KERNEL);
535 if (copy_desc_ptr == NULL)
538 memset(frame, 0, sizeof(*frame));
539 frame->desc_ptr = copy_desc_ptr;
540 frame->desc_size = desc_size;
546 * uclogic_params_frame_init_v1() - initialize v1 tablet interface frame
549 * @frame: Pointer to the frame parameters to initialize (to be cleaned
550 * up with uclogic_params_frame_cleanup()). Not modified in case
551 * of error, or if parameters are not found. Cannot be NULL.
552 * @pfound: Location for a flag which is set to true if the parameters
553 * were found, and to false if not (e.g. device was
554 * incompatible). Not modified in case of error. Cannot be NULL.
555 * @hdev: The HID device of the tablet interface to initialize and get
556 * parameters from. Cannot be NULL.
559 * Zero, if successful. A negative errno code on error.
561 static int uclogic_params_frame_init_v1(struct uclogic_params_frame *frame,
563 struct hid_device *hdev)
567 struct usb_device *usb_dev;
568 char *str_buf = NULL;
569 const size_t str_len = 16;
571 /* Check arguments */
572 if (frame == NULL || pfound == NULL || hdev == NULL) {
577 usb_dev = hid_to_usb_dev(hdev);
580 * Enable generic button mode
582 str_buf = kzalloc(str_len, GFP_KERNEL);
583 if (str_buf == NULL) {
588 rc = usb_string(usb_dev, 123, str_buf, str_len);
591 "generic button -enabling string descriptor not found\n");
594 } else if (strncmp(str_buf, "HK On", rc) != 0) {
596 "invalid response to enabling generic buttons: \"%s\"\n",
599 hid_dbg(hdev, "generic buttons enabled\n");
600 rc = uclogic_params_frame_init_with_desc(
602 uclogic_rdesc_v1_frame_arr,
603 uclogic_rdesc_v1_frame_size,
604 UCLOGIC_RDESC_V1_FRAME_ID);
618 * uclogic_params_cleanup - free resources used by struct uclogic_params
619 * (tablet interface's parameters).
620 * Can be called repeatedly.
622 * @params: Input parameters to cleanup. Cannot be NULL.
624 void uclogic_params_cleanup(struct uclogic_params *params)
626 if (!params->invalid) {
628 kfree(params->desc_ptr);
629 uclogic_params_pen_cleanup(¶ms->pen);
630 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++)
631 uclogic_params_frame_cleanup(¶ms->frame_list[i]);
633 memset(params, 0, sizeof(*params));
638 * uclogic_params_get_desc() - Get a replacement report descriptor for a
639 * tablet's interface.
641 * @params: The parameters of a tablet interface to get report
642 * descriptor for. Cannot be NULL.
643 * @pdesc: Location for the resulting, kmalloc-allocated report
644 * descriptor pointer, or for NULL, if there's no replacement
645 * report descriptor. Not modified in case of error. Cannot be
647 * @psize: Location for the resulting report descriptor size, not set if
648 * there's no replacement report descriptor. Not modified in case
649 * of error. Cannot be NULL.
652 * Zero, if successful.
653 * -EINVAL, if invalid arguments are supplied.
654 * -ENOMEM, if failed to allocate memory.
656 int uclogic_params_get_desc(const struct uclogic_params *params,
661 bool present = false;
662 unsigned int size = 0;
666 /* Check arguments */
667 if (params == NULL || pdesc == NULL || psize == NULL)
670 /* Concatenate descriptors */
671 #define ADD_DESC(_desc_ptr, _desc_size) \
673 unsigned int new_size; \
675 if ((_desc_ptr) == NULL) { \
678 new_size = size + (_desc_size); \
679 new_desc = krealloc(desc, new_size, GFP_KERNEL); \
680 if (new_desc == NULL) { \
683 memcpy(new_desc + size, (_desc_ptr), (_desc_size)); \
689 ADD_DESC(params->desc_ptr, params->desc_size);
690 ADD_DESC(params->pen.desc_ptr, params->pen.desc_size);
691 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
692 ADD_DESC(params->frame_list[i].desc_ptr,
693 params->frame_list[i].desc_size);
710 * uclogic_params_init_invalid() - initialize tablet interface parameters,
711 * specifying the interface is invalid.
713 * @params: Parameters to initialize (to be cleaned with
714 * uclogic_params_cleanup()). Cannot be NULL.
716 static void uclogic_params_init_invalid(struct uclogic_params *params)
718 params->invalid = true;
722 * uclogic_params_init_with_opt_desc() - initialize tablet interface
723 * parameters with an optional replacement report descriptor. Only modify
724 * report descriptor, if the original report descriptor matches the expected
727 * @params: Parameters to initialize (to be cleaned with
728 * uclogic_params_cleanup()). Not modified in case of
729 * error. Cannot be NULL.
730 * @hdev: The HID device of the tablet interface create the
731 * parameters for. Cannot be NULL.
732 * @orig_desc_size: Expected size of the original report descriptor to
734 * @desc_ptr: Pointer to the replacement report descriptor.
735 * Can be NULL, if desc_size is zero.
736 * @desc_size: Size of the replacement report descriptor.
739 * Zero, if successful. -EINVAL if an invalid argument was passed.
740 * -ENOMEM, if failed to allocate memory.
742 static int uclogic_params_init_with_opt_desc(struct uclogic_params *params,
743 struct hid_device *hdev,
744 unsigned int orig_desc_size,
746 unsigned int desc_size)
748 __u8 *desc_copy_ptr = NULL;
749 unsigned int desc_copy_size;
752 /* Check arguments */
753 if (params == NULL || hdev == NULL ||
754 (desc_ptr == NULL && desc_size != 0)) {
759 /* Replace report descriptor, if it matches */
760 if (hdev->dev_rsize == orig_desc_size) {
762 "device report descriptor matches the expected size, replacing\n");
763 desc_copy_ptr = kmemdup(desc_ptr, desc_size, GFP_KERNEL);
764 if (desc_copy_ptr == NULL) {
768 desc_copy_size = desc_size;
771 "device report descriptor doesn't match the expected size (%u != %u), preserving\n",
772 hdev->dev_rsize, orig_desc_size);
773 desc_copy_ptr = NULL;
777 /* Output parameters */
778 memset(params, 0, sizeof(*params));
779 params->desc_ptr = desc_copy_ptr;
780 desc_copy_ptr = NULL;
781 params->desc_size = desc_copy_size;
785 kfree(desc_copy_ptr);
790 * uclogic_params_huion_init() - initialize a Huion tablet interface and discover
793 * @params: Parameters to fill in (to be cleaned with
794 * uclogic_params_cleanup()). Not modified in case of error.
796 * @hdev: The HID device of the tablet interface to initialize and get
797 * parameters from. Cannot be NULL.
800 * Zero, if successful. A negative errno code on error.
802 static int uclogic_params_huion_init(struct uclogic_params *params,
803 struct hid_device *hdev)
806 struct usb_device *udev;
807 struct usb_interface *iface;
808 __u8 bInterfaceNumber;
810 /* The resulting parameters (noop) */
811 struct uclogic_params p = {0, };
812 static const char transition_ver[] = "HUION_T153_160607";
813 char *ver_ptr = NULL;
814 const size_t ver_len = sizeof(transition_ver) + 1;
815 __u8 *params_ptr = NULL;
816 size_t params_len = 0;
817 /* Parameters string descriptor of a model with touch ring (HS610) */
818 const __u8 touch_ring_model_params_buf[] = {
819 0x13, 0x03, 0x70, 0xC6, 0x00, 0x06, 0x7C, 0x00,
820 0xFF, 0x1F, 0xD8, 0x13, 0x03, 0x0D, 0x10, 0x01,
824 /* Check arguments */
825 if (params == NULL || hdev == NULL) {
830 udev = hid_to_usb_dev(hdev);
831 iface = to_usb_interface(hdev->dev.parent);
832 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
834 /* If it's a custom keyboard interface */
835 if (bInterfaceNumber == 1) {
836 /* Keep everything intact, but mark pen usage invalid */
837 p.pen.usage_invalid = true;
839 /* Else, if it's not a pen interface */
840 } else if (bInterfaceNumber != 0) {
841 uclogic_params_init_invalid(&p);
845 /* Try to get firmware version */
846 ver_ptr = kzalloc(ver_len, GFP_KERNEL);
847 if (ver_ptr == NULL) {
851 rc = usb_string(udev, 201, ver_ptr, ver_len);
856 "failed retrieving Huion firmware version: %d\n", rc);
860 /* If this is a transition firmware */
861 if (strcmp(ver_ptr, transition_ver) == 0) {
863 "transition firmware detected, not probing pen v2 parameters\n");
865 /* Try to probe v2 pen parameters */
866 rc = uclogic_params_pen_init_v2(&p.pen, &found,
867 ¶ms_ptr, ¶ms_len,
871 "failed probing pen v2 parameters: %d\n", rc);
874 hid_dbg(hdev, "pen v2 parameters found\n");
875 /* Create v2 frame button parameters */
876 rc = uclogic_params_frame_init_with_desc(
878 uclogic_rdesc_v2_frame_buttons_arr,
879 uclogic_rdesc_v2_frame_buttons_size,
880 UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID);
883 "failed creating v2 frame button parameters: %d\n",
888 /* Link from pen sub-report */
889 p.pen.subreport_list[0].value = 0xe0;
890 p.pen.subreport_list[0].id =
891 UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID;
893 /* If this is the model with touch ring */
894 if (params_ptr != NULL &&
895 params_len == sizeof(touch_ring_model_params_buf) &&
896 memcmp(params_ptr, touch_ring_model_params_buf,
898 /* Create touch ring parameters */
899 rc = uclogic_params_frame_init_with_desc(
901 uclogic_rdesc_v2_frame_touch_ring_arr,
902 uclogic_rdesc_v2_frame_touch_ring_size,
903 UCLOGIC_RDESC_V2_FRAME_TOUCH_ID);
906 "failed creating v2 frame touch ring parameters: %d\n",
910 p.frame_list[1].suffix = "Touch Ring";
911 p.frame_list[1].dev_id_byte =
912 UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE;
913 p.frame_list[1].touch_byte = 5;
914 p.frame_list[1].touch_max = 12;
915 p.frame_list[1].touch_flip_at = 7;
917 /* Create touch strip parameters */
918 rc = uclogic_params_frame_init_with_desc(
920 uclogic_rdesc_v2_frame_touch_strip_arr,
921 uclogic_rdesc_v2_frame_touch_strip_size,
922 UCLOGIC_RDESC_V2_FRAME_TOUCH_ID);
925 "failed creating v2 frame touch strip parameters: %d\n",
929 p.frame_list[1].suffix = "Touch Strip";
930 p.frame_list[1].dev_id_byte =
931 UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE;
932 p.frame_list[1].touch_byte = 5;
933 p.frame_list[1].touch_max = 8;
936 /* Link from pen sub-report */
937 p.pen.subreport_list[1].value = 0xf0;
938 p.pen.subreport_list[1].id =
939 UCLOGIC_RDESC_V2_FRAME_TOUCH_ID;
941 /* Create v2 frame dial parameters */
942 rc = uclogic_params_frame_init_with_desc(
944 uclogic_rdesc_v2_frame_dial_arr,
945 uclogic_rdesc_v2_frame_dial_size,
946 UCLOGIC_RDESC_V2_FRAME_DIAL_ID);
949 "failed creating v2 frame dial parameters: %d\n",
953 p.frame_list[2].suffix = "Dial";
954 p.frame_list[2].dev_id_byte =
955 UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE;
956 p.frame_list[2].bitmap_dial_byte = 5;
958 /* Link from pen sub-report */
959 p.pen.subreport_list[2].value = 0xf1;
960 p.pen.subreport_list[2].id =
961 UCLOGIC_RDESC_V2_FRAME_DIAL_ID;
965 hid_dbg(hdev, "pen v2 parameters not found\n");
968 /* Try to probe v1 pen parameters */
969 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
972 "failed probing pen v1 parameters: %d\n", rc);
975 hid_dbg(hdev, "pen v1 parameters found\n");
976 /* Try to probe v1 frame */
977 rc = uclogic_params_frame_init_v1(&p.frame_list[0],
980 hid_err(hdev, "v1 frame probing failed: %d\n", rc);
983 hid_dbg(hdev, "frame v1 parameters%s found\n",
984 (found ? "" : " not"));
986 /* Link frame button subreports from pen reports */
987 p.pen.subreport_list[0].value = 0xe0;
988 p.pen.subreport_list[0].id =
989 UCLOGIC_RDESC_V1_FRAME_ID;
993 hid_dbg(hdev, "pen v1 parameters not found\n");
995 uclogic_params_init_invalid(&p);
998 /* Output parameters */
999 memcpy(params, &p, sizeof(*params));
1000 memset(&p, 0, sizeof(p));
1005 uclogic_params_cleanup(&p);
1010 * uclogic_probe_interface() - some tablets, like the Parblo A610 PLUS V2 or
1011 * the XP-PEN Deco Mini 7, need to be initialized by sending them magic data.
1013 * @hdev: The HID device of the tablet interface to initialize and get
1014 * parameters from. Cannot be NULL.
1015 * @magic_arr: The magic data that should be sent to probe the interface.
1017 * @magic_size: Size of the magic data.
1018 * @endpoint: Endpoint where the magic data should be sent.
1021 * Zero, if successful. A negative errno code on error.
1023 static int uclogic_probe_interface(struct hid_device *hdev, u8 *magic_arr,
1024 int magic_size, int endpoint)
1026 struct usb_device *udev;
1027 unsigned int pipe = 0;
1032 if (!hdev || !magic_arr) {
1037 buf = kmemdup(magic_arr, magic_size, GFP_KERNEL);
1043 udev = hid_to_usb_dev(hdev);
1044 pipe = usb_sndintpipe(udev, endpoint);
1046 rc = usb_interrupt_msg(udev, pipe, buf, magic_size, &sent, 1000);
1047 if (rc || sent != magic_size) {
1048 hid_err(hdev, "Interface probing failed: %d\n", rc);
1060 * uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
1061 * discovering their parameters.
1063 * These tables, internally designed as v2 to differentiate them from older
1064 * models, expect a payload of magic data in orther to be switched to the fully
1065 * functional mode and expose their parameters in a similar way to the
1066 * information present in uclogic_params_pen_init_v1() but with some
1069 * @params: Parameters to fill in (to be cleaned with
1070 * uclogic_params_cleanup()). Not modified in case of error.
1072 * @hdev: The HID device of the tablet interface to initialize and get
1073 * parameters from. Cannot be NULL.
1076 * Zero, if successful. A negative errno code on error.
1078 static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
1079 struct hid_device *hdev)
1082 struct usb_interface *iface;
1083 __u8 bInterfaceNumber;
1084 const int str_desc_len = 12;
1085 __u8 *str_desc = NULL;
1086 __u8 *rdesc_pen = NULL;
1087 __u8 *rdesc_frame = NULL;
1088 s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
1090 __u8 magic_arr[] = {
1091 0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1093 /* The resulting parameters (noop) */
1094 struct uclogic_params p = {0, };
1096 if (!params || !hdev) {
1101 iface = to_usb_interface(hdev->dev.parent);
1102 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
1103 if (bInterfaceNumber != 2) {
1104 uclogic_params_init_invalid(&p);
1109 * Initialize the interface by sending magic data.
1110 * The specific data was discovered by sniffing the Windows driver
1113 rc = uclogic_probe_interface(hdev, magic_arr, sizeof(magic_arr), 0x03);
1115 uclogic_params_init_invalid(&p);
1120 * Read the string descriptor containing pen and frame parameters.
1121 * The specific string descriptor and data were discovered by sniffing
1122 * the Windows driver traffic.
1124 rc = uclogic_params_get_str_desc(&str_desc, hdev, 100, str_desc_len);
1125 if (rc != str_desc_len) {
1126 hid_err(hdev, "failed retrieving pen and frame parameters: %d\n", rc);
1127 uclogic_params_init_invalid(&p);
1131 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] =
1132 get_unaligned_le16(str_desc + 2);
1133 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] =
1134 get_unaligned_le16(str_desc + 4);
1135 desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = str_desc[6];
1136 desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] =
1137 get_unaligned_le16(str_desc + 8);
1138 resolution = get_unaligned_le16(str_desc + 10);
1139 if (resolution == 0) {
1140 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0;
1141 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0;
1143 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] =
1144 desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 /
1146 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] =
1147 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
1153 /* Initialize the pen interface */
1154 rdesc_pen = uclogic_rdesc_template_apply(
1155 uclogic_rdesc_ugee_v2_pen_template_arr,
1156 uclogic_rdesc_ugee_v2_pen_template_size,
1157 desc_params, ARRAY_SIZE(desc_params));
1163 p.pen.desc_ptr = rdesc_pen;
1164 p.pen.desc_size = uclogic_rdesc_ugee_v2_pen_template_size;
1166 p.pen.subreport_list[0].value = 0xf0;
1167 p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID;
1169 /* Initialize the frame interface */
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, ARRAY_SIZE(desc_params));
1179 rc = uclogic_params_frame_init_with_desc(&p.frame_list[0],
1181 uclogic_rdesc_ugee_v2_frame_btn_template_size,
1182 UCLOGIC_RDESC_V1_FRAME_ID);
1185 uclogic_params_init_invalid(&p);
1190 /* Output parameters */
1191 memcpy(params, &p, sizeof(*params));
1192 memset(&p, 0, sizeof(p));
1196 uclogic_params_cleanup(&p);
1201 * uclogic_params_init() - initialize a tablet interface and discover its
1204 * @params: Parameters to fill in (to be cleaned with
1205 * uclogic_params_cleanup()). Not modified in case of error.
1207 * @hdev: The HID device of the tablet interface to initialize and get
1208 * parameters from. Cannot be NULL. Must be using the USB low-level
1209 * driver, i.e. be an actual USB tablet.
1212 * Zero, if successful. A negative errno code on error.
1214 int uclogic_params_init(struct uclogic_params *params,
1215 struct hid_device *hdev)
1218 struct usb_device *udev;
1219 __u8 bNumInterfaces;
1220 struct usb_interface *iface;
1221 __u8 bInterfaceNumber;
1223 /* The resulting parameters (noop) */
1224 struct uclogic_params p = {0, };
1226 /* Check arguments */
1227 if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) {
1232 udev = hid_to_usb_dev(hdev);
1233 bNumInterfaces = udev->config->desc.bNumInterfaces;
1234 iface = to_usb_interface(hdev->dev.parent);
1235 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
1238 * Set replacement report descriptor if the original matches the
1239 * specified size. Otherwise keep interface unchanged.
1241 #define WITH_OPT_DESC(_orig_desc_token, _new_desc_token) \
1242 uclogic_params_init_with_opt_desc( \
1244 UCLOGIC_RDESC_##_orig_desc_token##_SIZE, \
1245 uclogic_rdesc_##_new_desc_token##_arr, \
1246 uclogic_rdesc_##_new_desc_token##_size)
1248 #define VID_PID(_vid, _pid) \
1249 (((__u32)(_vid) << 16) | ((__u32)(_pid) & U16_MAX))
1252 * Handle specific interfaces for specific tablets.
1254 * Observe the following logic:
1256 * If the interface is recognized as producing certain useful input:
1257 * Mark interface as valid.
1258 * Output interface parameters.
1259 * Else, if the interface is recognized as *not* producing any useful
1261 * Mark interface as invalid.
1263 * Mark interface as valid.
1264 * Output noop parameters.
1266 * Rule of thumb: it is better to disable a broken interface than let
1267 * it spew garbage input.
1270 switch (VID_PID(hdev->vendor, hdev->product)) {
1271 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1272 USB_DEVICE_ID_UCLOGIC_TABLET_PF1209):
1273 rc = WITH_OPT_DESC(PF1209_ORIG, pf1209_fixed);
1277 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1278 USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U):
1279 rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp4030u_fixed);
1283 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1284 USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U):
1285 if (hdev->dev_rsize == UCLOGIC_RDESC_WP5540U_V2_ORIG_SIZE) {
1286 if (bInterfaceNumber == 0) {
1287 /* Try to probe v1 pen parameters */
1288 rc = uclogic_params_pen_init_v1(&p.pen,
1292 "pen probing failed: %d\n",
1298 "pen parameters not found");
1301 uclogic_params_init_invalid(&p);
1304 rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp5540u_fixed);
1309 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1310 USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U):
1311 rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp8060u_fixed);
1315 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1316 USB_DEVICE_ID_UCLOGIC_TABLET_WP1062):
1317 rc = WITH_OPT_DESC(WP1062_ORIG, wp1062_fixed);
1321 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1322 USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850):
1323 switch (bInterfaceNumber) {
1325 rc = WITH_OPT_DESC(TWHL850_ORIG0, twhl850_fixed0);
1330 rc = WITH_OPT_DESC(TWHL850_ORIG1, twhl850_fixed1);
1335 rc = WITH_OPT_DESC(TWHL850_ORIG2, twhl850_fixed2);
1341 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1342 USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60):
1344 * If it is not a three-interface version, which is known to
1345 * respond to initialization.
1347 if (bNumInterfaces != 3) {
1348 switch (bInterfaceNumber) {
1350 rc = WITH_OPT_DESC(TWHA60_ORIG0,
1356 rc = WITH_OPT_DESC(TWHA60_ORIG1,
1365 case VID_PID(USB_VENDOR_ID_HUION,
1366 USB_DEVICE_ID_HUION_TABLET):
1367 case VID_PID(USB_VENDOR_ID_HUION,
1368 USB_DEVICE_ID_HUION_TABLET2):
1369 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1370 USB_DEVICE_ID_HUION_TABLET):
1371 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1372 USB_DEVICE_ID_YIYNOVA_TABLET):
1373 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1374 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_81):
1375 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1376 USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3):
1377 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1378 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_45):
1379 case VID_PID(USB_VENDOR_ID_UCLOGIC,
1380 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_47):
1381 rc = uclogic_params_huion_init(&p, hdev);
1385 case VID_PID(USB_VENDOR_ID_UGTIZER,
1386 USB_DEVICE_ID_UGTIZER_TABLET_GP0610):
1387 case VID_PID(USB_VENDOR_ID_UGTIZER,
1388 USB_DEVICE_ID_UGTIZER_TABLET_GT5040):
1389 case VID_PID(USB_VENDOR_ID_UGEE,
1390 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540):
1391 case VID_PID(USB_VENDOR_ID_UGEE,
1392 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640):
1393 case VID_PID(USB_VENDOR_ID_UGEE,
1394 USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06):
1395 case VID_PID(USB_VENDOR_ID_UGEE,
1396 USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720):
1397 /* If this is the pen interface */
1398 if (bInterfaceNumber == 1) {
1399 /* Probe v1 pen parameters */
1400 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1402 hid_err(hdev, "pen probing failed: %d\n", rc);
1406 hid_warn(hdev, "pen parameters not found");
1407 uclogic_params_init_invalid(&p);
1410 uclogic_params_init_invalid(&p);
1413 case VID_PID(USB_VENDOR_ID_UGEE,
1414 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01):
1415 /* If this is the pen and frame interface */
1416 if (bInterfaceNumber == 1) {
1417 /* Probe v1 pen parameters */
1418 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1420 hid_err(hdev, "pen probing failed: %d\n", rc);
1423 /* Initialize frame parameters */
1424 rc = uclogic_params_frame_init_with_desc(
1426 uclogic_rdesc_xppen_deco01_frame_arr,
1427 uclogic_rdesc_xppen_deco01_frame_size,
1432 uclogic_params_init_invalid(&p);
1435 case VID_PID(USB_VENDOR_ID_UGEE,
1436 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L):
1437 rc = uclogic_params_ugee_v2_init(&p, hdev);
1441 case VID_PID(USB_VENDOR_ID_TRUST,
1442 USB_DEVICE_ID_TRUST_PANORA_TABLET):
1443 case VID_PID(USB_VENDOR_ID_UGEE,
1444 USB_DEVICE_ID_UGEE_TABLET_G5):
1445 /* Ignore non-pen interfaces */
1446 if (bInterfaceNumber != 1) {
1447 uclogic_params_init_invalid(&p);
1451 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1453 hid_err(hdev, "pen probing failed: %d\n", rc);
1456 rc = uclogic_params_frame_init_with_desc(
1458 uclogic_rdesc_ugee_g5_frame_arr,
1459 uclogic_rdesc_ugee_g5_frame_size,
1460 UCLOGIC_RDESC_UGEE_G5_FRAME_ID);
1463 "failed creating frame parameters: %d\n",
1467 p.frame_list[0].re_lsb =
1468 UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB;
1469 p.frame_list[0].dev_id_byte =
1470 UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE;
1472 hid_warn(hdev, "pen parameters not found");
1473 uclogic_params_init_invalid(&p);
1477 case VID_PID(USB_VENDOR_ID_UGEE,
1478 USB_DEVICE_ID_UGEE_TABLET_EX07S):
1479 /* Ignore non-pen interfaces */
1480 if (bInterfaceNumber != 1) {
1481 uclogic_params_init_invalid(&p);
1485 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1487 hid_err(hdev, "pen probing failed: %d\n", rc);
1490 rc = uclogic_params_frame_init_with_desc(
1492 uclogic_rdesc_ugee_ex07_frame_arr,
1493 uclogic_rdesc_ugee_ex07_frame_size,
1497 "failed creating frame parameters: %d\n",
1502 hid_warn(hdev, "pen parameters not found");
1503 uclogic_params_init_invalid(&p);
1510 #undef WITH_OPT_DESC
1512 /* Output parameters */
1513 memcpy(params, &p, sizeof(*params));
1514 memset(&p, 0, sizeof(p));
1517 uclogic_params_cleanup(&p);