378 lines
13 KiB
Diff
378 lines
13 KiB
Diff
Subject: [PATCH] HID: uclogic: Add support for XP-PEN Artist 22R Pro
|
|
---
|
|
Index: drivers/hid/hid-ids.h
|
|
IDEA additional info:
|
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
|
<+>UTF-8
|
|
===================================================================
|
|
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
|
|
--- a/drivers/hid/hid-ids.h (revision 98f7e32f20d28ec452afb208f9cffc08448a2652)
|
|
+++ b/drivers/hid/hid-ids.h (revision ce3bdd7411f42c49333a387101a8fc95557d624a)
|
|
@@ -1364,6 +1364,7 @@
|
|
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S 0x0909
|
|
#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_TABLET_G5 0x0074
|
|
#define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071
|
|
#define USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720 0x0055
|
|
Index: drivers/hid/hid-uclogic-core.c
|
|
IDEA additional info:
|
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
|
<+>UTF-8
|
|
===================================================================
|
|
diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
|
|
--- a/drivers/hid/hid-uclogic-core.c (revision 98f7e32f20d28ec452afb208f9cffc08448a2652)
|
|
+++ b/drivers/hid/hid-uclogic-core.c (revision ce3bdd7411f42c49333a387101a8fc95557d624a)
|
|
@@ -62,6 +62,30 @@
|
|
return rdesc;
|
|
}
|
|
|
|
+/* Buttons considered valid tablet pad inputs. */
|
|
+static const unsigned int uclogic_extra_input_mapping[] = {
|
|
+ BTN_0,
|
|
+ BTN_1,
|
|
+ BTN_2,
|
|
+ BTN_3,
|
|
+ BTN_4,
|
|
+ BTN_5,
|
|
+ BTN_6,
|
|
+ BTN_7,
|
|
+ BTN_8,
|
|
+ BTN_RIGHT,
|
|
+ BTN_MIDDLE,
|
|
+ BTN_SIDE,
|
|
+ BTN_EXTRA,
|
|
+ BTN_FORWARD,
|
|
+ BTN_BACK,
|
|
+ BTN_B,
|
|
+ BTN_A,
|
|
+ BTN_BASE,
|
|
+ BTN_BASE2,
|
|
+ BTN_X
|
|
+};
|
|
+
|
|
static int uclogic_input_mapping(struct hid_device *hdev,
|
|
struct hid_input *hi,
|
|
struct hid_field *field,
|
|
@@ -72,9 +96,27 @@
|
|
struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
|
|
struct uclogic_params *params = &drvdata->params;
|
|
|
|
- /* Discard invalid pen usages */
|
|
- if (params->pen.usage_invalid && (field->application == HID_DG_PEN))
|
|
- return -1;
|
|
+ if (field->application == HID_GD_KEYPAD) {
|
|
+ /*
|
|
+ * Remap input buttons to sensible ones that are not invalid.
|
|
+ * This only affects previous behavior for devices with more than ten or so buttons.
|
|
+ */
|
|
+ const int key = (usage->hid & HID_USAGE) - 1;
|
|
+
|
|
+ if (key < ARRAY_SIZE(uclogic_extra_input_mapping)) {
|
|
+ hid_map_usage(hi,
|
|
+ usage,
|
|
+ bit,
|
|
+ max,
|
|
+ EV_KEY,
|
|
+ uclogic_extra_input_mapping[key]);
|
|
+ return 1;
|
|
+ }
|
|
+ } else if (field->application == HID_DG_PEN) {
|
|
+ /* Discard invalid pen usages */
|
|
+ if (params->pen.usage_invalid)
|
|
+ return -1;
|
|
+ }
|
|
|
|
/* Let hid-core decide what to do */
|
|
return 0;
|
|
@@ -406,8 +448,22 @@
|
|
|
|
/* If need to, and can, transform the bitmap dial reports */
|
|
if (frame->bitmap_dial_byte > 0 && frame->bitmap_dial_byte < size) {
|
|
- if (data[frame->bitmap_dial_byte] == 2)
|
|
+ switch (data[frame->bitmap_dial_byte]) {
|
|
+ case 2:
|
|
data[frame->bitmap_dial_byte] = -1;
|
|
+ break;
|
|
+
|
|
+ /* Everything below here is for tablets that shove multiple dials into 1 byte */
|
|
+ case 16:
|
|
+ data[frame->bitmap_dial_byte] = 0;
|
|
+ data[frame->bitmap_second_dial_destination_byte] = 1;
|
|
+ break;
|
|
+
|
|
+ case 32:
|
|
+ data[frame->bitmap_dial_byte] = 0;
|
|
+ data[frame->bitmap_second_dial_destination_byte] = -1;
|
|
+ break;
|
|
+ }
|
|
}
|
|
|
|
return 0;
|
|
@@ -545,6 +601,8 @@
|
|
.driver_data = UCLOGIC_MOUSE_FRAME_QUIRK | UCLOGIC_BATTERY_QUIRK },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
|
USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06) },
|
|
+ { HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
|
+ USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO) },
|
|
{ }
|
|
};
|
|
MODULE_DEVICE_TABLE(hid, uclogic_devices);
|
|
Index: drivers/hid/hid-uclogic-params.c
|
|
IDEA additional info:
|
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
|
<+>UTF-8
|
|
===================================================================
|
|
diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
|
|
--- a/drivers/hid/hid-uclogic-params.c (revision 98f7e32f20d28ec452afb208f9cffc08448a2652)
|
|
+++ b/drivers/hid/hid-uclogic-params.c (revision ce3bdd7411f42c49333a387101a8fc95557d624a)
|
|
@@ -103,6 +103,8 @@
|
|
frame->touch_flip_at);
|
|
hid_dbg(hdev, "\t\t.bitmap_dial_byte = %u\n",
|
|
frame->bitmap_dial_byte);
|
|
+ hid_dbg(hdev, "\t\t.bitmap_second_dial_destination_byte = %u\n",
|
|
+ frame->bitmap_second_dial_destination_byte);
|
|
}
|
|
|
|
/**
|
|
@@ -1518,6 +1520,126 @@
|
|
goto cleanup;
|
|
}
|
|
|
|
+output:
|
|
+ /* Output parameters */
|
|
+ memcpy(params, &p, sizeof(*params));
|
|
+ memset(&p, 0, sizeof(p));
|
|
+ rc = 0;
|
|
+cleanup:
|
|
+ kfree(str_desc);
|
|
+ uclogic_params_cleanup(&p);
|
|
+ return rc;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * uclogic_params_init_ugee_xppen_pro_22r() - Initializes a UGEE XP-Pen Pro 22R tablet device.
|
|
+ *
|
|
+ * @hdev: The HID device of the tablet interface to initialize and get
|
|
+ * parameters from. Cannot be NULL.
|
|
+ * @params: Parameters to fill in (to be cleaned with
|
|
+ * uclogic_params_cleanup()). Not modified in case of error.
|
|
+ * Cannot be NULL.
|
|
+ *
|
|
+ * 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)
|
|
+{
|
|
+ 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];
|
|
+ enum uclogic_params_frame_type frame_type;
|
|
+ /* The resulting parameters (noop) */
|
|
+ struct uclogic_params p = {0, };
|
|
+
|
|
+ if (!hdev || !params) {
|
|
+ rc = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ iface = to_usb_interface(hdev->dev.parent);
|
|
+ bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
|
|
+
|
|
+ /* Ignore non-pen interfaces */
|
|
+ if (bInterfaceNumber != 2) {
|
|
+ uclogic_params_init_invalid(&p);
|
|
+ goto output;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Initialize the interface by sending magic data.
|
|
+ * This magic data is the same as other UGEE v2 tablets.
|
|
+ */
|
|
+ rc = uclogic_probe_interface(hdev,
|
|
+ uclogic_ugee_v2_probe_arr,
|
|
+ uclogic_ugee_v2_probe_size,
|
|
+ uclogic_ugee_v2_probe_endpoint);
|
|
+ if (rc) {
|
|
+ uclogic_params_init_invalid(&p);
|
|
+ goto output;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Read the string descriptor containing pen and frame parameters.
|
|
+ * These are slightly different than typical UGEE v2 devices.
|
|
+ */
|
|
+ rc = uclogic_params_get_str_desc(&str_desc, hdev, 100, str_desc_len);
|
|
+ if (rc != str_desc_len) {
|
|
+ hid_err(hdev, "failed retrieving pen and frame parameters: %d\n", rc);
|
|
+ uclogic_params_init_invalid(&p);
|
|
+ goto output;
|
|
+ }
|
|
+
|
|
+ rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len,
|
|
+ desc_params,
|
|
+ ARRAY_SIZE(desc_params),
|
|
+ &frame_type);
|
|
+ if (rc)
|
|
+ goto cleanup;
|
|
+
|
|
+ // str_desc doesn't report the correct amount of buttons, so manually fix it
|
|
+ desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 20;
|
|
+
|
|
+ kfree(str_desc);
|
|
+ str_desc = NULL;
|
|
+
|
|
+ /* Initialize the pen interface */
|
|
+ rdesc_pen = uclogic_rdesc_template_apply(
|
|
+ uclogic_rdesc_ugee_v2_pen_template_arr,
|
|
+ uclogic_rdesc_ugee_v2_pen_template_size,
|
|
+ desc_params, ARRAY_SIZE(desc_params));
|
|
+ if (!rdesc_pen) {
|
|
+ rc = -ENOMEM;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ p.pen.desc_ptr = rdesc_pen;
|
|
+ p.pen.desc_size = uclogic_rdesc_ugee_v2_pen_template_size;
|
|
+ p.pen.id = 0x02;
|
|
+ p.pen.subreport_list[0].value = 0xf0;
|
|
+ p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID;
|
|
+
|
|
+ /* Initialize the frame interface */
|
|
+ rc = uclogic_params_frame_init_with_desc(
|
|
+ &p.frame_list[0],
|
|
+ rdesc_frame_arr,
|
|
+ rdesc_frame_size,
|
|
+ UCLOGIC_RDESC_V1_FRAME_ID);
|
|
+ if (rc < 0) {
|
|
+ hid_err(hdev, "initializing frame params failed: %d\n", rc);
|
|
+ goto output;
|
|
+ }
|
|
+
|
|
+ p.frame_list[0].bitmap_dial_byte = 7;
|
|
+ p.frame_list[0].bitmap_second_dial_destination_byte = 8;
|
|
+
|
|
output:
|
|
/* Output parameters */
|
|
memcpy(params, &p, sizeof(*params));
|
|
@@ -1845,6 +1967,16 @@
|
|
uclogic_params_init_invalid(&p);
|
|
}
|
|
|
|
+ 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,
|
|
+ hdev,
|
|
+ uclogic_rdesc_xppen_artist_22r_pro_frame_arr,
|
|
+ uclogic_rdesc_xppen_artist_22r_pro_frame_size);
|
|
+ if (rc != 0)
|
|
+ goto cleanup;
|
|
+
|
|
break;
|
|
}
|
|
|
|
Index: drivers/hid/hid-uclogic-params.h
|
|
IDEA additional info:
|
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
|
<+>UTF-8
|
|
===================================================================
|
|
diff --git a/drivers/hid/hid-uclogic-params.h b/drivers/hid/hid-uclogic-params.h
|
|
--- a/drivers/hid/hid-uclogic-params.h (revision 98f7e32f20d28ec452afb208f9cffc08448a2652)
|
|
+++ b/drivers/hid/hid-uclogic-params.h (revision ce3bdd7411f42c49333a387101a8fc95557d624a)
|
|
@@ -175,6 +175,11 @@
|
|
* counterclockwise, as opposed to the normal 1 and -1.
|
|
*/
|
|
unsigned int bitmap_dial_byte;
|
|
+ /*
|
|
+ * Destination offset for the second bitmap dial byte, if the tablet
|
|
+ * supports a second dial at all.
|
|
+ */
|
|
+ unsigned int bitmap_second_dial_destination_byte;
|
|
};
|
|
|
|
/*
|
|
Index: drivers/hid/hid-uclogic-rdesc.c
|
|
IDEA additional info:
|
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
|
<+>UTF-8
|
|
===================================================================
|
|
diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
|
|
--- a/drivers/hid/hid-uclogic-rdesc.c (revision 98f7e32f20d28ec452afb208f9cffc08448a2652)
|
|
+++ b/drivers/hid/hid-uclogic-rdesc.c (revision ce3bdd7411f42c49333a387101a8fc95557d624a)
|
|
@@ -1193,6 +1193,50 @@
|
|
const size_t uclogic_rdesc_xppen_deco01_frame_size =
|
|
sizeof(uclogic_rdesc_xppen_deco01_frame_arr);
|
|
|
|
+/* Fixed report descriptor for XP-Pen Arist 22R Pro frame */
|
|
+const __u8 uclogic_rdesc_xppen_artist_22r_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), */
|
|
+ 0xC0, /* End Collection */
|
|
+ 0xC0, /* End Collection */
|
|
+};
|
|
+
|
|
+const size_t uclogic_rdesc_xppen_artist_22r_pro_frame_size =
|
|
+ sizeof(uclogic_rdesc_xppen_artist_22r_pro_frame_arr);
|
|
+
|
|
/**
|
|
* uclogic_rdesc_template_apply() - apply report descriptor parameters to a
|
|
* report descriptor template, creating a report descriptor. Copies the
|
|
Index: drivers/hid/hid-uclogic-rdesc.h
|
|
IDEA additional info:
|
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
|
<+>UTF-8
|
|
===================================================================
|
|
diff --git a/drivers/hid/hid-uclogic-rdesc.h b/drivers/hid/hid-uclogic-rdesc.h
|
|
--- a/drivers/hid/hid-uclogic-rdesc.h (revision 98f7e32f20d28ec452afb208f9cffc08448a2652)
|
|
+++ b/drivers/hid/hid-uclogic-rdesc.h (revision ce3bdd7411f42c49333a387101a8fc95557d624a)
|
|
@@ -210,4 +210,8 @@
|
|
/* Least-significant bit of Ugee G5 frame rotary encoder state */
|
|
#define UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB 38
|
|
|
|
+/* Fixed report descriptor for XP-Pen Arist 22R Pro frame */
|
|
+extern const __u8 uclogic_rdesc_xppen_artist_22r_pro_frame_arr[];
|
|
+extern const size_t uclogic_rdesc_xppen_artist_22r_pro_frame_size;
|
|
+
|
|
#endif /* _HID_UCLOGIC_RDESC_H */
|