// SPDX-License-Identifier: GPL-2.0+
/*
 *  HID driver for UC-Logic devices not fully compliant with HID standard
 *  - tablet initialization and parameter retrieval
 *
 *  Copyright (c) 2018 Nikolai Kondrashov
 */

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 */

#include "hid-uclogic-params.h"
#include "hid-uclogic-rdesc.h"
#include "usbhid/usbhid.h"
#include "hid-ids.h"
#include <linux/ctype.h>
#include <linux/string.h>
#include <asm/unaligned.h>

/**
 * uclogic_params_pen_inrange_to_str() - Convert a pen in-range reporting type
 *                                       to a string.
 * @inrange:	The in-range reporting type to convert.
 *
 * Return:
 * * The string representing the type, or
 * * %NULL if the type is unknown.
 */
static const char *uclogic_params_pen_inrange_to_str(
				enum uclogic_params_pen_inrange inrange)
{
	switch (inrange) {
	case UCLOGIC_PARAMS_PEN_INRANGE_NORMAL:
		return "normal";
	case UCLOGIC_PARAMS_PEN_INRANGE_INVERTED:
		return "inverted";
	case UCLOGIC_PARAMS_PEN_INRANGE_NONE:
		return "none";
	default:
		return NULL;
	}
}

/**
 * uclogic_params_pen_hid_dbg() - Dump tablet interface pen parameters
 * @hdev:	The HID device the pen parameters describe.
 * @pen:	The pen parameters to dump.
 *
 * Dump tablet interface pen parameters with hid_dbg(). The dump is indented
 * with a tab.
 */
static void uclogic_params_pen_hid_dbg(const struct hid_device *hdev,
					const struct uclogic_params_pen *pen)
{
	size_t i;

	hid_dbg(hdev, "\t.usage_invalid = %s\n",
		(pen->usage_invalid ? "true" : "false"));
	hid_dbg(hdev, "\t.desc_ptr = %p\n", pen->desc_ptr);
	hid_dbg(hdev, "\t.desc_size = %u\n", pen->desc_size);
	hid_dbg(hdev, "\t.id = %u\n", pen->id);
	hid_dbg(hdev, "\t.subreport_list = {\n");
	for (i = 0; i < ARRAY_SIZE(pen->subreport_list); i++) {
		hid_dbg(hdev, "\t\t{0x%02hhx, %hhu}%s\n",
			pen->subreport_list[i].value,
			pen->subreport_list[i].id,
			i < (ARRAY_SIZE(pen->subreport_list) - 1) ? "," : "");
	}
	hid_dbg(hdev, "\t}\n");
	hid_dbg(hdev, "\t.inrange = %s\n",
		uclogic_params_pen_inrange_to_str(pen->inrange));
	hid_dbg(hdev, "\t.fragmented_hires = %s\n",
		(pen->fragmented_hires ? "true" : "false"));
	hid_dbg(hdev, "\t.tilt_y_flipped = %s\n",
		(pen->tilt_y_flipped ? "true" : "false"));
}

/**
 * uclogic_params_frame_hid_dbg() - Dump tablet interface frame parameters
 * @hdev:	The HID device the pen parameters describe.
 * @frame:	The frame parameters to dump.
 *
 * Dump tablet interface frame parameters with hid_dbg(). The dump is
 * indented with two tabs.
 */
static void uclogic_params_frame_hid_dbg(
				const struct hid_device *hdev,
				const struct uclogic_params_frame *frame)
{
	hid_dbg(hdev, "\t\t.desc_ptr = %p\n", frame->desc_ptr);
	hid_dbg(hdev, "\t\t.desc_size = %u\n", frame->desc_size);
	hid_dbg(hdev, "\t\t.id = %u\n", frame->id);
	hid_dbg(hdev, "\t\t.suffix = %s\n", frame->suffix);
	hid_dbg(hdev, "\t\t.re_lsb = %u\n", frame->re_lsb);
	hid_dbg(hdev, "\t\t.dev_id_byte = %u\n", frame->dev_id_byte);
	hid_dbg(hdev, "\t\t.touch_byte = %u\n", frame->touch_byte);
	hid_dbg(hdev, "\t\t.touch_max = %hhd\n", frame->touch_max);
	hid_dbg(hdev, "\t\t.touch_flip_at = %hhd\n",
		frame->touch_flip_at);
	hid_dbg(hdev, "\t\t.bitmap_dial_byte = %u\n",
		frame->bitmap_dial_byte);
}

/**
 * uclogic_params_hid_dbg() - Dump tablet interface parameters
 * @hdev:	The HID device the parameters describe.
 * @params:	The parameters to dump.
 *
 * Dump tablet interface parameters with hid_dbg().
 */
void uclogic_params_hid_dbg(const struct hid_device *hdev,
				const struct uclogic_params *params)
{
	size_t i;

	hid_dbg(hdev, ".invalid = %s\n",
		params->invalid ? "true" : "false");
	hid_dbg(hdev, ".desc_ptr = %p\n", params->desc_ptr);
	hid_dbg(hdev, ".desc_size = %u\n", params->desc_size);
	hid_dbg(hdev, ".pen = {\n");
	uclogic_params_pen_hid_dbg(hdev, &params->pen);
	hid_dbg(hdev, "\t}\n");
	hid_dbg(hdev, ".frame_list = {\n");
	for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
		hid_dbg(hdev, "\t{\n");
		uclogic_params_frame_hid_dbg(hdev, &params->frame_list[i]);
		hid_dbg(hdev, "\t}%s\n",
			i < (ARRAY_SIZE(params->frame_list) - 1) ? "," : "");
	}
	hid_dbg(hdev, "}\n");
}

/**
 * uclogic_params_get_str_desc - retrieve a string descriptor from a HID
 * device interface, putting it into a kmalloc-allocated buffer as is, without
 * character encoding conversion.
 *
 * @pbuf:	Location for the kmalloc-allocated buffer pointer containing
 *		the retrieved descriptor. Not modified in case of error.
 *		Can be NULL to have retrieved descriptor discarded.
 * @hdev:	The HID device of the tablet interface to retrieve the string
 *		descriptor from. Cannot be NULL.
 * @idx:	Index of the string descriptor to request from the device.
 * @len:	Length of the buffer to allocate and the data to retrieve.
 *
 * Returns:
 *	number of bytes retrieved (<= len),
 *	-EPIPE, if the descriptor was not found, or
 *	another negative errno code in case of other error.
 */
