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