Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 *  HID driver for UC-Logic devices not fully compliant with HID standard
   4 *  - tablet initialization and parameter retrieval
   5 *
   6 *  Copyright (c) 2018 Nikolai Kondrashov
   7 */
   8
   9/*
  10 * This program is free software; you can redistribute it and/or modify it
  11 * under the terms of the GNU General Public License as published by the Free
  12 * Software Foundation; either version 2 of the License, or (at your option)
  13 * any later version.
  14 */
  15
  16#include "hid-uclogic-params.h"
  17#include "hid-uclogic-rdesc.h"
  18#include "usbhid/usbhid.h"
  19#include "hid-ids.h"
  20#include <linux/ctype.h>
  21#include <linux/string.h>
  22#include <linux/unaligned.h>
  23
  24/**
  25 * uclogic_params_pen_inrange_to_str() - Convert a pen in-range reporting type
  26 *                                       to a string.
  27 * @inrange:	The in-range reporting type to convert.
  28 *
  29 * Return:
  30 * * The string representing the type, or
  31 * * %NULL if the type is unknown.
  32 */
  33static const char *uclogic_params_pen_inrange_to_str(
  34				enum uclogic_params_pen_inrange inrange)
  35{
  36	switch (inrange) {
  37	case UCLOGIC_PARAMS_PEN_INRANGE_NORMAL:
  38		return "normal";
  39	case UCLOGIC_PARAMS_PEN_INRANGE_INVERTED:
  40		return "inverted";
  41	case UCLOGIC_PARAMS_PEN_INRANGE_NONE:
  42		return "none";
  43	default:
  44		return NULL;
  45	}
  46}
  47
  48/**
  49 * uclogic_params_pen_hid_dbg() - Dump tablet interface pen parameters
  50 * @hdev:	The HID device the pen parameters describe.
  51 * @pen:	The pen parameters to dump.
  52 *
  53 * Dump tablet interface pen parameters with hid_dbg(). The dump is indented
  54 * with a tab.
  55 */
  56static void uclogic_params_pen_hid_dbg(const struct hid_device *hdev,
  57					const struct uclogic_params_pen *pen)
  58{
  59	size_t i;
  60
  61	hid_dbg(hdev, "\t.usage_invalid = %s\n",
  62		(pen->usage_invalid ? "true" : "false"));
  63	hid_dbg(hdev, "\t.desc_ptr = %p\n", pen->desc_ptr);
  64	hid_dbg(hdev, "\t.desc_size = %u\n", pen->desc_size);
  65	hid_dbg(hdev, "\t.id = %u\n", pen->id);
  66	hid_dbg(hdev, "\t.subreport_list = {\n");
  67	for (i = 0; i < ARRAY_SIZE(pen->subreport_list); i++) {
  68		hid_dbg(hdev, "\t\t{0x%02hhx, %hhu}%s\n",
  69			pen->subreport_list[i].value,
  70			pen->subreport_list[i].id,
  71			i < (ARRAY_SIZE(pen->subreport_list) - 1) ? "," : "");
  72	}
  73	hid_dbg(hdev, "\t}\n");
  74	hid_dbg(hdev, "\t.inrange = %s\n",
  75		uclogic_params_pen_inrange_to_str(pen->inrange));
  76	hid_dbg(hdev, "\t.fragmented_hires = %s\n",
  77		(pen->fragmented_hires ? "true" : "false"));
  78	hid_dbg(hdev, "\t.tilt_y_flipped = %s\n",
  79		(pen->tilt_y_flipped ? "true" : "false"));
  80}
  81
  82/**
  83 * uclogic_params_frame_hid_dbg() - Dump tablet interface frame parameters
  84 * @hdev:	The HID device the pen parameters describe.
  85 * @frame:	The frame parameters to dump.
  86 *
  87 * Dump tablet interface frame parameters with hid_dbg(). The dump is
  88 * indented with two tabs.
  89 */
  90static void uclogic_params_frame_hid_dbg(
  91				const struct hid_device *hdev,
  92				const struct uclogic_params_frame *frame)
  93{
  94	hid_dbg(hdev, "\t\t.desc_ptr = %p\n", frame->desc_ptr);
  95	hid_dbg(hdev, "\t\t.desc_size = %u\n", frame->desc_size);
  96	hid_dbg(hdev, "\t\t.id = %u\n", frame->id);
  97	hid_dbg(hdev, "\t\t.suffix = %s\n", frame->suffix);
  98	hid_dbg(hdev, "\t\t.re_lsb = %u\n", frame->re_lsb);
  99	hid_dbg(hdev, "\t\t.dev_id_byte = %u\n", frame->dev_id_byte);
 100	hid_dbg(hdev, "\t\t.touch_byte = %u\n", frame->touch_byte);
 101	hid_dbg(hdev, "\t\t.touch_max = %hhd\n", frame->touch_max);
 102	hid_dbg(hdev, "\t\t.touch_flip_at = %hhd\n",
 103		frame->touch_flip_at);
 104	hid_dbg(hdev, "\t\t.bitmap_dial_byte = %u\n",
 105		frame->bitmap_dial_byte);
 106}
 107
 108/**
 109 * uclogic_params_hid_dbg() - Dump tablet interface parameters
 110 * @hdev:	The HID device the parameters describe.
 111 * @params:	The parameters to dump.
 112 *
 113 * Dump tablet interface parameters with hid_dbg().
 114 */
 115void uclogic_params_hid_dbg(const struct hid_device *hdev,
 116				const struct uclogic_params *params)
 117{
 118	size_t i;
 119
 120	hid_dbg(hdev, ".invalid = %s\n",
 121		params->invalid ? "true" : "false");
 122	hid_dbg(hdev, ".desc_ptr = %p\n", params->desc_ptr);
 123	hid_dbg(hdev, ".desc_size = %u\n", params->desc_size);
 124	hid_dbg(hdev, ".pen = {\n");
 125	uclogic_params_pen_hid_dbg(hdev, &params->pen);
 126	hid_dbg(hdev, "\t}\n");
 127	hid_dbg(hdev, ".frame_list = {\n");
 128	for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
 129		hid_dbg(hdev, "\t{\n");
 130		uclogic_params_frame_hid_dbg(hdev, &params->frame_list[i]);
 131		hid_dbg(hdev, "\t}%s\n",
 132			i < (ARRAY_SIZE(params->frame_list) - 1) ? "," : "");
 133	}
 134	hid_dbg(hdev, "}\n");
 135}
 136
 137/**
 138 * uclogic_params_get_str_desc - retrieve a string descriptor from a HID
 139 * device interface, putting it into a kmalloc-allocated buffer as is, without
 140 * character encoding conversion.
 141 *
 142 * @pbuf:	Location for the kmalloc-allocated buffer pointer containing
 143 *		the retrieved descriptor. Not modified in case of error.
 144 *		Can be NULL to have retrieved descriptor discarded.
 145 * @hdev:	The HID device of the tablet interface to retrieve the string
 146 *		descriptor from. Cannot be NULL.
 147 * @idx:	Index of the string descriptor to request from the device.
 148 * @len:	Length of the buffer to allocate and the data to retrieve.
 149 *
 150 * Returns:
 151 *	number of bytes retrieved (<= len),
 152 *	-EPIPE, if the descriptor was not found, or
 153 *	another negative errno code in case of other error.
 154 */
 155static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev,
 156					__u8 idx, size_t len)
 157{
 158	int rc;
 159	struct usb_device *udev;
 160	__u8 *buf = NULL;
 161
 162	/* Check arguments */
 163	if (hdev == NULL) {
 164		rc = -EINVAL;
 165		goto cleanup;
 166	}
 167
 168	udev = hid_to_usb_dev(hdev);
 169
 170	buf = kmalloc(len, GFP_KERNEL);
 171	if (buf == NULL) {
 172		rc = -ENOMEM;
 173		goto cleanup;
 174	}
 175
 176	rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 177				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
 178				(USB_DT_STRING << 8) + idx,
 179				0x0409, buf, len,
 180				USB_CTRL_GET_TIMEOUT);
 181	if (rc == -EPIPE) {
 182		hid_dbg(hdev, "string descriptor #%hhu not found\n", idx);
 183		goto cleanup;
 184	} else if (rc < 0) {
 185		hid_err(hdev,
 186			"failed retrieving string descriptor #%u: %d\n",
 187			idx, rc);
 188		goto cleanup;
 189	}
 190
 191	if (pbuf != NULL) {
 192		*pbuf = buf;
 193		buf = NULL;
 194	}
 195
 196cleanup:
 197	kfree(buf);
 198	return rc;
 199}
 200
 201/**
 202 * uclogic_params_pen_cleanup - free resources used by struct
 203 * uclogic_params_pen (tablet interface's pen input parameters).
 204 * Can be called repeatedly.
 205 *
 206 * @pen:	Pen input parameters to cleanup. Cannot be NULL.
 207 */
 208static void uclogic_params_pen_cleanup(struct uclogic_params_pen *pen)
 209{
 210	kfree(pen->desc_ptr);
 211	memset(pen, 0, sizeof(*pen));
 212}
 213
 214/**
 215 * uclogic_params_pen_init_v1() - initialize tablet interface pen
 216 * input and retrieve its parameters from the device, using v1 protocol.
 217 *
 218 * @pen:	Pointer to the pen parameters to initialize (to be
 219 *		cleaned up with uclogic_params_pen_cleanup()). Not modified in
 220 *		case of error, or if parameters are not found. Cannot be NULL.
 221 * @pfound:	Location for a flag which is set to true if the parameters
 222 *		were found, and to false if not (e.g. device was
 223 *		incompatible). Not modified in case of error. Cannot be NULL.
 224 * @hdev:	The HID device of the tablet interface to initialize and get
 225 *		parameters from. Cannot be NULL.
 226 *
 227 * Returns:
 228 *	Zero, if successful. A negative errno code on error.
 229 */
 230static int uclogic_params_pen_init_v1(struct uclogic_params_pen *pen,
 231				      bool *pfound,
 232				      struct hid_device *hdev)
 233{
 234	int rc;
 235	bool found = false;
 236	/* Buffer for (part of) the string descriptor */
 237	__u8 *buf = NULL;
 238	/* Minimum descriptor length required, maximum seen so far is 18 */
 239	const int len = 12;
 240	s32 resolution;
 241	/* Pen report descriptor template parameters */
 242	s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
 243	__u8 *desc_ptr = NULL;
 244
 245	/* Check arguments */
 246	if (pen == NULL || pfound == NULL || hdev == NULL) {
 247		rc = -EINVAL;
 248		goto cleanup;
 249	}
 250
 251	/*
 252	 * Read string descriptor containing pen input parameters.
 253	 * The specific string descriptor and data were discovered by sniffing
 254	 * the Windows driver traffic.
 255	 * NOTE: This enables fully-functional tablet mode.
 256	 */
 257	rc = uclogic_params_get_str_desc(&buf, hdev, 100, len);
 258	if (rc == -EPIPE) {
 259		hid_dbg(hdev,
 260			"string descriptor with pen parameters not found, assuming not compatible\n");
 261		goto finish;
 262	} else if (rc < 0) {
 263		hid_err(hdev, "failed retrieving pen parameters: %d\n", rc);
 264		goto cleanup;
 265	} else if (rc != len) {
 266		hid_dbg(hdev,
 267			"string descriptor with pen parameters has invalid length (got %d, expected %d), assuming not compatible\n",
 268			rc, len);
 269		goto finish;
 270	}
 271
 272	/*
 273	 * Fill report descriptor parameters from the string descriptor
 274	 */
 275	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] =
 276		get_unaligned_le16(buf + 2);
 277	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] =
 278		get_unaligned_le16(buf + 4);
 279	desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] =
 280		get_unaligned_le16(buf + 8);
 281	resolution = get_unaligned_le16(buf + 10);
 282	if (resolution == 0) {
 283		desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0;
 284		desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0;
 285	} else {
 286		desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] =
 287			desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 /
 288			resolution;
 289		desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] =
 290			desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
 291			resolution;
 292	}
 293	kfree(buf);
 294	buf = NULL;
 295
 296	/*
 297	 * Generate pen report descriptor
 298	 */
 299	desc_ptr = uclogic_rdesc_template_apply(
 300				uclogic_rdesc_v1_pen_template_arr,
 301				uclogic_rdesc_v1_pen_template_size,
 302				desc_params, ARRAY_SIZE(desc_params));
 303	if (desc_ptr == NULL) {
 304		rc = -ENOMEM;
 305		goto cleanup;
 306	}
 307
 308	/*
 309	 * Fill-in the parameters
 310	 */
 311	memset(pen, 0, sizeof(*pen));
 312	pen->desc_ptr = desc_ptr;
 313	desc_ptr = NULL;
 314	pen->desc_size = uclogic_rdesc_v1_pen_template_size;
 315	pen->id = UCLOGIC_RDESC_V1_PEN_ID;
 316	pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_INVERTED;
 317	found = true;
 318finish:
 319	*pfound = found;
 320	rc = 0;
 321cleanup:
 322	kfree(desc_ptr);
 323	kfree(buf);
 324	return rc;
 325}
 326
 327/**
 328 * uclogic_params_get_le24() - get a 24-bit little-endian number from a
 329 * buffer.
 330 *
 331 * @p:	The pointer to the number buffer.
 332 *
 333 * Returns:
 334 *	The retrieved number
 335 */
 336static s32 uclogic_params_get_le24(const void *p)
 337{
 338	const __u8 *b = p;
 339	return b[0] | (b[1] << 8UL) | (b[2] << 16UL);
 340}
 341
 342/**
 343 * uclogic_params_pen_init_v2() - initialize tablet interface pen
 344 * input and retrieve its parameters from the device, using v2 protocol.
 345 *
 346 * @pen:		Pointer to the pen parameters to initialize (to be
 347 *			cleaned up with uclogic_params_pen_cleanup()). Not
 348 *			modified in case of error, or if parameters are not
 349 *			found. Cannot be NULL.
 350 * @pfound:		Location for a flag which is set to true if the
 351 *			parameters were found, and to false if not (e.g.
 352 *			device was incompatible). Not modified in case of
 353 *			error. Cannot be NULL.
 354 * @pparams_ptr:	Location for a kmalloc'ed pointer to the retrieved raw
 355 *			parameters, which could be used to identify the tablet
 356 *			to some extent. Should be freed with kfree after use.
 357 *			NULL, if not needed. Not modified in case of error.
 358 *			Only set if *pfound is set to true.
 359 * @pparams_len:	Location for the length of the retrieved raw
 360 *			parameters. NULL, if not needed. Not modified in case
 361 *			of error. Only set if *pfound is set to true.
 362 * @hdev:		The HID device of the tablet interface to initialize
 363 *			and get parameters from. Cannot be NULL.
 364 *
 365 * Returns:
 366 *	Zero, if successful. A negative errno code on error.
 367 */
 368static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
 369					bool *pfound,
 370					__u8 **pparams_ptr,
 371					size_t *pparams_len,
 372					struct hid_device *hdev)
 373{
 374	int rc;
 375	bool found = false;
 376	/* Buffer for (part of) the parameter string descriptor */
 377	__u8 *buf = NULL;
 378	/* Parameter string descriptor required length */
 379	const int params_len_min = 18;
 380	/* Parameter string descriptor accepted length */
 381	const int params_len_max = 32;
 382	/* Parameter string descriptor received length */
 383	int params_len;
 384	size_t i;
 385	s32 resolution;
 386	/* Pen report descriptor template parameters */
 387	s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
 388	__u8 *desc_ptr = NULL;
 389
 390	/* Check arguments */
 391	if (pen == NULL || pfound == NULL || hdev == NULL) {
 392		rc = -EINVAL;
 393		goto cleanup;
 394	}
 395
 396	/*
 397	 * Read string descriptor containing pen input parameters.
 398	 * The specific string descriptor and data were discovered by sniffing
 399	 * the Windows driver traffic.
 400	 * NOTE: This enables fully-functional tablet mode.
 401	 */
 402	rc = uclogic_params_get_str_desc(&buf, hdev, 200, params_len_max);
 403	if (rc == -EPIPE) {
 404		hid_dbg(hdev,
 405			"string descriptor with pen parameters not found, assuming not compatible\n");
 406		goto finish;
 407	} else if (rc < 0) {
 408		hid_err(hdev, "failed retrieving pen parameters: %d\n", rc);
 409		goto cleanup;
 410	} else if (rc < params_len_min) {
 411		hid_dbg(hdev,
 412			"string descriptor with pen parameters is too short (got %d, expected at least %d), assuming not compatible\n",
 413			rc, params_len_min);
 414		goto finish;
 415	}
 416
 417	params_len = rc;
 418
 419	/*
 420	 * Check it's not just a catch-all UTF-16LE-encoded ASCII
 421	 * string (such as the model name) some tablets put into all
 422	 * unknown string descriptors.
 423	 */
 424	for (i = 2;
 425	     i < params_len &&
 426		(buf[i] >= 0x20 && buf[i] < 0x7f && buf[i + 1] == 0);
 427	     i += 2);
 428	if (i >= params_len) {
 429		hid_dbg(hdev,
 430			"string descriptor with pen parameters seems to contain only text, assuming not compatible\n");
 431		goto finish;
 432	}
 433
 434	/*
 435	 * Fill report descriptor parameters from the string descriptor
 436	 */
 437	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] =
 438		uclogic_params_get_le24(buf + 2);
 439	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] =
 440		uclogic_params_get_le24(buf + 5);
 441	desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] =
 442		get_unaligned_le16(buf + 8);
 443	resolution = get_unaligned_le16(buf + 10);
 444	if (resolution == 0) {
 445		desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0;
 446		desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0;
 447	} else {
 448		desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] =
 449			desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 /
 450			resolution;
 451		desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] =
 452			desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
 453			resolution;
 454	}
 455
 456	/*
 457	 * Generate pen report descriptor
 458	 */
 459	desc_ptr = uclogic_rdesc_template_apply(
 460				uclogic_rdesc_v2_pen_template_arr,
 461				uclogic_rdesc_v2_pen_template_size,
 462				desc_params, ARRAY_SIZE(desc_params));
 463	if (desc_ptr == NULL) {
 464		rc = -ENOMEM;
 465		goto cleanup;
 466	}
 467
 468	/*
 469	 * Fill-in the parameters
 470	 */
 471	memset(pen, 0, sizeof(*pen));
 472	pen->desc_ptr = desc_ptr;
 473	desc_ptr = NULL;
 474	pen->desc_size = uclogic_rdesc_v2_pen_template_size;
 475	pen->id = UCLOGIC_RDESC_V2_PEN_ID;
 476	pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_NONE;
 477	pen->fragmented_hires = true;
 478	pen->tilt_y_flipped = true;
 479	found = true;
 480	if (pparams_ptr != NULL) {
 481		*pparams_ptr = buf;
 482		buf = NULL;
 483	}
 484	if (pparams_len != NULL)
 485		*pparams_len = params_len;
 486
 487finish:
 488	*pfound = found;
 489	rc = 0;
 490cleanup:
 491	kfree(desc_ptr);
 492	kfree(buf);
 493	return rc;
 494}
 495
 496/**
 497 * uclogic_params_frame_cleanup - free resources used by struct
 498 * uclogic_params_frame (tablet interface's frame controls input parameters).
 499 * Can be called repeatedly.
 500 *
 501 * @frame:	Frame controls input parameters to cleanup. Cannot be NULL.
 502 */
 503static void uclogic_params_frame_cleanup(struct uclogic_params_frame *frame)
 504{
 505	kfree(frame->desc_ptr);
 506	memset(frame, 0, sizeof(*frame));
 507}
 508
 509/**
 510 * uclogic_params_frame_init_with_desc() - initialize tablet's frame control
 511 * parameters with a static report descriptor.
 512 *
 513 * @frame:	Pointer to the frame parameters to initialize (to be cleaned
 514 *		up with uclogic_params_frame_cleanup()). Not modified in case
 515 *		of error. Cannot be NULL.
 516 * @desc_ptr:	Report descriptor pointer. Can be NULL, if desc_size is zero.
 517 * @desc_size:	Report descriptor size.
 518 * @id:		Report ID used for frame reports, if they should be tweaked,
 519 *		zero if not.
 520 *
 521 * Returns:
 522 *	Zero, if successful. A negative errno code on error.
 523 */
 524static int uclogic_params_frame_init_with_desc(
 525					struct uclogic_params_frame *frame,
 526					const __u8 *desc_ptr,
 527					size_t desc_size,
 528					unsigned int id)
 529{
 530	__u8 *copy_desc_ptr;
 531
 532	if (frame == NULL || (desc_ptr == NULL && desc_size != 0))
 533		return -EINVAL;
 534
 535	copy_desc_ptr = kmemdup(desc_ptr, desc_size, GFP_KERNEL);
 536	if (copy_desc_ptr == NULL)
 537		return -ENOMEM;
 538
 539	memset(frame, 0, sizeof(*frame));
 540	frame->desc_ptr = copy_desc_ptr;
 541	frame->desc_size = desc_size;
 542	frame->id = id;
 543	return 0;
 544}
 545
 546/**
 547 * uclogic_params_frame_init_v1() - initialize v1 tablet interface frame
 548 * controls.
 549 *
 550 * @frame:	Pointer to the frame parameters to initialize (to be cleaned
 551 *		up with uclogic_params_frame_cleanup()). Not modified in case
 552 *		of error, or if parameters are not found. Cannot be NULL.
 553 * @pfound:	Location for a flag which is set to true if the parameters
 554 *		were found, and to false if not (e.g. device was
 555 *		incompatible). Not modified in case of error. Cannot be NULL.
 556 * @hdev:	The HID device of the tablet interface to initialize and get
 557 *		parameters from. Cannot be NULL.
 558 *
 559 * Returns:
 560 *	Zero, if successful. A negative errno code on error.
 561 */
 562static int uclogic_params_frame_init_v1(struct uclogic_params_frame *frame,
 563					bool *pfound,
 564					struct hid_device *hdev)
 565{
 566	int rc;
 567	bool found = false;
 568	struct usb_device *usb_dev;
 569	char *str_buf = NULL;
 570	const size_t str_len = 16;
 571
 572	/* Check arguments */
 573	if (frame == NULL || pfound == NULL || hdev == NULL) {
 574		rc = -EINVAL;
 575		goto cleanup;
 576	}
 577
 578	usb_dev = hid_to_usb_dev(hdev);
 579
 580	/*
 581	 * Enable generic button mode
 582	 */
 583	str_buf = kzalloc(str_len, GFP_KERNEL);
 584	if (str_buf == NULL) {
 585		rc = -ENOMEM;
 586		goto cleanup;
 587	}
 588
 589	rc = usb_string(usb_dev, 123, str_buf, str_len);
 590	if (rc == -EPIPE) {
 591		hid_dbg(hdev,
 592			"generic button -enabling string descriptor not found\n");
 593	} else if (rc < 0) {
 594		goto cleanup;
 595	} else if (strncmp(str_buf, "HK On", rc) != 0) {
 596		hid_dbg(hdev,
 597			"invalid response to enabling generic buttons: \"%s\"\n",
 598			str_buf);
 599	} else {
 600		hid_dbg(hdev, "generic buttons enabled\n");
 601		rc = uclogic_params_frame_init_with_desc(
 602				frame,
 603				uclogic_rdesc_v1_frame_arr,
 604				uclogic_rdesc_v1_frame_size,
 605				UCLOGIC_RDESC_V1_FRAME_ID);
 606		if (rc != 0)
 607			goto cleanup;
 608		found = true;
 609	}
 610
 611	*pfound = found;
 612	rc = 0;
 613cleanup:
 614	kfree(str_buf);
 615	return rc;
 616}
 617
 618/**
 619 * uclogic_params_cleanup_event_hooks - free resources used by the list of raw
 620 * event hooks.
 621 * Can be called repeatedly.
 622 *
 623 * @params: Input parameters to cleanup. Cannot be NULL.
 624 */
 625static void uclogic_params_cleanup_event_hooks(struct uclogic_params *params)
 626{
 627	struct uclogic_raw_event_hook *curr, *n;
 628
 629	if (!params || !params->event_hooks)
 630		return;
 631
 632	list_for_each_entry_safe(curr, n, &params->event_hooks->list, list) {
 633		cancel_work_sync(&curr->work);
 634		list_del(&curr->list);
 635		kfree(curr->event);
 636		kfree(curr);
 637	}
 638
 639	kfree(params->event_hooks);
 640	params->event_hooks = NULL;
 641}
 642
 643/**
 644 * uclogic_params_cleanup - free resources used by struct uclogic_params
 645 * (tablet interface's parameters).
 646 * Can be called repeatedly.
 647 *
 648 * @params:	Input parameters to cleanup. Cannot be NULL.
 649 */
 650void uclogic_params_cleanup(struct uclogic_params *params)
 651{
 652	if (!params->invalid) {
 653		size_t i;
 654		kfree(params->desc_ptr);
 655		uclogic_params_pen_cleanup(&params->pen);
 656		for (i = 0; i < ARRAY_SIZE(params->frame_list); i++)
 657			uclogic_params_frame_cleanup(&params->frame_list[i]);
 658
 659		uclogic_params_cleanup_event_hooks(params);
 660		memset(params, 0, sizeof(*params));
 661	}
 662}
 663
 664/**
 665 * uclogic_params_get_desc() - Get a replacement report descriptor for a
 666 *                             tablet's interface.
 667 *
 668 * @params:	The parameters of a tablet interface to get report
 669 *		descriptor for. Cannot be NULL.
 670 * @pdesc:	Location for the resulting, kmalloc-allocated report
 671 *		descriptor pointer, or for NULL, if there's no replacement
 672 *		report descriptor. Not modified in case of error. Cannot be
 673 *		NULL.
 674 * @psize:	Location for the resulting report descriptor size, not set if
 675 *		there's no replacement report descriptor. Not modified in case
 676 *		of error. Cannot be NULL.
 677 *
 678 * Returns:
 679 *	Zero, if successful.
 680 *	-EINVAL, if invalid arguments are supplied.
 681 *	-ENOMEM, if failed to allocate memory.
 682 */
 683int uclogic_params_get_desc(const struct uclogic_params *params,
 684				const __u8 **pdesc,
 685				unsigned int *psize)
 686{
 687	int rc = -ENOMEM;
 688	bool present = false;
 689	unsigned int size = 0;
 690	__u8 *desc = NULL;
 691	size_t i;
 692
 693	/* Check arguments */
 694	if (params == NULL || pdesc == NULL || psize == NULL)
 695		return -EINVAL;
 696
 697	/* Concatenate descriptors */
 698#define ADD_DESC(_desc_ptr, _desc_size) \
 699	do {                                                        \
 700		unsigned int new_size;                              \
 701		__u8 *new_desc;                                     \
 702		if ((_desc_ptr) == NULL) {                          \
 703			break;                                      \
 704		}                                                   \
 705		new_size = size + (_desc_size);                     \
 706		new_desc = krealloc(desc, new_size, GFP_KERNEL);    \
 707		if (new_desc == NULL) {                             \
 708			goto cleanup;                               \
 709		}                                                   \
 710		memcpy(new_desc + size, (_desc_ptr), (_desc_size)); \
 711		desc = new_desc;                                    \
 712		size = new_size;                                    \
 713		present = true;                                     \
 714	} while (0)
 715
 716	ADD_DESC(params->desc_ptr, params->desc_size);
 717	ADD_DESC(params->pen.desc_ptr, params->pen.desc_size);
 718	for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
 719		ADD_DESC(params->frame_list[i].desc_ptr,
 720				params->frame_list[i].desc_size);
 721	}
 722
 723#undef ADD_DESC
 724
 725	if (present) {
 726		*pdesc = desc;
 727		*psize = size;
 728		desc = NULL;
 729	}
 730	rc = 0;
 731cleanup:
 732	kfree(desc);
 733	return rc;
 734}
 735
 736/**
 737 * uclogic_params_init_invalid() - initialize tablet interface parameters,
 738 * specifying the interface is invalid.
 739 *
 740 * @params:		Parameters to initialize (to be cleaned with
 741 *			uclogic_params_cleanup()). Cannot be NULL.
 742 */
 743static void uclogic_params_init_invalid(struct uclogic_params *params)
 744{
 745	params->invalid = true;
 746}
 747
 748/**
 749 * uclogic_params_init_with_opt_desc() - initialize tablet interface
 750 * parameters with an optional replacement report descriptor. Only modify
 751 * report descriptor, if the original report descriptor matches the expected
 752 * size.
 753 *
 754 * @params:		Parameters to initialize (to be cleaned with
 755 *			uclogic_params_cleanup()). Not modified in case of
 756 *			error. Cannot be NULL.
 757 * @hdev:		The HID device of the tablet interface create the
 758 *			parameters for. Cannot be NULL.
 759 * @orig_desc_size:	Expected size of the original report descriptor to
 760 *			be replaced.
 761 * @desc_ptr:		Pointer to the replacement report descriptor.
 762 *			Can be NULL, if desc_size is zero.
 763 * @desc_size:		Size of the replacement report descriptor.
 764 *
 765 * Returns:
 766 *	Zero, if successful. -EINVAL if an invalid argument was passed.
 767 *	-ENOMEM, if failed to allocate memory.
 768 */
 769static int uclogic_params_init_with_opt_desc(struct uclogic_params *params,
 770					     struct hid_device *hdev,
 771					     unsigned int orig_desc_size,
 772					     const __u8 *desc_ptr,
 773					     unsigned int desc_size)
 774{
 775	__u8 *desc_copy_ptr = NULL;
 776	unsigned int desc_copy_size;
 777	int rc;
 778
 779	/* Check arguments */
 780	if (params == NULL || hdev == NULL ||
 781	    (desc_ptr == NULL && desc_size != 0)) {
 782		rc = -EINVAL;
 783		goto cleanup;
 784	}
 785
 786	/* Replace report descriptor, if it matches */
 787	if (hdev->dev_rsize == orig_desc_size) {
 788		hid_dbg(hdev,
 789			"device report descriptor matches the expected size, replacing\n");
 790		desc_copy_ptr = kmemdup(desc_ptr, desc_size, GFP_KERNEL);
 791		if (desc_copy_ptr == NULL) {
 792			rc = -ENOMEM;
 793			goto cleanup;
 794		}
 795		desc_copy_size = desc_size;
 796	} else {
 797		hid_dbg(hdev,
 798			"device report descriptor doesn't match the expected size (%u != %u), preserving\n",
 799			hdev->dev_rsize, orig_desc_size);
 800		desc_copy_ptr = NULL;
 801		desc_copy_size = 0;
 802	}
 803
 804	/* Output parameters */
 805	memset(params, 0, sizeof(*params));
 806	params->desc_ptr = desc_copy_ptr;
 807	desc_copy_ptr = NULL;
 808	params->desc_size = desc_copy_size;
 809
 810	rc = 0;
 811cleanup:
 812	kfree(desc_copy_ptr);
 813	return rc;
 814}
 815
 816/**
 817 * uclogic_params_huion_init() - initialize a Huion tablet interface and discover
 818 * its parameters.
 819 *
 820 * @params:	Parameters to fill in (to be cleaned with
 821 *		uclogic_params_cleanup()). Not modified in case of error.
 822 *		Cannot be NULL.
 823 * @hdev:	The HID device of the tablet interface to initialize and get
 824 *		parameters from. Cannot be NULL.
 825 *
 826 * Returns:
 827 *	Zero, if successful. A negative errno code on error.
 828 */
 829static int uclogic_params_huion_init(struct uclogic_params *params,
 830				     struct hid_device *hdev)
 831{
 832	int rc;
 833	struct usb_device *udev;
 834	struct usb_interface *iface;
 835	__u8 bInterfaceNumber;
 836	bool found;
 837	/* The resulting parameters (noop) */
 838	struct uclogic_params p = {0, };
 839	static const char transition_ver[] = "HUION_T153_160607";
 840	char *ver_ptr = NULL;
 841	const size_t ver_len = sizeof(transition_ver) + 1;
 842	__u8 *params_ptr = NULL;
 843	size_t params_len = 0;
 844	/* Parameters string descriptor of a model with touch ring (HS610) */
 845	const __u8 touch_ring_model_params_buf[] = {
 846		0x13, 0x03, 0x70, 0xC6, 0x00, 0x06, 0x7C, 0x00,
 847		0xFF, 0x1F, 0xD8, 0x13, 0x03, 0x0D, 0x10, 0x01,
 848		0x04, 0x3C, 0x3E
 849	};
 850
 851	/* Check arguments */
 852	if (params == NULL || hdev == NULL) {
 853		rc = -EINVAL;
 854		goto cleanup;
 855	}
 856
 857	udev = hid_to_usb_dev(hdev);
 858	iface = to_usb_interface(hdev->dev.parent);
 859	bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
 860
 861	/* If it's a custom keyboard interface */
 862	if (bInterfaceNumber == 1) {
 863		/* Keep everything intact, but mark pen usage invalid */
 864		p.pen.usage_invalid = true;
 865		goto output;
 866	/* Else, if it's not a pen interface */
 867	} else if (bInterfaceNumber != 0) {
 868		uclogic_params_init_invalid(&p);
 869		goto output;
 870	}
 871
 872	/* Try to get firmware version */
 873	ver_ptr = kzalloc(ver_len, GFP_KERNEL);
 874	if (ver_ptr == NULL) {
 875		rc = -ENOMEM;
 876		goto cleanup;
 877	}
 878	rc = usb_string(udev, 201, ver_ptr, ver_len);
 879	if (rc == -EPIPE) {
 880		*ver_ptr = '\0';
 881	} else if (rc < 0) {
 882		hid_err(hdev,
 883			"failed retrieving Huion firmware version: %d\n", rc);
 884		goto cleanup;
 885	}
 886
 887	/* The firmware is used in userspace as unique identifier */
 888	strscpy(hdev->uniq, ver_ptr, sizeof(hdev->uniq));
 889
 890	/* If this is a transition firmware */
 891	if (strcmp(ver_ptr, transition_ver) == 0) {
 892		hid_dbg(hdev,
 893			"transition firmware detected, not probing pen v2 parameters\n");
 894	} else {
 895		/* Try to probe v2 pen parameters */
 896		rc = uclogic_params_pen_init_v2(&p.pen, &found,
 897						&params_ptr, &params_len,
 898						hdev);
 899		if (rc != 0) {
 900			hid_err(hdev,
 901				"failed probing pen v2 parameters: %d\n", rc);
 902			goto cleanup;
 903		} else if (found) {
 904			hid_dbg(hdev, "pen v2 parameters found\n");
 905			/* Create v2 frame button parameters */
 906			rc = uclogic_params_frame_init_with_desc(
 907					&p.frame_list[0],
 908					uclogic_rdesc_v2_frame_buttons_arr,
 909					uclogic_rdesc_v2_frame_buttons_size,
 910					UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID);
 911			if (rc != 0) {
 912				hid_err(hdev,
 913					"failed creating v2 frame button parameters: %d\n",
 914					rc);
 915				goto cleanup;
 916			}
 917
 918			/* Link from pen sub-report */
 919			p.pen.subreport_list[0].value = 0xe0;
 920			p.pen.subreport_list[0].id =
 921				UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID;
 922
 923			/* If this is the model with touch ring */
 924			if (params_ptr != NULL &&
 925			    params_len == sizeof(touch_ring_model_params_buf) &&
 926			    memcmp(params_ptr, touch_ring_model_params_buf,
 927				   params_len) == 0) {
 928				/* Create touch ring parameters */
 929				rc = uclogic_params_frame_init_with_desc(
 930					&p.frame_list[1],
 931					uclogic_rdesc_v2_frame_touch_ring_arr,
 932					uclogic_rdesc_v2_frame_touch_ring_size,
 933					UCLOGIC_RDESC_V2_FRAME_TOUCH_ID);
 934				if (rc != 0) {
 935					hid_err(hdev,
 936						"failed creating v2 frame touch ring parameters: %d\n",
 937						rc);
 938					goto cleanup;
 939				}
 940				p.frame_list[1].suffix = "Touch Ring";
 941				p.frame_list[1].dev_id_byte =
 942					UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE;
 943				p.frame_list[1].touch_byte = 5;
 944				p.frame_list[1].touch_max = 12;
 945				p.frame_list[1].touch_flip_at = 7;
 946			} else {
 947				/* Create touch strip parameters */
 948				rc = uclogic_params_frame_init_with_desc(
 949					&p.frame_list[1],
 950					uclogic_rdesc_v2_frame_touch_strip_arr,
 951					uclogic_rdesc_v2_frame_touch_strip_size,
 952					UCLOGIC_RDESC_V2_FRAME_TOUCH_ID);
 953				if (rc != 0) {
 954					hid_err(hdev,
 955						"failed creating v2 frame touch strip parameters: %d\n",
 956						rc);
 957					goto cleanup;
 958				}
 959				p.frame_list[1].suffix = "Touch Strip";
 960				p.frame_list[1].dev_id_byte =
 961					UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE;
 962				p.frame_list[1].touch_byte = 5;
 963				p.frame_list[1].touch_max = 8;
 964			}
 965
 966			/* Link from pen sub-report */
 967			p.pen.subreport_list[1].value = 0xf0;
 968			p.pen.subreport_list[1].id =
 969				UCLOGIC_RDESC_V2_FRAME_TOUCH_ID;
 970
 971			/* Create v2 frame dial parameters */
 972			rc = uclogic_params_frame_init_with_desc(
 973					&p.frame_list[2],
 974					uclogic_rdesc_v2_frame_dial_arr,
 975					uclogic_rdesc_v2_frame_dial_size,
 976					UCLOGIC_RDESC_V2_FRAME_DIAL_ID);
 977			if (rc != 0) {
 978				hid_err(hdev,
 979					"failed creating v2 frame dial parameters: %d\n",
 980					rc);
 981				goto cleanup;
 982			}
 983			p.frame_list[2].suffix = "Dial";
 984			p.frame_list[2].dev_id_byte =
 985				UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE;
 986			p.frame_list[2].bitmap_dial_byte = 5;
 987
 988			/* Link from pen sub-report */
 989			p.pen.subreport_list[2].value = 0xf1;
 990			p.pen.subreport_list[2].id =
 991				UCLOGIC_RDESC_V2_FRAME_DIAL_ID;
 992
 993			goto output;
 994		}
 995		hid_dbg(hdev, "pen v2 parameters not found\n");
 996	}
 997
 998	/* Try to probe v1 pen parameters */
 999	rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1000	if (rc != 0) {
1001		hid_err(hdev,
1002			"failed probing pen v1 parameters: %d\n", rc);
1003		goto cleanup;
1004	} else if (found) {
1005		hid_dbg(hdev, "pen v1 parameters found\n");
1006		/* Try to probe v1 frame */
1007		rc = uclogic_params_frame_init_v1(&p.frame_list[0],
1008						  &found, hdev);
1009		if (rc != 0) {
1010			hid_err(hdev, "v1 frame probing failed: %d\n", rc);
1011			goto cleanup;
1012		}
1013		hid_dbg(hdev, "frame v1 parameters%s found\n",
1014			(found ? "" : " not"));
1015		if (found) {
1016			/* Link frame button subreports from pen reports */
1017			p.pen.subreport_list[0].value = 0xe0;
1018			p.pen.subreport_list[0].id =
1019				UCLOGIC_RDESC_V1_FRAME_ID;
1020		}
1021		goto output;
1022	}
1023	hid_dbg(hdev, "pen v1 parameters not found\n");
1024
1025	uclogic_params_init_invalid(&p);
1026
1027output:
1028	/* Output parameters */
1029	memcpy(params, &p, sizeof(*params));
1030	memset(&p, 0, sizeof(p));
1031	rc = 0;
1032cleanup:
1033	kfree(params_ptr);
1034	kfree(ver_ptr);
1035	uclogic_params_cleanup(&p);
1036	return rc;
1037}
1038
1039/**
1040 * uclogic_probe_interface() - some tablets, like the Parblo A610 PLUS V2 or
1041 * the XP-PEN Deco Mini 7, need to be initialized by sending them magic data.
1042 *
1043 * @hdev:	The HID device of the tablet interface to initialize and get
1044 *		parameters from. Cannot be NULL.
1045 * @magic_arr:	The magic data that should be sent to probe the interface.
1046 *		Cannot be NULL.
1047 * @magic_size:	Size of the magic data.
1048 * @endpoint:	Endpoint where the magic data should be sent.
1049 *
1050 * Returns:
1051 *	Zero, if successful. A negative errno code on error.
1052 */
1053static int uclogic_probe_interface(struct hid_device *hdev, const u8 *magic_arr,
1054				   size_t magic_size, int endpoint)
1055{
1056	struct usb_device *udev;
1057	unsigned int pipe = 0;
1058	int sent;
1059	u8 *buf = NULL;
1060	int rc = 0;
1061
1062	if (!hdev || !magic_arr) {
1063		rc = -EINVAL;
1064		goto cleanup;
1065	}
1066
1067	buf = kmemdup(magic_arr, magic_size, GFP_KERNEL);
1068	if (!buf) {
1069		rc = -ENOMEM;
1070		goto cleanup;
1071	}
1072
1073	udev = hid_to_usb_dev(hdev);
1074	pipe = usb_sndintpipe(udev, endpoint);
1075
1076	rc = usb_interrupt_msg(udev, pipe, buf, magic_size, &sent, 1000);
1077	if (rc || sent != magic_size) {
1078		hid_err(hdev, "Interface probing failed: %d\n", rc);
1079		rc = -1;
1080		goto cleanup;
1081	}
1082
1083	rc = 0;
1084cleanup:
1085	kfree(buf);
1086	return rc;
1087}
1088
1089/**
1090 * uclogic_params_parse_ugee_v2_desc - parse the string descriptor containing
1091 * pen and frame parameters returned by UGEE v2 devices.
1092 *
1093 * @str_desc:		String descriptor, cannot be NULL.
1094 * @str_desc_size:	Size of the string descriptor.
1095 * @desc_params:	Output description params list.
1096 * @desc_params_size:	Size of the output description params list.
1097 * @frame_type:		Output frame type.
1098 *
1099 * Returns:
1100 *	Zero, if successful. A negative errno code on error.
1101 */
1102static int uclogic_params_parse_ugee_v2_desc(const __u8 *str_desc,
1103					     size_t str_desc_size,
1104					     s32 *desc_params,
1105					     size_t desc_params_size,
1106					     enum uclogic_params_frame_type *frame_type)
1107{
1108	s32 pen_x_lm, pen_y_lm;
1109	s32 pen_x_pm, pen_y_pm;
1110	s32 pen_pressure_lm;
1111	s32 frame_num_buttons;
1112	s32 resolution;
1113
1114	/* Minimum descriptor length required, maximum seen so far is 14 */
1115	const int min_str_desc_size = 12;
1116
1117	if (!str_desc || str_desc_size < min_str_desc_size)
1118		return -EINVAL;
1119
1120	if (desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
1121		return -EINVAL;
1122
1123	pen_x_lm = get_unaligned_le16(str_desc + 2);
1124	pen_y_lm = get_unaligned_le16(str_desc + 4);
1125	frame_num_buttons = str_desc[6];
1126	*frame_type = str_desc[7];
1127	pen_pressure_lm = get_unaligned_le16(str_desc + 8);
1128
1129	resolution = get_unaligned_le16(str_desc + 10);
1130	if (resolution == 0) {
1131		pen_x_pm = 0;
1132		pen_y_pm = 0;
1133	} else {
1134		pen_x_pm = pen_x_lm * 1000 / resolution;
1135		pen_y_pm = pen_y_lm * 1000 / resolution;
1136	}
1137
1138	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = pen_x_lm;
1139	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = pen_x_pm;
1140	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = pen_y_lm;
1141	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = pen_y_pm;
1142	desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = pen_pressure_lm;
1143	desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = frame_num_buttons;
1144
1145	return 0;
1146}
1147
1148/**
1149 * uclogic_params_ugee_v2_init_frame_buttons() - initialize a UGEE v2 frame with
1150 * buttons.
1151 * @p:			Parameters to fill in, cannot be NULL.
1152 * @desc_params:	Device description params list.
1153 * @desc_params_size:	Size of the description params list.
1154 *
1155 * Returns:
1156 *	Zero, if successful. A negative errno code on error.
1157 */
1158static int uclogic_params_ugee_v2_init_frame_buttons(struct uclogic_params *p,
1159						     const s32 *desc_params,
1160						     size_t desc_params_size)
1161{
1162	__u8 *rdesc_frame = NULL;
1163	int rc = 0;
1164
1165	if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
1166		return -EINVAL;
1167
1168	rdesc_frame = uclogic_rdesc_template_apply(
1169				uclogic_rdesc_ugee_v2_frame_btn_template_arr,
1170				uclogic_rdesc_ugee_v2_frame_btn_template_size,
1171				desc_params, UCLOGIC_RDESC_PH_ID_NUM);
1172	if (!rdesc_frame)
1173		return -ENOMEM;
1174
1175	rc = uclogic_params_frame_init_with_desc(&p->frame_list[0],
1176						 rdesc_frame,
1177						 uclogic_rdesc_ugee_v2_frame_btn_template_size,
1178						 UCLOGIC_RDESC_V1_FRAME_ID);
1179	kfree(rdesc_frame);
1180	return rc;
1181}
1182
1183/**
1184 * uclogic_params_ugee_v2_init_frame_dial() - initialize a UGEE v2 frame with a
1185 * bitmap dial.
1186 * @p:			Parameters to fill in, cannot be NULL.
1187 * @desc_params:	Device description params list.
1188 * @desc_params_size:	Size of the description params list.
1189 *
1190 * Returns:
1191 *	Zero, if successful. A negative errno code on error.
1192 */
1193static int uclogic_params_ugee_v2_init_frame_dial(struct uclogic_params *p,
1194						  const s32 *desc_params,
1195						  size_t desc_params_size)
1196{
1197	__u8 *rdesc_frame = NULL;
1198	int rc = 0;
1199
1200	if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
1201		return -EINVAL;
1202
1203	rdesc_frame = uclogic_rdesc_template_apply(
1204				uclogic_rdesc_ugee_v2_frame_dial_template_arr,
1205				uclogic_rdesc_ugee_v2_frame_dial_template_size,
1206				desc_params, UCLOGIC_RDESC_PH_ID_NUM);
1207	if (!rdesc_frame)
1208		return -ENOMEM;
1209
1210	rc = uclogic_params_frame_init_with_desc(&p->frame_list[0],
1211						 rdesc_frame,
1212						 uclogic_rdesc_ugee_v2_frame_dial_template_size,
1213						 UCLOGIC_RDESC_V1_FRAME_ID);
1214	kfree(rdesc_frame);
1215	if (rc)
1216		return rc;
1217
1218	p->frame_list[0].bitmap_dial_byte = 7;
1219	return 0;
1220}
1221
1222/**
1223 * uclogic_params_ugee_v2_init_frame_mouse() - initialize a UGEE v2 frame with a
1224 * mouse.
1225 * @p:			Parameters to fill in, cannot be NULL.
1226 *
1227 * Returns:
1228 *	Zero, if successful. A negative errno code on error.
1229 */
1230static int uclogic_params_ugee_v2_init_frame_mouse(struct uclogic_params *p)
1231{
1232	int rc = 0;
1233
1234	if (!p)
1235		return -EINVAL;
1236
1237	rc = uclogic_params_frame_init_with_desc(&p->frame_list[1],
1238						 uclogic_rdesc_ugee_v2_frame_mouse_template_arr,
1239						 uclogic_rdesc_ugee_v2_frame_mouse_template_size,
1240						 UCLOGIC_RDESC_V1_FRAME_ID);
1241	return rc;
1242}
1243
1244/**
1245 * uclogic_params_ugee_v2_has_battery() - check whether a UGEE v2 device has
1246 * battery or not.
1247 * @hdev:	The HID device of the tablet interface.
1248 *
1249 * Returns:
1250 *	True if the device has battery, false otherwise.
1251 */
1252static bool uclogic_params_ugee_v2_has_battery(struct hid_device *hdev)
1253{
1254	struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
1255
1256	if (drvdata->quirks & UCLOGIC_BATTERY_QUIRK)
1257		return true;
1258
1259	/* The XP-PEN Deco LW vendor, product and version are identical to the
1260	 * Deco L. The only difference reported by their firmware is the product
1261	 * name. Add a quirk to support battery reporting on the wireless
1262	 * version.
1263	 */
1264	if (hdev->vendor == USB_VENDOR_ID_UGEE &&
1265	    hdev->product == USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) {
1266		struct usb_device *udev = hid_to_usb_dev(hdev);
1267
1268		if (strstarts(udev->product, "Deco LW"))
1269			return true;
1270	}
1271
1272	return false;
1273}
1274
1275/**
1276 * uclogic_params_ugee_v2_init_battery() - initialize UGEE v2 battery reporting.
1277 * @hdev:	The HID device of the tablet interface, cannot be NULL.
1278 * @p:		Parameters to fill in, cannot be NULL.
1279 *
1280 * Returns:
1281 *	Zero, if successful. A negative errno code on error.
1282 */
1283static int uclogic_params_ugee_v2_init_battery(struct hid_device *hdev,
1284					       struct uclogic_params *p)
1285{
1286	int rc = 0;
1287
1288	if (!hdev || !p)
1289		return -EINVAL;
1290
1291	/* Some tablets contain invalid characters in hdev->uniq, throwing a
1292	 * "hwmon: '<name>' is not a valid name attribute, please fix" error.
1293	 * Use the device vendor and product IDs instead.
1294	 */
1295	snprintf(hdev->uniq, sizeof(hdev->uniq), "%x-%x", hdev->vendor,
1296		 hdev->product);
1297
1298	rc = uclogic_params_frame_init_with_desc(&p->frame_list[1],
1299						 uclogic_rdesc_ugee_v2_battery_template_arr,
1300						 uclogic_rdesc_ugee_v2_battery_template_size,
1301						 UCLOGIC_RDESC_UGEE_V2_BATTERY_ID);
1302	if (rc)
1303		return rc;
1304
1305	p->frame_list[1].suffix = "Battery";
1306	p->pen.subreport_list[1].value = 0xf2;
1307	p->pen.subreport_list[1].id = UCLOGIC_RDESC_UGEE_V2_BATTERY_ID;
1308
1309	return rc;
1310}
1311
1312/**
1313 * uclogic_params_ugee_v2_reconnect_work() - When a wireless tablet looses
1314 * connection to the USB dongle and reconnects, either because of its physical
1315 * distance or because it was switches off and on using the frame's switch,
1316 * uclogic_probe_interface() needs to be called again to enable the tablet.
1317 *
1318 * @work: The work that triggered this function.
1319 */
1320static void uclogic_params_ugee_v2_reconnect_work(struct work_struct *work)
1321{
1322	struct uclogic_raw_event_hook *event_hook;
1323
1324	event_hook = container_of(work, struct uclogic_raw_event_hook, work);
1325	uclogic_probe_interface(event_hook->hdev, uclogic_ugee_v2_probe_arr,
1326				uclogic_ugee_v2_probe_size,
1327				uclogic_ugee_v2_probe_endpoint);
1328}
1329
1330/**
1331 * uclogic_params_ugee_v2_init_event_hooks() - initialize the list of events
1332 * to be hooked for UGEE v2 devices.
1333 * @hdev:	The HID device of the tablet interface to initialize and get
1334 *		parameters from.
1335 * @p:		Parameters to fill in, cannot be NULL.
1336 *
1337 * Returns:
1338 *	Zero, if successful. A negative errno code on error.
1339 */
1340static int uclogic_params_ugee_v2_init_event_hooks(struct hid_device *hdev,
1341						   struct uclogic_params *p)
1342{
1343	struct uclogic_raw_event_hook *event_hook;
1344	__u8 reconnect_event[] = {
1345		/* Event received on wireless tablet reconnection */
1346		0x02, 0xF8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1347	};
1348
1349	if (!p)
1350		return -EINVAL;
1351
1352	/* The reconnection event is only received if the tablet has battery */
1353	if (!uclogic_params_ugee_v2_has_battery(hdev))
1354		return 0;
1355
1356	p->event_hooks = kzalloc(sizeof(*p->event_hooks), GFP_KERNEL);
1357	if (!p->event_hooks)
1358		return -ENOMEM;
1359
1360	INIT_LIST_HEAD(&p->event_hooks->list);
1361
1362	event_hook = kzalloc(sizeof(*event_hook), GFP_KERNEL);
1363	if (!event_hook)
1364		return -ENOMEM;
1365
1366	INIT_WORK(&event_hook->work, uclogic_params_ugee_v2_reconnect_work);
1367	event_hook->hdev = hdev;
1368	event_hook->size = ARRAY_SIZE(reconnect_event);
1369	event_hook->event = kmemdup(reconnect_event, event_hook->size, GFP_KERNEL);
1370	if (!event_hook->event)
1371		return -ENOMEM;
1372
1373	list_add_tail(&event_hook->list, &p->event_hooks->list);
1374
1375	return 0;
1376}
1377
1378/**
1379 * uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
1380 * discovering their parameters.
1381 *
1382 * These tables, internally designed as v2 to differentiate them from older
1383 * models, expect a payload of magic data in orther to be switched to the fully
1384 * functional mode and expose their parameters in a similar way to the
1385 * information present in uclogic_params_pen_init_v1() but with some
1386 * differences.
1387 *
1388 * @params:	Parameters to fill in (to be cleaned with
1389 *		uclogic_params_cleanup()). Not modified in case of error.
1390 *		Cannot be NULL.
1391 * @hdev:	The HID device of the tablet interface to initialize and get
1392 *		parameters from. Cannot be NULL.
1393 *
1394 * Returns:
1395 *	Zero, if successful. A negative errno code on error.
1396 */
1397static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
1398				       struct hid_device *hdev)
1399{
1400	int rc = 0;
1401	struct uclogic_drvdata *drvdata;
1402	struct usb_interface *iface;
1403	__u8 bInterfaceNumber;
1404	const int str_desc_len = 12;
1405	__u8 *str_desc = NULL;
1406	__u8 *rdesc_pen = NULL;
1407	s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
1408	enum uclogic_params_frame_type frame_type;
1409	/* The resulting parameters (noop) */
1410	struct uclogic_params p = {0, };
1411
1412	if (!params || !hdev) {
1413		rc = -EINVAL;
1414		goto cleanup;
1415	}
1416
1417	drvdata = hid_get_drvdata(hdev);
1418	iface = to_usb_interface(hdev->dev.parent);
1419	bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
1420
1421	if (bInterfaceNumber == 0) {
1422		rc = uclogic_params_ugee_v2_init_frame_mouse(&p);
1423		if (rc)
1424			goto cleanup;
1425
1426		goto output;
1427	}
1428
1429	if (bInterfaceNumber != 2) {
1430		uclogic_params_init_invalid(&p);
1431		goto output;
1432	}
1433
1434	/*
1435	 * Initialize the interface by sending magic data.
1436	 * The specific data was discovered by sniffing the Windows driver
1437	 * traffic.
1438	 */
1439	rc = uclogic_probe_interface(hdev, uclogic_ugee_v2_probe_arr,
1440				     uclogic_ugee_v2_probe_size,
1441				     uclogic_ugee_v2_probe_endpoint);
1442	if (rc) {
1443		uclogic_params_init_invalid(&p);
1444		goto output;
1445	}
1446
1447	/*
1448	 * Read the string descriptor containing pen and frame parameters.
1449	 * The specific string descriptor and data were discovered by sniffing
1450	 * the Windows driver traffic.
1451	 */
1452	rc = uclogic_params_get_str_desc(&str_desc, hdev, 100, str_desc_len);
1453	if (rc != str_desc_len) {
1454		hid_err(hdev, "failed retrieving pen and frame parameters: %d\n", rc);
1455		uclogic_params_init_invalid(&p);
1456		goto output;
1457	}
1458
1459	rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len,
1460					       desc_params,
1461					       ARRAY_SIZE(desc_params),
1462					       &frame_type);
1463	if (rc)
1464		goto cleanup;
1465
1466	kfree(str_desc);
1467	str_desc = NULL;
1468
1469	/* Initialize the pen interface */
1470	rdesc_pen = uclogic_rdesc_template_apply(
1471				uclogic_rdesc_ugee_v2_pen_template_arr,
1472				uclogic_rdesc_ugee_v2_pen_template_size,
1473				desc_params, ARRAY_SIZE(desc_params));
1474	if (!rdesc_pen) {
1475		rc = -ENOMEM;
1476		goto cleanup;
1477	}
1478
1479	p.pen.desc_ptr = rdesc_pen;
1480	p.pen.desc_size = uclogic_rdesc_ugee_v2_pen_template_size;
1481	p.pen.id = 0x02;
1482	p.pen.subreport_list[0].value = 0xf0;
1483	p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID;
1484
1485	/* Initialize the frame interface */
1486	if (drvdata->quirks & UCLOGIC_MOUSE_FRAME_QUIRK)
1487		frame_type = UCLOGIC_PARAMS_FRAME_MOUSE;
1488
1489	switch (frame_type) {
1490	case UCLOGIC_PARAMS_FRAME_DIAL:
1491	case UCLOGIC_PARAMS_FRAME_MOUSE:
1492		rc = uclogic_params_ugee_v2_init_frame_dial(&p, desc_params,
1493							    ARRAY_SIZE(desc_params));
1494		break;
1495	case UCLOGIC_PARAMS_FRAME_BUTTONS:
1496	default:
1497		rc = uclogic_params_ugee_v2_init_frame_buttons(&p, desc_params,
1498							       ARRAY_SIZE(desc_params));
1499		break;
1500	}
1501
1502	if (rc)
1503		goto cleanup;
1504
1505	/* Initialize the battery interface*/
1506	if (uclogic_params_ugee_v2_has_battery(hdev)) {
1507		rc = uclogic_params_ugee_v2_init_battery(hdev, &p);
1508		if (rc) {
1509			hid_err(hdev, "error initializing battery: %d\n", rc);
1510			goto cleanup;
1511		}
1512	}
1513
1514	/* Create a list of raw events to be ignored */
1515	rc = uclogic_params_ugee_v2_init_event_hooks(hdev, &p);
1516	if (rc) {
1517		hid_err(hdev, "error initializing event hook list: %d\n", rc);
1518		goto cleanup;
1519	}
1520
1521output:
1522	/* Output parameters */
1523	memcpy(params, &p, sizeof(*params));
1524	memset(&p, 0, sizeof(p));
1525	rc = 0;
1526cleanup:
1527	kfree(str_desc);
1528	uclogic_params_cleanup(&p);
1529	return rc;
1530}
1531
1532/**
1533 * uclogic_params_init() - initialize a tablet interface and discover its
1534 * parameters.
1535 *
1536 * @params:	Parameters to fill in (to be cleaned with
1537 *		uclogic_params_cleanup()). Not modified in case of error.
1538 *		Cannot be NULL.
1539 * @hdev:	The HID device of the tablet interface to initialize and get
1540 *		parameters from. Cannot be NULL. Must be using the USB low-level
1541 *		driver, i.e. be an actual USB tablet.
1542 *
1543 * Returns:
1544 *	Zero, if successful. A negative errno code on error.
1545 */
1546int uclogic_params_init(struct uclogic_params *params,
1547			struct hid_device *hdev)
1548{
1549	int rc;
1550	struct usb_device *udev;
1551	__u8  bNumInterfaces;
1552	struct usb_interface *iface;
1553	__u8 bInterfaceNumber;
1554	bool found;
1555	/* The resulting parameters (noop) */
1556	struct uclogic_params p = {0, };
1557
1558	/* Check arguments */
1559	if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) {
1560		rc = -EINVAL;
1561		goto cleanup;
1562	}
1563
1564	udev = hid_to_usb_dev(hdev);
1565	bNumInterfaces = udev->config->desc.bNumInterfaces;
1566	iface = to_usb_interface(hdev->dev.parent);
1567	bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
1568
1569	/*
1570	 * Set replacement report descriptor if the original matches the
1571	 * specified size. Otherwise keep interface unchanged.
1572	 */
1573#define WITH_OPT_DESC(_orig_desc_token, _new_desc_token) \
1574	uclogic_params_init_with_opt_desc(                  \
1575		&p, hdev,                                   \
1576		UCLOGIC_RDESC_##_orig_desc_token##_SIZE,    \
1577		uclogic_rdesc_##_new_desc_token##_arr,      \
1578		uclogic_rdesc_##_new_desc_token##_size)
1579
1580#define VID_PID(_vid, _pid) \
1581	(((__u32)(_vid) << 16) | ((__u32)(_pid) & U16_MAX))
1582
1583	/*
1584	 * Handle specific interfaces for specific tablets.
1585	 *
1586	 * Observe the following logic:
1587	 *
1588	 * If the interface is recognized as producing certain useful input:
1589	 *	Mark interface as valid.
1590	 *	Output interface parameters.
1591	 * Else, if the interface is recognized as *not* producing any useful
1592	 * input:
1593	 *	Mark interface as invalid.
1594	 * Else:
1595	 *	Mark interface as valid.
1596	 *	Output noop parameters.
1597	 *
1598	 * Rule of thumb: it is better to disable a broken interface than let
1599	 *		  it spew garbage input.
1600	 */
1601
1602	switch (VID_PID(hdev->vendor, hdev->product)) {
1603	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1604		     USB_DEVICE_ID_UCLOGIC_TABLET_PF1209):
1605		rc = WITH_OPT_DESC(PF1209_ORIG, pf1209_fixed);
1606		if (rc != 0)
1607			goto cleanup;
1608		break;
1609	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1610		     USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U):
1611		rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp4030u_fixed);
1612		if (rc != 0)
1613			goto cleanup;
1614		break;
1615	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1616		     USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U):
1617		if (hdev->dev_rsize == UCLOGIC_RDESC_WP5540U_V2_ORIG_SIZE) {
1618			if (bInterfaceNumber == 0) {
1619				/* Try to probe v1 pen parameters */
1620				rc = uclogic_params_pen_init_v1(&p.pen,
1621								&found, hdev);
1622				if (rc != 0) {
1623					hid_err(hdev,
1624						"pen probing failed: %d\n",
1625						rc);
1626					goto cleanup;
1627				}
1628				if (!found) {
1629					hid_warn(hdev,
1630						 "pen parameters not found");
1631				}
1632			} else {
1633				uclogic_params_init_invalid(&p);
1634			}
1635		} else {
1636			rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp5540u_fixed);
1637			if (rc != 0)
1638				goto cleanup;
1639		}
1640		break;
1641	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1642		     USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U):
1643		rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp8060u_fixed);
1644		if (rc != 0)
1645			goto cleanup;
1646		break;
1647	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1648		     USB_DEVICE_ID_UCLOGIC_TABLET_WP1062):
1649		rc = WITH_OPT_DESC(WP1062_ORIG, wp1062_fixed);
1650		if (rc != 0)
1651			goto cleanup;
1652		break;
1653	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1654		     USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850):
1655		switch (bInterfaceNumber) {
1656		case 0:
1657			rc = WITH_OPT_DESC(TWHL850_ORIG0, twhl850_fixed0);
1658			if (rc != 0)
1659				goto cleanup;
1660			break;
1661		case 1:
1662			rc = WITH_OPT_DESC(TWHL850_ORIG1, twhl850_fixed1);
1663			if (rc != 0)
1664				goto cleanup;
1665			break;
1666		case 2:
1667			rc = WITH_OPT_DESC(TWHL850_ORIG2, twhl850_fixed2);
1668			if (rc != 0)
1669				goto cleanup;
1670			break;
1671		}
1672		break;
1673	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1674		     USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60):
1675		/*
1676		 * If it is not a three-interface version, which is known to
1677		 * respond to initialization.
1678		 */
1679		if (bNumInterfaces != 3) {
1680			switch (bInterfaceNumber) {
1681			case 0:
1682				rc = WITH_OPT_DESC(TWHA60_ORIG0,
1683							twha60_fixed0);
1684				if (rc != 0)
1685					goto cleanup;
1686				break;
1687			case 1:
1688				rc = WITH_OPT_DESC(TWHA60_ORIG1,
1689							twha60_fixed1);
1690				if (rc != 0)
1691					goto cleanup;
1692				break;
1693			}
1694			break;
1695		}
1696		fallthrough;
1697	case VID_PID(USB_VENDOR_ID_HUION,
1698		     USB_DEVICE_ID_HUION_TABLET):
1699	case VID_PID(USB_VENDOR_ID_HUION,
1700		     USB_DEVICE_ID_HUION_TABLET2):
1701	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1702		     USB_DEVICE_ID_HUION_TABLET):
1703	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1704		     USB_DEVICE_ID_YIYNOVA_TABLET):
1705	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1706		     USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_81):
1707	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1708		     USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3):
1709	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1710		     USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_45):
1711	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1712		     USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_47):
1713		rc = uclogic_params_huion_init(&p, hdev);
1714		if (rc != 0)
1715			goto cleanup;
1716		break;
1717	case VID_PID(USB_VENDOR_ID_UGTIZER,
1718		     USB_DEVICE_ID_UGTIZER_TABLET_GP0610):
1719	case VID_PID(USB_VENDOR_ID_UGTIZER,
1720		     USB_DEVICE_ID_UGTIZER_TABLET_GT5040):
1721	case VID_PID(USB_VENDOR_ID_UGEE,
1722		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540):
1723	case VID_PID(USB_VENDOR_ID_UGEE,
1724		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640):
1725	case VID_PID(USB_VENDOR_ID_UGEE,
1726		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06):
1727	case VID_PID(USB_VENDOR_ID_UGEE,
1728		     USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720):
1729		/* If this is the pen interface */
1730		if (bInterfaceNumber == 1) {
1731			/* Probe v1 pen parameters */
1732			rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1733			if (rc != 0) {
1734				hid_err(hdev, "pen probing failed: %d\n", rc);
1735				goto cleanup;
1736			}
1737			if (!found) {
1738				hid_warn(hdev, "pen parameters not found");
1739				uclogic_params_init_invalid(&p);
1740			}
1741		} else {
1742			uclogic_params_init_invalid(&p);
1743		}
1744		break;
1745	case VID_PID(USB_VENDOR_ID_UGEE,
1746		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01):
1747		/* If this is the pen and frame interface */
1748		if (bInterfaceNumber == 1) {
1749			/* Probe v1 pen parameters */
1750			rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1751			if (rc != 0) {
1752				hid_err(hdev, "pen probing failed: %d\n", rc);
1753				goto cleanup;
1754			}
1755			/* Initialize frame parameters */
1756			rc = uclogic_params_frame_init_with_desc(
1757				&p.frame_list[0],
1758				uclogic_rdesc_xppen_deco01_frame_arr,
1759				uclogic_rdesc_xppen_deco01_frame_size,
1760				0);
1761			if (rc != 0)
1762				goto cleanup;
1763		} else {
1764			uclogic_params_init_invalid(&p);
1765		}
1766		break;
1767	case VID_PID(USB_VENDOR_ID_UGEE,
1768		     USB_DEVICE_ID_UGEE_PARBLO_A610_PRO):
1769	case VID_PID(USB_VENDOR_ID_UGEE,
1770		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01_V2):
1771	case VID_PID(USB_VENDOR_ID_UGEE,
1772		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L):
1773	case VID_PID(USB_VENDOR_ID_UGEE,
1774		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_MW):
1775	case VID_PID(USB_VENDOR_ID_UGEE,
1776		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S):
1777	case VID_PID(USB_VENDOR_ID_UGEE,
1778		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW):
1779		rc = uclogic_params_ugee_v2_init(&p, hdev);
1780		if (rc != 0)
1781			goto cleanup;
1782		break;
1783	case VID_PID(USB_VENDOR_ID_TRUST,
1784		     USB_DEVICE_ID_TRUST_PANORA_TABLET):
1785	case VID_PID(USB_VENDOR_ID_UGEE,
1786		     USB_DEVICE_ID_UGEE_TABLET_G5):
1787		/* Ignore non-pen interfaces */
1788		if (bInterfaceNumber != 1) {
1789			uclogic_params_init_invalid(&p);
1790			break;
1791		}
1792
1793		rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1794		if (rc != 0) {
1795			hid_err(hdev, "pen probing failed: %d\n", rc);
1796			goto cleanup;
1797		} else if (found) {
1798			rc = uclogic_params_frame_init_with_desc(
1799				&p.frame_list[0],
1800				uclogic_rdesc_ugee_g5_frame_arr,
1801				uclogic_rdesc_ugee_g5_frame_size,
1802				UCLOGIC_RDESC_UGEE_G5_FRAME_ID);
1803			if (rc != 0) {
1804				hid_err(hdev,
1805					"failed creating frame parameters: %d\n",
1806					rc);
1807				goto cleanup;
1808			}
1809			p.frame_list[0].re_lsb =
1810				UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB;
1811			p.frame_list[0].dev_id_byte =
1812				UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE;
1813		} else {
1814			hid_warn(hdev, "pen parameters not found");
1815			uclogic_params_init_invalid(&p);
1816		}
1817
1818		break;
1819	case VID_PID(USB_VENDOR_ID_UGEE,
1820		     USB_DEVICE_ID_UGEE_TABLET_EX07S):
1821		/* Ignore non-pen interfaces */
1822		if (bInterfaceNumber != 1) {
1823			uclogic_params_init_invalid(&p);
1824			break;
1825		}
1826
1827		rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1828		if (rc != 0) {
1829			hid_err(hdev, "pen probing failed: %d\n", rc);
1830			goto cleanup;
1831		} else if (found) {
1832			rc = uclogic_params_frame_init_with_desc(
1833				&p.frame_list[0],
1834				uclogic_rdesc_ugee_ex07_frame_arr,
1835				uclogic_rdesc_ugee_ex07_frame_size,
1836				0);
1837			if (rc != 0) {
1838				hid_err(hdev,
1839					"failed creating frame parameters: %d\n",
1840					rc);
1841				goto cleanup;
1842			}
1843		} else {
1844			hid_warn(hdev, "pen parameters not found");
1845			uclogic_params_init_invalid(&p);
1846		}
1847
1848		break;
1849	}
1850
1851#undef VID_PID
1852#undef WITH_OPT_DESC
1853
1854	/* Output parameters */
1855	memcpy(params, &p, sizeof(*params));
1856	memset(&p, 0, sizeof(p));
1857	rc = 0;
1858cleanup:
1859	uclogic_params_cleanup(&p);
1860	return rc;
1861}
1862
1863#ifdef CONFIG_HID_KUNIT_TEST
1864#include "hid-uclogic-params-test.c"
1865#endif