static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev,
					__u8 idx, size_t len)
{
	int rc;
	struct usb_device *udev;
	__u8 *buf = NULL;

	/* Check arguments */
	if (hdev == NULL) {
		rc = -EINVAL;
		goto cleanup;
	}

	udev = hid_to_usb_dev(hdev);

	buf = kmalloc(len, GFP_KERNEL);
	if (buf == NULL) {
		rc = -ENOMEM;
		goto cleanup;
	}

	rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
				(USB_DT_STRING << 8) + idx,
				0x0409, buf, len,
				USB_CTRL_GET_TIMEOUT);
	if (rc == -EPIPE) {
		hid_dbg(hdev, "string descriptor #%hhu not found\n", idx);
		goto cleanup;
	} else if (rc < 0) {
		hid_err(hdev,
			"failed retrieving string descriptor #%u: %d\n",
			idx, rc);
		goto cleanup;
	}

	if (pbuf != NULL) {
		*pbuf = buf;
		buf = NULL;
	}

cleanup:
	kfree(buf);
	return rc;
}

/**
 * uclogic_params_pen_cleanup - free resources used by struct
 * uclogic_params_pen (tablet interface's pen input parameters).
 * Can be called repeatedly.
 *
 * @pen:	Pen input parameters to cleanup. Cannot be NULL.
 */
static void uclogic_params_pen_cleanup(struct uclogic_params_pen *pen)
{
	kfree(pen->desc_ptr);
	memset(pen, 0, sizeof(*pen));
}

/**
 * uclogic_params_pen_init_v1() - initialize tablet interface pen
 * input and retrieve its parameters from the device, using v1 protocol.
 *
 * @pen:	Pointer to the pen parameters to initialize (to be
 *		cleaned up with uclogic_params_pen_cleanup()). Not modified in
 *		case of error, or if parameters are not found. Cannot be NULL.
 * @pfound:	Location for a flag which is set to true if the parameters
 *		were found, and to false if not (e.g. device was
 *		incompatible). Not modified in case of error. Cannot be NULL.
 * @hdev:	The HID device of the tablet interface to initialize and get
 *		parameters from. Cannot be NULL.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_params_pen_init_v1(struct uclogic_params_pen *pen,
				      bool *pfound,
				      struct hid_device *hdev)
{
	int rc;
	bool found = false;
	/* Buffer for (part of) the string descriptor */
	__u8 *buf = NULL;
	/* Minimum descriptor length required, maximum seen so far is 18 */
	const int len = 12;
	s32 resolution;
	/* Pen report descriptor template parameters */
	s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
	__u8 *desc_ptr = NULL;

	/* Check arguments */
	if (pen == NULL || pfound == NULL || hdev == NULL) {
		rc = -EINVAL;
		goto cleanup;
	}

	/*
	 * Read string descriptor containing pen input parameters.
	 * The specific string descriptor and data were discovered by sniffing
	 * the Windows driver traffic.
	 * NOTE: This enables fully-functional tablet mode.
	 */
	rc = uclogic_params_get_str_desc(&buf, hdev, 100, len);
	if (rc == -EPIPE) {
		hid_dbg(hdev,
			"string descriptor with pen parameters not found, assuming not compatible\n");
		goto finish;
	} else if (rc < 0) {
		hid_err(hdev, "failed retrieving pen parameters: %d\n", rc);
		goto cleanup;
	} else if (rc != len) {
		hid_dbg(hdev,
			"string descriptor with pen parameters has invalid length (got %d, expected %d), assuming not compatible\n",
			rc, len);
		goto finish;
	}

	/*
	 * Fill report descriptor parameters from the string descriptor
	 */
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] =
		get_unaligned_le16(buf + 2);
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] =
		get_unaligned_le16(buf + 4);
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] =
		get_unaligned_le16(buf + 8);
	resolution = get_unaligned_le16(buf + 10);
	if (resolution == 0) {
		desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0;
		desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0;
	} else {
		desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] =
			desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 /
			resolution;
		desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] =
			desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
			resolution;
	}
	kfree(buf);
	buf = NULL;

	/*
	 * Generate pen report descriptor
	 */
	desc_ptr = uclogic_rdesc_template_apply(
				uclogic_rdesc_v1_pen_template_arr,
				uclogic_rdesc_v1_pen_template_size,
				desc_params, ARRAY_SIZE(desc_params));
	if (desc_ptr == NULL) {
		rc = -ENOMEM;
		goto cleanup;
	}

	/*
	 * Fill-in the parameters
	 */
	memset(pen, 0, sizeof(*pen));
	pen->desc_ptr = desc_ptr;
	desc_ptr = NULL;
	pen->desc_size = uclogic_rdesc_v1_pen_template_size;
	pen->id = UCLOGIC_RDESC_V1_PEN_ID;
	pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_INVERTED;
	found = true;
finish:
	*pfound = found;
	rc = 0;
cleanup:
	kfree(desc_ptr);
	kfree(buf);
	return rc;
}

/**
 * uclogic_params_get_le24() - get a 24-bit little-endian number from a
 * buffer.
 *
 * @p:	The pointer to the number buffer.
 *
 * Returns:
 *	The retrieved number
 */
static s32 uclogic_params_get_le24(const void *p)
{
	const __u8 *b = p;
	return b[0] | (b[1] << 8UL) | (b[2] << 16UL);
}

