2022-02-19 19:00:52

by José Expósito

[permalink] [raw]
Subject: [PATCH for-5.18/uclogic 0/9] DIGImend patches, part II

Hi everyone,

This series is a follow up to [1], kindly reviewed and applied
by Jiří in hid.git#for-5.18/uclogic.

It might look a little bit longer than desired, but most of the
patches are code simplification and refactoring in preparation
for the last patch which adds support for multiple frame input
devices.

Thank you very much in advance to maintainers for reviewing it,
José Expósito

[1] https://lore.kernel.org/linux-input/[email protected]/T/

Nikolai Kondrashov (9):
HID: uclogic: Remove pen usage masking
HID: uclogic: Replace pen_frame_flag with subreport_list
HID: uclogic: Switch to matching subreport bytes
HID: uclogic: Specify total report size to buttonpad macro
HID: uclogic: Use different constants for frame report IDs
HID: uclogic: Use "frame" instead of "buttonpad"
HID: uclogic: Put version first in rdesc namespace
HID: uclogic: Define report IDs before their descriptors
HID: uclogic: Support multiple frame input devices

drivers/hid/hid-uclogic-core.c | 79 +++++++------
drivers/hid/hid-uclogic-params.c | 195 ++++++++++++++-----------------
drivers/hid/hid-uclogic-params.h | 86 +++++++-------
drivers/hid/hid-uclogic-rdesc.c | 53 ++++-----
drivers/hid/hid-uclogic-rdesc.h | 38 +++---
5 files changed, 221 insertions(+), 230 deletions(-)

--
2.25.1


2022-02-20 02:49:26

by José Expósito

[permalink] [raw]
Subject: [PATCH for-5.18/uclogic 2/9] HID: uclogic: Replace pen_frame_flag with subreport_list

From: Nikolai Kondrashov <[email protected]>

Replace a single pen_frame_flag in struct uclogic_params with
subreport_list in struct uclogic_params_pen to prepare for handling more
subreports in Huion HS610.

Signed-off-by: Nikolai Kondrashov <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-uclogic-core.c | 40 ++++++++++++++-------
drivers/hid/hid-uclogic-params.c | 12 ++++---
drivers/hid/hid-uclogic-params.h | 62 +++++++++++++++++++-------------
3 files changed, 73 insertions(+), 41 deletions(-)

diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
index 26849f1f5459..7092f86517a5 100644
--- a/drivers/hid/hid-uclogic-core.c
+++ b/drivers/hid/hid-uclogic-core.c
@@ -350,26 +350,40 @@ static int uclogic_raw_event(struct hid_device *hdev,
unsigned int report_id = report->id;
struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
struct uclogic_params *params = &drvdata->params;
+ struct uclogic_params_pen_subreport *subreport;
+ struct uclogic_params_pen_subreport *subreport_list_end;

/* Do not handle anything but input reports */
if (report->type != HID_INPUT_REPORT)
return 0;

- /* Tweak pen reports, if necessary */
- if ((report_id == params->pen.id) && (size >= 2)) {
- /* If it's the "virtual" frame controls report */
- if (params->frame.id != 0 &&
- data[1] & params->pen_frame_flag) {
- /* Change to virtual frame controls report ID */
- report_id = data[0] = params->frame.id;
- } else {
- return uclogic_raw_event_pen(drvdata, data, size);
+ while (true) {
+ /* Tweak pen reports, if necessary */
+ if ((report_id == params->pen.id) && (size >= 2)) {
+ subreport_list_end =
+ params->pen.subreport_list +
+ ARRAY_SIZE(params->pen.subreport_list);
+ /* Try to match a subreport */
+ for (subreport = params->pen.subreport_list;
+ subreport < subreport_list_end &&
+ (data[1] & subreport->mask) != subreport->mask;
+ subreport++);
+ /* If a subreport matched */
+ if (subreport < subreport_list_end) {
+ /* Change to subreport ID, and restart */
+ report_id = data[0] = subreport->id;
+ continue;
+ } else {
+ return uclogic_raw_event_pen(drvdata, data, size);
+ }
}
- }

- /* Tweak frame control reports, if necessary */
- if (report_id == params->frame.id)
- return uclogic_raw_event_frame(drvdata, data, size);
+ /* Tweak frame control reports, if necessary */
+ if (report_id == params->frame.id)
+ return uclogic_raw_event_frame(drvdata, data, size);
+
+ break;
+ }

return 0;
}
diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
index 71496735cbf0..138dd8b0a360 100644
--- a/drivers/hid/hid-uclogic-params.c
+++ b/drivers/hid/hid-uclogic-params.c
@@ -762,8 +762,10 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
rc);
goto cleanup;
}
- /* Set bitmask marking frame reports in pen reports */
- p.pen_frame_flag = 0x20;
+ /* Link frame button subreports from pen reports */
+ p.pen.subreport_list[0].mask = 0x20;
+ p.pen.subreport_list[0].id =
+ UCLOGIC_RDESC_BUTTONPAD_V2_ID;
goto output;
}
hid_dbg(hdev, "pen v2 parameters not found\n");
@@ -788,8 +790,10 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
hid_dbg(hdev, "buttonpad v1 parameters%s found\n",
(found ? "" : " not"));
if (found) {
- /* Set bitmask marking frame reports */
- p.pen_frame_flag = 0x20;
+ /* Link frame button subreports from pen reports */
+ p.pen.subreport_list[0].mask = 0x20;
+ p.pen.subreport_list[0].id =
+ UCLOGIC_RDESC_BUTTONPAD_V1_ID;
}
goto output;
}
diff --git a/drivers/hid/hid-uclogic-params.h b/drivers/hid/hid-uclogic-params.h
index 48b974943bb9..82db8ab36fec 100644
--- a/drivers/hid/hid-uclogic-params.h
+++ b/drivers/hid/hid-uclogic-params.h
@@ -33,6 +33,24 @@ enum uclogic_params_pen_inrange {
extern const char *uclogic_params_pen_inrange_to_str(
enum uclogic_params_pen_inrange inrange);

+
+/*
+ * Pen report's subreport data.
+ */
+struct uclogic_params_pen_subreport {
+ /*
+ * The subreport's bitmask matching the second byte of the pen report.
+ * If zero, the subreport is considered invalid, and won't match.
+ */
+ __u8 mask;
+
+ /*
+ * The ID to be assigned to the report, if the "mask" matches.
+ * Only valid if "mask" is not zero.
+ */
+ __u8 id;
+};
+
/*
* Tablet interface's pen input parameters.
*
@@ -54,6 +72,8 @@ struct uclogic_params_pen {
unsigned int desc_size;
/* Report ID, if reports should be tweaked, zero if not */
unsigned int id;
+ /* The list of subreports */
+ struct uclogic_params_pen_subreport subreport_list[1];
/* Type of in-range reporting, only valid if "id" is not zero */
enum uclogic_params_pen_inrange inrange;
/*
@@ -148,13 +168,6 @@ struct uclogic_params {
* Only valid, if "invalid" is false.
*/
struct uclogic_params_frame frame;
- /*
- * Bitmask matching frame controls "sub-report" flag in the second
- * byte of the pen report, or zero if it's not expected.
- * Only valid if both "pen" and "frame" are valid, and "frame.id" is
- * not zero.
- */
- __u8 pen_frame_flag;
};

