Lines Matching +full:tablet +full:- +full:mode
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
16 #include "hid-uclogic-params.h"
17 #include "hid-uclogic-rdesc.h"
19 #include "hid-ids.h"
25 * uclogic_params_pen_inrange_to_str() - Convert a pen in-range reporting type
27 * @inrange: The in-range reporting type to convert.
49 * uclogic_params_pen_hid_dbg() - Dump tablet interface pen parameters
53 * Dump tablet interface pen parameters with hid_dbg(). The dump is indented
62 (pen->usage_invalid ? "true" : "false")); in uclogic_params_pen_hid_dbg()
63 hid_dbg(hdev, "\t.desc_ptr = %p\n", pen->desc_ptr); in uclogic_params_pen_hid_dbg()
64 hid_dbg(hdev, "\t.desc_size = %u\n", pen->desc_size); in uclogic_params_pen_hid_dbg()
65 hid_dbg(hdev, "\t.id = %u\n", pen->id); in uclogic_params_pen_hid_dbg()
67 for (i = 0; i < ARRAY_SIZE(pen->subreport_list); i++) { in uclogic_params_pen_hid_dbg()
69 pen->subreport_list[i].value, in uclogic_params_pen_hid_dbg()
70 pen->subreport_list[i].id, in uclogic_params_pen_hid_dbg()
71 i < (ARRAY_SIZE(pen->subreport_list) - 1) ? "," : ""); in uclogic_params_pen_hid_dbg()
75 uclogic_params_pen_inrange_to_str(pen->inrange)); in uclogic_params_pen_hid_dbg()
77 (pen->fragmented_hires ? "true" : "false")); in uclogic_params_pen_hid_dbg()
79 (pen->tilt_y_flipped ? "true" : "false")); in uclogic_params_pen_hid_dbg()
83 * uclogic_params_frame_hid_dbg() - Dump tablet interface frame parameters
87 * Dump tablet interface frame parameters with hid_dbg(). The dump is
94 hid_dbg(hdev, "\t\t.desc_ptr = %p\n", frame->desc_ptr); in uclogic_params_frame_hid_dbg()
95 hid_dbg(hdev, "\t\t.desc_size = %u\n", frame->desc_size); in uclogic_params_frame_hid_dbg()
96 hid_dbg(hdev, "\t\t.id = %u\n", frame->id); in uclogic_params_frame_hid_dbg()
97 hid_dbg(hdev, "\t\t.suffix = %s\n", frame->suffix); in uclogic_params_frame_hid_dbg()
98 hid_dbg(hdev, "\t\t.re_lsb = %u\n", frame->re_lsb); in uclogic_params_frame_hid_dbg()
99 hid_dbg(hdev, "\t\t.dev_id_byte = %u\n", frame->dev_id_byte); in uclogic_params_frame_hid_dbg()
100 hid_dbg(hdev, "\t\t.touch_byte = %u\n", frame->touch_byte); in uclogic_params_frame_hid_dbg()
101 hid_dbg(hdev, "\t\t.touch_max = %hhd\n", frame->touch_max); in uclogic_params_frame_hid_dbg()
103 frame->touch_flip_at); in uclogic_params_frame_hid_dbg()
105 frame->bitmap_dial_byte); in uclogic_params_frame_hid_dbg()
109 * uclogic_params_hid_dbg() - Dump tablet interface parameters
113 * Dump tablet interface parameters with hid_dbg().
121 params->invalid ? "true" : "false"); in uclogic_params_hid_dbg()
122 hid_dbg(hdev, ".desc_ptr = %p\n", params->desc_ptr); in uclogic_params_hid_dbg()
123 hid_dbg(hdev, ".desc_size = %u\n", params->desc_size); in uclogic_params_hid_dbg()
125 uclogic_params_pen_hid_dbg(hdev, ¶ms->pen); in uclogic_params_hid_dbg()
128 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) { in uclogic_params_hid_dbg()
130 uclogic_params_frame_hid_dbg(hdev, ¶ms->frame_list[i]); in uclogic_params_hid_dbg()
132 i < (ARRAY_SIZE(params->frame_list) - 1) ? "," : ""); in uclogic_params_hid_dbg()
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
142 * @pbuf: Location for the kmalloc-allocated buffer pointer containing
145 * @hdev: The HID device of the tablet interface to retrieve the string
152 * -EPIPE, if the descriptor was not found, or
164 rc = -EINVAL; in uclogic_params_get_str_desc()
172 rc = -ENOMEM; in uclogic_params_get_str_desc()
181 if (rc == -EPIPE) { in uclogic_params_get_str_desc()
202 * uclogic_params_pen_cleanup - free resources used by struct
203 * uclogic_params_pen (tablet interface's pen input parameters).
210 kfree(pen->desc_ptr); in uclogic_params_pen_cleanup()
215 * uclogic_params_pen_init_v1() - initialize tablet interface pen
224 * @hdev: The HID device of the tablet interface to initialize and get
247 rc = -EINVAL; in uclogic_params_pen_init_v1()
255 * NOTE: This enables fully-functional tablet mode. in uclogic_params_pen_init_v1()
258 if (rc == -EPIPE) { in uclogic_params_pen_init_v1()
304 rc = -ENOMEM; in uclogic_params_pen_init_v1()
309 * Fill-in the parameters in uclogic_params_pen_init_v1()
312 pen->desc_ptr = desc_ptr; in uclogic_params_pen_init_v1()
314 pen->desc_size = uclogic_rdesc_v1_pen_template_size; in uclogic_params_pen_init_v1()
315 pen->id = UCLOGIC_RDESC_V1_PEN_ID; in uclogic_params_pen_init_v1()
316 pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_INVERTED; in uclogic_params_pen_init_v1()
328 * uclogic_params_get_le24() - get a 24-bit little-endian number from a
343 * uclogic_params_pen_init_v2() - initialize tablet interface pen
355 * parameters, which could be used to identify the tablet
362 * @hdev: The HID device of the tablet interface to initialize
392 rc = -EINVAL; in uclogic_params_pen_init_v2()
400 * NOTE: This enables fully-functional tablet mode. in uclogic_params_pen_init_v2()
403 if (rc == -EPIPE) { in uclogic_params_pen_init_v2()
420 * Check it's not just a catch-all UTF-16LE-encoded ASCII in uclogic_params_pen_init_v2()
464 rc = -ENOMEM; in uclogic_params_pen_init_v2()
469 * Fill-in the parameters in uclogic_params_pen_init_v2()
472 pen->desc_ptr = desc_ptr; in uclogic_params_pen_init_v2()
474 pen->desc_size = uclogic_rdesc_v2_pen_template_size; in uclogic_params_pen_init_v2()
475 pen->id = UCLOGIC_RDESC_V2_PEN_ID; in uclogic_params_pen_init_v2()
476 pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_NONE; in uclogic_params_pen_init_v2()
477 pen->fragmented_hires = true; in uclogic_params_pen_init_v2()
478 pen->tilt_y_flipped = true; in uclogic_params_pen_init_v2()
497 * uclogic_params_frame_cleanup - free resources used by struct
498 * uclogic_params_frame (tablet interface's frame controls input parameters).
505 kfree(frame->desc_ptr); in uclogic_params_frame_cleanup()
510 * uclogic_params_frame_init_with_desc() - initialize tablet's frame control
533 return -EINVAL; in uclogic_params_frame_init_with_desc()
537 return -ENOMEM; in uclogic_params_frame_init_with_desc()
540 frame->desc_ptr = copy_desc_ptr; in uclogic_params_frame_init_with_desc()
541 frame->desc_size = desc_size; in uclogic_params_frame_init_with_desc()
542 frame->id = id; in uclogic_params_frame_init_with_desc()
547 * uclogic_params_frame_init_v1() - initialize v1 tablet interface frame
556 * @hdev: The HID device of the tablet interface to initialize and get
574 rc = -EINVAL; in uclogic_params_frame_init_v1()
581 * Enable generic button mode in uclogic_params_frame_init_v1()
585 rc = -ENOMEM; in uclogic_params_frame_init_v1()
590 if (rc == -EPIPE) { in uclogic_params_frame_init_v1()
592 "generic button -enabling string descriptor not found\n"); in uclogic_params_frame_init_v1()
619 * uclogic_params_cleanup_event_hooks - free resources used by the list of raw
629 if (!params || !params->event_hooks) in uclogic_params_cleanup_event_hooks()
632 list_for_each_entry_safe(curr, n, ¶ms->event_hooks->list, list) { in uclogic_params_cleanup_event_hooks()
633 cancel_work_sync(&curr->work); in uclogic_params_cleanup_event_hooks()
634 list_del(&curr->list); in uclogic_params_cleanup_event_hooks()
635 kfree(curr->event); in uclogic_params_cleanup_event_hooks()
639 kfree(params->event_hooks); in uclogic_params_cleanup_event_hooks()
640 params->event_hooks = NULL; in uclogic_params_cleanup_event_hooks()
644 * uclogic_params_cleanup - free resources used by struct uclogic_params
645 * (tablet interface's parameters).
652 if (!params->invalid) { in uclogic_params_cleanup()
654 kfree(params->desc_ptr); in uclogic_params_cleanup()
655 uclogic_params_pen_cleanup(¶ms->pen); in uclogic_params_cleanup()
656 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) in uclogic_params_cleanup()
657 uclogic_params_frame_cleanup(¶ms->frame_list[i]); in uclogic_params_cleanup()
665 * uclogic_params_get_desc() - Get a replacement report descriptor for a
666 * tablet's interface.
668 * @params: The parameters of a tablet interface to get report
670 * @pdesc: Location for the resulting, kmalloc-allocated report
680 * -EINVAL, if invalid arguments are supplied.
681 * -ENOMEM, if failed to allocate memory.
687 int rc = -ENOMEM; in uclogic_params_get_desc()
695 return -EINVAL; in uclogic_params_get_desc()
716 ADD_DESC(params->desc_ptr, params->desc_size); in uclogic_params_get_desc()
717 ADD_DESC(params->pen.desc_ptr, params->pen.desc_size); in uclogic_params_get_desc()
718 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) { in uclogic_params_get_desc()
719 ADD_DESC(params->frame_list[i].desc_ptr, in uclogic_params_get_desc()
720 params->frame_list[i].desc_size); in uclogic_params_get_desc()
737 * uclogic_params_init_invalid() - initialize tablet interface parameters,
745 params->invalid = true; in uclogic_params_init_invalid()
749 * uclogic_params_init_with_opt_desc() - initialize tablet interface
757 * @hdev: The HID device of the tablet interface create the
766 * Zero, if successful. -EINVAL if an invalid argument was passed.
767 * -ENOMEM, if failed to allocate memory.
782 rc = -EINVAL; in uclogic_params_init_with_opt_desc()
787 if (hdev->dev_rsize == orig_desc_size) { in uclogic_params_init_with_opt_desc()
792 rc = -ENOMEM; in uclogic_params_init_with_opt_desc()
799 hdev->dev_rsize, orig_desc_size); in uclogic_params_init_with_opt_desc()
806 params->desc_ptr = desc_copy_ptr; in uclogic_params_init_with_opt_desc()
808 params->desc_size = desc_copy_size; in uclogic_params_init_with_opt_desc()
817 * uclogic_params_huion_init() - initialize a Huion tablet interface and discover
823 * @hdev: The HID device of the tablet interface to initialize and get
853 rc = -EINVAL; in uclogic_params_huion_init()
858 iface = to_usb_interface(hdev->dev.parent); in uclogic_params_huion_init()
859 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; in uclogic_params_huion_init()
875 rc = -ENOMEM; in uclogic_params_huion_init()
879 if (rc == -EPIPE) { in uclogic_params_huion_init()
915 /* Link from pen sub-report */ in uclogic_params_huion_init()
963 /* Link from pen sub-report */ in uclogic_params_huion_init()
985 /* Link from pen sub-report */ in uclogic_params_huion_init()
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.
1040 * @hdev: The HID device of the tablet interface to initialize and get
1060 rc = -EINVAL; in uclogic_probe_interface()
1066 rc = -ENOMEM; in uclogic_probe_interface()
1076 rc = -1; in uclogic_probe_interface()
1087 * uclogic_params_parse_ugee_v2_desc - parse the string descriptor containing
1115 return -EINVAL; in uclogic_params_parse_ugee_v2_desc()
1118 return -EINVAL; in uclogic_params_parse_ugee_v2_desc()
1146 * uclogic_params_ugee_v2_init_frame_buttons() - initialize a UGEE v2 frame with
1163 return -EINVAL; in uclogic_params_ugee_v2_init_frame_buttons()
1170 return -ENOMEM; in uclogic_params_ugee_v2_init_frame_buttons()
1172 rc = uclogic_params_frame_init_with_desc(&p->frame_list[0], in uclogic_params_ugee_v2_init_frame_buttons()
1181 * uclogic_params_ugee_v2_init_frame_dial() - initialize a UGEE v2 frame with a
1198 return -EINVAL; in uclogic_params_ugee_v2_init_frame_dial()
1205 return -ENOMEM; in uclogic_params_ugee_v2_init_frame_dial()
1207 rc = uclogic_params_frame_init_with_desc(&p->frame_list[0], in uclogic_params_ugee_v2_init_frame_dial()
1215 p->frame_list[0].bitmap_dial_byte = 7; in uclogic_params_ugee_v2_init_frame_dial()
1220 * uclogic_params_ugee_v2_init_frame_mouse() - initialize a UGEE v2 frame with a
1232 return -EINVAL; in uclogic_params_ugee_v2_init_frame_mouse()
1234 rc = uclogic_params_frame_init_with_desc(&p->frame_list[1], in uclogic_params_ugee_v2_init_frame_mouse()
1242 * uclogic_params_ugee_v2_has_battery() - check whether a UGEE v2 device has
1244 * @hdev: The HID device of the tablet interface.
1253 if (drvdata->quirks & UCLOGIC_BATTERY_QUIRK) in uclogic_params_ugee_v2_has_battery()
1256 /* The XP-PEN Deco LW vendor, product and version are identical to the in uclogic_params_ugee_v2_has_battery()
1261 if (hdev->vendor == USB_VENDOR_ID_UGEE && in uclogic_params_ugee_v2_has_battery()
1262 hdev->product == USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) { in uclogic_params_ugee_v2_has_battery()
1265 if (strstarts(udev->product, "Deco LW")) in uclogic_params_ugee_v2_has_battery()
1273 * uclogic_params_ugee_v2_init_battery() - initialize UGEE v2 battery reporting.
1274 * @hdev: The HID device of the tablet interface, cannot be NULL.
1286 return -EINVAL; in uclogic_params_ugee_v2_init_battery()
1288 /* Some tablets contain invalid characters in hdev->uniq, throwing a in uclogic_params_ugee_v2_init_battery()
1292 snprintf(hdev->uniq, sizeof(hdev->uniq), "%x-%x", hdev->vendor, in uclogic_params_ugee_v2_init_battery()
1293 hdev->product); in uclogic_params_ugee_v2_init_battery()
1295 rc = uclogic_params_frame_init_with_desc(&p->frame_list[1], in uclogic_params_ugee_v2_init_battery()
1302 p->frame_list[1].suffix = "Battery"; in uclogic_params_ugee_v2_init_battery()
1303 p->pen.subreport_list[1].value = 0xf2; in uclogic_params_ugee_v2_init_battery()
1304 p->pen.subreport_list[1].id = UCLOGIC_RDESC_UGEE_V2_BATTERY_ID; in uclogic_params_ugee_v2_init_battery()
1310 * uclogic_params_ugee_v2_reconnect_work() - When a wireless tablet looses
1313 * uclogic_probe_interface() needs to be called again to enable the tablet.
1322 uclogic_probe_interface(event_hook->hdev, uclogic_ugee_v2_probe_arr, in uclogic_params_ugee_v2_reconnect_work()
1328 * uclogic_params_ugee_v2_init_event_hooks() - initialize the list of events
1330 * @hdev: The HID device of the tablet interface to initialize and get
1342 /* Event received on wireless tablet reconnection */ in uclogic_params_ugee_v2_init_event_hooks()
1347 return -EINVAL; in uclogic_params_ugee_v2_init_event_hooks()
1349 /* The reconnection event is only received if the tablet has battery */ in uclogic_params_ugee_v2_init_event_hooks()
1353 p->event_hooks = kzalloc(sizeof(*p->event_hooks), GFP_KERNEL); in uclogic_params_ugee_v2_init_event_hooks()
1354 if (!p->event_hooks) in uclogic_params_ugee_v2_init_event_hooks()
1355 return -ENOMEM; in uclogic_params_ugee_v2_init_event_hooks()
1357 INIT_LIST_HEAD(&p->event_hooks->list); in uclogic_params_ugee_v2_init_event_hooks()
1361 return -ENOMEM; in uclogic_params_ugee_v2_init_event_hooks()
1363 INIT_WORK(&event_hook->work, uclogic_params_ugee_v2_reconnect_work); in uclogic_params_ugee_v2_init_event_hooks()
1364 event_hook->hdev = hdev; in uclogic_params_ugee_v2_init_event_hooks()
1365 event_hook->size = ARRAY_SIZE(reconnect_event); in uclogic_params_ugee_v2_init_event_hooks()
1366 event_hook->event = kmemdup(reconnect_event, event_hook->size, GFP_KERNEL); in uclogic_params_ugee_v2_init_event_hooks()
1367 if (!event_hook->event) in uclogic_params_ugee_v2_init_event_hooks()
1368 return -ENOMEM; in uclogic_params_ugee_v2_init_event_hooks()
1370 list_add_tail(&event_hook->list, &p->event_hooks->list); in uclogic_params_ugee_v2_init_event_hooks()
1376 * uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
1381 * functional mode and expose their parameters in a similar way to the
1388 * @hdev: The HID device of the tablet interface to initialize and get
1410 rc = -EINVAL; in uclogic_params_ugee_v2_init()
1415 iface = to_usb_interface(hdev->dev.parent); in uclogic_params_ugee_v2_init()
1416 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; in uclogic_params_ugee_v2_init()
1472 rc = -ENOMEM; in uclogic_params_ugee_v2_init()
1483 if (drvdata->quirks & UCLOGIC_MOUSE_FRAME_QUIRK) in uclogic_params_ugee_v2_init()
1530 * uclogic_params_init() - initialize a tablet interface and discover its
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.
1557 rc = -EINVAL; in uclogic_params_init()
1562 bNumInterfaces = udev->config->desc.bNumInterfaces; in uclogic_params_init()
1563 iface = to_usb_interface(hdev->dev.parent); in uclogic_params_init()
1564 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; in uclogic_params_init()
1599 switch (VID_PID(hdev->vendor, hdev->product)) { in uclogic_params_init()
1614 if (hdev->dev_rsize == UCLOGIC_RDESC_WP5540U_V2_ORIG_SIZE) { in uclogic_params_init()
1673 * If it is not a three-interface version, which is known to in uclogic_params_init()
1784 /* Ignore non-pen interfaces */ in uclogic_params_init()
1818 /* Ignore non-pen interfaces */ in uclogic_params_init()
1861 #include "hid-uclogic-params-test.c"