All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] elantech: add support for newer generation hardware
@ 2011-08-18  1:57 JJ Ding
  2011-08-18  1:57 ` [PATCH 1/6] Input: elantech - correct x, y value range for v2 hardware JJ Ding
                   ` (5 more replies)
  0 siblings, 6 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  1:57 UTC (permalink / raw)
  To: linux-input, linux-kernel
  Cc: Seth Forshee, Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini,
	JJ Ding

Hi list,

This is a series of patches to add support for newer generation of ELAN
touchpad.

Patches #1~5 are essentially fixes and cleanups that pave the way for
patch #6, which really adds code for v3 hardware support.

Any comments, suggestions are welcome.

Thank you.

JJ Ding (6):
  Input: elantech - correct x, y value range for v2 hardware
  Input: elantech - use firmware provided x, y ranges
  Input: elantech - packet checking for v2 hardware
  Input: elantech - work around EC buffer
  Input: elantech - clean up elantech_init
  Input: elantech - add v3 hardware support

 Documentation/input/elantech.txt |  112 ++++++++++--
 drivers/input/mouse/elantech.c   |  373 ++++++++++++++++++++++++++++++++------
 drivers/input/mouse/elantech.h   |   15 ++-
 3 files changed, 426 insertions(+), 74 deletions(-)

-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/6] Input: elantech - correct x, y value range for v2 hardware
  2011-08-18  1:57 [PATCH 0/6] elantech: add support for newer generation hardware JJ Ding
@ 2011-08-18  1:57 ` JJ Ding
  2011-08-19 12:20     ` Éric Piel
  2011-08-18  1:57 ` [PATCH 2/6] Input: elantech - use firmware provided x, y ranges JJ Ding
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 90+ messages in thread
From: JJ Ding @ 2011-08-18  1:57 UTC (permalink / raw)
  To: linux-input, linux-kernel
  Cc: Seth Forshee, Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini,
	JJ Ding

x, y values are actually 12-bit long. Also update protocol document to reflect
the change.

Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
---
 Documentation/input/elantech.txt |    8 ++++----
 drivers/input/mouse/elantech.c   |    8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt
index db798af..bce9941 100644
--- a/Documentation/input/elantech.txt
+++ b/Documentation/input/elantech.txt
@@ -389,14 +389,14 @@ byte 0:
 byte 1:
 
    bit   7   6   5   4   3   2   1   0
-	 p7  p6  p5  p4  .  x10 x9  x8
+	 p7  p6  p5  p4 x11 x10 x9  x8
 
 byte 2:
 
    bit   7   6   5   4   3   2   1   0
 	 x7  x6  x5  x4  x3  x2  x1  x0
 
-         x10..x0 = absolute x value (horizontal)
+         x11..x0 = absolute x value (horizontal)
 
 byte 3:
 
@@ -420,7 +420,7 @@ byte 3:
 byte 4:
 
    bit   7   6   5   4   3   2   1   0
-        p3  p1  p2  p0   .   .  y9  y8
+        p3  p1  p2  p0  y11 y10 y9  y8
 
 	 p7..p0 = pressure (not EF113)
 
@@ -429,7 +429,7 @@ byte 5:
    bit   7   6   5   4   3   2   1   0
         y7  y6  y5  y4  y3  y2  y1  y0
 
-         y9..y0 = absolute y value (vertical)
+         y11..y0 = absolute y value (vertical)
 
 
 4.2.2 Two finger touch
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 3250356..da161da 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -290,15 +290,15 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 		/* pass through... */
 	case 1:
 		/*
-		 * byte 1:  .   .   .   .   .  x10 x9  x8
+		 * byte 1:  .   .   .   .  x11 x10 x9  x8
 		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
 		 */
-		x1 = ((packet[1] & 0x07) << 8) | packet[2];
+		x1 = ((packet[1] & 0x0f) << 8) | packet[2];
 		/*
-		 * byte 4:  .   .   .   .   .   .  y9  y8
+		 * byte 4:  .   .   .   .  y11 y10 y9  y8
 		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
 		 */
-		y1 = ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]);
+		y1 = ETP_YMAX_V2 - (((packet[4] & 0x0f) << 8) | packet[5]);
 
 		input_report_abs(dev, ABS_X, x1);
 		input_report_abs(dev, ABS_Y, y1);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-08-18  1:57 [PATCH 0/6] elantech: add support for newer generation hardware JJ Ding
  2011-08-18  1:57 ` [PATCH 1/6] Input: elantech - correct x, y value range for v2 hardware JJ Ding
@ 2011-08-18  1:57 ` JJ Ding
  2011-08-18  2:44   ` Daniel Kurtz
  2011-08-18  7:47   ` Dmitry Torokhov
  2011-08-18  1:57 ` [PATCH 3/6] Input: elantech - packet checking for v2 hardware JJ Ding
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  1:57 UTC (permalink / raw)
  To: linux-input, linux-kernel
  Cc: Seth Forshee, Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini,
	JJ Ding

With newer hardware, the touchpad provides range info.
Let's use it.

Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
---
 drivers/input/mouse/elantech.c |   73 +++++++++++++++++++++++++++++++--------
 drivers/input/mouse/elantech.h |    4 ++-
 2 files changed, 61 insertions(+), 16 deletions(-)

diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index da161da..cf41f23 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -223,7 +223,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
 		input_report_abs(dev, ABS_X,
 			((packet[1] & 0x0c) << 6) | packet[2]);
 		input_report_abs(dev, ABS_Y,
-			ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3]));
+			etd->y_max - (((packet[1] & 0x03) << 8) | packet[3]));
 	}
 
 	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
@@ -233,7 +233,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
 	input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
 
 	if (etd->fw_version < 0x020000 &&
-	    (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
+	    (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) {
 		/* rocker up */
 		input_report_key(dev, BTN_FORWARD, packet[0] & 0x40);
 		/* rocker down */
@@ -298,7 +298,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 		 * byte 4:  .   .   .   .  y11 y10 y9  y8
 		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
 		 */
-		y1 = ETP_YMAX_V2 - (((packet[4] & 0x0f) << 8) | packet[5]);
+		y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
 
 		input_report_abs(dev, ABS_X, x1);
 		input_report_abs(dev, ABS_Y, y1);
@@ -316,14 +316,14 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 		 */
 		x1 = ((packet[0] & 0x10) << 4) | packet[1];
 		/* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */
-		y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]);
+		y1 = etd->y_2ft_max - (((packet[0] & 0x20) << 3) | packet[2]);
 		/*
 		 * byte 3:  .   .  by8 bx8  .   .   .   .
 		 * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
 		 */
 		x2 = ((packet[3] & 0x10) << 4) | packet[4];
 		/* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */
-		y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]);
+		y2 = etd->y_2ft_max - (((packet[3] & 0x20) << 3) | packet[5]);
 		/*
 		 * For compatibility with the X Synaptics driver scale up
 		 * one coordinate and report as ordinary mouse movent
@@ -470,6 +470,42 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
 	return rc;
 }
 
+static void set_range(struct psmouse *psmouse, unsigned int *x_min,
+		     unsigned int *y_min, unsigned int *x_max,
+		     unsigned int *y_max, unsigned int *y_2ft_max)
+{
+	struct elantech_data *etd = psmouse->private;
+	int i;
+
+	switch (etd->hw_version) {
+	case 1:
+		*x_min = ETP_XMIN_V1;
+		*y_min = ETP_YMIN_V1;
+		*x_max = ETP_XMAX_V1;
+		*y_max = ETP_YMAX_V1;
+		break;
+
+	case 2:
+		if (etd->fw_version == 0x020800 ||
+		    etd->fw_version == 0x020b00 ||
+		    etd->fw_version == 0x020030) {
+			*x_min = ETP_XMIN_V2;
+			*y_min = ETP_YMIN_V2;
+			*x_max = ETP_XMAX_V2;
+			*y_max = ETP_YMAX_V2;
+			*y_2ft_max = ETP_2FT_YMAX;
+			break;
+		}
+
+		i = (etd->fw_version > 0x020800 &&
+		     etd->fw_version < 0x020900) ? 1 : 2;
+		*x_max = (etd->capabilities[1] - i) * 64;
+		*y_max = (etd->capabilities[2] - i) * 64;
+		*y_2ft_max = (*y_max - i) * 64 / 4;
+		break;
+	}
+}
+
 /*
  * Set the appropriate event bits for the input subsystem
  */
@@ -477,6 +513,9 @@ static void elantech_set_input_params(struct psmouse *psmouse)
 {
 	struct input_dev *dev = psmouse->dev;
 	struct elantech_data *etd = psmouse->private;
+	unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
+
+	set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &y_2ft_max);
 
 	__set_bit(EV_KEY, dev->evbit);
 	__set_bit(EV_ABS, dev->evbit);
@@ -494,18 +533,18 @@ static void elantech_set_input_params(struct psmouse *psmouse)
 	case 1:
 		/* Rocker button */
 		if (etd->fw_version < 0x020000 &&
-		    (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
+		    (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) {
 			__set_bit(BTN_FORWARD, dev->keybit);
 			__set_bit(BTN_BACK, dev->keybit);
 		}
-		input_set_abs_params(dev, ABS_X, ETP_XMIN_V1, ETP_XMAX_V1, 0, 0);
-		input_set_abs_params(dev, ABS_Y, ETP_YMIN_V1, ETP_YMAX_V1, 0, 0);
+		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
+		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
 		break;
 
 	case 2:
 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
-		input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
-		input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
+		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
+		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
 		if (etd->reports_pressure) {
 			input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2,
 					     ETP_PMAX_V2, 0, 0);
@@ -514,10 +553,13 @@ static void elantech_set_input_params(struct psmouse *psmouse)
 		}
 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
 		input_mt_init_slots(dev, 2);
-		input_set_abs_params(dev, ABS_MT_POSITION_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
-		input_set_abs_params(dev, ABS_MT_POSITION_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
+		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
+		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
 		break;
 	}
+
+	etd->y_max = y_max;
+	etd->y_2ft_max = y_2ft_max;
 }
 
 struct elantech_attr_data {
@@ -771,13 +813,14 @@ int elantech_init(struct psmouse *psmouse)
 	pr_info("assuming hardware version %d, firmware version %d.%d.%d\n",
 		etd->hw_version, param[0], param[1], param[2]);
 
-	if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) {
+	if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY,
+	    etd->capabilities)) {
 		pr_err("failed to query capabilities.\n");
 		goto init_fail;
 	}
 	pr_info("Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n",
-		param[0], param[1], param[2]);
-	etd->capabilities = param[0];
+		etd->capabilities[0], etd->capabilities[1],
+		etd->capabilities[2]);
 
 	/*
 	 * This firmware suffers from misreporting coordinates when
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index fabb2b9..4b7447e 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -104,13 +104,15 @@ struct elantech_data {
 	unsigned char reg_25;
 	unsigned char reg_26;
 	unsigned char debug;
-	unsigned char capabilities;
+	unsigned char capabilities[3];
 	bool paritycheck;
 	bool jumpy_cursor;
 	bool reports_pressure;
 	unsigned char hw_version;
 	unsigned int fw_version;
 	unsigned int single_finger_reports;
+	unsigned int y_max;
+	unsigned int y_2ft_max;
 	unsigned char parity[256];
 };
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 3/6] Input: elantech - packet checking for v2 hardware
  2011-08-18  1:57 [PATCH 0/6] elantech: add support for newer generation hardware JJ Ding
  2011-08-18  1:57 ` [PATCH 1/6] Input: elantech - correct x, y value range for v2 hardware JJ Ding
  2011-08-18  1:57 ` [PATCH 2/6] Input: elantech - use firmware provided x, y ranges JJ Ding
@ 2011-08-18  1:57 ` JJ Ding
  2011-08-18  2:49   ` Daniel Kurtz
                     ` (2 more replies)
  2011-08-18  1:57 ` [PATCH 4/6] Input: elantech - work around EC buffer JJ Ding
                   ` (2 subsequent siblings)
  5 siblings, 3 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  1:57 UTC (permalink / raw)
  To: linux-input, linux-kernel
  Cc: Seth Forshee, Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini,
	JJ Ding

For v2 hardware, there is no real parity check, but we can still check
some constant bits for data integrity.

Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
---
 drivers/input/mouse/elantech.c |   26 +++++++++++++++++++++++---
 1 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index cf41f23..032181c 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -376,6 +376,25 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
 	       etd->parity[packet[3]] == p3;
 }
 
+static int packet_simple_check_v2(struct psmouse *psmouse)
+{
+	struct elantech_data *etd = psmouse->private;
+	unsigned char *packet = psmouse->packet;
+
+	if (etd->reports_pressure)
+		return (packet[0] & 0x0c) == 0x04 &&
+		       (packet[3] & 0x0f) == 0x02;
+
+	if ((packet[0] & 0xc0) == 0x80)
+		return (packet[0] & 0x0c) == 0x0c &&
+		       (packet[3] & 0x0e) == 0x08;
+
+	return (packet[0] & 0x3c) == 0x3c &&
+	       (packet[1] & 0xf0) == 0x00 &&
+	       (packet[3] & 0x3e) == 0x38 &&
+	       (packet[4] & 0xf0) == 0x00;
+}
+
 /*
  * Process byte stream from mouse and handle complete packets
  */
@@ -398,7 +417,9 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
 		break;
 
 	case 2:
-		/* We don't know how to check parity in protocol v2 */
+		if (etd->paritycheck && !packet_simple_check_v2(psmouse))
+			return PSMOUSE_BAD_DATA;
+
 		elantech_report_absolute_v2(psmouse);
 		break;
 	}
@@ -799,8 +820,7 @@ int elantech_init(struct psmouse *psmouse)
 		etd->hw_version = 2;
 		/* For now show extra debug information */
 		etd->debug = 1;
-		/* Don't know how to do parity checking for version 2 */
-		etd->paritycheck = 0;
+		etd->paritycheck = 1;
 
 		if (etd->fw_version >= 0x020800)
 			etd->reports_pressure = true;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 4/6] Input: elantech - work around EC buffer
  2011-08-18  1:57 [PATCH 0/6] elantech: add support for newer generation hardware JJ Ding
                   ` (2 preceding siblings ...)
  2011-08-18  1:57 ` [PATCH 3/6] Input: elantech - packet checking for v2 hardware JJ Ding
@ 2011-08-18  1:57 ` JJ Ding
  2011-08-18  2:50   ` Daniel Kurtz
                     ` (2 more replies)
  2011-08-18  1:57 ` [PATCH 5/6] Input: elantech - clean up elantech_init JJ Ding
  2011-08-18  1:57 ` [PATCH 6/6] Input: elantech - add v3 hardware support JJ Ding
  5 siblings, 3 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  1:57 UTC (permalink / raw)
  To: linux-input, linux-kernel
  Cc: Seth Forshee, Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini,
	JJ Ding

With some EC chips, when we resync due to bad packets, those bad bytes would
still remain in EC's buffer area. That makes us always get bad data back,
no matter what.

So shift packet for 1 byte when encounter bad packet, until we get rid of those
bytes.

Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
---
 drivers/input/mouse/elantech.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 032181c..7b9b6e5 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -411,20 +411,25 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
 	switch (etd->hw_version) {
 	case 1:
 		if (etd->paritycheck && !elantech_check_parity_v1(psmouse))
-			return PSMOUSE_BAD_DATA;
+			goto bad_packet;
 
 		elantech_report_absolute_v1(psmouse);
 		break;
 
 	case 2:
 		if (etd->paritycheck && !packet_simple_check_v2(psmouse))
-			return PSMOUSE_BAD_DATA;
+			goto bad_packet;
 
 		elantech_report_absolute_v2(psmouse);
 		break;
 	}
 
 	return PSMOUSE_FULL_PACKET;
+
+ bad_packet:
+	memmove(psmouse->packet, psmouse->packet + 1, psmouse->pktsize - 1);
+	psmouse->pktcnt--;
+	return PSMOUSE_GOOD_DATA;
 }
 
 /*
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 5/6] Input: elantech - clean up elantech_init
  2011-08-18  1:57 [PATCH 0/6] elantech: add support for newer generation hardware JJ Ding
                   ` (3 preceding siblings ...)
  2011-08-18  1:57 ` [PATCH 4/6] Input: elantech - work around EC buffer JJ Ding
@ 2011-08-18  1:57 ` JJ Ding
  2011-08-18  3:04   ` Daniel Kurtz
                     ` (2 more replies)
  2011-08-18  1:57 ` [PATCH 6/6] Input: elantech - add v3 hardware support JJ Ding
  5 siblings, 3 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  1:57 UTC (permalink / raw)
  To: linux-input, linux-kernel
  Cc: Seth Forshee, Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini,
	JJ Ding

Group property setting code into elantech_set_properties.

Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
---
 drivers/input/mouse/elantech.c |   69 ++++++++++++++++++++++-----------------
 1 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 7b9b6e5..ddd40eb 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -791,6 +791,42 @@ static int elantech_reconnect(struct psmouse *psmouse)
 }
 
 /*
+ * determine hardware version and set some properties according to it.
+ */
+static void elantech_set_properties(struct elantech_data *etd)
+{
+	/*
+	 * Assume every version greater than 0x020030 is new EeePC style
+	 * hardware with 6 byte packets, except 0x020600
+	 */
+	if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600)
+		etd->hw_version = 1;
+	else
+		etd->hw_version = 2;
+
+	/*
+	 * Turn on packet checking by default.
+	 */
+	etd->paritycheck = 1;
+
+	/*
+	 * This firmware suffers from misreporting coordinates when
+	 * a touch action starts causing the mouse cursor or scrolled page
+	 * to jump. Enable a workaround.
+	 */
+	etd->jumpy_cursor =
+		(etd->fw_version == 0x020022 || etd->fw_version == 0x020600);
+
+	if (etd->hw_version == 2) {
+		/* For now show extra debug information */
+		etd->debug = 1;
+
+		if (etd->fw_version >= 0x020800)
+			etd->reports_pressure = true;
+	}
+}
+
+/*
  * Initialize the touchpad and create sysfs entries
  */
 int elantech_init(struct psmouse *psmouse)
@@ -816,26 +852,9 @@ int elantech_init(struct psmouse *psmouse)
 	}
 
 	etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2];
-
-	/*
-	 * Assume every version greater than this is new EeePC style
-	 * hardware with 6 byte packets
-	 */
-	if (etd->fw_version >= 0x020030) {
-		etd->hw_version = 2;
-		/* For now show extra debug information */
-		etd->debug = 1;
-		etd->paritycheck = 1;
-
-		if (etd->fw_version >= 0x020800)
-			etd->reports_pressure = true;
-
-	} else {
-		etd->hw_version = 1;
-		etd->paritycheck = 1;
-	}
-
-	pr_info("assuming hardware version %d, firmware version %d.%d.%d\n",
+	elantech_set_properties(etd);
+	pr_info("assuming hardware version %d "
+		"(with firmware version 0x%02x%02x%02x)\n",
 		etd->hw_version, param[0], param[1], param[2]);
 
 	if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY,
@@ -847,16 +866,6 @@ int elantech_init(struct psmouse *psmouse)
 		etd->capabilities[0], etd->capabilities[1],
 		etd->capabilities[2]);
 
-	/*
-	 * This firmware suffers from misreporting coordinates when
-	 * a touch action starts causing the mouse cursor or scrolled page
-	 * to jump. Enable a workaround.
-	 */
-	if (etd->fw_version == 0x020022 || etd->fw_version == 0x020600) {
-		pr_info("firmware version 2.0.34/2.6.0 detected, enabling jumpy cursor workaround\n");
-		etd->jumpy_cursor = true;
-	}
-
 	if (elantech_set_absolute_mode(psmouse)) {
 		pr_err("failed to put touchpad into absolute mode.\n");
 		goto init_fail;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  1:57 [PATCH 0/6] elantech: add support for newer generation hardware JJ Ding
                   ` (4 preceding siblings ...)
  2011-08-18  1:57 ` [PATCH 5/6] Input: elantech - clean up elantech_init JJ Ding
@ 2011-08-18  1:57 ` JJ Ding
  2011-08-18  2:57   ` Daniel Kurtz
                     ` (5 more replies)
  5 siblings, 6 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  1:57 UTC (permalink / raw)
  To: linux-input, linux-kernel
  Cc: Seth Forshee, Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini,
	JJ Ding

v3 hardware's packet format is almost identical to v2 (one/three finger touch),
except when sensing two finger touch, the hardware sends 12 bytes of data.

Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
---
 Documentation/input/elantech.txt |  104 ++++++++++++++++--
 drivers/input/mouse/elantech.c   |  218 ++++++++++++++++++++++++++++++++++---
 drivers/input/mouse/elantech.h   |   11 ++
 3 files changed, 303 insertions(+), 30 deletions(-)

diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt
index bce9941..ce578bd 100644
--- a/Documentation/input/elantech.txt
+++ b/Documentation/input/elantech.txt
@@ -16,15 +16,22 @@ Contents
 
  1. Introduction
  2. Extra knobs
- 3. Hardware version 1
-    3.1 Registers
-    3.2 Native relative mode 4 byte packet format
-    3.3 Native absolute mode 4 byte packet format
- 4. Hardware version 2
+ 3. Differentiating hardware versions
+ 4. Hardware version 1
     4.1 Registers
-    4.2 Native absolute mode 6 byte packet format
-        4.2.1 One finger touch
-        4.2.2 Two finger touch
+    4.2 Native relative mode 4 byte packet format
+    4.3 Native absolute mode 4 byte packet format
+ 5. Hardware version 2
+    5.1 Registers
+    5.2 Native absolute mode 6 byte packet format
+        5.2.1 Parity checking and packet re-synchronization
+        5.2.2 One/Three finger touch
+        5.2.3 Two finger touch
+ 6. Hardware version 3
+    6.1 Registers
+    6.2 Native absolute mode 6 byte packet format
+        6.2.1 One/Three finger touch
+        6.2.2 Two finger touch
 
 
 
@@ -375,7 +382,7 @@ For all the other ones, there are just a few constant bits:
 
 In case an error is detected, all the packets are shifted by one (and packet[0] is discarded).
 
-5.2.1 One/Three finger touch
+5.2.2 One/Three finger touch
       ~~~~~~~~~~~~~~~~
 
 byte 0:
@@ -384,7 +391,7 @@ byte 0:
 	 n1  n0  w3  w2   .   .   R   L
 
          L, R = 1 when Left, Right mouse button pressed
-         n1..n0 = numbers of fingers on touchpad
+         n1..n0 = number of fingers on touchpad
 
 byte 1:
 
@@ -432,7 +439,7 @@ byte 5:
          y11..y0 = absolute y value (vertical)
 
 
-4.2.2 Two finger touch
+5.2.3 Two finger touch
       ~~~~~~~~~~~~~~~~
 
 Note that the two pairs of coordinates are not exactly the coordinates of the
@@ -446,7 +453,7 @@ byte 0:
         n1  n0  ay8 ax8  .   .   R   L
 
          L, R = 1 when Left, Right mouse button pressed
-         n1..n0 = numbers of fingers on touchpad
+         n1..n0 = number of fingers on touchpad
 
 byte 1:
 
@@ -480,3 +487,76 @@ byte 5:
         by7 by8 by5 by4 by3 by2 by1 by0
 
          by8..by0 = upper-right finger absolute y value
+
+/////////////////////////////////////////////////////////////////////////////
+
+6. Hardware version 3
+   ==================
+
+6.1 Registers
+    ~~~~~~~~~
+* reg_10
+
+   bit   7   6   5   4   3   2   1   0
+         0   0   0   0   0   0   0   A
+
+         A: 1 = enable absolute tracking
+
+6.2 Native absolute mode 6 byte packet format
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+1 and 3 finger touch shares the same 6-byte packet format, except that
+3 finger touch only reports the position of the center of all three fingers.
+
+Firmware would send 12 bytes of data for 2 finger touch.
+
+6.2.1 One/Three finger touch
+      ~~~~~~~~~~~~~~~~~~~~~~
+
+byte 0:
+
+   bit   7   6   5   4   3   2   1   0
+        n1  n0  w3  w2   0   1   R   L
+
+        L, R = 1 when Left, Right mouse button pressed
+        n1..n0 = number of fingers on touchpad
+
+byte 1:
+
+   bit   7   6   5   4   3   2   1   0
+        p7  p6  p5  p4 x11 x10  x9  x8
+
+byte 2:
+
+   bit   7   6   5   4   3   2   1   0
+        x7  x6  x5  x4  x3  x2  x1  x0
+
+        x11..x0 = absolute x value (horizontal)
+
+byte 3:
+
+   bit   7   6   5   4   3   2   1   0
+         0   0  w1  w0   0   0   1   0
+
+         w3..w0 = width of the finger touch
+
+byte 4:
+
+   bit   7   6   5   4   3   2   1   0
+        p3  p1  p2  p0  y11 y10 y9  y8
+
+        p7..p0 = pressure
+
+byte 5:
+
+   bit   7   6   5   4   3   2   1   0
+        y7  y6  y5  y4  y3  y2  y1  y0
+
+        y11..y0 = absolute y value (vertical)
+
+6.2.2 Two finger touch
+      ~~~~~~~~~~~~~~~~
+
+The packet format is exactly the same for two finger touch, except the hardware
+sends two 6 byte packets. The first packet contains data for the first finger,
+the second packet has data for the second finger. So for two finger touch a
+total of 12 bytes are sent.
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index ddd40eb..e13a719 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -108,6 +108,16 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
 			rc = -1;
 		}
 		break;
+
+	case 3:
+		if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
+		    elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
+		    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
+		    elantech_ps2_command(psmouse, NULL, reg) ||
+		    elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
+			rc = -1;
+		}
+		break;
 	}
 
 	if (rc)
@@ -154,6 +164,18 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg,
 			rc = -1;
 		}
 		break;
+
+	case 3:
+		if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
+		    elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
+		    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
+		    elantech_ps2_command(psmouse, NULL, reg) ||
+		    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
+		    elantech_ps2_command(psmouse, NULL, val) ||
+		    elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) {
+			rc = -1;
+		}
+		break;
 	}
 
 	if (rc)
@@ -352,6 +374,94 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 	input_sync(dev);
 }
 
+/*
+ * firmware tells us there's noise.
+ */
+static inline int debounce(unsigned int x, unsigned int y)
+{
+	return (x == 0xfff) && (y == 0xfff);
+}
+
+/*
+ * Interpret complete data packets and report absolute mode input events for
+ * hardware version 3. (12 byte packets for two fingers)
+ */
+static void elantech_report_absolute_v3(struct psmouse *psmouse,
+					int packet_type)
+{
+	struct input_dev *dev = psmouse->dev;
+	struct elantech_data *etd = psmouse->private;
+	unsigned char *packet = psmouse->packet;
+	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+	unsigned int width = 0, pres = 0;
+
+	/* byte 0: n1  n0   .   .   .   .   R   L */
+	fingers = (packet[0] & 0xc0) >> 6;
+
+	switch (fingers) {
+	case 3:
+	case 1:
+		/*
+		 * byte 1:  .   .   .   .  x11 x10 x9  x8
+		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
+		 */
+		x1 = ((packet[1] & 0x0f) << 8) | packet[2];
+		/*
+		 * byte 4:  .   .   .   .  y11 y10 y9  y8
+		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
+		 */
+		y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
+
+		if (fingers == 3 && debounce(x1, y1))
+			return;
+
+		break;
+
+	case 2:
+		if (packet_type == PACKET_V3_HEAD) {
+			/*
+			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
+			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
+			 */
+			etd->prev_x = ((packet[1] & 0x0f) << 8) | packet[2];
+			/*
+			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
+			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
+			 */
+			etd->prev_y = etd->y_max -
+				(((packet[4] & 0x0f) << 8) | packet[5]);
+			/*
+			 * wait for next packet
+			 */
+			return;
+		}
+
+		/* packet_type == PACKET_V3_TAIL */
+		x1 = etd->prev_x;
+		y1 = etd->prev_y;
+		x2 = ((packet[1] & 0x0f) << 8) | packet[2];
+		y2 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
+		break;
+	}
+
+	pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
+	width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4);
+
+	input_report_key(dev, BTN_TOUCH, fingers != 0);
+	input_report_abs(dev, ABS_X, x1);
+	input_report_abs(dev, ABS_Y, y1);
+	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
+	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
+	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
+	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
+	input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
+	input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+	input_report_abs(dev, ABS_PRESSURE, pres);
+	input_report_abs(dev, ABS_TOOL_WIDTH, width);
+
+	input_sync(dev);
+}
+
 static int elantech_check_parity_v1(struct psmouse *psmouse)
 {
 	struct elantech_data *etd = psmouse->private;
@@ -396,11 +506,31 @@ static int packet_simple_check_v2(struct psmouse *psmouse)
 }
 
 /*
+ * We check the constant bits to determine what packet type we get,
+ * so packet checking is mandatory for v3 hardware.
+ */
+static int determine_packet_v3(struct psmouse *psmouse)
+{
+	unsigned char *packet = psmouse->packet;
+
+	if ((packet[0] & 0x0c) == 0x04 &&
+	    (packet[3] & 0xcf) == 0x02)
+		return PACKET_V3_HEAD;
+
+	if ((packet[0] & 0x0c) == 0x0c &&
+	    (packet[3] & 0xce) == 0x0c)
+		return PACKET_V3_TAIL;
+
+	return PACKET_UNKNOWN;
+}
+
+/*
  * Process byte stream from mouse and handle complete packets
  */
 static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
 {
 	struct elantech_data *etd = psmouse->private;
+	int packet_type;
 
 	if (psmouse->pktcnt < psmouse->pktsize)
 		return PSMOUSE_GOOD_DATA;
@@ -422,6 +552,14 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
 
 		elantech_report_absolute_v2(psmouse);
 		break;
+
+	case 3:
+		packet_type = determine_packet_v3(psmouse);
+		if (packet_type == PACKET_UNKNOWN)
+			goto bad_packet;
+
+		elantech_report_absolute_v3(psmouse, packet_type);
+		break;
 	}
 
 	return PSMOUSE_FULL_PACKET;
@@ -459,10 +597,17 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
 		etd->reg_21 = 0x60;	/* 0x00 */
 		if (elantech_write_reg(psmouse, 0x10, etd->reg_10) ||
 		    elantech_write_reg(psmouse, 0x11, etd->reg_11) ||
-		    elantech_write_reg(psmouse, 0x21, etd->reg_21)) {
+		    elantech_write_reg(psmouse, 0x21, etd->reg_21))
 			rc = -1;
-			break;
-		}
+
+		break;
+
+	case 3:
+		etd->reg_10 = 0x0b;
+		if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
+			rc = -1;
+
+		break;
 	}
 
 	if (rc == 0) {
@@ -496,11 +641,12 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
 	return rc;
 }
 
-static void set_range(struct psmouse *psmouse, unsigned int *x_min,
+static int set_range(struct psmouse *psmouse, unsigned int *x_min,
 		     unsigned int *y_min, unsigned int *x_max,
 		     unsigned int *y_max, unsigned int *y_2ft_max)
 {
 	struct elantech_data *etd = psmouse->private;
+	unsigned char param[3];
 	int i;
 
 	switch (etd->hw_version) {
@@ -529,19 +675,30 @@ static void set_range(struct psmouse *psmouse, unsigned int *x_min,
 		*y_max = (etd->capabilities[2] - i) * 64;
 		*y_2ft_max = (*y_max - i) * 64 / 4;
 		break;
+
+	case 3:
+		if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
+			return -1;
+
+		*x_max = (0x0f & param[0]) << 8 | param[1];
+		*y_max = (0xf0 & param[0]) << 4 | param[2];
+		break;
 	}
+
+	return 0;
 }
 
 /*
  * Set the appropriate event bits for the input subsystem
  */
-static void elantech_set_input_params(struct psmouse *psmouse)
+static int elantech_set_input_params(struct psmouse *psmouse)
 {
 	struct input_dev *dev = psmouse->dev;
 	struct elantech_data *etd = psmouse->private;
 	unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
 
-	set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &y_2ft_max);
+	if (set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &y_2ft_max))
+		return -1;
 
 	__set_bit(EV_KEY, dev->evbit);
 	__set_bit(EV_ABS, dev->evbit);
@@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
 		break;
+
+	case 3:
+		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
+		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
+		/* range of pressure and width is the same as v2 */
+		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,
+				     ETP_WMAX_V2, 0, 0);
+		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
+		input_mt_init_slots(dev, 2);
+		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
+		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
+		break;
 	}
 
 	etd->y_max = y_max;
 	etd->y_2ft_max = y_2ft_max;
+
+	return 0;
 }
 
 struct elantech_attr_data {
@@ -727,7 +900,8 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties)
 	 * Report this in case there are Elantech models that use a different
 	 * set of magic numbers
 	 */
-	if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
+	if (param[0] != 0x3c || param[1] != 0x03 ||
+	    (param[2] != 0xc8 && param[2] != 0x00)) {
 		pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
 			 param[0], param[1], param[2]);
 		return -1;
@@ -793,16 +967,16 @@ static int elantech_reconnect(struct psmouse *psmouse)
 /*
  * determine hardware version and set some properties according to it.
  */
-static void elantech_set_properties(struct elantech_data *etd)
+static int elantech_set_properties(struct elantech_data *etd)
 {
-	/*
-	 * Assume every version greater than 0x020030 is new EeePC style
-	 * hardware with 6 byte packets, except 0x020600
-	 */
 	if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600)
 		etd->hw_version = 1;
-	else
+	else if (etd->fw_version < 0x150600)
 		etd->hw_version = 2;
+	else if ((etd->fw_version & 0x0f0000) >> 16 == 5)
+		etd->hw_version = 3;
+	else
+		return -1;
 
 	/*
 	 * Turn on packet checking by default.
@@ -817,13 +991,15 @@ static void elantech_set_properties(struct elantech_data *etd)
 	etd->jumpy_cursor =
 		(etd->fw_version == 0x020022 || etd->fw_version == 0x020600);
 
-	if (etd->hw_version == 2) {
+	if (etd->hw_version > 1) {
 		/* For now show extra debug information */
 		etd->debug = 1;
 
 		if (etd->fw_version >= 0x020800)
 			etd->reports_pressure = true;
 	}
+
+	return 0;
 }
 
 /*
@@ -850,9 +1026,12 @@ int elantech_init(struct psmouse *psmouse)
 		pr_err("failed to query firmware version.\n");
 		goto init_fail;
 	}
-
 	etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2];
-	elantech_set_properties(etd);
+
+	if (elantech_set_properties(etd)) {
+		pr_err("unknown hardware version, aborting...\n");
+		goto init_fail;
+	}
 	pr_info("assuming hardware version %d "
 		"(with firmware version 0x%02x%02x%02x)\n",
 		etd->hw_version, param[0], param[1], param[2]);
@@ -871,7 +1050,10 @@ int elantech_init(struct psmouse *psmouse)
 		goto init_fail;
 	}
 
-	elantech_set_input_params(psmouse);
+	if (elantech_set_input_params(psmouse)) {
+		pr_err("failed to query touchpad range.\n");
+		goto init_fail;
+	}
 
 	error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
 				   &elantech_attr_group);
@@ -883,7 +1065,7 @@ int elantech_init(struct psmouse *psmouse)
 	psmouse->protocol_handler = elantech_process_byte;
 	psmouse->disconnect = elantech_disconnect;
 	psmouse->reconnect = elantech_reconnect;
-	psmouse->pktsize = etd->hw_version == 2 ? 6 : 4;
+	psmouse->pktsize = etd->hw_version > 1 ? 6 : 4;
 
 	return 0;
 
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index 4b7447e..4f01fc6 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -16,6 +16,7 @@
 /*
  * Command values for Synaptics style queries
  */
+#define ETP_FW_ID_QUERY			0x00
 #define ETP_FW_VERSION_QUERY		0x01
 #define ETP_CAPABILITIES_QUERY		0x02
 
@@ -24,6 +25,7 @@
  */
 #define ETP_REGISTER_READ		0x10
 #define ETP_REGISTER_WRITE		0x11
+#define ETP_REGISTER_READWRITE		0x00
 
 /*
  * Hardware version 2 custom PS/2 command value
@@ -93,6 +95,13 @@
 #define ETP_2FT_YMIN			(  0 + ETP_2FT_FUZZ)
 #define ETP_2FT_YMAX			(192 - ETP_2FT_FUZZ)
 
+/*
+ * v3 hardware has 2 kinds of packet types.
+ */
+#define PACKET_UNKNOWN			0x01
+#define PACKET_V3_HEAD			0x02
+#define PACKET_V3_TAIL			0x03
+
 struct elantech_data {
 	unsigned char reg_10;
 	unsigned char reg_11;
@@ -113,6 +122,8 @@ struct elantech_data {
 	unsigned int single_finger_reports;
 	unsigned int y_max;
 	unsigned int y_2ft_max;
+	unsigned int prev_x;
+	unsigned int prev_y;
 	unsigned char parity[256];
 };
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-08-18  1:57 ` [PATCH 2/6] Input: elantech - use firmware provided x, y ranges JJ Ding
@ 2011-08-18  2:44   ` Daniel Kurtz
  2011-08-18  7:47   ` Dmitry Torokhov
  1 sibling, 0 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  2:44 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding <jj_ding@emc.com.tw> wrote:
> With newer hardware, the touchpad provides range info.
> Let's use it.
>
> Signed-off-by: JJ Ding <jj_ding@emc.com.tw>

Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 3/6] Input: elantech - packet checking for v2 hardware
  2011-08-18  1:57 ` [PATCH 3/6] Input: elantech - packet checking for v2 hardware JJ Ding
@ 2011-08-18  2:49   ` Daniel Kurtz
  2011-08-18  6:38   ` Dmitry Torokhov
  2011-08-19 12:22     ` Éric Piel
  2 siblings, 0 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  2:49 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding <jj_ding@emc.com.tw> wrote:
> For v2 hardware, there is no real parity check, but we can still check
> some constant bits for data integrity.
>
> Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
> ---
>  drivers/input/mouse/elantech.c |   26 +++++++++++++++++++++++---
>  1 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index cf41f23..032181c 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -376,6 +376,25 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
>               etd->parity[packet[3]] == p3;
>  }
>
> +static int packet_simple_check_v2(struct psmouse *psmouse)
> +{
> +       struct elantech_data *etd = psmouse->private;
> +       unsigned char *packet = psmouse->packet;
> +
> +       if (etd->reports_pressure)
> +               return (packet[0] & 0x0c) == 0x04 &&
> +                      (packet[3] & 0x0f) == 0x02;
> +
> +       if ((packet[0] & 0xc0) == 0x80)
> +               return (packet[0] & 0x0c) == 0x0c &&
> +                      (packet[3] & 0x0e) == 0x08;
> +
> +       return (packet[0] & 0x3c) == 0x3c &&
> +              (packet[1] & 0xf0) == 0x00 &&
> +              (packet[3] & 0x3e) == 0x38 &&
> +              (packet[4] & 0xf0) == 0x00;
> +}
> +
>  /*
>  * Process byte stream from mouse and handle complete packets
>  */
> @@ -398,7 +417,9 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>                break;
>
>        case 2:
> -               /* We don't know how to check parity in protocol v2 */
> +               if (etd->paritycheck && !packet_simple_check_v2(psmouse))
> +                       return PSMOUSE_BAD_DATA;
> +
>                elantech_report_absolute_v2(psmouse);
>                break;
>        }
> @@ -799,8 +820,7 @@ int elantech_init(struct psmouse *psmouse)
>                etd->hw_version = 2;
>                /* For now show extra debug information */
>                etd->debug = 1;
> -               /* Don't know how to do parity checking for version 2 */
> -               etd->paritycheck = 0;
> +               etd->paritycheck = 1;

If we always do some sort of check, can we just remove etd->paritycheck now?

>
>                if (etd->fw_version >= 0x020800)
>                        etd->reports_pressure = true;
> --
> 1.7.4.1
>
>

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/6] Input: elantech - work around EC buffer
  2011-08-18  1:57 ` [PATCH 4/6] Input: elantech - work around EC buffer JJ Ding
@ 2011-08-18  2:50   ` Daniel Kurtz
  2011-08-18  3:07   ` Wanlong Gao
  2011-08-18  6:39   ` Dmitry Torokhov
  2 siblings, 0 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  2:50 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding <jj_ding@emc.com.tw> wrote:
> With some EC chips, when we resync due to bad packets, those bad bytes would
> still remain in EC's buffer area. That makes us always get bad data back,
> no matter what.
>
> So shift packet for 1 byte when encounter bad packet, until we get rid of those
> bytes.
>
> Signed-off-by: JJ Ding <jj_ding@emc.com.tw>

Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  1:57 ` [PATCH 6/6] Input: elantech - add v3 hardware support JJ Ding
@ 2011-08-18  2:57   ` Daniel Kurtz
  2011-08-18  3:04     ` Wanlong Gao
  2011-08-18  5:39     ` JJ Ding
  2011-08-18  3:01   ` Wanlong Gao
                     ` (4 subsequent siblings)
  5 siblings, 2 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  2:57 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding <jj_ding@emc.com.tw> wrote:
> v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> except when sensing two finger touch, the hardware sends 12 bytes of data.
>
> Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
> ---
>  Documentation/input/elantech.txt |  104 ++++++++++++++++--
>  drivers/input/mouse/elantech.c   |  218 ++++++++++++++++++++++++++++++++++---
>  drivers/input/mouse/elantech.h   |   11 ++
>  3 files changed, 303 insertions(+), 30 deletions(-)
>
> diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt
> index bce9941..ce578bd 100644
> --- a/Documentation/input/elantech.txt
> +++ b/Documentation/input/elantech.txt
> @@ -16,15 +16,22 @@ Contents
>
>  1. Introduction
>  2. Extra knobs
> - 3. Hardware version 1
> -    3.1 Registers
> -    3.2 Native relative mode 4 byte packet format
> -    3.3 Native absolute mode 4 byte packet format
> - 4. Hardware version 2
> + 3. Differentiating hardware versions
> + 4. Hardware version 1
>     4.1 Registers
> -    4.2 Native absolute mode 6 byte packet format
> -        4.2.1 One finger touch
> -        4.2.2 Two finger touch
> +    4.2 Native relative mode 4 byte packet format
> +    4.3 Native absolute mode 4 byte packet format
> + 5. Hardware version 2
> +    5.1 Registers
> +    5.2 Native absolute mode 6 byte packet format
> +        5.2.1 Parity checking and packet re-synchronization
> +        5.2.2 One/Three finger touch
> +        5.2.3 Two finger touch
> + 6. Hardware version 3
> +    6.1 Registers
> +    6.2 Native absolute mode 6 byte packet format
> +        6.2.1 One/Three finger touch
> +        6.2.2 Two finger touch
>
>
>
> @@ -375,7 +382,7 @@ For all the other ones, there are just a few constant bits:
>
>  In case an error is detected, all the packets are shifted by one (and packet[0] is discarded).
>
> -5.2.1 One/Three finger touch
> +5.2.2 One/Three finger touch
>       ~~~~~~~~~~~~~~~~
>
>  byte 0:
> @@ -384,7 +391,7 @@ byte 0:
>         n1  n0  w3  w2   .   .   R   L
>
>          L, R = 1 when Left, Right mouse button pressed
> -         n1..n0 = numbers of fingers on touchpad
> +         n1..n0 = number of fingers on touchpad
>
>  byte 1:
>
> @@ -432,7 +439,7 @@ byte 5:
>          y11..y0 = absolute y value (vertical)
>
>
> -4.2.2 Two finger touch
> +5.2.3 Two finger touch
>       ~~~~~~~~~~~~~~~~
>
>  Note that the two pairs of coordinates are not exactly the coordinates of the
> @@ -446,7 +453,7 @@ byte 0:
>         n1  n0  ay8 ax8  .   .   R   L
>
>          L, R = 1 when Left, Right mouse button pressed
> -         n1..n0 = numbers of fingers on touchpad
> +         n1..n0 = number of fingers on touchpad
>
>  byte 1:
>
> @@ -480,3 +487,76 @@ byte 5:
>         by7 by8 by5 by4 by3 by2 by1 by0
>
>          by8..by0 = upper-right finger absolute y value
> +
> +/////////////////////////////////////////////////////////////////////////////
> +
> +6. Hardware version 3
> +   ==================
> +
> +6.1 Registers
> +    ~~~~~~~~~
> +* reg_10
> +
> +   bit   7   6   5   4   3   2   1   0
> +         0   0   0   0   0   0   0   A
> +
> +         A: 1 = enable absolute tracking
> +
> +6.2 Native absolute mode 6 byte packet format
> +    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +1 and 3 finger touch shares the same 6-byte packet format, except that
> +3 finger touch only reports the position of the center of all three fingers.
> +
> +Firmware would send 12 bytes of data for 2 finger touch.
> +
> +6.2.1 One/Three finger touch
> +      ~~~~~~~~~~~~~~~~~~~~~~
> +
> +byte 0:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        n1  n0  w3  w2   0   1   R   L
> +
> +        L, R = 1 when Left, Right mouse button pressed
> +        n1..n0 = number of fingers on touchpad
> +
> +byte 1:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        p7  p6  p5  p4 x11 x10  x9  x8
> +
> +byte 2:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        x7  x6  x5  x4  x3  x2  x1  x0
> +
> +        x11..x0 = absolute x value (horizontal)
> +
> +byte 3:
> +
> +   bit   7   6   5   4   3   2   1   0
> +         0   0  w1  w0   0   0   1   0
> +
> +         w3..w0 = width of the finger touch
> +
> +byte 4:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        p3  p1  p2  p0  y11 y10 y9  y8
> +
> +        p7..p0 = pressure
> +
> +byte 5:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        y7  y6  y5  y4  y3  y2  y1  y0
> +
> +        y11..y0 = absolute y value (vertical)
> +
> +6.2.2 Two finger touch
> +      ~~~~~~~~~~~~~~~~
> +
> +The packet format is exactly the same for two finger touch, except the hardware
> +sends two 6 byte packets. The first packet contains data for the first finger,
> +the second packet has data for the second finger. So for two finger touch a
> +total of 12 bytes are sent.
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index ddd40eb..e13a719 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -108,6 +108,16 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
>                        rc = -1;
>                }
>                break;
> +
> +       case 3:
> +               if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +                   elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
> +                   elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +                   elantech_ps2_command(psmouse, NULL, reg) ||
> +                   elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
> +                       rc = -1;
> +               }
> +               break;
>        }
>
>        if (rc)
> @@ -154,6 +164,18 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg,
>                        rc = -1;
>                }
>                break;
> +
> +       case 3:
> +               if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +                   elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
> +                   elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +                   elantech_ps2_command(psmouse, NULL, reg) ||
> +                   elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +                   elantech_ps2_command(psmouse, NULL, val) ||
> +                   elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) {
> +                       rc = -1;
> +               }
> +               break;
>        }
>
>        if (rc)
> @@ -352,6 +374,94 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
>        input_sync(dev);
>  }
>
> +/*
> + * firmware tells us there's noise.
> + */
> +static inline int debounce(unsigned int x, unsigned int y)
> +{
> +       return (x == 0xfff) && (y == 0xfff);

Perhaps you could document this behavior in the elantech.txt.

> +}
> +
> +/*
> + * Interpret complete data packets and report absolute mode input events for
> + * hardware version 3. (12 byte packets for two fingers)
> + */
> +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> +                                       int packet_type)
> +{
> +       struct input_dev *dev = psmouse->dev;
> +       struct elantech_data *etd = psmouse->private;
> +       unsigned char *packet = psmouse->packet;
> +       unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> +       unsigned int width = 0, pres = 0;
> +
> +       /* byte 0: n1  n0   .   .   .   .   R   L */
> +       fingers = (packet[0] & 0xc0) >> 6;
> +
> +       switch (fingers) {
> +       case 3:
> +       case 1:
> +               /*
> +                * byte 1:  .   .   .   .  x11 x10 x9  x8
> +                * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> +                */
> +               x1 = ((packet[1] & 0x0f) << 8) | packet[2];
> +               /*
> +                * byte 4:  .   .   .   .  y11 y10 y9  y8
> +                * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> +                */
> +               y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
> +
> +               if (fingers == 3 && debounce(x1, y1))
> +                       return;
> +
> +               break;
> +
> +       case 2:
> +               if (packet_type == PACKET_V3_HEAD) {
> +                       /*
> +                        * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> +                        * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> +                        */
> +                       etd->prev_x = ((packet[1] & 0x0f) << 8) | packet[2];
> +                       /*
> +                        * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> +                        * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> +                        */
> +                       etd->prev_y = etd->y_max -
> +                               (((packet[4] & 0x0f) << 8) | packet[5]);
> +                       /*
> +                        * wait for next packet
> +                        */
> +                       return;
> +               }
> +
> +               /* packet_type == PACKET_V3_TAIL */
> +               x1 = etd->prev_x;
> +               y1 = etd->prev_y;
> +               x2 = ((packet[1] & 0x0f) << 8) | packet[2];
> +               y2 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
> +               break;
> +       }
> +
> +       pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
> +       width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4);
> +
> +       input_report_key(dev, BTN_TOUCH, fingers != 0);
> +       input_report_abs(dev, ABS_X, x1);
> +       input_report_abs(dev, ABS_Y, y1);
> +       elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
> +       input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
> +       input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
> +       input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
> +       input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
> +       input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
> +       input_report_abs(dev, ABS_PRESSURE, pres);
> +       input_report_abs(dev, ABS_TOOL_WIDTH, width);
> +
> +       input_sync(dev);
> +}
> +
>  static int elantech_check_parity_v1(struct psmouse *psmouse)
>  {
>        struct elantech_data *etd = psmouse->private;
> @@ -396,11 +506,31 @@ static int packet_simple_check_v2(struct psmouse *psmouse)
>  }
>
>  /*
> + * We check the constant bits to determine what packet type we get,
> + * so packet checking is mandatory for v3 hardware.
> + */
> +static int determine_packet_v3(struct psmouse *psmouse)
> +{
> +       unsigned char *packet = psmouse->packet;
> +
> +       if ((packet[0] & 0x0c) == 0x04 &&
> +           (packet[3] & 0xcf) == 0x02)
> +               return PACKET_V3_HEAD;
> +
> +       if ((packet[0] & 0x0c) == 0x0c &&
> +           (packet[3] & 0xce) == 0x0c)
> +               return PACKET_V3_TAIL;
> +
> +       return PACKET_UNKNOWN;
> +}
> +
> +/*
>  * Process byte stream from mouse and handle complete packets
>  */
>  static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>  {
>        struct elantech_data *etd = psmouse->private;
> +       int packet_type;
>
>        if (psmouse->pktcnt < psmouse->pktsize)
>                return PSMOUSE_GOOD_DATA;
> @@ -422,6 +552,14 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>
>                elantech_report_absolute_v2(psmouse);
>                break;
> +
> +       case 3:
> +               packet_type = determine_packet_v3(psmouse);
> +               if (packet_type == PACKET_UNKNOWN)
> +                       goto bad_packet;
> +
> +               elantech_report_absolute_v3(psmouse, packet_type);
> +               break;
>        }
>
>        return PSMOUSE_FULL_PACKET;
> @@ -459,10 +597,17 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
>                etd->reg_21 = 0x60;     /* 0x00 */
>                if (elantech_write_reg(psmouse, 0x10, etd->reg_10) ||
>                    elantech_write_reg(psmouse, 0x11, etd->reg_11) ||
> -                   elantech_write_reg(psmouse, 0x21, etd->reg_21)) {
> +                   elantech_write_reg(psmouse, 0x21, etd->reg_21))
>                        rc = -1;
> -                       break;
> -               }
> +
> +               break;
> +
> +       case 3:
> +               etd->reg_10 = 0x0b;
> +               if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
> +                       rc = -1;
> +
> +               break;
>        }
>
>        if (rc == 0) {
> @@ -496,11 +641,12 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
>        return rc;
>  }
>
> -static void set_range(struct psmouse *psmouse, unsigned int *x_min,
> +static int set_range(struct psmouse *psmouse, unsigned int *x_min,
>                     unsigned int *y_min, unsigned int *x_max,
>                     unsigned int *y_max, unsigned int *y_2ft_max)
>  {
>        struct elantech_data *etd = psmouse->private;
> +       unsigned char param[3];
>        int i;
>
>        switch (etd->hw_version) {
> @@ -529,19 +675,30 @@ static void set_range(struct psmouse *psmouse, unsigned int *x_min,
>                *y_max = (etd->capabilities[2] - i) * 64;
>                *y_2ft_max = (*y_max - i) * 64 / 4;
>                break;
> +
> +       case 3:
> +               if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
> +                       return -1;
> +
> +               *x_max = (0x0f & param[0]) << 8 | param[1];
> +               *y_max = (0xf0 & param[0]) << 4 | param[2];
> +               break;
>        }
> +
> +       return 0;
>  }
>
>  /*
>  * Set the appropriate event bits for the input subsystem
>  */
> -static void elantech_set_input_params(struct psmouse *psmouse)
> +static int elantech_set_input_params(struct psmouse *psmouse)
>  {
>        struct input_dev *dev = psmouse->dev;
>        struct elantech_data *etd = psmouse->private;
>        unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
>
> -       set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &y_2ft_max);
> +       if (set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &y_2ft_max))
> +               return -1;
>
>        __set_bit(EV_KEY, dev->evbit);
>        __set_bit(EV_ABS, dev->evbit);
> @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
>                input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
>                input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
>                break;
> +
> +       case 3:
> +               input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> +               input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> +               /* range of pressure and width is the same as v2 */
> +               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,
> +                                    ETP_WMAX_V2, 0, 0);
> +               __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> +               input_mt_init_slots(dev, 2);
> +               input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> +               input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> +               break;
>        }
>
>        etd->y_max = y_max;
>        etd->y_2ft_max = y_2ft_max;
> +
> +       return 0;
>  }
>
>  struct elantech_attr_data {
> @@ -727,7 +900,8 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties)
>         * Report this in case there are Elantech models that use a different
>         * set of magic numbers
>         */
> -       if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
> +       if (param[0] != 0x3c || param[1] != 0x03 ||
> +           (param[2] != 0xc8 && param[2] != 0x00)) {
>                pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
>                         param[0], param[1], param[2]);
>                return -1;
> @@ -793,16 +967,16 @@ static int elantech_reconnect(struct psmouse *psmouse)
>  /*
>  * determine hardware version and set some properties according to it.
>  */
> -static void elantech_set_properties(struct elantech_data *etd)
> +static int elantech_set_properties(struct elantech_data *etd)
>  {
> -       /*
> -        * Assume every version greater than 0x020030 is new EeePC style
> -        * hardware with 6 byte packets, except 0x020600
> -        */
>        if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600)
>                etd->hw_version = 1;
> -       else
> +       else if (etd->fw_version < 0x150600)
>                etd->hw_version = 2;
> +       else if ((etd->fw_version & 0x0f0000) >> 16 == 5)
> +               etd->hw_version = 3;
> +       else
> +               return -1;
>
>        /*
>         * Turn on packet checking by default.
> @@ -817,13 +991,15 @@ static void elantech_set_properties(struct elantech_data *etd)
>        etd->jumpy_cursor =
>                (etd->fw_version == 0x020022 || etd->fw_version == 0x020600);
>
> -       if (etd->hw_version == 2) {
> +       if (etd->hw_version > 1) {
>                /* For now show extra debug information */
>                etd->debug = 1;
>
>                if (etd->fw_version >= 0x020800)
>                        etd->reports_pressure = true;
>        }
> +
> +       return 0;
>  }
>
>  /*
> @@ -850,9 +1026,12 @@ int elantech_init(struct psmouse *psmouse)
>                pr_err("failed to query firmware version.\n");
>                goto init_fail;
>        }
> -
>        etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2];
> -       elantech_set_properties(etd);
> +
> +       if (elantech_set_properties(etd)) {
> +               pr_err("unknown hardware version, aborting...\n");
> +               goto init_fail;
> +       }
>        pr_info("assuming hardware version %d "
>                "(with firmware version 0x%02x%02x%02x)\n",
>                etd->hw_version, param[0], param[1], param[2]);
> @@ -871,7 +1050,10 @@ int elantech_init(struct psmouse *psmouse)
>                goto init_fail;
>        }
>
> -       elantech_set_input_params(psmouse);
> +       if (elantech_set_input_params(psmouse)) {
> +               pr_err("failed to query touchpad range.\n");
> +               goto init_fail;
> +       }
>
>        error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
>                                   &elantech_attr_group);
> @@ -883,7 +1065,7 @@ int elantech_init(struct psmouse *psmouse)
>        psmouse->protocol_handler = elantech_process_byte;
>        psmouse->disconnect = elantech_disconnect;
>        psmouse->reconnect = elantech_reconnect;
> -       psmouse->pktsize = etd->hw_version == 2 ? 6 : 4;
> +       psmouse->pktsize = etd->hw_version > 1 ? 6 : 4;
>
>        return 0;
>
> diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
> index 4b7447e..4f01fc6 100644
> --- a/drivers/input/mouse/elantech.h
> +++ b/drivers/input/mouse/elantech.h
> @@ -16,6 +16,7 @@
>  /*
>  * Command values for Synaptics style queries
>  */
> +#define ETP_FW_ID_QUERY                        0x00

One tab too many?

>  #define ETP_FW_VERSION_QUERY           0x01
>  #define ETP_CAPABILITIES_QUERY         0x02
>
> @@ -24,6 +25,7 @@
>  */
>  #define ETP_REGISTER_READ              0x10
>  #define ETP_REGISTER_WRITE             0x11
> +#define ETP_REGISTER_READWRITE         0x00
>
>  /*
>  * Hardware version 2 custom PS/2 command value
> @@ -93,6 +95,13 @@
>  #define ETP_2FT_YMIN                   (  0 + ETP_2FT_FUZZ)
>  #define ETP_2FT_YMAX                   (192 - ETP_2FT_FUZZ)
>
> +/*
> + * v3 hardware has 2 kinds of packet types.
> + */
> +#define PACKET_UNKNOWN                 0x01
> +#define PACKET_V3_HEAD                 0x02
> +#define PACKET_V3_TAIL                 0x03
> +
>  struct elantech_data {
>        unsigned char reg_10;
>        unsigned char reg_11;
> @@ -113,6 +122,8 @@ struct elantech_data {
>        unsigned int single_finger_reports;
>        unsigned int y_max;
>        unsigned int y_2ft_max;
> +       unsigned int prev_x;
> +       unsigned int prev_y;
>        unsigned char parity[256];
>  };
>
> --
> 1.7.4.1
>
>

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  1:57 ` [PATCH 6/6] Input: elantech - add v3 hardware support JJ Ding
  2011-08-18  2:57   ` Daniel Kurtz
@ 2011-08-18  3:01   ` Wanlong Gao
  2011-08-18  5:26     ` JJ Ding
  2011-08-18  3:30   ` Wanlong Gao
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  3:01 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 09:57 AM, JJ Ding wrote:
> v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> except when sensing two finger touch, the hardware sends 12 bytes of data.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
> ---
>   Documentation/input/elantech.txt |  104 ++++++++++++++++--
>   drivers/input/mouse/elantech.c   |  218 ++++++++++++++++++++++++++++++++++---
>   drivers/input/mouse/elantech.h   |   11 ++
>   3 files changed, 303 insertions(+), 30 deletions(-)
>
> diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt
> index bce9941..ce578bd 100644
> --- a/Documentation/input/elantech.txt
> +++ b/Documentation/input/elantech.txt
> @@ -16,15 +16,22 @@ Contents
>
>    1. Introduction
>    2. Extra knobs
> - 3. Hardware version 1
> -    3.1 Registers
> -    3.2 Native relative mode 4 byte packet format
> -    3.3 Native absolute mode 4 byte packet format
> - 4. Hardware version 2
> + 3. Differentiating hardware versions
> + 4. Hardware version 1
>       4.1 Registers
> -    4.2 Native absolute mode 6 byte packet format
> -        4.2.1 One finger touch
> -        4.2.2 Two finger touch
> +    4.2 Native relative mode 4 byte packet format
> +    4.3 Native absolute mode 4 byte packet format
> + 5. Hardware version 2
> +    5.1 Registers
> +    5.2 Native absolute mode 6 byte packet format
> +        5.2.1 Parity checking and packet re-synchronization
> +        5.2.2 One/Three finger touch
> +        5.2.3 Two finger touch
> + 6. Hardware version 3
> +    6.1 Registers
> +    6.2 Native absolute mode 6 byte packet format
> +        6.2.1 One/Three finger touch
> +        6.2.2 Two finger touch
>
>
>
> @@ -375,7 +382,7 @@ For all the other ones, there are just a few constant bits:
>
>   In case an error is detected, all the packets are shifted by one (and packet[0] is discarded).
>
> -5.2.1 One/Three finger touch
> +5.2.2 One/Three finger touch
>         ~~~~~~~~~~~~~~~~
>
>   byte 0:
> @@ -384,7 +391,7 @@ byte 0:
>   	 n1  n0  w3  w2   .   .   R   L
>
>            L, R = 1 when Left, Right mouse button pressed
> -         n1..n0 = numbers of fingers on touchpad
> +         n1..n0 = number of fingers on touchpad
>
>   byte 1:
>
> @@ -432,7 +439,7 @@ byte 5:
>            y11..y0 = absolute y value (vertical)
>
>
> -4.2.2 Two finger touch
> +5.2.3 Two finger touch
>         ~~~~~~~~~~~~~~~~
>
>   Note that the two pairs of coordinates are not exactly the coordinates of the
> @@ -446,7 +453,7 @@ byte 0:
>           n1  n0  ay8 ax8  .   .   R   L
>
>            L, R = 1 when Left, Right mouse button pressed
> -         n1..n0 = numbers of fingers on touchpad
> +         n1..n0 = number of fingers on touchpad
>
>   byte 1:
>
> @@ -480,3 +487,76 @@ byte 5:
>           by7 by8 by5 by4 by3 by2 by1 by0
>
>            by8..by0 = upper-right finger absolute y value
> +
> +/////////////////////////////////////////////////////////////////////////////
> +
> +6. Hardware version 3
> +   ==================
> +
> +6.1 Registers
> +    ~~~~~~~~~
> +* reg_10
> +
> +   bit   7   6   5   4   3   2   1   0
> +         0   0   0   0   0   0   0   A
> +
> +         A: 1 = enable absolute tracking
> +
> +6.2 Native absolute mode 6 byte packet format
> +    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +1 and 3 finger touch shares the same 6-byte packet format, except that
> +3 finger touch only reports the position of the center of all three fingers.
> +
> +Firmware would send 12 bytes of data for 2 finger touch.
> +
> +6.2.1 One/Three finger touch
> +      ~~~~~~~~~~~~~~~~~~~~~~
> +
> +byte 0:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        n1  n0  w3  w2   0   1   R   L
> +
> +        L, R = 1 when Left, Right mouse button pressed
> +        n1..n0 = number of fingers on touchpad
> +
> +byte 1:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        p7  p6  p5  p4 x11 x10  x9  x8
> +
> +byte 2:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        x7  x6  x5  x4  x3  x2  x1  x0
> +
> +        x11..x0 = absolute x value (horizontal)
> +
> +byte 3:
> +
> +   bit   7   6   5   4   3   2   1   0
> +         0   0  w1  w0   0   0   1   0
> +
> +         w3..w0 = width of the finger touch
> +
> +byte 4:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        p3  p1  p2  p0  y11 y10 y9  y8
> +
> +        p7..p0 = pressure
> +
> +byte 5:
> +
> +   bit   7   6   5   4   3   2   1   0
> +        y7  y6  y5  y4  y3  y2  y1  y0
> +
> +        y11..y0 = absolute y value (vertical)
> +
> +6.2.2 Two finger touch
> +      ~~~~~~~~~~~~~~~~
> +
> +The packet format is exactly the same for two finger touch, except the hardware
> +sends two 6 byte packets. The first packet contains data for the first finger,
> +the second packet has data for the second finger. So for two finger touch a
> +total of 12 bytes are sent.
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index ddd40eb..e13a719 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -108,6 +108,16 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
>   			rc = -1;
>   		}
>   		break;
> +
> +	case 3:
> +		if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, reg) ||
> +		    elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
> +			rc = -1;
> +		}
> +		break;
>   	}
>
>   	if (rc)
> @@ -154,6 +164,18 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg,
>   			rc = -1;
>   		}
>   		break;
> +
> +	case 3:
> +		if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, reg) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, val) ||
> +		    elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) {
> +			rc = -1;
> +		}
> +		break;
>   	}
>
>   	if (rc)
> @@ -352,6 +374,94 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
>   	input_sync(dev);
>   }
>
> +/*
> + * firmware tells us there's noise.
> + */
> +static inline int debounce(unsigned int x, unsigned int y)
> +{
> +	return (x == 0xfff)&&  (y == 0xfff);
> +}
> +
> +/*
> + * Interpret complete data packets and report absolute mode input events for
> + * hardware version 3. (12 byte packets for two fingers)
> + */
> +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> +					int packet_type)
> +{
> +	struct input_dev *dev = psmouse->dev;
> +	struct elantech_data *etd = psmouse->private;
> +	unsigned char *packet = psmouse->packet;
> +	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> +	unsigned int width = 0, pres = 0;
> +
> +	/* byte 0: n1  n0   .   .   .   .   R   L */
> +	fingers = (packet[0]&  0xc0)>>  6;
> +
> +	switch (fingers) {
> +	case 3:
> +	case 1:
> +		/*
> +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
> +		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> +		 */
> +		x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> +		/*
> +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
> +		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> +		 */
> +		y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> +
> +		if (fingers == 3&&  debounce(x1, y1))
> +			return;
> +
> +		break;
> +
> +	case 2:
> +		if (packet_type == PACKET_V3_HEAD) {
> +			/*
> +			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> +			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> +			 */
> +			etd->prev_x = ((packet[1]&  0x0f)<<  8) | packet[2];
> +			/*
> +			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> +			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> +			 */
> +			etd->prev_y = etd->y_max -
> +				(((packet[4]&  0x0f)<<  8) | packet[5]);
> +			/*
> +			 * wait for next packet
> +			 */
> +			return;
> +		}
> +
> +		/* packet_type == PACKET_V3_TAIL */
> +		x1 = etd->prev_x;
> +		y1 = etd->prev_y;
> +		x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
> +		y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> +		break;
> +	}
> +
> +	pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
> +	width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
> +
> +	input_report_key(dev, BTN_TOUCH, fingers != 0);
> +	input_report_abs(dev, ABS_X, x1);
> +	input_report_abs(dev, ABS_Y, y1);
> +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
> +	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
> +	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
> +	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
> +	input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
> +	input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
> +	input_report_abs(dev, ABS_PRESSURE, pres);
> +	input_report_abs(dev, ABS_TOOL_WIDTH, width);
> +
> +	input_sync(dev);
> +}
> +
>   static int elantech_check_parity_v1(struct psmouse *psmouse)
>   {
>   	struct elantech_data *etd = psmouse->private;
> @@ -396,11 +506,31 @@ static int packet_simple_check_v2(struct psmouse *psmouse)
>   }
>
>   /*
> + * We check the constant bits to determine what packet type we get,
> + * so packet checking is mandatory for v3 hardware.
> + */
> +static int determine_packet_v3(struct psmouse *psmouse)
elantech_check_parity_v1
packet_simple_check_v2
determine_packet_v3

Why not consistent them?
> +{
> +	unsigned char *packet = psmouse->packet;
> +
> +	if ((packet[0]&  0x0c) == 0x04&&
> +	    (packet[3]&  0xcf) == 0x02)
> +		return PACKET_V3_HEAD;
> +
> +	if ((packet[0]&  0x0c) == 0x0c&&
> +	    (packet[3]&  0xce) == 0x0c)
> +		return PACKET_V3_TAIL;
> +
> +	return PACKET_UNKNOWN;
> +}
> +
> +/*
>    * Process byte stream from mouse and handle complete packets
>    */
>   static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>   {
>   	struct elantech_data *etd = psmouse->private;
> +	int packet_type;
>
>   	if (psmouse->pktcnt<  psmouse->pktsize)
>   		return PSMOUSE_GOOD_DATA;
> @@ -422,6 +552,14 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>
>   		elantech_report_absolute_v2(psmouse);
>   		break;
> +
> +	case 3:
> +		packet_type = determine_packet_v3(psmouse);
> +		if (packet_type == PACKET_UNKNOWN)
> +			goto bad_packet;
> +
> +		elantech_report_absolute_v3(psmouse, packet_type);
> +		break;
>   	}
>
>   	return PSMOUSE_FULL_PACKET;
> @@ -459,10 +597,17 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
>   		etd->reg_21 = 0x60;	/* 0x00 */
>   		if (elantech_write_reg(psmouse, 0x10, etd->reg_10) ||
>   		    elantech_write_reg(psmouse, 0x11, etd->reg_11) ||
> -		    elantech_write_reg(psmouse, 0x21, etd->reg_21)) {
> +		    elantech_write_reg(psmouse, 0x21, etd->reg_21))
>   			rc = -1;
> -			break;
> -		}
> +
> +		break;
> +
> +	case 3:
> +		etd->reg_10 = 0x0b;
> +		if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
> +			rc = -1;
> +
> +		break;
>   	}
>
>   	if (rc == 0) {
> @@ -496,11 +641,12 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
>   	return rc;
>   }
>
> -static void set_range(struct psmouse *psmouse, unsigned int *x_min,
> +static int set_range(struct psmouse *psmouse, unsigned int *x_min,
>   		     unsigned int *y_min, unsigned int *x_max,
>   		     unsigned int *y_max, unsigned int *y_2ft_max)
>   {
>   	struct elantech_data *etd = psmouse->private;
> +	unsigned char param[3];
>   	int i;
>
>   	switch (etd->hw_version) {
> @@ -529,19 +675,30 @@ static void set_range(struct psmouse *psmouse, unsigned int *x_min,
>   		*y_max = (etd->capabilities[2] - i) * 64;
>   		*y_2ft_max = (*y_max - i) * 64 / 4;
>   		break;
> +
> +	case 3:
> +		if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
> +			return -1;
> +
> +		*x_max = (0x0f&  param[0])<<  8 | param[1];
> +		*y_max = (0xf0&  param[0])<<  4 | param[2];
> +		break;
>   	}
> +
> +	return 0;
>   }
>
>   /*
>    * Set the appropriate event bits for the input subsystem
>    */
> -static void elantech_set_input_params(struct psmouse *psmouse)
> +static int elantech_set_input_params(struct psmouse *psmouse)
>   {
>   	struct input_dev *dev = psmouse->dev;
>   	struct elantech_data *etd = psmouse->private;
>   	unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
>
> -	set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
> +	if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
> +		return -1;
>
>   	__set_bit(EV_KEY, dev->evbit);
>   	__set_bit(EV_ABS, dev->evbit);
> @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
>   		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
>   		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
>   		break;
> +
> +	case 3:
> +		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> +		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> +		/* range of pressure and width is the same as v2 */
> +		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,
> +				     ETP_WMAX_V2, 0, 0);
> +		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> +		input_mt_init_slots(dev, 2);
> +		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> +		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> +		break;
>   	}
>
>   	etd->y_max = y_max;
>   	etd->y_2ft_max = y_2ft_max;
> +
> +	return 0;
>   }
>
>   struct elantech_attr_data {
> @@ -727,7 +900,8 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties)
>   	 * Report this in case there are Elantech models that use a different
>   	 * set of magic numbers
>   	 */
> -	if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
> +	if (param[0] != 0x3c || param[1] != 0x03 ||
> +	    (param[2] != 0xc8&&  param[2] != 0x00)) {
>   		pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
>   			 param[0], param[1], param[2]);
>   		return -1;
> @@ -793,16 +967,16 @@ static int elantech_reconnect(struct psmouse *psmouse)
>   /*
>    * determine hardware version and set some properties according to it.
>    */
> -static void elantech_set_properties(struct elantech_data *etd)
> +static int elantech_set_properties(struct elantech_data *etd)
>   {
> -	/*
> -	 * Assume every version greater than 0x020030 is new EeePC style
> -	 * hardware with 6 byte packets, except 0x020600
> -	 */
>   	if (etd->fw_version<  0x020030 || etd->fw_version == 0x020600)
>   		etd->hw_version = 1;
> -	else
> +	else if (etd->fw_version<  0x150600)
>   		etd->hw_version = 2;
> +	else if ((etd->fw_version&  0x0f0000)>>  16 == 5)
> +		etd->hw_version = 3;
> +	else
> +		return -1;
>
>   	/*
>   	 * Turn on packet checking by default.
> @@ -817,13 +991,15 @@ static void elantech_set_properties(struct elantech_data *etd)
>   	etd->jumpy_cursor =
>   		(etd->fw_version == 0x020022 || etd->fw_version == 0x020600);
>
> -	if (etd->hw_version == 2) {
> +	if (etd->hw_version>  1) {
>   		/* For now show extra debug information */
>   		etd->debug = 1;
>
>   		if (etd->fw_version>= 0x020800)
>   			etd->reports_pressure = true;
>   	}
> +
> +	return 0;
>   }
>
>   /*
> @@ -850,9 +1026,12 @@ int elantech_init(struct psmouse *psmouse)
>   		pr_err("failed to query firmware version.\n");
>   		goto init_fail;
>   	}
> -
>   	etd->fw_version = (param[0]<<  16) | (param[1]<<  8) | param[2];
> -	elantech_set_properties(etd);
> +
> +	if (elantech_set_properties(etd)) {
> +		pr_err("unknown hardware version, aborting...\n");
> +		goto init_fail;
> +	}
>   	pr_info("assuming hardware version %d "
>   		"(with firmware version 0x%02x%02x%02x)\n",
>   		etd->hw_version, param[0], param[1], param[2]);
> @@ -871,7 +1050,10 @@ int elantech_init(struct psmouse *psmouse)
>   		goto init_fail;
>   	}
>
> -	elantech_set_input_params(psmouse);
> +	if (elantech_set_input_params(psmouse)) {
> +		pr_err("failed to query touchpad range.\n");
> +		goto init_fail;
> +	}
>
>   	error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
>   				&elantech_attr_group);
> @@ -883,7 +1065,7 @@ int elantech_init(struct psmouse *psmouse)
>   	psmouse->protocol_handler = elantech_process_byte;
>   	psmouse->disconnect = elantech_disconnect;
>   	psmouse->reconnect = elantech_reconnect;
> -	psmouse->pktsize = etd->hw_version == 2 ? 6 : 4;
> +	psmouse->pktsize = etd->hw_version>  1 ? 6 : 4;
>
>   	return 0;
>
> diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
> index 4b7447e..4f01fc6 100644
> --- a/drivers/input/mouse/elantech.h
> +++ b/drivers/input/mouse/elantech.h
> @@ -16,6 +16,7 @@
>   /*
>    * Command values for Synaptics style queries
>    */
> +#define ETP_FW_ID_QUERY			0x00
>   #define ETP_FW_VERSION_QUERY		0x01
>   #define ETP_CAPABILITIES_QUERY		0x02
>
> @@ -24,6 +25,7 @@
>    */
>   #define ETP_REGISTER_READ		0x10
>   #define ETP_REGISTER_WRITE		0x11
> +#define ETP_REGISTER_READWRITE		0x00
>
>   /*
>    * Hardware version 2 custom PS/2 command value
> @@ -93,6 +95,13 @@
>   #define ETP_2FT_YMIN			(  0 + ETP_2FT_FUZZ)
>   #define ETP_2FT_YMAX			(192 - ETP_2FT_FUZZ)
>
> +/*
> + * v3 hardware has 2 kinds of packet types.
> + */
> +#define PACKET_UNKNOWN			0x01
> +#define PACKET_V3_HEAD			0x02
> +#define PACKET_V3_TAIL			0x03
> +
>   struct elantech_data {
>   	unsigned char reg_10;
>   	unsigned char reg_11;
> @@ -113,6 +122,8 @@ struct elantech_data {
>   	unsigned int single_finger_reports;
>   	unsigned int y_max;
>   	unsigned int y_2ft_max;
> +	unsigned int prev_x;
> +	unsigned int prev_y;
>   	unsigned char parity[256];
>   };
>


-- 
Thanks
Wanlong Gao

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  2:57   ` Daniel Kurtz
@ 2011-08-18  3:04     ` Wanlong Gao
  2011-08-18  3:09         ` Daniel Kurtz
  2011-08-18  5:39     ` JJ Ding
  1 sibling, 1 reply; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  3:04 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 10:57 AM, Daniel Kurtz wrote:
> On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding<jj_ding@emc.com.tw>  wrote:
>> v3 hardware's packet format is almost identical to v2 (one/three finger touch),
>> except when sensing two finger touch, the hardware sends 12 bytes of data.
>>
>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>> ---
>>   Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>   drivers/input/mouse/elantech.c   |  218 ++++++++++++++++++++++++++++++++++---
>>   drivers/input/mouse/elantech.h   |   11 ++
>>   3 files changed, 303 insertions(+), 30 deletions(-)
>>
>> diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt
>> index bce9941..ce578bd 100644
>> --- a/Documentation/input/elantech.txt
>> +++ b/Documentation/input/elantech.txt
>> @@ -16,15 +16,22 @@ Contents
>>
>>   1. Introduction
>>   2. Extra knobs
>> - 3. Hardware version 1
>> -    3.1 Registers
>> -    3.2 Native relative mode 4 byte packet format
>> -    3.3 Native absolute mode 4 byte packet format
>> - 4. Hardware version 2
>> + 3. Differentiating hardware versions
>> + 4. Hardware version 1
>>      4.1 Registers
>> -    4.2 Native absolute mode 6 byte packet format
>> -        4.2.1 One finger touch
>> -        4.2.2 Two finger touch
>> +    4.2 Native relative mode 4 byte packet format
>> +    4.3 Native absolute mode 4 byte packet format
>> + 5. Hardware version 2
>> +    5.1 Registers
>> +    5.2 Native absolute mode 6 byte packet format
>> +        5.2.1 Parity checking and packet re-synchronization
>> +        5.2.2 One/Three finger touch
>> +        5.2.3 Two finger touch
>> + 6. Hardware version 3
>> +    6.1 Registers
>> +    6.2 Native absolute mode 6 byte packet format
>> +        6.2.1 One/Three finger touch
>> +        6.2.2 Two finger touch
>>
>>
>>
>> @@ -375,7 +382,7 @@ For all the other ones, there are just a few constant bits:
>>
>>   In case an error is detected, all the packets are shifted by one (and packet[0] is discarded).
>>
>> -5.2.1 One/Three finger touch
>> +5.2.2 One/Three finger touch
>>        ~~~~~~~~~~~~~~~~
>>
>>   byte 0:
>> @@ -384,7 +391,7 @@ byte 0:
>>          n1  n0  w3  w2   .   .   R   L
>>
>>           L, R = 1 when Left, Right mouse button pressed
>> -         n1..n0 = numbers of fingers on touchpad
>> +         n1..n0 = number of fingers on touchpad
>>
>>   byte 1:
>>
>> @@ -432,7 +439,7 @@ byte 5:
>>           y11..y0 = absolute y value (vertical)
>>
>>
>> -4.2.2 Two finger touch
>> +5.2.3 Two finger touch
>>        ~~~~~~~~~~~~~~~~
>>
>>   Note that the two pairs of coordinates are not exactly the coordinates of the
>> @@ -446,7 +453,7 @@ byte 0:
>>          n1  n0  ay8 ax8  .   .   R   L
>>
>>           L, R = 1 when Left, Right mouse button pressed
>> -         n1..n0 = numbers of fingers on touchpad
>> +         n1..n0 = number of fingers on touchpad
>>
>>   byte 1:
>>
>> @@ -480,3 +487,76 @@ byte 5:
>>          by7 by8 by5 by4 by3 by2 by1 by0
>>
>>           by8..by0 = upper-right finger absolute y value
>> +
>> +/////////////////////////////////////////////////////////////////////////////
>> +
>> +6. Hardware version 3
>> +   ==================
>> +
>> +6.1 Registers
>> +    ~~~~~~~~~
>> +* reg_10
>> +
>> +   bit   7   6   5   4   3   2   1   0
>> +         0   0   0   0   0   0   0   A
>> +
>> +         A: 1 = enable absolute tracking
>> +
>> +6.2 Native absolute mode 6 byte packet format
>> +    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> +1 and 3 finger touch shares the same 6-byte packet format, except that
>> +3 finger touch only reports the position of the center of all three fingers.
>> +
>> +Firmware would send 12 bytes of data for 2 finger touch.
>> +
>> +6.2.1 One/Three finger touch
>> +      ~~~~~~~~~~~~~~~~~~~~~~
>> +
>> +byte 0:
>> +
>> +   bit   7   6   5   4   3   2   1   0
>> +        n1  n0  w3  w2   0   1   R   L
>> +
>> +        L, R = 1 when Left, Right mouse button pressed
>> +        n1..n0 = number of fingers on touchpad
>> +
>> +byte 1:
>> +
>> +   bit   7   6   5   4   3   2   1   0
>> +        p7  p6  p5  p4 x11 x10  x9  x8
>> +
>> +byte 2:
>> +
>> +   bit   7   6   5   4   3   2   1   0
>> +        x7  x6  x5  x4  x3  x2  x1  x0
>> +
>> +        x11..x0 = absolute x value (horizontal)
>> +
>> +byte 3:
>> +
>> +   bit   7   6   5   4   3   2   1   0
>> +         0   0  w1  w0   0   0   1   0
>> +
>> +         w3..w0 = width of the finger touch
>> +
>> +byte 4:
>> +
>> +   bit   7   6   5   4   3   2   1   0
>> +        p3  p1  p2  p0  y11 y10 y9  y8
>> +
>> +        p7..p0 = pressure
>> +
>> +byte 5:
>> +
>> +   bit   7   6   5   4   3   2   1   0
>> +        y7  y6  y5  y4  y3  y2  y1  y0
>> +
>> +        y11..y0 = absolute y value (vertical)
>> +
>> +6.2.2 Two finger touch
>> +      ~~~~~~~~~~~~~~~~
>> +
>> +The packet format is exactly the same for two finger touch, except the hardware
>> +sends two 6 byte packets. The first packet contains data for the first finger,
>> +the second packet has data for the second finger. So for two finger touch a
>> +total of 12 bytes are sent.
>> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
>> index ddd40eb..e13a719 100644
>> --- a/drivers/input/mouse/elantech.c
>> +++ b/drivers/input/mouse/elantech.c
>> @@ -108,6 +108,16 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
>>                         rc = -1;
>>                 }
>>                 break;
>> +
>> +       case 3:
>> +               if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>> +                   elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
>> +                   elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>> +                   elantech_ps2_command(psmouse, NULL, reg) ||
>> +                   elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
>> +                       rc = -1;
>> +               }
>> +               break;
>>         }
>>
>>         if (rc)
>> @@ -154,6 +164,18 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg,
>>                         rc = -1;
>>                 }
>>                 break;
>> +
>> +       case 3:
>> +               if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>> +                   elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
>> +                   elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>> +                   elantech_ps2_command(psmouse, NULL, reg) ||
>> +                   elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>> +                   elantech_ps2_command(psmouse, NULL, val) ||
>> +                   elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) {
>> +                       rc = -1;
>> +               }
>> +               break;
>>         }
>>
>>         if (rc)
>> @@ -352,6 +374,94 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
>>         input_sync(dev);
>>   }
>>
>> +/*
>> + * firmware tells us there's noise.
>> + */
>> +static inline int debounce(unsigned int x, unsigned int y)
>> +{
>> +       return (x == 0xfff)&&  (y == 0xfff);
>
> Perhaps you could document this behavior in the elantech.txt.
>
>> +}
>> +
>> +/*
>> + * Interpret complete data packets and report absolute mode input events for
>> + * hardware version 3. (12 byte packets for two fingers)
>> + */
>> +static void elantech_report_absolute_v3(struct psmouse *psmouse,
>> +                                       int packet_type)
>> +{
>> +       struct input_dev *dev = psmouse->dev;
>> +       struct elantech_data *etd = psmouse->private;
>> +       unsigned char *packet = psmouse->packet;
>> +       unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
>> +       unsigned int width = 0, pres = 0;
>> +
>> +       /* byte 0: n1  n0   .   .   .   .   R   L */
>> +       fingers = (packet[0]&  0xc0)>>  6;
>> +
>> +       switch (fingers) {
>> +       case 3:
>> +       case 1:
>> +               /*
>> +                * byte 1:  .   .   .   .  x11 x10 x9  x8
>> +                * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
>> +                */
>> +               x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
>> +               /*
>> +                * byte 4:  .   .   .   .  y11 y10 y9  y8
>> +                * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
>> +                */
>> +               y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
>> +
>> +               if (fingers == 3&&  debounce(x1, y1))
>> +                       return;
>> +
>> +               break;
>> +
>> +       case 2:
>> +               if (packet_type == PACKET_V3_HEAD) {
>> +                       /*
>> +                        * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
>> +                        * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
>> +                        */
>> +                       etd->prev_x = ((packet[1]&  0x0f)<<  8) | packet[2];
>> +                       /*
>> +                        * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
>> +                        * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
>> +                        */
>> +                       etd->prev_y = etd->y_max -
>> +                               (((packet[4]&  0x0f)<<  8) | packet[5]);
>> +                       /*
>> +                        * wait for next packet
>> +                        */
>> +                       return;
>> +               }
>> +
>> +               /* packet_type == PACKET_V3_TAIL */
>> +               x1 = etd->prev_x;
>> +               y1 = etd->prev_y;
>> +               x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
>> +               y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
>> +               break;
>> +       }
>> +
>> +       pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
>> +       width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
>> +
>> +       input_report_key(dev, BTN_TOUCH, fingers != 0);
>> +       input_report_abs(dev, ABS_X, x1);
>> +       input_report_abs(dev, ABS_Y, y1);
>> +       elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
>> +       input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
>> +       input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
>> +       input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
>> +       input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
>> +       input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
>> +       input_report_abs(dev, ABS_PRESSURE, pres);
>> +       input_report_abs(dev, ABS_TOOL_WIDTH, width);
>> +
>> +       input_sync(dev);
>> +}
>> +
>>   static int elantech_check_parity_v1(struct psmouse *psmouse)
>>   {
>>         struct elantech_data *etd = psmouse->private;
>> @@ -396,11 +506,31 @@ static int packet_simple_check_v2(struct psmouse *psmouse)
>>   }
>>
>>   /*
>> + * We check the constant bits to determine what packet type we get,
>> + * so packet checking is mandatory for v3 hardware.
>> + */
>> +static int determine_packet_v3(struct psmouse *psmouse)
>> +{
>> +       unsigned char *packet = psmouse->packet;
>> +
>> +       if ((packet[0]&  0x0c) == 0x04&&
>> +           (packet[3]&  0xcf) == 0x02)
>> +               return PACKET_V3_HEAD;
>> +
>> +       if ((packet[0]&  0x0c) == 0x0c&&
>> +           (packet[3]&  0xce) == 0x0c)
>> +               return PACKET_V3_TAIL;
>> +
>> +       return PACKET_UNKNOWN;
>> +}
>> +
>> +/*
>>   * Process byte stream from mouse and handle complete packets
>>   */
>>   static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>>   {
>>         struct elantech_data *etd = psmouse->private;
>> +       int packet_type;
>>
>>         if (psmouse->pktcnt<  psmouse->pktsize)
>>                 return PSMOUSE_GOOD_DATA;
>> @@ -422,6 +552,14 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>>
>>                 elantech_report_absolute_v2(psmouse);
>>                 break;
>> +
>> +       case 3:
>> +               packet_type = determine_packet_v3(psmouse);
>> +               if (packet_type == PACKET_UNKNOWN)
>> +                       goto bad_packet;
>> +
>> +               elantech_report_absolute_v3(psmouse, packet_type);
>> +               break;
>>         }
>>
>>         return PSMOUSE_FULL_PACKET;
>> @@ -459,10 +597,17 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
>>                 etd->reg_21 = 0x60;     /* 0x00 */
>>                 if (elantech_write_reg(psmouse, 0x10, etd->reg_10) ||
>>                     elantech_write_reg(psmouse, 0x11, etd->reg_11) ||
>> -                   elantech_write_reg(psmouse, 0x21, etd->reg_21)) {
>> +                   elantech_write_reg(psmouse, 0x21, etd->reg_21))
>>                         rc = -1;
>> -                       break;
>> -               }
>> +
>> +               break;
>> +
>> +       case 3:
>> +               etd->reg_10 = 0x0b;
>> +               if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
>> +                       rc = -1;
>> +
>> +               break;
>>         }
>>
>>         if (rc == 0) {
>> @@ -496,11 +641,12 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
>>         return rc;
>>   }
>>
>> -static void set_range(struct psmouse *psmouse, unsigned int *x_min,
>> +static int set_range(struct psmouse *psmouse, unsigned int *x_min,
>>                      unsigned int *y_min, unsigned int *x_max,
>>                      unsigned int *y_max, unsigned int *y_2ft_max)
>>   {
>>         struct elantech_data *etd = psmouse->private;
>> +       unsigned char param[3];
>>         int i;
>>
>>         switch (etd->hw_version) {
>> @@ -529,19 +675,30 @@ static void set_range(struct psmouse *psmouse, unsigned int *x_min,
>>                 *y_max = (etd->capabilities[2] - i) * 64;
>>                 *y_2ft_max = (*y_max - i) * 64 / 4;
>>                 break;
>> +
>> +       case 3:
>> +               if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
>> +                       return -1;
>> +
>> +               *x_max = (0x0f&  param[0])<<  8 | param[1];
>> +               *y_max = (0xf0&  param[0])<<  4 | param[2];
>> +               break;
>>         }
>> +
>> +       return 0;
>>   }
>>
>>   /*
>>   * Set the appropriate event bits for the input subsystem
>>   */
>> -static void elantech_set_input_params(struct psmouse *psmouse)
>> +static int elantech_set_input_params(struct psmouse *psmouse)
>>   {
>>         struct input_dev *dev = psmouse->dev;
>>         struct elantech_data *etd = psmouse->private;
>>         unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
>>
>> -       set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
>> +       if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
>> +               return -1;
>>
>>         __set_bit(EV_KEY, dev->evbit);
>>         __set_bit(EV_ABS, dev->evbit);
>> @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
>>                 input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
>>                 input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
>>                 break;
>> +
>> +       case 3:
>> +               input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
>> +               input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
>> +               /* range of pressure and width is the same as v2 */
>> +               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,
>> +                                    ETP_WMAX_V2, 0, 0);
>> +               __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
>> +               input_mt_init_slots(dev, 2);
>> +               input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
>> +               input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
>> +               break;
>>         }
>>
>>         etd->y_max = y_max;
>>         etd->y_2ft_max = y_2ft_max;
>> +
>> +       return 0;
>>   }
>>
>>   struct elantech_attr_data {
>> @@ -727,7 +900,8 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties)
>>          * Report this in case there are Elantech models that use a different
>>          * set of magic numbers
>>          */
>> -       if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
>> +       if (param[0] != 0x3c || param[1] != 0x03 ||
>> +           (param[2] != 0xc8&&  param[2] != 0x00)) {
>>                 pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
>>                          param[0], param[1], param[2]);
>>                 return -1;
>> @@ -793,16 +967,16 @@ static int elantech_reconnect(struct psmouse *psmouse)
>>   /*
>>   * determine hardware version and set some properties according to it.
>>   */
>> -static void elantech_set_properties(struct elantech_data *etd)
>> +static int elantech_set_properties(struct elantech_data *etd)
>>   {
>> -       /*
>> -        * Assume every version greater than 0x020030 is new EeePC style
>> -        * hardware with 6 byte packets, except 0x020600
>> -        */
>>         if (etd->fw_version<  0x020030 || etd->fw_version == 0x020600)
>>                 etd->hw_version = 1;
>> -       else
>> +       else if (etd->fw_version<  0x150600)
>>                 etd->hw_version = 2;
>> +       else if ((etd->fw_version&  0x0f0000)>>  16 == 5)
>> +               etd->hw_version = 3;
>> +       else
>> +               return -1;
>>
>>         /*
>>          * Turn on packet checking by default.
>> @@ -817,13 +991,15 @@ static void elantech_set_properties(struct elantech_data *etd)
>>         etd->jumpy_cursor =
>>                 (etd->fw_version == 0x020022 || etd->fw_version == 0x020600);
>>
>> -       if (etd->hw_version == 2) {
>> +       if (etd->hw_version>  1) {
>>                 /* For now show extra debug information */
>>                 etd->debug = 1;
>>
>>                 if (etd->fw_version>= 0x020800)
>>                         etd->reports_pressure = true;
>>         }
>> +
>> +       return 0;
>>   }
>>
>>   /*
>> @@ -850,9 +1026,12 @@ int elantech_init(struct psmouse *psmouse)
>>                 pr_err("failed to query firmware version.\n");
>>                 goto init_fail;
>>         }
>> -
>>         etd->fw_version = (param[0]<<  16) | (param[1]<<  8) | param[2];
>> -       elantech_set_properties(etd);
>> +
>> +       if (elantech_set_properties(etd)) {
>> +               pr_err("unknown hardware version, aborting...\n");
>> +               goto init_fail;
>> +       }
>>         pr_info("assuming hardware version %d "
>>                 "(with firmware version 0x%02x%02x%02x)\n",
>>                 etd->hw_version, param[0], param[1], param[2]);
>> @@ -871,7 +1050,10 @@ int elantech_init(struct psmouse *psmouse)
>>                 goto init_fail;
>>         }
>>
>> -       elantech_set_input_params(psmouse);
>> +       if (elantech_set_input_params(psmouse)) {
>> +               pr_err("failed to query touchpad range.\n");
>> +               goto init_fail;
>> +       }
>>
>>         error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
>>                                    &elantech_attr_group);
>> @@ -883,7 +1065,7 @@ int elantech_init(struct psmouse *psmouse)
>>         psmouse->protocol_handler = elantech_process_byte;
>>         psmouse->disconnect = elantech_disconnect;
>>         psmouse->reconnect = elantech_reconnect;
>> -       psmouse->pktsize = etd->hw_version == 2 ? 6 : 4;
>> +       psmouse->pktsize = etd->hw_version>  1 ? 6 : 4;
>>
>>         return 0;
>>
>> diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
>> index 4b7447e..4f01fc6 100644
>> --- a/drivers/input/mouse/elantech.h
>> +++ b/drivers/input/mouse/elantech.h
>> @@ -16,6 +16,7 @@
>>   /*
>>   * Command values for Synaptics style queries
>>   */
>> +#define ETP_FW_ID_QUERY                        0x00
>
> One tab too many?
No.
>
>>   #define ETP_FW_VERSION_QUERY           0x01
>>   #define ETP_CAPABILITIES_QUERY         0x02
>>
>> @@ -24,6 +25,7 @@
>>   */
>>   #define ETP_REGISTER_READ              0x10
>>   #define ETP_REGISTER_WRITE             0x11
>> +#define ETP_REGISTER_READWRITE         0x00
>>
>>   /*
>>   * Hardware version 2 custom PS/2 command value
>> @@ -93,6 +95,13 @@
>>   #define ETP_2FT_YMIN                   (  0 + ETP_2FT_FUZZ)
>>   #define ETP_2FT_YMAX                   (192 - ETP_2FT_FUZZ)
>>
>> +/*
>> + * v3 hardware has 2 kinds of packet types.
>> + */
>> +#define PACKET_UNKNOWN                 0x01
>> +#define PACKET_V3_HEAD                 0x02
>> +#define PACKET_V3_TAIL                 0x03
>> +
>>   struct elantech_data {
>>         unsigned char reg_10;
>>         unsigned char reg_11;
>> @@ -113,6 +122,8 @@ struct elantech_data {
>>         unsigned int single_finger_reports;
>>         unsigned int y_max;
>>         unsigned int y_2ft_max;
>> +       unsigned int prev_x;
>> +       unsigned int prev_y;
>>         unsigned char parity[256];
>>   };
>>
>> --
>> 1.7.4.1
>>
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
Thanks
Wanlong Gao

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 5/6] Input: elantech - clean up elantech_init
  2011-08-18  1:57 ` [PATCH 5/6] Input: elantech - clean up elantech_init JJ Ding
@ 2011-08-18  3:04   ` Daniel Kurtz
  2011-08-18  3:08     ` Wanlong Gao
  2011-08-18  6:34   ` Wanlong Gao
  2011-08-19 12:29     ` Éric Piel
  2 siblings, 1 reply; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  3:04 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding <jj_ding@emc.com.tw> wrote:
> Group property setting code into elantech_set_properties.
>
> Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
> ---
>  drivers/input/mouse/elantech.c |   69 ++++++++++++++++++++++-----------------
>  1 files changed, 39 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index 7b9b6e5..ddd40eb 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -791,6 +791,42 @@ static int elantech_reconnect(struct psmouse *psmouse)
>  }
>
>  /*
> + * determine hardware version and set some properties according to it.
> + */
> +static void elantech_set_properties(struct elantech_data *etd)
> +{
> +       /*
> +        * Assume every version greater than 0x020030 is new EeePC style
> +        * hardware with 6 byte packets, except 0x020600
> +        */
> +       if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600)
> +               etd->hw_version = 1;
> +       else
> +               etd->hw_version = 2;
> +
> +       /*
> +        * Turn on packet checking by default.
> +        */
> +       etd->paritycheck = 1;

Assuming paritycheck goes away:

Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/6] Input: elantech - work around EC buffer
  2011-08-18  1:57 ` [PATCH 4/6] Input: elantech - work around EC buffer JJ Ding
  2011-08-18  2:50   ` Daniel Kurtz
@ 2011-08-18  3:07   ` Wanlong Gao
  2011-08-18  6:48     ` JJ Ding
  2011-08-18  6:39   ` Dmitry Torokhov
  2 siblings, 1 reply; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  3:07 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 09:57 AM, JJ Ding wrote:
> With some EC chips, when we resync due to bad packets, those bad bytes would
> still remain in EC's buffer area. That makes us always get bad data back,
> no matter what.
>
> So shift packet for 1 byte when encounter bad packet, until we get rid of those
> bytes.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
> ---
>   drivers/input/mouse/elantech.c |    9 +++++++--
>   1 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index 032181c..7b9b6e5 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -411,20 +411,25 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>   	switch (etd->hw_version) {
>   	case 1:
>   		if (etd->paritycheck&&  !elantech_check_parity_v1(psmouse))
> -			return PSMOUSE_BAD_DATA;
> +			goto bad_packet;
>
>   		elantech_report_absolute_v1(psmouse);
>   		break;
>
>   	case 2:
>   		if (etd->paritycheck&&  !packet_simple_check_v2(psmouse))
> -			return PSMOUSE_BAD_DATA;
> +			goto bad_packet;
>
>   		elantech_report_absolute_v2(psmouse);
>   		break;
>   	}
>
>   	return PSMOUSE_FULL_PACKET;
> +
> + bad_packet:
You may introduce space here.
> +	memmove(psmouse->packet, psmouse->packet + 1, psmouse->pktsize - 1);
> +	psmouse->pktcnt--;
> +	return PSMOUSE_GOOD_DATA;
>   }
>
>   /*


-- 
Thanks
Wanlong Gao

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 5/6] Input: elantech - clean up elantech_init
  2011-08-18  3:04   ` Daniel Kurtz
@ 2011-08-18  3:08     ` Wanlong Gao
  2011-08-18  5:35       ` JJ Ding
  0 siblings, 1 reply; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  3:08 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 11:04 AM, Daniel Kurtz wrote:
> On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding<jj_ding@emc.com.tw>  wrote:
>> Group property setting code into elantech_set_properties.
>>
>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>> ---
>>   drivers/input/mouse/elantech.c |   69 ++++++++++++++++++++++-----------------
>>   1 files changed, 39 insertions(+), 30 deletions(-)
>>
>> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
>> index 7b9b6e5..ddd40eb 100644
>> --- a/drivers/input/mouse/elantech.c
>> +++ b/drivers/input/mouse/elantech.c
>> @@ -791,6 +791,42 @@ static int elantech_reconnect(struct psmouse *psmouse)
>>   }
>>
>>   /*
>> + * determine hardware version and set some properties according to it.
>> + */
>> +static void elantech_set_properties(struct elantech_data *etd)
>> +{
>> +       /*
>> +        * Assume every version greater than 0x020030 is new EeePC style
>> +        * hardware with 6 byte packets, except 0x020600
>> +        */
>> +       if (etd->fw_version<  0x020030 || etd->fw_version == 0x020600)
>> +               etd->hw_version = 1;
>> +       else
>> +               etd->hw_version = 2;
>> +
>> +       /*
>> +        * Turn on packet checking by default.
>> +        */
>> +       etd->paritycheck = 1;
>
> Assuming paritycheck goes away:
Agree.
>
> Reviewed-by: Daniel Kurtz<djkurtz@chromium.org>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
Thanks
Wanlong Gao

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  3:04     ` Wanlong Gao
@ 2011-08-18  3:09         ` Daniel Kurtz
  0 siblings, 0 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  3:09 UTC (permalink / raw)
  To: gaowanlong
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On Thu, Aug 18, 2011 at 11:04 AM, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> On 08/18/2011 10:57 AM, Daniel Kurtz wrote:
>>
>> On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding<jj_ding@emc.com.tw>  wrote:
>>>
>>> v3 hardware's packet format is almost identical to v2 (one/three finger
>>> touch),
>>> except when sensing two finger touch, the hardware sends 12 bytes of
>>> data.
>>>
>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>>> ---
>>>  Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>>  drivers/input/mouse/elantech.c   |  218
>>> ++++++++++++++++++++++++++++++++++---
>>>  drivers/input/mouse/elantech.h   |   11 ++
>>>  3 files changed, 303 insertions(+), 30 deletions(-)
>>>
>>> diff --git a/Documentation/input/elantech.txt
>>> b/Documentation/input/elantech.txt
>>> index bce9941..ce578bd 100644
>>> --- a/Documentation/input/elantech.txt
>>> +++ b/Documentation/input/elantech.txt
>>> @@ -16,15 +16,22 @@ Contents
>>>
>>>  1. Introduction
>>>  2. Extra knobs
>>> - 3. Hardware version 1
>>> -    3.1 Registers
>>> -    3.2 Native relative mode 4 byte packet format
>>> -    3.3 Native absolute mode 4 byte packet format
>>> - 4. Hardware version 2
>>> + 3. Differentiating hardware versions
>>> + 4. Hardware version 1
>>>     4.1 Registers
>>> -    4.2 Native absolute mode 6 byte packet format
>>> -        4.2.1 One finger touch
>>> -        4.2.2 Two finger touch
>>> +    4.2 Native relative mode 4 byte packet format
>>> +    4.3 Native absolute mode 4 byte packet format
>>> + 5. Hardware version 2
>>> +    5.1 Registers
>>> +    5.2 Native absolute mode 6 byte packet format
>>> +        5.2.1 Parity checking and packet re-synchronization
>>> +        5.2.2 One/Three finger touch
>>> +        5.2.3 Two finger touch
>>> + 6. Hardware version 3
>>> +    6.1 Registers
>>> +    6.2 Native absolute mode 6 byte packet format
>>> +        6.2.1 One/Three finger touch
>>> +        6.2.2 Two finger touch
>>>
>>>
>>>
>>> @@ -375,7 +382,7 @@ For all the other ones, there are just a few constant
>>> bits:
>>>
>>>  In case an error is detected, all the packets are shifted by one (and
>>> packet[0] is discarded).
>>>
>>> -5.2.1 One/Three finger touch
>>> +5.2.2 One/Three finger touch
>>>       ~~~~~~~~~~~~~~~~
>>>
>>>  byte 0:
>>> @@ -384,7 +391,7 @@ byte 0:
>>>         n1  n0  w3  w2   .   .   R   L
>>>
>>>          L, R = 1 when Left, Right mouse button pressed
>>> -         n1..n0 = numbers of fingers on touchpad
>>> +         n1..n0 = number of fingers on touchpad
>>>
>>>  byte 1:
>>>
>>> @@ -432,7 +439,7 @@ byte 5:
>>>          y11..y0 = absolute y value (vertical)
>>>
>>>
>>> -4.2.2 Two finger touch
>>> +5.2.3 Two finger touch
>>>       ~~~~~~~~~~~~~~~~
>>>
>>>  Note that the two pairs of coordinates are not exactly the coordinates
>>> of the
>>> @@ -446,7 +453,7 @@ byte 0:
>>>         n1  n0  ay8 ax8  .   .   R   L
>>>
>>>          L, R = 1 when Left, Right mouse button pressed
>>> -         n1..n0 = numbers of fingers on touchpad
>>> +         n1..n0 = number of fingers on touchpad
>>>
>>>  byte 1:
>>>
>>> @@ -480,3 +487,76 @@ byte 5:
>>>         by7 by8 by5 by4 by3 by2 by1 by0
>>>
>>>          by8..by0 = upper-right finger absolute y value
>>> +
>>>
>>> +/////////////////////////////////////////////////////////////////////////////
>>> +
>>> +6. Hardware version 3
>>> +   ==================
>>> +
>>> +6.1 Registers
>>> +    ~~~~~~~~~
>>> +* reg_10
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +         0   0   0   0   0   0   0   A
>>> +
>>> +         A: 1 = enable absolute tracking
>>> +
>>> +6.2 Native absolute mode 6 byte packet format
>>> +    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> +1 and 3 finger touch shares the same 6-byte packet format, except that
>>> +3 finger touch only reports the position of the center of all three
>>> fingers.
>>> +
>>> +Firmware would send 12 bytes of data for 2 finger touch.
>>> +
>>> +6.2.1 One/Three finger touch
>>> +      ~~~~~~~~~~~~~~~~~~~~~~
>>> +
>>> +byte 0:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        n1  n0  w3  w2   0   1   R   L
>>> +
>>> +        L, R = 1 when Left, Right mouse button pressed
>>> +        n1..n0 = number of fingers on touchpad
>>> +
>>> +byte 1:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        p7  p6  p5  p4 x11 x10  x9  x8
>>> +
>>> +byte 2:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        x7  x6  x5  x4  x3  x2  x1  x0
>>> +
>>> +        x11..x0 = absolute x value (horizontal)
>>> +
>>> +byte 3:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +         0   0  w1  w0   0   0   1   0
>>> +
>>> +         w3..w0 = width of the finger touch
>>> +
>>> +byte 4:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        p3  p1  p2  p0  y11 y10 y9  y8
>>> +
>>> +        p7..p0 = pressure
>>> +
>>> +byte 5:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        y7  y6  y5  y4  y3  y2  y1  y0
>>> +
>>> +        y11..y0 = absolute y value (vertical)
>>> +
>>> +6.2.2 Two finger touch
>>> +      ~~~~~~~~~~~~~~~~
>>> +
>>> +The packet format is exactly the same for two finger touch, except the
>>> hardware
>>> +sends two 6 byte packets. The first packet contains data for the first
>>> finger,
>>> +the second packet has data for the second finger. So for two finger
>>> touch a
>>> +total of 12 bytes are sent.
>>> diff --git a/drivers/input/mouse/elantech.c
>>> b/drivers/input/mouse/elantech.c
>>> index ddd40eb..e13a719 100644
>>> --- a/drivers/input/mouse/elantech.c
>>> +++ b/drivers/input/mouse/elantech.c
>>> @@ -108,6 +108,16 @@ static int elantech_read_reg(struct psmouse
>>> *psmouse, unsigned char reg,
>>>                        rc = -1;
>>>                }
>>>                break;
>>> +
>>> +       case 3:
>>> +               if (elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_REGISTER_READWRITE) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL, reg) ||
>>> +                   elantech_ps2_command(psmouse, param,
>>> PSMOUSE_CMD_GETINFO)) {
>>> +                       rc = -1;
>>> +               }
>>> +               break;
>>>        }
>>>
>>>        if (rc)
>>> @@ -154,6 +164,18 @@ static int elantech_write_reg(struct psmouse
>>> *psmouse, unsigned char reg,
>>>                        rc = -1;
>>>                }
>>>                break;
>>> +
>>> +       case 3:
>>> +               if (elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_REGISTER_READWRITE) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL, reg) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL, val) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> PSMOUSE_CMD_SETSCALE11)) {
>>> +                       rc = -1;
>>> +               }
>>> +               break;
>>>        }
>>>
>>>        if (rc)
>>> @@ -352,6 +374,94 @@ static void elantech_report_absolute_v2(struct
>>> psmouse *psmouse)
>>>        input_sync(dev);
>>>  }
>>>
>>> +/*
>>> + * firmware tells us there's noise.
>>> + */
>>> +static inline int debounce(unsigned int x, unsigned int y)
>>> +{
>>> +       return (x == 0xfff)&&  (y == 0xfff);
>>
>> Perhaps you could document this behavior in the elantech.txt.
>>
>>> +}
>>> +
>>> +/*
>>> + * Interpret complete data packets and report absolute mode input events
>>> for
>>> + * hardware version 3. (12 byte packets for two fingers)
>>> + */
>>> +static void elantech_report_absolute_v3(struct psmouse *psmouse,
>>> +                                       int packet_type)
>>> +{
>>> +       struct input_dev *dev = psmouse->dev;
>>> +       struct elantech_data *etd = psmouse->private;
>>> +       unsigned char *packet = psmouse->packet;
>>> +       unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
>>> +       unsigned int width = 0, pres = 0;
>>> +
>>> +       /* byte 0: n1  n0   .   .   .   .   R   L */
>>> +       fingers = (packet[0]&  0xc0)>>  6;
>>> +
>>> +       switch (fingers) {
>>> +       case 3:
>>> +       case 1:
>>> +               /*
>>> +                * byte 1:  .   .   .   .  x11 x10 x9  x8
>>> +                * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
>>> +                */
>>> +               x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
>>> +               /*
>>> +                * byte 4:  .   .   .   .  y11 y10 y9  y8
>>> +                * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
>>> +                */
>>> +               y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) |
>>> packet[5]);
>>> +
>>> +               if (fingers == 3&&  debounce(x1, y1))
>>> +                       return;
>>> +
>>> +               break;
>>> +
>>> +       case 2:
>>> +               if (packet_type == PACKET_V3_HEAD) {
>>> +                       /*
>>> +                        * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
>>> +                        * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
>>> +                        */
>>> +                       etd->prev_x = ((packet[1]&  0x0f)<<  8) |
>>> packet[2];
>>> +                       /*
>>> +                        * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
>>> +                        * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
>>> +                        */
>>> +                       etd->prev_y = etd->y_max -
>>> +                               (((packet[4]&  0x0f)<<  8) | packet[5]);
>>> +                       /*
>>> +                        * wait for next packet
>>> +                        */
>>> +                       return;
>>> +               }
>>> +
>>> +               /* packet_type == PACKET_V3_TAIL */
>>> +               x1 = etd->prev_x;
>>> +               y1 = etd->prev_y;
>>> +               x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
>>> +               y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) |
>>> packet[5]);
>>> +               break;
>>> +       }
>>> +
>>> +       pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
>>> +       width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
>>> +
>>> +       input_report_key(dev, BTN_TOUCH, fingers != 0);
>>> +       input_report_abs(dev, ABS_X, x1);
>>> +       input_report_abs(dev, ABS_Y, y1);
>>> +       elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
>>> +       input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
>>> +       input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
>>> +       input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
>>> +       input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
>>> +       input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
>>> +       input_report_abs(dev, ABS_PRESSURE, pres);
>>> +       input_report_abs(dev, ABS_TOOL_WIDTH, width);
>>> +
>>> +       input_sync(dev);
>>> +}
>>> +
>>>  static int elantech_check_parity_v1(struct psmouse *psmouse)
>>>  {
>>>        struct elantech_data *etd = psmouse->private;
>>> @@ -396,11 +506,31 @@ static int packet_simple_check_v2(struct psmouse
>>> *psmouse)
>>>  }
>>>
>>>  /*
>>> + * We check the constant bits to determine what packet type we get,
>>> + * so packet checking is mandatory for v3 hardware.
>>> + */
>>> +static int determine_packet_v3(struct psmouse *psmouse)
>>> +{
>>> +       unsigned char *packet = psmouse->packet;
>>> +
>>> +       if ((packet[0]&  0x0c) == 0x04&&
>>> +           (packet[3]&  0xcf) == 0x02)
>>> +               return PACKET_V3_HEAD;
>>> +
>>> +       if ((packet[0]&  0x0c) == 0x0c&&
>>> +           (packet[3]&  0xce) == 0x0c)
>>> +               return PACKET_V3_TAIL;
>>> +
>>> +       return PACKET_UNKNOWN;
>>> +}
>>> +
>>> +/*
>>>  * Process byte stream from mouse and handle complete packets
>>>  */
>>>  static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>>>  {
>>>        struct elantech_data *etd = psmouse->private;
>>> +       int packet_type;
>>>
>>>        if (psmouse->pktcnt<  psmouse->pktsize)
>>>                return PSMOUSE_GOOD_DATA;
>>> @@ -422,6 +552,14 @@ static psmouse_ret_t elantech_process_byte(struct
>>> psmouse *psmouse)
>>>
>>>                elantech_report_absolute_v2(psmouse);
>>>                break;
>>> +
>>> +       case 3:
>>> +               packet_type = determine_packet_v3(psmouse);
>>> +               if (packet_type == PACKET_UNKNOWN)
>>> +                       goto bad_packet;
>>> +
>>> +               elantech_report_absolute_v3(psmouse, packet_type);
>>> +               break;
>>>        }
>>>
>>>        return PSMOUSE_FULL_PACKET;
>>> @@ -459,10 +597,17 @@ static int elantech_set_absolute_mode(struct
>>> psmouse *psmouse)
>>>                etd->reg_21 = 0x60;     /* 0x00 */
>>>                if (elantech_write_reg(psmouse, 0x10, etd->reg_10) ||
>>>                    elantech_write_reg(psmouse, 0x11, etd->reg_11) ||
>>> -                   elantech_write_reg(psmouse, 0x21, etd->reg_21)) {
>>> +                   elantech_write_reg(psmouse, 0x21, etd->reg_21))
>>>                        rc = -1;
>>> -                       break;
>>> -               }
>>> +
>>> +               break;
>>> +
>>> +       case 3:
>>> +               etd->reg_10 = 0x0b;
>>> +               if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
>>> +                       rc = -1;
>>> +
>>> +               break;
>>>        }
>>>
>>>        if (rc == 0) {
>>> @@ -496,11 +641,12 @@ static int elantech_set_absolute_mode(struct
>>> psmouse *psmouse)
>>>        return rc;
>>>  }
>>>
>>> -static void set_range(struct psmouse *psmouse, unsigned int *x_min,
>>> +static int set_range(struct psmouse *psmouse, unsigned int *x_min,
>>>                     unsigned int *y_min, unsigned int *x_max,
>>>                     unsigned int *y_max, unsigned int *y_2ft_max)
>>>  {
>>>        struct elantech_data *etd = psmouse->private;
>>> +       unsigned char param[3];
>>>        int i;
>>>
>>>        switch (etd->hw_version) {
>>> @@ -529,19 +675,30 @@ static void set_range(struct psmouse *psmouse,
>>> unsigned int *x_min,
>>>                *y_max = (etd->capabilities[2] - i) * 64;
>>>                *y_2ft_max = (*y_max - i) * 64 / 4;
>>>                break;
>>> +
>>> +       case 3:
>>> +               if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
>>> +                       return -1;
>>> +
>>> +               *x_max = (0x0f&  param[0])<<  8 | param[1];
>>> +               *y_max = (0xf0&  param[0])<<  4 | param[2];
>>> +               break;
>>>        }
>>> +
>>> +       return 0;
>>>  }
>>>
>>>  /*
>>>  * Set the appropriate event bits for the input subsystem
>>>  */
>>> -static void elantech_set_input_params(struct psmouse *psmouse)
>>> +static int elantech_set_input_params(struct psmouse *psmouse)
>>>  {
>>>        struct input_dev *dev = psmouse->dev;
>>>        struct elantech_data *etd = psmouse->private;
>>>        unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max
>>> = 0;
>>>
>>> -       set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
>>> +       if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
>>> +               return -1;
>>>
>>>        __set_bit(EV_KEY, dev->evbit);
>>>        __set_bit(EV_ABS, dev->evbit);
>>> @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct
>>> psmouse *psmouse)
>>>                input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max,
>>> 0, 0);
>>>                input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max,
>>> 0, 0);
>>>                break;
>>> +
>>> +       case 3:
>>> +               input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
>>> +               input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
>>> +               /* range of pressure and width is the same as v2 */
>>> +               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,
>>> +                                    ETP_WMAX_V2, 0, 0);
>>> +               __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
>>> +               input_mt_init_slots(dev, 2);
>>> +               input_set_abs_params(dev, ABS_MT_POSITION_X, x_min,
>>> x_max, 0, 0);
>>> +               input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min,
>>> y_max, 0, 0);
>>> +               break;
>>>        }
>>>
>>>        etd->y_max = y_max;
>>>        etd->y_2ft_max = y_2ft_max;
>>> +
>>> +       return 0;
>>>  }
>>>
>>>  struct elantech_attr_data {
>>> @@ -727,7 +900,8 @@ int elantech_detect(struct psmouse *psmouse, bool
>>> set_properties)
>>>         * Report this in case there are Elantech models that use a
>>> different
>>>         * set of magic numbers
>>>         */
>>> -       if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
>>> +       if (param[0] != 0x3c || param[1] != 0x03 ||
>>> +           (param[2] != 0xc8&&  param[2] != 0x00)) {
>>>                pr_debug("unexpected magic knock result 0x%02x, 0x%02x,
>>> 0x%02x.\n",
>>>                         param[0], param[1], param[2]);
>>>                return -1;
>>> @@ -793,16 +967,16 @@ static int elantech_reconnect(struct psmouse
>>> *psmouse)
>>>  /*
>>>  * determine hardware version and set some properties according to it.
>>>  */
>>> -static void elantech_set_properties(struct elantech_data *etd)
>>> +static int elantech_set_properties(struct elantech_data *etd)
>>>  {
>>> -       /*
>>> -        * Assume every version greater than 0x020030 is new EeePC style
>>> -        * hardware with 6 byte packets, except 0x020600
>>> -        */
>>>        if (etd->fw_version<  0x020030 || etd->fw_version == 0x020600)
>>>                etd->hw_version = 1;
>>> -       else
>>> +       else if (etd->fw_version<  0x150600)
>>>                etd->hw_version = 2;
>>> +       else if ((etd->fw_version&  0x0f0000)>>  16 == 5)
>>> +               etd->hw_version = 3;
>>> +       else
>>> +               return -1;
>>>
>>>        /*
>>>         * Turn on packet checking by default.
>>> @@ -817,13 +991,15 @@ static void elantech_set_properties(struct
>>> elantech_data *etd)
>>>        etd->jumpy_cursor =
>>>                (etd->fw_version == 0x020022 || etd->fw_version ==
>>> 0x020600);
>>>
>>> -       if (etd->hw_version == 2) {
>>> +       if (etd->hw_version>  1) {
>>>                /* For now show extra debug information */
>>>                etd->debug = 1;
>>>
>>>                if (etd->fw_version>= 0x020800)
>>>                        etd->reports_pressure = true;
>>>        }
>>> +
>>> +       return 0;
>>>  }
>>>
>>>  /*
>>> @@ -850,9 +1026,12 @@ int elantech_init(struct psmouse *psmouse)
>>>                pr_err("failed to query firmware version.\n");
>>>                goto init_fail;
>>>        }
>>> -
>>>        etd->fw_version = (param[0]<<  16) | (param[1]<<  8) | param[2];
>>> -       elantech_set_properties(etd);
>>> +
>>> +       if (elantech_set_properties(etd)) {
>>> +               pr_err("unknown hardware version, aborting...\n");
>>> +               goto init_fail;
>>> +       }
>>>        pr_info("assuming hardware version %d "
>>>                "(with firmware version 0x%02x%02x%02x)\n",
>>>                etd->hw_version, param[0], param[1], param[2]);
>>> @@ -871,7 +1050,10 @@ int elantech_init(struct psmouse *psmouse)
>>>                goto init_fail;
>>>        }
>>>
>>> -       elantech_set_input_params(psmouse);
>>> +       if (elantech_set_input_params(psmouse)) {
>>> +               pr_err("failed to query touchpad range.\n");
>>> +               goto init_fail;
>>> +       }
>>>
>>>        error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
>>>                                   &elantech_attr_group);
>>> @@ -883,7 +1065,7 @@ int elantech_init(struct psmouse *psmouse)
>>>        psmouse->protocol_handler = elantech_process_byte;
>>>        psmouse->disconnect = elantech_disconnect;
>>>        psmouse->reconnect = elantech_reconnect;
>>> -       psmouse->pktsize = etd->hw_version == 2 ? 6 : 4;
>>> +       psmouse->pktsize = etd->hw_version>  1 ? 6 : 4;
>>>
>>>        return 0;
>>>
>>> diff --git a/drivers/input/mouse/elantech.h
>>> b/drivers/input/mouse/elantech.h
>>> index 4b7447e..4f01fc6 100644
>>> --- a/drivers/input/mouse/elantech.h
>>> +++ b/drivers/input/mouse/elantech.h
>>> @@ -16,6 +16,7 @@
>>>  /*
>>>  * Command values for Synaptics style queries
>>>  */
>>> +#define ETP_FW_ID_QUERY                        0x00
>>
>> One tab too many?
>
> No.

Yeah, weird patchwork diff'ing artifact....


>>
>>>  #define ETP_FW_VERSION_QUERY           0x01
>>>  #define ETP_CAPABILITIES_QUERY         0x02
>>>
>>> @@ -24,6 +25,7 @@
>>>  */
>>>  #define ETP_REGISTER_READ              0x10
>>>  #define ETP_REGISTER_WRITE             0x11
>>> +#define ETP_REGISTER_READWRITE         0x00
>>>
>>>  /*
>>>  * Hardware version 2 custom PS/2 command value
>>> @@ -93,6 +95,13 @@
>>>  #define ETP_2FT_YMIN                   (  0 + ETP_2FT_FUZZ)
>>>  #define ETP_2FT_YMAX                   (192 - ETP_2FT_FUZZ)
>>>
>>> +/*
>>> + * v3 hardware has 2 kinds of packet types.
>>> + */
>>> +#define PACKET_UNKNOWN                 0x01
>>> +#define PACKET_V3_HEAD                 0x02
>>> +#define PACKET_V3_TAIL                 0x03
>>> +
>>>  struct elantech_data {
>>>        unsigned char reg_10;
>>>        unsigned char reg_11;
>>> @@ -113,6 +122,8 @@ struct elantech_data {
>>>        unsigned int single_finger_reports;
>>>        unsigned int y_max;
>>>        unsigned int y_2ft_max;
>>> +       unsigned int prev_x;
>>> +       unsigned int prev_y;
>>>        unsigned char parity[256];
>>>  };
>>>
>>> --
>>> 1.7.4.1
>>>
>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-input" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
>
> --
> Thanks
> Wanlong Gao
>

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-18  3:09         ` Daniel Kurtz
  0 siblings, 0 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  3:09 UTC (permalink / raw)
  To: gaowanlong
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On Thu, Aug 18, 2011 at 11:04 AM, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> On 08/18/2011 10:57 AM, Daniel Kurtz wrote:
>>
>> On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding<jj_ding@emc.com.tw>  wrote:
>>>
>>> v3 hardware's packet format is almost identical to v2 (one/three finger
>>> touch),
>>> except when sensing two finger touch, the hardware sends 12 bytes of
>>> data.
>>>
>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>>> ---
>>>  Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>>  drivers/input/mouse/elantech.c   |  218
>>> ++++++++++++++++++++++++++++++++++---
>>>  drivers/input/mouse/elantech.h   |   11 ++
>>>  3 files changed, 303 insertions(+), 30 deletions(-)
>>>
>>> diff --git a/Documentation/input/elantech.txt
>>> b/Documentation/input/elantech.txt
>>> index bce9941..ce578bd 100644
>>> --- a/Documentation/input/elantech.txt
>>> +++ b/Documentation/input/elantech.txt
>>> @@ -16,15 +16,22 @@ Contents
>>>
>>>  1. Introduction
>>>  2. Extra knobs
>>> - 3. Hardware version 1
>>> -    3.1 Registers
>>> -    3.2 Native relative mode 4 byte packet format
>>> -    3.3 Native absolute mode 4 byte packet format
>>> - 4. Hardware version 2
>>> + 3. Differentiating hardware versions
>>> + 4. Hardware version 1
>>>     4.1 Registers
>>> -    4.2 Native absolute mode 6 byte packet format
>>> -        4.2.1 One finger touch
>>> -        4.2.2 Two finger touch
>>> +    4.2 Native relative mode 4 byte packet format
>>> +    4.3 Native absolute mode 4 byte packet format
>>> + 5. Hardware version 2
>>> +    5.1 Registers
>>> +    5.2 Native absolute mode 6 byte packet format
>>> +        5.2.1 Parity checking and packet re-synchronization
>>> +        5.2.2 One/Three finger touch
>>> +        5.2.3 Two finger touch
>>> + 6. Hardware version 3
>>> +    6.1 Registers
>>> +    6.2 Native absolute mode 6 byte packet format
>>> +        6.2.1 One/Three finger touch
>>> +        6.2.2 Two finger touch
>>>
>>>
>>>
>>> @@ -375,7 +382,7 @@ For all the other ones, there are just a few constant
>>> bits:
>>>
>>>  In case an error is detected, all the packets are shifted by one (and
>>> packet[0] is discarded).
>>>
>>> -5.2.1 One/Three finger touch
>>> +5.2.2 One/Three finger touch
>>>       ~~~~~~~~~~~~~~~~
>>>
>>>  byte 0:
>>> @@ -384,7 +391,7 @@ byte 0:
>>>         n1  n0  w3  w2   .   .   R   L
>>>
>>>          L, R = 1 when Left, Right mouse button pressed
>>> -         n1..n0 = numbers of fingers on touchpad
>>> +         n1..n0 = number of fingers on touchpad
>>>
>>>  byte 1:
>>>
>>> @@ -432,7 +439,7 @@ byte 5:
>>>          y11..y0 = absolute y value (vertical)
>>>
>>>
>>> -4.2.2 Two finger touch
>>> +5.2.3 Two finger touch
>>>       ~~~~~~~~~~~~~~~~
>>>
>>>  Note that the two pairs of coordinates are not exactly the coordinates
>>> of the
>>> @@ -446,7 +453,7 @@ byte 0:
>>>         n1  n0  ay8 ax8  .   .   R   L
>>>
>>>          L, R = 1 when Left, Right mouse button pressed
>>> -         n1..n0 = numbers of fingers on touchpad
>>> +         n1..n0 = number of fingers on touchpad
>>>
>>>  byte 1:
>>>
>>> @@ -480,3 +487,76 @@ byte 5:
>>>         by7 by8 by5 by4 by3 by2 by1 by0
>>>
>>>          by8..by0 = upper-right finger absolute y value
>>> +
>>>
>>> +/////////////////////////////////////////////////////////////////////////////
>>> +
>>> +6. Hardware version 3
>>> +   ==================
>>> +
>>> +6.1 Registers
>>> +    ~~~~~~~~~
>>> +* reg_10
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +         0   0   0   0   0   0   0   A
>>> +
>>> +         A: 1 = enable absolute tracking
>>> +
>>> +6.2 Native absolute mode 6 byte packet format
>>> +    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> +1 and 3 finger touch shares the same 6-byte packet format, except that
>>> +3 finger touch only reports the position of the center of all three
>>> fingers.
>>> +
>>> +Firmware would send 12 bytes of data for 2 finger touch.
>>> +
>>> +6.2.1 One/Three finger touch
>>> +      ~~~~~~~~~~~~~~~~~~~~~~
>>> +
>>> +byte 0:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        n1  n0  w3  w2   0   1   R   L
>>> +
>>> +        L, R = 1 when Left, Right mouse button pressed
>>> +        n1..n0 = number of fingers on touchpad
>>> +
>>> +byte 1:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        p7  p6  p5  p4 x11 x10  x9  x8
>>> +
>>> +byte 2:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        x7  x6  x5  x4  x3  x2  x1  x0
>>> +
>>> +        x11..x0 = absolute x value (horizontal)
>>> +
>>> +byte 3:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +         0   0  w1  w0   0   0   1   0
>>> +
>>> +         w3..w0 = width of the finger touch
>>> +
>>> +byte 4:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        p3  p1  p2  p0  y11 y10 y9  y8
>>> +
>>> +        p7..p0 = pressure
>>> +
>>> +byte 5:
>>> +
>>> +   bit   7   6   5   4   3   2   1   0
>>> +        y7  y6  y5  y4  y3  y2  y1  y0
>>> +
>>> +        y11..y0 = absolute y value (vertical)
>>> +
>>> +6.2.2 Two finger touch
>>> +      ~~~~~~~~~~~~~~~~
>>> +
>>> +The packet format is exactly the same for two finger touch, except the
>>> hardware
>>> +sends two 6 byte packets. The first packet contains data for the first
>>> finger,
>>> +the second packet has data for the second finger. So for two finger
>>> touch a
>>> +total of 12 bytes are sent.
>>> diff --git a/drivers/input/mouse/elantech.c
>>> b/drivers/input/mouse/elantech.c
>>> index ddd40eb..e13a719 100644
>>> --- a/drivers/input/mouse/elantech.c
>>> +++ b/drivers/input/mouse/elantech.c
>>> @@ -108,6 +108,16 @@ static int elantech_read_reg(struct psmouse
>>> *psmouse, unsigned char reg,
>>>                        rc = -1;
>>>                }
>>>                break;
>>> +
>>> +       case 3:
>>> +               if (elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_REGISTER_READWRITE) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL, reg) ||
>>> +                   elantech_ps2_command(psmouse, param,
>>> PSMOUSE_CMD_GETINFO)) {
>>> +                       rc = -1;
>>> +               }
>>> +               break;
>>>        }
>>>
>>>        if (rc)
>>> @@ -154,6 +164,18 @@ static int elantech_write_reg(struct psmouse
>>> *psmouse, unsigned char reg,
>>>                        rc = -1;
>>>                }
>>>                break;
>>> +
>>> +       case 3:
>>> +               if (elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_REGISTER_READWRITE) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL, reg) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> ETP_PS2_CUSTOM_COMMAND) ||
>>> +                   elantech_ps2_command(psmouse, NULL, val) ||
>>> +                   elantech_ps2_command(psmouse, NULL,
>>> PSMOUSE_CMD_SETSCALE11)) {
>>> +                       rc = -1;
>>> +               }
>>> +               break;
>>>        }
>>>
>>>        if (rc)
>>> @@ -352,6 +374,94 @@ static void elantech_report_absolute_v2(struct
>>> psmouse *psmouse)
>>>        input_sync(dev);
>>>  }
>>>
>>> +/*
>>> + * firmware tells us there's noise.
>>> + */
>>> +static inline int debounce(unsigned int x, unsigned int y)
>>> +{
>>> +       return (x == 0xfff)&&  (y == 0xfff);
>>
>> Perhaps you could document this behavior in the elantech.txt.
>>
>>> +}
>>> +
>>> +/*
>>> + * Interpret complete data packets and report absolute mode input events
>>> for
>>> + * hardware version 3. (12 byte packets for two fingers)
>>> + */
>>> +static void elantech_report_absolute_v3(struct psmouse *psmouse,
>>> +                                       int packet_type)
>>> +{
>>> +       struct input_dev *dev = psmouse->dev;
>>> +       struct elantech_data *etd = psmouse->private;
>>> +       unsigned char *packet = psmouse->packet;
>>> +       unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
>>> +       unsigned int width = 0, pres = 0;
>>> +
>>> +       /* byte 0: n1  n0   .   .   .   .   R   L */
>>> +       fingers = (packet[0]&  0xc0)>>  6;
>>> +
>>> +       switch (fingers) {
>>> +       case 3:
>>> +       case 1:
>>> +               /*
>>> +                * byte 1:  .   .   .   .  x11 x10 x9  x8
>>> +                * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
>>> +                */
>>> +               x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
>>> +               /*
>>> +                * byte 4:  .   .   .   .  y11 y10 y9  y8
>>> +                * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
>>> +                */
>>> +               y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) |
>>> packet[5]);
>>> +
>>> +               if (fingers == 3&&  debounce(x1, y1))
>>> +                       return;
>>> +
>>> +               break;
>>> +
>>> +       case 2:
>>> +               if (packet_type == PACKET_V3_HEAD) {
>>> +                       /*
>>> +                        * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
>>> +                        * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
>>> +                        */
>>> +                       etd->prev_x = ((packet[1]&  0x0f)<<  8) |
>>> packet[2];
>>> +                       /*
>>> +                        * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
>>> +                        * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
>>> +                        */
>>> +                       etd->prev_y = etd->y_max -
>>> +                               (((packet[4]&  0x0f)<<  8) | packet[5]);
>>> +                       /*
>>> +                        * wait for next packet
>>> +                        */
>>> +                       return;
>>> +               }
>>> +
>>> +               /* packet_type == PACKET_V3_TAIL */
>>> +               x1 = etd->prev_x;
>>> +               y1 = etd->prev_y;
>>> +               x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
>>> +               y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) |
>>> packet[5]);
>>> +               break;
>>> +       }
>>> +
>>> +       pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
>>> +       width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
>>> +
>>> +       input_report_key(dev, BTN_TOUCH, fingers != 0);
>>> +       input_report_abs(dev, ABS_X, x1);
>>> +       input_report_abs(dev, ABS_Y, y1);
>>> +       elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
>>> +       input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
>>> +       input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
>>> +       input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
>>> +       input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
>>> +       input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
>>> +       input_report_abs(dev, ABS_PRESSURE, pres);
>>> +       input_report_abs(dev, ABS_TOOL_WIDTH, width);
>>> +
>>> +       input_sync(dev);
>>> +}
>>> +
>>>  static int elantech_check_parity_v1(struct psmouse *psmouse)
>>>  {
>>>        struct elantech_data *etd = psmouse->private;
>>> @@ -396,11 +506,31 @@ static int packet_simple_check_v2(struct psmouse
>>> *psmouse)
>>>  }
>>>
>>>  /*
>>> + * We check the constant bits to determine what packet type we get,
>>> + * so packet checking is mandatory for v3 hardware.
>>> + */
>>> +static int determine_packet_v3(struct psmouse *psmouse)
>>> +{
>>> +       unsigned char *packet = psmouse->packet;
>>> +
>>> +       if ((packet[0]&  0x0c) == 0x04&&
>>> +           (packet[3]&  0xcf) == 0x02)
>>> +               return PACKET_V3_HEAD;
>>> +
>>> +       if ((packet[0]&  0x0c) == 0x0c&&
>>> +           (packet[3]&  0xce) == 0x0c)
>>> +               return PACKET_V3_TAIL;
>>> +
>>> +       return PACKET_UNKNOWN;
>>> +}
>>> +
>>> +/*
>>>  * Process byte stream from mouse and handle complete packets
>>>  */
>>>  static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>>>  {
>>>        struct elantech_data *etd = psmouse->private;
>>> +       int packet_type;
>>>
>>>        if (psmouse->pktcnt<  psmouse->pktsize)
>>>                return PSMOUSE_GOOD_DATA;
>>> @@ -422,6 +552,14 @@ static psmouse_ret_t elantech_process_byte(struct
>>> psmouse *psmouse)
>>>
>>>                elantech_report_absolute_v2(psmouse);
>>>                break;
>>> +
>>> +       case 3:
>>> +               packet_type = determine_packet_v3(psmouse);
>>> +               if (packet_type == PACKET_UNKNOWN)
>>> +                       goto bad_packet;
>>> +
>>> +               elantech_report_absolute_v3(psmouse, packet_type);
>>> +               break;
>>>        }
>>>
>>>        return PSMOUSE_FULL_PACKET;
>>> @@ -459,10 +597,17 @@ static int elantech_set_absolute_mode(struct
>>> psmouse *psmouse)
>>>                etd->reg_21 = 0x60;     /* 0x00 */
>>>                if (elantech_write_reg(psmouse, 0x10, etd->reg_10) ||
>>>                    elantech_write_reg(psmouse, 0x11, etd->reg_11) ||
>>> -                   elantech_write_reg(psmouse, 0x21, etd->reg_21)) {
>>> +                   elantech_write_reg(psmouse, 0x21, etd->reg_21))
>>>                        rc = -1;
>>> -                       break;
>>> -               }
>>> +
>>> +               break;
>>> +
>>> +       case 3:
>>> +               etd->reg_10 = 0x0b;
>>> +               if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
>>> +                       rc = -1;
>>> +
>>> +               break;
>>>        }
>>>
>>>        if (rc == 0) {
>>> @@ -496,11 +641,12 @@ static int elantech_set_absolute_mode(struct
>>> psmouse *psmouse)
>>>        return rc;
>>>  }
>>>
>>> -static void set_range(struct psmouse *psmouse, unsigned int *x_min,
>>> +static int set_range(struct psmouse *psmouse, unsigned int *x_min,
>>>                     unsigned int *y_min, unsigned int *x_max,
>>>                     unsigned int *y_max, unsigned int *y_2ft_max)
>>>  {
>>>        struct elantech_data *etd = psmouse->private;
>>> +       unsigned char param[3];
>>>        int i;
>>>
>>>        switch (etd->hw_version) {
>>> @@ -529,19 +675,30 @@ static void set_range(struct psmouse *psmouse,
>>> unsigned int *x_min,
>>>                *y_max = (etd->capabilities[2] - i) * 64;
>>>                *y_2ft_max = (*y_max - i) * 64 / 4;
>>>                break;
>>> +
>>> +       case 3:
>>> +               if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
>>> +                       return -1;
>>> +
>>> +               *x_max = (0x0f&  param[0])<<  8 | param[1];
>>> +               *y_max = (0xf0&  param[0])<<  4 | param[2];
>>> +               break;
>>>        }
>>> +
>>> +       return 0;
>>>  }
>>>
>>>  /*
>>>  * Set the appropriate event bits for the input subsystem
>>>  */
>>> -static void elantech_set_input_params(struct psmouse *psmouse)
>>> +static int elantech_set_input_params(struct psmouse *psmouse)
>>>  {
>>>        struct input_dev *dev = psmouse->dev;
>>>        struct elantech_data *etd = psmouse->private;
>>>        unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max
>>> = 0;
>>>
>>> -       set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
>>> +       if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
>>> +               return -1;
>>>
>>>        __set_bit(EV_KEY, dev->evbit);
>>>        __set_bit(EV_ABS, dev->evbit);
>>> @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct
>>> psmouse *psmouse)
>>>                input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max,
>>> 0, 0);
>>>                input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max,
>>> 0, 0);
>>>                break;
>>> +
>>> +       case 3:
>>> +               input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
>>> +               input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
>>> +               /* range of pressure and width is the same as v2 */
>>> +               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,
>>> +                                    ETP_WMAX_V2, 0, 0);
>>> +               __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
>>> +               input_mt_init_slots(dev, 2);
>>> +               input_set_abs_params(dev, ABS_MT_POSITION_X, x_min,
>>> x_max, 0, 0);
>>> +               input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min,
>>> y_max, 0, 0);
>>> +               break;
>>>        }
>>>
>>>        etd->y_max = y_max;
>>>        etd->y_2ft_max = y_2ft_max;
>>> +
>>> +       return 0;
>>>  }
>>>
>>>  struct elantech_attr_data {
>>> @@ -727,7 +900,8 @@ int elantech_detect(struct psmouse *psmouse, bool
>>> set_properties)
>>>         * Report this in case there are Elantech models that use a
>>> different
>>>         * set of magic numbers
>>>         */
>>> -       if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
>>> +       if (param[0] != 0x3c || param[1] != 0x03 ||
>>> +           (param[2] != 0xc8&&  param[2] != 0x00)) {
>>>                pr_debug("unexpected magic knock result 0x%02x, 0x%02x,
>>> 0x%02x.\n",
>>>                         param[0], param[1], param[2]);
>>>                return -1;
>>> @@ -793,16 +967,16 @@ static int elantech_reconnect(struct psmouse
>>> *psmouse)
>>>  /*
>>>  * determine hardware version and set some properties according to it.
>>>  */
>>> -static void elantech_set_properties(struct elantech_data *etd)
>>> +static int elantech_set_properties(struct elantech_data *etd)
>>>  {
>>> -       /*
>>> -        * Assume every version greater than 0x020030 is new EeePC style
>>> -        * hardware with 6 byte packets, except 0x020600
>>> -        */
>>>        if (etd->fw_version<  0x020030 || etd->fw_version == 0x020600)
>>>                etd->hw_version = 1;
>>> -       else
>>> +       else if (etd->fw_version<  0x150600)
>>>                etd->hw_version = 2;
>>> +       else if ((etd->fw_version&  0x0f0000)>>  16 == 5)
>>> +               etd->hw_version = 3;
>>> +       else
>>> +               return -1;
>>>
>>>        /*
>>>         * Turn on packet checking by default.
>>> @@ -817,13 +991,15 @@ static void elantech_set_properties(struct
>>> elantech_data *etd)
>>>        etd->jumpy_cursor =
>>>                (etd->fw_version == 0x020022 || etd->fw_version ==
>>> 0x020600);
>>>
>>> -       if (etd->hw_version == 2) {
>>> +       if (etd->hw_version>  1) {
>>>                /* For now show extra debug information */
>>>                etd->debug = 1;
>>>
>>>                if (etd->fw_version>= 0x020800)
>>>                        etd->reports_pressure = true;
>>>        }
>>> +
>>> +       return 0;
>>>  }
>>>
>>>  /*
>>> @@ -850,9 +1026,12 @@ int elantech_init(struct psmouse *psmouse)
>>>                pr_err("failed to query firmware version.\n");
>>>                goto init_fail;
>>>        }
>>> -
>>>        etd->fw_version = (param[0]<<  16) | (param[1]<<  8) | param[2];
>>> -       elantech_set_properties(etd);
>>> +
>>> +       if (elantech_set_properties(etd)) {
>>> +               pr_err("unknown hardware version, aborting...\n");
>>> +               goto init_fail;
>>> +       }
>>>        pr_info("assuming hardware version %d "
>>>                "(with firmware version 0x%02x%02x%02x)\n",
>>>                etd->hw_version, param[0], param[1], param[2]);
>>> @@ -871,7 +1050,10 @@ int elantech_init(struct psmouse *psmouse)
>>>                goto init_fail;
>>>        }
>>>
>>> -       elantech_set_input_params(psmouse);
>>> +       if (elantech_set_input_params(psmouse)) {
>>> +               pr_err("failed to query touchpad range.\n");
>>> +               goto init_fail;
>>> +       }
>>>
>>>        error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
>>>                                   &elantech_attr_group);
>>> @@ -883,7 +1065,7 @@ int elantech_init(struct psmouse *psmouse)
>>>        psmouse->protocol_handler = elantech_process_byte;
>>>        psmouse->disconnect = elantech_disconnect;
>>>        psmouse->reconnect = elantech_reconnect;
>>> -       psmouse->pktsize = etd->hw_version == 2 ? 6 : 4;
>>> +       psmouse->pktsize = etd->hw_version>  1 ? 6 : 4;
>>>
>>>        return 0;
>>>
>>> diff --git a/drivers/input/mouse/elantech.h
>>> b/drivers/input/mouse/elantech.h
>>> index 4b7447e..4f01fc6 100644
>>> --- a/drivers/input/mouse/elantech.h
>>> +++ b/drivers/input/mouse/elantech.h
>>> @@ -16,6 +16,7 @@
>>>  /*
>>>  * Command values for Synaptics style queries
>>>  */
>>> +#define ETP_FW_ID_QUERY                        0x00
>>
>> One tab too many?
>
> No.

Yeah, weird patchwork diff'ing artifact....


>>
>>>  #define ETP_FW_VERSION_QUERY           0x01
>>>  #define ETP_CAPABILITIES_QUERY         0x02
>>>
>>> @@ -24,6 +25,7 @@
>>>  */
>>>  #define ETP_REGISTER_READ              0x10
>>>  #define ETP_REGISTER_WRITE             0x11
>>> +#define ETP_REGISTER_READWRITE         0x00
>>>
>>>  /*
>>>  * Hardware version 2 custom PS/2 command value
>>> @@ -93,6 +95,13 @@
>>>  #define ETP_2FT_YMIN                   (  0 + ETP_2FT_FUZZ)
>>>  #define ETP_2FT_YMAX                   (192 - ETP_2FT_FUZZ)
>>>
>>> +/*
>>> + * v3 hardware has 2 kinds of packet types.
>>> + */
>>> +#define PACKET_UNKNOWN                 0x01
>>> +#define PACKET_V3_HEAD                 0x02
>>> +#define PACKET_V3_TAIL                 0x03
>>> +
>>>  struct elantech_data {
>>>        unsigned char reg_10;
>>>        unsigned char reg_11;
>>> @@ -113,6 +122,8 @@ struct elantech_data {
>>>        unsigned int single_finger_reports;
>>>        unsigned int y_max;
>>>        unsigned int y_2ft_max;
>>> +       unsigned int prev_x;
>>> +       unsigned int prev_y;
>>>        unsigned char parity[256];
>>>  };
>>>
>>> --
>>> 1.7.4.1
>>>
>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-input" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
>
> --
> Thanks
> Wanlong Gao
>
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  3:09         ` Daniel Kurtz
  (?)
@ 2011-08-18  3:22         ` Wanlong Gao
  -1 siblings, 0 replies; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  3:22 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 11:09 AM, Daniel Kurtz wrote:
> On Thu, Aug 18, 2011 at 11:04 AM, Wanlong Gao<gaowanlong@cn.fujitsu.com>  wrote:
>> On 08/18/2011 10:57 AM, Daniel Kurtz wrote:
>>>
>>> On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding<jj_ding@emc.com.tw>    wrote:
>>>>
>>>> v3 hardware's packet format is almost identical to v2 (one/three finger
>>>> touch),
>>>> except when sensing two finger touch, the hardware sends 12 bytes of
>>>> data.
>>>>
>>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>>>> ---
>>>>   Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>>>   drivers/input/mouse/elantech.c   |  218
>>>> ++++++++++++++++++++++++++++++++++---
>>>>   drivers/input/mouse/elantech.h   |   11 ++
>>>>   3 files changed, 303 insertions(+), 30 deletions(-)
>>>>

>>>>
>>>> diff --git a/drivers/input/mouse/elantech.h
>>>> b/drivers/input/mouse/elantech.h
>>>> index 4b7447e..4f01fc6 100644
>>>> --- a/drivers/input/mouse/elantech.h
>>>> +++ b/drivers/input/mouse/elantech.h
>>>> @@ -16,6 +16,7 @@
>>>>   /*
>>>>   * Command values for Synaptics style queries
>>>>   */
>>>> +#define ETP_FW_ID_QUERY                        0x00
>>>
>>> One tab too many?
>>
>> No.
>
> Yeah, weird patchwork diff'ing artifact....
Yeah, it's caused by the '+' ahead the line.
-- 
Thanks
Wanlong Gao

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  1:57 ` [PATCH 6/6] Input: elantech - add v3 hardware support JJ Ding
  2011-08-18  2:57   ` Daniel Kurtz
  2011-08-18  3:01   ` Wanlong Gao
@ 2011-08-18  3:30   ` Wanlong Gao
  2011-08-18  3:47     ` Li Zefan
  2011-08-18 13:58   ` Seth Forshee
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  3:30 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 09:57 AM, JJ Ding wrote:
> v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> except when sensing two finger touch, the hardware sends 12 bytes of data.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
> ---
>   Documentation/input/elantech.txt |  104 ++++++++++++++++--
>   drivers/input/mouse/elantech.c   |  218 ++++++++++++++++++++++++++++++++++---
>   drivers/input/mouse/elantech.h   |   11 ++
>   3 files changed, 303 insertions(+), 30 deletions(-)

> +The packet format is exactly the same for two finger touch, except the hardware
> +sends two 6 byte packets. The first packet contains data for the first finger,
> +the second packet has data for the second finger. So for two finger touch a
> +total of 12 bytes are sent.
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index ddd40eb..e13a719 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -108,6 +108,16 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
>   			rc = -1;
>   		}
>   		break;
> +
> +	case 3:
> +		if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, reg) ||
> +		    elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
> +			rc = -1;
> +		}
Prefer to remove these big brace ?
also with "case 1, case 2 "?
> +		break;
>   	}
>
>   	if (rc)
> @@ -154,6 +164,18 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg,
>   			rc = -1;
>   		}
>   		break;
> +
> +	case 3:
> +		if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, reg) ||
> +		    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> +		    elantech_ps2_command(psmouse, NULL, val) ||
> +		    elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) {
> +			rc = -1;
> +		}
ditto

--
Thanks
Wanlong Gao

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  3:30   ` Wanlong Gao
@ 2011-08-18  3:47     ` Li Zefan
  2011-08-18  4:15       ` Wanlong Gao
  0 siblings, 1 reply; 90+ messages in thread
From: Li Zefan @ 2011-08-18  3:47 UTC (permalink / raw)
  To: gaowanlong
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz,
	Chase Douglas, Henrik Rydberg, Alessandro Rubini

>> +
>> +    case 3:
>> +        if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>> +            elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
>> +            elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>> +            elantech_ps2_command(psmouse, NULL, reg) ||
>> +            elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
>> +            rc = -1;
>> +        }
> Prefer to remove these big brace ?
> also with "case 1, case 2 "?

Just wondering What's wrong with this piece of code and what do you
sugguest to improve it?

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  3:47     ` Li Zefan
@ 2011-08-18  4:15       ` Wanlong Gao
  2011-08-18  6:02         ` Dmitry Torokhov
  0 siblings, 1 reply; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  4:15 UTC (permalink / raw)
  To: Li Zefan
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz,
	Chase Douglas, Henrik Rydberg, Alessandro Rubini

On 08/18/2011 11:47 AM, Li Zefan wrote:
>>> +
>>> +    case 3:
>>> +        if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>>> +            elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
>>> +            elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>>> +            elantech_ps2_command(psmouse, NULL, reg) ||
>>> +            elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
>>> +            rc = -1;
>>> +        }
>> Prefer to remove these big brace ?
>> also with "case 1, case 2 "?
>
> Just wondering What's wrong with this piece of code and what do you
> sugguest to improve it?

I think no need to add a '{}' with the *if* ?
and remove the '{}' in whole elantech_read_reg() and 
elantech_write_reg(), right?

-Wanlong Gao


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  3:01   ` Wanlong Gao
@ 2011-08-18  5:26     ` JJ Ding
  2011-08-18  5:31       ` Wanlong Gao
  0 siblings, 1 reply; 90+ messages in thread
From: JJ Ding @ 2011-08-18  5:26 UTC (permalink / raw)
  To: gaowanlong
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Hi Wanlong Gao,

On Thu, 18 Aug 2011 11:01:52 +0800, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> On 08/18/2011 09:57 AM, JJ Ding wrote:
> > v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> > except when sensing two finger touch, the hardware sends 12 bytes of data.
> >
> > Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
> > ---
> >   Documentation/input/elantech.txt |  104 ++++++++++++++++--
> >   drivers/input/mouse/elantech.c   |  218 ++++++++++++++++++++++++++++++++++---
> >   drivers/input/mouse/elantech.h   |   11 ++
> >   3 files changed, 303 insertions(+), 30 deletions(-)
> >
> > +static int determine_packet_v3(struct psmouse *psmouse)
> elantech_check_parity_v1
> packet_simple_check_v2
> determine_packet_v3
> 
> Why not consistent them?
OK, how do these names sound to you?

elantech_check_parity_v1
elantech_packet_check_v2
elantech_packet_check_v3

Thanks,
jj

> -- 
> Thanks
> Wanlong Gao
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  5:26     ` JJ Ding
@ 2011-08-18  5:31       ` Wanlong Gao
  2011-08-18  5:34         ` Daniel Kurtz
  0 siblings, 1 reply; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  5:31 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 01:26 PM, JJ Ding wrote:
> Hi Wanlong Gao,
>
> On Thu, 18 Aug 2011 11:01:52 +0800, Wanlong Gao<gaowanlong@cn.fujitsu.com>  wrote:
>> On 08/18/2011 09:57 AM, JJ Ding wrote:
>>> v3 hardware's packet format is almost identical to v2 (one/three finger touch),
>>> except when sensing two finger touch, the hardware sends 12 bytes of data.
>>>
>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>>> ---
>>>    Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>>    drivers/input/mouse/elantech.c   |  218 ++++++++++++++++++++++++++++++++++---
>>>    drivers/input/mouse/elantech.h   |   11 ++
>>>    3 files changed, 303 insertions(+), 30 deletions(-)
>>>
>>> +static int determine_packet_v3(struct psmouse *psmouse)
>> elantech_check_parity_v1
>> packet_simple_check_v2
>> determine_packet_v3
>>
>> Why not consistent them?
> OK, how do these names sound to you?
>
> elantech_check_parity_v1
> elantech_packet_check_v2
> elantech_packet_check_v3
>
> Thanks,
> jj

Yeah, sounds perfectly.

Thanks
-Wanlong Gao


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  5:31       ` Wanlong Gao
@ 2011-08-18  5:34         ` Daniel Kurtz
  2011-08-18  5:44           ` Wanlong Gao
  0 siblings, 1 reply; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  5:34 UTC (permalink / raw)
  To: gaowanlong
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On Thu, Aug 18, 2011 at 1:31 PM, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> On 08/18/2011 01:26 PM, JJ Ding wrote:
>>
>> Hi Wanlong Gao,
>>
>> On Thu, 18 Aug 2011 11:01:52 +0800, Wanlong Gao<gaowanlong@cn.fujitsu.com>
>>  wrote:
>>>
>>> On 08/18/2011 09:57 AM, JJ Ding wrote:
>>>>
>>>> v3 hardware's packet format is almost identical to v2 (one/three finger
>>>> touch),
>>>> except when sensing two finger touch, the hardware sends 12 bytes of
>>>> data.
>>>>
>>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>>>> ---
>>>>   Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>>>   drivers/input/mouse/elantech.c   |  218
>>>> ++++++++++++++++++++++++++++++++++---
>>>>   drivers/input/mouse/elantech.h   |   11 ++
>>>>   3 files changed, 303 insertions(+), 30 deletions(-)
>>>>
>>>> +static int determine_packet_v3(struct psmouse *psmouse)
>>>
>>> elantech_check_parity_v1
>>> packet_simple_check_v2
>>> determine_packet_v3
>>>
>>> Why not consistent them?
>>
>> OK, how do these names sound to you?
>>
>> elantech_check_parity_v1
>> elantech_packet_check_v2
>> elantech_packet_check_v3
>>
>> Thanks,
>> jj
>
> Yeah, sounds perfectly.

Or just:

elantech_packet_check_v1
elantech_packet_check_v2
elantech_packet_check_v3

:)

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 5/6] Input: elantech - clean up elantech_init
  2011-08-18  3:08     ` Wanlong Gao
@ 2011-08-18  5:35       ` JJ Ding
  2011-08-18  5:38         ` Wanlong Gao
  2011-08-18  6:00         ` Dmitry Torokhov
  0 siblings, 2 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  5:35 UTC (permalink / raw)
  To: gaowanlong, Daniel Kurtz
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Hi Wanlong Gao, Daniel,

On Thu, 18 Aug 2011 11:08:08 +0800, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> On 08/18/2011 11:04 AM, Daniel Kurtz wrote:
> > On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding<jj_ding@emc.com.tw>  wrote:
> >>   /*
> >> + * determine hardware version and set some properties according to it.
> >> + */
> >> +static void elantech_set_properties(struct elantech_data *etd)
> >> +{
> >> +       /*
> >> +        * Assume every version greater than 0x020030 is new EeePC style
> >> +        * hardware with 6 byte packets, except 0x020600
> >> +        */
> >> +       if (etd->fw_version<  0x020030 || etd->fw_version == 0x020600)
> >> +               etd->hw_version = 1;
> >> +       else
> >> +               etd->hw_version = 2;
> >> +
> >> +       /*
> >> +        * Turn on packet checking by default.
> >> +        */
> >> +       etd->paritycheck = 1;
> >
> > Assuming paritycheck goes away:
> Agree.
I thought about removing it, too. But it occured to me that v1 and v2
hardware can still have the sysfs entry to turn off parity check.

And since it's exposed in sysfs, I suppose there might be some init
scripts relying on it.

What do you think, Dmitry?
Shall I remove it?

Thanks,
jj

> >
> > Reviewed-by: Daniel Kurtz<djkurtz@chromium.org>
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-input" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> 
> 
> -- 
> Thanks
> Wanlong Gao

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 5/6] Input: elantech - clean up elantech_init
  2011-08-18  5:35       ` JJ Ding
@ 2011-08-18  5:38         ` Wanlong Gao
  2011-08-18  6:00         ` Dmitry Torokhov
  1 sibling, 0 replies; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  5:38 UTC (permalink / raw)
  To: JJ Ding
  Cc: Daniel Kurtz, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 01:35 PM, JJ Ding wrote:
> Hi Wanlong Gao, Daniel,
>
> On Thu, 18 Aug 2011 11:08:08 +0800, Wanlong Gao<gaowanlong@cn.fujitsu.com>  wrote:
>> On 08/18/2011 11:04 AM, Daniel Kurtz wrote:
>>> On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding<jj_ding@emc.com.tw>   wrote:
>>>>    /*
>>>> + * determine hardware version and set some properties according to it.
>>>> + */
>>>> +static void elantech_set_properties(struct elantech_data *etd)
>>>> +{
>>>> +       /*
>>>> +        * Assume every version greater than 0x020030 is new EeePC style
>>>> +        * hardware with 6 byte packets, except 0x020600
>>>> +        */
>>>> +       if (etd->fw_version<   0x020030 || etd->fw_version == 0x020600)
>>>> +               etd->hw_version = 1;
>>>> +       else
>>>> +               etd->hw_version = 2;
>>>> +
>>>> +       /*
>>>> +        * Turn on packet checking by default.
>>>> +        */
>>>> +       etd->paritycheck = 1;
>>>
>>> Assuming paritycheck goes away:
>> Agree.
> I thought about removing it, too. But it occured to me that v1 and v2
> hardware can still have the sysfs entry to turn off parity check.
>
> And since it's exposed in sysfs, I suppose there might be some init
> scripts relying on it.
>
> What do you think, Dmitry?
> Shall I remove it?
>
> Thanks,
> jj

aha, maybe you can make the sysfs entry func to be noop, and mark it to 
be obsoleted, or just remove it?

Thanks
-Wanlong Gao

>
>>>
>>> Reviewed-by: Daniel Kurtz<djkurtz@chromium.org>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-input" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>
>>
>> --
>> Thanks
>> Wanlong Gao
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  2:57   ` Daniel Kurtz
  2011-08-18  3:04     ` Wanlong Gao
@ 2011-08-18  5:39     ` JJ Ding
  1 sibling, 0 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  5:39 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Hi Daniel,

On Thu, 18 Aug 2011 10:57:57 +0800, Daniel Kurtz <djkurtz@chromium.org> wrote:
> On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding <jj_ding@emc.com.tw> wrote:
> > v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> > except when sensing two finger touch, the hardware sends 12 bytes of data.
> >
> > Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
> > ---
> >  Documentation/input/elantech.txt |  104 ++++++++++++++++--
> >  drivers/input/mouse/elantech.c   |  218 ++++++++++++++++++++++++++++++++++---
> >  drivers/input/mouse/elantech.h   |   11 ++
> >  3 files changed, 303 insertions(+), 30 deletions(-)
> >
> > +/*
> > + * firmware tells us there's noise.
> > + */
> > +static inline int debounce(unsigned int x, unsigned int y)
> > +{
> > +       return (x == 0xfff) && (y == 0xfff);
> 
> Perhaps you could document this behavior in the elantech.txt.
OK, I will do that.

> >
> > diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
> > index 4b7447e..4f01fc6 100644
> > --- a/drivers/input/mouse/elantech.h
> > +++ b/drivers/input/mouse/elantech.h
> > @@ -16,6 +16,7 @@
> >  /*
> >  * Command values for Synaptics style queries
> >  */
> > +#define ETP_FW_ID_QUERY                        0x00
> 
> One tab too many?
> 
> >  #define ETP_FW_VERSION_QUERY           0x01
> >  #define ETP_CAPABILITIES_QUERY         0x02
> >
> > @@ -24,6 +25,7 @@
> >  */
> >  #define ETP_REGISTER_READ              0x10
> >  #define ETP_REGISTER_WRITE             0x11
> > +#define ETP_REGISTER_READWRITE         0x00
> >
> >  /*
> >  * Hardware version 2 custom PS/2 command value
> > @@ -93,6 +95,13 @@
> >  #define ETP_2FT_YMIN                   (  0 + ETP_2FT_FUZZ)
> >  #define ETP_2FT_YMAX                   (192 - ETP_2FT_FUZZ)
> >
> > +/*
> > + * v3 hardware has 2 kinds of packet types.
> > + */
> > +#define PACKET_UNKNOWN                 0x01
> > +#define PACKET_V3_HEAD                 0x02
> > +#define PACKET_V3_TAIL                 0x03
> > +
> >  struct elantech_data {
> >        unsigned char reg_10;
> >        unsigned char reg_11;
> > @@ -113,6 +122,8 @@ struct elantech_data {
> >        unsigned int single_finger_reports;
> >        unsigned int y_max;
> >        unsigned int y_2ft_max;
> > +       unsigned int prev_x;
> > +       unsigned int prev_y;
> >        unsigned char parity[256];
> >  };
> >
> > --
> > 1.7.4.1
> >
> >

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  5:34         ` Daniel Kurtz
@ 2011-08-18  5:44           ` Wanlong Gao
  2011-08-18  6:01               ` Daniel Kurtz
  0 siblings, 1 reply; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  5:44 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 01:34 PM, Daniel Kurtz wrote:
> On Thu, Aug 18, 2011 at 1:31 PM, Wanlong Gao<gaowanlong@cn.fujitsu.com>  wrote:
>> On 08/18/2011 01:26 PM, JJ Ding wrote:
>>>
>>> Hi Wanlong Gao,
>>>
>>> On Thu, 18 Aug 2011 11:01:52 +0800, Wanlong Gao<gaowanlong@cn.fujitsu.com>
>>>   wrote:
>>>>
>>>> On 08/18/2011 09:57 AM, JJ Ding wrote:
>>>>>
>>>>> v3 hardware's packet format is almost identical to v2 (one/three finger
>>>>> touch),
>>>>> except when sensing two finger touch, the hardware sends 12 bytes of
>>>>> data.
>>>>>
>>>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>>>>> ---
>>>>>    Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>>>>    drivers/input/mouse/elantech.c   |  218
>>>>> ++++++++++++++++++++++++++++++++++---
>>>>>    drivers/input/mouse/elantech.h   |   11 ++
>>>>>    3 files changed, 303 insertions(+), 30 deletions(-)
>>>>>
>>>>> +static int determine_packet_v3(struct psmouse *psmouse)
>>>>
>>>> elantech_check_parity_v1
>>>> packet_simple_check_v2
>>>> determine_packet_v3
>>>>
>>>> Why not consistent them?
>>>
>>> OK, how do these names sound to you?
>>>
>>> elantech_check_parity_v1
>>> elantech_packet_check_v2
>>> elantech_packet_check_v3
>>>
>>> Thanks,
>>> jj
>>
>> Yeah, sounds perfectly.
>
> Or just:
>
> elantech_packet_check_v1
> elantech_packet_check_v2
> elantech_packet_check_v3
>
> :)

Hmm... maybe they can go into an elantech_packet_check()?
like:
case 1:
	...
case 2:
	...
What do you think? ;)

Thanks
-Wanlong Gao
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 5/6] Input: elantech - clean up elantech_init
  2011-08-18  5:35       ` JJ Ding
  2011-08-18  5:38         ` Wanlong Gao
@ 2011-08-18  6:00         ` Dmitry Torokhov
  2011-08-18  7:44           ` JJ Ding
  1 sibling, 1 reply; 90+ messages in thread
From: Dmitry Torokhov @ 2011-08-18  6:00 UTC (permalink / raw)
  To: JJ Ding
  Cc: gaowanlong, Daniel Kurtz, linux-input, linux-kernel,
	Seth Forshee, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On Thu, Aug 18, 2011 at 01:35:55PM +0800, JJ Ding wrote:
> Hi Wanlong Gao, Daniel,
> 
> On Thu, 18 Aug 2011 11:08:08 +0800, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> > On 08/18/2011 11:04 AM, Daniel Kurtz wrote:
> > > On Thu, Aug 18, 2011 at 9:57 AM, JJ Ding<jj_ding@emc.com.tw>  wrote:
> > >>   /*
> > >> + * determine hardware version and set some properties according to it.
> > >> + */
> > >> +static void elantech_set_properties(struct elantech_data *etd)
> > >> +{
> > >> +       /*
> > >> +        * Assume every version greater than 0x020030 is new EeePC style
> > >> +        * hardware with 6 byte packets, except 0x020600
> > >> +        */
> > >> +       if (etd->fw_version<  0x020030 || etd->fw_version == 0x020600)
> > >> +               etd->hw_version = 1;
> > >> +       else
> > >> +               etd->hw_version = 2;
> > >> +
> > >> +       /*
> > >> +        * Turn on packet checking by default.
> > >> +        */
> > >> +       etd->paritycheck = 1;
> > >
> > > Assuming paritycheck goes away:
> > Agree.
> I thought about removing it, too. But it occured to me that v1 and v2
> hardware can still have the sysfs entry to turn off parity check.
> 
> And since it's exposed in sysfs, I suppose there might be some init
> scripts relying on it.
> 
> What do you think, Dmitry?
> Shall I remove it?

No, we should not remove it, since it is useful for V1 hardware which we
still support.

How confident are we in the V2/V3 checking not tripping on valid packets?

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  5:44           ` Wanlong Gao
@ 2011-08-18  6:01               ` Daniel Kurtz
  0 siblings, 0 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  6:01 UTC (permalink / raw)
  To: gaowanlong
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On Thu, Aug 18, 2011 at 1:44 PM, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> On 08/18/2011 01:34 PM, Daniel Kurtz wrote:
>>
>> On Thu, Aug 18, 2011 at 1:31 PM, Wanlong Gao<gaowanlong@cn.fujitsu.com>
>>  wrote:
>>>
>>> On 08/18/2011 01:26 PM, JJ Ding wrote:
>>>>
>>>> Hi Wanlong Gao,
>>>>
>>>> On Thu, 18 Aug 2011 11:01:52 +0800, Wanlong
>>>> Gao<gaowanlong@cn.fujitsu.com>
>>>>  wrote:
>>>>>
>>>>> On 08/18/2011 09:57 AM, JJ Ding wrote:
>>>>>>
>>>>>> v3 hardware's packet format is almost identical to v2 (one/three
>>>>>> finger
>>>>>> touch),
>>>>>> except when sensing two finger touch, the hardware sends 12 bytes of
>>>>>> data.
>>>>>>
>>>>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>>>>>> ---
>>>>>>   Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>>>>>   drivers/input/mouse/elantech.c   |  218
>>>>>> ++++++++++++++++++++++++++++++++++---
>>>>>>   drivers/input/mouse/elantech.h   |   11 ++
>>>>>>   3 files changed, 303 insertions(+), 30 deletions(-)
>>>>>>
>>>>>> +static int determine_packet_v3(struct psmouse *psmouse)
>>>>>
>>>>> elantech_check_parity_v1
>>>>> packet_simple_check_v2
>>>>> determine_packet_v3
>>>>>
>>>>> Why not consistent them?
>>>>
>>>> OK, how do these names sound to you?
>>>>
>>>> elantech_check_parity_v1
>>>> elantech_packet_check_v2
>>>> elantech_packet_check_v3
>>>>
>>>> Thanks,
>>>> jj
>>>
>>> Yeah, sounds perfectly.
>>
>> Or just:
>>
>> elantech_packet_check_v1
>> elantech_packet_check_v2
>> elantech_packet_check_v3
>>
>> :)
>
> Hmm... maybe they can go into an elantech_packet_check()?
> like:
> case 1:
>        ...
> case 2:
>        ...
> What do you think? ;)
>
> Thanks
> -Wanlong Gao

Since we've already parsed the hardware type at this point, it seems
inefficient to parse it again inside another function.
I would prefer individual functions.

Thanks,
-Daniel

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-18  6:01               ` Daniel Kurtz
  0 siblings, 0 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-08-18  6:01 UTC (permalink / raw)
  To: gaowanlong
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On Thu, Aug 18, 2011 at 1:44 PM, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> On 08/18/2011 01:34 PM, Daniel Kurtz wrote:
>>
>> On Thu, Aug 18, 2011 at 1:31 PM, Wanlong Gao<gaowanlong@cn.fujitsu.com>
>>  wrote:
>>>
>>> On 08/18/2011 01:26 PM, JJ Ding wrote:
>>>>
>>>> Hi Wanlong Gao,
>>>>
>>>> On Thu, 18 Aug 2011 11:01:52 +0800, Wanlong
>>>> Gao<gaowanlong@cn.fujitsu.com>
>>>>  wrote:
>>>>>
>>>>> On 08/18/2011 09:57 AM, JJ Ding wrote:
>>>>>>
>>>>>> v3 hardware's packet format is almost identical to v2 (one/three
>>>>>> finger
>>>>>> touch),
>>>>>> except when sensing two finger touch, the hardware sends 12 bytes of
>>>>>> data.
>>>>>>
>>>>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>>>>>> ---
>>>>>>   Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>>>>>   drivers/input/mouse/elantech.c   |  218
>>>>>> ++++++++++++++++++++++++++++++++++---
>>>>>>   drivers/input/mouse/elantech.h   |   11 ++
>>>>>>   3 files changed, 303 insertions(+), 30 deletions(-)
>>>>>>
>>>>>> +static int determine_packet_v3(struct psmouse *psmouse)
>>>>>
>>>>> elantech_check_parity_v1
>>>>> packet_simple_check_v2
>>>>> determine_packet_v3
>>>>>
>>>>> Why not consistent them?
>>>>
>>>> OK, how do these names sound to you?
>>>>
>>>> elantech_check_parity_v1
>>>> elantech_packet_check_v2
>>>> elantech_packet_check_v3
>>>>
>>>> Thanks,
>>>> jj
>>>
>>> Yeah, sounds perfectly.
>>
>> Or just:
>>
>> elantech_packet_check_v1
>> elantech_packet_check_v2
>> elantech_packet_check_v3
>>
>> :)
>
> Hmm... maybe they can go into an elantech_packet_check()?
> like:
> case 1:
>        ...
> case 2:
>        ...
> What do you think? ;)
>
> Thanks
> -Wanlong Gao

Since we've already parsed the hardware type at this point, it seems
inefficient to parse it again inside another function.
I would prefer individual functions.

Thanks,
-Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  4:15       ` Wanlong Gao
@ 2011-08-18  6:02         ` Dmitry Torokhov
  2011-08-18  6:08           ` Wanlong Gao
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry Torokhov @ 2011-08-18  6:02 UTC (permalink / raw)
  To: Wanlong Gao
  Cc: Li Zefan, JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On Thu, Aug 18, 2011 at 12:15:00PM +0800, Wanlong Gao wrote:
> On 08/18/2011 11:47 AM, Li Zefan wrote:
> >>>+
> >>>+    case 3:
> >>>+        if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> >>>+            elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
> >>>+            elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
> >>>+            elantech_ps2_command(psmouse, NULL, reg) ||
> >>>+            elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
> >>>+            rc = -1;
> >>>+        }
> >>Prefer to remove these big brace ?
> >>also with "case 1, case 2 "?
> >
> >Just wondering What's wrong with this piece of code and what do you
> >sugguest to improve it?
> 
> I think no need to add a '{}' with the *if* ?
> and remove the '{}' in whole elantech_read_reg() and
> elantech_write_reg(), right?
> 

In case when conditon "overpowers" the body (i.e. multi-line condition)
I prefer having braces so the body stands out.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  6:01               ` Daniel Kurtz
  (?)
@ 2011-08-18  6:06               ` Wanlong Gao
  2011-08-18  7:49                 ` Tom _Lin
  -1 siblings, 1 reply; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  6:06 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 02:01 PM, Daniel Kurtz wrote:
> On Thu, Aug 18, 2011 at 1:44 PM, Wanlong Gao<gaowanlong@cn.fujitsu.com>  wrote:
>> On 08/18/2011 01:34 PM, Daniel Kurtz wrote:
>>>
>>> On Thu, Aug 18, 2011 at 1:31 PM, Wanlong Gao<gaowanlong@cn.fujitsu.com>
>>>   wrote:
>>>>
>>>> On 08/18/2011 01:26 PM, JJ Ding wrote:
>>>>>
>>>>> Hi Wanlong Gao,
>>>>>
>>>>> On Thu, 18 Aug 2011 11:01:52 +0800, Wanlong
>>>>> Gao<gaowanlong@cn.fujitsu.com>
>>>>>   wrote:
>>>>>>
>>>>>> On 08/18/2011 09:57 AM, JJ Ding wrote:
>>>>>>>
>>>>>>> v3 hardware's packet format is almost identical to v2 (one/three
>>>>>>> finger
>>>>>>> touch),
>>>>>>> except when sensing two finger touch, the hardware sends 12 bytes of
>>>>>>> data.
>>>>>>>
>>>>>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
>>>>>>> ---
>>>>>>>    Documentation/input/elantech.txt |  104 ++++++++++++++++--
>>>>>>>    drivers/input/mouse/elantech.c   |  218
>>>>>>> ++++++++++++++++++++++++++++++++++---
>>>>>>>    drivers/input/mouse/elantech.h   |   11 ++
>>>>>>>    3 files changed, 303 insertions(+), 30 deletions(-)
>>>>>>>
>>>>>>> +static int determine_packet_v3(struct psmouse *psmouse)
>>>>>>
>>>>>> elantech_check_parity_v1
>>>>>> packet_simple_check_v2
>>>>>> determine_packet_v3
>>>>>>
>>>>>> Why not consistent them?
>>>>>
>>>>> OK, how do these names sound to you?
>>>>>
>>>>> elantech_check_parity_v1
>>>>> elantech_packet_check_v2
>>>>> elantech_packet_check_v3
>>>>>
>>>>> Thanks,
>>>>> jj
>>>>
>>>> Yeah, sounds perfectly.
>>>
>>> Or just:
>>>
>>> elantech_packet_check_v1
>>> elantech_packet_check_v2
>>> elantech_packet_check_v3
>>>
>>> :)
>>
>> Hmm... maybe they can go into an elantech_packet_check()?
>> like:
>> case 1:
>>         ...
>> case 2:
>>         ...
>> What do you think? ;)
>>
>> Thanks
>> -Wanlong Gao
>
> Since we've already parsed the hardware type at this point, it seems
> inefficient to parse it again inside another function.
> I would prefer individual functions.
>
> Thanks,
> -Daniel
>

Yeah, It makes sense.

Thanks
-Wanlong Gao

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  6:02         ` Dmitry Torokhov
@ 2011-08-18  6:08           ` Wanlong Gao
  0 siblings, 0 replies; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  6:08 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Li Zefan, JJ Ding, linux-input, linux-kernel, Seth Forshee,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 02:02 PM, Dmitry Torokhov wrote:
> On Thu, Aug 18, 2011 at 12:15:00PM +0800, Wanlong Gao wrote:
>> On 08/18/2011 11:47 AM, Li Zefan wrote:
>>>>> +
>>>>> +    case 3:
>>>>> +        if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>>>>> +            elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
>>>>> +            elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
>>>>> +            elantech_ps2_command(psmouse, NULL, reg) ||
>>>>> +            elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
>>>>> +            rc = -1;
>>>>> +        }
>>>> Prefer to remove these big brace ?
>>>> also with "case 1, case 2 "?
>>>
>>> Just wondering What's wrong with this piece of code and what do you
>>> sugguest to improve it?
>>
>> I think no need to add a '{}' with the *if* ?
>> and remove the '{}' in whole elantech_read_reg() and
>> elantech_write_reg(), right?
>>
>
> In case when conditon "overpowers" the body (i.e. multi-line condition)
> I prefer having braces so the body stands out.
>
> Thanks.
>

I see, Thanks

-Wanlong Gao



^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 5/6] Input: elantech - clean up elantech_init
  2011-08-18  1:57 ` [PATCH 5/6] Input: elantech - clean up elantech_init JJ Ding
  2011-08-18  3:04   ` Daniel Kurtz
@ 2011-08-18  6:34   ` Wanlong Gao
  2011-08-19 12:29     ` Éric Piel
  2 siblings, 0 replies; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  6:34 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 09:57 AM, JJ Ding wrote:
>   	if (elantech_set_absolute_mode(psmouse)) {
>   		pr_err("failed to put touchpad into absolute mode.\n");
>   		goto init_fail;
Hi JJ,
--
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index e13a719..675c236 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -1069,7 +1069,7 @@ int elantech_init(struct psmouse *psmouse)

         return 0;

- init_fail:
+init_fail:
         kfree(etd);
         return -1;
  }
--

also has space before *init_fail*, you may do this in your next version.

Thanks
-Wanlong Gao

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* Re: [PATCH 3/6] Input: elantech - packet checking for v2 hardware
  2011-08-18  1:57 ` [PATCH 3/6] Input: elantech - packet checking for v2 hardware JJ Ding
  2011-08-18  2:49   ` Daniel Kurtz
@ 2011-08-18  6:38   ` Dmitry Torokhov
  2011-08-18  7:31     ` JJ Ding
  2011-08-19 12:22     ` Éric Piel
  2 siblings, 1 reply; 90+ messages in thread
From: Dmitry Torokhov @ 2011-08-18  6:38 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 09:57:06AM +0800, JJ Ding wrote:
> For v2 hardware, there is no real parity check, but we can still check
> some constant bits for data integrity.
> 
> Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
> ---
>  drivers/input/mouse/elantech.c |   26 +++++++++++++++++++++++---
>  1 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index cf41f23..032181c 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -376,6 +376,25 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
>  	       etd->parity[packet[3]] == p3;
>  }
>  
> +static int packet_simple_check_v2(struct psmouse *psmouse)
> +{
> +	struct elantech_data *etd = psmouse->private;
> +	unsigned char *packet = psmouse->packet;
> +
> +	if (etd->reports_pressure)
> +		return (packet[0] & 0x0c) == 0x04 &&
> +		       (packet[3] & 0x0f) == 0x02;
> +
> +	if ((packet[0] & 0xc0) == 0x80)
> +		return (packet[0] & 0x0c) == 0x0c &&
> +		       (packet[3] & 0x0e) == 0x08;
> +
> +	return (packet[0] & 0x3c) == 0x3c &&
> +	       (packet[1] & 0xf0) == 0x00 &&
> +	       (packet[3] & 0x3e) == 0x38 &&
> +	       (packet[4] & 0xf0) == 0x00;

Can we please spell out the assumptions under which we decide that
packet is invalid?

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/6] Input: elantech - work around EC buffer
  2011-08-18  1:57 ` [PATCH 4/6] Input: elantech - work around EC buffer JJ Ding
  2011-08-18  2:50   ` Daniel Kurtz
  2011-08-18  3:07   ` Wanlong Gao
@ 2011-08-18  6:39   ` Dmitry Torokhov
  2011-08-18  6:54     ` JJ Ding
  2 siblings, 1 reply; 90+ messages in thread
From: Dmitry Torokhov @ 2011-08-18  6:39 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 09:57:07AM +0800, JJ Ding wrote:
> With some EC chips, when we resync due to bad packets, those bad bytes would
> still remain in EC's buffer area. That makes us always get bad data back,
> no matter what.
> 
> So shift packet for 1 byte when encounter bad packet, until we get rid of those
> bytes.

If we want to do this I think it should be done in psmouse core.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/6] Input: elantech - work around EC buffer
  2011-08-18  3:07   ` Wanlong Gao
@ 2011-08-18  6:48     ` JJ Ding
  2011-08-18  6:54       ` Wanlong Gao
  0 siblings, 1 reply; 90+ messages in thread
From: JJ Ding @ 2011-08-18  6:48 UTC (permalink / raw)
  To: gaowanlong
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Hi Wanlong Gao,

On Thu, 18 Aug 2011 11:07:23 +0800, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> On 08/18/2011 09:57 AM, JJ Ding wrote:
> >
> >   	return PSMOUSE_FULL_PACKET;
> > +
> > + bad_packet:
> You may introduce space here.
Sorry, I am following you here.
Do you want me to add one more line below bad_packet:,
or you want me to remove the space before bad_packet?

I keep that space to make the goto tags look consistent with other
places in this file.

Should I remove all starting spaces in goto tags in the file?

Thanks,

jj

> > +	memmove(psmouse->packet, psmouse->packet + 1, psmouse->pktsize - 1);
> > +	psmouse->pktcnt--;
> > +	return PSMOUSE_GOOD_DATA;
> >   }
> >
> >   /*
> 
> 
> -- 
> Thanks
> Wanlong Gao

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/6] Input: elantech - work around EC buffer
  2011-08-18  6:39   ` Dmitry Torokhov
@ 2011-08-18  6:54     ` JJ Ding
  0 siblings, 0 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  6:54 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Hi Dmitry,

On Wed, 17 Aug 2011 23:39:18 -0700, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> On Thu, Aug 18, 2011 at 09:57:07AM +0800, JJ Ding wrote:
> > With some EC chips, when we resync due to bad packets, those bad bytes would
> > still remain in EC's buffer area. That makes us always get bad data back,
> > no matter what.
> > 
> > So shift packet for 1 byte when encounter bad packet, until we get rid of those
> > bytes.
> 
> If we want to do this I think it should be done in psmouse core.
> 
> Thanks.
OK. That sounds more appropriate.
I will remove this patch from the series.

Thanks, 

jj

> 
> -- 
> Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/6] Input: elantech - work around EC buffer
  2011-08-18  6:48     ` JJ Ding
@ 2011-08-18  6:54       ` Wanlong Gao
  0 siblings, 0 replies; 90+ messages in thread
From: Wanlong Gao @ 2011-08-18  6:54 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

On 08/18/2011 02:48 PM, JJ Ding wrote:
> Hi Wanlong Gao,
>
> On Thu, 18 Aug 2011 11:07:23 +0800, Wanlong Gao<gaowanlong@cn.fujitsu.com>  wrote:
>> On 08/18/2011 09:57 AM, JJ Ding wrote:
>>>
>>>    	return PSMOUSE_FULL_PACKET;
>>> +
>>> + bad_packet:
>> You may introduce space here.
> Sorry, I am following you here.
> Do you want me to add one more line below bad_packet:,
> or you want me to remove the space before bad_packet?
>
> I keep that space to make the goto tags look consistent with other
> places in this file.
>
> Should I remove all starting spaces in goto tags in the file?
>
> Thanks,
>
> jj

aha, I see that some with space but some without.
Now, I'm not sure....;)

Thanks
-Wanlong Gao
>
>>> +	memmove(psmouse->packet, psmouse->packet + 1, psmouse->pktsize - 1);
>>> +	psmouse->pktcnt--;
>>> +	return PSMOUSE_GOOD_DATA;
>>>    }
>>>
>>>    /*
>>
>>
>> --
>> Thanks
>> Wanlong Gao
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 3/6] Input: elantech - packet checking for v2 hardware
  2011-08-18  6:38   ` Dmitry Torokhov
@ 2011-08-18  7:31     ` JJ Ding
  2011-08-18  7:52       ` Dmitry Torokhov
  0 siblings, 1 reply; 90+ messages in thread
From: JJ Ding @ 2011-08-18  7:31 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Hi Dmitry,

On Wed, 17 Aug 2011 23:38:18 -0700, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> On Thu, Aug 18, 2011 at 09:57:06AM +0800, JJ Ding wrote:
> > For v2 hardware, there is no real parity check, but we can still check
> > some constant bits for data integrity.
> > 
> > Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
> > ---
> >  drivers/input/mouse/elantech.c |   26 +++++++++++++++++++++++---
> >  1 files changed, 23 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> > index cf41f23..032181c 100644
> > --- a/drivers/input/mouse/elantech.c
> > +++ b/drivers/input/mouse/elantech.c
> > @@ -376,6 +376,25 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
> >  	       etd->parity[packet[3]] == p3;
> >  }
> >  
> > +static int packet_simple_check_v2(struct psmouse *psmouse)
> > +{
> > +	struct elantech_data *etd = psmouse->private;
> > +	unsigned char *packet = psmouse->packet;
> > +
> > +	if (etd->reports_pressure)
> > +		return (packet[0] & 0x0c) == 0x04 &&
> > +		       (packet[3] & 0x0f) == 0x02;
        this is for newer v2 hardware

> > +
> > +	if ((packet[0] & 0xc0) == 0x80)
> > +		return (packet[0] & 0x0c) == 0x0c &&
> > +		       (packet[3] & 0x0e) == 0x08;
        this is for older v2, two finger touch 

> > +
> > +	return (packet[0] & 0x3c) == 0x3c &&
> > +	       (packet[1] & 0xf0) == 0x00 &&
> > +	       (packet[3] & 0x3e) == 0x38 &&
> > +	       (packet[4] & 0xf0) == 0x00;
        this is for older v2, 1/3 finger touch
      
> 
> Can we please spell out the assumptions under which we decide that
> packet is invalid?
> 
> Thanks.
> 
> -- 
> Dmitry
V2 hardware has two flavors. Older ones that do not report pressure,
and newer ones that reports pressure and width.

With newer ones, all packets (1, 2, 3 finger touch) have the same
constant bits.

With older ones, 1/3 finger touch packets and 2 finger touch packets have
different constant bits.

With all three cases, if the constant bits are not exactly what I
expected, I consider them invalid.

Dmitry, how do you want me to improve this? not enough comments?

Thanks
jj
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 5/6] Input: elantech - clean up elantech_init
  2011-08-18  6:00         ` Dmitry Torokhov
@ 2011-08-18  7:44           ` JJ Ding
  0 siblings, 0 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  7:44 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: gaowanlong, Daniel Kurtz, linux-input, linux-kernel,
	Seth Forshee, Aaron Huang, Tom Lin, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Hi Dmitry,

On Wed, 17 Aug 2011 23:00:38 -0700, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> On Thu, Aug 18, 2011 at 01:35:55PM +0800, JJ Ding wrote:
> > Hi Wanlong Gao, Daniel,
> > 
> > On Thu, 18 Aug 2011 11:08:08 +0800, Wanlong Gao <gaowanlong@cn.fujitsu.com> wrote:
> > > On 08/18/2011 11:04 AM, Daniel Kurtz wrote:
> > > >
> > > > Assuming paritycheck goes away:
> > > Agree.
> > I thought about removing it, too. But it occured to me that v1 and v2
> > hardware can still have the sysfs entry to turn off parity check.
> > 
> > And since it's exposed in sysfs, I suppose there might be some init
> > scripts relying on it.
> > 
> > What do you think, Dmitry?
> > Shall I remove it?
> 
> No, we should not remove it, since it is useful for V1 hardware which we
> still support.
> 
> How confident are we in the V2/V3 checking not tripping on valid packets?
> 
> Thanks.
With V2 it should work reasonbaly well. Although I don't have test data,
I didn't encounter any problem turning paritycheck off when testing V2.

With V3 we use the check to distinguish first 2-finger packet and the
second one. So it's mandatory with V3.

Thanks
jj
> -- 
> Dmitry
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-08-18  1:57 ` [PATCH 2/6] Input: elantech - use firmware provided x, y ranges JJ Ding
  2011-08-18  2:44   ` Daniel Kurtz
@ 2011-08-18  7:47   ` Dmitry Torokhov
  2011-08-19  9:47     ` JJ Ding
  2011-09-01 18:26     ` Chase Douglas
  1 sibling, 2 replies; 90+ messages in thread
From: Dmitry Torokhov @ 2011-08-18  7:47 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
> +
> +		i = (etd->fw_version > 0x020800 &&
> +		     etd->fw_version < 0x020900) ? 1 : 2;
> +		*x_max = (etd->capabilities[1] - i) * 64;
> +		*y_max = (etd->capabilities[2] - i) * 64;
> +		*y_2ft_max = (*y_max - i) * 64 / 4;

Hmm, we should have the same range for ST and MT data and scale MT data
if it has lower resolution to match ST.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  6:06               ` Wanlong Gao
@ 2011-08-18  7:49                 ` Tom _Lin
  0 siblings, 0 replies; 90+ messages in thread
From: Tom _Lin @ 2011-08-18  7:49 UTC (permalink / raw)
  To: jj_ding
  Cc: Daniel Kurtz, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Eric Piel, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini, gaowanlong

Hi JJ
On Thu, 2011-08-18 at 14:06 +0800, Wanlong Gao wrote:
> On 08/18/2011 02:01 PM, Daniel Kurtz wrote:
> > On Thu, Aug 18, 2011 at 1:44 PM, Wanlong Gao<gaowanlong@cn.fujitsu.com>  wrote:
> >> On 08/18/2011 01:34 PM, Daniel Kurtz wrote:
> >>>
> >>> On Thu, Aug 18, 2011 at 1:31 PM, Wanlong Gao<gaowanlong@cn.fujitsu.com>
> >>>   wrote:
> >>>>
> >>>> On 08/18/2011 01:26 PM, JJ Ding wrote:
> >>>>>
> >>>>> Hi Wanlong Gao,
> >>>>>
> >>>>> On Thu, 18 Aug 2011 11:01:52 +0800, Wanlong
> >>>>> Gao<gaowanlong@cn.fujitsu.com>
> >>>>>   wrote:
> >>>>>>
> >>>>>> On 08/18/2011 09:57 AM, JJ Ding wrote:
> >>>>>>>
> >>>>>>> v3 hardware's packet format is almost identical to v2 (one/three
> >>>>>>> finger
> >>>>>>> touch),
> >>>>>>> except when sensing two finger touch, the hardware sends 12 bytes of
> >>>>>>> data.
> >>>>>>>
> >>>>>>> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
> >>>>>>> ---
> >>>>>>>    Documentation/input/elantech.txt |  104 ++++++++++++++++--
> >>>>>>>    drivers/input/mouse/elantech.c   |  218
> >>>>>>> ++++++++++++++++++++++++++++++++++---
> >>>>>>>    drivers/input/mouse/elantech.h   |   11 ++
> >>>>>>>    3 files changed, 303 insertions(+), 30 deletions(-)
> >>>>>>>
> >>>>>>> +static int determine_packet_v3(struct psmouse *psmouse)
> >>>>>>
> >>>>>> elantech_check_parity_v1
> >>>>>> packet_simple_check_v2
> >>>>>> determine_packet_v3
> >>>>>>
> >>>>>> Why not consistent them?
> >>>>>
> >>>>> OK, how do these names sound to you?
> >>>>>
> >>>>> elantech_check_parity_v1
> >>>>> elantech_packet_check_v2
> >>>>> elantech_packet_check_v3
> >>>>>
> >>>>> Thanks,
> >>>>> jj
> >>>>
> >>>> Yeah, sounds perfectly.
> >>>
> >>> Or just:
> >>>
> >>> elantech_packet_check_v1
> >>> elantech_packet_check_v2
> >>> elantech_packet_check_v3
I prefer this way. 
> >>>
> >>> :)
> >>
> >> Hmm... maybe they can go into an elantech_packet_check()?
> >> like:
> >> case 1:
> >>         ...
> >> case 2:
> >>         ...
> >> What do you think? ;)
> >>
> >> Thanks
> >> -Wanlong Gao
> >
> > Since we've already parsed the hardware type at this point, it seems
> > inefficient to parse it again inside another function.
> > I would prefer individual functions.
> >
> > Thanks,
> > -Daniel
> >
> 
> Yeah, It makes sense.
> 
> Thanks
> -Wanlong Gao
> 

Thanks
-TomLin


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 3/6] Input: elantech - packet checking for v2 hardware
  2011-08-18  7:31     ` JJ Ding
@ 2011-08-18  7:52       ` Dmitry Torokhov
  2011-08-18  8:06         ` JJ Ding
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry Torokhov @ 2011-08-18  7:52 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 03:31:27PM +0800, JJ Ding wrote:
> Hi Dmitry,
> 
> On Wed, 17 Aug 2011 23:38:18 -0700, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> > On Thu, Aug 18, 2011 at 09:57:06AM +0800, JJ Ding wrote:
> > > For v2 hardware, there is no real parity check, but we can still check
> > > some constant bits for data integrity.
> > > 
> > > Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
> > > ---
> > >  drivers/input/mouse/elantech.c |   26 +++++++++++++++++++++++---
> > >  1 files changed, 23 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> > > index cf41f23..032181c 100644
> > > --- a/drivers/input/mouse/elantech.c
> > > +++ b/drivers/input/mouse/elantech.c
> > > @@ -376,6 +376,25 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
> > >  	       etd->parity[packet[3]] == p3;
> > >  }
> > >  
> > > +static int packet_simple_check_v2(struct psmouse *psmouse)
> > > +{
> > > +	struct elantech_data *etd = psmouse->private;
> > > +	unsigned char *packet = psmouse->packet;
> > > +
> > > +	if (etd->reports_pressure)
> > > +		return (packet[0] & 0x0c) == 0x04 &&
> > > +		       (packet[3] & 0x0f) == 0x02;
>         this is for newer v2 hardware
> 
> > > +
> > > +	if ((packet[0] & 0xc0) == 0x80)
> > > +		return (packet[0] & 0x0c) == 0x0c &&
> > > +		       (packet[3] & 0x0e) == 0x08;
>         this is for older v2, two finger touch 
> 
> > > +
> > > +	return (packet[0] & 0x3c) == 0x3c &&
> > > +	       (packet[1] & 0xf0) == 0x00 &&
> > > +	       (packet[3] & 0x3e) == 0x38 &&
> > > +	       (packet[4] & 0xf0) == 0x00;
>         this is for older v2, 1/3 finger touch
>       
> > 
> > Can we please spell out the assumptions under which we decide that
> > packet is invalid?
> > 
> > Thanks.
> > 
> > -- 
> > Dmitry
> V2 hardware has two flavors. Older ones that do not report pressure,
> and newer ones that reports pressure and width.
> 
> With newer ones, all packets (1, 2, 3 finger touch) have the same
> constant bits.
> 
> With older ones, 1/3 finger touch packets and 2 finger touch packets have
> different constant bits.
> 
> With all three cases, if the constant bits are not exactly what I
> expected, I consider them invalid.
> 
> Dmitry, how do you want me to improve this? not enough comments?

Right, if you could put the above into comments right in the
packet_simple_check_v2() that woudl be great.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 3/6] Input: elantech - packet checking for v2 hardware
  2011-08-18  7:52       ` Dmitry Torokhov
@ 2011-08-18  8:06         ` JJ Ding
  0 siblings, 0 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-18  8:06 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Hi Dmitry,

On Thu, 18 Aug 2011 00:52:26 -0700, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> On Thu, Aug 18, 2011 at 03:31:27PM +0800, JJ Ding wrote:
> > Hi Dmitry,
> > 
> > On Wed, 17 Aug 2011 23:38:18 -0700, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> > > On Thu, Aug 18, 2011 at 09:57:06AM +0800, JJ Ding wrote:
> > > > For v2 hardware, there is no real parity check, but we can still check
> > > > some constant bits for data integrity.
> > > > 
> > > > Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
> > > > ---
> > > >  drivers/input/mouse/elantech.c |   26 +++++++++++++++++++++++---
> > > >  1 files changed, 23 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> > > > index cf41f23..032181c 100644
> > > > --- a/drivers/input/mouse/elantech.c
> > > > +++ b/drivers/input/mouse/elantech.c
> > > > @@ -376,6 +376,25 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
> > > >  	       etd->parity[packet[3]] == p3;
> > > >  }
> > > >  
> > > > +static int packet_simple_check_v2(struct psmouse *psmouse)
> > > > +{
> > > > +	struct elantech_data *etd = psmouse->private;
> > > > +	unsigned char *packet = psmouse->packet;
> > > > +
> > > > +	if (etd->reports_pressure)
> > > > +		return (packet[0] & 0x0c) == 0x04 &&
> > > > +		       (packet[3] & 0x0f) == 0x02;
> >         this is for newer v2 hardware
> > 
> > > > +
> > > > +	if ((packet[0] & 0xc0) == 0x80)
> > > > +		return (packet[0] & 0x0c) == 0x0c &&
> > > > +		       (packet[3] & 0x0e) == 0x08;
> >         this is for older v2, two finger touch 
> > 
> > > > +
> > > > +	return (packet[0] & 0x3c) == 0x3c &&
> > > > +	       (packet[1] & 0xf0) == 0x00 &&
> > > > +	       (packet[3] & 0x3e) == 0x38 &&
> > > > +	       (packet[4] & 0xf0) == 0x00;
> >         this is for older v2, 1/3 finger touch
> >       
> > > 
> > > Can we please spell out the assumptions under which we decide that
> > > packet is invalid?
> > > 
> > > Thanks.
> > > 
> > > -- 
> > > Dmitry
> > V2 hardware has two flavors. Older ones that do not report pressure,
> > and newer ones that reports pressure and width.
> > 
> > With newer ones, all packets (1, 2, 3 finger touch) have the same
> > constant bits.
> > 
> > With older ones, 1/3 finger touch packets and 2 finger touch packets have
> > different constant bits.
> > 
> > With all three cases, if the constant bits are not exactly what I
> > expected, I consider them invalid.
> > 
> > Dmitry, how do you want me to improve this? not enough comments?
> 
> Right, if you could put the above into comments right in the
> packet_simple_check_v2() that woudl be great.
> 
> Thanks.
No problem. I will do that. 
> -- 
> Dmitry
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  1:57 ` [PATCH 6/6] Input: elantech - add v3 hardware support JJ Ding
                     ` (2 preceding siblings ...)
  2011-08-18  3:30   ` Wanlong Gao
@ 2011-08-18 13:58   ` Seth Forshee
  2011-08-18 14:25       ` Seth Forshee
  2011-08-18 17:39   ` Seth Forshee
  2011-08-19 13:03     ` Éric Piel
  5 siblings, 1 reply; 90+ messages in thread
From: Seth Forshee @ 2011-08-18 13:58 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 09:57:09AM +0800, JJ Ding wrote:
> v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> except when sensing two finger touch, the hardware sends 12 bytes of data.

This looks mostly similar in substance to the patch I sent, although
with some good improvements resulting from your better knowledge of the
hardware :)

One suggestion below. I'll test as soon as my build finishes.

> @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
>  		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
>  		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
>  		break;
> +
> +	case 3:
> +		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> +		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> +		/* range of pressure and width is the same as v2 */
> +		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,
> +				     ETP_WMAX_V2, 0, 0);
> +		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> +		input_mt_init_slots(dev, 2);
> +		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> +		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> +		break;

The case 3 code is nearly identical to case 2. How about this?

	case 2:
		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
		/* fall through */

	case 3:
		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
		/* range of pressure and width is the same as v2 */
		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,
				     ETP_WMAX_V2, 0, 0);
		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
		input_mt_init_slots(dev, 2);
		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
		break;

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18 13:58   ` Seth Forshee
@ 2011-08-18 14:25       ` Seth Forshee
  0 siblings, 0 replies; 90+ messages in thread
From: Seth Forshee @ 2011-08-18 14:25 UTC (permalink / raw)
  To: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang,
	Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 08:58:53AM -0500, Seth Forshee wrote:
> The case 3 code is nearly identical to case 2. How about this?
> 
> 	case 2:
> 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
> 		/* fall through */
> 
> 	case 3:
> 		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> 		/* range of pressure and width is the same as v2 */
> 		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,
> 				     ETP_WMAX_V2, 0, 0);
> 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> 		input_mt_init_slots(dev, 2);
> 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> 		break;

Sorry, that should have been:

	case 2:
		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
		/* fall through */

	case 3:
		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
		if (etd->reports_pressure) {
			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,
					     ETP_WMAX_V2, 0, 0);
		}
		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
		input_mt_init_slots(dev, 2);
		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
		break;

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-18 14:25       ` Seth Forshee
  0 siblings, 0 replies; 90+ messages in thread
From: Seth Forshee @ 2011-08-18 14:25 UTC (permalink / raw)
  To: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang

On Thu, Aug 18, 2011 at 08:58:53AM -0500, Seth Forshee wrote:
> The case 3 code is nearly identical to case 2. How about this?
> 
> 	case 2:
> 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
> 		/* fall through */
> 
> 	case 3:
> 		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> 		/* range of pressure and width is the same as v2 */
> 		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,
> 				     ETP_WMAX_V2, 0, 0);
> 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> 		input_mt_init_slots(dev, 2);
> 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> 		break;

Sorry, that should have been:

	case 2:
		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
		/* fall through */

	case 3:
		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
		if (etd->reports_pressure) {
			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,
					     ETP_WMAX_V2, 0, 0);
		}
		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
		input_mt_init_slots(dev, 2);
		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
		break;

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  1:57 ` [PATCH 6/6] Input: elantech - add v3 hardware support JJ Ding
                     ` (3 preceding siblings ...)
  2011-08-18 13:58   ` Seth Forshee
@ 2011-08-18 17:39   ` Seth Forshee
  2011-08-19  8:29     ` JJ Ding
  2011-08-19 13:03     ` Éric Piel
  5 siblings, 1 reply; 90+ messages in thread
From: Seth Forshee @ 2011-08-18 17:39 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Thu, Aug 18, 2011 at 09:57:09AM +0800, JJ Ding wrote:
> @@ -352,6 +374,94 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
>  	input_sync(dev);
>  }
>  
> +/*
> + * firmware tells us there's noise.
> + */
> +static inline int debounce(unsigned int x, unsigned int y)
> +{
> +	return (x == 0xfff) && (y == 0xfff);
> +}

This is problematic in my testing, in two ways.

First, it never actually triggers, because the y values passed to it are
not the raw data from the packets and as such are not 0xfff anymore in
the cases you're trying to detect.

Second, I get these packets with 1 and 2 finger touches on the Samsung
NF310, but you only check it in the 3 finger case.

As a result, I'm getting some reports with negative values for the y
position.

> +
> +/*
> + * Interpret complete data packets and report absolute mode input events for
> + * hardware version 3. (12 byte packets for two fingers)
> + */
> +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> +					int packet_type)
> +{
> +	struct input_dev *dev = psmouse->dev;
> +	struct elantech_data *etd = psmouse->private;
> +	unsigned char *packet = psmouse->packet;
> +	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> +	unsigned int width = 0, pres = 0;
> +
> +	/* byte 0: n1  n0   .   .   .   .   R   L */
> +	fingers = (packet[0] & 0xc0) >> 6;
> +
> +	switch (fingers) {
> +	case 3:
> +	case 1:
> +		/*
> +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
> +		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> +		 */
> +		x1 = ((packet[1] & 0x0f) << 8) | packet[2];
> +		/*
> +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
> +		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> +		 */
> +		y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
> +
> +		if (fingers == 3 && debounce(x1, y1))
> +			return;
> +
> +		break;
> +
> +	case 2:
> +		if (packet_type == PACKET_V3_HEAD) {
> +			/*
> +			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> +			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> +			 */
> +			etd->prev_x = ((packet[1] & 0x0f) << 8) | packet[2];
> +			/*
> +			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> +			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> +			 */
> +			etd->prev_y = etd->y_max -
> +				(((packet[4] & 0x0f) << 8) | packet[5]);
> +			/*
> +			 * wait for next packet
> +			 */
> +			return;
> +		}
> +
> +		/* packet_type == PACKET_V3_TAIL */
> +		x1 = etd->prev_x;
> +		y1 = etd->prev_y;
> +		x2 = ((packet[1] & 0x0f) << 8) | packet[2];
> +		y2 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
> +		break;
> +	}
> +
> +	pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
> +	width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4);
> +
> +	input_report_key(dev, BTN_TOUCH, fingers != 0);
> +	input_report_abs(dev, ABS_X, x1);
> +	input_report_abs(dev, ABS_Y, y1);

You should only report the ABS_[XY] coordinates when fingers != 0. The
xorg synaptics module sees the values reported in that case as
legitimate. This is causing me to see strange behaviors when scrolling
with two-finger drags.

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18 14:25       ` Seth Forshee
@ 2011-08-19  0:15         ` Wanlong Gao
  -1 siblings, 0 replies; 90+ messages in thread
From: Wanlong Gao @ 2011-08-19  0:15 UTC (permalink / raw)
  To: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang,
	Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On 08/18/2011 10:25 PM, Seth Forshee wrote:
> On Thu, Aug 18, 2011 at 08:58:53AM -0500, Seth Forshee wrote:
>> The case 3 code is nearly identical to case 2. How about this?
>>
>> 	case 2:
>> 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
>> 		/* fall through */
>>
>> 	case 3:
>> 		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
>> 		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
>> 		/* range of pressure and width is the same as v2 */
>> 		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,
>> 				     ETP_WMAX_V2, 0, 0);
>> 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
>> 		input_mt_init_slots(dev, 2);
>> 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
>> 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
>> 		break;
>
> Sorry, that should have been:
>
> 	case 2:
> 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
> 		/* fall through */
>
> 	case 3:
> 		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> 		if (etd->reports_pressure) {
> 			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,
> 					     ETP_WMAX_V2, 0, 0);
> 		}
> 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> 		input_mt_init_slots(dev, 2);
> 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> 		break;

simplify, seems good.

Thanks
-Wanlong Gao
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-19  0:15         ` Wanlong Gao
  0 siblings, 0 replies; 90+ messages in thread
From: Wanlong Gao @ 2011-08-19  0:15 UTC (permalink / raw)
  To: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang

On 08/18/2011 10:25 PM, Seth Forshee wrote:
> On Thu, Aug 18, 2011 at 08:58:53AM -0500, Seth Forshee wrote:
>> The case 3 code is nearly identical to case 2. How about this?
>>
>> 	case 2:
>> 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
>> 		/* fall through */
>>
>> 	case 3:
>> 		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
>> 		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
>> 		/* range of pressure and width is the same as v2 */
>> 		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,
>> 				     ETP_WMAX_V2, 0, 0);
>> 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
>> 		input_mt_init_slots(dev, 2);
>> 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
>> 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
>> 		break;
>
> Sorry, that should have been:
>
> 	case 2:
> 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
> 		/* fall through */
>
> 	case 3:
> 		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> 		if (etd->reports_pressure) {
> 			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,
> 					     ETP_WMAX_V2, 0, 0);
> 		}
> 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> 		input_mt_init_slots(dev, 2);
> 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> 		break;

simplify, seems good.

Thanks
-Wanlong Gao
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18 14:25       ` Seth Forshee
@ 2011-08-19  2:23         ` JJ Ding
  -1 siblings, 0 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-19  2:23 UTC (permalink / raw)
  To: Seth Forshee, linux-input, linux-kernel, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Hi Seth,

On Thu, 18 Aug 2011 09:25:00 -0500, Seth Forshee <seth.forshee@canonical.com> wrote:
> On Thu, Aug 18, 2011 at 08:58:53AM -0500, Seth Forshee wrote:
> 
> Sorry, that should have been:
> 
> 	case 2:
> 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
> 		/* fall through */
> 
> 	case 3:
> 		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> 		if (etd->reports_pressure) {
> 			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,
> 					     ETP_WMAX_V2, 0, 0);
> 		}
> 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> 		input_mt_init_slots(dev, 2);
> 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> 		break;
Looks nice, thank you, I will change it.

jj

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-19  2:23         ` JJ Ding
  0 siblings, 0 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-19  2:23 UTC (permalink / raw)
  To: Seth Forshee, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang

Hi Seth,

On Thu, 18 Aug 2011 09:25:00 -0500, Seth Forshee <seth.forshee@canonical.com> wrote:
> On Thu, Aug 18, 2011 at 08:58:53AM -0500, Seth Forshee wrote:
> 
> Sorry, that should have been:
> 
> 	case 2:
> 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
> 		/* fall through */
> 
> 	case 3:
> 		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> 		if (etd->reports_pressure) {
> 			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,
> 					     ETP_WMAX_V2, 0, 0);
> 		}
> 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> 		input_mt_init_slots(dev, 2);
> 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> 		break;
Looks nice, thank you, I will change it.

jj

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18 17:39   ` Seth Forshee
@ 2011-08-19  8:29     ` JJ Ding
  2011-08-19 12:13       ` Seth Forshee
  0 siblings, 1 reply; 90+ messages in thread
From: JJ Ding @ 2011-08-19  8:29 UTC (permalink / raw)
  To: Seth Forshee
  Cc: linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Hi Seth,

On Thu, 18 Aug 2011 12:39:59 -0500, Seth Forshee <seth.forshee@canonical.com> wrote:
> On Thu, Aug 18, 2011 at 09:57:09AM +0800, JJ Ding wrote:
> > @@ -352,6 +374,94 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
> >  	input_sync(dev);
> >  }
> >  
> > +/*
> > + * firmware tells us there's noise.
> > + */
> > +static inline int debounce(unsigned int x, unsigned int y)
> > +{
> > +	return (x == 0xfff) && (y == 0xfff);
> > +}
> 
> This is problematic in my testing, in two ways.
> 
> First, it never actually triggers, because the y values passed to it are
> not the raw data from the packets and as such are not 0xfff anymore in
> the cases you're trying to detect.
> 
> Second, I get these packets with 1 and 2 finger touches on the Samsung
> NF310, but you only check it in the 3 finger case.
> 
> As a result, I'm getting some reports with negative values for the y
> position.
Thank you for reporting this bug.
As for now, the following should fix this issue.
I will correct this in v2.
---
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index e13a719..fa842f7 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -410,11 +410,12 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse,
                 * byte 4:  .   .   .   .  y11 y10 y9  y8
                 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
                 */
-               y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
+               y1 = ((packet[4] & 0x0f) << 8) | packet[5];
 
                if (fingers == 3 && debounce(x1, y1))
                        return;
 
+               y1 = etd->y_max - y1;
                break;
 
        case 2:
---
> > +
> > +/*
> > + * Interpret complete data packets and report absolute mode input events for
> > + * hardware version 3. (12 byte packets for two fingers)
> > + */
> > +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> > +					int packet_type)
> > +{
> > +	struct input_dev *dev = psmouse->dev;
> > +	struct elantech_data *etd = psmouse->private;
> > +	unsigned char *packet = psmouse->packet;
> > +	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> > +	unsigned int width = 0, pres = 0;
> > +
> > +	/* byte 0: n1  n0   .   .   .   .   R   L */
> > +	fingers = (packet[0] & 0xc0) >> 6;
> > +
> > +	switch (fingers) {
> > +	case 3:
> > +	case 1:
> > +		/*
> > +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
> > +		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> > +		 */
> > +		x1 = ((packet[1] & 0x0f) << 8) | packet[2];
> > +		/*
> > +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
> > +		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> > +		 */
> > +		y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
> > +
> > +		if (fingers == 3 && debounce(x1, y1))
> > +			return;
> > +
> > +		break;
> > +
> > +	case 2:
> > +		if (packet_type == PACKET_V3_HEAD) {
> > +			/*
> > +			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> > +			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> > +			 */
> > +			etd->prev_x = ((packet[1] & 0x0f) << 8) | packet[2];
> > +			/*
> > +			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> > +			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> > +			 */
> > +			etd->prev_y = etd->y_max -
> > +				(((packet[4] & 0x0f) << 8) | packet[5]);
> > +			/*
> > +			 * wait for next packet
> > +			 */
> > +			return;
> > +		}
> > +
> > +		/* packet_type == PACKET_V3_TAIL */
> > +		x1 = etd->prev_x;
> > +		y1 = etd->prev_y;
> > +		x2 = ((packet[1] & 0x0f) << 8) | packet[2];
> > +		y2 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
> > +		break;
> > +	}
> > +
> > +	pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
> > +	width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4);
> > +
> > +	input_report_key(dev, BTN_TOUCH, fingers != 0);
> > +	input_report_abs(dev, ABS_X, x1);
> > +	input_report_abs(dev, ABS_Y, y1);
> 
> You should only report the ABS_[XY] coordinates when fingers != 0. The
> xorg synaptics module sees the values reported in that case as
> legitimate. This is causing me to see strange behaviors when scrolling
> with two-finger drags.
AFAIK, though v2 and v3 differ in packet format, they really report the
same data to the userspace. In this version of v3 support, I even try to
make v2 and v3 report all the data in the same sequnce. If you're seeing
this issue, maybe we should do the same with v2?

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-08-18  7:47   ` Dmitry Torokhov
@ 2011-08-19  9:47     ` JJ Ding
  2011-08-19 12:19         ` Éric Piel
  2011-09-01 18:26     ` Chase Douglas
  1 sibling, 1 reply; 90+ messages in thread
From: JJ Ding @ 2011-08-19  9:47 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Hi Dmitry,

Sorry for late reply. I missed this one somehow.

On Thu, 18 Aug 2011 00:47:56 -0700, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
> > +
> > +		i = (etd->fw_version > 0x020800 &&
> > +		     etd->fw_version < 0x020900) ? 1 : 2;
> > +		*x_max = (etd->capabilities[1] - i) * 64;
> > +		*y_max = (etd->capabilities[2] - i) * 64;
> > +		*y_2ft_max = (*y_max - i) * 64 / 4;
> 
> Hmm, we should have the same range for ST and MT data and scale MT data
> if it has lower resolution to match ST.
So I should just remove y_2ft_max and those ETP_2FT_XXXX in elantech.h,
and do the scale in elantech_report_absolute_v2?

If so, I will create another patch for this change.

Is this OK with you?

Thanks.
jj
> Thanks.
> 
> -- 
> Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-19  8:29     ` JJ Ding
@ 2011-08-19 12:13       ` Seth Forshee
  2011-08-19 12:41           ` Éric Piel
  2011-08-22  0:55         ` JJ Ding
  0 siblings, 2 replies; 90+ messages in thread
From: Seth Forshee @ 2011-08-19 12:13 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Fri, Aug 19, 2011 at 04:29:57PM +0800, JJ Ding wrote:
> > You should only report the ABS_[XY] coordinates when fingers != 0. The
> > xorg synaptics module sees the values reported in that case as
> > legitimate. This is causing me to see strange behaviors when scrolling
> > with two-finger drags.
> AFAIK, though v2 and v3 differ in packet format, they really report the
> same data to the userspace. In this version of v3 support, I even try to
> make v2 and v3 report all the data in the same sequnce. If you're seeing
> this issue, maybe we should do the same with v2?

Actually neither v1 nor v2 reports ABS_[XY] unless fingers != 0. In v2
the reporting is in a switch statement on the number of fingers, and 0
is unhandled.

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-08-19  9:47     ` JJ Ding
@ 2011-08-19 12:19         ` Éric Piel
  0 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:19 UTC (permalink / raw)
  To: JJ Ding
  Cc: Dmitry Torokhov, linux-input, linux-kernel, Seth Forshee,
	Aaron Huang, Tom Lin, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Op 19-08-11 11:47, JJ Ding schreef:
> Hi Dmitry,
>
> Sorry for late reply. I missed this one somehow.
>
> On Thu, 18 Aug 2011 00:47:56 -0700, Dmitry Torokhov<dmitry.torokhov@gmail.com>  wrote:
>> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
>>> +
>>> +		i = (etd->fw_version>  0x020800&&
>>> +		     etd->fw_version<  0x020900) ? 1 : 2;
>>> +		*x_max = (etd->capabilities[1] - i) * 64;
>>> +		*y_max = (etd->capabilities[2] - i) * 64;
>>> +		*y_2ft_max = (*y_max - i) * 64 / 4;
>>
>> Hmm, we should have the same range for ST and MT data and scale MT data
>> if it has lower resolution to match ST.
> So I should just remove y_2ft_max and those ETP_2FT_XXXX in elantech.h,
> and do the scale in elantech_report_absolute_v2?
Humm, yes, I think what Dmitry wants is that both ABS_MT_POSITION_Y and 
ABS_Y have the same min and max, and the scaling is done when reading 
the data. However, it seems this already what is being tried to be done, 
excepted that I mess it up in the latest patch set I sent. I just 
noticed it now, sorry :-S

You can see in elantech_report_absolute_v2() in case of 2 fingers:
The part for updating ABS_X, ABS_Y is correct:
  input_report_abs(dev, ABS_X, x1 << 2);
  input_report_abs(dev, ABS_Y, y1 << 2);

But I forgot to do the same for MT:
  elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
That should be:
  elantech_report_semi_mt_data(dev, fingers, x1 << 2, y1 << 2, x2 << 2, 
y2 << 2);

Or, even more clean, just move the shift directly into the computation, 
like:
  y1 = etd->y_max - ((((packet[0] & 0x20) << 3) | packet[2]) << 2);

In such case you can drop completely y_2ft_max, and move the 
input_report_abs() outside of the switch.


In addition, I have a couple of more remarks on this patch:
> +		*x_max = (etd->capabilities[1] - i) * 64;
> +		*y_max = (etd->capabilities[2] - i) * 64;
> +		*y_2ft_max = (*y_max - i) * 64 / 4;
This last line is probably wrong as I think it should be:
  *y_2ft_max = *y_max / 4;

But if you drop y_2ft_max, that shouldn't matter anymore!
> +	case 1:
> +		*x_min = ETP_XMIN_V1;
> +		*y_min = ETP_YMIN_V1;
> +		*x_max = ETP_XMAX_V1;
> +		*y_max = ETP_YMAX_V1;
> +		break;
> +
> +	case 2:
> +		if (etd->fw_version == 0x020800 ||
> +		    etd->fw_version == 0x020b00 ||
> +		    etd->fw_version == 0x020030) {
> +			*x_min = ETP_XMIN_V2;
> +			*y_min = ETP_YMIN_V2;
> +			*x_max = ETP_XMAX_V2;
> +			*y_max = ETP_YMAX_V2;
> +			*y_2ft_max = ETP_2FT_YMAX;
> +			break;
> +		}

Actually these variables are defined as:
#define ETP_YMAX_V2	( 768 - ETP_EDGE_FUZZ_V2)

I'd suggest to remove trying being too clever and remove the 
ETP_EDGE_FUZZ_V2. They should be just the raw resolution of the device. 
Otherwise, they can cause underflow on the Y axis.

Finally, a minor style suggestion, in "case 2:" above, only use one 
single "break;" and put the two part in a complete "if-else" statement, 
with xmin, y_min all explicit. E.g.:
case 2:
	if (etd->fw_version == 0x020800 ||
	    etd->fw_version == 0x020b00 ||
	    etd->fw_version == 0x020030) {
		*x_min = ETP_XMIN_V2;
		*y_min = ETP_YMIN_V2;
		*x_max = ETP_XMAX_V2;
		*y_max = ETP_YMAX_V2;
	} else {
		i = (etd->fw_version > 0x020800 &&
		     etd->fw_version < 0x020900) ? 1 : 2;
		*x_min = 0;
		*y_min = 0;
		*x_max = (etd->capabilities[1] - i) * 64;
		*y_max = (etd->capabilities[2] - i) * 64;
	}
	break;

> If so, I will create another patch for this change.
>
If you could send a new version of this patch with these changes, it'd 
be great :-)

Cheers,
Éric

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
@ 2011-08-19 12:19         ` Éric Piel
  0 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:19 UTC (permalink / raw)
  To: JJ Ding
  Cc: Dmitry Torokhov, linux-input, linux-kernel, Seth Forshee,
	Aaron Huang, Tom Lin, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Op 19-08-11 11:47, JJ Ding schreef:
> Hi Dmitry,
>
> Sorry for late reply. I missed this one somehow.
>
> On Thu, 18 Aug 2011 00:47:56 -0700, Dmitry Torokhov<dmitry.torokhov@gmail.com>  wrote:
>> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
>>> +
>>> +		i = (etd->fw_version>  0x020800&&
>>> +		     etd->fw_version<  0x020900) ? 1 : 2;
>>> +		*x_max = (etd->capabilities[1] - i) * 64;
>>> +		*y_max = (etd->capabilities[2] - i) * 64;
>>> +		*y_2ft_max = (*y_max - i) * 64 / 4;
>>
>> Hmm, we should have the same range for ST and MT data and scale MT data
>> if it has lower resolution to match ST.
> So I should just remove y_2ft_max and those ETP_2FT_XXXX in elantech.h,
> and do the scale in elantech_report_absolute_v2?
Humm, yes, I think what Dmitry wants is that both ABS_MT_POSITION_Y and 
ABS_Y have the same min and max, and the scaling is done when reading 
the data. However, it seems this already what is being tried to be done, 
excepted that I mess it up in the latest patch set I sent. I just 
noticed it now, sorry :-S

You can see in elantech_report_absolute_v2() in case of 2 fingers:
The part for updating ABS_X, ABS_Y is correct:
  input_report_abs(dev, ABS_X, x1 << 2);
  input_report_abs(dev, ABS_Y, y1 << 2);

But I forgot to do the same for MT:
  elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
That should be:
  elantech_report_semi_mt_data(dev, fingers, x1 << 2, y1 << 2, x2 << 2, 
y2 << 2);

Or, even more clean, just move the shift directly into the computation, 
like:
  y1 = etd->y_max - ((((packet[0] & 0x20) << 3) | packet[2]) << 2);

In such case you can drop completely y_2ft_max, and move the 
input_report_abs() outside of the switch.


In addition, I have a couple of more remarks on this patch:
> +		*x_max = (etd->capabilities[1] - i) * 64;
> +		*y_max = (etd->capabilities[2] - i) * 64;
> +		*y_2ft_max = (*y_max - i) * 64 / 4;
This last line is probably wrong as I think it should be:
  *y_2ft_max = *y_max / 4;

But if you drop y_2ft_max, that shouldn't matter anymore!
> +	case 1:
> +		*x_min = ETP_XMIN_V1;
> +		*y_min = ETP_YMIN_V1;
> +		*x_max = ETP_XMAX_V1;
> +		*y_max = ETP_YMAX_V1;
> +		break;
> +
> +	case 2:
> +		if (etd->fw_version == 0x020800 ||
> +		    etd->fw_version == 0x020b00 ||
> +		    etd->fw_version == 0x020030) {
> +			*x_min = ETP_XMIN_V2;
> +			*y_min = ETP_YMIN_V2;
> +			*x_max = ETP_XMAX_V2;
> +			*y_max = ETP_YMAX_V2;
> +			*y_2ft_max = ETP_2FT_YMAX;
> +			break;
> +		}

Actually these variables are defined as:
#define ETP_YMAX_V2	( 768 - ETP_EDGE_FUZZ_V2)

I'd suggest to remove trying being too clever and remove the 
ETP_EDGE_FUZZ_V2. They should be just the raw resolution of the device. 
Otherwise, they can cause underflow on the Y axis.

Finally, a minor style suggestion, in "case 2:" above, only use one 
single "break;" and put the two part in a complete "if-else" statement, 
with xmin, y_min all explicit. E.g.:
case 2:
	if (etd->fw_version == 0x020800 ||
	    etd->fw_version == 0x020b00 ||
	    etd->fw_version == 0x020030) {
		*x_min = ETP_XMIN_V2;
		*y_min = ETP_YMIN_V2;
		*x_max = ETP_XMAX_V2;
		*y_max = ETP_YMAX_V2;
	} else {
		i = (etd->fw_version > 0x020800 &&
		     etd->fw_version < 0x020900) ? 1 : 2;
		*x_min = 0;
		*y_min = 0;
		*x_max = (etd->capabilities[1] - i) * 64;
		*y_max = (etd->capabilities[2] - i) * 64;
	}
	break;

> If so, I will create another patch for this change.
>
If you could send a new version of this patch with these changes, it'd 
be great :-)

Cheers,
Éric
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 1/6] Input: elantech - correct x, y value range for v2 hardware
  2011-08-18  1:57 ` [PATCH 1/6] Input: elantech - correct x, y value range for v2 hardware JJ Ding
@ 2011-08-19 12:20     ` Éric Piel
  0 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:20 UTC (permalink / raw)
  To: JJ Ding, Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini

Op 18-08-11 03:57, JJ Ding schreef:
> x, y values are actually 12-bit long. Also update protocol document to reflect
> the change.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
With patch 2 applied after that, it seems fine.

Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>

Éric
> ---
>   Documentation/input/elantech.txt |    8 ++++----
>   drivers/input/mouse/elantech.c   |    8 ++++----
>   2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt
> index db798af..bce9941 100644
> --- a/Documentation/input/elantech.txt
> +++ b/Documentation/input/elantech.txt
> @@ -389,14 +389,14 @@ byte 0:
>   byte 1:
>
>      bit   7   6   5   4   3   2   1   0
> -	 p7  p6  p5  p4  .  x10 x9  x8
> +	 p7  p6  p5  p4 x11 x10 x9  x8
>
>   byte 2:
>
>      bit   7   6   5   4   3   2   1   0
>   	 x7  x6  x5  x4  x3  x2  x1  x0
>
> -         x10..x0 = absolute x value (horizontal)
> +         x11..x0 = absolute x value (horizontal)
>
>   byte 3:
>
> @@ -420,7 +420,7 @@ byte 3:
>   byte 4:
>
>      bit   7   6   5   4   3   2   1   0
> -        p3  p1  p2  p0   .   .  y9  y8
> +        p3  p1  p2  p0  y11 y10 y9  y8
>
>   	 p7..p0 = pressure (not EF113)
>
> @@ -429,7 +429,7 @@ byte 5:
>      bit   7   6   5   4   3   2   1   0
>           y7  y6  y5  y4  y3  y2  y1  y0
>
> -         y9..y0 = absolute y value (vertical)
> +         y11..y0 = absolute y value (vertical)
>
>
>   4.2.2 Two finger touch
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index 3250356..da161da 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -290,15 +290,15 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
>   		/* pass through... */
>   	case 1:
>   		/*
> -		 * byte 1:  .   .   .   .   .  x10 x9  x8
> +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
>   		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
>   		 */
> -		x1 = ((packet[1]&  0x07)<<  8) | packet[2];
> +		x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
>   		/*
> -		 * byte 4:  .   .   .   .   .   .  y9  y8
> +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
>   		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
>   		 */
> -		y1 = ETP_YMAX_V2 - (((packet[4]&  0x03)<<  8) | packet[5]);
> +		y1 = ETP_YMAX_V2 - (((packet[4]&  0x0f)<<  8) | packet[5]);
>
>   		input_report_abs(dev, ABS_X, x1);
>   		input_report_abs(dev, ABS_Y, y1);


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 1/6] Input: elantech - correct x, y value range for v2 hardware
@ 2011-08-19 12:20     ` Éric Piel
  0 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:20 UTC (permalink / raw)
  To: JJ Ding, Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini

Op 18-08-11 03:57, JJ Ding schreef:
> x, y values are actually 12-bit long. Also update protocol document to reflect
> the change.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
With patch 2 applied after that, it seems fine.

Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>

Éric
> ---
>   Documentation/input/elantech.txt |    8 ++++----
>   drivers/input/mouse/elantech.c   |    8 ++++----
>   2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt
> index db798af..bce9941 100644
> --- a/Documentation/input/elantech.txt
> +++ b/Documentation/input/elantech.txt
> @@ -389,14 +389,14 @@ byte 0:
>   byte 1:
>
>      bit   7   6   5   4   3   2   1   0
> -	 p7  p6  p5  p4  .  x10 x9  x8
> +	 p7  p6  p5  p4 x11 x10 x9  x8
>
>   byte 2:
>
>      bit   7   6   5   4   3   2   1   0
>   	 x7  x6  x5  x4  x3  x2  x1  x0
>
> -         x10..x0 = absolute x value (horizontal)
> +         x11..x0 = absolute x value (horizontal)
>
>   byte 3:
>
> @@ -420,7 +420,7 @@ byte 3:
>   byte 4:
>
>      bit   7   6   5   4   3   2   1   0
> -        p3  p1  p2  p0   .   .  y9  y8
> +        p3  p1  p2  p0  y11 y10 y9  y8
>
>   	 p7..p0 = pressure (not EF113)
>
> @@ -429,7 +429,7 @@ byte 5:
>      bit   7   6   5   4   3   2   1   0
>           y7  y6  y5  y4  y3  y2  y1  y0
>
> -         y9..y0 = absolute y value (vertical)
> +         y11..y0 = absolute y value (vertical)
>
>
>   4.2.2 Two finger touch
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index 3250356..da161da 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -290,15 +290,15 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
>   		/* pass through... */
>   	case 1:
>   		/*
> -		 * byte 1:  .   .   .   .   .  x10 x9  x8
> +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
>   		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
>   		 */
> -		x1 = ((packet[1]&  0x07)<<  8) | packet[2];
> +		x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
>   		/*
> -		 * byte 4:  .   .   .   .   .   .  y9  y8
> +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
>   		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
>   		 */
> -		y1 = ETP_YMAX_V2 - (((packet[4]&  0x03)<<  8) | packet[5]);
> +		y1 = ETP_YMAX_V2 - (((packet[4]&  0x0f)<<  8) | packet[5]);
>
>   		input_report_abs(dev, ABS_X, x1);
>   		input_report_abs(dev, ABS_Y, y1);

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 3/6] Input: elantech - packet checking for v2 hardware
  2011-08-18  1:57 ` [PATCH 3/6] Input: elantech - packet checking for v2 hardware JJ Ding
@ 2011-08-19 12:22     ` Éric Piel
  2011-08-18  6:38   ` Dmitry Torokhov
  2011-08-19 12:22     ` Éric Piel
  2 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:22 UTC (permalink / raw)
  To: JJ Ding, Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini

Op 18-08-11 03:57, JJ Ding schreef:
> For v2 hardware, there is no real parity check, but we can still check
> some constant bits for data integrity.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
If you add some comments, as suggest by Dmitry, it looks perfect :-)

Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>

Éric

> ---
>   drivers/input/mouse/elantech.c |   26 +++++++++++++++++++++++---
>   1 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index cf41f23..032181c 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -376,6 +376,25 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
>   	       etd->parity[packet[3]] == p3;
>   }
>
> +static int packet_simple_check_v2(struct psmouse *psmouse)
> +{
> +	struct elantech_data *etd = psmouse->private;
> +	unsigned char *packet = psmouse->packet;
> +
> +	if (etd->reports_pressure)
> +		return (packet[0]&  0x0c) == 0x04&&
> +		       (packet[3]&  0x0f) == 0x02;
> +
> +	if ((packet[0]&  0xc0) == 0x80)
> +		return (packet[0]&  0x0c) == 0x0c&&
> +		       (packet[3]&  0x0e) == 0x08;
> +
> +	return (packet[0]&  0x3c) == 0x3c&&
> +	       (packet[1]&  0xf0) == 0x00&&
> +	       (packet[3]&  0x3e) == 0x38&&
> +	       (packet[4]&  0xf0) == 0x00;
> +}
> +
>   /*
>    * Process byte stream from mouse and handle complete packets
>    */
> @@ -398,7 +417,9 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>   		break;
>
>   	case 2:
> -		/* We don't know how to check parity in protocol v2 */
> +		if (etd->paritycheck&&  !packet_simple_check_v2(psmouse))
> +			return PSMOUSE_BAD_DATA;
> +
>   		elantech_report_absolute_v2(psmouse);
>   		break;
>   	}
> @@ -799,8 +820,7 @@ int elantech_init(struct psmouse *psmouse)
>   		etd->hw_version = 2;
>   		/* For now show extra debug information */
>   		etd->debug = 1;
> -		/* Don't know how to do parity checking for version 2 */
> -		etd->paritycheck = 0;
> +		etd->paritycheck = 1;
>
>   		if (etd->fw_version>= 0x020800)
>   			etd->reports_pressure = true;


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 3/6] Input: elantech - packet checking for v2 hardware
@ 2011-08-19 12:22     ` Éric Piel
  0 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:22 UTC (permalink / raw)
  To: JJ Ding, Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini

Op 18-08-11 03:57, JJ Ding schreef:
> For v2 hardware, there is no real parity check, but we can still check
> some constant bits for data integrity.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
If you add some comments, as suggest by Dmitry, it looks perfect :-)

Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>

Éric

> ---
>   drivers/input/mouse/elantech.c |   26 +++++++++++++++++++++++---
>   1 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index cf41f23..032181c 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -376,6 +376,25 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
>   	       etd->parity[packet[3]] == p3;
>   }
>
> +static int packet_simple_check_v2(struct psmouse *psmouse)
> +{
> +	struct elantech_data *etd = psmouse->private;
> +	unsigned char *packet = psmouse->packet;
> +
> +	if (etd->reports_pressure)
> +		return (packet[0]&  0x0c) == 0x04&&
> +		       (packet[3]&  0x0f) == 0x02;
> +
> +	if ((packet[0]&  0xc0) == 0x80)
> +		return (packet[0]&  0x0c) == 0x0c&&
> +		       (packet[3]&  0x0e) == 0x08;
> +
> +	return (packet[0]&  0x3c) == 0x3c&&
> +	       (packet[1]&  0xf0) == 0x00&&
> +	       (packet[3]&  0x3e) == 0x38&&
> +	       (packet[4]&  0xf0) == 0x00;
> +}
> +
>   /*
>    * Process byte stream from mouse and handle complete packets
>    */
> @@ -398,7 +417,9 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
>   		break;
>
>   	case 2:
> -		/* We don't know how to check parity in protocol v2 */
> +		if (etd->paritycheck&&  !packet_simple_check_v2(psmouse))
> +			return PSMOUSE_BAD_DATA;
> +
>   		elantech_report_absolute_v2(psmouse);
>   		break;
>   	}
> @@ -799,8 +820,7 @@ int elantech_init(struct psmouse *psmouse)
>   		etd->hw_version = 2;
>   		/* For now show extra debug information */
>   		etd->debug = 1;
> -		/* Don't know how to do parity checking for version 2 */
> -		etd->paritycheck = 0;
> +		etd->paritycheck = 1;
>
>   		if (etd->fw_version>= 0x020800)
>   			etd->reports_pressure = true;

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 5/6] Input: elantech - clean up elantech_init
  2011-08-18  1:57 ` [PATCH 5/6] Input: elantech - clean up elantech_init JJ Ding
@ 2011-08-19 12:29     ` Éric Piel
  2011-08-18  6:34   ` Wanlong Gao
  2011-08-19 12:29     ` Éric Piel
  2 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:29 UTC (permalink / raw)
  To: JJ Ding, Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini

Op 18-08-11 03:57, JJ Ding schreef:
> Group property setting code into elantech_set_properties.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
Looks good.

Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>

Éric
> ---
>   drivers/input/mouse/elantech.c |   69 ++++++++++++++++++++++-----------------
>   1 files changed, 39 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index 7b9b6e5..ddd40eb 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -791,6 +791,42 @@ static int elantech_reconnect(struct psmouse *psmouse)
>   }
>
>   /*
> + * determine hardware version and set some properties according to it.
> + */
> +static void elantech_set_properties(struct elantech_data *etd)
> +{
> +	/*
> +	 * Assume every version greater than 0x020030 is new EeePC style
> +	 * hardware with 6 byte packets, except 0x020600
> +	 */
> +	if (etd->fw_version<  0x020030 || etd->fw_version == 0x020600)
> +		etd->hw_version = 1;
> +	else
> +		etd->hw_version = 2;
> +
> +	/*
> +	 * Turn on packet checking by default.
> +	 */
> +	etd->paritycheck = 1;
> +
> +	/*
> +	 * This firmware suffers from misreporting coordinates when
> +	 * a touch action starts causing the mouse cursor or scrolled page
> +	 * to jump. Enable a workaround.
> +	 */
> +	etd->jumpy_cursor =
> +		(etd->fw_version == 0x020022 || etd->fw_version == 0x020600);
> +
> +	if (etd->hw_version == 2) {
> +		/* For now show extra debug information */
> +		etd->debug = 1;
> +
> +		if (etd->fw_version>= 0x020800)
> +			etd->reports_pressure = true;
> +	}
> +}
> +
> +/*
>    * Initialize the touchpad and create sysfs entries
>    */
>   int elantech_init(struct psmouse *psmouse)
> @@ -816,26 +852,9 @@ int elantech_init(struct psmouse *psmouse)
>   	}
>
>   	etd->fw_version = (param[0]<<  16) | (param[1]<<  8) | param[2];
> -
> -	/*
> -	 * Assume every version greater than this is new EeePC style
> -	 * hardware with 6 byte packets
> -	 */
> -	if (etd->fw_version>= 0x020030) {
> -		etd->hw_version = 2;
> -		/* For now show extra debug information */
> -		etd->debug = 1;
> -		etd->paritycheck = 1;
> -
> -		if (etd->fw_version>= 0x020800)
> -			etd->reports_pressure = true;
> -
> -	} else {
> -		etd->hw_version = 1;
> -		etd->paritycheck = 1;
> -	}
> -
> -	pr_info("assuming hardware version %d, firmware version %d.%d.%d\n",
> +	elantech_set_properties(etd);
> +	pr_info("assuming hardware version %d "
> +		"(with firmware version 0x%02x%02x%02x)\n",
>   		etd->hw_version, param[0], param[1], param[2]);
>
>   	if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY,
> @@ -847,16 +866,6 @@ int elantech_init(struct psmouse *psmouse)
>   		etd->capabilities[0], etd->capabilities[1],
>   		etd->capabilities[2]);
>
> -	/*
> -	 * This firmware suffers from misreporting coordinates when
> -	 * a touch action starts causing the mouse cursor or scrolled page
> -	 * to jump. Enable a workaround.
> -	 */
> -	if (etd->fw_version == 0x020022 || etd->fw_version == 0x020600) {
> -		pr_info("firmware version 2.0.34/2.6.0 detected, enabling jumpy cursor workaround\n");
> -		etd->jumpy_cursor = true;
> -	}
> -
>   	if (elantech_set_absolute_mode(psmouse)) {
>   		pr_err("failed to put touchpad into absolute mode.\n");
>   		goto init_fail;


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 5/6] Input: elantech - clean up elantech_init
@ 2011-08-19 12:29     ` Éric Piel
  0 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:29 UTC (permalink / raw)
  To: JJ Ding, Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Daniel Kurtz, Chase Douglas, Henrik Rydberg, Alessandro Rubini

Op 18-08-11 03:57, JJ Ding schreef:
> Group property setting code into elantech_set_properties.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
Looks good.

Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>

Éric
> ---
>   drivers/input/mouse/elantech.c |   69 ++++++++++++++++++++++-----------------
>   1 files changed, 39 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index 7b9b6e5..ddd40eb 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -791,6 +791,42 @@ static int elantech_reconnect(struct psmouse *psmouse)
>   }
>
>   /*
> + * determine hardware version and set some properties according to it.
> + */
> +static void elantech_set_properties(struct elantech_data *etd)
> +{
> +	/*
> +	 * Assume every version greater than 0x020030 is new EeePC style
> +	 * hardware with 6 byte packets, except 0x020600
> +	 */
> +	if (etd->fw_version<  0x020030 || etd->fw_version == 0x020600)
> +		etd->hw_version = 1;
> +	else
> +		etd->hw_version = 2;
> +
> +	/*
> +	 * Turn on packet checking by default.
> +	 */
> +	etd->paritycheck = 1;
> +
> +	/*
> +	 * This firmware suffers from misreporting coordinates when
> +	 * a touch action starts causing the mouse cursor or scrolled page
> +	 * to jump. Enable a workaround.
> +	 */
> +	etd->jumpy_cursor =
> +		(etd->fw_version == 0x020022 || etd->fw_version == 0x020600);
> +
> +	if (etd->hw_version == 2) {
> +		/* For now show extra debug information */
> +		etd->debug = 1;
> +
> +		if (etd->fw_version>= 0x020800)
> +			etd->reports_pressure = true;
> +	}
> +}
> +
> +/*
>    * Initialize the touchpad and create sysfs entries
>    */
>   int elantech_init(struct psmouse *psmouse)
> @@ -816,26 +852,9 @@ int elantech_init(struct psmouse *psmouse)
>   	}
>
>   	etd->fw_version = (param[0]<<  16) | (param[1]<<  8) | param[2];
> -
> -	/*
> -	 * Assume every version greater than this is new EeePC style
> -	 * hardware with 6 byte packets
> -	 */
> -	if (etd->fw_version>= 0x020030) {
> -		etd->hw_version = 2;
> -		/* For now show extra debug information */
> -		etd->debug = 1;
> -		etd->paritycheck = 1;
> -
> -		if (etd->fw_version>= 0x020800)
> -			etd->reports_pressure = true;
> -
> -	} else {
> -		etd->hw_version = 1;
> -		etd->paritycheck = 1;
> -	}
> -
> -	pr_info("assuming hardware version %d, firmware version %d.%d.%d\n",
> +	elantech_set_properties(etd);
> +	pr_info("assuming hardware version %d "
> +		"(with firmware version 0x%02x%02x%02x)\n",
>   		etd->hw_version, param[0], param[1], param[2]);
>
>   	if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY,
> @@ -847,16 +866,6 @@ int elantech_init(struct psmouse *psmouse)
>   		etd->capabilities[0], etd->capabilities[1],
>   		etd->capabilities[2]);
>
> -	/*
> -	 * This firmware suffers from misreporting coordinates when
> -	 * a touch action starts causing the mouse cursor or scrolled page
> -	 * to jump. Enable a workaround.
> -	 */
> -	if (etd->fw_version == 0x020022 || etd->fw_version == 0x020600) {
> -		pr_info("firmware version 2.0.34/2.6.0 detected, enabling jumpy cursor workaround\n");
> -		etd->jumpy_cursor = true;
> -	}
> -
>   	if (elantech_set_absolute_mode(psmouse)) {
>   		pr_err("failed to put touchpad into absolute mode.\n");
>   		goto init_fail;

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-19 12:13       ` Seth Forshee
@ 2011-08-19 12:41           ` Éric Piel
  2011-08-22  0:55         ` JJ Ding
  1 sibling, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:41 UTC (permalink / raw)
  To: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang,
	Tom Lin, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Op 19-08-11 14:13, Seth Forshee schreef:
> On Fri, Aug 19, 2011 at 04:29:57PM +0800, JJ Ding wrote:
>>> You should only report the ABS_[XY] coordinates when fingers != 0. The
>>> xorg synaptics module sees the values reported in that case as
>>> legitimate. This is causing me to see strange behaviors when scrolling
>>> with two-finger drags.
>> AFAIK, though v2 and v3 differ in packet format, they really report the
>> same data to the userspace. In this version of v3 support, I even try to
>> make v2 and v3 report all the data in the same sequnce. If you're seeing
>> this issue, maybe we should do the same with v2?
>
> Actually neither v1 nor v2 reports ABS_[XY] unless fingers != 0. In v2
> the reporting is in a switch statement on the number of fingers, and 0
> is unhandled.

Yes, in other words, in the case of v1 or v2, the switch(fingers) does 
nothing if fingers == 0.

Maybe you could do put these 3 lines inside a "if (fingers != 0)":
+	input_report_abs(dev, ABS_X, x1);
+	input_report_abs(dev, ABS_Y, y1);
+	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);

Éric

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-19 12:41           ` Éric Piel
  0 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 12:41 UTC (permalink / raw)
  To: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang

Op 19-08-11 14:13, Seth Forshee schreef:
> On Fri, Aug 19, 2011 at 04:29:57PM +0800, JJ Ding wrote:
>>> You should only report the ABS_[XY] coordinates when fingers != 0. The
>>> xorg synaptics module sees the values reported in that case as
>>> legitimate. This is causing me to see strange behaviors when scrolling
>>> with two-finger drags.
>> AFAIK, though v2 and v3 differ in packet format, they really report the
>> same data to the userspace. In this version of v3 support, I even try to
>> make v2 and v3 report all the data in the same sequnce. If you're seeing
>> this issue, maybe we should do the same with v2?
>
> Actually neither v1 nor v2 reports ABS_[XY] unless fingers != 0. In v2
> the reporting is in a switch statement on the number of fingers, and 0
> is unhandled.

Yes, in other words, in the case of v1 or v2, the switch(fingers) does 
nothing if fingers == 0.

Maybe you could do put these 3 lines inside a "if (fingers != 0)":
+	input_report_abs(dev, ABS_X, x1);
+	input_report_abs(dev, ABS_Y, y1);
+	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);

Éric
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-19 12:41           ` Éric Piel
@ 2011-08-19 12:50             ` Seth Forshee
  -1 siblings, 0 replies; 90+ messages in thread
From: Seth Forshee @ 2011-08-19 12:50 UTC (permalink / raw)
  To: Éric Piel
  Cc: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang,
	Tom Lin, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Fri, Aug 19, 2011 at 02:41:01PM +0200, Éric Piel wrote:
> Op 19-08-11 14:13, Seth Forshee schreef:
> >On Fri, Aug 19, 2011 at 04:29:57PM +0800, JJ Ding wrote:
> >>>You should only report the ABS_[XY] coordinates when fingers != 0. The
> >>>xorg synaptics module sees the values reported in that case as
> >>>legitimate. This is causing me to see strange behaviors when scrolling
> >>>with two-finger drags.
> >>AFAIK, though v2 and v3 differ in packet format, they really report the
> >>same data to the userspace. In this version of v3 support, I even try to
> >>make v2 and v3 report all the data in the same sequnce. If you're seeing
> >>this issue, maybe we should do the same with v2?
> >
> >Actually neither v1 nor v2 reports ABS_[XY] unless fingers != 0. In v2
> >the reporting is in a switch statement on the number of fingers, and 0
> >is unhandled.
> 
> Yes, in other words, in the case of v1 or v2, the switch(fingers)
> does nothing if fingers == 0.
> 
> Maybe you could do put these 3 lines inside a "if (fingers != 0)":
> +	input_report_abs(dev, ABS_X, x1);
> +	input_report_abs(dev, ABS_Y, y1);
> +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);

I don't think elantech_report_semi_mt_data() should be moved inside the
condition. It's doing the right thing when fingers is 0.

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-19 12:50             ` Seth Forshee
  0 siblings, 0 replies; 90+ messages in thread
From: Seth Forshee @ 2011-08-19 12:50 UTC (permalink / raw)
  To: Éric Piel
  Cc: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang,
	Tom Lin, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

On Fri, Aug 19, 2011 at 02:41:01PM +0200, Éric Piel wrote:
> Op 19-08-11 14:13, Seth Forshee schreef:
> >On Fri, Aug 19, 2011 at 04:29:57PM +0800, JJ Ding wrote:
> >>>You should only report the ABS_[XY] coordinates when fingers != 0. The
> >>>xorg synaptics module sees the values reported in that case as
> >>>legitimate. This is causing me to see strange behaviors when scrolling
> >>>with two-finger drags.
> >>AFAIK, though v2 and v3 differ in packet format, they really report the
> >>same data to the userspace. In this version of v3 support, I even try to
> >>make v2 and v3 report all the data in the same sequnce. If you're seeing
> >>this issue, maybe we should do the same with v2?
> >
> >Actually neither v1 nor v2 reports ABS_[XY] unless fingers != 0. In v2
> >the reporting is in a switch statement on the number of fingers, and 0
> >is unhandled.
> 
> Yes, in other words, in the case of v1 or v2, the switch(fingers)
> does nothing if fingers == 0.
> 
> Maybe you could do put these 3 lines inside a "if (fingers != 0)":
> +	input_report_abs(dev, ABS_X, x1);
> +	input_report_abs(dev, ABS_Y, y1);
> +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);

I don't think elantech_report_semi_mt_data() should be moved inside the
condition. It's doing the right thing when fingers is 0.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-18  1:57 ` [PATCH 6/6] Input: elantech - add v3 hardware support JJ Ding
@ 2011-08-19 13:03     ` Éric Piel
  2011-08-18  3:01   ` Wanlong Gao
                       ` (4 subsequent siblings)
  5 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 13:03 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Op 18-08-11 03:57, JJ Ding schreef:
> v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> except when sensing two finger touch, the hardware sends 12 bytes of data.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
Hi,
A couple of comments, in line.

:
:
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index ddd40eb..e13a719 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
:
> +/*
> + * Interpret complete data packets and report absolute mode input events for
> + * hardware version 3. (12 byte packets for two fingers)
> + */
> +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> +					int packet_type)
> +{
> +	struct input_dev *dev = psmouse->dev;
> +	struct elantech_data *etd = psmouse->private;
> +	unsigned char *packet = psmouse->packet;
> +	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> +	unsigned int width = 0, pres = 0;
> +
> +	/* byte 0: n1  n0   .   .   .   .   R   L */
> +	fingers = (packet[0]&  0xc0)>>  6;
> +
> +	switch (fingers) {
> +	case 3:
> +	case 1:
> +		/*
> +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
> +		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> +		 */
> +		x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> +		/*
> +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
> +		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> +		 */
> +		y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> +
> +		if (fingers == 3&&  debounce(x1, y1))
> +			return;
> +
> +		break;
> +
> +	case 2:
> +		if (packet_type == PACKET_V3_HEAD) {
> +			/*
> +			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> +			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> +			 */
> +			etd->prev_x = ((packet[1]&  0x0f)<<  8) | packet[2];
> +			/*
> +			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> +			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> +			 */
> +			etd->prev_y = etd->y_max -
> +				(((packet[4]&  0x0f)<<  8) | packet[5]);
> +			/*
> +			 * wait for next packet
> +			 */
> +			return;
> +		}
> +
> +		/* packet_type == PACKET_V3_TAIL */
> +		x1 = etd->prev_x;
> +		y1 = etd->prev_y;
> +		x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
> +		y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> +		break;
> +	}
You actually have three times the same formula, so you could simplify it:

if (fingers !=0 ) {
	/*
	 * byte 1:  .   .   .   .  x11 x10 x9  x8
	 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
	 */
	x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
	/*
	 * byte 4:  .   .   .   .  y11 y10 y9  y8
	 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
	 */
	y1 = ((packet[4]&  0x0f)<<  8) | packet[5];
}

if ((fingers == 3) && debounce(x1, y1))
	return;

if (fingers == 2) {
	if (packet_type == PACKET_V3_HEAD)) {
		/* wait for next packet */
		etd->prev_x = x1;
		etd->prev_y = etd->y_max - y1;
		return;
	} else {
		/* packet_type == PACKET_V3_TAIL */
		x2 = etd->prev_x;
		y2 = etd->prev_y;
	}
}


> +
> +	pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
> +	width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
What about the case of two fingers? Are pressure and width correct for 
both fingers? In that case, maybe it should also be saved from 
PACKET_V3_HEAD.


> +
> +	input_report_key(dev, BTN_TOUCH, fingers != 0);
> +	input_report_abs(dev, ABS_X, x1);
> +	input_report_abs(dev, ABS_Y, y1);
> +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
> +	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
> +	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
> +	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
> +	input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
> +	input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
> +	input_report_abs(dev, ABS_PRESSURE, pres);
> +	input_report_abs(dev, ABS_TOOL_WIDTH, width);
> +
> +	input_sync(dev);
> +}
> +
:
>
>   /*
>    * Set the appropriate event bits for the input subsystem
>    */
> -static void elantech_set_input_params(struct psmouse *psmouse)
> +static int elantech_set_input_params(struct psmouse *psmouse)
>   {
>   	struct input_dev *dev = psmouse->dev;
>   	struct elantech_data *etd = psmouse->private;
>   	unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
>
> -	set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
> +	if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
> +		return -1;
>
>   	__set_bit(EV_KEY, dev->evbit);
>   	__set_bit(EV_ABS, dev->evbit);
> @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
>   		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
>   		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
>   		break;
> +
> +	case 3:
> +		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> +		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> +		/* range of pressure and width is the same as v2 */
> +		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,
> +				     ETP_WMAX_V2, 0, 0);
> +		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
Does v3 have the same limitation in MT about only reporting the edges of 
the bounding box? Or are the two fingers always reported independently? 
If that is so, you can drop this line :-)


> +		input_mt_init_slots(dev, 2);
> +		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> +		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> +		break;
>   	}
>

Cheers,
Éric

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-19 13:03     ` Éric Piel
  0 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 13:03 UTC (permalink / raw)
  To: JJ Ding
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Op 18-08-11 03:57, JJ Ding schreef:
> v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> except when sensing two finger touch, the hardware sends 12 bytes of data.
>
> Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
Hi,
A couple of comments, in line.

:
:
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index ddd40eb..e13a719 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
:
> +/*
> + * Interpret complete data packets and report absolute mode input events for
> + * hardware version 3. (12 byte packets for two fingers)
> + */
> +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> +					int packet_type)
> +{
> +	struct input_dev *dev = psmouse->dev;
> +	struct elantech_data *etd = psmouse->private;
> +	unsigned char *packet = psmouse->packet;
> +	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> +	unsigned int width = 0, pres = 0;
> +
> +	/* byte 0: n1  n0   .   .   .   .   R   L */
> +	fingers = (packet[0]&  0xc0)>>  6;
> +
> +	switch (fingers) {
> +	case 3:
> +	case 1:
> +		/*
> +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
> +		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> +		 */
> +		x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> +		/*
> +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
> +		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> +		 */
> +		y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> +
> +		if (fingers == 3&&  debounce(x1, y1))
> +			return;
> +
> +		break;
> +
> +	case 2:
> +		if (packet_type == PACKET_V3_HEAD) {
> +			/*
> +			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> +			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> +			 */
> +			etd->prev_x = ((packet[1]&  0x0f)<<  8) | packet[2];
> +			/*
> +			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> +			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> +			 */
> +			etd->prev_y = etd->y_max -
> +				(((packet[4]&  0x0f)<<  8) | packet[5]);
> +			/*
> +			 * wait for next packet
> +			 */
> +			return;
> +		}
> +
> +		/* packet_type == PACKET_V3_TAIL */
> +		x1 = etd->prev_x;
> +		y1 = etd->prev_y;
> +		x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
> +		y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> +		break;
> +	}
You actually have three times the same formula, so you could simplify it:

if (fingers !=0 ) {
	/*
	 * byte 1:  .   .   .   .  x11 x10 x9  x8
	 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
	 */
	x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
	/*
	 * byte 4:  .   .   .   .  y11 y10 y9  y8
	 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
	 */
	y1 = ((packet[4]&  0x0f)<<  8) | packet[5];
}

if ((fingers == 3) && debounce(x1, y1))
	return;

if (fingers == 2) {
	if (packet_type == PACKET_V3_HEAD)) {
		/* wait for next packet */
		etd->prev_x = x1;
		etd->prev_y = etd->y_max - y1;
		return;
	} else {
		/* packet_type == PACKET_V3_TAIL */
		x2 = etd->prev_x;
		y2 = etd->prev_y;
	}
}


> +
> +	pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
> +	width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
What about the case of two fingers? Are pressure and width correct for 
both fingers? In that case, maybe it should also be saved from 
PACKET_V3_HEAD.


> +
> +	input_report_key(dev, BTN_TOUCH, fingers != 0);
> +	input_report_abs(dev, ABS_X, x1);
> +	input_report_abs(dev, ABS_Y, y1);
> +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
> +	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
> +	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
> +	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
> +	input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
> +	input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
> +	input_report_abs(dev, ABS_PRESSURE, pres);
> +	input_report_abs(dev, ABS_TOOL_WIDTH, width);
> +
> +	input_sync(dev);
> +}
> +
:
>
>   /*
>    * Set the appropriate event bits for the input subsystem
>    */
> -static void elantech_set_input_params(struct psmouse *psmouse)
> +static int elantech_set_input_params(struct psmouse *psmouse)
>   {
>   	struct input_dev *dev = psmouse->dev;
>   	struct elantech_data *etd = psmouse->private;
>   	unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
>
> -	set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
> +	if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
> +		return -1;
>
>   	__set_bit(EV_KEY, dev->evbit);
>   	__set_bit(EV_ABS, dev->evbit);
> @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
>   		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
>   		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
>   		break;
> +
> +	case 3:
> +		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> +		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> +		/* range of pressure and width is the same as v2 */
> +		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,
> +				     ETP_WMAX_V2, 0, 0);
> +		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
Does v3 have the same limitation in MT about only reporting the edges of 
the bounding box? Or are the two fingers always reported independently? 
If that is so, you can drop this line :-)


> +		input_mt_init_slots(dev, 2);
> +		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> +		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> +		break;
>   	}
>

Cheers,
Éric
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-19 12:50             ` Seth Forshee
@ 2011-08-19 13:39               ` Éric Piel
  -1 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 13:39 UTC (permalink / raw)
  To: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang,
	Tom Lin, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Op 19-08-11 14:50, Seth Forshee schreef:
>>
>> Yes, in other words, in the case of v1 or v2, the switch(fingers)
>> does nothing if fingers == 0.
>>
>> Maybe you could do put these 3 lines inside a "if (fingers != 0)":
>> +	input_report_abs(dev, ABS_X, x1);
>> +	input_report_abs(dev, ABS_Y, y1);
>> +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
>
> I don't think elantech_report_semi_mt_data() should be moved inside the
> condition. It's doing the right thing when fingers is 0.
Oh, right, it already tests for this case :-) My mistake.

Éric

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-19 13:39               ` Éric Piel
  0 siblings, 0 replies; 90+ messages in thread
From: Éric Piel @ 2011-08-19 13:39 UTC (permalink / raw)
  To: JJ Ding, linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang

Op 19-08-11 14:50, Seth Forshee schreef:
>>
>> Yes, in other words, in the case of v1 or v2, the switch(fingers)
>> does nothing if fingers == 0.
>>
>> Maybe you could do put these 3 lines inside a "if (fingers != 0)":
>> +	input_report_abs(dev, ABS_X, x1);
>> +	input_report_abs(dev, ABS_Y, y1);
>> +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
>
> I don't think elantech_report_semi_mt_data() should be moved inside the
> condition. It's doing the right thing when fingers is 0.
Oh, right, it already tests for this case :-) My mistake.

Éric
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-19 12:13       ` Seth Forshee
  2011-08-19 12:41           ` Éric Piel
@ 2011-08-22  0:55         ` JJ Ding
  1 sibling, 0 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-22  0:55 UTC (permalink / raw)
  To: Seth Forshee
  Cc: linux-input, linux-kernel, Dmitry Torokhov, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Chase Douglas, Henrik Rydberg,
	Alessandro Rubini

Hi Seth,

On Fri, 19 Aug 2011 07:13:08 -0500, Seth Forshee <seth.forshee@canonical.com> wrote:
> On Fri, Aug 19, 2011 at 04:29:57PM +0800, JJ Ding wrote:
> > > You should only report the ABS_[XY] coordinates when fingers != 0. The
> > > xorg synaptics module sees the values reported in that case as
> > > legitimate. This is causing me to see strange behaviors when scrolling
> > > with two-finger drags.
> > AFAIK, though v2 and v3 differ in packet format, they really report the
> > same data to the userspace. In this version of v3 support, I even try to
> > make v2 and v3 report all the data in the same sequnce. If you're seeing
> > this issue, maybe we should do the same with v2?
> 
> Actually neither v1 nor v2 reports ABS_[XY] unless fingers != 0. In v2
> the reporting is in a switch statement on the number of fingers, and 0
> is unhandled.
Yes, You are right. Sorry I misread your reply about this. I will fix
this as you suggested.

jj

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-19 13:03     ` Éric Piel
@ 2011-08-22  6:05       ` JJ Ding
  -1 siblings, 0 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-22  6:05 UTC (permalink / raw)
  To: Éric Piel
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Hi Éric,

Thanks for your comments, a few lines below:

On Fri, 19 Aug 2011 15:03:04 +0200, Éric Piel <E.A.B.Piel@tudelft.nl> wrote:
> Op 18-08-11 03:57, JJ Ding schreef:
> > v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> > except when sensing two finger touch, the hardware sends 12 bytes of data.
> >
> > Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
> Hi,
> A couple of comments, in line.
> 
> :
> :
> > diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> > index ddd40eb..e13a719 100644
> > --- a/drivers/input/mouse/elantech.c
> > +++ b/drivers/input/mouse/elantech.c
> :
> > +/*
> > + * Interpret complete data packets and report absolute mode input events for
> > + * hardware version 3. (12 byte packets for two fingers)
> > + */
> > +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> > +					int packet_type)
> > +{
> > +	struct input_dev *dev = psmouse->dev;
> > +	struct elantech_data *etd = psmouse->private;
> > +	unsigned char *packet = psmouse->packet;
> > +	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> > +	unsigned int width = 0, pres = 0;
> > +
> > +	/* byte 0: n1  n0   .   .   .   .   R   L */
> > +	fingers = (packet[0]&  0xc0)>>  6;
> > +
> > +	switch (fingers) {
> > +	case 3:
> > +	case 1:
> > +		/*
> > +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
> > +		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> > +		 */
> > +		x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > +		/*
> > +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
> > +		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> > +		 */
> > +		y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> > +
> > +		if (fingers == 3&&  debounce(x1, y1))
> > +			return;
> > +
> > +		break;
> > +
> > +	case 2:
> > +		if (packet_type == PACKET_V3_HEAD) {
> > +			/*
> > +			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> > +			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> > +			 */
> > +			etd->prev_x = ((packet[1]&  0x0f)<<  8) | packet[2];
> > +			/*
> > +			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> > +			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> > +			 */
> > +			etd->prev_y = etd->y_max -
> > +				(((packet[4]&  0x0f)<<  8) | packet[5]);
> > +			/*
> > +			 * wait for next packet
> > +			 */
> > +			return;
> > +		}
> > +
> > +		/* packet_type == PACKET_V3_TAIL */
> > +		x1 = etd->prev_x;
> > +		y1 = etd->prev_y;
> > +		x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > +		y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> > +		break;
> > +	}
> You actually have three times the same formula, so you could simplify it:
> 
> if (fingers !=0 ) {
> 	/*
> 	 * byte 1:  .   .   .   .  x11 x10 x9  x8
> 	 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> 	 */
> 	x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> 	/*
> 	 * byte 4:  .   .   .   .  y11 y10 y9  y8
> 	 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> 	 */
> 	y1 = ((packet[4]&  0x0f)<<  8) | packet[5];
> }
> 
> if ((fingers == 3) && debounce(x1, y1))
> 	return;
we need one more line here, for fingers != 2 :
y1 = etd->y_max - y1;
> if (fingers == 2) {
> 	if (packet_type == PACKET_V3_HEAD)) {
> 		/* wait for next packet */
> 		etd->prev_x = x1;
> 		etd->prev_y = etd->y_max - y1;
                etd->prev_y = y1;
> 		return;
> 	} else {
> 		/* packet_type == PACKET_V3_TAIL */
> 		x2 = etd->prev_x;
> 		y2 = etd->prev_y;
> 	}
> }
I like this compact version, but it seems to me this is not as straight
forward as the original switch case. I am OK with either. Is there
anyone who has more to say about this?
> 
> > +
> > +	pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
> > +	width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
> What about the case of two fingers? Are pressure and width correct for 
> both fingers? In that case, maybe it should also be saved from 
> PACKET_V3_HEAD.
I am told (by our firmware guy) that pres and width are sent the same
value for two finger touch.
> 
> > +
> > +	input_report_key(dev, BTN_TOUCH, fingers != 0);
> > +	input_report_abs(dev, ABS_X, x1);
> > +	input_report_abs(dev, ABS_Y, y1);
> > +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
> > +	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
> > +	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
> > +	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
> > +	input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
> > +	input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
> > +	input_report_abs(dev, ABS_PRESSURE, pres);
> > +	input_report_abs(dev, ABS_TOOL_WIDTH, width);
> > +
> > +	input_sync(dev);
> > +}
> > +
> :
> >
> >   /*
> >    * Set the appropriate event bits for the input subsystem
> >    */
> > -static void elantech_set_input_params(struct psmouse *psmouse)
> > +static int elantech_set_input_params(struct psmouse *psmouse)
> >   {
> >   	struct input_dev *dev = psmouse->dev;
> >   	struct elantech_data *etd = psmouse->private;
> >   	unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
> >
> > -	set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
> > +	if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
> > +		return -1;
> >
> >   	__set_bit(EV_KEY, dev->evbit);
> >   	__set_bit(EV_ABS, dev->evbit);
> > @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
> >   		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> >   		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> >   		break;
> > +
> > +	case 3:
> > +		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> > +		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> > +		/* range of pressure and width is the same as v2 */
> > +		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,
> > +				     ETP_WMAX_V2, 0, 0);
> > +		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> Does v3 have the same limitation in MT about only reporting the edges of 
> the bounding box? Or are the two fingers always reported independently? 
> If that is so, you can drop this line :-)
I suppose it's the same as v2, but I have to comfirm with our firmware team.
I will ckeck this.
> 
> > +		input_mt_init_slots(dev, 2);
> > +		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> > +		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> > +		break;
> >   	}
> >
> 
> Cheers,
> Éric
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-22  6:05       ` JJ Ding
  0 siblings, 0 replies; 90+ messages in thread
From: JJ Ding @ 2011-08-22  6:05 UTC (permalink / raw)
  To: Éric Piel
  Cc: linux-input, linux-kernel, Seth Forshee, Dmitry Torokhov,
	Aaron Huang, Tom Lin, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Hi Éric,

Thanks for your comments, a few lines below:

On Fri, 19 Aug 2011 15:03:04 +0200, Éric Piel <E.A.B.Piel@tudelft.nl> wrote:
> Op 18-08-11 03:57, JJ Ding schreef:
> > v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> > except when sensing two finger touch, the hardware sends 12 bytes of data.
> >
> > Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
> Hi,
> A couple of comments, in line.
> 
> :
> :
> > diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> > index ddd40eb..e13a719 100644
> > --- a/drivers/input/mouse/elantech.c
> > +++ b/drivers/input/mouse/elantech.c
> :
> > +/*
> > + * Interpret complete data packets and report absolute mode input events for
> > + * hardware version 3. (12 byte packets for two fingers)
> > + */
> > +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> > +					int packet_type)
> > +{
> > +	struct input_dev *dev = psmouse->dev;
> > +	struct elantech_data *etd = psmouse->private;
> > +	unsigned char *packet = psmouse->packet;
> > +	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> > +	unsigned int width = 0, pres = 0;
> > +
> > +	/* byte 0: n1  n0   .   .   .   .   R   L */
> > +	fingers = (packet[0]&  0xc0)>>  6;
> > +
> > +	switch (fingers) {
> > +	case 3:
> > +	case 1:
> > +		/*
> > +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
> > +		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> > +		 */
> > +		x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > +		/*
> > +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
> > +		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> > +		 */
> > +		y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> > +
> > +		if (fingers == 3&&  debounce(x1, y1))
> > +			return;
> > +
> > +		break;
> > +
> > +	case 2:
> > +		if (packet_type == PACKET_V3_HEAD) {
> > +			/*
> > +			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> > +			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> > +			 */
> > +			etd->prev_x = ((packet[1]&  0x0f)<<  8) | packet[2];
> > +			/*
> > +			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> > +			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> > +			 */
> > +			etd->prev_y = etd->y_max -
> > +				(((packet[4]&  0x0f)<<  8) | packet[5]);
> > +			/*
> > +			 * wait for next packet
> > +			 */
> > +			return;
> > +		}
> > +
> > +		/* packet_type == PACKET_V3_TAIL */
> > +		x1 = etd->prev_x;
> > +		y1 = etd->prev_y;
> > +		x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > +		y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> > +		break;
> > +	}
> You actually have three times the same formula, so you could simplify it:
> 
> if (fingers !=0 ) {
> 	/*
> 	 * byte 1:  .   .   .   .  x11 x10 x9  x8
> 	 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> 	 */
> 	x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> 	/*
> 	 * byte 4:  .   .   .   .  y11 y10 y9  y8
> 	 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> 	 */
> 	y1 = ((packet[4]&  0x0f)<<  8) | packet[5];
> }
> 
> if ((fingers == 3) && debounce(x1, y1))
> 	return;
we need one more line here, for fingers != 2 :
y1 = etd->y_max - y1;
> if (fingers == 2) {
> 	if (packet_type == PACKET_V3_HEAD)) {
> 		/* wait for next packet */
> 		etd->prev_x = x1;
> 		etd->prev_y = etd->y_max - y1;
                etd->prev_y = y1;
> 		return;
> 	} else {
> 		/* packet_type == PACKET_V3_TAIL */
> 		x2 = etd->prev_x;
> 		y2 = etd->prev_y;
> 	}
> }
I like this compact version, but it seems to me this is not as straight
forward as the original switch case. I am OK with either. Is there
anyone who has more to say about this?
> 
> > +
> > +	pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
> > +	width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
> What about the case of two fingers? Are pressure and width correct for 
> both fingers? In that case, maybe it should also be saved from 
> PACKET_V3_HEAD.
I am told (by our firmware guy) that pres and width are sent the same
value for two finger touch.
> 
> > +
> > +	input_report_key(dev, BTN_TOUCH, fingers != 0);
> > +	input_report_abs(dev, ABS_X, x1);
> > +	input_report_abs(dev, ABS_Y, y1);
> > +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
> > +	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
> > +	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
> > +	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
> > +	input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
> > +	input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
> > +	input_report_abs(dev, ABS_PRESSURE, pres);
> > +	input_report_abs(dev, ABS_TOOL_WIDTH, width);
> > +
> > +	input_sync(dev);
> > +}
> > +
> :
> >
> >   /*
> >    * Set the appropriate event bits for the input subsystem
> >    */
> > -static void elantech_set_input_params(struct psmouse *psmouse)
> > +static int elantech_set_input_params(struct psmouse *psmouse)
> >   {
> >   	struct input_dev *dev = psmouse->dev;
> >   	struct elantech_data *etd = psmouse->private;
> >   	unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
> >
> > -	set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
> > +	if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
> > +		return -1;
> >
> >   	__set_bit(EV_KEY, dev->evbit);
> >   	__set_bit(EV_ABS, dev->evbit);
> > @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
> >   		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> >   		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> >   		break;
> > +
> > +	case 3:
> > +		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> > +		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> > +		/* range of pressure and width is the same as v2 */
> > +		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,
> > +				     ETP_WMAX_V2, 0, 0);
> > +		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> Does v3 have the same limitation in MT about only reporting the edges of 
> the bounding box? Or are the two fingers always reported independently? 
> If that is so, you can drop this line :-)
I suppose it's the same as v2, but I have to comfirm with our firmware team.
I will ckeck this.
> 
> > +		input_mt_init_slots(dev, 2);
> > +		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> > +		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> > +		break;
> >   	}
> >
> 
> Cheers,
> Éric
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
  2011-08-22  6:05       ` JJ Ding
@ 2011-08-22  7:20         ` Tom _Lin
  -1 siblings, 0 replies; 90+ messages in thread
From: Tom _Lin @ 2011-08-22  7:20 UTC (permalink / raw)
  To: JJ Ding
  Cc: Éric Piel, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Hi JJ
On Mon, 2011-08-22 at 14:05 +0800, JJ Ding wrote:
> Hi Éric,
> 
> Thanks for your comments, a few lines below:
> 
> On Fri, 19 Aug 2011 15:03:04 +0200, Éric Piel <E.A.B.Piel@tudelft.nl> wrote:
> > Op 18-08-11 03:57, JJ Ding schreef:
> > > v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> > > except when sensing two finger touch, the hardware sends 12 bytes of data.
> > >
> > > Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
> > Hi,
> > A couple of comments, in line.
> > 
> > :
> > :
> > > diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> > > index ddd40eb..e13a719 100644
> > > --- a/drivers/input/mouse/elantech.c
> > > +++ b/drivers/input/mouse/elantech.c
> > :
> > > +/*
> > > + * Interpret complete data packets and report absolute mode input events for
> > > + * hardware version 3. (12 byte packets for two fingers)
> > > + */
> > > +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> > > +					int packet_type)
> > > +{
> > > +	struct input_dev *dev = psmouse->dev;
> > > +	struct elantech_data *etd = psmouse->private;
> > > +	unsigned char *packet = psmouse->packet;
> > > +	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> > > +	unsigned int width = 0, pres = 0;
> > > +
> > > +	/* byte 0: n1  n0   .   .   .   .   R   L */
> > > +	fingers = (packet[0]&  0xc0)>>  6;
> > > +
> > > +	switch (fingers) {
> > > +	case 3:
> > > +	case 1:
> > > +		/*
> > > +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
> > > +		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> > > +		 */
> > > +		x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > > +		/*
> > > +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
> > > +		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> > > +		 */
> > > +		y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> > > +
> > > +		if (fingers == 3&&  debounce(x1, y1))
> > > +			return;
> > > +
> > > +		break;
> > > +
> > > +	case 2:
> > > +		if (packet_type == PACKET_V3_HEAD) {
> > > +			/*
> > > +			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> > > +			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> > > +			 */
> > > +			etd->prev_x = ((packet[1]&  0x0f)<<  8) | packet[2];
> > > +			/*
> > > +			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> > > +			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> > > +			 */
> > > +			etd->prev_y = etd->y_max -
> > > +				(((packet[4]&  0x0f)<<  8) | packet[5]);
> > > +			/*
> > > +			 * wait for next packet
> > > +			 */
> > > +			return;
> > > +		}
> > > +
> > > +		/* packet_type == PACKET_V3_TAIL */
> > > +		x1 = etd->prev_x;
> > > +		y1 = etd->prev_y;
> > > +		x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > > +		y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> > > +		break;
> > > +	}
> > You actually have three times the same formula, so you could simplify it:
> > 
> > if (fingers !=0 ) {
> > 	/*
> > 	 * byte 1:  .   .   .   .  x11 x10 x9  x8
> > 	 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> > 	 */
> > 	x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > 	/*
> > 	 * byte 4:  .   .   .   .  y11 y10 y9  y8
> > 	 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> > 	 */
> > 	y1 = ((packet[4]&  0x0f)<<  8) | packet[5];
> > }
> > 
> > if ((fingers == 3) && debounce(x1, y1))
> > 	return;
> we need one more line here, for fingers != 2 :
> y1 = etd->y_max - y1;
> > if (fingers == 2) {
> > 	if (packet_type == PACKET_V3_HEAD)) {
> > 		/* wait for next packet */
> > 		etd->prev_x = x1;
> > 		etd->prev_y = etd->y_max - y1;
>                 etd->prev_y = y1;
> > 		return;
> > 	} else {
> > 		/* packet_type == PACKET_V3_TAIL */
> > 		x2 = etd->prev_x;
> > 		y2 = etd->prev_y;
> > 	}
> > }
> I like this compact version, but it seems to me this is not as straight
> forward as the original switch case. I am OK with either. Is there
> anyone who has more to say about this?
Éric's version is compact but this is not straight forward as original
code and does not improve more performances. Then other versions of
"elantech_report_absolute" also needed to  modify the same style . so I
prefer original style.
> > 
> > > +
> > > +	pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
> > > +	width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
> > What about the case of two fingers? Are pressure and width correct for 
> > both fingers? In that case, maybe it should also be saved from 
> > PACKET_V3_HEAD.
> I am told (by our firmware guy) that pres and width are sent the same
> value for two finger touch.
> > 
> > > +
> > > +	input_report_key(dev, BTN_TOUCH, fingers != 0);
> > > +	input_report_abs(dev, ABS_X, x1);
> > > +	input_report_abs(dev, ABS_Y, y1);
> > > +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
> > > +	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
> > > +	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
> > > +	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
> > > +	input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
> > > +	input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
> > > +	input_report_abs(dev, ABS_PRESSURE, pres);
> > > +	input_report_abs(dev, ABS_TOOL_WIDTH, width);
> > > +
> > > +	input_sync(dev);
> > > +}
> > > +
> > :
> > >
> > >   /*
> > >    * Set the appropriate event bits for the input subsystem
> > >    */
> > > -static void elantech_set_input_params(struct psmouse *psmouse)
> > > +static int elantech_set_input_params(struct psmouse *psmouse)
> > >   {
> > >   	struct input_dev *dev = psmouse->dev;
> > >   	struct elantech_data *etd = psmouse->private;
> > >   	unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
> > >
> > > -	set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
> > > +	if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
> > > +		return -1;
> > >
> > >   	__set_bit(EV_KEY, dev->evbit);
> > >   	__set_bit(EV_ABS, dev->evbit);
> > > @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
> > >   		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> > >   		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> > >   		break;
> > > +
> > > +	case 3:
> > > +		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> > > +		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> > > +		/* range of pressure and width is the same as v2 */
> > > +		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,
> > > +				     ETP_WMAX_V2, 0, 0);
> > > +		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> > Does v3 have the same limitation in MT about only reporting the edges of 
> > the bounding box? Or are the two fingers always reported independently? 
> > If that is so, you can drop this line :-)
> I suppose it's the same as v2, but I have to comfirm with our firmware team.
> I will ckeck this.
> > 
> > > +		input_mt_init_slots(dev, 2);
> > > +		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> > > +		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> > > +		break;
> > >   	}
> > >
> > 
> > Cheers,
> > Éric
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-input" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 



^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 6/6] Input: elantech - add v3 hardware support
@ 2011-08-22  7:20         ` Tom _Lin
  0 siblings, 0 replies; 90+ messages in thread
From: Tom _Lin @ 2011-08-22  7:20 UTC (permalink / raw)
  To: JJ Ding
  Cc: Éric Piel, linux-input, linux-kernel, Seth Forshee,
	Dmitry Torokhov, Aaron Huang, Daniel Kurtz, Chase Douglas,
	Henrik Rydberg, Alessandro Rubini

Hi JJ
On Mon, 2011-08-22 at 14:05 +0800, JJ Ding wrote:
> Hi Éric,
> 
> Thanks for your comments, a few lines below:
> 
> On Fri, 19 Aug 2011 15:03:04 +0200, Éric Piel <E.A.B.Piel@tudelft.nl> wrote:
> > Op 18-08-11 03:57, JJ Ding schreef:
> > > v3 hardware's packet format is almost identical to v2 (one/three finger touch),
> > > except when sensing two finger touch, the hardware sends 12 bytes of data.
> > >
> > > Signed-off-by: JJ Ding<jj_ding@emc.com.tw>
> > Hi,
> > A couple of comments, in line.
> > 
> > :
> > :
> > > diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> > > index ddd40eb..e13a719 100644
> > > --- a/drivers/input/mouse/elantech.c
> > > +++ b/drivers/input/mouse/elantech.c
> > :
> > > +/*
> > > + * Interpret complete data packets and report absolute mode input events for
> > > + * hardware version 3. (12 byte packets for two fingers)
> > > + */
> > > +static void elantech_report_absolute_v3(struct psmouse *psmouse,
> > > +					int packet_type)
> > > +{
> > > +	struct input_dev *dev = psmouse->dev;
> > > +	struct elantech_data *etd = psmouse->private;
> > > +	unsigned char *packet = psmouse->packet;
> > > +	unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> > > +	unsigned int width = 0, pres = 0;
> > > +
> > > +	/* byte 0: n1  n0   .   .   .   .   R   L */
> > > +	fingers = (packet[0]&  0xc0)>>  6;
> > > +
> > > +	switch (fingers) {
> > > +	case 3:
> > > +	case 1:
> > > +		/*
> > > +		 * byte 1:  .   .   .   .  x11 x10 x9  x8
> > > +		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> > > +		 */
> > > +		x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > > +		/*
> > > +		 * byte 4:  .   .   .   .  y11 y10 y9  y8
> > > +		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> > > +		 */
> > > +		y1 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> > > +
> > > +		if (fingers == 3&&  debounce(x1, y1))
> > > +			return;
> > > +
> > > +		break;
> > > +
> > > +	case 2:
> > > +		if (packet_type == PACKET_V3_HEAD) {
> > > +			/*
> > > +			 * byte 1:   .    .    .    .  ax11 ax10 ax9  ax8
> > > +			 * byte 2: ax7  ax6  ax5  ax4  ax3  ax2  ax1  ax0
> > > +			 */
> > > +			etd->prev_x = ((packet[1]&  0x0f)<<  8) | packet[2];
> > > +			/*
> > > +			 * byte 4:   .    .    .    .  ay11 ay10 ay9  ay8
> > > +			 * byte 5: ay7  ay6  ay5  ay4  ay3  ay2  ay1  ay0
> > > +			 */
> > > +			etd->prev_y = etd->y_max -
> > > +				(((packet[4]&  0x0f)<<  8) | packet[5]);
> > > +			/*
> > > +			 * wait for next packet
> > > +			 */
> > > +			return;
> > > +		}
> > > +
> > > +		/* packet_type == PACKET_V3_TAIL */
> > > +		x1 = etd->prev_x;
> > > +		y1 = etd->prev_y;
> > > +		x2 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > > +		y2 = etd->y_max - (((packet[4]&  0x0f)<<  8) | packet[5]);
> > > +		break;
> > > +	}
> > You actually have three times the same formula, so you could simplify it:
> > 
> > if (fingers !=0 ) {
> > 	/*
> > 	 * byte 1:  .   .   .   .  x11 x10 x9  x8
> > 	 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
> > 	 */
> > 	x1 = ((packet[1]&  0x0f)<<  8) | packet[2];
> > 	/*
> > 	 * byte 4:  .   .   .   .  y11 y10 y9  y8
> > 	 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
> > 	 */
> > 	y1 = ((packet[4]&  0x0f)<<  8) | packet[5];
> > }
> > 
> > if ((fingers == 3) && debounce(x1, y1))
> > 	return;
> we need one more line here, for fingers != 2 :
> y1 = etd->y_max - y1;
> > if (fingers == 2) {
> > 	if (packet_type == PACKET_V3_HEAD)) {
> > 		/* wait for next packet */
> > 		etd->prev_x = x1;
> > 		etd->prev_y = etd->y_max - y1;
>                 etd->prev_y = y1;
> > 		return;
> > 	} else {
> > 		/* packet_type == PACKET_V3_TAIL */
> > 		x2 = etd->prev_x;
> > 		y2 = etd->prev_y;
> > 	}
> > }
> I like this compact version, but it seems to me this is not as straight
> forward as the original switch case. I am OK with either. Is there
> anyone who has more to say about this?
Éric's version is compact but this is not straight forward as original
code and does not improve more performances. Then other versions of
"elantech_report_absolute" also needed to  modify the same style . so I
prefer original style.
> > 
> > > +
> > > +	pres = (packet[1]&  0xf0) | ((packet[4]&  0xf0)>>  4);
> > > +	width = ((packet[0]&  0x30)>>  2) | ((packet[3]&  0x30)>>  4);
> > What about the case of two fingers? Are pressure and width correct for 
> > both fingers? In that case, maybe it should also be saved from 
> > PACKET_V3_HEAD.
> I am told (by our firmware guy) that pres and width are sent the same
> value for two finger touch.
> > 
> > > +
> > > +	input_report_key(dev, BTN_TOUCH, fingers != 0);
> > > +	input_report_abs(dev, ABS_X, x1);
> > > +	input_report_abs(dev, ABS_Y, y1);
> > > +	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
> > > +	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
> > > +	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
> > > +	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
> > > +	input_report_key(dev, BTN_LEFT, packet[0]&  0x01);
> > > +	input_report_key(dev, BTN_RIGHT, packet[0]&  0x02);
> > > +	input_report_abs(dev, ABS_PRESSURE, pres);
> > > +	input_report_abs(dev, ABS_TOOL_WIDTH, width);
> > > +
> > > +	input_sync(dev);
> > > +}
> > > +
> > :
> > >
> > >   /*
> > >    * Set the appropriate event bits for the input subsystem
> > >    */
> > > -static void elantech_set_input_params(struct psmouse *psmouse)
> > > +static int elantech_set_input_params(struct psmouse *psmouse)
> > >   {
> > >   	struct input_dev *dev = psmouse->dev;
> > >   	struct elantech_data *etd = psmouse->private;
> > >   	unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, y_2ft_max = 0;
> > >
> > > -	set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max);
> > > +	if (set_range(psmouse,&x_min,&y_min,&x_max,&y_max,&y_2ft_max))
> > > +		return -1;
> > >
> > >   	__set_bit(EV_KEY, dev->evbit);
> > >   	__set_bit(EV_ABS, dev->evbit);
> > > @@ -582,10 +739,26 @@ static void elantech_set_input_params(struct psmouse *psmouse)
> > >   		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> > >   		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> > >   		break;
> > > +
> > > +	case 3:
> > > +		input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
> > > +		input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
> > > +		/* range of pressure and width is the same as v2 */
> > > +		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,
> > > +				     ETP_WMAX_V2, 0, 0);
> > > +		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
> > Does v3 have the same limitation in MT about only reporting the edges of 
> > the bounding box? Or are the two fingers always reported independently? 
> > If that is so, you can drop this line :-)
> I suppose it's the same as v2, but I have to comfirm with our firmware team.
> I will ckeck this.
> > 
> > > +		input_mt_init_slots(dev, 2);
> > > +		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
> > > +		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
> > > +		break;
> > >   	}
> > >
> > 
> > Cheers,
> > Éric
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-input" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-08-18  7:47   ` Dmitry Torokhov
  2011-08-19  9:47     ` JJ Ding
@ 2011-09-01 18:26     ` Chase Douglas
  2011-09-05  3:22       ` JJ Ding
  1 sibling, 1 reply; 90+ messages in thread
From: Chase Douglas @ 2011-09-01 18:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee, Aaron Huang,
	Tom Lin, Eric Piel, Daniel Kurtz, Henrik Rydberg,
	Alessandro Rubini

On 08/18/2011 12:47 AM, Dmitry Torokhov wrote:
> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
>> +
>> +		i = (etd->fw_version > 0x020800 &&
>> +		     etd->fw_version < 0x020900) ? 1 : 2;
>> +		*x_max = (etd->capabilities[1] - i) * 64;
>> +		*y_max = (etd->capabilities[2] - i) * 64;
>> +		*y_2ft_max = (*y_max - i) * 64 / 4;
> 
> Hmm, we should have the same range for ST and MT data and scale MT data
> if it has lower resolution to match ST.

I saw this go by a while back and it made sense to me at the time.
However, I've had some thoughts that give me pause.

Seth Forshee has been working on getting a semi-mt driver for ALPS
devices. The ALPS devices have an interesting mechanism for providing
multitouch data, but it boils down to having a resolution of only 15
values in the X axis and 11 in the Y axis (it looks possible to
extrapolate and get double the resolution, but my point will remain).

Let's take the X synaptics module as an example of the repercussions of
in-kernel axis scaling. The X synaptics module translates two touch
drags into scroll events. Synaptics will want to use the highest
resolution axis for generating scroll events. If both the MT and ST axes
have the same resolution, it might pick the MT axes for scrolling. On
ALPS devices with in-kernel axis scaling that would be a bad choice.

It's trivial to project the MT and ST axes onto each other in userspace.
I suggest we report the real range and resolution of ST and MT axes
independently.

-- Chase

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-09-01 18:26     ` Chase Douglas
@ 2011-09-05  3:22       ` JJ Ding
  2011-09-06 17:03         ` Chase Douglas
  0 siblings, 1 reply; 90+ messages in thread
From: JJ Ding @ 2011-09-05  3:22 UTC (permalink / raw)
  To: Chase Douglas, Dmitry Torokhov
  Cc: linux-input, linux-kernel, Seth Forshee, Aaron Huang, Tom Lin,
	Eric Piel, Daniel Kurtz, Henrik Rydberg, Alessandro Rubini

Hi Chase,

On Thu, 01 Sep 2011 11:26:32 -0700, Chase Douglas <chase.douglas@canonical.com> wrote:
> On 08/18/2011 12:47 AM, Dmitry Torokhov wrote:
> > On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
> >> +
> >> +		i = (etd->fw_version > 0x020800 &&
> >> +		     etd->fw_version < 0x020900) ? 1 : 2;
> >> +		*x_max = (etd->capabilities[1] - i) * 64;
> >> +		*y_max = (etd->capabilities[2] - i) * 64;
> >> +		*y_2ft_max = (*y_max - i) * 64 / 4;
> > 
> > Hmm, we should have the same range for ST and MT data and scale MT data
> > if it has lower resolution to match ST.
> 
> I saw this go by a while back and it made sense to me at the time.
> However, I've had some thoughts that give me pause.
> 
> Seth Forshee has been working on getting a semi-mt driver for ALPS
> devices. The ALPS devices have an interesting mechanism for providing
> multitouch data, but it boils down to having a resolution of only 15
> values in the X axis and 11 in the Y axis (it looks possible to
> extrapolate and get double the resolution, but my point will remain).
> 
> Let's take the X synaptics module as an example of the repercussions of
> in-kernel axis scaling. The X synaptics module translates two touch
> drags into scroll events. Synaptics will want to use the highest
> resolution axis for generating scroll events. If both the MT and ST axes
> have the same resolution, it might pick the MT axes for scrolling. On
> ALPS devices with in-kernel axis scaling that would be a bad choice.
I don't know about the ALPS devices, but since we already report
ABS_MT_POSITION_{X,Y} with elantech v2, we have to do the scaling in
kernel anyway to adhere to multitouch protocol. So I would say it is
still more appropriate to have the same resolution for ST and MT with
respect to elantech v2. Maybe ALPS should be considered an exception to this?
> It's trivial to project the MT and ST axes onto each other in userspace.
> I suggest we report the real range and resolution of ST and MT axes
> independently.

> -- Chase

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-09-05  3:22       ` JJ Ding
@ 2011-09-06 17:03         ` Chase Douglas
  2011-09-06 17:36           ` Dmitry Torokhov
  0 siblings, 1 reply; 90+ messages in thread
From: Chase Douglas @ 2011-09-06 17:03 UTC (permalink / raw)
  To: JJ Ding
  Cc: Dmitry Torokhov, linux-input, linux-kernel, Seth Forshee,
	Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz, Henrik Rydberg,
	Alessandro Rubini

On 09/04/2011 08:22 PM, JJ Ding wrote:
> Hi Chase,
> 
> On Thu, 01 Sep 2011 11:26:32 -0700, Chase Douglas <chase.douglas@canonical.com> wrote:
>> On 08/18/2011 12:47 AM, Dmitry Torokhov wrote:
>>> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
>>>> +
>>>> +		i = (etd->fw_version > 0x020800 &&
>>>> +		     etd->fw_version < 0x020900) ? 1 : 2;
>>>> +		*x_max = (etd->capabilities[1] - i) * 64;
>>>> +		*y_max = (etd->capabilities[2] - i) * 64;
>>>> +		*y_2ft_max = (*y_max - i) * 64 / 4;
>>>
>>> Hmm, we should have the same range for ST and MT data and scale MT data
>>> if it has lower resolution to match ST.
>>
>> I saw this go by a while back and it made sense to me at the time.
>> However, I've had some thoughts that give me pause.
>>
>> Seth Forshee has been working on getting a semi-mt driver for ALPS
>> devices. The ALPS devices have an interesting mechanism for providing
>> multitouch data, but it boils down to having a resolution of only 15
>> values in the X axis and 11 in the Y axis (it looks possible to
>> extrapolate and get double the resolution, but my point will remain).
>>
>> Let's take the X synaptics module as an example of the repercussions of
>> in-kernel axis scaling. The X synaptics module translates two touch
>> drags into scroll events. Synaptics will want to use the highest
>> resolution axis for generating scroll events. If both the MT and ST axes
>> have the same resolution, it might pick the MT axes for scrolling. On
>> ALPS devices with in-kernel axis scaling that would be a bad choice.
> I don't know about the ALPS devices, but since we already report
> ABS_MT_POSITION_{X,Y} with elantech v2, we have to do the scaling in
> kernel anyway to adhere to multitouch protocol. So I would say it is
> still more appropriate to have the same resolution for ST and MT with
> respect to elantech v2. Maybe ALPS should be considered an exception to this?

The multitouch protocol doesn't require scaling of axes to match, at
least not according to the protocol documentation.

I see that the current code scales the coordinates for v2, but it's only
half-resolution. That's not a huge deal since the resolution of modern
touchpads is very high. We could leave it scaled to not break abi, if
that was a concern. However, with new devices it makes sense to state
the ranges in terms of what the device actually supports. Otherwise,
we're just masking out useful data that userspace could be using.

-- Chase

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-09-06 17:03         ` Chase Douglas
@ 2011-09-06 17:36           ` Dmitry Torokhov
  2011-09-06 18:05             ` Chase Douglas
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry Torokhov @ 2011-09-06 17:36 UTC (permalink / raw)
  To: Chase Douglas
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee, Aaron Huang,
	Tom Lin, Eric Piel, Daniel Kurtz, Henrik Rydberg,
	Alessandro Rubini

On Tue, Sep 06, 2011 at 10:03:05AM -0700, Chase Douglas wrote:
> On 09/04/2011 08:22 PM, JJ Ding wrote:
> > Hi Chase,
> > 
> > On Thu, 01 Sep 2011 11:26:32 -0700, Chase Douglas <chase.douglas@canonical.com> wrote:
> >> On 08/18/2011 12:47 AM, Dmitry Torokhov wrote:
> >>> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
> >>>> +
> >>>> +		i = (etd->fw_version > 0x020800 &&
> >>>> +		     etd->fw_version < 0x020900) ? 1 : 2;
> >>>> +		*x_max = (etd->capabilities[1] - i) * 64;
> >>>> +		*y_max = (etd->capabilities[2] - i) * 64;
> >>>> +		*y_2ft_max = (*y_max - i) * 64 / 4;
> >>>
> >>> Hmm, we should have the same range for ST and MT data and scale MT data
> >>> if it has lower resolution to match ST.
> >>
> >> I saw this go by a while back and it made sense to me at the time.
> >> However, I've had some thoughts that give me pause.
> >>
> >> Seth Forshee has been working on getting a semi-mt driver for ALPS
> >> devices. The ALPS devices have an interesting mechanism for providing
> >> multitouch data, but it boils down to having a resolution of only 15
> >> values in the X axis and 11 in the Y axis (it looks possible to
> >> extrapolate and get double the resolution, but my point will remain).
> >>
> >> Let's take the X synaptics module as an example of the repercussions of
> >> in-kernel axis scaling. The X synaptics module translates two touch
> >> drags into scroll events. Synaptics will want to use the highest
> >> resolution axis for generating scroll events. If both the MT and ST axes
> >> have the same resolution, it might pick the MT axes for scrolling. On
> >> ALPS devices with in-kernel axis scaling that would be a bad choice.
> > I don't know about the ALPS devices, but since we already report
> > ABS_MT_POSITION_{X,Y} with elantech v2, we have to do the scaling in
> > kernel anyway to adhere to multitouch protocol. So I would say it is
> > still more appropriate to have the same resolution for ST and MT with
> > respect to elantech v2. Maybe ALPS should be considered an exception to this?
> 
> The multitouch protocol doesn't require scaling of axes to match, at
> least not according to the protocol documentation.
> 
> I see that the current code scales the coordinates for v2, but it's only
> half-resolution. That's not a huge deal since the resolution of modern
> touchpads is very high. We could leave it scaled to not break abi, if
> that was a concern. However, with new devices it makes sense to state
> the ranges in terms of what the device actually supports. Otherwise,
> we're just masking out useful data that userspace could be using.
> 

I disagree. I believe that ST and MT ranges reported for the same
working surface should match, especially since many devices derive ST
data from MT.

As far as devices that have ranges 0-15 in MT mode - I am not sure how
useful such MT steam anyway and if we are better of just ignore them
(maybe just use the data to report number of fingers on the surface but
otherwise use standard ST protocol).

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-09-06 17:36           ` Dmitry Torokhov
@ 2011-09-06 18:05             ` Chase Douglas
  2011-09-06 18:20               ` Dmitry Torokhov
  2011-09-06 18:47               ` Henrik Rydberg
  0 siblings, 2 replies; 90+ messages in thread
From: Chase Douglas @ 2011-09-06 18:05 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee, Aaron Huang,
	Tom Lin, Eric Piel, Daniel Kurtz, Henrik Rydberg,
	Alessandro Rubini

On 09/06/2011 10:36 AM, Dmitry Torokhov wrote:
> On Tue, Sep 06, 2011 at 10:03:05AM -0700, Chase Douglas wrote:
>> On 09/04/2011 08:22 PM, JJ Ding wrote:
>>> Hi Chase,
>>>
>>> On Thu, 01 Sep 2011 11:26:32 -0700, Chase Douglas <chase.douglas@canonical.com> wrote:
>>>> On 08/18/2011 12:47 AM, Dmitry Torokhov wrote:
>>>>> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
>>>>>> +
>>>>>> +		i = (etd->fw_version > 0x020800 &&
>>>>>> +		     etd->fw_version < 0x020900) ? 1 : 2;
>>>>>> +		*x_max = (etd->capabilities[1] - i) * 64;
>>>>>> +		*y_max = (etd->capabilities[2] - i) * 64;
>>>>>> +		*y_2ft_max = (*y_max - i) * 64 / 4;
>>>>>
>>>>> Hmm, we should have the same range for ST and MT data and scale MT data
>>>>> if it has lower resolution to match ST.
>>>>
>>>> I saw this go by a while back and it made sense to me at the time.
>>>> However, I've had some thoughts that give me pause.
>>>>
>>>> Seth Forshee has been working on getting a semi-mt driver for ALPS
>>>> devices. The ALPS devices have an interesting mechanism for providing
>>>> multitouch data, but it boils down to having a resolution of only 15
>>>> values in the X axis and 11 in the Y axis (it looks possible to
>>>> extrapolate and get double the resolution, but my point will remain).
>>>>
>>>> Let's take the X synaptics module as an example of the repercussions of
>>>> in-kernel axis scaling. The X synaptics module translates two touch
>>>> drags into scroll events. Synaptics will want to use the highest
>>>> resolution axis for generating scroll events. If both the MT and ST axes
>>>> have the same resolution, it might pick the MT axes for scrolling. On
>>>> ALPS devices with in-kernel axis scaling that would be a bad choice.
>>> I don't know about the ALPS devices, but since we already report
>>> ABS_MT_POSITION_{X,Y} with elantech v2, we have to do the scaling in
>>> kernel anyway to adhere to multitouch protocol. So I would say it is
>>> still more appropriate to have the same resolution for ST and MT with
>>> respect to elantech v2. Maybe ALPS should be considered an exception to this?
>>
>> The multitouch protocol doesn't require scaling of axes to match, at
>> least not according to the protocol documentation.
>>
>> I see that the current code scales the coordinates for v2, but it's only
>> half-resolution. That's not a huge deal since the resolution of modern
>> touchpads is very high. We could leave it scaled to not break abi, if
>> that was a concern. However, with new devices it makes sense to state
>> the ranges in terms of what the device actually supports. Otherwise,
>> we're just masking out useful data that userspace could be using.
>>
> 
> I disagree. I believe that ST and MT ranges reported for the same
> working surface should match, especially since many devices derive ST
> data from MT.
> 
> As far as devices that have ranges 0-15 in MT mode - I am not sure how
> useful such MT steam anyway and if we are better of just ignore them
> (maybe just use the data to report number of fingers on the surface but
> otherwise use standard ST protocol).

The MT data could still be useful for pinch to zoom or potentially
rotate (though most low res devices probably are only semi-mt). I don't
want to forsake pinch to zoom just because we can't pass on the
resolution of MT data properly.

-- Chase

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-09-06 18:05             ` Chase Douglas
@ 2011-09-06 18:20               ` Dmitry Torokhov
  2011-09-06 19:29                 ` Chase Douglas
  2011-09-06 18:47               ` Henrik Rydberg
  1 sibling, 1 reply; 90+ messages in thread
From: Dmitry Torokhov @ 2011-09-06 18:20 UTC (permalink / raw)
  To: Chase Douglas
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee, Aaron Huang,
	Tom Lin, Eric Piel, Daniel Kurtz, Henrik Rydberg,
	Alessandro Rubini

On Tue, Sep 06, 2011 at 11:05:11AM -0700, Chase Douglas wrote:
> On 09/06/2011 10:36 AM, Dmitry Torokhov wrote:
> > On Tue, Sep 06, 2011 at 10:03:05AM -0700, Chase Douglas wrote:
> >> On 09/04/2011 08:22 PM, JJ Ding wrote:
> >>> Hi Chase,
> >>>
> >>> On Thu, 01 Sep 2011 11:26:32 -0700, Chase Douglas <chase.douglas@canonical.com> wrote:
> >>>> On 08/18/2011 12:47 AM, Dmitry Torokhov wrote:
> >>>>> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
> >>>>>> +
> >>>>>> +		i = (etd->fw_version > 0x020800 &&
> >>>>>> +		     etd->fw_version < 0x020900) ? 1 : 2;
> >>>>>> +		*x_max = (etd->capabilities[1] - i) * 64;
> >>>>>> +		*y_max = (etd->capabilities[2] - i) * 64;
> >>>>>> +		*y_2ft_max = (*y_max - i) * 64 / 4;
> >>>>>
> >>>>> Hmm, we should have the same range for ST and MT data and scale MT data
> >>>>> if it has lower resolution to match ST.
> >>>>
> >>>> I saw this go by a while back and it made sense to me at the time.
> >>>> However, I've had some thoughts that give me pause.
> >>>>
> >>>> Seth Forshee has been working on getting a semi-mt driver for ALPS
> >>>> devices. The ALPS devices have an interesting mechanism for providing
> >>>> multitouch data, but it boils down to having a resolution of only 15
> >>>> values in the X axis and 11 in the Y axis (it looks possible to
> >>>> extrapolate and get double the resolution, but my point will remain).
> >>>>
> >>>> Let's take the X synaptics module as an example of the repercussions of
> >>>> in-kernel axis scaling. The X synaptics module translates two touch
> >>>> drags into scroll events. Synaptics will want to use the highest
> >>>> resolution axis for generating scroll events. If both the MT and ST axes
> >>>> have the same resolution, it might pick the MT axes for scrolling. On
> >>>> ALPS devices with in-kernel axis scaling that would be a bad choice.
> >>> I don't know about the ALPS devices, but since we already report
> >>> ABS_MT_POSITION_{X,Y} with elantech v2, we have to do the scaling in
> >>> kernel anyway to adhere to multitouch protocol. So I would say it is
> >>> still more appropriate to have the same resolution for ST and MT with
> >>> respect to elantech v2. Maybe ALPS should be considered an exception to this?
> >>
> >> The multitouch protocol doesn't require scaling of axes to match, at
> >> least not according to the protocol documentation.
> >>
> >> I see that the current code scales the coordinates for v2, but it's only
> >> half-resolution. That's not a huge deal since the resolution of modern
> >> touchpads is very high. We could leave it scaled to not break abi, if
> >> that was a concern. However, with new devices it makes sense to state
> >> the ranges in terms of what the device actually supports. Otherwise,
> >> we're just masking out useful data that userspace could be using.
> >>
> > 
> > I disagree. I believe that ST and MT ranges reported for the same
> > working surface should match, especially since many devices derive ST
> > data from MT.
> > 
> > As far as devices that have ranges 0-15 in MT mode - I am not sure how
> > useful such MT steam anyway and if we are better of just ignore them
> > (maybe just use the data to report number of fingers on the surface but
> > otherwise use standard ST protocol).
> 
> The MT data could still be useful for pinch to zoom or potentially
> rotate (though most low res devices probably are only semi-mt). I don't
> want to forsake pinch to zoom just because we can't pass on the
> resolution of MT data properly.

How would userspace know that MT data should only be used for gestures
but nothign else? By examining range? What is the "too small range"
then? It would be different for different devices. I do not want
userspace portions of the drivers to turn into unmanageble collection of
quirks.

Some hardware is just hopeless... And pinch to zoom is cute but hardly
most used function on a laptop (as opposed to phone/tablet), I'd just
leave it be.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-09-06 18:05             ` Chase Douglas
  2011-09-06 18:20               ` Dmitry Torokhov
@ 2011-09-06 18:47               ` Henrik Rydberg
  2011-09-06 18:58                 ` Chase Douglas
  1 sibling, 1 reply; 90+ messages in thread
From: Henrik Rydberg @ 2011-09-06 18:47 UTC (permalink / raw)
  To: Chase Douglas
  Cc: Dmitry Torokhov, JJ Ding, linux-input, linux-kernel,
	Seth Forshee, Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz,
	Alessandro Rubini

> >> I see that the current code scales the coordinates for v2, but it's only
> >> half-resolution. That's not a huge deal since the resolution of modern
> >> touchpads is very high. We could leave it scaled to not break abi, if
> >> that was a concern. However, with new devices it makes sense to state
> >> the ranges in terms of what the device actually supports. Otherwise,
> >> we're just masking out useful data that userspace could be using.
> >>
> > 
> > I disagree. I believe that ST and MT ranges reported for the same
> > working surface should match, especially since many devices derive ST
> > data from MT.
> > 
> > As far as devices that have ranges 0-15 in MT mode - I am not sure how
> > useful such MT steam anyway and if we are better of just ignore them
> > (maybe just use the data to report number of fingers on the surface but
> > otherwise use standard ST protocol).
> 
> The MT data could still be useful for pinch to zoom or potentially
> rotate (though most low res devices probably are only semi-mt). I don't
> want to forsake pinch to zoom just because we can't pass on the
> resolution of MT data properly.

We are not forsaking anything. At best, the detail missed out by using
the same scaling for ST and MT is the ability to distinguish the axis
with the best or poorest resolution. However, some devices report
higher MT than ST resolution, not because it is better (it is indeed
worse), but simply to not lose bits in the filtering process. In other
words: the logic is not without corner cases, and it only makes a
difference to the transitional devices that are not fully MT
capable. If this really was a concern, userspace could use the ST
coordinates for some transformations instead.

Henrik

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-09-06 18:47               ` Henrik Rydberg
@ 2011-09-06 18:58                 ` Chase Douglas
  0 siblings, 0 replies; 90+ messages in thread
From: Chase Douglas @ 2011-09-06 18:58 UTC (permalink / raw)
  To: Henrik Rydberg
  Cc: Dmitry Torokhov, JJ Ding, linux-input, linux-kernel,
	Seth Forshee, Aaron Huang, Tom Lin, Eric Piel, Daniel Kurtz,
	Alessandro Rubini

On 09/06/2011 11:47 AM, Henrik Rydberg wrote:
>>>> I see that the current code scales the coordinates for v2, but it's only
>>>> half-resolution. That's not a huge deal since the resolution of modern
>>>> touchpads is very high. We could leave it scaled to not break abi, if
>>>> that was a concern. However, with new devices it makes sense to state
>>>> the ranges in terms of what the device actually supports. Otherwise,
>>>> we're just masking out useful data that userspace could be using.
>>>>
>>>
>>> I disagree. I believe that ST and MT ranges reported for the same
>>> working surface should match, especially since many devices derive ST
>>> data from MT.
>>>
>>> As far as devices that have ranges 0-15 in MT mode - I am not sure how
>>> useful such MT steam anyway and if we are better of just ignore them
>>> (maybe just use the data to report number of fingers on the surface but
>>> otherwise use standard ST protocol).
>>
>> The MT data could still be useful for pinch to zoom or potentially
>> rotate (though most low res devices probably are only semi-mt). I don't
>> want to forsake pinch to zoom just because we can't pass on the
>> resolution of MT data properly.
> 
> We are not forsaking anything. At best, the detail missed out by using
> the same scaling for ST and MT is the ability to distinguish the axis
> with the best or poorest resolution. However, some devices report
> higher MT than ST resolution, not because it is better (it is indeed
> worse), but simply to not lose bits in the filtering process. In other
> words: the logic is not without corner cases, and it only makes a
> difference to the transitional devices that are not fully MT
> capable. If this really was a concern, userspace could use the ST
> coordinates for some transformations instead.

So what do we want userspace to do? In the absence of supplying this
information we need to provide guidelines. We could say:

* Always use ST coords + finger count for drag gestures (i.e. scrolling)
* Use MT coords for pinch and rotate

If this is acceptable, we should add it to the documentation. Thoughts?

-- Chase

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-09-06 18:20               ` Dmitry Torokhov
@ 2011-09-06 19:29                 ` Chase Douglas
  2011-09-07  2:33                     ` Daniel Kurtz
  0 siblings, 1 reply; 90+ messages in thread
From: Chase Douglas @ 2011-09-06 19:29 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: JJ Ding, linux-input, linux-kernel, Seth Forshee, Aaron Huang,
	Tom Lin, Eric Piel, Daniel Kurtz, Henrik Rydberg,
	Alessandro Rubini

On 09/06/2011 11:20 AM, Dmitry Torokhov wrote:
> On Tue, Sep 06, 2011 at 11:05:11AM -0700, Chase Douglas wrote:
>> On 09/06/2011 10:36 AM, Dmitry Torokhov wrote:
>>> On Tue, Sep 06, 2011 at 10:03:05AM -0700, Chase Douglas wrote:
>>>> On 09/04/2011 08:22 PM, JJ Ding wrote:
>>>>> Hi Chase,
>>>>>
>>>>> On Thu, 01 Sep 2011 11:26:32 -0700, Chase Douglas <chase.douglas@canonical.com> wrote:
>>>>>> On 08/18/2011 12:47 AM, Dmitry Torokhov wrote:
>>>>>>> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
>>>>>>>> +
>>>>>>>> +		i = (etd->fw_version > 0x020800 &&
>>>>>>>> +		     etd->fw_version < 0x020900) ? 1 : 2;
>>>>>>>> +		*x_max = (etd->capabilities[1] - i) * 64;
>>>>>>>> +		*y_max = (etd->capabilities[2] - i) * 64;
>>>>>>>> +		*y_2ft_max = (*y_max - i) * 64 / 4;
>>>>>>>
>>>>>>> Hmm, we should have the same range for ST and MT data and scale MT data
>>>>>>> if it has lower resolution to match ST.
>>>>>>
>>>>>> I saw this go by a while back and it made sense to me at the time.
>>>>>> However, I've had some thoughts that give me pause.
>>>>>>
>>>>>> Seth Forshee has been working on getting a semi-mt driver for ALPS
>>>>>> devices. The ALPS devices have an interesting mechanism for providing
>>>>>> multitouch data, but it boils down to having a resolution of only 15
>>>>>> values in the X axis and 11 in the Y axis (it looks possible to
>>>>>> extrapolate and get double the resolution, but my point will remain).
>>>>>>
>>>>>> Let's take the X synaptics module as an example of the repercussions of
>>>>>> in-kernel axis scaling. The X synaptics module translates two touch
>>>>>> drags into scroll events. Synaptics will want to use the highest
>>>>>> resolution axis for generating scroll events. If both the MT and ST axes
>>>>>> have the same resolution, it might pick the MT axes for scrolling. On
>>>>>> ALPS devices with in-kernel axis scaling that would be a bad choice.
>>>>> I don't know about the ALPS devices, but since we already report
>>>>> ABS_MT_POSITION_{X,Y} with elantech v2, we have to do the scaling in
>>>>> kernel anyway to adhere to multitouch protocol. So I would say it is
>>>>> still more appropriate to have the same resolution for ST and MT with
>>>>> respect to elantech v2. Maybe ALPS should be considered an exception to this?
>>>>
>>>> The multitouch protocol doesn't require scaling of axes to match, at
>>>> least not according to the protocol documentation.
>>>>
>>>> I see that the current code scales the coordinates for v2, but it's only
>>>> half-resolution. That's not a huge deal since the resolution of modern
>>>> touchpads is very high. We could leave it scaled to not break abi, if
>>>> that was a concern. However, with new devices it makes sense to state
>>>> the ranges in terms of what the device actually supports. Otherwise,
>>>> we're just masking out useful data that userspace could be using.
>>>>
>>>
>>> I disagree. I believe that ST and MT ranges reported for the same
>>> working surface should match, especially since many devices derive ST
>>> data from MT.
>>>
>>> As far as devices that have ranges 0-15 in MT mode - I am not sure how
>>> useful such MT steam anyway and if we are better of just ignore them
>>> (maybe just use the data to report number of fingers on the surface but
>>> otherwise use standard ST protocol).
>>
>> The MT data could still be useful for pinch to zoom or potentially
>> rotate (though most low res devices probably are only semi-mt). I don't
>> want to forsake pinch to zoom just because we can't pass on the
>> resolution of MT data properly.
> 
> How would userspace know that MT data should only be used for gestures
> but nothign else? By examining range? What is the "too small range"
> then? It would be different for different devices. I do not want
> userspace portions of the drivers to turn into unmanageble collection of
> quirks.

I wasn't suggesting that it have a big switch that enables or disables
gestures. I just want userspace to be able to figure out whether ST or
MT data would be better for a given task. If the range of the ST and MT
axes could provide this data, then it makes sense to do so. The test
wouldn't be like "is MT range big enough", it would be "is MT range
better than ST or vice versa".

However, Henrik pointed out that some devices report ranges that aren't
representative of how accurate or precise they really are. That
invalidates this approach.

> Some hardware is just hopeless... And pinch to zoom is cute but hardly
> most used function on a laptop (as opposed to phone/tablet), I'd just
> leave it be.

Just because a piece of hardware is imprecise does not mean it is
useless for gestures. Sure, it may not work that great for precision
zooming, but it would be good enough for threshold matching. The Unity
window manager uses these thresholds to fire actions like spread (or
"expose" in OS X terms).

-- Chase

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
  2011-09-06 19:29                 ` Chase Douglas
@ 2011-09-07  2:33                     ` Daniel Kurtz
  0 siblings, 0 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-09-07  2:33 UTC (permalink / raw)
  To: Chase Douglas
  Cc: Dmitry Torokhov, JJ Ding, linux-input, linux-kernel,
	Seth Forshee, Aaron Huang, Tom Lin, Eric Piel, Henrik Rydberg,
	Alessandro Rubini

Hi,

On Wed, Sep 7, 2011 at 3:29 AM, Chase Douglas
<chase.douglas@canonical.com> wrote:
>
> On 09/06/2011 11:20 AM, Dmitry Torokhov wrote:
> > On Tue, Sep 06, 2011 at 11:05:11AM -0700, Chase Douglas wrote:
> >> On 09/06/2011 10:36 AM, Dmitry Torokhov wrote:
> >>> On Tue, Sep 06, 2011 at 10:03:05AM -0700, Chase Douglas wrote:
> >>>> On 09/04/2011 08:22 PM, JJ Ding wrote:
> >>>>> Hi Chase,
> >>>>>
> >>>>> On Thu, 01 Sep 2011 11:26:32 -0700, Chase Douglas <chase.douglas@canonical.com> wrote:
> >>>>>> On 08/18/2011 12:47 AM, Dmitry Torokhov wrote:
> >>>>>>> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
> >>>>>>>> +
> >>>>>>>> +              i = (etd->fw_version > 0x020800 &&
> >>>>>>>> +                   etd->fw_version < 0x020900) ? 1 : 2;
> >>>>>>>> +              *x_max = (etd->capabilities[1] - i) * 64;
> >>>>>>>> +              *y_max = (etd->capabilities[2] - i) * 64;
> >>>>>>>> +              *y_2ft_max = (*y_max - i) * 64 / 4;
> >>>>>>>
> >>>>>>> Hmm, we should have the same range for ST and MT data and scale MT data
> >>>>>>> if it has lower resolution to match ST.
> >>>>>>
> >>>>>> I saw this go by a while back and it made sense to me at the time.
> >>>>>> However, I've had some thoughts that give me pause.
> >>>>>>
> >>>>>> Seth Forshee has been working on getting a semi-mt driver for ALPS
> >>>>>> devices. The ALPS devices have an interesting mechanism for providing
> >>>>>> multitouch data, but it boils down to having a resolution of only 15
> >>>>>> values in the X axis and 11 in the Y axis (it looks possible to
> >>>>>> extrapolate and get double the resolution, but my point will remain).
> >>>>>>
> >>>>>> Let's take the X synaptics module as an example of the repercussions of
> >>>>>> in-kernel axis scaling. The X synaptics module translates two touch
> >>>>>> drags into scroll events. Synaptics will want to use the highest
> >>>>>> resolution axis for generating scroll events. If both the MT and ST axes
> >>>>>> have the same resolution, it might pick the MT axes for scrolling. On
> >>>>>> ALPS devices with in-kernel axis scaling that would be a bad choice.
> >>>>> I don't know about the ALPS devices, but since we already report
> >>>>> ABS_MT_POSITION_{X,Y} with elantech v2, we have to do the scaling in
> >>>>> kernel anyway to adhere to multitouch protocol. So I would say it is
> >>>>> still more appropriate to have the same resolution for ST and MT with
> >>>>> respect to elantech v2. Maybe ALPS should be considered an exception to this?
> >>>>
> >>>> The multitouch protocol doesn't require scaling of axes to match, at
> >>>> least not according to the protocol documentation.
> >>>>
> >>>> I see that the current code scales the coordinates for v2, but it's only
> >>>> half-resolution. That's not a huge deal since the resolution of modern
> >>>> touchpads is very high. We could leave it scaled to not break abi, if
> >>>> that was a concern. However, with new devices it makes sense to state
> >>>> the ranges in terms of what the device actually supports. Otherwise,
> >>>> we're just masking out useful data that userspace could be using.
> >>>>
> >>>
> >>> I disagree. I believe that ST and MT ranges reported for the same
> >>> working surface should match, especially since many devices derive ST
> >>> data from MT.
> >>>
> >>> As far as devices that have ranges 0-15 in MT mode - I am not sure how
> >>> useful such MT steam anyway and if we are better of just ignore them
> >>> (maybe just use the data to report number of fingers on the surface but
> >>> otherwise use standard ST protocol).
> >>
> >> The MT data could still be useful for pinch to zoom or potentially
> >> rotate (though most low res devices probably are only semi-mt). I don't
> >> want to forsake pinch to zoom just because we can't pass on the
> >> resolution of MT data properly.
> >
> > How would userspace know that MT data should only be used for gestures
> > but nothign else? By examining range? What is the "too small range"
> > then? It would be different for different devices. I do not want
> > userspace portions of the drivers to turn into unmanageble collection of
> > quirks.
>
> I wasn't suggesting that it have a big switch that enables or disables
> gestures. I just want userspace to be able to figure out whether ST or
> MT data would be better for a given task. If the range of the ST and MT
> axes could provide this data, then it makes sense to do so. The test
> wouldn't be like "is MT range big enough", it would be "is MT range
> better than ST or vice versa".
>
> However, Henrik pointed out that some devices report ranges that aren't
> representative of how accurate or precise they really are. That
> invalidates this approach.
>
> > Some hardware is just hopeless... And pinch to zoom is cute but hardly
> > most used function on a laptop (as opposed to phone/tablet), I'd just
> > leave it be.
>
> Just because a piece of hardware is imprecise does not mean it is
> useless for gestures. Sure, it may not work that great for precision
> zooming, but it would be good enough for threshold matching. The Unity
> window manager uses these thresholds to fire actions like spread (or
> "expose" in OS X terms).
>
> -- Chase

As far as I can tell, when the pad reports exactly 2 fingers, it
reports them both with half the resolution with which it would report
a single finger (in the 1 finger or 3 fingers cases).

It sounded like Chase was recommending to report "ST" at full
resolution and "MT" at half resolution.  Thus, if there is 1 finger,
we would throw away 1 bit for the MT report.  If there were 2 fingers,
we would inflate the ST reported finger by one bit.

I prefer the original behavior of this patch, which just always
reports ST and MT using the ST scale.

-Daniel

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 2/6] Input: elantech - use firmware provided x, y ranges
@ 2011-09-07  2:33                     ` Daniel Kurtz
  0 siblings, 0 replies; 90+ messages in thread
From: Daniel Kurtz @ 2011-09-07  2:33 UTC (permalink / raw)
  To: Chase Douglas
  Cc: Dmitry Torokhov, JJ Ding, linux-input, linux-kernel,
	Seth Forshee, Aaron Huang, Tom Lin, Eric Piel, Henrik Rydberg,
	Alessandro Rubini

Hi,

On Wed, Sep 7, 2011 at 3:29 AM, Chase Douglas
<chase.douglas@canonical.com> wrote:
>
> On 09/06/2011 11:20 AM, Dmitry Torokhov wrote:
> > On Tue, Sep 06, 2011 at 11:05:11AM -0700, Chase Douglas wrote:
> >> On 09/06/2011 10:36 AM, Dmitry Torokhov wrote:
> >>> On Tue, Sep 06, 2011 at 10:03:05AM -0700, Chase Douglas wrote:
> >>>> On 09/04/2011 08:22 PM, JJ Ding wrote:
> >>>>> Hi Chase,
> >>>>>
> >>>>> On Thu, 01 Sep 2011 11:26:32 -0700, Chase Douglas <chase.douglas@canonical.com> wrote:
> >>>>>> On 08/18/2011 12:47 AM, Dmitry Torokhov wrote:
> >>>>>>> On Thu, Aug 18, 2011 at 09:57:05AM +0800, JJ Ding wrote:
> >>>>>>>> +
> >>>>>>>> +              i = (etd->fw_version > 0x020800 &&
> >>>>>>>> +                   etd->fw_version < 0x020900) ? 1 : 2;
> >>>>>>>> +              *x_max = (etd->capabilities[1] - i) * 64;
> >>>>>>>> +              *y_max = (etd->capabilities[2] - i) * 64;
> >>>>>>>> +              *y_2ft_max = (*y_max - i) * 64 / 4;
> >>>>>>>
> >>>>>>> Hmm, we should have the same range for ST and MT data and scale MT data
> >>>>>>> if it has lower resolution to match ST.
> >>>>>>
> >>>>>> I saw this go by a while back and it made sense to me at the time.
> >>>>>> However, I've had some thoughts that give me pause.
> >>>>>>
> >>>>>> Seth Forshee has been working on getting a semi-mt driver for ALPS
> >>>>>> devices. The ALPS devices have an interesting mechanism for providing
> >>>>>> multitouch data, but it boils down to having a resolution of only 15
> >>>>>> values in the X axis and 11 in the Y axis (it looks possible to
> >>>>>> extrapolate and get double the resolution, but my point will remain).
> >>>>>>
> >>>>>> Let's take the X synaptics module as an example of the repercussions of
> >>>>>> in-kernel axis scaling. The X synaptics module translates two touch
> >>>>>> drags into scroll events. Synaptics will want to use the highest
> >>>>>> resolution axis for generating scroll events. If both the MT and ST axes
> >>>>>> have the same resolution, it might pick the MT axes for scrolling. On
> >>>>>> ALPS devices with in-kernel axis scaling that would be a bad choice.
> >>>>> I don't know about the ALPS devices, but since we already report
> >>>>> ABS_MT_POSITION_{X,Y} with elantech v2, we have to do the scaling in
> >>>>> kernel anyway to adhere to multitouch protocol. So I would say it is
> >>>>> still more appropriate to have the same resolution for ST and MT with
> >>>>> respect to elantech v2. Maybe ALPS should be considered an exception to this?
> >>>>
> >>>> The multitouch protocol doesn't require scaling of axes to match, at
> >>>> least not according to the protocol documentation.
> >>>>
> >>>> I see that the current code scales the coordinates for v2, but it's only
> >>>> half-resolution. That's not a huge deal since the resolution of modern
> >>>> touchpads is very high. We could leave it scaled to not break abi, if
> >>>> that was a concern. However, with new devices it makes sense to state
> >>>> the ranges in terms of what the device actually supports. Otherwise,
> >>>> we're just masking out useful data that userspace could be using.
> >>>>
> >>>
> >>> I disagree. I believe that ST and MT ranges reported for the same
> >>> working surface should match, especially since many devices derive ST
> >>> data from MT.
> >>>
> >>> As far as devices that have ranges 0-15 in MT mode - I am not sure how
> >>> useful such MT steam anyway and if we are better of just ignore them
> >>> (maybe just use the data to report number of fingers on the surface but
> >>> otherwise use standard ST protocol).
> >>
> >> The MT data could still be useful for pinch to zoom or potentially
> >> rotate (though most low res devices probably are only semi-mt). I don't
> >> want to forsake pinch to zoom just because we can't pass on the
> >> resolution of MT data properly.
> >
> > How would userspace know that MT data should only be used for gestures
> > but nothign else? By examining range? What is the "too small range"
> > then? It would be different for different devices. I do not want
> > userspace portions of the drivers to turn into unmanageble collection of
> > quirks.
>
> I wasn't suggesting that it have a big switch that enables or disables
> gestures. I just want userspace to be able to figure out whether ST or
> MT data would be better for a given task. If the range of the ST and MT
> axes could provide this data, then it makes sense to do so. The test
> wouldn't be like "is MT range big enough", it would be "is MT range
> better than ST or vice versa".
>
> However, Henrik pointed out that some devices report ranges that aren't
> representative of how accurate or precise they really are. That
> invalidates this approach.
>
> > Some hardware is just hopeless... And pinch to zoom is cute but hardly
> > most used function on a laptop (as opposed to phone/tablet), I'd just
> > leave it be.
>
> Just because a piece of hardware is imprecise does not mean it is
> useless for gestures. Sure, it may not work that great for precision
> zooming, but it would be good enough for threshold matching. The Unity
> window manager uses these thresholds to fire actions like spread (or
> "expose" in OS X terms).
>
> -- Chase

As far as I can tell, when the pad reports exactly 2 fingers, it
reports them both with half the resolution with which it would report
a single finger (in the 1 finger or 3 fingers cases).

It sounded like Chase was recommending to report "ST" at full
resolution and "MT" at half resolution.  Thus, if there is 1 finger,
we would throw away 1 bit for the MT report.  If there were 2 fingers,
we would inflate the ST reported finger by one bit.

I prefer the original behavior of this patch, which just always
reports ST and MT using the ST scale.

-Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

end of thread, other threads:[~2011-09-07  2:34 UTC | newest]

Thread overview: 90+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-18  1:57 [PATCH 0/6] elantech: add support for newer generation hardware JJ Ding
2011-08-18  1:57 ` [PATCH 1/6] Input: elantech - correct x, y value range for v2 hardware JJ Ding
2011-08-19 12:20   ` Éric Piel
2011-08-19 12:20     ` Éric Piel
2011-08-18  1:57 ` [PATCH 2/6] Input: elantech - use firmware provided x, y ranges JJ Ding
2011-08-18  2:44   ` Daniel Kurtz
2011-08-18  7:47   ` Dmitry Torokhov
2011-08-19  9:47     ` JJ Ding
2011-08-19 12:19       ` Éric Piel
2011-08-19 12:19         ` Éric Piel
2011-09-01 18:26     ` Chase Douglas
2011-09-05  3:22       ` JJ Ding
2011-09-06 17:03         ` Chase Douglas
2011-09-06 17:36           ` Dmitry Torokhov
2011-09-06 18:05             ` Chase Douglas
2011-09-06 18:20               ` Dmitry Torokhov
2011-09-06 19:29                 ` Chase Douglas
2011-09-07  2:33                   ` Daniel Kurtz
2011-09-07  2:33                     ` Daniel Kurtz
2011-09-06 18:47               ` Henrik Rydberg
2011-09-06 18:58                 ` Chase Douglas
2011-08-18  1:57 ` [PATCH 3/6] Input: elantech - packet checking for v2 hardware JJ Ding
2011-08-18  2:49   ` Daniel Kurtz
2011-08-18  6:38   ` Dmitry Torokhov
2011-08-18  7:31     ` JJ Ding
2011-08-18  7:52       ` Dmitry Torokhov
2011-08-18  8:06         ` JJ Ding
2011-08-19 12:22   ` Éric Piel
2011-08-19 12:22     ` Éric Piel
2011-08-18  1:57 ` [PATCH 4/6] Input: elantech - work around EC buffer JJ Ding
2011-08-18  2:50   ` Daniel Kurtz
2011-08-18  3:07   ` Wanlong Gao
2011-08-18  6:48     ` JJ Ding
2011-08-18  6:54       ` Wanlong Gao
2011-08-18  6:39   ` Dmitry Torokhov
2011-08-18  6:54     ` JJ Ding
2011-08-18  1:57 ` [PATCH 5/6] Input: elantech - clean up elantech_init JJ Ding
2011-08-18  3:04   ` Daniel Kurtz
2011-08-18  3:08     ` Wanlong Gao
2011-08-18  5:35       ` JJ Ding
2011-08-18  5:38         ` Wanlong Gao
2011-08-18  6:00         ` Dmitry Torokhov
2011-08-18  7:44           ` JJ Ding
2011-08-18  6:34   ` Wanlong Gao
2011-08-19 12:29   ` Éric Piel
2011-08-19 12:29     ` Éric Piel
2011-08-18  1:57 ` [PATCH 6/6] Input: elantech - add v3 hardware support JJ Ding
2011-08-18  2:57   ` Daniel Kurtz
2011-08-18  3:04     ` Wanlong Gao
2011-08-18  3:09       ` Daniel Kurtz
2011-08-18  3:09         ` Daniel Kurtz
2011-08-18  3:22         ` Wanlong Gao
2011-08-18  5:39     ` JJ Ding
2011-08-18  3:01   ` Wanlong Gao
2011-08-18  5:26     ` JJ Ding
2011-08-18  5:31       ` Wanlong Gao
2011-08-18  5:34         ` Daniel Kurtz
2011-08-18  5:44           ` Wanlong Gao
2011-08-18  6:01             ` Daniel Kurtz
2011-08-18  6:01               ` Daniel Kurtz
2011-08-18  6:06               ` Wanlong Gao
2011-08-18  7:49                 ` Tom _Lin
2011-08-18  3:30   ` Wanlong Gao
2011-08-18  3:47     ` Li Zefan
2011-08-18  4:15       ` Wanlong Gao
2011-08-18  6:02         ` Dmitry Torokhov
2011-08-18  6:08           ` Wanlong Gao
2011-08-18 13:58   ` Seth Forshee
2011-08-18 14:25     ` Seth Forshee
2011-08-18 14:25       ` Seth Forshee
2011-08-19  0:15       ` Wanlong Gao
2011-08-19  0:15         ` Wanlong Gao
2011-08-19  2:23       ` JJ Ding
2011-08-19  2:23         ` JJ Ding
2011-08-18 17:39   ` Seth Forshee
2011-08-19  8:29     ` JJ Ding
2011-08-19 12:13       ` Seth Forshee
2011-08-19 12:41         ` Éric Piel
2011-08-19 12:41           ` Éric Piel
2011-08-19 12:50           ` Seth Forshee
2011-08-19 12:50             ` Seth Forshee
2011-08-19 13:39             ` Éric Piel
2011-08-19 13:39               ` Éric Piel
2011-08-22  0:55         ` JJ Ding
2011-08-19 13:03   ` Éric Piel
2011-08-19 13:03     ` Éric Piel
2011-08-22  6:05     ` JJ Ding
2011-08-22  6:05       ` JJ Ding
2011-08-22  7:20       ` Tom _Lin
2011-08-22  7:20         ` Tom _Lin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.