2022-10-29 16:31:47

by José Expósito

[permalink] [raw]
Subject: [PATCH v3 0/2] Add support for XP-PEN Deco LW

v1 -> v2: https://lore.kernel.org/linux-input/20221028081656.GA19766@elementary/T/

- Barnabás Pőcze: Use strstarts() instead of a custom implementation

v2 -> v3: https://lore.kernel.org/linux-input/20221029145511.GA7941@elementary/T/

- Mia Kanashi: When using the USB dongle, do not fetch battery until
the tablet is paired

José Expósito (2):
HID: input: do not query XP-PEN Deco LW battery
HID: uclogic: Add support for XP-PEN Deco LW

drivers/hid/hid-input.c | 6 +++
drivers/hid/hid-uclogic-params.c | 73 ++++++++++++++++++++++++++++++++
drivers/hid/hid-uclogic-rdesc.c | 34 +++++++++++++++
drivers/hid/hid-uclogic-rdesc.h | 7 +++
4 files changed, 120 insertions(+)

--
2.25.1



2022-10-29 16:41:54

by José Expósito

[permalink] [raw]
Subject: [PATCH v3 2/2] HID: uclogic: Add support for XP-PEN Deco LW

The XP-PEN Deco LW is a UGEE v2 device with a frame with 8 buttons.
Its pen has 2 buttons, supports tilt and pressure.

It can be connected by USB cable or using a USB Bluetooth dongle to use
it in wireless mode. When it is connected using the dongle, the device
battery is used to power it.

Its vendor, product and version are identical to the Deco L. The only
difference reported by its firmware is the product name.
In order to add support for battery reporting, add a new HID descriptor
and a quirk to detect the wireless version of the tablet.

Link: https://github.com/DIGImend/digimend-kernel-drivers/issues/635
Tested-by: Mia Kanashi <[email protected]>
Tested-by: Andreas Grosse <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-uclogic-params.c | 73 ++++++++++++++++++++++++++++++++
drivers/hid/hid-uclogic-rdesc.c | 34 +++++++++++++++
drivers/hid/hid-uclogic-rdesc.h | 7 +++
3 files changed, 114 insertions(+)

diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
index 34fa991e6267..cd1233d7e253 100644
--- a/drivers/hid/hid-uclogic-params.c
+++ b/drivers/hid/hid-uclogic-params.c
@@ -18,6 +18,7 @@
#include "usbhid/usbhid.h"
#include "hid-ids.h"
#include <linux/ctype.h>
+#include <linux/string.h>
#include <asm/unaligned.h>

