Merge branch 'for-6.2/uclogic' into for-linus
- XP-PEN Deco LW support (José Expósito)
This commit is contained in:
@@ -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_PERCENT (1 << 0) /* always reports percent */
|
||||||
#define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */
|
#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_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[] = {
|
static const struct hid_device_id hid_battery_quirks[] = {
|
||||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
{ 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_BATTERY_QUIRK_IGNORE },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
|
||||||
HID_BATTERY_QUIRK_IGNORE },
|
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_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15),
|
||||||
HID_BATTERY_QUIRK_IGNORE },
|
HID_BATTERY_QUIRK_IGNORE },
|
||||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100),
|
{ 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 &&
|
dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
|
||||||
field->physical == HID_DG_STYLUS;
|
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);
|
dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
|
||||||
if (IS_ERR(dev->battery)) {
|
if (IS_ERR(dev->battery)) {
|
||||||
error = PTR_ERR(dev->battery);
|
error = PTR_ERR(dev->battery);
|
||||||
|
@@ -136,7 +136,7 @@ static void uclogic_parse_ugee_v2_desc_case_desc(struct uclogic_parse_ugee_v2_de
|
|||||||
KUNIT_ARRAY_PARAM(uclogic_parse_ugee_v2_desc, uclogic_parse_ugee_v2_desc_cases,
|
KUNIT_ARRAY_PARAM(uclogic_parse_ugee_v2_desc, uclogic_parse_ugee_v2_desc_cases,
|
||||||
uclogic_parse_ugee_v2_desc_case_desc);
|
uclogic_parse_ugee_v2_desc_case_desc);
|
||||||
|
|
||||||
static void uclogic_parse_ugee_v2_desc_test(struct kunit *test)
|
static void hid_test_uclogic_parse_ugee_v2_desc(struct kunit *test)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
|
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
|
||||||
@@ -175,7 +175,7 @@ static void uclogic_parse_ugee_v2_desc_test(struct kunit *test)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct kunit_case hid_uclogic_params_test_cases[] = {
|
static struct kunit_case hid_uclogic_params_test_cases[] = {
|
||||||
KUNIT_CASE_PARAM(uclogic_parse_ugee_v2_desc_test,
|
KUNIT_CASE_PARAM(hid_test_uclogic_parse_ugee_v2_desc,
|
||||||
uclogic_parse_ugee_v2_desc_gen_params),
|
uclogic_parse_ugee_v2_desc_gen_params),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "usbhid/usbhid.h"
|
#include "usbhid/usbhid.h"
|
||||||
#include "hid-ids.h"
|
#include "hid-ids.h"
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/string.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1211,6 +1212,69 @@ static int uclogic_params_ugee_v2_init_frame_mouse(struct uclogic_params *p)
|
|||||||
return rc;
|
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
|
* uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
|
||||||
* discovering their parameters.
|
* discovering their parameters.
|
||||||
@@ -1334,6 +1398,15 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto cleanup;
|
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:
|
||||||
/* Output parameters */
|
/* Output parameters */
|
||||||
memcpy(params, &p, sizeof(*params));
|
memcpy(params, &p, sizeof(*params));
|
||||||
|
@@ -187,7 +187,7 @@ static void uclogic_template_case_desc(struct uclogic_template_case *t,
|
|||||||
KUNIT_ARRAY_PARAM(uclogic_template, uclogic_template_cases,
|
KUNIT_ARRAY_PARAM(uclogic_template, uclogic_template_cases,
|
||||||
uclogic_template_case_desc);
|
uclogic_template_case_desc);
|
||||||
|
|
||||||
static void uclogic_template_test(struct kunit *test)
|
static void hid_test_uclogic_template(struct kunit *test)
|
||||||
{
|
{
|
||||||
__u8 *res;
|
__u8 *res;
|
||||||
const struct uclogic_template_case *params = test->param_value;
|
const struct uclogic_template_case *params = test->param_value;
|
||||||
@@ -203,7 +203,7 @@ static void uclogic_template_test(struct kunit *test)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct kunit_case hid_uclogic_rdesc_test_cases[] = {
|
static struct kunit_case hid_uclogic_rdesc_test_cases[] = {
|
||||||
KUNIT_CASE_PARAM(uclogic_template_test, uclogic_template_gen_params),
|
KUNIT_CASE_PARAM(hid_test_uclogic_template, uclogic_template_gen_params),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -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 =
|
const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size =
|
||||||
sizeof(uclogic_rdesc_ugee_v2_frame_mouse_template_arr);
|
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 */
|
/* Fixed report descriptor for Ugee EX07 frame */
|
||||||
const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
|
const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
|
||||||
0x05, 0x01, /* Usage Page (Desktop), */
|
0x05, 0x01, /* Usage Page (Desktop), */
|
||||||
|
@@ -161,6 +161,9 @@ extern const size_t uclogic_rdesc_v2_frame_dial_size;
|
|||||||
/* Device ID byte offset in v2 frame dial reports */
|
/* Device ID byte offset in v2 frame dial reports */
|
||||||
#define UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE 0x4
|
#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 */
|
/* Fixed report descriptor template for UGEE v2 pen reports */
|
||||||
extern const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[];
|
extern const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[];
|
||||||
extern const size_t uclogic_rdesc_ugee_v2_pen_template_size;
|
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 __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[];
|
||||||
extern const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size;
|
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 */
|
/* Fixed report descriptor for Ugee EX07 frame */
|
||||||
extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
|
extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
|
||||||
extern const size_t uclogic_rdesc_ugee_ex07_frame_size;
|
extern const size_t uclogic_rdesc_ugee_ex07_frame_size;
|
||||||
|
Reference in New Issue
Block a user