/**
 * uclogic_params_pen_init_v2() - initialize tablet interface pen
 * input and retrieve its parameters from the device, using v2 protocol.
 *
 * @pen:		Pointer to the pen parameters to initialize (to be
 *			cleaned up with uclogic_params_pen_cleanup()). Not
 *			modified in case of error, or if parameters are not
 *			found. Cannot be NULL.
 * @pfound:		Location for a flag which is set to true if the
 *			parameters were found, and to false if not (e.g.
 *			device was incompatible). Not modified in case of
 *			error. Cannot be NULL.
 * @pparams_ptr:	Location for a kmalloc'ed pointer to the retrieved raw
 *			parameters, which could be used to identify the tablet
 *			to some extent. Should be freed with kfree after use.
 *			NULL, if not needed. Not modified in case of error.
 *			Only set if *pfound is set to true.
 * @pparams_len:	Location for the length of the retrieved raw
 *			parameters. NULL, if not needed. Not modified in case
 *			of error. Only set if *pfound is set to true.
 * @hdev:		The HID device of the tablet interface to initialize
 *			and get parameters from. Cannot be NULL.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
					bool *pfound,
					__u8 **pparams_ptr,
					size_t *pparams_len,
					struct hid_device *hdev)
{
	int rc;
	bool found = false;
	/* Buffer for (part of) the parameter string descriptor */
	__u8 *buf = NULL;
	/* Parameter string descriptor required length */
	const int params_len_min = 18;
	/* Parameter string descriptor accepted length */
	const int params_len_max = 32;
	/* Parameter string descriptor received length */
	int params_len;
	size_t i;
	s32 resolution;
	/* Pen report descriptor template parameters */
	s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
	__u8 *desc_ptr = NULL;

	/* Check arguments */
	if (pen == NULL || pfound == NULL || hdev == NULL) {
		rc = -EINVAL;
		goto cleanup;
	}

	/*
	 * Read string descriptor containing pen input parameters.
	 * The specific string descriptor and data were discovered by sniffing
	 * the Windows driver traffic.
	 * NOTE: This enables fully-functional tablet mode.
	 */
	rc = uclogic_params_get_str_desc(&buf, hdev, 200, params_len_max);
	if (rc == -EPIPE) {
		hid_dbg(hdev,
			"string descriptor with pen parameters not found, assuming not compatible\n");
		goto finish;
	} else if (rc < 0) {
		hid_err(hdev, "failed retrieving pen parameters: %d\n", rc);
		goto cleanup;
	} else if (rc < params_len_min) {
		hid_dbg(hdev,
			"string descriptor with pen parameters is too short (got %d, expected at least %d), assuming not compatible\n",
			rc, params_len_min);
		goto finish;
	}

	params_len = rc;

	/*
	 * Check it's not just a catch-all UTF-16LE-encoded ASCII
	 * string (such as the model name) some tablets put into all
	 * unknown string descriptors.
	 */
	for (i = 2;
	     i < params_len &&
		(buf[i] >= 0x20 && buf[i] < 0x7f && buf[i + 1] == 0);
	     i += 2);
	if (i >= params_len) {
		hid_dbg(hdev,
			"string descriptor with pen parameters seems to contain only text, assuming not compatible\n");
		goto finish;
	}

	/*
	 * Fill report descriptor parameters from the string descriptor
	 */
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] =
		uclogic_params_get_le24(buf + 2);
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] =
		uclogic_params_get_le24(buf + 5);
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] =
		get_unaligned_le16(buf + 8);
	resolution = get_unaligned_le16(buf + 10);
	if (resolution == 0) {
		desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0;
		desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0;
	} else {
		desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] =
			desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 /
			resolution;
		desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] =
			desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
			resolution;
	}

	/*
	 * Generate pen report descriptor
	 */
	desc_ptr = uclogic_rdesc_template_apply(
				uclogic_rdesc_v2_pen_template_arr,
				uclogic_rdesc_v2_pen_template_size,
				desc_params, ARRAY_SIZE(desc_params));
	if (desc_ptr == NULL) {
		rc = -ENOMEM;
		goto cleanup;
	}

	/*
	 * Fill-in the parameters
	 */
	memset(pen, 0, sizeof(*pen));
	pen->desc_ptr = desc_ptr;
	desc_ptr = NULL;
	pen->desc_size = uclogic_rdesc_v2_pen_template_size;
	pen->id = UCLOGIC_RDESC_V2_PEN_ID;
	pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_NONE;
	pen->fragmented_hires = true;
	pen->tilt_y_flipped = true;
	found = true;
	if (pparams_ptr != NULL) {
		*pparams_ptr = buf;
		buf = NULL;
	}
	if (pparams_len != NULL)
		*pparams_len = params_len;

finish:
	*pfound = found;
	rc = 0;
cleanup:
	kfree(desc_ptr);
	kfree(buf);
	return rc;
}

/**
 * uclogic_params_frame_cleanup - free resources used by struct
 * uclogic_params_frame (tablet interface's frame controls input parameters).
 * Can be called repeatedly.
 *
 * @frame:	Frame controls input parameters to cleanup. Cannot be NULL.
 */
static void uclogic_params_frame_cleanup(struct uclogic_params_frame *frame)
{
	kfree(frame->desc_ptr);
	memset(frame, 0, sizeof(*frame));
}

/**
 * uclogic_params_frame_init_with_desc() - initialize tablet's frame control
 * parameters with a static report descriptor.
 *
 * @frame:	Pointer to the frame parameters to initialize (to be cleaned
 *		up with uclogic_params_frame_cleanup()). Not modified in case
 *		of error. Cannot be NULL.
 * @desc_ptr:	Report descriptor pointer. Can be NULL, if desc_size is zero.
 * @desc_size:	Report descriptor size.
 * @id:		Report ID used for frame reports, if they should be tweaked,
 *		zero if not.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_params_frame_init_with_desc(
					struct uclogic_params_frame *frame,
					const __u8 *desc_ptr,
					size_t desc_size,
					unsigned int id)
{
	__u8 *copy_desc_ptr;

	if (frame == NULL || (desc_ptr == NULL && desc_size != 0))
		return -EINVAL;

	copy_desc_ptr = kmemdup(desc_ptr, desc_size, GFP_KERNEL);
	if (copy_desc_ptr == NULL)
		return -ENOMEM;

	memset(frame, 0, sizeof(*frame));
	frame->desc_ptr = copy_desc_ptr;
	frame->desc_size = desc_size;
	frame->id = id;
	return 0;
}

/**
 * uclogic_params_frame_init_v1() - initialize v1 tablet interface frame
 * controls.
 *
 * @frame:	Pointer to the frame parameters to initialize (to be cleaned
 *		up with uclogic_params_frame_cleanup()). Not modified in case
 *		of error, or if parameters are not found. Cannot be NULL.
 * @pfound:	Location for a flag which is set to true if the parameters
 *		were found, and to false if not (e.g. device was
 *		incompatible). Not modified in case of error. Cannot be NULL.
 * @hdev:	The HID device of the tablet interface to initialize and get
 *		parameters from. Cannot be NULL.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_params_frame_init_v1(struct uclogic_params_frame *frame,
					bool *pfound,
					struct hid_device *hdev)
{
	int rc;
	bool found = false;
	struct usb_device *usb_dev;
	char *str_buf = NULL;
	const size_t str_len = 16;

	/* Check arguments */
	if (frame == NULL || pfound == NULL || hdev == NULL) {
		rc = -EINVAL;
		goto cleanup;
	}

	usb_dev = hid_to_usb_dev(hdev);

	/*
	 * Enable generic button mode
	 */
	str_buf = kzalloc(str_len, GFP_KERNEL);
	if (str_buf == NULL) {
		rc = -ENOMEM;
		goto cleanup;
	}

	rc = usb_string(usb_dev, 123, str_buf, str_len);
	if (rc == -EPIPE) {
		hid_dbg(hdev,
			"generic button -enabling string descriptor not found\n");
	} else if (rc < 0) {
		goto cleanup;
	} else if (strncmp(str_buf, "HK On", rc) != 0) {
		hid_dbg(hdev,
			"invalid response to enabling generic buttons: \"%s\"\n",
			str_buf);
	} else {
		hid_dbg(hdev, "generic buttons enabled\n");
		rc = uclogic_params_frame_init_with_desc(
				frame,
				uclogic_rdesc_v1_frame_arr,
				uclogic_rdesc_v1_frame_size,
				UCLOGIC_RDESC_V1_FRAME_ID);
		if (rc != 0)
			goto cleanup;
		found = true;
	}

	*pfound = found;
	rc = 0;
cleanup:
	kfree(str_buf);
	return rc;
}

/**
 * uclogic_params_cleanup_event_hooks - free resources used by the list of raw
 * event hooks.
 * Can be called repeatedly.
 *
 * @params: Input parameters to cleanup. Cannot be NULL.
 */
