Skip to content

Commit 8b01309

Browse files
spbnickJiri Kosina
authored andcommitted
HID: uclogic: Replace pen_frame_flag with subreport_list
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 <spbnick@gmail.com> Signed-off-by: José Expósito <jose.exposito89@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
1 parent 606dadc commit 8b01309

3 files changed

Lines changed: 73 additions & 41 deletions

File tree

drivers/hid/hid-uclogic-core.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -350,26 +350,40 @@ static int uclogic_raw_event(struct hid_device *hdev,
350350
unsigned int report_id = report->id;
351351
struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
352352
struct uclogic_params *params = &drvdata->params;
353+
struct uclogic_params_pen_subreport *subreport;
354+
struct uclogic_params_pen_subreport *subreport_list_end;
353355

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

358-
/* Tweak pen reports, if necessary */
359-
if ((report_id == params->pen.id) && (size >= 2)) {
360-
/* If it's the "virtual" frame controls report */
361-
if (params->frame.id != 0 &&
362-
data[1] & params->pen_frame_flag) {
363-
/* Change to virtual frame controls report ID */
364-
report_id = data[0] = params->frame.id;
365-
} else {
366-
return uclogic_raw_event_pen(drvdata, data, size);
360+
while (true) {
361+
/* Tweak pen reports, if necessary */
362+
if ((report_id == params->pen.id) && (size >= 2)) {
363+
subreport_list_end =
364+
params->pen.subreport_list +
365+
ARRAY_SIZE(params->pen.subreport_list);
366+
/* Try to match a subreport */
367+
for (subreport = params->pen.subreport_list;
368+
subreport < subreport_list_end &&
369+
(data[1] & subreport->mask) != subreport->mask;
370+
subreport++);
371+
/* If a subreport matched */
372+
if (subreport < subreport_list_end) {
373+
/* Change to subreport ID, and restart */
374+
report_id = data[0] = subreport->id;
375+
continue;
376+
} else {
377+
return uclogic_raw_event_pen(drvdata, data, size);
378+
}
367379
}
368-
}
369380

370-
/* Tweak frame control reports, if necessary */
371-
if (report_id == params->frame.id)
372-
return uclogic_raw_event_frame(drvdata, data, size);
381+
/* Tweak frame control reports, if necessary */
382+
if (report_id == params->frame.id)
383+
return uclogic_raw_event_frame(drvdata, data, size);
384+
385+
break;
386+
}
373387

374388
return 0;
375389
}

drivers/hid/hid-uclogic-params.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -762,8 +762,10 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
762762
rc);
763763
goto cleanup;
764764
}
765-
/* Set bitmask marking frame reports in pen reports */
766-
p.pen_frame_flag = 0x20;
765+
/* Link frame button subreports from pen reports */
766+
p.pen.subreport_list[0].mask = 0x20;
767+
p.pen.subreport_list[0].id =
768+
UCLOGIC_RDESC_BUTTONPAD_V2_ID;
767769
goto output;
768770
}
769771
hid_dbg(hdev, "pen v2 parameters not found\n");
@@ -788,8 +790,10 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
788790
hid_dbg(hdev, "buttonpad v1 parameters%s found\n",
789791
(found ? "" : " not"));
790792
if (found) {
791-
/* Set bitmask marking frame reports */
792-
p.pen_frame_flag = 0x20;
793+
/* Link frame button subreports from pen reports */
794+
p.pen.subreport_list[0].mask = 0x20;
795+
p.pen.subreport_list[0].id =
796+
UCLOGIC_RDESC_BUTTONPAD_V1_ID;
793797
}
794798
goto output;
795799
}

