mirror of https://github.com/torvalds/linux.git
HID: uclogic: Add support for the XP-PEN Artist 24 Pro
The tablet is similar to the 22R Pro, but with a few annoying differences. Its descriptors are bigger because of the tablet's split coordinate system, I guess it's just that large. Thankfully, this is easy enough to support as all we have to do is shift bytes around. To help code re-use, I changed the signature of uclogic_params_init_ugee_xppen_pro to accept a pen descriptor so we didn't create yet-another initialization function. I have been testing this locally for a month or so and it works great, and also corroborated this with a few other testers. Since this touches my 22R Pro code, I have tested and checked that it didn't regress that device. Signed-off-by: Joshua Goins <josh@redstrate.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
This commit is contained in:
parent
54ba6d9b13
commit
ee35448c89
|
|
@ -1416,6 +1416,7 @@
|
|||
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW 0x0933
|
||||
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078
|
||||
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO 0x091b
|
||||
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_24_PRO 0x092d
|
||||
#define USB_DEVICE_ID_UGEE_TABLET_G5 0x0074
|
||||
#define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071
|
||||
#define USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720 0x0055
|
||||
|
|
|
|||
|
|
@ -362,6 +362,23 @@ static int uclogic_raw_event_pen(struct uclogic_drvdata *drvdata,
|
|||
data[8] = pressure_low_byte;
|
||||
data[9] = pressure_high_byte;
|
||||
}
|
||||
if (size == 12 && pen->fragmented_hires2) {
|
||||
// 00 00 when on the left side, 01 00 in the right
|
||||
// we move these to the end of the x coord (u16) to create a correct x coord (u32)
|
||||
u8 lsb_low_byte = data[10];
|
||||
u8 lsb_high_byte = data[11];
|
||||
|
||||
// shift everything right by 2 bytes, to make space for the moved lsb
|
||||
data[11] = data[9];
|
||||
data[10] = data[8];
|
||||
data[9] = data[7];
|
||||
data[8] = data[6];
|
||||
data[7] = data[5];
|
||||
data[6] = data[4];
|
||||
|
||||
data[4] = lsb_low_byte;
|
||||
data[5] = lsb_high_byte;
|
||||
}
|
||||
/* If we need to emulate in-range detection */
|
||||
if (pen->inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE) {
|
||||
/* Set in-range bit */
|
||||
|
|
@ -604,6 +621,8 @@ static const struct hid_device_id uclogic_devices[] = {
|
|||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_24_PRO) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, uclogic_devices);
|
||||
|
|
|
|||
|
|
@ -1123,6 +1123,9 @@ static int uclogic_params_parse_ugee_v2_desc(const __u8 *str_desc,
|
|||
return -EINVAL;
|
||||
|
||||
pen_x_lm = get_unaligned_le16(str_desc + 2);
|
||||
if (str_desc_size > 12)
|
||||
pen_x_lm += (u8)str_desc[12] << 16;
|
||||
|
||||
pen_y_lm = get_unaligned_le16(str_desc + 4);
|
||||
frame_num_buttons = str_desc[6];
|
||||
*frame_type = str_desc[7];
|
||||
|
|
@ -1532,7 +1535,7 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
|
|||
}
|
||||
|
||||
/*
|
||||
* uclogic_params_init_ugee_xppen_pro_22r() - Initializes a UGEE XP-Pen Pro 22R tablet device.
|
||||
* uclogic_params_init_ugee_xppen_pro() - Initializes a UGEE XP-Pen Pro tablet device.
|
||||
*
|
||||
* @hdev: The HID device of the tablet interface to initialize and get
|
||||
* parameters from. Cannot be NULL.
|
||||
|
|
@ -1543,15 +1546,17 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
|
|||
* Returns:
|
||||
* Zero, if successful. A negative errno code on error.
|
||||
*/
|
||||
static int uclogic_params_init_ugee_xppen_pro_22r(struct uclogic_params *params,
|
||||
struct hid_device *hdev,
|
||||
const u8 rdesc_frame_arr[],
|
||||
const size_t rdesc_frame_size)
|
||||
static int uclogic_params_init_ugee_xppen_pro(struct uclogic_params *params,
|
||||
struct hid_device *hdev,
|
||||
const u8 rdesc_pen_arr[],
|
||||
const size_t rdesc_pen_size,
|
||||
const u8 rdesc_frame_arr[],
|
||||
const size_t rdesc_frame_size,
|
||||
size_t str_desc_len)
|
||||
{
|
||||
int rc = 0;
|
||||
struct usb_interface *iface;
|
||||
__u8 bInterfaceNumber;
|
||||
const int str_desc_len = 12;
|
||||
u8 *str_desc = NULL;
|
||||
__u8 *rdesc_pen = NULL;
|
||||
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
|
||||
|
|
@ -1614,8 +1619,8 @@ static int uclogic_params_init_ugee_xppen_pro_22r(struct uclogic_params *params,
|
|||
|
||||
/* Initialize the pen interface */
|
||||
rdesc_pen = uclogic_rdesc_template_apply(
|
||||
uclogic_rdesc_ugee_v2_pen_template_arr,
|
||||
uclogic_rdesc_ugee_v2_pen_template_size,
|
||||
rdesc_pen_arr,
|
||||
rdesc_pen_size,
|
||||
desc_params, ARRAY_SIZE(desc_params));
|
||||
if (!rdesc_pen) {
|
||||
rc = -ENOMEM;
|
||||
|
|
@ -1623,7 +1628,7 @@ static int uclogic_params_init_ugee_xppen_pro_22r(struct uclogic_params *params,
|
|||
}
|
||||
|
||||
p.pen.desc_ptr = rdesc_pen;
|
||||
p.pen.desc_size = uclogic_rdesc_ugee_v2_pen_template_size;
|
||||
p.pen.desc_size = rdesc_pen_size;
|
||||
p.pen.id = 0x02;
|
||||
p.pen.subreport_list[0].value = 0xf0;
|
||||
p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID;
|
||||
|
|
@ -1970,10 +1975,30 @@ int uclogic_params_init(struct uclogic_params *params,
|
|||
break;
|
||||
case VID_PID(USB_VENDOR_ID_UGEE,
|
||||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO):
|
||||
rc = uclogic_params_init_ugee_xppen_pro_22r(&p,
|
||||
rc = uclogic_params_init_ugee_xppen_pro(&p,
|
||||
hdev,
|
||||
uclogic_rdesc_ugee_v2_pen_template_arr,
|
||||
uclogic_rdesc_ugee_v2_pen_template_size,
|
||||
uclogic_rdesc_xppen_artist_22r_pro_frame_arr,
|
||||
uclogic_rdesc_xppen_artist_22r_pro_frame_size);
|
||||
uclogic_rdesc_xppen_artist_22r_pro_frame_size,
|
||||
12);
|
||||
if (rc != 0)
|
||||
goto cleanup;
|
||||
|
||||
break;
|
||||
case VID_PID(USB_VENDOR_ID_UGEE,
|
||||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_24_PRO):
|
||||
rc = uclogic_params_init_ugee_xppen_pro(&p,
|
||||
hdev,
|
||||
uclogic_rdesc_xppen_artist_24_pro_pen_template_arr,
|
||||
uclogic_rdesc_xppen_artist_24_pro_pen_template_size,
|
||||
uclogic_rdesc_xppen_artist_24_pro_frame_arr,
|
||||
uclogic_rdesc_xppen_artist_24_pro_frame_size,
|
||||
14);
|
||||
|
||||
// The 24 Pro has a fragmented X Coord.
|
||||
p.pen.fragmented_hires2 = true;
|
||||
|
||||
if (rc != 0)
|
||||
goto cleanup;
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,11 @@ struct uclogic_params_pen {
|
|||
* Only valid if "id" is not zero.
|
||||
*/
|
||||
bool tilt_y_flipped;
|
||||
/*
|
||||
* True, if reports include fragmented high resolution X coords.
|
||||
* This moves bytes 10-11 to the LSB of the X coordinate.
|
||||
*/
|
||||
bool fragmented_hires2;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1237,6 +1237,131 @@ const __u8 uclogic_rdesc_xppen_artist_22r_pro_frame_arr[] = {
|
|||
const size_t uclogic_rdesc_xppen_artist_22r_pro_frame_size =
|
||||
sizeof(uclogic_rdesc_xppen_artist_22r_pro_frame_arr);
|
||||
|
||||
/* Fixed report descriptor template for XP-PEN 24 Pro reports
|
||||
* Mostly identical to uclogic_rdesc_ugee_v2_pen_template_arr except that the X coordinate has to be
|
||||
* 32-bits instead of 16-bits.
|
||||
*/
|
||||
const __u8 uclogic_rdesc_xppen_artist_24_pro_pen_template_arr[] = {
|
||||
0x05, 0x0d, /* Usage Page (Digitizers), */
|
||||
0x09, 0x01, /* Usage (Digitizer), */
|
||||
0xa1, 0x01, /* Collection (Application), */
|
||||
0x85, 0x02, /* Report ID (2), */
|
||||
0x09, 0x20, /* Usage (Stylus), */
|
||||
0xa1, 0x00, /* Collection (Physical), */
|
||||
0x09, 0x42, /* Usage (Tip Switch), */
|
||||
0x09, 0x44, /* Usage (Barrel Switch), */
|
||||
0x09, 0x46, /* Usage (Tablet Pick), */
|
||||
0x75, 0x01, /* Report Size (1), */
|
||||
0x95, 0x03, /* Report Count (3), */
|
||||
0x14, /* Logical Minimum (0), */
|
||||
0x25, 0x01, /* Logical Maximum (1), */
|
||||
0x81, 0x02, /* Input (Variable), */
|
||||
0x95, 0x02, /* Report Count (2), */
|
||||
0x81, 0x03, /* Input (Constant, Variable), */
|
||||
0x09, 0x32, /* Usage (In Range), */
|
||||
0x95, 0x01, /* Report Count (1), */
|
||||
0x81, 0x02, /* Input (Variable), */
|
||||
0x95, 0x02, /* Report Count (2), */
|
||||
0x81, 0x03, /* Input (Constant, Variable), */
|
||||
0x75, 0x10, /* Report Size (16), */
|
||||
0x95, 0x01, /* Report Count (1), */
|
||||
0x35, 0x00, /* Physical Minimum (0), */
|
||||
0xa4, /* Push, */
|
||||
0x05, 0x01, /* Usage Page (Desktop), */
|
||||
0x09, 0x30, /* Usage (X), */
|
||||
0x65, 0x13, /* Unit (Inch), */
|
||||
0x55, 0x0d, /* Unit Exponent (-3), */
|
||||
0x27, UCLOGIC_RDESC_PEN_PH(X_LM),
|
||||
/* Logical Maximum (PLACEHOLDER), */
|
||||
0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
|
||||
/* Physical Maximum (PLACEHOLDER), */
|
||||
0x75, 0x20, /* Report Size (32), */
|
||||
0x81, 0x02, /* Input (Variable), */
|
||||
0x75, 0x10, /* Report Size (16), */
|
||||
0x09, 0x31, /* Usage (Y), */
|
||||
0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
|
||||
/* Logical Maximum (PLACEHOLDER), */
|
||||
0x47, UCLOGIC_RDESC_PEN_PH(Y_PM),
|
||||
/* Physical Maximum (PLACEHOLDER), */
|
||||
0x81, 0x02, /* Input (Variable), */
|
||||
0xb4, /* Pop, */
|
||||
0x09, 0x30, /* Usage (Tip Pressure), */
|
||||
0x45, 0x00, /* Physical Maximum (0), */
|
||||
0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
|
||||
/* Logical Maximum (PLACEHOLDER), */
|
||||
0x75, 0x0D, /* Report Size (13), */
|
||||
0x95, 0x01, /* Report Count (1), */
|
||||
0x81, 0x02, /* Input (Variable), */
|
||||
0x75, 0x01, /* Report Size (1), */
|
||||
0x95, 0x03, /* Report Count (3), */
|
||||
0x81, 0x01, /* Input (Constant), */
|
||||
0x09, 0x3d, /* Usage (X Tilt), */
|
||||
0x35, 0xC3, /* Physical Minimum (-61), */
|
||||
0x45, 0x3C, /* Physical Maximum (60), */
|
||||
0x15, 0xC3, /* Logical Minimum (-61), */
|
||||
0x25, 0x3C, /* Logical Maximum (60), */
|
||||
0x75, 0x08, /* Report Size (8), */
|
||||
0x95, 0x01, /* Report Count (1), */
|
||||
0x81, 0x02, /* Input (Variable), */
|
||||
0x09, 0x3e, /* Usage (Y Tilt), */
|
||||
0x35, 0xC3, /* Physical Minimum (-61), */
|
||||
0x45, 0x3C, /* Physical Maximum (60), */
|
||||
0x15, 0xC3, /* Logical Minimum (-61), */
|
||||
0x25, 0x3C, /* Logical Maximum (60), */
|
||||
0x81, 0x02, /* Input (Variable), */
|
||||
0xc0, /* End Collection, */
|
||||
0xc0, /* End Collection */
|
||||
};
|
||||
const size_t uclogic_rdesc_xppen_artist_24_pro_pen_template_size =
|
||||
sizeof(uclogic_rdesc_xppen_artist_24_pro_pen_template_arr);
|
||||
|
||||
/* Fixed report descriptor for XP-Pen Arist 24 Pro frame */
|
||||
const __u8 uclogic_rdesc_xppen_artist_24_pro_frame_arr[] = {
|
||||
0x05, 0x01, /* Usage Page (Desktop), */
|
||||
0x09, 0x07, /* Usage (Keypad), */
|
||||
0xA1, 0x01, /* Collection (Application), */
|
||||
0x85, UCLOGIC_RDESC_V1_FRAME_ID,
|
||||
/* Report ID (Virtual report), */
|
||||
0x05, 0x0D, /* Usage Page (Digitizer), */
|
||||
0x09, 0x39, /* Usage (Tablet Function Keys), */
|
||||
0xA0, /* Collection (Physical), */
|
||||
0x14, /* Logical Minimum (0), */
|
||||
0x25, 0x01, /* Logical Maximum (1), */
|
||||
0x75, 0x01, /* Report Size (1), */
|
||||
0x95, 0x08, /* Report Count (8), */
|
||||
0x81, 0x01, /* Input (Constant), */
|
||||
0x05, 0x09, /* Usage Page (Button), */
|
||||
0x19, 0x01, /* Usage Minimum (01h), */
|
||||
0x29, 0x14, /* Usage Maximum (14h), */
|
||||
0x95, 0x14, /* Report Count (20), */
|
||||
0x81, 0x02, /* Input (Variable), */
|
||||
0x95, 0x14, /* Report Count (20), */
|
||||
0x81, 0x01, /* Input (Constant), */
|
||||
0x05, 0x01, /* Usage Page (Desktop), */
|
||||
0x09, 0x38, /* Usage (Wheel), */
|
||||
0x75, 0x08, /* Report Size (8), */
|
||||
0x95, 0x01, /* Report Count (1), */
|
||||
0x15, 0xFF, /* Logical Minimum (-1), */
|
||||
0x25, 0x08, /* Logical Maximum (8), */
|
||||
0x81, 0x06, /* Input (Variable, Relative), */
|
||||
0x05, 0x0C, /* Usage Page (Consumer Devices), */
|
||||
0x0A, 0x38, 0x02, /* Usage (AC PAN), */
|
||||
0x95, 0x01, /* Report Count (1), */
|
||||
0x81, 0x06, /* Input (Variable, Relative), */
|
||||
0x26, 0xFF, 0x00, /* Logical Maximum (255), */
|
||||
0x75, 0x08, /* Report Size (8), */
|
||||
0x95, 0x01, /* Report Count (1), */
|
||||
0x81, 0x02, /* Input (Variable), */
|
||||
0x75, 0x01, /* Report Size (1), */
|
||||
0x95, 16, /* Report Count (16), */
|
||||
0x81, 0x01, /* Input (Constant), */
|
||||
0xC0, /* End Collection */
|
||||
0xC0, /* End Collection */
|
||||
};
|
||||
|
||||
const size_t uclogic_rdesc_xppen_artist_24_pro_frame_size =
|
||||
sizeof(uclogic_rdesc_xppen_artist_24_pro_frame_arr);
|
||||
|
||||
/**
|
||||
* uclogic_rdesc_template_apply() - apply report descriptor parameters to a
|
||||
* report descriptor template, creating a report descriptor. Copies the
|
||||
|
|
|
|||
|
|
@ -214,4 +214,12 @@ extern const size_t uclogic_rdesc_ugee_g5_frame_size;
|
|||
extern const __u8 uclogic_rdesc_xppen_artist_22r_pro_frame_arr[];
|
||||
extern const size_t uclogic_rdesc_xppen_artist_22r_pro_frame_size;
|
||||
|
||||
/* Fixed report descriptor for XP-Pen Arist 24 Pro frame */
|
||||
extern const __u8 uclogic_rdesc_xppen_artist_24_pro_pen_template_arr[];
|
||||
extern const size_t uclogic_rdesc_xppen_artist_24_pro_pen_template_size;
|
||||
|
||||
/* Fixed report descriptor for XP-Pen Arist 24 Pro frame */
|
||||
extern const __u8 uclogic_rdesc_xppen_artist_24_pro_frame_arr[];
|
||||
extern const size_t uclogic_rdesc_xppen_artist_24_pro_frame_size;
|
||||
|
||||
#endif /* _HID_UCLOGIC_RDESC_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue