diff mbox series

[4/6] Input: elantech - High resolution report for new pattern 2

Message ID 000c01d5abde$1b1ea420$515bec60$@emc.com.tw (mailing list archive)
State New, archived
Headers show
Series None | expand

Commit Message

Dave.Wang Dec. 6, 2019, 2:37 a.m. UTC
Due to the higher resolution touchpad is produced, the former
resolution bits were not enough. Extend the resolution bits
from 12 to 14 bits and also remove the mk value for new pattern 2.

Signed-off-by: Dave Wang <dave.wang@emc.com.tw>
---
 drivers/input/mouse/elantech.c | 66 +++++++++++++++++++++++++---------
 1 file changed, 49 insertions(+), 17 deletions(-)

((packet[0] & 0xf0) >> 4);
+	}
 
 	input_mt_slot(dev, id);
 	input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
@@ -655,9 +661,11 @@ static void process_packet_head_v4(struct psmouse
*psmouse)
 	input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[id].x);
 	input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[id].y);
 	input_report_abs(dev, ABS_MT_PRESSURE, pres);
-	input_report_abs(dev, ABS_MT_TOUCH_MAJOR, traces * etd->width);
-	/* report this for backwards compatibility */
-	input_report_abs(dev, ABS_TOOL_WIDTH, traces);
+	if (etd->info.pattern <= 0x01) {
+		input_report_abs(dev, ABS_MT_TOUCH_MAJOR, traces *
etd->width);
+		/* report this for backwards compatibility */
+		input_report_abs(dev, ABS_TOOL_WIDTH, traces);
+	}
 
 	elantech_input_sync_v4(psmouse);
 }
@@ -1057,15 +1065,24 @@ static int elantech_set_absolute_mode(struct psmouse
*psmouse)
 }
 
 /*
- * (value from firmware) * 10 + 790 = dpi
+ * pattern <= 0x01:
+ *	(value from firmware) * 10 + 790 = dpi
+ * else
+ *	((value from firmware) + 3) * 100 = dpi
+ *
  * we also have to convert dpi to dots/mm (*10/254 to avoid floating point)
  */
-static unsigned int elantech_convert_res(unsigned int val)
+static unsigned int elantech_convert_res(unsigned int val,
+					unsigned char pattern)
 {
-	return (val * 10 + 790) * 10 / 254;
+	if (pattern <= 0x01)
+		return (val * 10 + 790) * 10 / 254;
+	else
+		return ((val + 3) * 100) * 10 / 254;
 }
 
 static int elantech_get_resolution_v4(struct psmouse *psmouse,
+					  unsigned char pattern,
 				      unsigned int *x_res,
 				      unsigned int *y_res,
 				      unsigned int *bus)
@@ -1075,8 +1092,8 @@ static int elantech_get_resolution_v4(struct psmouse
*psmouse,
 	if (elantech_send_cmd(psmouse, ETP_RESOLUTION_QUERY, param))
 		return -1;
 
-	*x_res = elantech_convert_res(param[1] & 0x0f);
-	*y_res = elantech_convert_res((param[1] & 0xf0) >> 4);
+	*x_res = elantech_convert_res(param[1] & 0x0f, pattern);
+	*y_res = elantech_convert_res((param[1] & 0xf0) >> 4, pattern);
 	*bus = param[2];
 
 	return 0;
@@ -1194,7 +1211,8 @@ static int elantech_set_input_params(struct psmouse
*psmouse)
 		 */
 		input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2,
 				     ETP_PMAX_V2, 0, 0);
-		input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2,
+		if (etd->info.pattern <= 0x01)
+			input_set_abs_params(dev, ABS_TOOL_WIDTH,
ETP_WMIN_V2,
 				     ETP_WMAX_V2, 0, 0);
 		/* Multitouch capable pad, up to 5 fingers. */
 		input_mt_init_slots(dev, ETP_MAX_FINGERS, 0);
@@ -1206,7 +1224,8 @@ static int elantech_set_input_params(struct psmouse
*psmouse)
 		 * The firmware reports how many trace lines the finger
spans,
 		 * convert to surface unit as Protocol-B requires.
 		 */
-		input_set_abs_params(dev, ABS_MT_TOUCH_MAJOR, 0,
+		if (etd->info.pattern <= 0x01)
+			input_set_abs_params(dev, ABS_MT_TOUCH_MAJOR, 0,
 				     ETP_WMAX_V2 * width, 0, 0);
 		break;
 	}
@@ -1628,6 +1647,7 @@ static int elantech_query_info(struct psmouse
*psmouse,
 {
 	unsigned char param[3];
 	unsigned char traces;
+	unsigned char y_max_l;
 
 	memset(info, 0, sizeof(*info));
 
@@ -1732,6 +1752,7 @@ static int elantech_query_info(struct psmouse
*psmouse,
 	info->y_res = 31;
 	if (info->hw_version == 4) {
 		if (elantech_get_resolution_v4(psmouse,
+							info->pattern,
 					       &info->x_res,
 					       &info->y_res,
 					       &info->bus)) {
@@ -1800,8 +1821,19 @@ static int elantech_query_info(struct psmouse
*psmouse,
 		if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
 			return -EINVAL;
 
-		info->x_max = (0x0f & param[0]) << 8 | param[1];
-		info->y_max = (0xf0 & param[0]) << 4 | param[2];
+		if (info->pattern <= 0x01) {
+			info->x_max = (0x0f & param[0]) << 8 | param[1];
+			info->y_max = (0xf0 & param[0]) << 4 | param[2];
+		} else {
+			info->x_max = (param[0] << 8) | param[1];
+			y_max_l = param[2];
+
+			if (info->send_cmd(psmouse, ETP_SAMPLE_QUERY,
param))
+				return -1;
+
+			info->y_max = param[2] << 8 | y_max_l;
+		}
+
 		traces = info->capabilities[1];
 		if ((traces < 2) || (traces > info->x_max))
 			return -EINVAL;
diff mbox series

Patch

diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 322b181d00e9..53d7ff719d76 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -639,15 +639,21 @@  static void process_packet_head_v4(struct psmouse
*psmouse)
 	struct elantech_data *etd = psmouse->private;
 	unsigned char *packet = psmouse->packet;
 	int id = ((packet[3] & 0xe0) >> 5) - 1;
-	int pres, traces;
+	int pres, traces = 0;
 
 	if (id < 0)
 		return;
 
-	etd->mt[id].x = ((packet[1] & 0x0f) << 8) | packet[2];
-	etd->mt[id].y = etd->y_max - (((packet[4] & 0x0f) << 8) |
packet[5]);
-	pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
-	traces = (packet[0] & 0xf0) >> 4;
+	if (etd->info.pattern <= 0x01) {
+		etd->mt[id].x = ((packet[1] & 0x0f) << 8) | packet[2];
+		etd->mt[id].y = etd->y_max - (((packet[4] & 0x0f) << 8) |
packet[5]);
+		pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
+		traces = (packet[0] & 0xf0) >> 4;
+	} else {
+		etd->mt[id].x = ((packet[1] & 0x3f) << 8) | packet[2];
+		etd->mt[id].y = etd->y_max - (((packet[4] & 0x3f) << 8) |
packet[5]);
+		pres = (packet[4] & 0xc0) | ((packet[1] & 0xc0) >> 2) |