From 530201a53fc0bb9b0db53c41d8e2fe7f324a4d8f Mon Sep 17 00:00:00 2001
From: Dmitry Mastykin <dmastykin@astralinux.ru>
Date: Fri, 20 Nov 2020 18:12:39 +0300
Subject: buttons support


diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 280d85e0eac5..5d4301fa5b75 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -107,6 +107,8 @@ struct mt_usages {
 	bool *barrel_state;
 	bool *invert_state;
 	bool *eraser_state;
+	int rclick;
+	int mclick;
 };
 
 struct mt_application {
@@ -538,6 +540,8 @@ static struct mt_usages *mt_allocate_usage(struct hid_device *hdev,
 	usage->barrel_state = DEFAULT_FALSE;
 	usage->invert_state = DEFAULT_FALSE;
 	usage->eraser_state = DEFAULT_FALSE;
+	usage->rclick = 0;
+	usage->mclick = 0;
 
 	list_add_tail(&usage->list, &application->mt_usages);
 
@@ -939,6 +943,8 @@ static int mt_pen_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 			MT_STORE_FIELD(invert_state);
 			return 1;
 		case HID_DG_ERASER:
+			input_set_capability(hi->input,
+					     EV_KEY, BTN_STYLUS);
 			MT_STORE_FIELD(eraser_state);
 			return 1;
 		case HID_DG_TIPPRESSURE:
@@ -1329,17 +1335,58 @@ static void mt_pen_report(struct hid_device *hid,
 					       struct mt_usages, list)))
 		return;
 
+	switch (usage->rclick) {
+	case 0:
+		if (*usage->barrel_state)
+			usage->rclick++;
+		break;
+	case 1:
+	case 7:
+		if (*usage->tip_state)
+			usage->rclick = 2;
+		else if (!*usage->barrel_state)
+			usage->rclick = 0;
+		break;
+	case 2:
+		if (!*usage->tip_state)
+			usage->rclick++;
+		break;
+	default:
+		usage->rclick++;
+	}
+
+	switch (usage->mclick) {
+	case 0:
+		if (*usage->eraser_state)
+			usage->mclick++;
+		break;
+	case 1:
+		if (!*usage->eraser_state)
+			usage->mclick++;
+		break;
+	case 3:
+		if (!*usage->tip_state)
+			usage->mclick = 0;
+		break;
+	default:
+		usage->mclick++;
+	}
 
-	MY("inr:tip:bar:inv:era %d:%d:%d:%d:%d",
+	MY("inr:tip:bar:rck::inv:era:mck %d:%d:%d:%d::%d:%d:%d",
 		*usage->inrange_state,
 		*usage->tip_state,
 		*usage->barrel_state,
+		usage->rclick,
 		*usage->invert_state,
-		*usage->eraser_state
+		*usage->eraser_state,
+		usage->mclick
 	);
-	input_report_key(input, BTN_TOOL_PEN, *usage->inrange_state);
-	input_report_key(input, BTN_TOUCH, *usage->tip_state);
-	// input_report_key(input, BTN_STYLUS2, *usage->barrel_state);
+	input_report_key(input, BTN_TOOL_PEN, *usage->inrange_state ||
+			 *usage->tip_state);
+	input_report_key(input, BTN_TOUCH, *usage->tip_state &&
+			 !(usage->rclick || usage->mclick));
+	input_report_key(input, BTN_STYLUS2, usage->rclick == 2);
+	input_report_key(input, BTN_STYLUS, usage->mclick);
 	input_event(input, EV_ABS, ABS_X, *usage->x);
 	input_event(input, EV_ABS, ABS_Y, *usage->y);
 	input_event(input, EV_ABS, ABS_PRESSURE, *usage->p);