/**
@@ -1211,6 +1212,69 @@ static int uclogic_params_ugee_v2_init_frame_mouse(struct uclogic_params *p)
return rc;
}

+/**
+ * uclogic_params_ugee_v2_has_battery() - check whether a UGEE v2 device has
+ * battery or not.
+ * @hdev: The HID device of the tablet interface.
+ *
+ * Returns:
+ * True if the device has battery, false otherwise.
+ */
+static bool uclogic_params_ugee_v2_has_battery(struct hid_device *hdev)
+{
+ /* The XP-PEN Deco LW vendor, product and version are identical to the
+ * Deco L. The only difference reported by their firmware is the product
+ * name. Add a quirk to support battery reporting on the wireless
+ * version.
+ */
+ if (hdev->vendor == USB_VENDOR_ID_UGEE &&
+ hdev->product == USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) {
+ struct usb_device *udev = hid_to_usb_dev(hdev);
+
+ if (strstarts(udev->product, "Deco LW"))
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * uclogic_params_ugee_v2_init_battery() - initialize UGEE v2 battery reporting.
+ * @hdev: The HID device of the tablet interface, cannot be NULL.
+ * @p: Parameters to fill in, cannot be NULL.
+ *
+ * Returns:
+ * Zero, if successful. A negative errno code on error.
+ */
+static int uclogic_params_ugee_v2_init_battery(struct hid_device *hdev,
+ struct uclogic_params *p)
+{
+ int rc = 0;
+
+ if (!hdev || !p)
+ return -EINVAL;
+
+ /* Some tablets contain invalid characters in hdev->uniq, throwing a
+ * "hwmon: '<name>' is not a valid name attribute, please fix" error.
+ * Use the device vendor and product IDs instead.
+ */
+ snprintf(hdev->uniq, sizeof(hdev->uniq), "%x-%x", hdev->vendor,
+ hdev->product);
+
+ rc = uclogic_params_frame_init_with_desc(&p->frame_list[1],
+ uclogic_rdesc_ugee_v2_battery_template_arr,
+ uclogic_rdesc_ugee_v2_battery_template_size,
+ UCLOGIC_RDESC_UGEE_V2_BATTERY_ID);
+ if (rc)
+ return rc;
+
+ p->frame_list[1].suffix = "Battery";
+ p->pen.subreport_list[1].value = 0xf2;
+ p->pen.subreport_list[1].id = UCLOGIC_RDESC_UGEE_V2_BATTERY_ID;
+
+ return rc;
+}
+
/**
* uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
* discovering their parameters.
@@ -1334,6 +1398,15 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
if (rc)
goto cleanup;

+ /* Initialize the battery interface*/
+ if (uclogic_params_ugee_v2_has_battery(hdev)) {
+ rc = uclogic_params_ugee_v2_init_battery(hdev, &p);
+ if (rc) {
+ hid_err(hdev, "error initializing battery: %d\n", rc);
+ goto cleanup;
+ }
+ }
+
output:
/* Output parameters */
memcpy(params, &p, sizeof(*params));
diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
index 4bd54c4fb5b0..6524b4b61b25 100644
--- a/drivers/hid/hid-uclogic-rdesc.c
+++ b/drivers/hid/hid-uclogic-rdesc.c
@@ -1035,6 +1035,40 @@ const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[] = {
const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size =
sizeof(uclogic_rdesc_ugee_v2_frame_mouse_template_arr);

+/* Fixed report descriptor template for UGEE v2 battery reports */
+const __u8 uclogic_rdesc_ugee_v2_battery_template_arr[] = {
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x07, /* Usage (Keypad), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, UCLOGIC_RDESC_UGEE_V2_BATTERY_ID,
+ /* Report ID, */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x05, 0x84, /* Usage Page (Power Device), */
+ 0x05, 0x85, /* Usage Page (Battery System), */
+ 0x09, 0x65, /* Usage Page (AbsoluteStateOfCharge), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x26, 0xff, 0x00, /* Logical Maximum (255), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x09, 0x44, /* Usage Page (Charging), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x07, /* Report Count (7), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x07, /* Report Count (7), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0xC0 /* End Collection */
+};
+const size_t uclogic_rdesc_ugee_v2_battery_template_size =
+ sizeof(uclogic_rdesc_ugee_v2_battery_template_arr);
+
/* Fixed report descriptor for Ugee EX07 frame */
const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
0x05, 0x01, /* Usage Page (Desktop), */
diff --git a/drivers/hid/hid-uclogic-rdesc.h b/drivers/hid/hid-uclogic-rdesc.h
index 0502a0656496..a1f78c07293f 100644
--- a/drivers/hid/hid-uclogic-rdesc.h
+++ b/drivers/hid/hid-uclogic-rdesc.h
@@ -161,6 +161,9 @@ extern const size_t uclogic_rdesc_v2_frame_dial_size;
/* Device ID byte offset in v2 frame dial reports */
#define UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE 0x4

+/* Report ID for tweaked UGEE v2 battery reports */
+#define UCLOGIC_RDESC_UGEE_V2_BATTERY_ID 0xba
+
/* Fixed report descriptor template for UGEE v2 pen reports */
extern const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[];
extern const size_t uclogic_rdesc_ugee_v2_pen_template_size;
@@ -177,6 +180,10 @@ extern const size_t uclogic_rdesc_ugee_v2_frame_dial_template_size;
extern const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[];
extern const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size;

+/* Fixed report descriptor template for UGEE v2 battery reports */
+extern const __u8 uclogic_rdesc_ugee_v2_battery_template_arr[];
+extern const size_t uclogic_rdesc_ugee_v2_battery_template_size;
+
/* Fixed report descriptor for Ugee EX07 frame */
extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
extern const size_t uclogic_rdesc_ugee_ex07_frame_size;
--
2.25.1


2022-10-29 17:14:07

by José Expósito

[permalink] [raw]
Subject: [PATCH v3 1/2] HID: input: do not query XP-PEN Deco LW battery

The XP-PEN Deco LW drawing tablet can be connected by USB cable or using
a USB Bluetooth dongle. When it is connected using the dongle, there
might be a small delay until the tablet is paired with the dongle.

Fetching the device battery during this delay results in random battery
percentage values.

Add a quirk to avoid actively querying the battery percentage and wait
for the device to report it on its own.

Reported-by: Mia Kanashi <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-input.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 859aeb07542e..d728a94c642e 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -340,6 +340,7 @@ static enum power_supply_property hidinput_battery_props[] = {
#define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */
#define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */
#define HID_BATTERY_QUIRK_IGNORE (1 << 2) /* completely ignore the battery */
+#define HID_BATTERY_QUIRK_AVOID_QUERY (1 << 3) /* do not query the battery */

static const struct hid_device_id hid_battery_quirks[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
@@ -373,6 +374,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
HID_BATTERY_QUIRK_IGNORE },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L),
+ HID_BATTERY_QUIRK_AVOID_QUERY },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15),
HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100),
@@ -554,6 +557,9 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
field->physical == HID_DG_STYLUS;

