Skip to content

Commit ab6847b

Browse files
author
Jiri Kosina
committed
Merge branch 'for-6.2/uclogic' into for-linus
- XP-PEN Deco LW support (José Expósito)
2 parents 4e6ff44 + af89dfd commit ab6847b

File tree

6 files changed

+124
-4
lines changed

6 files changed

+124
-4
lines changed

drivers/hid/hid-input.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ static enum power_supply_property hidinput_battery_props[] = {
340340
#define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */
341341
#define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */
342342
#define HID_BATTERY_QUIRK_IGNORE (1 << 2) /* completely ignore the battery */
343+
#define HID_BATTERY_QUIRK_AVOID_QUERY (1 << 3) /* do not query the battery */
343344

344345
static const struct hid_device_id hid_battery_quirks[] = {
345346
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
@@ -373,6 +374,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
373374
HID_BATTERY_QUIRK_IGNORE },
374375
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
375376
HID_BATTERY_QUIRK_IGNORE },
377+
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L),
378+
HID_BATTERY_QUIRK_AVOID_QUERY },
376379
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15),
377380
HID_BATTERY_QUIRK_IGNORE },
378381
{ 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,
554557
dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
555558
field->physical == HID_DG_STYLUS;
556559

560+
if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY)
561+
dev->battery_avoid_query = true;
562+
557563
dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
558564
if (IS_ERR(dev->battery)) {
559565
error = PTR_ERR(dev->battery);

drivers/hid/hid-uclogic-params-test.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ static void uclogic_parse_ugee_v2_desc_case_desc(struct uclogic_parse_ugee_v2_de
136136
KUNIT_ARRAY_PARAM(uclogic_parse_ugee_v2_desc, uclogic_parse_ugee_v2_desc_cases,
137137
uclogic_parse_ugee_v2_desc_case_desc);
138138

139-
static void uclogic_parse_ugee_v2_desc_test(struct kunit *test)
139+
static void hid_test_uclogic_parse_ugee_v2_desc(struct kunit *test)
140140
{
141141
int res;
142142
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
@@ -175,7 +175,7 @@ static void uclogic_parse_ugee_v2_desc_test(struct kunit *test)
175175
}
176176

177177
static struct kunit_case hid_uclogic_params_test_cases[] = {
178-
KUNIT_CASE_PARAM(uclogic_parse_ugee_v2_desc_test,
178+
KUNIT_CASE_PARAM(hid_test_uclogic_parse_ugee_v2_desc,
179179
uclogic_parse_ugee_v2_desc_gen_params),
180180
{}
181181
};

drivers/hid/hid-uclogic-params.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "usbhid/usbhid.h"
1919
#include "hid-ids.h"
2020
#include <linux/ctype.h>
21+
#include <linux/string.h>
2122
#include <asm/unaligned.h>
2223

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

1215+
/**
1216+
* uclogic_params_ugee_v2_has_battery() - check whether a UGEE v2 device has
1217+
* battery or not.
1218+
* @hdev: The HID device of the tablet interface.
1219+
*
1220+
* Returns:
1221+
* True if the device has battery, false otherwise.
1222+
*/
1223+
static bool uclogic_params_ugee_v2_has_battery(struct hid_device *hdev)
1224+
{
1225+
/* The XP-PEN Deco LW vendor, product and version are identical to the
1226+
* Deco L. The only difference reported by their firmware is the product
1227+
* name. Add a quirk to support battery reporting on the wireless
1228+
* version.
1229+
*/
1230+
if (hdev->vendor == USB_VENDOR_ID_UGEE &&
1231+
hdev->product == USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) {
1232+
struct usb_device *udev = hid_to_usb_dev(hdev);
1233+
1234+
if (strstarts(udev->product, "Deco LW"))
1235+
return true;
1236+
}
1237+
1238+
return false;
1239+
}
1240+
1241+
/**
1242+
* uclogic_params_ugee_v2_init_battery() - initialize UGEE v2 battery reporting.
1243+
* @hdev: The HID device of the tablet interface, cannot be NULL.
1244+
* @p: Parameters to fill in, cannot be NULL.
1245+
*
1246+
* Returns:
1247+
* Zero, if successful. A negative errno code on error.
1248+
*/
1249+
static int uclogic_params_ugee_v2_init_battery(struct hid_device *hdev,
1250+
struct uclogic_params *p)
1251+
{
1252+
int rc = 0;
1253+
1254+
if (!hdev || !p)
1255+
return -EINVAL;
1256+
1257+
/* Some tablets contain invalid characters in hdev->uniq, throwing a
1258+
* "hwmon: '<name>' is not a valid name attribute, please fix" error.
1259+
* Use the device vendor and product IDs instead.
1260+
*/
1261+
snprintf(hdev->uniq, sizeof(hdev->uniq), "%x-%x", hdev->vendor,
1262+
hdev->product);
1263+
1264+
rc = uclogic_params_frame_init_with_desc(&p->frame_list[1],
1265+
uclogic_rdesc_ugee_v2_battery_template_arr,
1266+
uclogic_rdesc_ugee_v2_battery_template_size,
1267+
UCLOGIC_RDESC_UGEE_V2_BATTERY_ID);
1268+
if (rc)
1269+
return rc;
1270+
1271+
p->frame_list[1].suffix = "Battery";
1272+
p->pen.subreport_list[1].value = 0xf2;
1273+
p->pen.subreport_list[1].id = UCLOGIC_RDESC_UGEE_V2_BATTERY_ID;
1274+
1275+
return rc;
1276+
}
1277+
12141278
/**
12151279
* uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
12161280
* discovering their parameters.
@@ -1334,6 +1398,15 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
13341398
if (rc)
13351399
goto cleanup;
13361400

1401+
/* Initialize the battery interface*/
1402+
if (uclogic_params_ugee_v2_has_battery(hdev)) {
1403+
rc = uclogic_params_ugee_v2_init_battery(hdev, &p);
1404+
if (rc) {
1405+
hid_err(hdev, "error initializing battery: %d\n", rc);
1406+
goto cleanup;
1407+
}
1408+
}
1409+
13371410
output:
13381411
/* Output parameters */
13391412
memcpy(params, &p, sizeof(*params));

drivers/hid/hid-uclogic-rdesc-test.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ static void uclogic_template_case_desc(struct uclogic_template_case *t,
187187
KUNIT_ARRAY_PARAM(uclogic_template, uclogic_template_cases,
188188
uclogic_template_case_desc);
189189

190-
static void uclogic_template_test(struct kunit *test)
190+
static void hid_test_uclogic_template(struct kunit *test)
191191
{
192192
__u8 *res;
193193
const struct uclogic_template_case *params = test->param_value;
@@ -203,7 +203,7 @@ static void uclogic_template_test(struct kunit *test)
203203
}
204204

205205
static struct kunit_case hid_uclogic_rdesc_test_cases[] = {
206-
KUNIT_CASE_PARAM(uclogic_template_test, uclogic_template_gen_params),
206+
KUNIT_CASE_PARAM(hid_test_uclogic_template, uclogic_template_gen_params),
207207
{}
208208
};
209209

drivers/hid/hid-uclogic-rdesc.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,40 @@ const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[] = {
10351035
const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size =
10361036
sizeof(uclogic_rdesc_ugee_v2_frame_mouse_template_arr);
10371037

1038+
/* Fixed report descriptor template for UGEE v2 battery reports */
1039+
const __u8 uclogic_rdesc_ugee_v2_battery_template_arr[] = {
1040+
0x05, 0x01, /* Usage Page (Desktop), */
1041+
0x09, 0x07, /* Usage (Keypad), */
1042+
0xA1, 0x01, /* Collection (Application), */
1043+
0x85, UCLOGIC_RDESC_UGEE_V2_BATTERY_ID,
1044+
/* Report ID, */
1045+
0x75, 0x08, /* Report Size (8), */
1046+
0x95, 0x02, /* Report Count (2), */
1047+
0x81, 0x01, /* Input (Constant), */
1048+
0x05, 0x84, /* Usage Page (Power Device), */
1049+
0x05, 0x85, /* Usage Page (Battery System), */
1050+
0x09, 0x65, /* Usage Page (AbsoluteStateOfCharge), */
1051+
0x75, 0x08, /* Report Size (8), */
1052+
0x95, 0x01, /* Report Count (1), */
1053+
0x15, 0x00, /* Logical Minimum (0), */
1054+
0x26, 0xff, 0x00, /* Logical Maximum (255), */
1055+
0x81, 0x02, /* Input (Variable), */
1056+
0x75, 0x01, /* Report Size (1), */
1057+
0x95, 0x01, /* Report Count (1), */
1058+
0x15, 0x00, /* Logical Minimum (0), */
1059+
0x25, 0x01, /* Logical Maximum (1), */
1060+
0x09, 0x44, /* Usage Page (Charging), */
1061+
0x81, 0x02, /* Input (Variable), */
1062+
0x95, 0x07, /* Report Count (7), */
1063+
0x81, 0x01, /* Input (Constant), */
1064+
0x75, 0x08, /* Report Size (8), */
1065+
0x95, 0x07, /* Report Count (7), */
1066+
0x81, 0x01, /* Input (Constant), */
1067+
0xC0 /* End Collection */
1068+
};
1069+
const size_t uclogic_rdesc_ugee_v2_battery_template_size =
1070+
sizeof(uclogic_rdesc_ugee_v2_battery_template_arr);
1071+
10381072
/* Fixed report descriptor for Ugee EX07 frame */
10391073
const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
10401074
0x05, 0x01, /* Usage Page (Desktop), */

drivers/hid/hid-uclogic-rdesc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ extern const size_t uclogic_rdesc_v2_frame_dial_size;
161161
/* Device ID byte offset in v2 frame dial reports */
162162
#define UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE 0x4
163163

164+
/* Report ID for tweaked UGEE v2 battery reports */
165+
#define UCLOGIC_RDESC_UGEE_V2_BATTERY_ID 0xba
166+
164167
/* Fixed report descriptor template for UGEE v2 pen reports */
165168
extern const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[];
166169
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;
177180
extern const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[];
178181
extern const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size;
179182

183+
/* Fixed report descriptor template for UGEE v2 battery reports */
184+
extern const __u8 uclogic_rdesc_ugee_v2_battery_template_arr[];
185+
extern const size_t uclogic_rdesc_ugee_v2_battery_template_size;
186+
180187
/* Fixed report descriptor for Ugee EX07 frame */
181188
extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
182189
extern const size_t uclogic_rdesc_ugee_ex07_frame_size;

0 commit comments

Comments
 (0)