static void uclogic_params_cleanup_event_hooks(struct uclogic_params *params)
{
	struct uclogic_raw_event_hook *curr, *n;

	if (!params || !params->event_hooks)
		return;

	list_for_each_entry_safe(curr, n, &params->event_hooks->list, list) {
		cancel_work_sync(&curr->work);
		list_del(&curr->list);
		kfree(curr->event);
		kfree(curr);
	}

	kfree(params->event_hooks);
	params->event_hooks = NULL;
}

/**
 * uclogic_params_cleanup - free resources used by struct uclogic_params
 * (tablet interface's parameters).
 * Can be called repeatedly.
 *
 * @params:	Input parameters to cleanup. Cannot be NULL.
 */
void uclogic_params_cleanup(struct uclogic_params *params)
{
	if (!params->invalid) {
		size_t i;
		kfree(params->desc_ptr);
		uclogic_params_pen_cleanup(&params->pen);
		for (i = 0; i < ARRAY_SIZE(params->frame_list); i++)
			uclogic_params_frame_cleanup(&params->frame_list[i]);

		uclogic_params_cleanup_event_hooks(params);
		memset(params, 0, sizeof(*params));
	}
}

/**
 * uclogic_params_get_desc() - Get a replacement report descriptor for a
 *                             tablet's interface.
 *
 * @params:	The parameters of a tablet interface to get report
 *		descriptor for. Cannot be NULL.
 * @pdesc:	Location for the resulting, kmalloc-allocated report
 *		descriptor pointer, or for NULL, if there's no replacement
 *		report descriptor. Not modified in case of error. Cannot be
 *		NULL.
 * @psize:	Location for the resulting report descriptor size, not set if
 *		there's no replacement report descriptor. Not modified in case
 *		of error. Cannot be NULL.
 *
 * Returns:
 *	Zero, if successful.
 *	-EINVAL, if invalid arguments are supplied.
 *	-ENOMEM, if failed to allocate memory.
 */
int uclogic_params_get_desc(const struct uclogic_params *params,
				__u8 **pdesc,
				unsigned int *psize)
{
	int rc = -ENOMEM;
	bool present = false;
	unsigned int size = 0;
	__u8 *desc = NULL;
	size_t i;

	/* Check arguments */
	if (params == NULL || pdesc == NULL || psize == NULL)
		return -EINVAL;

	/* Concatenate descriptors */
#define ADD_DESC(_desc_ptr, _desc_size) \
	do {                                                        \
		unsigned int new_size;                              \
		__u8 *new_desc;                                     \
		if ((_desc_ptr) == NULL) {                          \
			break;                                      \
		}                                                   \
		new_size = size + (_desc_size);                     \
		new_desc = krealloc(desc, new_size, GFP_KERNEL);    \
		if (new_desc == NULL) {                             \
			goto cleanup;                               \
		}                                                   \
		memcpy(new_desc + size, (_desc_ptr), (_desc_size)); \
		desc = new_desc;                                    \
		size = new_size;                                    \
		present = true;                                     \
	} while (0)

	ADD_DESC(params->desc_ptr, params->desc_size);
	ADD_DESC(params->pen.desc_ptr, params->pen.desc_size);
	for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
		ADD_DESC(params->frame_list[i].desc_ptr,
				params->frame_list[i].desc_size);
	}

#undef ADD_DESC

	if (present) {
		*pdesc = desc;
		*psize = size;
		desc = NULL;
	}
	rc = 0;
cleanup:
	kfree(desc);
	return rc;
}

/**
 * uclogic_params_init_invalid() - initialize tablet interface parameters,
 * specifying the interface is invalid.
 *
 * @params:		Parameters to initialize (to be cleaned with
 *			uclogic_params_cleanup()). Cannot be NULL.
 */
static void uclogic_params_init_invalid(struct uclogic_params *params)
{
	params->invalid = true;
}

/**
 * uclogic_params_init_with_opt_desc() - initialize tablet interface
 * parameters with an optional replacement report descriptor. Only modify
 * report descriptor, if the original report descriptor matches the expected
 * size.
 *
 * @params:		Parameters to initialize (to be cleaned with
 *			uclogic_params_cleanup()). Not modified in case of
 *			error. Cannot be NULL.
 * @hdev:		The HID device of the tablet interface create the
 *			parameters for. Cannot be NULL.
 * @orig_desc_size:	Expected size of the original report descriptor to
 *			be replaced.
 * @desc_ptr:		Pointer to the replacement report descriptor.
 *			Can be NULL, if desc_size is zero.
 * @desc_size:		Size of the replacement report descriptor.
 *
 * Returns:
 *	Zero, if successful. -EINVAL if an invalid argument was passed.
 *	-ENOMEM, if failed to allocate memory.
 */
static int uclogic_params_init_with_opt_desc(struct uclogic_params *params,
					     struct hid_device *hdev,
					     unsigned int orig_desc_size,
					     __u8 *desc_ptr,
					     unsigned int desc_size)
{
	__u8 *desc_copy_ptr = NULL;
	unsigned int desc_copy_size;
	int rc;

	/* Check arguments */
	if (params == NULL || hdev == NULL ||
	    (desc_ptr == NULL && desc_size != 0)) {
		rc = -EINVAL;
		goto cleanup;
	}

	/* Replace report descriptor, if it matches */
	if (hdev->dev_rsize == orig_desc_size) {
		hid_dbg(hdev,
			"device report descriptor matches the expected size, replacing\n");
		desc_copy_ptr = kmemdup(desc_ptr, desc_size, GFP_KERNEL);
		if (desc_copy_ptr == NULL) {
			rc = -ENOMEM;
			goto cleanup;
		}
		desc_copy_size = desc_size;
	} else {
		hid_dbg(hdev,
			"device report descriptor doesn't match the expected size (%u != %u), preserving\n",
			hdev->dev_rsize, orig_desc_size);
		desc_copy_ptr = NULL;
		desc_copy_size = 0;
	}

	/* Output parameters */
	memset(params, 0, sizeof(*params));
	params->desc_ptr = desc_copy_ptr;
	desc_copy_ptr = NULL;
	params->desc_size = desc_copy_size;

	rc = 0;
cleanup:
	kfree(desc_copy_ptr);
	return rc;
}