+ if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY)
+ dev->battery_avoid_query = true;
+
dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
if (IS_ERR(dev->battery)) {
error = PTR_ERR(dev->battery);
--
2.25.1


2022-10-29 18:14:34

by Mia Kanashi

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] HID: input: do not query XP-PEN Deco LW battery

On 29 October 2022 19:12:39 EEST, "José Expósito" <[email protected]> wrote:
>The XP-PEN Deco LW drawing tablet can be connected by USB cable or using
>a USB Bluetooth dongle. When it is connected using the dongle, there
>might be a small delay until the tablet is paired with the dongle.
>
>Fetching the device battery during this delay results in random battery
>percentage values.
>
>Add a quirk to avoid actively querying the battery percentage and wait
>for the device to report it on its own.
>
>Reported-by: Mia Kanashi <[email protected]>
>Signed-off-by: José Expósito <[email protected]>
>---
> drivers/hid/hid-input.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
>diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
>index 859aeb07542e..d728a94c642e 100644
>--- a/drivers/hid/hid-input.c
>+++ b/drivers/hid/hid-input.c
>@@ -340,6 +340,7 @@ static enum power_supply_property hidinput_battery_props[] = {
> #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */
> #define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */
> #define HID_BATTERY_QUIRK_IGNORE (1 << 2) /* completely ignore the battery */
>+#define HID_BATTERY_QUIRK_AVOID_QUERY (1 << 3) /* do not query the battery */
>
> static const struct hid_device_id hid_battery_quirks[] = {
> { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
>@@ -373,6 +374,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
> HID_BATTERY_QUIRK_IGNORE },
> { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
> HID_BATTERY_QUIRK_IGNORE },
>+ { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L),
>+ HID_BATTERY_QUIRK_AVOID_QUERY },
> { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15),
> HID_BATTERY_QUIRK_IGNORE },
> { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100),
>@@ -554,6 +557,9 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
> dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
> field->physical == HID_DG_STYLUS;
>
>+ if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY)
>+ dev->battery_avoid_query = true;
>+
> dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
> if (IS_ERR(dev->battery)) {
> error = PTR_ERR(dev->battery);

I've tested this patch and now power supply status is correctly set to Unknown and capacity is set to 0 initially.

Just a note that that issue occured not only with the dongle, but a cable also.
It seems that tablet just doesn't respond to the query.

Thank you for the work!

2022-10-29 18:47:36

by José Expósito

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] HID: input: do not query XP-PEN Deco LW battery

Hi!

On Sat, Oct 29, 2022 at 08:34:46PM +0300, Mia Kanashi wrote:
> On 29 October 2022 19:12:39 EEST, "Jos? Exp?sito" <[email protected]> wrote:
> >The XP-PEN Deco LW drawing tablet can be connected by USB cable or using
> >a USB Bluetooth dongle. When it is connected using the dongle, there
> >might be a small delay until the tablet is paired with the dongle.
> >
> >Fetching the device battery during this delay results in random battery
> >percentage values.
> >
> >Add a quirk to avoid actively querying the battery percentage and wait
> >for the device to report it on its own.
> >
> >Reported-by: Mia Kanashi <[email protected]>
> >Signed-off-by: Jos? Exp?sito <[email protected]>
> >
> > [...]
>
> I've tested this patch and now power supply status is correctly set to Unknown and capacity is set to 0 initially.
>
> Just a note that that issue occured not only with the dongle, but a cable also.
> It seems that tablet just doesn't respond to the query.
>
> Thank you for the work!

Thanks a lot for testing it, I'm glad it's working :D

Jose

2022-11-04 13:24:10

by Jiri Kosina

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] HID: input: do not query XP-PEN Deco LW battery

On Sat, 29 Oct 2022, Mia Kanashi wrote:

