Commit 8b013098 authored by Nikolai Kondrashov's avatar Nikolai Kondrashov Committed by Jiri Kosina
Browse files

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: default avatarNikolai Kondrashov <spbnick@gmail.com>
Signed-off-by: default avatarJosé Expósito <jose.exposito89@gmail.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 606dadc1
Loading
Loading
Loading
Loading
+27 −13
Original line number Diff line number Diff line
@@ -350,18 +350,29 @@ 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;

	while (true) {
		/* 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;
			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);
			}
@@ -371,6 +382,9 @@ static int uclogic_raw_event(struct hid_device *hdev,
		if (report_id == params->frame.id)
			return uclogic_raw_event_frame(drvdata, data, size);

		break;
	}

	return 0;
}

+8 −4
Original line number Diff line number Diff line
@@ -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;
	}
+38 −24
Original line number Diff line number Diff line
@@ -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 */
@@ -169,6 +182,7 @@ extern int uclogic_params_init(struct uclogic_params *params,
		".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"                    \
@@ -176,8 +190,7 @@ extern int uclogic_params_init(struct uclogic_params *params,
		".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"
		".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,