/**
 * uclogic_params_huion_init() - initialize a Huion tablet interface and discover
 * its parameters.
 *
 * @params:	Parameters to fill in (to be cleaned with
 *		uclogic_params_cleanup()). Not modified in case of error.
 *		Cannot be NULL.
 * @hdev:	The HID device of the tablet interface to initialize and get
 *		parameters from. Cannot be NULL.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_params_huion_init(struct uclogic_params *params,
				     struct hid_device *hdev)
{
	int rc;
	struct usb_device *udev;
	struct usb_interface *iface;
	__u8 bInterfaceNumber;
	bool found;
	/* The resulting parameters (noop) */
	struct uclogic_params p = {0, };
	static const char transition_ver[] = "HUION_T153_160607";
	char *ver_ptr = NULL;
	const size_t ver_len = sizeof(transition_ver) + 1;
	__u8 *params_ptr = NULL;
	size_t params_len = 0;
	/* Parameters string descriptor of a model with touch ring (HS610) */
	const __u8 touch_ring_model_params_buf[] = {
		0x13, 0x03, 0x70, 0xC6, 0x00, 0x06, 0x7C, 0x00,
		0xFF, 0x1F, 0xD8, 0x13, 0x03, 0x0D, 0x10, 0x01,
		0x04, 0x3C, 0x3E
	};

	/* Check arguments */
	if (params == NULL || hdev == NULL) {
		rc = -EINVAL;
		goto cleanup;
	}

	udev = hid_to_usb_dev(hdev);
	iface = to_usb_interface(hdev->dev.parent);
	bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;

	/* If it's a custom keyboard interface */
	if (bInterfaceNumber == 1) {
		/* Keep everything intact, but mark pen usage invalid */
		p.pen.usage_invalid = true;
		goto output;
	/* Else, if it's not a pen interface */
	} else if (bInterfaceNumber != 0) {
		uclogic_params_init_invalid(&p);
		goto output;
	}

	/* Try to get firmware version */
	ver_ptr = kzalloc(ver_len, GFP_KERNEL);
	if (ver_ptr == NULL) {
		rc = -ENOMEM;
		goto cleanup;
	}
	rc = usb_string(udev, 201, ver_ptr, ver_len);
	if (rc == -EPIPE) {
		*ver_ptr = '\0';
	} else if (rc < 0) {
		hid_err(hdev,
			"failed retrieving Huion firmware version: %d\n", rc);
		goto cleanup;
	}

	/* If this is a transition firmware */
	if (strcmp(ver_ptr, transition_ver) == 0) {
		hid_dbg(hdev,
			"transition firmware detected, not probing pen v2 parameters\n");
	} else {
		/* Try to probe v2 pen parameters */
		rc = uclogic_params_pen_init_v2(&p.pen, &found,
						&params_ptr, &params_len,
						hdev);
		if (rc != 0) {
			hid_err(hdev,
				"failed probing pen v2 parameters: %d\n", rc);
			goto cleanup;
		} else if (found) {
			hid_dbg(hdev, "pen v2 parameters found\n");
			/* Create v2 frame button parameters */
			rc = uclogic_params_frame_init_with_desc(
					&p.frame_list[0],
					uclogic_rdesc_v2_frame_buttons_arr,
					uclogic_rdesc_v2_frame_buttons_size,
					UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID);
			if (rc != 0) {
				hid_err(hdev,
					"failed creating v2 frame button parameters: %d\n",
					rc);
				goto cleanup;
			}

			/* Link from pen sub-report */
			p.pen.subreport_list[0].value = 0xe0;
			p.pen.subreport_list[0].id =
				UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID;

			/* If this is the model with touch ring */
			if (params_ptr != NULL &&
			    params_len == sizeof(touch_ring_model_params_buf) &&
			    memcmp(params_ptr, touch_ring_model_params_buf,
				   params_len) == 0) {
				/* Create touch ring parameters */
				rc = uclogic_params_frame_init_with_desc(
					&p.frame_list[1],
					uclogic_rdesc_v2_frame_touch_ring_arr,
					uclogic_rdesc_v2_frame_touch_ring_size,
					UCLOGIC_RDESC_V2_FRAME_TOUCH_ID);
				if (rc != 0) {
					hid_err(hdev,
						"failed creating v2 frame touch ring parameters: %d\n",
						rc);
					goto cleanup;
				}
				p.frame_list[1].suffix = "Touch Ring";
				p.frame_list[1].dev_id_byte =
					UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE;
				p.frame_list[1].touch_byte = 5;
				p.frame_list[1].touch_max = 12;
				p.frame_list[1].touch_flip_at = 7;
			} else {
				/* Create touch strip parameters */
				rc = uclogic_params_frame_init_with_desc(
					&p.frame_list[1],
					uclogic_rdesc_v2_frame_touch_strip_arr,
					uclogic_rdesc_v2_frame_touch_strip_size,
					UCLOGIC_RDESC_V2_FRAME_TOUCH_ID);
				if (rc != 0) {
					hid_err(hdev,
						"failed creating v2 frame touch strip parameters: %d\n",
						rc);
					goto cleanup;
				}
				p.frame_list[1].suffix = "Touch Strip";
				p.frame_list[1].dev_id_byte =
					UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE;
				p.frame_list[1].touch_byte = 5;
				p.frame_list[1].touch_max = 8;
			}

			/* Link from pen sub-report */
			p.pen.subreport_list[1].value = 0xf0;
			p.pen.subreport_list[1].id =
				UCLOGIC_RDESC_V2_FRAME_TOUCH_ID;

			/* Create v2 frame dial parameters */
			rc = uclogic_params_frame_init_with_desc(
					&p.frame_list[2],
					uclogic_rdesc_v2_frame_dial_arr,
					uclogic_rdesc_v2_frame_dial_size,
					UCLOGIC_RDESC_V2_FRAME_DIAL_ID);
			if (rc != 0) {
				hid_err(hdev,
					"failed creating v2 frame dial parameters: %d\n",
					rc);
				goto cleanup;
			}
			p.frame_list[2].suffix = "Dial";
			p.frame_list[2].dev_id_byte =
				UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE;
			p.frame_list[2].bitmap_dial_byte = 5;

			/* Link from pen sub-report */
			p.pen.subreport_list[2].value = 0xf1;
			p.pen.subreport_list[2].id =
				UCLOGIC_RDESC_V2_FRAME_DIAL_ID;

			goto output;
		}
		hid_dbg(hdev, "pen v2 parameters not found\n");
	}

	/* Try to probe v1 pen parameters */
	rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
	if (rc != 0) {
		hid_err(hdev,
			"failed probing pen v1 parameters: %d\n", rc);
		goto cleanup;
	} else if (found) {
		hid_dbg(hdev, "pen v1 parameters found\n");
		/* Try to probe v1 frame */
		rc = uclogic_params_frame_init_v1(&p.frame_list[0],
						  &found, hdev);
		if (rc != 0) {
			hid_err(hdev, "v1 frame probing failed: %d\n", rc);
			goto cleanup;
		}
		hid_dbg(hdev, "frame v1 parameters%s found\n",
			(found ? "" : " not"));
		if (found) {
			/* Link frame button subreports from pen reports */
			p.pen.subreport_list[0].value = 0xe0;
			p.pen.subreport_list[0].id =
				UCLOGIC_RDESC_V1_FRAME_ID;
		}
		goto output;
	}
	hid_dbg(hdev, "pen v1 parameters not found\n");

	uclogic_params_init_invalid(&p);

output:
	/* Output parameters */
	memcpy(params, &p, sizeof(*params));
	memset(&p, 0, sizeof(p));
	rc = 0;
