Commit ab6847b9 authored by Jiri Kosina's avatar Jiri Kosina
Browse files

Merge branch 'for-6.2/uclogic' into for-linus

- XP-PEN Deco LW support (José Expósito)
parents 4e6ff447 af89dfde
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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 −2
Original line number Diff line number Diff line
@@ -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,
		  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;
	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[] = {
	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),
	{}
};
+73 −0
Original line number Diff line number Diff line
@@ -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));
+2 −2
Original line number Diff line number Diff line
@@ -187,7 +187,7 @@ static void uclogic_template_case_desc(struct uclogic_template_case *t,
KUNIT_ARRAY_PARAM(uclogic_template, uclogic_template_cases,
		  uclogic_template_case_desc);

static void uclogic_template_test(struct kunit *test)
static void hid_test_uclogic_template(struct kunit *test)
{
	__u8 *res;
	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[] = {
	KUNIT_CASE_PARAM(uclogic_template_test, uclogic_template_gen_params),
	KUNIT_CASE_PARAM(hid_test_uclogic_template, uclogic_template_gen_params),
	{}
};

+34 −0
Original line number Diff line number Diff line
@@ -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),                   */
Loading