drivers/hid/hid-uclogic-params.h

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ enum uclogic_params_pen_inrange {
3333
extern const char *uclogic_params_pen_inrange_to_str(
3434
enum uclogic_params_pen_inrange inrange);
3535

36+
37+
/*
38+
* Pen report's subreport data.
39+
*/
40+
struct uclogic_params_pen_subreport {
41+
/*
42+
* The subreport's bitmask matching the second byte of the pen report.
43+
* If zero, the subreport is considered invalid, and won't match.
44+
*/
45+
__u8 mask;
46+
47+
/*
48+
* The ID to be assigned to the report, if the "mask" matches.
49+
* Only valid if "mask" is not zero.
50+
*/
51+
__u8 id;
52+
};
53+
3654
/*
3755
* Tablet interface's pen input parameters.
3856
*
@@ -54,6 +72,8 @@ struct uclogic_params_pen {
5472
unsigned int desc_size;
5573
/* Report ID, if reports should be tweaked, zero if not */
5674
unsigned int id;
75+
/* The list of subreports */
76+
struct uclogic_params_pen_subreport subreport_list[1];
5777
/* Type of in-range reporting, only valid if "id" is not zero */
5878
enum uclogic_params_pen_inrange inrange;
5979
/*
@@ -148,13 +168,6 @@ struct uclogic_params {
148168
* Only valid, if "invalid" is false.
149169
*/
150170
struct uclogic_params_frame frame;
151-
/*
152-
* Bitmask matching frame controls "sub-report" flag in the second
153-
* byte of the pen report, or zero if it's not expected.
154-
* Only valid if both "pen" and "frame" are valid, and "frame.id" is
155-
* not zero.
156-
*/
157-
__u8 pen_frame_flag;
158171
};
159172

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

164177
/* Tablet interface parameters *printf format string */
165178
#define UCLOGIC_PARAMS_FMT_STR \
166-
".invalid = %s\n" \
167-
".desc_ptr = %p\n" \
168-
".desc_size = %u\n" \
169-
".pen.desc_ptr = %p\n" \
170-
".pen.desc_size = %u\n" \
171-
".pen.id = %u\n" \
172-
".pen.inrange = %s\n" \
173-
".pen.fragmented_hires = %s\n" \
174-
".pen.tilt_y_flipped = %s\n" \
175-
".frame.desc_ptr = %p\n" \
176-
".frame.desc_size = %u\n" \
177-
".frame.id = %u\n" \
178-
".frame.re_lsb = %u\n" \
179-
".frame.dev_id_byte = %u\n" \
180-
".pen_frame_flag = 0x%02x\n"
179+
".invalid = %s\n" \
180+
".desc_ptr = %p\n" \
181+
".desc_size = %u\n" \
182+
".pen.desc_ptr = %p\n" \
183+
".pen.desc_size = %u\n" \
184+
".pen.id = %u\n" \
185+
".pen.subreport_list[0] = {0x%02hhx, %hhu}\n" \
186+
".pen.inrange = %s\n" \
187+
".pen.fragmented_hires = %s\n" \
188+
".pen.tilt_y_flipped = %s\n" \
189+
".frame.desc_ptr = %p\n" \
190+
".frame.desc_size = %u\n" \
191+
".frame.id = %u\n" \
192+
".frame.re_lsb = %u\n" \
193+
".frame.dev_id_byte = %u\n"
181194

182195
/* Tablet interface parameters *printf format arguments */
183196
#define UCLOGIC_PARAMS_FMT_ARGS(_params) \
@@ -187,15 +200,16 @@ extern int uclogic_params_init(struct uclogic_params *params,
187200
(_params)->pen.desc_ptr, \
188201
(_params)->pen.desc_size, \
189202
(_params)->pen.id, \
203+
(_params)->pen.subreport_list[0].mask, \
204+
(_params)->pen.subreport_list[0].id, \
190205
uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
191206
((_params)->pen.fragmented_hires ? "true" : "false"), \
192207
((_params)->pen.tilt_y_flipped ? "true" : "false"), \
193208
(_params)->frame.desc_ptr, \
194209
(_params)->frame.desc_size, \
195210
(_params)->frame.id, \
196211
(_params)->frame.re_lsb, \
197-
(_params)->frame.dev_id_byte, \
198-
(_params)->pen_frame_flag
212+
(_params)->frame.dev_id_byte
199213

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

0 commit comments

Comments
 (0)