Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions hid-uclogic-params.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,87 @@ static int uclogic_params_pen_init_v1(struct uclogic_params_pen *pen,
return rc;
}

/**
* uclogic_params_pen_init_mast10() - initialize tablet interface pen
* input and retrieve its parameters from the device, using v1 protocol.
*
* @pen: Pointer to the pen parameters to initialize (to be
* cleaned up with uclogic_params_pen_cleanup()). Not modified in
* case of error, or if parameters are not found. Cannot be NULL.
* @pfound: Location for a flag which is set to true if the parameters
* were found, and to false if not (e.g. device was
* incompatible). Not modified in case of error. Cannot be NULL.
* @hdev: The HID device of the tablet interface to initialize and get
* parameters from. Cannot be NULL.
*
* Returns:
* Zero, if successful. A negative errno code on error.
*/
static int uclogic_params_pen_init_mast10(struct uclogic_params_pen *pen,
bool *pfound,
struct hid_device *hdev)
{
int rc;
bool found = false;
/* Buffer for (part of) the string descriptor */
__u8 *buf = NULL;
/* Minimum descriptor length required, maximum seen so far is 18 */
const int len = 12;
__u8 *desc_copy_ptr = NULL;

/* Check arguments */
if (pen == NULL || pfound == NULL || hdev == NULL) {
rc = -EINVAL;
goto cleanup;
}

/*
* Read string descriptor containing pen input parameters.
* The specific string descriptor and data were discovered by sniffing
* the Windows driver traffic.
* NOTE: This enables fully-functional tablet mode.
*/
rc = uclogic_params_get_str_desc(&buf, hdev, 100, len);
if (rc == -EPIPE) {
hid_dbg(hdev,
"string descriptor with pen parameters not found, assuming not compatible\n");
goto finish;
} else if (rc < 0) {
hid_err(hdev, "failed retrieving pen parameters: %d\n", rc);
goto cleanup;
} else if (rc != len) {
hid_dbg(hdev,
"string descriptor with pen parameters has invalid length (got %d, expected %d), assuming not compatible\n",
rc, len);
goto finish;
}

kfree(buf);
buf = NULL;

desc_copy_ptr = kmemdup(uclogic_rdesc_mast10_fixed0_arr, uclogic_rdesc_mast10_fixed0_size, GFP_KERNEL);
if (desc_copy_ptr == NULL) {
rc = -ENOMEM;
goto cleanup;
}

/*
* Fill-in the parameters
*/
memset(pen, 0, sizeof(*pen));
pen->desc_ptr = desc_copy_ptr;
desc_copy_ptr = NULL;
pen->desc_size = uclogic_rdesc_mast10_fixed0_size;
found = true;
finish:
*pfound = found;
rc = 0;
cleanup:
kfree(desc_copy_ptr);
kfree(buf);
return rc;
}

/**
* uclogic_params_get_le24() - get a 24-bit little-endian number from a
* buffer.
Expand Down Expand Up @@ -989,6 +1070,19 @@ int uclogic_params_init(struct uclogic_params *params,
USB_DEVICE_ID_HUION_TABLET):
case VID_PID(USB_VENDOR_ID_UCLOGIC,
USB_DEVICE_ID_YIYNOVA_TABLET):
if (hdev->dev_rsize == UCLOGIC_RDESC_MAST10_ORIG0_SIZE &&
bInterfaceNumber == 0) {
rc = uclogic_params_pen_init_mast10(&p.pen, &found, hdev);
if (rc != 0) {
hid_err(hdev, "pen probing failed: %d\n", rc);
goto cleanup;
}
if (!found) {
hid_warn(hdev, "pen parameters not found");
uclogic_params_init_invalid(&p);
}
break;
}
case VID_PID(USB_VENDOR_ID_UCLOGIC,
USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_81):
case VID_PID(USB_VENDOR_ID_UCLOGIC,
Expand Down
51 changes: 51 additions & 0 deletions hid-uclogic-rdesc.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,57 @@ const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = {
const size_t uclogic_rdesc_xppen_deco01_frame_size =
sizeof(uclogic_rdesc_xppen_deco01_frame_arr);

/* Fixed Mast10 report descriptor, interface 0 (stylus) */
__u8 uclogic_rdesc_mast10_fixed0_arr[] = {
0x05, 0x0D, /* Usage Page (Digitizer), */
0x09, 0x02, /* Usage (Pen), */
0xA1, 0x01, /* Collection (Application), */
0x85, 0x07, /* Report ID (7), */
0x09, 0x20, /* Usage (Stylus), */
0xA0, /* Collection (Physical), */
0x14, /* Logical Minimum (0), */
0x25, 0x01, /* Logical Maximum (1), */
0x75, 0x01, /* Report Size (1), */
0x09, 0x42, /* Usage (Tip Switch), */
0x09, 0x44, /* Usage (Barrel Switch), */
0x09, 0x46, /* Usage (Tablet Pick), */
0x95, 0x03, /* Report Count (3), */
0x81, 0x02, /* Input (Variable), */
0x95, 0x03, /* Report Count (3), */
0x81, 0x03, /* Input (Constant, Variable), */
0x09, 0x32, /* Usage (In Range), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x02, /* Input (Variable), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x03, /* Input (Constant, Variable), */
0x75, 0x10, /* Report Size (16), */
0x95, 0x01, /* Report Count (1), */
0xA4, /* Push, */
0x05, 0x01, /* Usage Page (Desktop), */
0x65, 0x13, /* Unit (Inch), */
0x55, 0xFD, /* Unit Exponent (-3), */
0x34, /* Physical Minimum (0), */
0x09, 0x30, /* Usage (X), */
0x26, 0xBE, 0x54, /* Logical Maximum (21694), */
0x46, 0x5D, 0x21, /* Physical Maximum (8541), */
0x81, 0x02, /* Input (Variable), */
0x09, 0x31, /* Usage (Y), */
0x26, 0xF6, 0x34, /* Logical Maximum (13558), */
0x46, 0xDA, 0x14, /* Physical Maximum (5338), */
0x81, 0x02, /* Input (Variable), */
0xB4, /* Pop, */
0x09, 0x30, /* Usage (Tip Pressure), */
0x26, 0xFF, 0x07, /* Logical Maximum (2047), */
0x81, 0x02, /* Input (Variable), */
0x75, 0x10, /* Report Size (16), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x03, /* Input (Constant, Variable), */
0xC0, /* End Collection, */
0xC0 /* End Collection */
};
const size_t uclogic_rdesc_mast10_fixed0_size =
sizeof(uclogic_rdesc_mast10_fixed0_arr);

/**
* uclogic_rdesc_template_apply() - apply report descriptor parameters to a
* report descriptor template, creating a report descriptor. Copies the
Expand Down
7 changes: 7 additions & 0 deletions hid-uclogic-rdesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,11 @@ extern const size_t uclogic_rdesc_ugee_g5_frame_size;
/* Least-significant bit of Ugee G5 frame rotary encoder state */
#define UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB 38

/* Size of the original descriptors of Mast10 tablet */
#define UCLOGIC_RDESC_MAST10_ORIG0_SIZE 192

/* Fixed report descriptor for Mast10 tablet */
extern __u8 uclogic_rdesc_mast10_fixed0_arr[];
extern const size_t uclogic_rdesc_mast10_fixed0_size;

#endif /* _HID_UCLOGIC_RDESC_H */