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 <asm/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  */
33 static 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  */
56 static 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  */
90 static 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  */
115 void 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  */
155 static 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 
196 cleanup:
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  */
208 static 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  */
230 static 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;
318 finish:
319 	*pfound = found;
320 	rc = 0;
321 cleanup:
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  */
336 static 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  */
368 static 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 
487 finish:
488 	*pfound = found;
489 	rc = 0;
490 cleanup:
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  */
503 static 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  */
524 static 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  */
562 static 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;
613 cleanup:
614 	kfree(str_buf);
615 	return rc;
616 }
617 
618 /**
619  * uclogic_params_cleanup - free resources used by struct uclogic_params
620  * (tablet interface's parameters).
621  * Can be called repeatedly.
622  *
623  * @params:	Input parameters to cleanup. Cannot be NULL.
624  */
625 void uclogic_params_cleanup(struct uclogic_params *params)
626 {
627 	if (!params->invalid) {
628 		size_t i;
629 		kfree(params->desc_ptr);
630 		uclogic_params_pen_cleanup(&params->pen);
631 		for (i = 0; i < ARRAY_SIZE(params->frame_list); i++)
632 			uclogic_params_frame_cleanup(&params->frame_list[i]);
633 
634 		memset(params, 0, sizeof(*params));
635 	}
636 }
637 
638 /**
639  * uclogic_params_get_desc() - Get a replacement report descriptor for a
640  *                             tablet's interface.
641  *
642  * @params:	The parameters of a tablet interface to get report
643  *		descriptor for. Cannot be NULL.
644  * @pdesc:	Location for the resulting, kmalloc-allocated report
645  *		descriptor pointer, or for NULL, if there's no replacement
646  *		report descriptor. Not modified in case of error. Cannot be
647  *		NULL.
648  * @psize:	Location for the resulting report descriptor size, not set if
649  *		there's no replacement report descriptor. Not modified in case
650  *		of error. Cannot be NULL.
651  *
652  * Returns:
653  *	Zero, if successful.
654  *	-EINVAL, if invalid arguments are supplied.
655  *	-ENOMEM, if failed to allocate memory.
656  */
657 int uclogic_params_get_desc(const struct uclogic_params *params,
658 				__u8 **pdesc,
659 				unsigned int *psize)
660 {
661 	int rc = -ENOMEM;
662 	bool present = false;
663 	unsigned int size = 0;
664 	__u8 *desc = NULL;
665 	size_t i;
666 
667 	/* Check arguments */
668 	if (params == NULL || pdesc == NULL || psize == NULL)
669 		return -EINVAL;
670 
671 	/* Concatenate descriptors */
672 #define ADD_DESC(_desc_ptr, _desc_size) \
673 	do {                                                        \
674 		unsigned int new_size;                              \
675 		__u8 *new_desc;                                     \
676 		if ((_desc_ptr) == NULL) {                          \
677 			break;                                      \
678 		}                                                   \
679 		new_size = size + (_desc_size);                     \
680 		new_desc = krealloc(desc, new_size, GFP_KERNEL);    \
681 		if (new_desc == NULL) {                             \
682 			goto cleanup;                               \
683 		}                                                   \
684 		memcpy(new_desc + size, (_desc_ptr), (_desc_size)); \
685 		desc = new_desc;                                    \
686 		size = new_size;                                    \
687 		present = true;                                     \
688 	} while (0)
689 
690 	ADD_DESC(params->desc_ptr, params->desc_size);
691 	ADD_DESC(params->pen.desc_ptr, params->pen.desc_size);
692 	for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
693 		ADD_DESC(params->frame_list[i].desc_ptr,
694 				params->frame_list[i].desc_size);
695 	}
696 
697 #undef ADD_DESC
698 
699 	if (present) {
700 		*pdesc = desc;
701 		*psize = size;
702 		desc = NULL;
703 	}
704 	rc = 0;
705 cleanup:
706 	kfree(desc);
707 	return rc;
708 }
709 
710 /**
711  * uclogic_params_init_invalid() - initialize tablet interface parameters,
712  * specifying the interface is invalid.
713  *
714  * @params:		Parameters to initialize (to be cleaned with
715  *			uclogic_params_cleanup()). Cannot be NULL.
716  */
717 static void uclogic_params_init_invalid(struct uclogic_params *params)
718 {
719 	params->invalid = true;
720 }
721 
722 /**
723  * uclogic_params_init_with_opt_desc() - initialize tablet interface
724  * parameters with an optional replacement report descriptor. Only modify
725  * report descriptor, if the original report descriptor matches the expected
726  * size.
727  *
728  * @params:		Parameters to initialize (to be cleaned with
729  *			uclogic_params_cleanup()). Not modified in case of
730  *			error. Cannot be NULL.
731  * @hdev:		The HID device of the tablet interface create the
732  *			parameters for. Cannot be NULL.
733  * @orig_desc_size:	Expected size of the original report descriptor to
734  *			be replaced.
735  * @desc_ptr:		Pointer to the replacement report descriptor.
736  *			Can be NULL, if desc_size is zero.
737  * @desc_size:		Size of the replacement report descriptor.
738  *
739  * Returns:
740  *	Zero, if successful. -EINVAL if an invalid argument was passed.
741  *	-ENOMEM, if failed to allocate memory.
742  */
743 static int uclogic_params_init_with_opt_desc(struct uclogic_params *params,
744 					     struct hid_device *hdev,
745 					     unsigned int orig_desc_size,
746 					     __u8 *desc_ptr,
747 					     unsigned int desc_size)
748 {
749 	__u8 *desc_copy_ptr = NULL;
750 	unsigned int desc_copy_size;
751 	int rc;
752 
753 	/* Check arguments */
754 	if (params == NULL || hdev == NULL ||
755 	    (desc_ptr == NULL && desc_size != 0)) {
756 		rc = -EINVAL;
757 		goto cleanup;
758 	}
759 
760 	/* Replace report descriptor, if it matches */
761 	if (hdev->dev_rsize == orig_desc_size) {
762 		hid_dbg(hdev,
763 			"device report descriptor matches the expected size, replacing\n");
764 		desc_copy_ptr = kmemdup(desc_ptr, desc_size, GFP_KERNEL);
765 		if (desc_copy_ptr == NULL) {
766 			rc = -ENOMEM;
767 			goto cleanup;
768 		}
769 		desc_copy_size = desc_size;
770 	} else {
771 		hid_dbg(hdev,
772 			"device report descriptor doesn't match the expected size (%u != %u), preserving\n",
773 			hdev->dev_rsize, orig_desc_size);
774 		desc_copy_ptr = NULL;
775 		desc_copy_size = 0;
776 	}
777 
778 	/* Output parameters */
779 	memset(params, 0, sizeof(*params));
780 	params->desc_ptr = desc_copy_ptr;
781 	desc_copy_ptr = NULL;
782 	params->desc_size = desc_copy_size;
783 
784 	rc = 0;
785 cleanup:
786 	kfree(desc_copy_ptr);
787 	return rc;
788 }
789 
790 /**
791  * uclogic_params_huion_init() - initialize a Huion tablet interface and discover
792  * its parameters.
793  *
794  * @params:	Parameters to fill in (to be cleaned with
795  *		uclogic_params_cleanup()). Not modified in case of error.
796  *		Cannot be NULL.
797  * @hdev:	The HID device of the tablet interface to initialize and get
798  *		parameters from. Cannot be NULL.
799  *
800  * Returns:
801  *	Zero, if successful. A negative errno code on error.
802  */
803 static int uclogic_params_huion_init(struct uclogic_params *params,
804 				     struct hid_device *hdev)
805 {
806 	int rc;
807 	struct usb_device *udev;
808 	struct usb_interface *iface;
809 	__u8 bInterfaceNumber;
810 	bool found;
811 	/* The resulting parameters (noop) */
812 	struct uclogic_params p = {0, };
813 	static const char transition_ver[] = "HUION_T153_160607";
814 	char *ver_ptr = NULL;
815 	const size_t ver_len = sizeof(transition_ver) + 1;
816 	__u8 *params_ptr = NULL;
817 	size_t params_len = 0;
818 	/* Parameters string descriptor of a model with touch ring (HS610) */
819 	const __u8 touch_ring_model_params_buf[] = {
820 		0x13, 0x03, 0x70, 0xC6, 0x00, 0x06, 0x7C, 0x00,
821 		0xFF, 0x1F, 0xD8, 0x13, 0x03, 0x0D, 0x10, 0x01,
822 		0x04, 0x3C, 0x3E
823 	};
824 
825 	/* Check arguments */
826 	if (params == NULL || hdev == NULL) {
827 		rc = -EINVAL;
828 		goto cleanup;
829 	}
830 
831 	udev = hid_to_usb_dev(hdev);
832 	iface = to_usb_interface(hdev->dev.parent);
833 	bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
834 
835 	/* If it's a custom keyboard interface */
836 	if (bInterfaceNumber == 1) {
837 		/* Keep everything intact, but mark pen usage invalid */
838 		p.pen.usage_invalid = true;
839 		goto output;
840 	/* Else, if it's not a pen interface */
841 	} else if (bInterfaceNumber != 0) {
842 		uclogic_params_init_invalid(&p);
843 		goto output;
844 	}
845 
846 	/* Try to get firmware version */
847 	ver_ptr = kzalloc(ver_len, GFP_KERNEL);
848 	if (ver_ptr == NULL) {
849 		rc = -ENOMEM;
850 		goto cleanup;
851 	}
852 	rc = usb_string(udev, 201, ver_ptr, ver_len);
853 	if (rc == -EPIPE) {
854 		*ver_ptr = '\0';
855 	} else if (rc < 0) {
856 		hid_err(hdev,
857 			"failed retrieving Huion firmware version: %d\n", rc);
858 		goto cleanup;
859 	}
860 
861 	/* If this is a transition firmware */
862 	if (strcmp(ver_ptr, transition_ver) == 0) {
863 		hid_dbg(hdev,
864 			"transition firmware detected, not probing pen v2 parameters\n");
865 	} else {
866 		/* Try to probe v2 pen parameters */
867 		rc = uclogic_params_pen_init_v2(&p.pen, &found,
868 						&params_ptr, &params_len,
869 						hdev);
870 		if (rc != 0) {
871 			hid_err(hdev,
872 				"failed probing pen v2 parameters: %d\n", rc);
873 			goto cleanup;
874 		} else if (found) {
875 			hid_dbg(hdev, "pen v2 parameters found\n");
876 			/* Create v2 frame button parameters */
877 			rc = uclogic_params_frame_init_with_desc(
878 					&p.frame_list[0],
879 					uclogic_rdesc_v2_frame_buttons_arr,
880 					uclogic_rdesc_v2_frame_buttons_size,
881 					UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID);
882 			if (rc != 0) {
883 				hid_err(hdev,
884 					"failed creating v2 frame button parameters: %d\n",
885 					rc);
886 				goto cleanup;
887 			}
888 
889 			/* Link from pen sub-report */
890 			p.pen.subreport_list[0].value = 0xe0;
891 			p.pen.subreport_list[0].id =
892 				UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID;
893 
894 			/* If this is the model with touch ring */
895 			if (params_ptr != NULL &&
896 			    params_len == sizeof(touch_ring_model_params_buf) &&
897 			    memcmp(params_ptr, touch_ring_model_params_buf,
898 				   params_len) == 0) {
899 				/* Create touch ring parameters */
900 				rc = uclogic_params_frame_init_with_desc(
901 					&p.frame_list[1],
902 					uclogic_rdesc_v2_frame_touch_ring_arr,
903 					uclogic_rdesc_v2_frame_touch_ring_size,
904 					UCLOGIC_RDESC_V2_FRAME_TOUCH_ID);
905 				if (rc != 0) {
906 					hid_err(hdev,
907 						"failed creating v2 frame touch ring parameters: %d\n",
908 						rc);
909 					goto cleanup;
910 				}
911 				p.frame_list[1].suffix = "Touch Ring";
912 				p.frame_list[1].dev_id_byte =
913 					UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE;
914 				p.frame_list[1].touch_byte = 5;
915 				p.frame_list[1].touch_max = 12;
916 				p.frame_list[1].touch_flip_at = 7;
917 			} else {
918 				/* Create touch strip parameters */
919 				rc = uclogic_params_frame_init_with_desc(
920 					&p.frame_list[1],
921 					uclogic_rdesc_v2_frame_touch_strip_arr,
922 					uclogic_rdesc_v2_frame_touch_strip_size,
923 					UCLOGIC_RDESC_V2_FRAME_TOUCH_ID);
924 				if (rc != 0) {
925 					hid_err(hdev,
926 						"failed creating v2 frame touch strip parameters: %d\n",
927 						rc);
928 					goto cleanup;
929 				}
930 				p.frame_list[1].suffix = "Touch Strip";
931 				p.frame_list[1].dev_id_byte =
932 					UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE;
933 				p.frame_list[1].touch_byte = 5;
934 				p.frame_list[1].touch_max = 8;
935 			}
936 
937 			/* Link from pen sub-report */
938 			p.pen.subreport_list[1].value = 0xf0;
939 			p.pen.subreport_list[1].id =
940 				UCLOGIC_RDESC_V2_FRAME_TOUCH_ID;
941 
942 			/* Create v2 frame dial parameters */
943 			rc = uclogic_params_frame_init_with_desc(
944 					&p.frame_list[2],
945 					uclogic_rdesc_v2_frame_dial_arr,
946 					uclogic_rdesc_v2_frame_dial_size,
947 					UCLOGIC_RDESC_V2_FRAME_DIAL_ID);
948 			if (rc != 0) {
949 				hid_err(hdev,
950 					"failed creating v2 frame dial parameters: %d\n",
951 					rc);
952 				goto cleanup;
953 			}
954 			p.frame_list[2].suffix = "Dial";
955 			p.frame_list[2].dev_id_byte =
956 				UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE;
957 			p.frame_list[2].bitmap_dial_byte = 5;
958 
959 			/* Link from pen sub-report */
960 			p.pen.subreport_list[2].value = 0xf1;
961 			p.pen.subreport_list[2].id =
962 				UCLOGIC_RDESC_V2_FRAME_DIAL_ID;
963 
964 			goto output;
965 		}
966 		hid_dbg(hdev, "pen v2 parameters not found\n");
967 	}
968 
969 	/* Try to probe v1 pen parameters */
970 	rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
971 	if (rc != 0) {
972 		hid_err(hdev,
973 			"failed probing pen v1 parameters: %d\n", rc);
974 		goto cleanup;
975 	} else if (found) {
976 		hid_dbg(hdev, "pen v1 parameters found\n");
977 		/* Try to probe v1 frame */
978 		rc = uclogic_params_frame_init_v1(&p.frame_list[0],
979 						  &found, hdev);
980 		if (rc != 0) {
981 			hid_err(hdev, "v1 frame probing failed: %d\n", rc);
982 			goto cleanup;
983 		}
984 		hid_dbg(hdev, "frame v1 parameters%s found\n",
985 			(found ? "" : " not"));
986 		if (found) {
987 			/* Link frame button subreports from pen reports */
988 			p.pen.subreport_list[0].value = 0xe0;
989 			p.pen.subreport_list[0].id =
990 				UCLOGIC_RDESC_V1_FRAME_ID;
991 		}
992 		goto output;
993 	}
994 	hid_dbg(hdev, "pen v1 parameters not found\n");
995 
996 	uclogic_params_init_invalid(&p);
997 
998 output:
999 	/* Output parameters */
1000 	memcpy(params, &p, sizeof(*params));
1001 	memset(&p, 0, sizeof(p));
1002 	rc = 0;
1003 cleanup:
1004 	kfree(params_ptr);
1005 	kfree(ver_ptr);
1006 	uclogic_params_cleanup(&p);
1007 	return rc;
1008 }
1009 
1010 /**
1011  * uclogic_probe_interface() - some tablets, like the Parblo A610 PLUS V2 or
1012  * the XP-PEN Deco Mini 7, need to be initialized by sending them magic data.
1013  *
1014  * @hdev:	The HID device of the tablet interface to initialize and get
1015  *		parameters from. Cannot be NULL.
1016  * @magic_arr:	The magic data that should be sent to probe the interface.
1017  *		Cannot be NULL.
1018  * @magic_size:	Size of the magic data.
1019  * @endpoint:	Endpoint where the magic data should be sent.
1020  *
1021  * Returns:
1022  *	Zero, if successful. A negative errno code on error.
1023  */
1024 static int uclogic_probe_interface(struct hid_device *hdev, u8 *magic_arr,
1025 				   int magic_size, int endpoint)
1026 {
1027 	struct usb_device *udev;
1028 	unsigned int pipe = 0;
1029 	int sent;
1030 	u8 *buf = NULL;
1031 	int rc = 0;
1032 
1033 	if (!hdev || !magic_arr) {
1034 		rc = -EINVAL;
1035 		goto cleanup;
1036 	}
1037 
1038 	buf = kmemdup(magic_arr, magic_size, GFP_KERNEL);
1039 	if (!buf) {
1040 		rc = -ENOMEM;
1041 		goto cleanup;
1042 	}
1043 
1044 	udev = hid_to_usb_dev(hdev);
1045 	pipe = usb_sndintpipe(udev, endpoint);
1046 
1047 	rc = usb_interrupt_msg(udev, pipe, buf, magic_size, &sent, 1000);
1048 	if (rc || sent != magic_size) {
1049 		hid_err(hdev, "Interface probing failed: %d\n", rc);
1050 		rc = -1;
1051 		goto cleanup;
1052 	}
1053 
1054 	rc = 0;
1055 cleanup:
1056 	kfree(buf);
1057 	return rc;
1058 }
1059 
1060 /**
1061  * uclogic_params_parse_ugee_v2_desc - parse the string descriptor containing
1062  * pen and frame parameters returned by UGEE v2 devices.
1063  *
1064  * @str_desc:		String descriptor, cannot be NULL.
1065  * @str_desc_size:	Size of the string descriptor.
1066  * @desc_params:	Output description params list.
1067  * @desc_params_size:	Size of the output description params list.
1068  * @frame_type:		Output frame type.
1069  *
1070  * Returns:
1071  *	Zero, if successful. A negative errno code on error.
1072  */
1073 static int uclogic_params_parse_ugee_v2_desc(const __u8 *str_desc,
1074 					     size_t str_desc_size,
1075 					     s32 *desc_params,
1076 					     size_t desc_params_size,
1077 					     enum uclogic_params_frame_type *frame_type)
1078 {
1079 	s32 pen_x_lm, pen_y_lm;
1080 	s32 pen_x_pm, pen_y_pm;
1081 	s32 pen_pressure_lm;
1082 	s32 frame_num_buttons;
1083 	s32 resolution;
1084 
1085 	/* Minimum descriptor length required, maximum seen so far is 14 */
1086 	const int min_str_desc_size = 12;
1087 
1088 	if (!str_desc || str_desc_size < min_str_desc_size)
1089 		return -EINVAL;
1090 
1091 	if (desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
1092 		return -EINVAL;
1093 
1094 	pen_x_lm = get_unaligned_le16(str_desc + 2);
1095 	pen_y_lm = get_unaligned_le16(str_desc + 4);
1096 	frame_num_buttons = str_desc[6];
1097 	*frame_type = str_desc[7];
1098 	pen_pressure_lm = get_unaligned_le16(str_desc + 8);
1099 
1100 	resolution = get_unaligned_le16(str_desc + 10);
1101 	if (resolution == 0) {
1102 		pen_x_pm = 0;
1103 		pen_y_pm = 0;
1104 	} else {
1105 		pen_x_pm = pen_x_lm * 1000 / resolution;
1106 		pen_y_pm = pen_y_lm * 1000 / resolution;
1107 	}
1108 
1109 	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = pen_x_lm;
1110 	desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = pen_x_pm;
1111 	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = pen_y_lm;
1112 	desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = pen_y_pm;
1113 	desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = pen_pressure_lm;
1114 	desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = frame_num_buttons;
1115 
1116 	return 0;
1117 }
1118 
1119 /**
1120  * uclogic_params_ugee_v2_init_frame_buttons() - initialize a UGEE v2 frame with
1121  * buttons.
1122  * @p:			Parameters to fill in, cannot be NULL.
1123  * @desc_params:	Device description params list.
1124  * @desc_params_size:	Size of the description params list.
1125  *
1126  * Returns:
1127  *	Zero, if successful. A negative errno code on error.
1128  */
1129 static int uclogic_params_ugee_v2_init_frame_buttons(struct uclogic_params *p,
1130 						     const s32 *desc_params,
1131 						     size_t desc_params_size)
1132 {
1133 	__u8 *rdesc_frame = NULL;
1134 	int rc = 0;
1135 
1136 	if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
1137 		return -EINVAL;
1138 
1139 	rdesc_frame = uclogic_rdesc_template_apply(
1140 				uclogic_rdesc_ugee_v2_frame_btn_template_arr,
1141 				uclogic_rdesc_ugee_v2_frame_btn_template_size,
1142 				desc_params, UCLOGIC_RDESC_PH_ID_NUM);
1143 	if (!rdesc_frame)
1144 		return -ENOMEM;
1145 
1146 	rc = uclogic_params_frame_init_with_desc(&p->frame_list[0],
1147 						 rdesc_frame,
1148 						 uclogic_rdesc_ugee_v2_frame_btn_template_size,
1149 						 UCLOGIC_RDESC_V1_FRAME_ID);
1150 	kfree(rdesc_frame);
1151 	return rc;
1152 }
1153 
1154 /**
1155  * uclogic_params_ugee_v2_init_frame_dial() - initialize a UGEE v2 frame with a
1156  * bitmap dial.
1157  * @p:			Parameters to fill in, cannot be NULL.
1158  * @desc_params:	Device description params list.
1159  * @desc_params_size:	Size of the description params list.
1160  *
1161  * Returns:
1162  *	Zero, if successful. A negative errno code on error.
1163  */
1164 static int uclogic_params_ugee_v2_init_frame_dial(struct uclogic_params *p,
1165 						  const s32 *desc_params,
1166 						  size_t desc_params_size)
1167 {
1168 	__u8 *rdesc_frame = NULL;
1169 	int rc = 0;
1170 
1171 	if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
1172 		return -EINVAL;
1173 
1174 	rdesc_frame = uclogic_rdesc_template_apply(
1175 				uclogic_rdesc_ugee_v2_frame_dial_template_arr,
1176 				uclogic_rdesc_ugee_v2_frame_dial_template_size,
1177 				desc_params, UCLOGIC_RDESC_PH_ID_NUM);
1178 	if (!rdesc_frame)
1179 		return -ENOMEM;
1180 
1181 	rc = uclogic_params_frame_init_with_desc(&p->frame_list[0],
1182 						 rdesc_frame,
1183 						 uclogic_rdesc_ugee_v2_frame_dial_template_size,
1184 						 UCLOGIC_RDESC_V1_FRAME_ID);
1185 	kfree(rdesc_frame);
1186 	if (rc)
1187 		return rc;
1188 
1189 	p->frame_list[0].bitmap_dial_byte = 7;
1190 	return 0;
1191 }
1192 
1193 /**
1194  * uclogic_params_ugee_v2_init_frame_mouse() - initialize a UGEE v2 frame with a
1195  * mouse.
1196  * @p:			Parameters to fill in, cannot be NULL.
1197  *
1198  * Returns:
1199  *	Zero, if successful. A negative errno code on error.
1200  */
1201 static int uclogic_params_ugee_v2_init_frame_mouse(struct uclogic_params *p)
1202 {
1203 	int rc = 0;
1204 
1205 	if (!p)
1206 		return -EINVAL;
1207 
1208 	rc = uclogic_params_frame_init_with_desc(&p->frame_list[1],
1209 						 uclogic_rdesc_ugee_v2_frame_mouse_template_arr,
1210 						 uclogic_rdesc_ugee_v2_frame_mouse_template_size,
1211 						 UCLOGIC_RDESC_V1_FRAME_ID);
1212 	return rc;
1213 }
1214 
1215 /**
1216  * uclogic_params_ugee_v2_has_battery() - check whether a UGEE v2 device has
1217  * battery or not.
1218  * @hdev:	The HID device of the tablet interface.
1219  *
1220  * Returns:
1221  *	True if the device has battery, false otherwise.
1222  */
1223 static bool uclogic_params_ugee_v2_has_battery(struct hid_device *hdev)
1224 {
1225 	/* The XP-PEN Deco LW vendor, product and version are identical to the
1226 	 * Deco L. The only difference reported by their firmware is the product
1227 	 * name. Add a quirk to support battery reporting on the wireless
1228 	 * version.
1229 	 */
1230 	if (hdev->vendor == USB_VENDOR_ID_UGEE &&
1231 	    hdev->product == USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) {
1232 		struct usb_device *udev = hid_to_usb_dev(hdev);
1233 
1234 		if (strstarts(udev->product, "Deco LW"))
1235 			return true;
1236 	}
1237 
1238 	return false;
1239 }
1240 
1241 /**
1242  * uclogic_params_ugee_v2_init_battery() - initialize UGEE v2 battery reporting.
1243  * @hdev:	The HID device of the tablet interface, cannot be NULL.
1244  * @p:		Parameters to fill in, cannot be NULL.
1245  *
1246  * Returns:
1247  *	Zero, if successful. A negative errno code on error.
1248  */
1249 static int uclogic_params_ugee_v2_init_battery(struct hid_device *hdev,
1250 					       struct uclogic_params *p)
1251 {
1252 	int rc = 0;
1253 
1254 	if (!hdev || !p)
1255 		return -EINVAL;
1256 
1257 	/* Some tablets contain invalid characters in hdev->uniq, throwing a
1258 	 * "hwmon: '<name>' is not a valid name attribute, please fix" error.
1259 	 * Use the device vendor and product IDs instead.
1260 	 */
1261 	snprintf(hdev->uniq, sizeof(hdev->uniq), "%x-%x", hdev->vendor,
1262 		 hdev->product);
1263 
1264 	rc = uclogic_params_frame_init_with_desc(&p->frame_list[1],
1265 						 uclogic_rdesc_ugee_v2_battery_template_arr,
1266 						 uclogic_rdesc_ugee_v2_battery_template_size,
1267 						 UCLOGIC_RDESC_UGEE_V2_BATTERY_ID);
1268 	if (rc)
1269 		return rc;
1270 
1271 	p->frame_list[1].suffix = "Battery";
1272 	p->pen.subreport_list[1].value = 0xf2;
1273 	p->pen.subreport_list[1].id = UCLOGIC_RDESC_UGEE_V2_BATTERY_ID;
1274 
1275 	return rc;
1276 }
1277 
1278 /**
1279  * uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
1280  * discovering their parameters.
1281  *
1282  * These tables, internally designed as v2 to differentiate them from older
1283  * models, expect a payload of magic data in orther to be switched to the fully
1284  * functional mode and expose their parameters in a similar way to the
1285  * information present in uclogic_params_pen_init_v1() but with some
1286  * differences.
1287  *
1288  * @params:	Parameters to fill in (to be cleaned with
1289  *		uclogic_params_cleanup()). Not modified in case of error.
1290  *		Cannot be NULL.
1291  * @hdev:	The HID device of the tablet interface to initialize and get
1292  *		parameters from. Cannot be NULL.
1293  *
1294  * Returns:
1295  *	Zero, if successful. A negative errno code on error.
1296  */
1297 static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
1298 				       struct hid_device *hdev)
1299 {
1300 	int rc = 0;
1301 	struct usb_interface *iface;
1302 	__u8 bInterfaceNumber;
1303 	const int str_desc_len = 12;
1304 	__u8 *str_desc = NULL;
1305 	__u8 *rdesc_pen = NULL;
1306 	s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
1307 	enum uclogic_params_frame_type frame_type;
1308 	__u8 magic_arr[] = {
1309 		0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1310 	};
1311 	/* The resulting parameters (noop) */
1312 	struct uclogic_params p = {0, };
1313 
1314 	if (!params || !hdev) {
1315 		rc = -EINVAL;
1316 		goto cleanup;
1317 	}
1318 
1319 	iface = to_usb_interface(hdev->dev.parent);
1320 	bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
1321 
1322 	if (bInterfaceNumber == 0) {
1323 		rc = uclogic_params_ugee_v2_init_frame_mouse(&p);
1324 		if (rc)
1325 			goto cleanup;
1326 
1327 		goto output;
1328 	}
1329 
1330 	if (bInterfaceNumber != 2) {
1331 		uclogic_params_init_invalid(&p);
1332 		goto output;
1333 	}
1334 
1335 	/*
1336 	 * Initialize the interface by sending magic data.
1337 	 * The specific data was discovered by sniffing the Windows driver
1338 	 * traffic.
1339 	 */
1340 	rc = uclogic_probe_interface(hdev, magic_arr, sizeof(magic_arr), 0x03);
1341 	if (rc) {
1342 		uclogic_params_init_invalid(&p);
1343 		goto output;
1344 	}
1345 
1346 	/*
1347 	 * Read the string descriptor containing pen and frame parameters.
1348 	 * The specific string descriptor and data were discovered by sniffing
1349 	 * the Windows driver traffic.
1350 	 */
1351 	rc = uclogic_params_get_str_desc(&str_desc, hdev, 100, str_desc_len);
1352 	if (rc != str_desc_len) {
1353 		hid_err(hdev, "failed retrieving pen and frame parameters: %d\n", rc);
1354 		uclogic_params_init_invalid(&p);
1355 		goto output;
1356 	}
1357 
1358 	rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len,
1359 					       desc_params,
1360 					       ARRAY_SIZE(desc_params),
1361 					       &frame_type);
1362 	if (rc)
1363 		goto cleanup;
1364 
1365 	kfree(str_desc);
1366 	str_desc = NULL;
1367 
1368 	/* Initialize the pen interface */
1369 	rdesc_pen = uclogic_rdesc_template_apply(
1370 				uclogic_rdesc_ugee_v2_pen_template_arr,
1371 				uclogic_rdesc_ugee_v2_pen_template_size,
1372 				desc_params, ARRAY_SIZE(desc_params));
1373 	if (!rdesc_pen) {
1374 		rc = -ENOMEM;
1375 		goto cleanup;
1376 	}
1377 
1378 	p.pen.desc_ptr = rdesc_pen;
1379 	p.pen.desc_size = uclogic_rdesc_ugee_v2_pen_template_size;
1380 	p.pen.id = 0x02;
1381 	p.pen.subreport_list[0].value = 0xf0;
1382 	p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID;
1383 
1384 	/* Initialize the frame interface */
1385 	switch (frame_type) {
1386 	case UCLOGIC_PARAMS_FRAME_DIAL:
1387 	case UCLOGIC_PARAMS_FRAME_MOUSE:
1388 		rc = uclogic_params_ugee_v2_init_frame_dial(&p, desc_params,
1389 							    ARRAY_SIZE(desc_params));
1390 		break;
1391 	case UCLOGIC_PARAMS_FRAME_BUTTONS:
1392 	default:
1393 		rc = uclogic_params_ugee_v2_init_frame_buttons(&p, desc_params,
1394 							       ARRAY_SIZE(desc_params));
1395 		break;
1396 	}
1397 
1398 	if (rc)
1399 		goto cleanup;
1400 
1401 	/* Initialize the battery interface*/
1402 	if (uclogic_params_ugee_v2_has_battery(hdev)) {
1403 		rc = uclogic_params_ugee_v2_init_battery(hdev, &p);
1404 		if (rc) {
1405 			hid_err(hdev, "error initializing battery: %d\n", rc);
1406 			goto cleanup;
1407 		}
1408 	}
1409 
1410 output:
1411 	/* Output parameters */
1412 	memcpy(params, &p, sizeof(*params));
1413 	memset(&p, 0, sizeof(p));
1414 	rc = 0;
1415 cleanup:
1416 	kfree(str_desc);
1417 	uclogic_params_cleanup(&p);
1418 	return rc;
1419 }
1420 
1421 /**
1422  * uclogic_params_init() - initialize a tablet interface and discover its
1423  * parameters.
1424  *
1425  * @params:	Parameters to fill in (to be cleaned with
1426  *		uclogic_params_cleanup()). Not modified in case of error.
1427  *		Cannot be NULL.
1428  * @hdev:	The HID device of the tablet interface to initialize and get
1429  *		parameters from. Cannot be NULL. Must be using the USB low-level
1430  *		driver, i.e. be an actual USB tablet.
1431  *
1432  * Returns:
1433  *	Zero, if successful. A negative errno code on error.
1434  */
1435 int uclogic_params_init(struct uclogic_params *params,
1436 			struct hid_device *hdev)
1437 {
1438 	int rc;
1439 	struct usb_device *udev;
1440 	__u8  bNumInterfaces;
1441 	struct usb_interface *iface;
1442 	__u8 bInterfaceNumber;
1443 	bool found;
1444 	/* The resulting parameters (noop) */
1445 	struct uclogic_params p = {0, };
1446 
1447 	/* Check arguments */
1448 	if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) {
1449 		rc = -EINVAL;
1450 		goto cleanup;
1451 	}
1452 
1453 	udev = hid_to_usb_dev(hdev);
1454 	bNumInterfaces = udev->config->desc.bNumInterfaces;
1455 	iface = to_usb_interface(hdev->dev.parent);
1456 	bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
1457 
1458 	/*
1459 	 * Set replacement report descriptor if the original matches the
1460 	 * specified size. Otherwise keep interface unchanged.
1461 	 */
1462 #define WITH_OPT_DESC(_orig_desc_token, _new_desc_token) \
1463 	uclogic_params_init_with_opt_desc(                  \
1464 		&p, hdev,                                   \
1465 		UCLOGIC_RDESC_##_orig_desc_token##_SIZE,    \
1466 		uclogic_rdesc_##_new_desc_token##_arr,      \
1467 		uclogic_rdesc_##_new_desc_token##_size)
1468 
1469 #define VID_PID(_vid, _pid) \
1470 	(((__u32)(_vid) << 16) | ((__u32)(_pid) & U16_MAX))
1471 
1472 	/*
1473 	 * Handle specific interfaces for specific tablets.
1474 	 *
1475 	 * Observe the following logic:
1476 	 *
1477 	 * If the interface is recognized as producing certain useful input:
1478 	 *	Mark interface as valid.
1479 	 *	Output interface parameters.
1480 	 * Else, if the interface is recognized as *not* producing any useful
1481 	 * input:
1482 	 *	Mark interface as invalid.
1483 	 * Else:
1484 	 *	Mark interface as valid.
1485 	 *	Output noop parameters.
1486 	 *
1487 	 * Rule of thumb: it is better to disable a broken interface than let
1488 	 *		  it spew garbage input.
1489 	 */
1490 
1491 	switch (VID_PID(hdev->vendor, hdev->product)) {
1492 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1493 		     USB_DEVICE_ID_UCLOGIC_TABLET_PF1209):
1494 		rc = WITH_OPT_DESC(PF1209_ORIG, pf1209_fixed);
1495 		if (rc != 0)
1496 			goto cleanup;
1497 		break;
1498 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1499 		     USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U):
1500 		rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp4030u_fixed);
1501 		if (rc != 0)
1502 			goto cleanup;
1503 		break;
1504 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1505 		     USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U):
1506 		if (hdev->dev_rsize == UCLOGIC_RDESC_WP5540U_V2_ORIG_SIZE) {
1507 			if (bInterfaceNumber == 0) {
1508 				/* Try to probe v1 pen parameters */
1509 				rc = uclogic_params_pen_init_v1(&p.pen,
1510 								&found, hdev);
1511 				if (rc != 0) {
1512 					hid_err(hdev,
1513 						"pen probing failed: %d\n",
1514 						rc);
1515 					goto cleanup;
1516 				}
1517 				if (!found) {
1518 					hid_warn(hdev,
1519 						 "pen parameters not found");
1520 				}
1521 			} else {
1522 				uclogic_params_init_invalid(&p);
1523 			}
1524 		} else {
1525 			rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp5540u_fixed);
1526 			if (rc != 0)
1527 				goto cleanup;
1528 		}
1529 		break;
1530 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1531 		     USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U):
1532 		rc = WITH_OPT_DESC(WPXXXXU_ORIG, wp8060u_fixed);
1533 		if (rc != 0)
1534 			goto cleanup;
1535 		break;
1536 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1537 		     USB_DEVICE_ID_UCLOGIC_TABLET_WP1062):
1538 		rc = WITH_OPT_DESC(WP1062_ORIG, wp1062_fixed);
1539 		if (rc != 0)
1540 			goto cleanup;
1541 		break;
1542 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1543 		     USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850):
1544 		switch (bInterfaceNumber) {
1545 		case 0:
1546 			rc = WITH_OPT_DESC(TWHL850_ORIG0, twhl850_fixed0);
1547 			if (rc != 0)
1548 				goto cleanup;
1549 			break;
1550 		case 1:
1551 			rc = WITH_OPT_DESC(TWHL850_ORIG1, twhl850_fixed1);
1552 			if (rc != 0)
1553 				goto cleanup;
1554 			break;
1555 		case 2:
1556 			rc = WITH_OPT_DESC(TWHL850_ORIG2, twhl850_fixed2);
1557 			if (rc != 0)
1558 				goto cleanup;
1559 			break;
1560 		}
1561 		break;
1562 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1563 		     USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60):
1564 		/*
1565 		 * If it is not a three-interface version, which is known to
1566 		 * respond to initialization.
1567 		 */
1568 		if (bNumInterfaces != 3) {
1569 			switch (bInterfaceNumber) {
1570 			case 0:
1571 				rc = WITH_OPT_DESC(TWHA60_ORIG0,
1572 							twha60_fixed0);
1573 				if (rc != 0)
1574 					goto cleanup;
1575 				break;
1576 			case 1:
1577 				rc = WITH_OPT_DESC(TWHA60_ORIG1,
1578 							twha60_fixed1);
1579 				if (rc != 0)
1580 					goto cleanup;
1581 				break;
1582 			}
1583 			break;
1584 		}
1585 		fallthrough;
1586 	case VID_PID(USB_VENDOR_ID_HUION,
1587 		     USB_DEVICE_ID_HUION_TABLET):
1588 	case VID_PID(USB_VENDOR_ID_HUION,
1589 		     USB_DEVICE_ID_HUION_TABLET2):
1590 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1591 		     USB_DEVICE_ID_HUION_TABLET):
1592 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1593 		     USB_DEVICE_ID_YIYNOVA_TABLET):
1594 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1595 		     USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_81):
1596 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1597 		     USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3):
1598 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1599 		     USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_45):
1600 	case VID_PID(USB_VENDOR_ID_UCLOGIC,
1601 		     USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_47):
1602 		rc = uclogic_params_huion_init(&p, hdev);
1603 		if (rc != 0)
1604 			goto cleanup;
1605 		break;
1606 	case VID_PID(USB_VENDOR_ID_UGTIZER,
1607 		     USB_DEVICE_ID_UGTIZER_TABLET_GP0610):
1608 	case VID_PID(USB_VENDOR_ID_UGTIZER,
1609 		     USB_DEVICE_ID_UGTIZER_TABLET_GT5040):
1610 	case VID_PID(USB_VENDOR_ID_UGEE,
1611 		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540):
1612 	case VID_PID(USB_VENDOR_ID_UGEE,
1613 		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640):
1614 	case VID_PID(USB_VENDOR_ID_UGEE,
1615 		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06):
1616 	case VID_PID(USB_VENDOR_ID_UGEE,
1617 		     USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720):
1618 		/* If this is the pen interface */
1619 		if (bInterfaceNumber == 1) {
1620 			/* Probe v1 pen parameters */
1621 			rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1622 			if (rc != 0) {
1623 				hid_err(hdev, "pen probing failed: %d\n", rc);
1624 				goto cleanup;
1625 			}
1626 			if (!found) {
1627 				hid_warn(hdev, "pen parameters not found");
1628 				uclogic_params_init_invalid(&p);
1629 			}
1630 		} else {
1631 			uclogic_params_init_invalid(&p);
1632 		}
1633 		break;
1634 	case VID_PID(USB_VENDOR_ID_UGEE,
1635 		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01):
1636 		/* If this is the pen and frame interface */
1637 		if (bInterfaceNumber == 1) {
1638 			/* Probe v1 pen parameters */
1639 			rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1640 			if (rc != 0) {
1641 				hid_err(hdev, "pen probing failed: %d\n", rc);
1642 				goto cleanup;
1643 			}
1644 			/* Initialize frame parameters */
1645 			rc = uclogic_params_frame_init_with_desc(
1646 				&p.frame_list[0],
1647 				uclogic_rdesc_xppen_deco01_frame_arr,
1648 				uclogic_rdesc_xppen_deco01_frame_size,
1649 				0);
1650 			if (rc != 0)
1651 				goto cleanup;
1652 		} else {
1653 			uclogic_params_init_invalid(&p);
1654 		}
1655 		break;
1656 	case VID_PID(USB_VENDOR_ID_UGEE,
1657 		     USB_DEVICE_ID_UGEE_PARBLO_A610_PRO):
1658 	case VID_PID(USB_VENDOR_ID_UGEE,
1659 		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L):
1660 	case VID_PID(USB_VENDOR_ID_UGEE,
1661 		     USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S):
1662 		rc = uclogic_params_ugee_v2_init(&p, hdev);
1663 		if (rc != 0)
1664 			goto cleanup;
1665 		break;
1666 	case VID_PID(USB_VENDOR_ID_TRUST,
1667 		     USB_DEVICE_ID_TRUST_PANORA_TABLET):
1668 	case VID_PID(USB_VENDOR_ID_UGEE,
1669 		     USB_DEVICE_ID_UGEE_TABLET_G5):
1670 		/* Ignore non-pen interfaces */
1671 		if (bInterfaceNumber != 1) {
1672 			uclogic_params_init_invalid(&p);
1673 			break;
1674 		}
1675 
1676 		rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1677 		if (rc != 0) {
1678 			hid_err(hdev, "pen probing failed: %d\n", rc);
1679 			goto cleanup;
1680 		} else if (found) {
1681 			rc = uclogic_params_frame_init_with_desc(
1682 				&p.frame_list[0],
1683 				uclogic_rdesc_ugee_g5_frame_arr,
1684 				uclogic_rdesc_ugee_g5_frame_size,
1685 				UCLOGIC_RDESC_UGEE_G5_FRAME_ID);
1686 			if (rc != 0) {
1687 				hid_err(hdev,
1688 					"failed creating frame parameters: %d\n",
1689 					rc);
1690 				goto cleanup;
1691 			}
1692 			p.frame_list[0].re_lsb =
1693 				UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB;
1694 			p.frame_list[0].dev_id_byte =
1695 				UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE;
1696 		} else {
1697 			hid_warn(hdev, "pen parameters not found");
1698 			uclogic_params_init_invalid(&p);
1699 		}
1700 
1701 		break;
1702 	case VID_PID(USB_VENDOR_ID_UGEE,
1703 		     USB_DEVICE_ID_UGEE_TABLET_EX07S):
1704 		/* Ignore non-pen interfaces */
1705 		if (bInterfaceNumber != 1) {
1706 			uclogic_params_init_invalid(&p);
1707 			break;
1708 		}
1709 
1710 		rc = uclogic_params_pen_init_v1(&p.pen, &found, hdev);
1711 		if (rc != 0) {
1712 			hid_err(hdev, "pen probing failed: %d\n", rc);
1713 			goto cleanup;
1714 		} else if (found) {
1715 			rc = uclogic_params_frame_init_with_desc(
1716 				&p.frame_list[0],
1717 				uclogic_rdesc_ugee_ex07_frame_arr,
1718 				uclogic_rdesc_ugee_ex07_frame_size,
1719 				0);
1720 			if (rc != 0) {
1721 				hid_err(hdev,
1722 					"failed creating frame parameters: %d\n",
1723 					rc);
1724 				goto cleanup;
1725 			}
1726 		} else {
1727 			hid_warn(hdev, "pen parameters not found");
1728 			uclogic_params_init_invalid(&p);
1729 		}
1730 
1731 		break;
1732 	}
1733 
1734 #undef VID_PID
1735 #undef WITH_OPT_DESC
1736 
1737 	/* Output parameters */
1738 	memcpy(params, &p, sizeof(*params));
1739 	memset(&p, 0, sizeof(p));
1740 	rc = 0;
1741 cleanup:
1742 	uclogic_params_cleanup(&p);
1743 	return rc;
1744 }
1745 
1746 #ifdef CONFIG_HID_KUNIT_TEST
1747 #include "hid-uclogic-params-test.c"
1748 #endif
1749