mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-23 16:53:58 -05:00
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>
This commit is contained in:
parent
606dadc187
commit
8b013098be
3 changed files with 73 additions and 41 deletions
|
@ -350,26 +350,40 @@ static int uclogic_raw_event(struct hid_device *hdev,
|
||||||
unsigned int report_id = report->id;
|
unsigned int report_id = report->id;
|
||||||
struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
|
struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
|
||||||
struct uclogic_params *params = &drvdata->params;
|
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 */
|
/* Do not handle anything but input reports */
|
||||||
if (report->type != HID_INPUT_REPORT)
|
if (report->type != HID_INPUT_REPORT)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Tweak pen reports, if necessary */
|
while (true) {
|
||||||
if ((report_id == params->pen.id) && (size >= 2)) {
|
/* Tweak pen reports, if necessary */
|
||||||
/* If it's the "virtual" frame controls report */
|
if ((report_id == params->pen.id) && (size >= 2)) {
|
||||||
if (params->frame.id != 0 &&
|
subreport_list_end =
|
||||||
data[1] & params->pen_frame_flag) {
|
params->pen.subreport_list +
|
||||||
/* Change to virtual frame controls report ID */
|
ARRAY_SIZE(params->pen.subreport_list);
|
||||||
report_id = data[0] = params->frame.id;
|
/* Try to match a subreport */
|
||||||
} else {
|
for (subreport = params->pen.subreport_list;
|
||||||
return uclogic_raw_event_pen(drvdata, data, size);
|
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 */
|
/* Tweak frame control reports, if necessary */
|
||||||
if (report_id == params->frame.id)
|
if (report_id == params->frame.id)
|
||||||
return uclogic_raw_event_frame(drvdata, data, size);
|
return uclogic_raw_event_frame(drvdata, data, size);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -762,8 +762,10 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
|
||||||
rc);
|
rc);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
/* Set bitmask marking frame reports in pen reports */
|
/* Link frame button subreports from pen reports */
|
||||||
p.pen_frame_flag = 0x20;
|
p.pen.subreport_list[0].mask = 0x20;
|
||||||
|
p.pen.subreport_list[0].id =
|
||||||
|
UCLOGIC_RDESC_BUTTONPAD_V2_ID;
|
||||||
goto output;
|
goto output;
|
||||||
}
|
}
|
||||||
hid_dbg(hdev, "pen v2 parameters not found\n");
|
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",
|
hid_dbg(hdev, "buttonpad v1 parameters%s found\n",
|
||||||
(found ? "" : " not"));
|
(found ? "" : " not"));
|
||||||
if (found) {
|
if (found) {
|
||||||
/* Set bitmask marking frame reports */
|
/* Link frame button subreports from pen reports */
|
||||||
p.pen_frame_flag = 0x20;
|
p.pen.subreport_list[0].mask = 0x20;
|
||||||
|
p.pen.subreport_list[0].id =
|
||||||
|
UCLOGIC_RDESC_BUTTONPAD_V1_ID;
|
||||||
}
|
}
|
||||||
goto output;
|
goto output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,24 @@ enum uclogic_params_pen_inrange {
|
||||||
extern const char *uclogic_params_pen_inrange_to_str(
|
extern const char *uclogic_params_pen_inrange_to_str(
|
||||||
enum uclogic_params_pen_inrange inrange);
|
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.
|
* Tablet interface's pen input parameters.
|
||||||
*
|
*
|
||||||
|
@ -54,6 +72,8 @@ struct uclogic_params_pen {
|
||||||
unsigned int desc_size;
|
unsigned int desc_size;
|
||||||
/* Report ID, if reports should be tweaked, zero if not */
|
/* Report ID, if reports should be tweaked, zero if not */
|
||||||
unsigned int id;
|
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 */
|
/* Type of in-range reporting, only valid if "id" is not zero */
|
||||||
enum uclogic_params_pen_inrange inrange;
|
enum uclogic_params_pen_inrange inrange;
|
||||||
/*
|
/*
|
||||||
|
@ -148,13 +168,6 @@ struct uclogic_params {
|
||||||
* Only valid, if "invalid" is false.
|
* Only valid, if "invalid" is false.
|
||||||
*/
|
*/
|
||||||
struct uclogic_params_frame frame;
|
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 */
|
/* 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 */
|
/* Tablet interface parameters *printf format string */
|
||||||
#define UCLOGIC_PARAMS_FMT_STR \
|
#define UCLOGIC_PARAMS_FMT_STR \
|
||||||
".invalid = %s\n" \
|
".invalid = %s\n" \
|
||||||
".desc_ptr = %p\n" \
|
".desc_ptr = %p\n" \
|
||||||
".desc_size = %u\n" \
|
".desc_size = %u\n" \
|
||||||
".pen.desc_ptr = %p\n" \
|
".pen.desc_ptr = %p\n" \
|
||||||
".pen.desc_size = %u\n" \
|
".pen.desc_size = %u\n" \
|
||||||
".pen.id = %u\n" \
|
".pen.id = %u\n" \
|
||||||
".pen.inrange = %s\n" \
|
".pen.subreport_list[0] = {0x%02hhx, %hhu}\n" \
|
||||||
".pen.fragmented_hires = %s\n" \
|
".pen.inrange = %s\n" \
|
||||||
".pen.tilt_y_flipped = %s\n" \
|
".pen.fragmented_hires = %s\n" \
|
||||||
".frame.desc_ptr = %p\n" \
|
".pen.tilt_y_flipped = %s\n" \
|
||||||
".frame.desc_size = %u\n" \
|
".frame.desc_ptr = %p\n" \
|
||||||
".frame.id = %u\n" \
|
".frame.desc_size = %u\n" \
|
||||||
".frame.re_lsb = %u\n" \
|
".frame.id = %u\n" \
|
||||||
".frame.dev_id_byte = %u\n" \
|
".frame.re_lsb = %u\n" \
|
||||||
".pen_frame_flag = 0x%02x\n"
|
".frame.dev_id_byte = %u\n"
|
||||||
|
|
||||||
/* Tablet interface parameters *printf format arguments */
|
/* Tablet interface parameters *printf format arguments */
|
||||||
#define UCLOGIC_PARAMS_FMT_ARGS(_params) \
|
#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_ptr, \
|
||||||
(_params)->pen.desc_size, \
|
(_params)->pen.desc_size, \
|
||||||
(_params)->pen.id, \
|
(_params)->pen.id, \
|
||||||
|
(_params)->pen.subreport_list[0].mask, \
|
||||||
|
(_params)->pen.subreport_list[0].id, \
|
||||||
uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
|
uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
|
||||||
((_params)->pen.fragmented_hires ? "true" : "false"), \
|
((_params)->pen.fragmented_hires ? "true" : "false"), \
|
||||||
((_params)->pen.tilt_y_flipped ? "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.desc_size, \
|
||||||
(_params)->frame.id, \
|
(_params)->frame.id, \
|
||||||
(_params)->frame.re_lsb, \
|
(_params)->frame.re_lsb, \
|
||||||
(_params)->frame.dev_id_byte, \
|
(_params)->frame.dev_id_byte
|
||||||
(_params)->pen_frame_flag
|
|
||||||
|
|
||||||
/* Get a replacement report descriptor for a tablet's interface. */
|
/* Get a replacement report descriptor for a tablet's interface. */
|
||||||
extern int uclogic_params_get_desc(const struct uclogic_params *params,
|
extern int uclogic_params_get_desc(const struct uclogic_params *params,
|
||||||
|
|
Loading…
Add table
Reference in a new issue