cleanup:
	kfree(params_ptr);
	kfree(ver_ptr);
	uclogic_params_cleanup(&p);
	return rc;
}

/**
 * uclogic_probe_interface() - some tablets, like the Parblo A610 PLUS V2 or
 * the XP-PEN Deco Mini 7, need to be initialized by sending them magic data.
 *
 * @hdev:	The HID device of the tablet interface to initialize and get
 *		parameters from. Cannot be NULL.
 * @magic_arr:	The magic data that should be sent to probe the interface.
 *		Cannot be NULL.
 * @magic_size:	Size of the magic data.
 * @endpoint:	Endpoint where the magic data should be sent.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_probe_interface(struct hid_device *hdev, const u8 *magic_arr,
				   size_t magic_size, int endpoint)
{
	struct usb_device *udev;
	unsigned int pipe = 0;
	int sent;
	u8 *buf = NULL;
	int rc = 0;

	if (!hdev || !magic_arr) {
		rc = -EINVAL;
		goto cleanup;
	}

	buf = kmemdup(magic_arr, magic_size, GFP_KERNEL);
	if (!buf) {
		rc = -ENOMEM;
		goto cleanup;
	}

	udev = hid_to_usb_dev(hdev);
	pipe = usb_sndintpipe(udev, endpoint);

	rc = usb_interrupt_msg(udev, pipe, buf, magic_size, &sent, 1000);
	if (rc || sent != magic_size) {
		hid_err(hdev, "Interface probing failed: %d\n", rc);
		rc = -1;
		goto cleanup;
	}

	rc = 0;
cleanup:
	kfree(buf);
	return rc;
}

/**
 * uclogic_params_parse_ugee_v2_desc - parse the string descriptor containing
 * pen and frame parameters returned by UGEE v2 devices.
 *
 * @str_desc:		String descriptor, cannot be NULL.
 * @str_desc_size:	Size of the string descriptor.
 * @desc_params:	Output description params list.
 * @desc_params_size:	Size of the output description params list.
 * @frame_type:		Output frame type.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_params_parse_ugee_v2_desc(const __u8 *str_desc,
					     size_t str_desc_size,
					     s32 *desc_params,
					     size_t desc_params_size,
					     enum uclogic_params_frame_type *frame_type)
{
	s32 pen_x_lm, pen_y_lm;
	s32 pen_x_pm, pen_y_pm;
	s32 pen_pressure_lm;
	s32 frame_num_buttons;
	s32 resolution;

	/* Minimum descriptor length required, maximum seen so far is 14 */
	const int min_str_desc_size = 12;

	if (!str_desc || str_desc_size < min_str_desc_size)
		return -EINVAL;

	if (desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
		return -EINVAL;

	pen_x_lm = get_unaligned_le16(str_desc + 2);
	pen_y_lm = get_unaligned_le16(str_desc + 4);
	frame_num_buttons = str_desc[6];
	*frame_type = str_desc[7];
	pen_pressure_lm = get_unaligned_le16(str_desc + 8);

	resolution = get_unaligned_le16(str_desc + 10);
	if (resolution == 0) {
		pen_x_pm = 0;
		pen_y_pm = 0;
	} else {
		pen_x_pm = pen_x_lm * 1000 / resolution;
		pen_y_pm = pen_y_lm * 1000 / resolution;
	}

	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = pen_x_lm;
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = pen_x_pm;
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = pen_y_lm;
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = pen_y_pm;
	desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = pen_pressure_lm;
	desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = frame_num_buttons;

	return 0;
}

/**
 * uclogic_params_ugee_v2_init_frame_buttons() - initialize a UGEE v2 frame with
 * buttons.
 * @p:			Parameters to fill in, cannot be NULL.
 * @desc_params:	Device description params list.
 * @desc_params_size:	Size of the description params list.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_params_ugee_v2_init_frame_buttons(struct uclogic_params *p,
						     const s32 *desc_params,
						     size_t desc_params_size)
{
	__u8 *rdesc_frame = NULL;
	int rc = 0;

	if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
		return -EINVAL;

	rdesc_frame = uclogic_rdesc_template_apply(
				uclogic_rdesc_ugee_v2_frame_btn_template_arr,
				uclogic_rdesc_ugee_v2_frame_btn_template_size,
				desc_params, UCLOGIC_RDESC_PH_ID_NUM);
	if (!rdesc_frame)
		return -ENOMEM;

	rc = uclogic_params_frame_init_with_desc(&p->frame_list[0],
						 rdesc_frame,
						 uclogic_rdesc_ugee_v2_frame_btn_template_size,
						 UCLOGIC_RDESC_V1_FRAME_ID);
	kfree(rdesc_frame);
	return rc;
}

/**
 * uclogic_params_ugee_v2_init_frame_dial() - initialize a UGEE v2 frame with a
 * bitmap dial.
 * @p:			Parameters to fill in, cannot be NULL.
 * @desc_params:	Device description params list.
 * @desc_params_size:	Size of the description params list.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_params_ugee_v2_init_frame_dial(struct uclogic_params *p,
						  const s32 *desc_params,
						  size_t desc_params_size)
{
	__u8 *rdesc_frame = NULL;
	int rc = 0;

	if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
		return -EINVAL;

	rdesc_frame = uclogic_rdesc_template_apply(
				uclogic_rdesc_ugee_v2_frame_dial_template_arr,
				uclogic_rdesc_ugee_v2_frame_dial_template_size,
				desc_params, UCLOGIC_RDESC_PH_ID_NUM);
	if (!rdesc_frame)
		return -ENOMEM;

	rc = uclogic_params_frame_init_with_desc(&p->frame_list[0],
						 rdesc_frame,
						 uclogic_rdesc_ugee_v2_frame_dial_template_size,
						 UCLOGIC_RDESC_V1_FRAME_ID);
	kfree(rdesc_frame);
	if (rc)
		return rc;

	p->frame_list[0].bitmap_dial_byte = 7;
	return 0;
}

/**
 * uclogic_params_ugee_v2_init_frame_mouse() - initialize a UGEE v2 frame with a
 * mouse.
 * @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_frame_mouse(struct uclogic_params *p)
{
	int rc = 0;

	if (!p)
		return -EINVAL;

	rc = uclogic_params_frame_init_with_desc(&p->frame_list[1],
						 uclogic_rdesc_ugee_v2_frame_mouse_template_arr,
						 uclogic_rdesc_ugee_v2_frame_mouse_template_size,
						 UCLOGIC_RDESC_V1_FRAME_ID);
	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)
{
	struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);

	if (drvdata->quirks & UCLOGIC_BATTERY_QUIRK)
		return true;

	/* 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_reconnect_work() - When a wireless tablet looses
 * connection to the USB dongle and reconnects, either because of its physical
 * distance or because it was switches off and on using the frame's switch,
 * uclogic_probe_interface() needs to be called again to enable the tablet.
 *
 * @work: The work that triggered this function.
 */
