hid-uclogic-params.c (a985de58186fc37992bbebc386ced8d7d25aa400) hid-uclogic-params.c (337fa051d9b8aabf7081795d40e92e9d96f3442d)
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

--- 498 unchanged lines hidden (view full) ---

507 * (tablet interface's parameters).
508 * Can be called repeatedly.
509 *
510 * @params: Input parameters to cleanup. Cannot be NULL.
511 */
512void uclogic_params_cleanup(struct uclogic_params *params)
513{
514 if (!params->invalid) {
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

--- 498 unchanged lines hidden (view full) ---

507 * (tablet interface's parameters).
508 * Can be called repeatedly.
509 *
510 * @params: Input parameters to cleanup. Cannot be NULL.
511 */
512void uclogic_params_cleanup(struct uclogic_params *params)
513{
514 if (!params->invalid) {
515 size_t i;
515 kfree(params->desc_ptr);
516 uclogic_params_pen_cleanup(&params->pen);
516 kfree(params->desc_ptr);
517 uclogic_params_pen_cleanup(&params->pen);
517 uclogic_params_frame_cleanup(&params->frame);
518 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++)
519 uclogic_params_frame_cleanup(&params->frame_list[i]);
520
518 memset(params, 0, sizeof(*params));
519 }
520}
521
522/**
523 * uclogic_params_get_desc() - Get a replacement report descriptor for a
524 * tablet's interface.
525 *

--- 11 unchanged lines hidden (view full) ---

537 * Zero, if successful.
538 * -EINVAL, if invalid arguments are supplied.
539 * -ENOMEM, if failed to allocate memory.
540 */
541int uclogic_params_get_desc(const struct uclogic_params *params,
542 __u8 **pdesc,
543 unsigned int *psize)
544{
521 memset(params, 0, sizeof(*params));
522 }
523}
524
525/**
526 * uclogic_params_get_desc() - Get a replacement report descriptor for a
527 * tablet's interface.
528 *

--- 11 unchanged lines hidden (view full) ---

540 * Zero, if successful.
541 * -EINVAL, if invalid arguments are supplied.
542 * -ENOMEM, if failed to allocate memory.
543 */
544int uclogic_params_get_desc(const struct uclogic_params *params,
545 __u8 **pdesc,
546 unsigned int *psize)
547{
545 bool common_present;
546 bool pen_present;
547 bool frame_present;
548 unsigned int size;
548 int rc = -ENOMEM;
549 bool present = false;
550 unsigned int size = 0;
549 __u8 *desc = NULL;
551 __u8 *desc = NULL;
552 size_t i;
550
551 /* Check arguments */
552 if (params == NULL || pdesc == NULL || psize == NULL)
553 return -EINVAL;
554
553
554 /* Check arguments */
555 if (params == NULL || pdesc == NULL || psize == NULL)
556 return -EINVAL;
557
555 size = 0;
558 /* Concatenate descriptors */
559#define ADD_DESC(_desc_ptr, _desc_size) \
560 do { \
561 unsigned int new_size; \
562 __u8 *new_desc; \
563 if ((_desc_ptr) == NULL) { \
564 break; \
565 } \
566 new_size = size + (_desc_size); \
567 new_desc = krealloc(desc, new_size, GFP_KERNEL); \
568 if (new_desc == NULL) { \
569 goto cleanup; \
570 } \
571 memcpy(new_desc + size, (_desc_ptr), (_desc_size)); \
572 desc = new_desc; \
573 size = new_size; \
574 present = true; \
575 } while (0)
556
576
557 common_present = (params->desc_ptr != NULL);
558 pen_present = (params->pen.desc_ptr != NULL);
559 frame_present = (params->frame.desc_ptr != NULL);
577 ADD_DESC(params->desc_ptr, params->desc_size);
578 ADD_DESC(params->pen.desc_ptr, params->pen.desc_size);
579 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
580 ADD_DESC(params->frame_list[i].desc_ptr,
581 params->frame_list[i].desc_size);
582 }
560
583
561 if (common_present)
562 size += params->desc_size;
563 if (pen_present)
564 size += params->pen.desc_size;
565 if (frame_present)
566 size += params->frame.desc_size;
584#undef ADD_DESC
567
585
568 if (common_present || pen_present || frame_present) {
569 __u8 *p;
570
571 desc = kmalloc(size, GFP_KERNEL);
572 if (desc == NULL)
573 return -ENOMEM;
574 p = desc;
575
576 if (common_present) {
577 memcpy(p, params->desc_ptr,
578 params->desc_size);
579 p += params->desc_size;
580 }
581 if (pen_present) {
582 memcpy(p, params->pen.desc_ptr,
583 params->pen.desc_size);
584 p += params->pen.desc_size;
585 }
586 if (frame_present) {
587 memcpy(p, params->frame.desc_ptr,
588 params->frame.desc_size);
589 p += params->frame.desc_size;
590 }
591
592 WARN_ON(p != desc + size);
593
586 if (present) {
587 *pdesc = desc;
594 *psize = size;
588 *psize = size;
589 desc = NULL;
595 }
590 }
596
597 *pdesc = desc;
598 return 0;
591 rc = 0;
592cleanup:
593 kfree(desc);
594 return rc;
599}
600
601/**
602 * uclogic_params_init_invalid() - initialize tablet interface parameters,
603 * specifying the interface is invalid.
604 *
605 * @params: Parameters to initialize (to be cleaned with
606 * uclogic_params_cleanup()). Cannot be NULL.

--- 139 unchanged lines hidden (view full) ---

746 if (rc != 0) {
747 hid_err(hdev,
748 "failed probing pen v2 parameters: %d\n", rc);
749 goto cleanup;
750 } else if (found) {
751 hid_dbg(hdev, "pen v2 parameters found\n");
752 /* Create v2 frame parameters */
753 rc = uclogic_params_frame_init_with_desc(
595}
596
597/**
598 * uclogic_params_init_invalid() - initialize tablet interface parameters,
599 * specifying the interface is invalid.
600 *
601 * @params: Parameters to initialize (to be cleaned with
602 * uclogic_params_cleanup()). Cannot be NULL.

--- 139 unchanged lines hidden (view full) ---

742 if (rc != 0) {
743 hid_err(hdev,
744 "failed probing pen v2 parameters: %d\n", rc);
745 goto cleanup;
746 } else if (found) {
747 hid_dbg(hdev, "pen v2 parameters found\n");
748 /* Create v2 frame parameters */
749 rc = uclogic_params_frame_init_with_desc(
754 &p.frame,
750 &p.frame_list[0],
755 uclogic_rdesc_v2_frame_arr,
756 uclogic_rdesc_v2_frame_size,
757 UCLOGIC_RDESC_V2_FRAME_ID);
758 if (rc != 0) {
759 hid_err(hdev,
760 "failed creating v2 frame parameters: %d\n",
761 rc);
762 goto cleanup;

--- 11 unchanged lines hidden (view full) ---

774 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
775 if (rc != 0) {
776 hid_err(hdev,
777 "failed probing pen v1 parameters: %d\n", rc);
778 goto cleanup;
779 } else if (found) {
780 hid_dbg(hdev, "pen v1 parameters found\n");
781 /* Try to probe v1 frame */
751 uclogic_rdesc_v2_frame_arr,
752 uclogic_rdesc_v2_frame_size,
753 UCLOGIC_RDESC_V2_FRAME_ID);
754 if (rc != 0) {
755 hid_err(hdev,
756 "failed creating v2 frame parameters: %d\n",
757 rc);
758 goto cleanup;

--- 11 unchanged lines hidden (view full) ---

770 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
771 if (rc != 0) {
772 hid_err(hdev,
773 "failed probing pen v1 parameters: %d\n", rc);
774 goto cleanup;
775 } else if (found) {
776 hid_dbg(hdev, "pen v1 parameters found\n");
777 /* Try to probe v1 frame */
782 rc = uclogic_params_frame_init_v1(&p.frame,
778 rc = uclogic_params_frame_init_v1(&p.frame_list[0],
783 &found, hdev);
784 if (rc != 0) {
785 hid_err(hdev, "v1 frame probing failed: %d\n", rc);
786 goto cleanup;
787 }
788 hid_dbg(hdev, "frame v1 parameters%s found\n",
789 (found ? "" : " not"));
790 if (found) {

--- 237 unchanged lines hidden (view full) ---

1028 /* Probe v1 pen parameters */
1029 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1030 if (rc != 0) {
1031 hid_err(hdev, "pen probing failed: %d\n", rc);
1032 goto cleanup;
1033 }
1034 /* Initialize frame parameters */
1035 rc = uclogic_params_frame_init_with_desc(
779 &found, hdev);
780 if (rc != 0) {
781 hid_err(hdev, "v1 frame probing failed: %d\n", rc);
782 goto cleanup;
783 }
784 hid_dbg(hdev, "frame v1 parameters%s found\n",
785 (found ? "" : " not"));
786 if (found) {

--- 237 unchanged lines hidden (view full) ---

1024 /* Probe v1 pen parameters */
1025 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1026 if (rc != 0) {
1027 hid_err(hdev, "pen probing failed: %d\n", rc);
1028 goto cleanup;
1029 }
1030 /* Initialize frame parameters */
1031 rc = uclogic_params_frame_init_with_desc(
1036 &p.frame,
1032 &p.frame_list[0],
1037 uclogic_rdesc_xppen_deco01_frame_arr,
1038 uclogic_rdesc_xppen_deco01_frame_size,
1039 0);
1040 if (rc != 0)
1041 goto cleanup;
1042 } else {
1043 uclogic_params_init_invalid(&p);
1044 }

--- 9 unchanged lines hidden (view full) ---

1054 }
1055
1056 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1057 if (rc != 0) {
1058 hid_err(hdev, "pen probing failed: %d\n", rc);
1059 goto cleanup;
1060 } else if (found) {
1061 rc = uclogic_params_frame_init_with_desc(
1033 uclogic_rdesc_xppen_deco01_frame_arr,
1034 uclogic_rdesc_xppen_deco01_frame_size,
1035 0);
1036 if (rc != 0)
1037 goto cleanup;
1038 } else {
1039 uclogic_params_init_invalid(&p);
1040 }

--- 9 unchanged lines hidden (view full) ---

1050 }
1051
1052 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1053 if (rc != 0) {
1054 hid_err(hdev, "pen probing failed: %d\n", rc);
1055 goto cleanup;
1056 } else if (found) {
1057 rc = uclogic_params_frame_init_with_desc(
1062 &p.frame,
1058 &p.frame_list[0],
1063 uclogic_rdesc_ugee_g5_frame_arr,
1064 uclogic_rdesc_ugee_g5_frame_size,
1065 UCLOGIC_RDESC_UGEE_G5_FRAME_ID);
1066 if (rc != 0) {
1067 hid_err(hdev,
1068 "failed creating frame parameters: %d\n",
1069 rc);
1070 goto cleanup;
1071 }
1059 uclogic_rdesc_ugee_g5_frame_arr,
1060 uclogic_rdesc_ugee_g5_frame_size,
1061 UCLOGIC_RDESC_UGEE_G5_FRAME_ID);
1062 if (rc != 0) {
1063 hid_err(hdev,
1064 "failed creating frame parameters: %d\n",
1065 rc);
1066 goto cleanup;
1067 }
1072 p.frame.re_lsb =
1068 p.frame_list[0].re_lsb =
1073 UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB;
1069 UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB;
1074 p.frame.dev_id_byte =
1070 p.frame_list[0].dev_id_byte =
1075 UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE;
1076 } else {
1077 hid_warn(hdev, "pen parameters not found");
1078 uclogic_params_init_invalid(&p);
1079 }
1080
1081 break;
1082 case VID_PID(USB_VENDOR_ID_UGEE,

--- 5 unchanged lines hidden (view full) ---

1088 }
1089
1090 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1091 if (rc != 0) {
1092 hid_err(hdev, "pen probing failed: %d\n", rc);
1093 goto cleanup;
1094 } else if (found) {
1095 rc = uclogic_params_frame_init_with_desc(
1071 UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE;
1072 } else {
1073 hid_warn(hdev, "pen parameters not found");
1074 uclogic_params_init_invalid(&p);
1075 }
1076
1077 break;
1078 case VID_PID(USB_VENDOR_ID_UGEE,

--- 5 unchanged lines hidden (view full) ---

1084 }
1085
1086 rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1087 if (rc != 0) {
1088 hid_err(hdev, "pen probing failed: %d\n", rc);
1089 goto cleanup;
1090 } else if (found) {
1091 rc = uclogic_params_frame_init_with_desc(
1096 &p.frame,
1092 &p.frame_list[0],
1097 uclogic_rdesc_ugee_ex07_frame_arr,
1098 uclogic_rdesc_ugee_ex07_frame_size,
1099 0);
1100 if (rc != 0) {
1101 hid_err(hdev,
1102 "failed creating frame parameters: %d\n",
1103 rc);
1104 goto cleanup;

--- 20 unchanged lines hidden ---
1093 uclogic_rdesc_ugee_ex07_frame_arr,
1094 uclogic_rdesc_ugee_ex07_frame_size,
1095 0);
1096 if (rc != 0) {
1097 hid_err(hdev,
1098 "failed creating frame parameters: %d\n",
1099 rc);
1100 goto cleanup;

--- 20 unchanged lines hidden ---