> >The XP-PEN Deco LW drawing tablet can be connected by USB cable or using
> >a USB Bluetooth dongle. When it is connected using the dongle, there
> >might be a small delay until the tablet is paired with the dongle.
> >
> >Fetching the device battery during this delay results in random battery
> >percentage values.
> >
> >Add a quirk to avoid actively querying the battery percentage and wait
> >for the device to report it on its own.
> >
> >Reported-by: Mia Kanashi <[email protected]>
> >Signed-off-by: José Expósito <[email protected]>

[ ... snip ... ]

> I've tested this patch and now power supply status is correctly set to
> Unknown and capacity is set to 0 initially.
>
> Just a note that that issue occured not only with the dongle, but a
> cable also. It seems that tablet just doesn't respond to the query.
>
> Thank you for the work!

Based on this, can I assume that I can turn

Reported-by: Mia Kanashi <[email protected]>

into

Reported-and-tested-by: Mia Kanashi <[email protected]>

for the final version?

Thanks,

--
Jiri Kosina
SUSE Labs


2022-11-04 15:26:50

by Jiri Kosina

[permalink] [raw]
Subject: Re: [PATCH v3 0/2] Add support for XP-PEN Deco LW

On Sat, 29 Oct 2022, José Expósito wrote:

> v1 -> v2: https://lore.kernel.org/linux-input/20221028081656.GA19766@elementary/T/
>
> - Barnabás Pőcze: Use strstarts() instead of a custom implementation
>
> v2 -> v3: https://lore.kernel.org/linux-input/20221029145511.GA7941@elementary/T/
>
> - Mia Kanashi: When using the USB dongle, do not fetch battery until
> the tablet is paired
>
> José Expósito (2):
> HID: input: do not query XP-PEN Deco LW battery
> HID: uclogic: Add support for XP-PEN Deco LW
>
> drivers/hid/hid-input.c | 6 +++
> drivers/hid/hid-uclogic-params.c | 73 ++++++++++++++++++++++++++++++++
> drivers/hid/hid-uclogic-rdesc.c | 34 +++++++++++++++
> drivers/hid/hid-uclogic-rdesc.h | 7 +++
> 4 files changed, 120 insertions(+)

Now in hid.git#for-6.2/uclogic.

--
Jiri Kosina
SUSE Labs


2022-11-04 16:16:00

by Mia Kanashi

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] HID: input: do not query XP-PEN Deco LW battery

On 4 November 2022 15:13:34 EET, Jiri Kosina <[email protected]> wrote:
>Based on this, can I assume that I can turn
>
> Reported-by: Mia Kanashi <[email protected]>
>
>into
>
> Reported-and-tested-by: Mia Kanashi <[email protected]>
>
>for the final version?
>
>Thanks,

Yes, but maintainer docs don't recommend using combined tags. :)

Please do not use combined tags, e.g. Reported-and-tested-by,
as they just complicate automated extraction of tags.

link: https://www.kernel.org/doc/html/latest/process/maintainer-tip.html?highlight=Reported-and-tested-by#ordering-of-commit-tags

2022-11-04 17:06:41

by José Expósito

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] HID: input: do not query XP-PEN Deco LW battery

On Fri, Nov 04, 2022 at 02:13:34PM +0100, Jiri Kosina wrote:
> On Sat, 29 Oct 2022, Mia Kanashi wrote:
>
> > >The XP-PEN Deco LW drawing tablet can be connected by USB cable or using
> > >a USB Bluetooth dongle. When it is connected using the dongle, there
> > >might be a small delay until the tablet is paired with the dongle.
> > >
> > >Fetching the device battery during this delay results in random battery
> > >percentage values.
> > >
> > >Add a quirk to avoid actively querying the battery percentage and wait
> > >for the device to report it on its own.
> > >
> > >Reported-by: Mia Kanashi <[email protected]>
> > >Signed-off-by: José Expósito <[email protected]>
>
> [ ... snip ... ]
>
> > I've tested this patch and now power supply status is correctly set to
> > Unknown and capacity is set to 0 initially.
> >
> > Just a note that that issue occured not only with the dongle, but a
> > cable also. It seems that tablet just doesn't respond to the query.
> >
> > Thank you for the work!
>
> Based on this, can I assume that I can turn
>
> Reported-by: Mia Kanashi <[email protected]>
>
> into
>
> Reported-and-tested-by: Mia Kanashi <[email protected]>
>
> for the final version?
>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
>

Thanks for adding the tags and reviewing and merging the patches Jiří!

Jose