static void uclogic_params_ugee_v2_reconnect_work(struct work_struct *work)
{
	struct uclogic_raw_event_hook *event_hook;

	event_hook = container_of(work, struct uclogic_raw_event_hook, work);
	uclogic_probe_interface(event_hook->hdev, uclogic_ugee_v2_probe_arr,
				uclogic_ugee_v2_probe_size,
				uclogic_ugee_v2_probe_endpoint);
}

/**
 * uclogic_params_ugee_v2_init_event_hooks() - initialize the list of events
 * to be hooked for UGEE v2 devices.
 * @hdev:	The HID device of the tablet interface to initialize and get
 *		parameters from.
 * @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_event_hooks(struct hid_device *hdev,
						   struct uclogic_params *p)
{
	struct uclogic_raw_event_hook *event_hook;
	__u8 reconnect_event[] = {
		/* Event received on wireless tablet reconnection */
		0x02, 0xF8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};

	if (!p)
		return -EINVAL;

	/* The reconnection event is only received if the tablet has battery */
	if (!uclogic_params_ugee_v2_has_battery(hdev))
		return 0;

	p->event_hooks = kzalloc(sizeof(*p->event_hooks), GFP_KERNEL);
	if (!p->event_hooks)
		return -ENOMEM;

	INIT_LIST_HEAD(&p->event_hooks->list);

	event_hook = kzalloc(sizeof(*event_hook), GFP_KERNEL);
	if (!event_hook)
		return -ENOMEM;

	INIT_WORK(&event_hook->work, uclogic_params_ugee_v2_reconnect_work);
	event_hook->hdev = hdev;
	event_hook->size = ARRAY_SIZE(reconnect_event);
	event_hook->event = kmemdup(reconnect_event, event_hook->size, GFP_KERNEL);
	if (!event_hook->event)
		return -ENOMEM;

	list_add_tail(&event_hook->list, &p->event_hooks->list);

	return 0;
}