/* Initialize a tablet interface and discover its parameters */
@@ -163,21 +176,21 @@ extern int uclogic_params_init(struct uclogic_params *params,

/* Tablet interface parameters *printf format string */
#define UCLOGIC_PARAMS_FMT_STR \
- ".invalid = %s\n" \
- ".desc_ptr = %p\n" \
- ".desc_size = %u\n" \
- ".pen.desc_ptr = %p\n" \
- ".pen.desc_size = %u\n" \
- ".pen.id = %u\n" \
- ".pen.inrange = %s\n" \
- ".pen.fragmented_hires = %s\n" \
- ".pen.tilt_y_flipped = %s\n" \
- ".frame.desc_ptr = %p\n" \
- ".frame.desc_size = %u\n" \
- ".frame.id = %u\n" \
- ".frame.re_lsb = %u\n" \
- ".frame.dev_id_byte = %u\n" \
- ".pen_frame_flag = 0x%02x\n"
+ ".invalid = %s\n" \
+ ".desc_ptr = %p\n" \
+ ".desc_size = %u\n" \
+ ".pen.desc_ptr = %p\n" \
+ ".pen.desc_size = %u\n" \
+ ".pen.id = %u\n" \
+ ".pen.subreport_list[0] = {0x%02hhx, %hhu}\n" \
+ ".pen.inrange = %s\n" \
+ ".pen.fragmented_hires = %s\n" \
+ ".pen.tilt_y_flipped = %s\n" \
+ ".frame.desc_ptr = %p\n" \
+ ".frame.desc_size = %u\n" \
+ ".frame.id = %u\n" \
+ ".frame.re_lsb = %u\n" \
+ ".frame.dev_id_byte = %u\n"

/* Tablet interface parameters *printf format arguments */
#define UCLOGIC_PARAMS_FMT_ARGS(_params) \
@@ -187,6 +200,8 @@ extern int uclogic_params_init(struct uclogic_params *params,
(_params)->pen.desc_ptr, \
(_params)->pen.desc_size, \
(_params)->pen.id, \
+ (_params)->pen.subreport_list[0].mask, \
+ (_params)->pen.subreport_list[0].id, \
uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
((_params)->pen.fragmented_hires ? "true" : "false"), \
((_params)->pen.tilt_y_flipped ? "true" : "false"), \
@@ -194,8 +209,7 @@ extern int uclogic_params_init(struct uclogic_params *params,
(_params)->frame.desc_size, \
(_params)->frame.id, \
(_params)->frame.re_lsb, \
- (_params)->frame.dev_id_byte, \
- (_params)->pen_frame_flag
+ (_params)->frame.dev_id_byte

/* Get a replacement report descriptor for a tablet's interface. */
extern int uclogic_params_get_desc(const struct uclogic_params *params,
--
2.25.1

2022-02-20 03:19:52

by José Expósito

[permalink] [raw]
Subject: [PATCH for-5.18/uclogic 8/9] HID: uclogic: Define report IDs before their descriptors

From: Nikolai Kondrashov <[email protected]>

Signed-off-by: Nikolai Kondrashov <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-uclogic-rdesc.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/hid-uclogic-rdesc.h b/drivers/hid/hid-uclogic-rdesc.h
index d1ab1f346f22..3d904c27b86a 100644
--- a/drivers/hid/hid-uclogic-rdesc.h
+++ b/drivers/hid/hid-uclogic-rdesc.h
@@ -117,20 +117,20 @@ extern const size_t uclogic_rdesc_v1_pen_template_size;
extern const __u8 uclogic_rdesc_v2_pen_template_arr[];
extern const size_t uclogic_rdesc_v2_pen_template_size;

+/* Report ID for tweaked v1 frame reports */
+#define UCLOGIC_RDESC_V1_FRAME_ID 0xf7
+
/* Fixed report descriptor for (tweaked) v1 frame reports */
extern const __u8 uclogic_rdesc_v1_frame_arr[];
extern const size_t uclogic_rdesc_v1_frame_size;

-/* Report ID for tweaked v1 frame reports */
-#define UCLOGIC_RDESC_V1_FRAME_ID 0xf7
+/* Report ID for tweaked v2 frame reports */
+#define UCLOGIC_RDESC_V2_FRAME_ID 0xf7

/* Fixed report descriptor for (tweaked) v2 frame reports */
extern const __u8 uclogic_rdesc_v2_frame_arr[];
extern const size_t uclogic_rdesc_v2_frame_size;

-/* Report ID for tweaked v2 frame reports */
-#define UCLOGIC_RDESC_V2_FRAME_ID 0xf7
-
/* Fixed report descriptor for Ugee EX07 frame */
extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
extern const size_t uclogic_rdesc_ugee_ex07_frame_size;
--
2.25.1

2022-02-20 03:22:00

by José Expósito

[permalink] [raw]
Subject: [PATCH for-5.18/uclogic 4/9] HID: uclogic: Specify total report size to buttonpad macro

From: Nikolai Kondrashov <[email protected]>

Simplify the UCLOGIC_RDESC_BUTTONPAD_BYTES macro by passing as param
the size of the report to pad to in bytes.

Signed-off-by: Nikolai Kondrashov <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-uclogic-rdesc.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
index ec16355d200b..6e5bef39417e 100644
--- a/drivers/hid/hid-uclogic-rdesc.c
+++ b/drivers/hid/hid-uclogic-rdesc.c
@@ -654,10 +654,9 @@ const size_t uclogic_rdesc_pen_v2_template_size =
/*
* Expand to the contents of a generic buttonpad report descriptor.
*
- * @_padding: Padding from the end of button bits at bit 44, until
- * the end of the report, in bits.
+ * @_size: Size of the report to pad to, including report ID, bytes.
*/
-#define UCLOGIC_RDESC_BUTTONPAD_BYTES(_padding) \
+#define UCLOGIC_RDESC_BUTTONPAD_BYTES(_size) \
0x05, 0x01, /* Usage Page (Desktop), */ \
0x09, 0x07, /* Usage (Keypad), */ \
0xA1, 0x01, /* Collection (Application), */ \
@@ -692,21 +691,22 @@ const size_t uclogic_rdesc_pen_v2_template_size =
0x29, 0x03, /* Usage Maximum (03h), */ \
0x95, 0x03, /* Report Count (3), */ \
0x81, 0x02, /* Input (Variable), */ \
- 0x95, _padding, /* Report Count (_padding), */ \
+ 0x95, ((_size) * 8 - 45), \
+ /* Report Count (padding), */ \
0x81, 0x01, /* Input (Constant), */ \
0xC0, /* End Collection, */ \
0xC0 /* End Collection */

/* Fixed report descriptor for (tweaked) v1 buttonpad reports */
const __u8 uclogic_rdesc_buttonpad_v1_arr[] = {
- UCLOGIC_RDESC_BUTTONPAD_BYTES(19)
+ UCLOGIC_RDESC_BUTTONPAD_BYTES(8)
};
const size_t uclogic_rdesc_buttonpad_v1_size =
sizeof(uclogic_rdesc_buttonpad_v1_arr);

/* Fixed report descriptor for (tweaked) v2 buttonpad reports */
const __u8 uclogic_rdesc_buttonpad_v2_arr[] = {
- UCLOGIC_RDESC_BUTTONPAD_BYTES(51)
+ UCLOGIC_RDESC_BUTTONPAD_BYTES(12)
};
const size_t uclogic_rdesc_buttonpad_v2_size =
sizeof(uclogic_rdesc_buttonpad_v2_arr);
--
2.25.1

2022-02-20 03:54:39

by José Expósito

[permalink] [raw]
Subject: [PATCH for-5.18/uclogic 6/9] HID: uclogic: Use "frame" instead of "buttonpad"

From: Nikolai Kondrashov <[email protected]>

Use the term "frame" instead of "buttonpad" for consistency, in UC-Logic
driver.

Signed-off-by: Nikolai Kondrashov <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-uclogic-params.c | 46 +++++++++++++++-----------------
drivers/hid/hid-uclogic-rdesc.c | 32 +++++++++++-----------
drivers/hid/hid-uclogic-rdesc.h | 26 +++++++++---------
3 files changed, 51 insertions(+), 53 deletions(-)

diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
index a4a53ab1e72c..168749d9a112 100644
--- a/drivers/hid/hid-uclogic-params.c
+++ b/drivers/hid/hid-uclogic-params.c
@@ -431,8 +431,8 @@ static int uclogic_params_frame_init_with_desc(
}

/**
- * uclogic_params_frame_init_v1_buttonpad() - initialize abstract buttonpad
- * on a v1 tablet interface.
+ * uclogic_params_frame_init_v1() - initialize v1 tablet interface frame
+ * controls.
*
* @frame: Pointer to the frame parameters to initialize (to be cleaned
* up with uclogic_params_frame_cleanup()). Not modified in case
@@ -446,8 +446,7 @@ static int uclogic_params_frame_init_with_desc(
* Returns:
* Zero, if successful. A negative errno code on error.
*/
-static int uclogic_params_frame_init_v1_buttonpad(
- struct uclogic_params_frame *frame,
+static int uclogic_params_frame_init_v1(struct uclogic_params_frame *frame,
bool *pfound,
struct hid_device *hdev)
{
@@ -488,9 +487,9 @@ static int uclogic_params_frame_init_v1_buttonpad(
hid_dbg(hdev, "generic buttons enabled\n");
rc = uclogic_params_frame_init_with_desc(
frame,
- uclogic_rdesc_buttonpad_v1_arr,
- uclogic_rdesc_buttonpad_v1_size,
- UCLOGIC_RDESC_BUTTONPAD_V1_ID);
+ uclogic_rdesc_frame_v1_arr,
+ uclogic_rdesc_frame_v1_size,
+ UCLOGIC_RDESC_FRAME_V1_ID);
if (rc != 0)
goto cleanup;
found = true;
@@ -750,22 +749,22 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
goto cleanup;
} else if (found) {
hid_dbg(hdev, "pen v2 parameters found\n");
- /* Create v2 buttonpad parameters */
+ /* Create v2 frame parameters */
rc = uclogic_params_frame_init_with_desc(
&p.frame,
- uclogic_rdesc_buttonpad_v2_arr,
- uclogic_rdesc_buttonpad_v2_size,
- UCLOGIC_RDESC_BUTTONPAD_V2_ID);
+ uclogic_rdesc_frame_v2_arr,
+ uclogic_rdesc_frame_v2_size,
+ UCLOGIC_RDESC_FRAME_V2_ID);
if (rc != 0) {
hid_err(hdev,
- "failed creating v2 buttonpad parameters: %d\n",
+ "failed creating v2 frame parameters: %d\n",
rc);
goto cleanup;
}
/* Link frame button subreports from pen reports */
p.pen.subreport_list[0].value = 0xe0;
p.pen.subreport_list[0].id =
- UCLOGIC_RDESC_BUTTONPAD_V2_ID;
+ UCLOGIC_RDESC_FRAME_V2_ID;
goto output;
}
hid_dbg(hdev, "pen v2 parameters not found\n");
@@ -779,21 +778,20 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
goto cleanup;
} else if (found) {
hid_dbg(hdev, "pen v1 parameters found\n");
- /* Try to probe v1 buttonpad */
- rc = uclogic_params_frame_init_v1_buttonpad(
- &p.frame,
- &found, hdev);
+ /* Try to probe v1 frame */
+ rc = uclogic_params_frame_init_v1(&p.frame,
+ &found, hdev);
if (rc != 0) {
- hid_err(hdev, "v1 buttonpad probing failed: %d\n", rc);
+ hid_err(hdev, "v1 frame probing failed: %d\n", rc);
goto cleanup;
}
- hid_dbg(hdev, "buttonpad v1 parameters%s found\n",
+ hid_dbg(hdev, "frame v1 parameters%s found\n",
(found ? "" : " not"));
if (found) {
/* Link frame button subreports from pen reports */
p.pen.subreport_list[0].value = 0xe0;
p.pen.subreport_list[0].id =
- UCLOGIC_RDESC_BUTTONPAD_V1_ID;
+ UCLOGIC_RDESC_FRAME_V1_ID;
}
goto output;
}
@@ -1067,7 +1065,7 @@ int uclogic_params_init(struct uclogic_params *params,
UCLOGIC_RDESC_UGEE_G5_FRAME_ID);
if (rc != 0) {
hid_err(hdev,
- "failed creating buttonpad parameters: %d\n",
+ "failed creating frame parameters: %d\n",
rc);
goto cleanup;
}
@@ -1096,12 +1094,12 @@ int uclogic_params_init(struct uclogic_params *params,
} else if (found) {
rc = uclogic_params_frame_init_with_desc(
&p.frame,
- uclogic_rdesc_ugee_ex07_buttonpad_arr,
- uclogic_rdesc_ugee_ex07_buttonpad_size,
+ uclogic_rdesc_ugee_ex07_frame_arr,
+ uclogic_rdesc_ugee_ex07_frame_size,
0);
if (rc != 0) {
hid_err(hdev,
- "failed creating buttonpad parameters: %d\n",
+ "failed creating frame parameters: %d\n",
rc);
goto cleanup;
}
diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
index 66aa83f67ccc..e8dedede3395 100644
--- a/drivers/hid/hid-uclogic-rdesc.c
+++ b/drivers/hid/hid-uclogic-rdesc.c
@@ -652,12 +652,12 @@ const size_t uclogic_rdesc_pen_v2_template_size =
sizeof(uclogic_rdesc_pen_v2_template_arr);

/*
- * Expand to the contents of a generic buttonpad report descriptor.
+ * Expand to the contents of a generic frame report descriptor.
*
* @_id: The report ID to use.
* @_size: Size of the report to pad to, including report ID, bytes.
*/
-#define UCLOGIC_RDESC_BUTTONPAD_BYTES(_id, _size) \
+#define UCLOGIC_RDESC_FRAME_BYTES(_id, _size) \
0x05, 0x01, /* Usage Page (Desktop), */ \
0x09, 0x07, /* Usage (Keypad), */ \
0xA1, 0x01, /* Collection (Application), */ \
@@ -698,22 +698,22 @@ const size_t uclogic_rdesc_pen_v2_template_size =
0xC0, /* End Collection, */ \
0xC0 /* End Collection */

-/* Fixed report descriptor for (tweaked) v1 buttonpad reports */
-const __u8 uclogic_rdesc_buttonpad_v1_arr[] = {
- UCLOGIC_RDESC_BUTTONPAD_BYTES(UCLOGIC_RDESC_BUTTONPAD_V1_ID, 8)
+/* Fixed report descriptor for (tweaked) v1 frame reports */
+const __u8 uclogic_rdesc_frame_v1_arr[] = {
+ UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_FRAME_V1_ID, 8)
};
-const size_t uclogic_rdesc_buttonpad_v1_size =
- sizeof(uclogic_rdesc_buttonpad_v1_arr);
+const size_t uclogic_rdesc_frame_v1_size =
+ sizeof(uclogic_rdesc_frame_v1_arr);

-/* Fixed report descriptor for (tweaked) v2 buttonpad reports */
-const __u8 uclogic_rdesc_buttonpad_v2_arr[] = {
- UCLOGIC_RDESC_BUTTONPAD_BYTES(UCLOGIC_RDESC_BUTTONPAD_V2_ID, 12)
+/* Fixed report descriptor for (tweaked) v2 frame reports */
+const __u8 uclogic_rdesc_frame_v2_arr[] = {
+ UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_FRAME_V2_ID, 12)
};
-const size_t uclogic_rdesc_buttonpad_v2_size =
- sizeof(uclogic_rdesc_buttonpad_v2_arr);
+const size_t uclogic_rdesc_frame_v2_size =
+ sizeof(uclogic_rdesc_frame_v2_arr);

-/* Fixed report descriptor for Ugee EX07 buttonpad */
-const __u8 uclogic_rdesc_ugee_ex07_buttonpad_arr[] = {
+/* Fixed report descriptor for Ugee EX07 frame */
+const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x07, /* Usage (Keypad), */
0xA1, 0x01, /* Collection (Application), */
@@ -736,8 +736,8 @@ const __u8 uclogic_rdesc_ugee_ex07_buttonpad_arr[] = {
0xC0, /* End Collection, */
0xC0 /* End Collection */
};
-const size_t uclogic_rdesc_ugee_ex07_buttonpad_size =
- sizeof(uclogic_rdesc_ugee_ex07_buttonpad_arr);
+const size_t uclogic_rdesc_ugee_ex07_frame_size =
+ sizeof(uclogic_rdesc_ugee_ex07_frame_arr);

/* Fixed report descriptor for Ugee G5 frame controls */
const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = {
diff --git a/drivers/hid/hid-uclogic-rdesc.h b/drivers/hid/hid-uclogic-rdesc.h
index c5da51055af3..40c6f02c6bab 100644
--- a/drivers/hid/hid-uclogic-rdesc.h
+++ b/drivers/hid/hid-uclogic-rdesc.h
@@ -117,23 +117,23 @@ extern const size_t uclogic_rdesc_pen_v1_template_size;
extern const __u8 uclogic_rdesc_pen_v2_template_arr[];
extern const size_t uclogic_rdesc_pen_v2_template_size;

-/* Fixed report descriptor for (tweaked) v1 buttonpad reports */
-extern const __u8 uclogic_rdesc_buttonpad_v1_arr[];
-extern const size_t uclogic_rdesc_buttonpad_v1_size;
+/* Fixed report descriptor for (tweaked) v1 frame reports */
+extern const __u8 uclogic_rdesc_frame_v1_arr[];
+extern const size_t uclogic_rdesc_frame_v1_size;

-/* Report ID for tweaked v1 buttonpad reports */
-#define UCLOGIC_RDESC_BUTTONPAD_V1_ID 0xf7
+/* Report ID for tweaked v1 frame reports */
+#define UCLOGIC_RDESC_FRAME_V1_ID 0xf7

-/* Fixed report descriptor for (tweaked) v2 buttonpad reports */
-extern const __u8 uclogic_rdesc_buttonpad_v2_arr[];
-extern const size_t uclogic_rdesc_buttonpad_v2_size;
+/* Fixed report descriptor for (tweaked) v2 frame reports */
+extern const __u8 uclogic_rdesc_frame_v2_arr[];
+extern const size_t uclogic_rdesc_frame_v2_size;

-/* Report ID for tweaked v2 buttonpad reports */
-#define UCLOGIC_RDESC_BUTTONPAD_V2_ID 0xf7
+/* Report ID for tweaked v2 frame reports */
+#define UCLOGIC_RDESC_FRAME_V2_ID 0xf7

-/* Fixed report descriptor for Ugee EX07 buttonpad */
-extern const __u8 uclogic_rdesc_ugee_ex07_buttonpad_arr[];
-extern const size_t uclogic_rdesc_ugee_ex07_buttonpad_size;
+/* Fixed report descriptor for Ugee EX07 frame */
+extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
+extern const size_t uclogic_rdesc_ugee_ex07_frame_size;

/* Fixed report descriptor for XP-Pen Deco 01 frame controls */
extern const __u8 uclogic_rdesc_xppen_deco01_frame_arr[];
--
2.25.1

2022-02-20 22:31:58

by José Expósito

[permalink] [raw]
Subject: [PATCH for-5.18/uclogic 7/9] HID: uclogic: Put version first in rdesc namespace

From: Nikolai Kondrashov <[email protected]>

Put general hardware version before everything else in uclogic_rdesc_
namespace.

Signed-off-by: Nikolai Kondrashov <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-uclogic-params.c | 32 ++++++++++++++++----------------
drivers/hid/hid-uclogic-rdesc.c | 28 ++++++++++++++--------------
drivers/hid/hid-uclogic-rdesc.h | 24 ++++++++++++------------
3 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
index 168749d9a112..f667347ad0df 100644
--- a/drivers/hid/hid-uclogic-params.c
+++ b/drivers/hid/hid-uclogic-params.c
@@ -207,8 +207,8 @@ static int uclogic_params_pen_init_v1(struct uclogic_params_pen *pen,
* Generate pen report descriptor
*/
desc_ptr = uclogic_rdesc_template_apply(
- uclogic_rdesc_pen_v1_template_arr,
- uclogic_rdesc_pen_v1_template_size,
+ uclogic_rdesc_v1_pen_template_arr,
+ uclogic_rdesc_v1_pen_template_size,
desc_params, ARRAY_SIZE(desc_params));
if (desc_ptr == NULL) {
rc = -ENOMEM;
@@ -221,8 +221,8 @@ static int uclogic_params_pen_init_v1(struct uclogic_params_pen *pen,
memset(pen, 0, sizeof(*pen));
pen->desc_ptr = desc_ptr;
desc_ptr = NULL;
- pen->desc_size = uclogic_rdesc_pen_v1_template_size;
- pen->id = UCLOGIC_RDESC_PEN_V1_ID;
+ pen->desc_size = uclogic_rdesc_v1_pen_template_size;
+ pen->id = UCLOGIC_RDESC_V1_PEN_ID;
pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_INVERTED;
found = true;
finish:
@@ -351,8 +351,8 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
* Generate pen report descriptor
*/
desc_ptr = uclogic_rdesc_template_apply(
- uclogic_rdesc_pen_v2_template_arr,
- uclogic_rdesc_pen_v2_template_size,
+ uclogic_rdesc_v2_pen_template_arr,
+ uclogic_rdesc_v2_pen_template_size,
desc_params, ARRAY_SIZE(desc_params));
if (desc_ptr == NULL) {
rc = -ENOMEM;
@@ -365,8 +365,8 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
memset(pen, 0, sizeof(*pen));
pen->desc_ptr = desc_ptr;
desc_ptr = NULL;
- pen->desc_size = uclogic_rdesc_pen_v2_template_size;
- pen->id = UCLOGIC_RDESC_PEN_V2_ID;
+ pen->desc_size = uclogic_rdesc_v2_pen_template_size;
+ pen->id = UCLOGIC_RDESC_V2_PEN_ID;
pen->inrange = UCLOGIC_PARAMS_PEN_INRANGE_NONE;
pen->fragmented_hires = true;
pen->tilt_y_flipped = true;
@@ -487,9 +487,9 @@ static int uclogic_params_frame_init_v1(struct uclogic_params_frame *frame,
hid_dbg(hdev, "generic buttons enabled\n");
rc = uclogic_params_frame_init_with_desc(
frame,
- uclogic_rdesc_frame_v1_arr,
- uclogic_rdesc_frame_v1_size,
- UCLOGIC_RDESC_FRAME_V1_ID);
+ uclogic_rdesc_v1_frame_arr,
+ uclogic_rdesc_v1_frame_size,
+ UCLOGIC_RDESC_V1_FRAME_ID);
if (rc != 0)
goto cleanup;
found = true;
@@ -752,9 +752,9 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
/* Create v2 frame parameters */
rc = uclogic_params_frame_init_with_desc(
&p.frame,
- uclogic_rdesc_frame_v2_arr,
- uclogic_rdesc_frame_v2_size,
- UCLOGIC_RDESC_FRAME_V2_ID);
+ uclogic_rdesc_v2_frame_arr,
+ uclogic_rdesc_v2_frame_size,
+ UCLOGIC_RDESC_V2_FRAME_ID);
if (rc != 0) {
hid_err(hdev,
"failed creating v2 frame parameters: %d\n",
@@ -764,7 +764,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
/* Link frame button subreports from pen reports */
p.pen.subreport_list[0].value = 0xe0;
p.pen.subreport_list[0].id =
- UCLOGIC_RDESC_FRAME_V2_ID;
+ UCLOGIC_RDESC_V2_FRAME_ID;
goto output;
}
hid_dbg(hdev, "pen v2 parameters not found\n");
@@ -791,7 +791,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
/* Link frame button subreports from pen reports */
p.pen.subreport_list[0].value = 0xe0;
p.pen.subreport_list[0].id =
- UCLOGIC_RDESC_FRAME_V1_ID;
+ UCLOGIC_RDESC_V1_FRAME_ID;
}
goto output;
}
diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
index e8dedede3395..04644d93bd11 100644
--- a/drivers/hid/hid-uclogic-rdesc.c
+++ b/drivers/hid/hid-uclogic-rdesc.c
@@ -532,7 +532,7 @@ const size_t uclogic_rdesc_twha60_fixed1_size =
sizeof(uclogic_rdesc_twha60_fixed1_arr);

/* Fixed report descriptor template for (tweaked) v1 pen reports */
-const __u8 uclogic_rdesc_pen_v1_template_arr[] = {
+const __u8 uclogic_rdesc_v1_pen_template_arr[] = {
0x05, 0x0D, /* Usage Page (Digitizer), */
0x09, 0x02, /* Usage (Pen), */
0xA1, 0x01, /* Collection (Application), */
@@ -582,11 +582,11 @@ const __u8 uclogic_rdesc_pen_v1_template_arr[] = {
0xC0 /* End Collection */
};

-const size_t uclogic_rdesc_pen_v1_template_size =
- sizeof(uclogic_rdesc_pen_v1_template_arr);
+const size_t uclogic_rdesc_v1_pen_template_size =
+ sizeof(uclogic_rdesc_v1_pen_template_arr);

/* Fixed report descriptor template for (tweaked) v2 pen reports */
-const __u8 uclogic_rdesc_pen_v2_template_arr[] = {
+const __u8 uclogic_rdesc_v2_pen_template_arr[] = {
0x05, 0x0D, /* Usage Page (Digitizer), */
0x09, 0x02, /* Usage (Pen), */
0xA1, 0x01, /* Collection (Application), */
@@ -648,8 +648,8 @@ const __u8 uclogic_rdesc_pen_v2_template_arr[] = {
0xC0 /* End Collection */
};

-const size_t uclogic_rdesc_pen_v2_template_size =
- sizeof(uclogic_rdesc_pen_v2_template_arr);
+const size_t uclogic_rdesc_v2_pen_template_size =
+ sizeof(uclogic_rdesc_v2_pen_template_arr);

/*
* Expand to the contents of a generic frame report descriptor.
@@ -699,18 +699,18 @@ const size_t uclogic_rdesc_pen_v2_template_size =
0xC0 /* End Collection */

/* Fixed report descriptor for (tweaked) v1 frame reports */
-const __u8 uclogic_rdesc_frame_v1_arr[] = {
- UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_FRAME_V1_ID, 8)
+const __u8 uclogic_rdesc_v1_frame_arr[] = {
+ UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8)
};
-const size_t uclogic_rdesc_frame_v1_size =
- sizeof(uclogic_rdesc_frame_v1_arr);
+const size_t uclogic_rdesc_v1_frame_size =
+ sizeof(uclogic_rdesc_v1_frame_arr);

/* Fixed report descriptor for (tweaked) v2 frame reports */
-const __u8 uclogic_rdesc_frame_v2_arr[] = {
- UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_FRAME_V2_ID, 12)
+const __u8 uclogic_rdesc_v2_frame_arr[] = {
+ UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_V2_FRAME_ID, 12)
};
-const size_t uclogic_rdesc_frame_v2_size =
- sizeof(uclogic_rdesc_frame_v2_arr);
+const size_t uclogic_rdesc_v2_frame_size =
+ sizeof(uclogic_rdesc_v2_frame_arr);

/* Fixed report descriptor for Ugee EX07 frame */
const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
diff --git a/drivers/hid/hid-uclogic-rdesc.h b/drivers/hid/hid-uclogic-rdesc.h
index 40c6f02c6bab..d1ab1f346f22 100644
--- a/drivers/hid/hid-uclogic-rdesc.h
+++ b/drivers/hid/hid-uclogic-rdesc.h
@@ -104,32 +104,32 @@ enum uclogic_rdesc_pen_ph_id {
UCLOGIC_RDESC_PH_HEAD, UCLOGIC_RDESC_PEN_PH_ID_##_ID

/* Report ID for v1 pen reports */
-#define UCLOGIC_RDESC_PEN_V1_ID 0x07
+#define UCLOGIC_RDESC_V1_PEN_ID 0x07

/* Fixed report descriptor template for (tweaked) v1 pen reports */
-extern const __u8 uclogic_rdesc_pen_v1_template_arr[];
-extern const size_t uclogic_rdesc_pen_v1_template_size;
+extern const __u8 uclogic_rdesc_v1_pen_template_arr[];
+extern const size_t uclogic_rdesc_v1_pen_template_size;

/* Report ID for v2 pen reports */
-#define UCLOGIC_RDESC_PEN_V2_ID 0x08
+#define UCLOGIC_RDESC_V2_PEN_ID 0x08

/* Fixed report descriptor template for (tweaked) v2 pen reports */
-extern const __u8 uclogic_rdesc_pen_v2_template_arr[];
-extern const size_t uclogic_rdesc_pen_v2_template_size;
+extern const __u8 uclogic_rdesc_v2_pen_template_arr[];
+extern const size_t uclogic_rdesc_v2_pen_template_size;

/* Fixed report descriptor for (tweaked) v1 frame reports */
-extern const __u8 uclogic_rdesc_frame_v1_arr[];
-extern const size_t uclogic_rdesc_frame_v1_size;
+extern const __u8 uclogic_rdesc_v1_frame_arr[];
+extern const size_t uclogic_rdesc_v1_frame_size;

/* Report ID for tweaked v1 frame reports */
-#define UCLOGIC_RDESC_FRAME_V1_ID 0xf7
+#define UCLOGIC_RDESC_V1_FRAME_ID 0xf7

/* Fixed report descriptor for (tweaked) v2 frame reports */
-extern const __u8 uclogic_rdesc_frame_v2_arr[];
-extern const size_t uclogic_rdesc_frame_v2_size;
+extern const __u8 uclogic_rdesc_v2_frame_arr[];
+extern const size_t uclogic_rdesc_v2_frame_size;

/* Report ID for tweaked v2 frame reports */
-#define UCLOGIC_RDESC_FRAME_V2_ID 0xf7
+#define UCLOGIC_RDESC_V2_FRAME_ID 0xf7

/* Fixed report descriptor for Ugee EX07 frame */
extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
--
2.25.1

2022-02-21 07:57:44

by José Expósito

[permalink] [raw]
Subject: [PATCH for-5.18/uclogic 3/9] HID: uclogic: Switch to matching subreport bytes

From: Nikolai Kondrashov <[email protected]>

Switch from matching UC-Logic subreport with a mask to a full value to
support detecting Huion HS610 touch dial reports. Those would match the
button mask otherwise.

Signed-off-by: Nikolai Kondrashov <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-uclogic-core.c | 9 ++++++---
drivers/hid/hid-uclogic-params.c | 4 ++--
drivers/hid/hid-uclogic-params.h | 13 +++++++------
3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
index 7092f86517a5..a02edeb30a35 100644
--- a/drivers/hid/hid-uclogic-core.c
+++ b/drivers/hid/hid-uclogic-core.c
@@ -365,9 +365,12 @@ static int uclogic_raw_event(struct hid_device *hdev,
ARRAY_SIZE(params->pen.subreport_list);
/* Try to match a subreport */
for (subreport = params->pen.subreport_list;
- subreport < subreport_list_end &&
- (data[1] & subreport->mask) != subreport->mask;
- subreport++);
+ subreport < subreport_list_end; subreport++) {
+ if (subreport->value != 0 &&
+ subreport->value == data[1]) {
+ break;
+ }
+ }
/* If a subreport matched */
if (subreport < subreport_list_end) {
/* Change to subreport ID, and restart */
diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
index 138dd8b0a360..a4a53ab1e72c 100644
--- a/drivers/hid/hid-uclogic-params.c
+++ b/drivers/hid/hid-uclogic-params.c
@@ -763,7 +763,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
goto cleanup;
}
/* Link frame button subreports from pen reports */
- p.pen.subreport_list[0].mask = 0x20;
+ p.pen.subreport_list[0].value = 0xe0;
p.pen.subreport_list[0].id =
UCLOGIC_RDESC_BUTTONPAD_V2_ID;
goto output;
@@ -791,7 +791,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
(found ? "" : " not"));
if (found) {
/* Link frame button subreports from pen reports */
- p.pen.subreport_list[0].mask = 0x20;
+ p.pen.subreport_list[0].value = 0xe0;
p.pen.subreport_list[0].id =
UCLOGIC_RDESC_BUTTONPAD_V1_ID;
}
diff --git a/drivers/hid/hid-uclogic-params.h b/drivers/hid/hid-uclogic-params.h
index 82db8ab36fec..c18569591b75 100644
--- a/drivers/hid/hid-uclogic-params.h
+++ b/drivers/hid/hid-uclogic-params.h
@@ -39,14 +39,15 @@ extern const char *uclogic_params_pen_inrange_to_str(
*/
struct uclogic_params_pen_subreport {
/*
- * The subreport's bitmask matching the second byte of the pen report.
- * If zero, the subreport is considered invalid, and won't match.
+ * The value of the second byte of the pen report indicating this
+ * subreport. If zero, the subreport should be considered invalid and
+ * not matched.
*/
- __u8 mask;
+ __u8 value;

/*
- * The ID to be assigned to the report, if the "mask" matches.
- * Only valid if "mask" is not zero.
+ * The ID to be assigned to the report, if the second byte of the pen
+ * report is equal to "value". Only valid if "value" is not zero.
*/
__u8 id;
};
@@ -200,7 +201,7 @@ extern int uclogic_params_init(struct uclogic_params *params,
(_params)->pen.desc_ptr, \
(_params)->pen.desc_size, \
(_params)->pen.id, \
- (_params)->pen.subreport_list[0].mask, \
+ (_params)->pen.subreport_list[0].value, \
(_params)->pen.subreport_list[0].id, \
uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
((_params)->pen.fragmented_hires ? "true" : "false"), \
--
2.25.1

2022-02-21 09:16:46

by José Expósito

[permalink] [raw]
Subject: [PATCH for-5.18/uclogic 5/9] HID: uclogic: Use different constants for frame report IDs

From: Nikolai Kondrashov <[email protected]>

Allow to set the report ID in UCLOGIC_RDESC_FRAME_BYTES instead of
using a hardcoded value.

Signed-off-by: Nikolai Kondrashov <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-uclogic-rdesc.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
index 6e5bef39417e..66aa83f67ccc 100644
--- a/drivers/hid/hid-uclogic-rdesc.c
+++ b/drivers/hid/hid-uclogic-rdesc.c
@@ -654,13 +654,14 @@ const size_t uclogic_rdesc_pen_v2_template_size =
/*
* Expand to the contents of a generic buttonpad report descriptor.
*
+ * @_id: The report ID to use.
* @_size: Size of the report to pad to, including report ID, bytes.
*/
-#define UCLOGIC_RDESC_BUTTONPAD_BYTES(_size) \
+#define UCLOGIC_RDESC_BUTTONPAD_BYTES(_id, _size) \
0x05, 0x01, /* Usage Page (Desktop), */ \
0x09, 0x07, /* Usage (Keypad), */ \
0xA1, 0x01, /* Collection (Application), */ \
- 0x85, 0xF7, /* Report ID (247), */ \
+ 0x85, (_id), /* Report ID (_id), */ \
0x14, /* Logical Minimum (0), */ \
0x25, 0x01, /* Logical Maximum (1), */ \
0x75, 0x01, /* Report Size (1), */ \
@@ -699,14 +700,14 @@ const size_t uclogic_rdesc_pen_v2_template_size =

/* Fixed report descriptor for (tweaked) v1 buttonpad reports */
const __u8 uclogic_rdesc_buttonpad_v1_arr[] = {
- UCLOGIC_RDESC_BUTTONPAD_BYTES(8)
+ UCLOGIC_RDESC_BUTTONPAD_BYTES(UCLOGIC_RDESC_BUTTONPAD_V1_ID, 8)
};
const size_t uclogic_rdesc_buttonpad_v1_size =
sizeof(uclogic_rdesc_buttonpad_v1_arr);

/* Fixed report descriptor for (tweaked) v2 buttonpad reports */
const __u8 uclogic_rdesc_buttonpad_v2_arr[] = {
- UCLOGIC_RDESC_BUTTONPAD_BYTES(12)
+ UCLOGIC_RDESC_BUTTONPAD_BYTES(UCLOGIC_RDESC_BUTTONPAD_V2_ID, 12)
};
const size_t uclogic_rdesc_buttonpad_v2_size =
sizeof(uclogic_rdesc_buttonpad_v2_arr);
--
2.25.1

2022-02-21 09:33:35

by José Expósito

[permalink] [raw]
Subject: [PATCH for-5.18/uclogic 9/9] HID: uclogic: Support multiple frame input devices

From: Nikolai Kondrashov <[email protected]>

Add support for multiple frame input devices and their parameters to
the UC-Logic driver. This prepares for creating a separate input device
for Huion HS610 virtual touch ring reports.

Signed-off-by: Nikolai Kondrashov <[email protected]>
Signed-off-by: José Expósito <[email protected]>
---
drivers/hid/hid-uclogic-core.c | 19 ++++--
drivers/hid/hid-uclogic-params.c | 100 +++++++++++++++----------------
drivers/hid/hid-uclogic-params.h | 26 ++++----
3 files changed, 74 insertions(+), 71 deletions(-)

diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
index a02edeb30a35..05147f2d7564 100644
--- a/drivers/hid/hid-uclogic-core.c
+++ b/drivers/hid/hid-uclogic-core.c
@@ -296,17 +296,18 @@ static int uclogic_raw_event_pen(struct uclogic_drvdata *drvdata,
* uclogic_raw_event_frame - handle raw frame events (frame HID reports).
*
* @drvdata: Driver data.
+ * @frame: The parameters of the frame controls to handle.
* @data: Report data buffer, can be modified.
* @size: Report data size, bytes.
*
* Returns:
* Negative value on error (stops event delivery), zero for success.
*/
-static int uclogic_raw_event_frame(struct uclogic_drvdata *drvdata,
- u8 *data, int size)
+static int uclogic_raw_event_frame(
+ struct uclogic_drvdata *drvdata,
+ const struct uclogic_params_frame *frame,
+ u8 *data, int size)
{
- struct uclogic_params_frame *frame = &drvdata->params.frame;
-
WARN_ON(drvdata == NULL);
WARN_ON(data == NULL && size != 0);

@@ -352,6 +353,7 @@ static int uclogic_raw_event(struct hid_device *hdev,
struct uclogic_params *params = &drvdata->params;
struct uclogic_params_pen_subreport *subreport;
struct uclogic_params_pen_subreport *subreport_list_end;
+ size_t i;

/* Do not handle anything but input reports */
if (report->type != HID_INPUT_REPORT)
@@ -382,8 +384,13 @@ static int uclogic_raw_event(struct hid_device *hdev,
}

/* Tweak frame control reports, if necessary */
- if (report_id == params->frame.id)
- return uclogic_raw_event_frame(drvdata, data, size);
+ for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
+ if (report_id == params->frame_list[i].id) {
+ return uclogic_raw_event_frame(
+ drvdata, &params->frame_list[i],
+ data, size);
+ }
+ }

break;
}
diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
index f667347ad0df..5f50ceb875d6 100644
--- a/drivers/hid/hid-uclogic-params.c
+++ b/drivers/hid/hid-uclogic-params.c
@@ -512,9 +512,12 @@ static int uclogic_params_frame_init_v1(struct uclogic_params_frame *frame,
void uclogic_params_cleanup(struct uclogic_params *params)
{
if (!params->invalid) {
+ size_t i;
kfree(params->desc_ptr);
uclogic_params_pen_cleanup(&params->pen);
- uclogic_params_frame_cleanup(&params->frame);
+ for (i = 0; i < ARRAY_SIZE(params->frame_list); i++)
+ uclogic_params_frame_cleanup(&params->frame_list[i]);
+
memset(params, 0, sizeof(*params));
}
}
@@ -542,60 +545,53 @@ int uclogic_params_get_desc(const struct uclogic_params *params,
__u8 **pdesc,
unsigned int *psize)
{
- bool common_present;
- bool pen_present;
- bool frame_present;
- unsigned int size;
+ int rc = -ENOMEM;
+ bool present = false;
+ unsigned int size = 0;
__u8 *desc = NULL;
+ size_t i;

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

- size = 0;
-
- common_present = (params->desc_ptr != NULL);
- pen_present = (params->pen.desc_ptr != NULL);
- frame_present = (params->frame.desc_ptr != NULL);
-
- if (common_present)
- size += params->desc_size;
- if (pen_present)
- size += params->pen.desc_size;
- if (frame_present)
- size += params->frame.desc_size;
-
- if (common_present || pen_present || frame_present) {
- __u8 *p;
-
- desc = kmalloc(size, GFP_KERNEL);
- if (desc == NULL)
- return -ENOMEM;
- p = desc;
-
- if (common_present) {
- memcpy(p, params->desc_ptr,
- params->desc_size);
- p += params->desc_size;
- }
- if (pen_present) {
- memcpy(p, params->pen.desc_ptr,
- params->pen.desc_size);
- p += params->pen.desc_size;
- }
- if (frame_present) {
- memcpy(p, params->frame.desc_ptr,
- params->frame.desc_size);
- p += params->frame.desc_size;
- }
+ /* Concatenate descriptors */
+#define ADD_DESC(_desc_ptr, _desc_size) \
+ do { \
+ unsigned int new_size; \
+ __u8 *new_desc; \
+ if ((_desc_ptr) == NULL) { \
+ break; \
+ } \
+ new_size = size + (_desc_size); \
+ new_desc = krealloc(desc, new_size, GFP_KERNEL); \
+ if (new_desc == NULL) { \
+ goto cleanup; \
+ } \
+ memcpy(new_desc + size, (_desc_ptr), (_desc_size)); \
+ desc = new_desc; \
+ size = new_size; \
+ present = true; \
+ } while (0)
+
+ ADD_DESC(params->desc_ptr, params->desc_size);
+ ADD_DESC(params->pen.desc_ptr, params->pen.desc_size);
+ for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
+ ADD_DESC(params->frame_list[i].desc_ptr,
+ params->frame_list[i].desc_size);
+ }

- WARN_ON(p != desc + size);
+#undef ADD_DESC

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

/**
@@ -751,7 +747,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
hid_dbg(hdev, "pen v2 parameters found\n");
/* Create v2 frame parameters */
rc = uclogic_params_frame_init_with_desc(
- &p.frame,
+ &p.frame_list[0],
uclogic_rdesc_v2_frame_arr,
uclogic_rdesc_v2_frame_size,
UCLOGIC_RDESC_V2_FRAME_ID);
@@ -779,7 +775,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
} else if (found) {
hid_dbg(hdev, "pen v1 parameters found\n");
/* Try to probe v1 frame */
- rc = uclogic_params_frame_init_v1(&p.frame,
+ rc = uclogic_params_frame_init_v1(&p.frame_list[0],
&found, hdev);
if (rc != 0) {
hid_err(hdev, "v1 frame probing failed: %d\n", rc);
@@ -1033,7 +1029,7 @@ int uclogic_params_init(struct uclogic_params *params,
}
/* Initialize frame parameters */
rc = uclogic_params_frame_init_with_desc(
- &p.frame,
+ &p.frame_list[0],
uclogic_rdesc_xppen_deco01_frame_arr,
uclogic_rdesc_xppen_deco01_frame_size,
0);
@@ -1059,7 +1055,7 @@ int uclogic_params_init(struct uclogic_params *params,
goto cleanup;
} else if (found) {
rc = uclogic_params_frame_init_with_desc(
- &p.frame,
+ &p.frame_list[0],
uclogic_rdesc_ugee_g5_frame_arr,
uclogic_rdesc_ugee_g5_frame_size,
UCLOGIC_RDESC_UGEE_G5_FRAME_ID);
@@ -1069,9 +1065,9 @@ int uclogic_params_init(struct uclogic_params *params,
rc);
goto cleanup;
}
- p.frame.re_lsb =
+ p.frame_list[0].re_lsb =
UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB;
- p.frame.dev_id_byte =
+ p.frame_list[0].dev_id_byte =
UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE;
} else {
hid_warn(hdev, "pen parameters not found");
@@ -1093,7 +1089,7 @@ int uclogic_params_init(struct uclogic_params *params,
goto cleanup;
} else if (found) {
rc = uclogic_params_frame_init_with_desc(
- &p.frame,
+ &p.frame_list[0],
uclogic_rdesc_ugee_ex07_frame_arr,
uclogic_rdesc_ugee_ex07_frame_size,
0);
diff --git a/drivers/hid/hid-uclogic-params.h b/drivers/hid/hid-uclogic-params.h
index c18569591b75..86f616dfbb53 100644
--- a/drivers/hid/hid-uclogic-params.h
+++ b/drivers/hid/hid-uclogic-params.h
@@ -165,10 +165,10 @@ struct uclogic_params {
*/
struct uclogic_params_pen pen;
/*
- * Frame control parameters and optional report descriptor part.
- * Only valid, if "invalid" is false.
+ * The list of frame control parameters and optional report descriptor
+ * parts. Only valid, if "invalid" is false.
*/
- struct uclogic_params_frame frame;
+ struct uclogic_params_frame frame_list[1];
};

/* Initialize a tablet interface and discover its parameters */
@@ -187,11 +187,11 @@ extern int uclogic_params_init(struct uclogic_params *params,
".pen.inrange = %s\n" \
".pen.fragmented_hires = %s\n" \
".pen.tilt_y_flipped = %s\n" \
- ".frame.desc_ptr = %p\n" \
- ".frame.desc_size = %u\n" \
- ".frame.id = %u\n" \
- ".frame.re_lsb = %u\n" \
- ".frame.dev_id_byte = %u\n"
+ ".frame_list[0].desc_ptr = %p\n" \
+ ".frame_list[0].desc_size = %u\n" \
+ ".frame_list[0].id = %u\n" \
+ ".frame_list[0].re_lsb = %u\n" \
+ ".frame_list[0].dev_id_byte = %u\n"

/* Tablet interface parameters *printf format arguments */
#define UCLOGIC_PARAMS_FMT_ARGS(_params) \
@@ -206,11 +206,11 @@ extern int uclogic_params_init(struct uclogic_params *params,
uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
((_params)->pen.fragmented_hires ? "true" : "false"), \
((_params)->pen.tilt_y_flipped ? "true" : "false"), \
- (_params)->frame.desc_ptr, \
- (_params)->frame.desc_size, \
- (_params)->frame.id, \
- (_params)->frame.re_lsb, \
- (_params)->frame.dev_id_byte
+ (_params)->frame_list[0].desc_ptr, \
+ (_params)->frame_list[0].desc_size, \
+ (_params)->frame_list[0].id, \
+ (_params)->frame_list[0].re_lsb, \
+ (_params)->frame_list[0].dev_id_byte

/* Get a replacement report descriptor for a tablet's interface. */
extern int uclogic_params_get_desc(const struct uclogic_params *params,
--
2.25.1

2022-03-01 18:46:17

by Nikolai Kondrashov

[permalink] [raw]
Subject: Re: [PATCH for-5.18/uclogic 0/9] DIGImend patches, part II

On 3/1/22 16:29, Jiri Kosina wrote:
> On Sat, 19 Feb 2022, José Expósito wrote:
>
>> Hi everyone,
>>
>> This series is a follow up to [1], kindly reviewed and applied
>> by Jiří in hid.git#for-5.18/uclogic.
>>
>> It might look a little bit longer than desired, but most of the
>> patches are code simplification and refactoring in preparation
>> for the last patch which adds support for multiple frame input
>> devices.
>>
>> Thank you very much in advance to maintainers for reviewing it,
>> José Expósito
>>
>> [1] https://lore.kernel.org/linux-input/[email protected]/T/
>>
>> Nikolai Kondrashov (9):
>> HID: uclogic: Remove pen usage masking
>> HID: uclogic: Replace pen_frame_flag with subreport_list
>> HID: uclogic: Switch to matching subreport bytes
>> HID: uclogic: Specify total report size to buttonpad macro
>> HID: uclogic: Use different constants for frame report IDs
>> HID: uclogic: Use "frame" instead of "buttonpad"
>> HID: uclogic: Put version first in rdesc namespace
>> HID: uclogic: Define report IDs before their descriptors
>> HID: uclogic: Support multiple frame input devices
>>
>> drivers/hid/hid-uclogic-core.c | 79 +++++++------
>> drivers/hid/hid-uclogic-params.c | 195 ++++++++++++++-----------------
>> drivers/hid/hid-uclogic-params.h | 86 +++++++-------
>> drivers/hid/hid-uclogic-rdesc.c | 53 ++++-----
>> drivers/hid/hid-uclogic-rdesc.h | 38 +++---
>> 5 files changed, 221 insertions(+), 230 deletions(-)
>
> Now queued in hid.git#for-5.18/uclogic.

Thank you for your work, José, and for your reviews Jiri!

Nick

2022-03-02 16:39:44

by Jiri Kosina

[permalink] [raw]
Subject: Re: [PATCH for-5.18/uclogic 0/9] DIGImend patches, part II

On Sat, 19 Feb 2022, José Expósito wrote:

> Hi everyone,
>
> This series is a follow up to [1], kindly reviewed and applied
> by Jiří in hid.git#for-5.18/uclogic.
>
> It might look a little bit longer than desired, but most of the
> patches are code simplification and refactoring in preparation
> for the last patch which adds support for multiple frame input
> devices.
>
> Thank you very much in advance to maintainers for reviewing it,
> José Expósito
>
> [1] https://lore.kernel.org/linux-input/[email protected]/T/
>
> Nikolai Kondrashov (9):
> HID: uclogic: Remove pen usage masking
> HID: uclogic: Replace pen_frame_flag with subreport_list
> HID: uclogic: Switch to matching subreport bytes
> HID: uclogic: Specify total report size to buttonpad macro
> HID: uclogic: Use different constants for frame report IDs
> HID: uclogic: Use "frame" instead of "buttonpad"
> HID: uclogic: Put version first in rdesc namespace
> HID: uclogic: Define report IDs before their descriptors
> HID: uclogic: Support multiple frame input devices
>
> drivers/hid/hid-uclogic-core.c | 79 +++++++------
> drivers/hid/hid-uclogic-params.c | 195 ++++++++++++++-----------------
> drivers/hid/hid-uclogic-params.h | 86 +++++++-------
> drivers/hid/hid-uclogic-rdesc.c | 53 ++++-----
> drivers/hid/hid-uclogic-rdesc.h | 38 +++---
> 5 files changed, 221 insertions(+), 230 deletions(-)

Now queued in hid.git#for-5.18/uclogic.

Thanks,

--
Jiri Kosina
SUSE Labs