/**
 * uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
 * discovering their parameters.
 *
 * These tables, internally designed as v2 to differentiate them from older
 * models, expect a payload of magic data in orther to be switched to the fully
 * functional mode and expose their parameters in a similar way to the
 * information present in uclogic_params_pen_init_v1() but with some
 * differences.
 *
 * @params:	Parameters to fill in (to be cleaned with
 *		uclogic_params_cleanup()). Not modified in case of error.
 *		Cannot be NULL.
 * @hdev:	The HID device of the tablet interface to initialize and get
 *		parameters from. Cannot be NULL.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
				       struct hid_device *hdev)
{
	int rc = 0;
	struct uclogic_drvdata *drvdata;
	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 (!params || !hdev) {
		rc = -EINVAL;
		goto cleanup;
	}

	drvdata = hid_get_drvdata(hdev);
	iface = to_usb_interface(hdev->dev.parent);
	bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;

	if (bInterfaceNumber == 0) {
		rc = uclogic_params_ugee_v2_init_frame_mouse(&p);
		if (rc)
			goto cleanup;

		goto output;
	}

	if (bInterfaceNumber != 2) {
		uclogic_params_init_invalid(&p);
		goto output;
	}

	/*
	 * Initialize the interface by sending magic data.
	 * The specific data was discovered by sniffing the Windows driver
	 * traffic.
	 */
	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.
	 * The specific string descriptor and data were discovered by sniffing
	 * the Windows driver traffic.
	 */
	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;

	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 */
	if (drvdata->quirks & UCLOGIC_MOUSE_FRAME_QUIRK)
		frame_type = UCLOGIC_PARAMS_FRAME_MOUSE;

	switch (frame_type) {
	case UCLOGIC_PARAMS_FRAME_DIAL:
	case UCLOGIC_PARAMS_FRAME_MOUSE:
		rc = uclogic_params_ugee_v2_init_frame_dial(&p, desc_params,
							    ARRAY_SIZE(desc_params));
		break;
	case UCLOGIC_PARAMS_FRAME_BUTTONS:
	default:
		rc = uclogic_params_ugee_v2_init_frame_buttons(&p, desc_params,
							       ARRAY_SIZE(desc_params));
		break;
	}

	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;
		}
	}

	/* Create a list of raw events to be ignored */
	rc = uclogic_params_ugee_v2_init_event_hooks(hdev, &p);
	if (rc) {
		hid_err(hdev, "error initializing event hook list: %d\n", rc);
		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() - initialize a tablet interface and discover its
 * parameters.
 *
 * @params:	Parameters to fill in (to be cleaned with
 *		uclogic_params_cleanup()). Not modified in case of error.
 *		Cannot be NULL.
 * @hdev:	The HID device of the tablet interface to initialize and get
 *		parameters from. Cannot be NULL. Must be using the USB low-level
 *		driver, i.e. be an actual USB tablet.
 *
 * Returns:
 *	Zero, if successful. A negative errno code on error.
 */
int uclogic_params_init(struct uclogic_params *params,
			struct hid_device *hdev)
{
	int rc;
	struct usb_device *udev;
	__u8  bNumInterfaces;
	struct usb_interface *iface;
	__u8 bInterfaceNumber;
	bool found;
	/* The resulting parameters (noop) */
	struct uclogic_params p = {0, };

	/* Check arguments */
	if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) {
		rc = -EINVAL;
		goto cleanup;
	}

	udev = hid_to_usb_dev(hdev);
	bNumInterfaces = udev->config->desc.bNumInterfaces;
	iface = to_usb_interface(hdev->dev.parent);
	bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;

	/*
	 * Set replacement report descriptor if the original matches the
	 * specified size. Otherwise keep interface unchanged.
	 */
#define WITH_OPT_DESC(_orig_desc_token, _new_desc_token) \
	uclogic_params_init_with_opt_desc(                  \
		&p, hdev,                                   \
		UCLOGIC_RDESC_##_orig_desc_token##_SIZE,    \
		uclogic_rdesc_##_new_desc_token##_arr,      \
		uclogic_rdesc_##_new_desc_token##_size)

#define VID_PID(_vid, _pid) \
	(((__u32)(_vid) << 16) | ((__u32)(_pid) & U16_MAX))

	/*
	 * Handle specific interfaces for specific tablets.
	 *
	 * Observe the following logic:
	 *
	 * If the interface is recognized as producing certain useful input:
	 *	Mark interface as valid.
	 *	Output interface parameters.
	 * Else, if the interface is recognized as *not* producing any useful
	 * input:
	 *	Mark interface as invalid.
	 * Else:
	 *	Mark interface as valid.
	 *	Output noop parameters.
	 *
	 * Rule of thumb: it is better to disable a broken interface than let
	 *		  it spew garbage input.
	 */

	switch (VID_PID(hdev->vendor, hdev->product)) {
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_TABLET_PF1209):
		rc = WITH_OPT_DESC(PF1209_ORIG, pf1209_fixed);
		if (rc != 0)
			goto cleanup;
		break;
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U):
		rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp4030u_fixed);
		if (rc != 0)
			goto cleanup;
		break;
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U):
		if (hdev->dev_rsize == UCLOGIC_RDESC_WP5540U_V2_ORIG_SIZE) {
			if (bInterfaceNumber == 0) {
				/* Try to probe v1 pen parameters */
				rc = uclogic_params_pen_init_v1(&p.pen,
								&found, hdev);
				if (rc != 0) {
					hid_err(hdev,
						"pen probing failed: %d\n",
						rc);
					goto cleanup;
				}
				if (!found) {
					hid_warn(hdev,
						 "pen parameters not found");
				}
			} else {
				uclogic_params_init_invalid(&p);
			}
		} else {
			rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp5540u_fixed);
			if (rc != 0)
				goto cleanup;
		}
		break;
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U):
		rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp8060u_fixed);
		if (rc != 0)
			goto cleanup;
		break;
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_TABLET_WP1062):
		rc = WITH_OPT_DESC(WP1062_ORIG, wp1062_fixed);
		if (rc != 0)
			goto cleanup;
		break;
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850):
		switch (bInterfaceNumber) {
		case 0:
			rc = WITH_OPT_DESC(TWHL850_ORIG0, twhl850_fixed0);
			if (rc != 0)
				goto cleanup;
			break;
		case 1:
			rc = WITH_OPT_DESC(TWHL850_ORIG1, twhl850_fixed1);
			if (rc != 0)
				goto cleanup;
			break;
		case 2:
			rc = WITH_OPT_DESC(TWHL850_ORIG2, twhl850_fixed2);
			if (rc != 0)
				goto cleanup;
			break;
		}
		break;
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60):
		/*
		 * If it is not a three-interface version, which is known to
		 * respond to initialization.
		 */
		if (bNumInterfaces != 3) {
			switch (bInterfaceNumber) {
			case 0:
				rc = WITH_OPT_DESC(TWHA60_ORIG0,
							twha60_fixed0);
				if (rc != 0)
					goto cleanup;
				break;
			case 1:
				rc = WITH_OPT_DESC(TWHA60_ORIG1,
							twha60_fixed1);
				if (rc != 0)
					goto cleanup;
				break;
			}
			break;
		}
		fallthrough;
	case VID_PID(USB_VENDOR_ID_HUION,
		     USB_DEVICE_ID_HUION_TABLET):
	case VID_PID(USB_VENDOR_ID_HUION,
		     USB_DEVICE_ID_HUION_TABLET2):
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_HUION_TABLET):
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_YIYNOVA_TABLET):
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_81):
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3):
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_45):
	case VID_PID(USB_VENDOR_ID_UCLOGIC,
		     USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_47):
		rc = uclogic_params_huion_init(&p, hdev);
		if (rc != 0)
			goto cleanup;
		break;
	case VID_PID(USB_VENDOR_ID_UGTIZER,
		     USB_DEVICE_ID_UGTIZER_TABLET_GP0610):
	case VID_PID(USB_VENDOR_ID_UGTIZER,
		     USB_DEVICE_ID_UGTIZER_TABLET_GT5040):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720):
		/* If this is the pen interface */
		if (bInterfaceNumber == 1) {
			/* Probe v1 pen parameters */
			rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
			if (rc != 0) {
				hid_err(hdev, "pen probing failed: %d\n", rc);
				goto cleanup;
			}
			if (!found) {
				hid_warn(hdev, "pen parameters not found");
				uclogic_params_init_invalid(&p);
			}
		} else {
			uclogic_params_init_invalid(&p);
		}
		break;
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01):
		/* If this is the pen and frame interface */
		if (bInterfaceNumber == 1) {
			/* Probe v1 pen parameters */
			rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
			if (rc != 0) {
				hid_err(hdev, "pen probing failed: %d\n", rc);
				goto cleanup;
			}
			/* Initialize frame parameters */
			rc = uclogic_params_frame_init_with_desc(
				&p.frame_list[0],
				uclogic_rdesc_xppen_deco01_frame_arr,
				uclogic_rdesc_xppen_deco01_frame_size,
				0);
			if (rc != 0)
				goto cleanup;
		} else {
			uclogic_params_init_invalid(&p);
		}
		break;
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_PARBLO_A610_PRO):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01_V2):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_MW):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW):
		rc = uclogic_params_ugee_v2_init(&p, hdev);
		if (rc != 0)
			goto cleanup;
		break;
	case VID_PID(USB_VENDOR_ID_TRUST,
		     USB_DEVICE_ID_TRUST_PANORA_TABLET):
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_TABLET_G5):
		/* Ignore non-pen interfaces */
		if (bInterfaceNumber != 1) {
			uclogic_params_init_invalid(&p);
			break;
		}

		rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
		if (rc != 0) {
			hid_err(hdev, "pen probing failed: %d\n", rc);
			goto cleanup;
		} else if (found) {
			rc = uclogic_params_frame_init_with_desc(
				&p.frame_list[0],
				uclogic_rdesc_ugee_g5_frame_arr,
				uclogic_rdesc_ugee_g5_frame_size,
				UCLOGIC_RDESC_UGEE_G5_FRAME_ID);
			if (rc != 0) {
				hid_err(hdev,
					"failed creating frame parameters: %d\n",
					rc);
				goto cleanup;
			}
			p.frame_list[0].re_lsb =
				UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB;
			p.frame_list[0].dev_id_byte =
				UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE;
		} else {
			hid_warn(hdev, "pen parameters not found");
			uclogic_params_init_invalid(&p);
		}

		break;
	case VID_PID(USB_VENDOR_ID_UGEE,
		     USB_DEVICE_ID_UGEE_TABLET_EX07S):
		/* Ignore non-pen interfaces */
		if (bInterfaceNumber != 1) {
			uclogic_params_init_invalid(&p);
			break;
		}

		rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
		if (rc != 0) {
			hid_err(hdev, "pen probing failed: %d\n", rc);
			goto cleanup;
		} else if (found) {
			rc = uclogic_params_frame_init_with_desc(
				&p.frame_list[0],
				uclogic_rdesc_ugee_ex07_frame_arr,
				uclogic_rdesc_ugee_ex07_frame_size,
				0);
			if (rc != 0) {
				hid_err(hdev,
					"failed creating frame parameters: %d\n",
					rc);
				goto cleanup;
			}
		} else {
			hid_warn(hdev, "pen parameters not found");
			uclogic_params_init_invalid(&p);
		}

		break;
	}

#undef VID_PID
#undef WITH_OPT_DESC

	/* Output parameters */
	memcpy(params, &p, sizeof(*params));
	memset(&p, 0, sizeof(p));
	rc = 0;
cleanup:
	uclogic_params_cleanup(&p);
	return rc;
}

#ifdef CONFIG_HID_KUNIT_TEST
#include "hid-uclogic-params-test.c"
#endif
