[PATCH 0/2] some updates for newer elantech touchpads

STALE5369d

Revision v1 of 2 in this series.

5 messages, 2 authors, 2011-11-18 · open the first message on its own page

[PATCH 0/2] some updates for newer elantech touchpads

From: JJ Ding <hidden>
Date: 2011-11-17 10:18:44

Hi,

These two are my last pending patches for newer elantech touchpads.
The first patch adds support for a shorter and faster send_cmd, available
since v3 hardware. The other one teaches the driver to query resolution
data from v4 hardware.

Patches are against Dmitry's current -next tree.

Any comment is welcome, thank you very much.

JJ Ding (2):
  Input: elantech - add support for elantech fast command
  Input: elantech - add resolution query support for v4 hardware

 drivers/input/mouse/elantech.c |   70 +++++++++++++++++++++++++++++++++++----
 drivers/input/mouse/elantech.h |    2 +
 2 files changed, 64 insertions(+), 8 deletions(-)

-- 
1.7.8-rc2

[PATCH 1/2] Input: elantech - add support for elantech fast command

From: JJ Ding <hidden>
Date: 2011-11-17 10:18:45

Starting with v3 hardware, the firmware supports this shorter
elantech_send_cmd. Teach the driver to use it.

Signed-off-by: JJ Ding <redacted>
---
 drivers/input/mouse/elantech.c |   38 ++++++++++++++++++++++++++++++--------
 drivers/input/mouse/elantech.h |    1 +
 2 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index b562392..dae020c 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -43,6 +43,24 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c,
 }
 
 /*
+ * V3 and later support this fast command
+ */
+static int elantech_send_cmd(struct psmouse *psmouse, unsigned char c,
+				unsigned char *param)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+
+	if (ps2_command(ps2dev, NULL, ETP_PS2_CUSTOM_COMMAND) ||
+	    ps2_command(ps2dev, NULL, c) ||
+	    ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
+		psmouse_err(psmouse, "%s query 0x%02x failed.\n", __func__, c);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
  * A retrying version of ps2_command
  */
 static int elantech_ps2_command(struct psmouse *psmouse,
@@ -863,13 +881,13 @@ static int elantech_set_range(struct psmouse *psmouse,
 			i = (etd->fw_version > 0x020800 &&
 			     etd->fw_version < 0x020900) ? 1 : 2;
 
-			if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
+			if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
 				return -1;
 
 			fixed_dpi = param[1] & 0x10;
 
 			if (((etd->fw_version >> 16) == 0x14) && fixed_dpi) {
-				if (synaptics_send_cmd(psmouse, ETP_SAMPLE_QUERY, param))
+				if (etd->send_cmd(psmouse, ETP_SAMPLE_QUERY, param))
 					return -1;
 
 				*x_max = (etd->capabilities[1] - i) * param[1] / 2;
@@ -888,7 +906,7 @@ static int elantech_set_range(struct psmouse *psmouse,
 		break;
 
 	case 3:
-		if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
+		if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
 			return -1;
 
 		*x_max = (0x0f & param[0]) << 8 | param[1];
@@ -896,7 +914,7 @@ static int elantech_set_range(struct psmouse *psmouse,
 		break;
 
 	case 4:
-		if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
+		if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
 			return -1;
 
 		*x_max = (0x0f & param[0]) << 8 | param[1];
@@ -1220,9 +1238,13 @@ static int elantech_set_properties(struct elantech_data *etd)
 	else
 		return -1;
 
-	/*
-	 * Turn on packet checking by default.
-	 */
+	/* decide which send_cmd we're gonna use early */
+	if (etd->hw_version > 2)
+		etd->send_cmd = elantech_send_cmd;
+	else
+		etd->send_cmd = synaptics_send_cmd;
+
+	/* Turn on packet checking by default */
 	etd->paritycheck = 1;
 
 	/*
@@ -1278,7 +1300,7 @@ int elantech_init(struct psmouse *psmouse)
 		     "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,
+	if (etd->send_cmd(psmouse, ETP_CAPABILITIES_QUERY,
 	    etd->capabilities)) {
 		psmouse_err(psmouse, "failed to query capabilities.\n");
 		goto init_fail;
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index 9e5f1aa..08d00bd 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -135,6 +135,7 @@ struct elantech_data {
 	unsigned int width;
 	struct finger_pos mt[ETP_MAX_FINGERS];
 	unsigned char parity[256];
+	int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param);
 };
 
 #ifdef CONFIG_MOUSE_PS2_ELANTECH
-- 
1.7.8-rc2

[PATCH 2/2] Input: elantech - add resolution query support for v4 hardware

From: JJ Ding <hidden>
Date: 2011-11-17 10:18:45

It turns out that v4's firmware provides a command so we can query
the resolution. Let's use it.

Signed-off-by: JJ Ding <redacted>
---
 drivers/input/mouse/elantech.c |   32 ++++++++++++++++++++++++++++++++
 drivers/input/mouse/elantech.h |    1 +
 2 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index dae020c..7c00c1a 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -931,6 +931,30 @@ static int elantech_set_range(struct psmouse *psmouse,
 }
 
 /*
+ * (value from firmware) * 10 + 790 = dpi
+ * we also have to convert dpi to dots/mm (*10/254 to avoid floating point)
+ */
+static inline unsigned int convert_res(unsigned int val)
+{
+	return (val * 10 + 790) * 10 / 254;
+}
+
+static int set_resolution_v4(struct psmouse *psmouse,
+			     unsigned int *x_res,
+			     unsigned int *y_res)
+{
+	unsigned char param[3];
+
+	if (elantech_send_cmd(psmouse, ETP_RESOLUTION_QUERY, param))
+		return -1;
+
+	*x_res = convert_res(param[1] & 0x0f);
+	*y_res = convert_res((param[1] & 0xf0) >> 4);
+
+	return 0;
+}
+
+/*
  * Set the appropriate event bits for the input subsystem
  */
 static int elantech_set_input_params(struct psmouse *psmouse)
@@ -938,6 +962,7 @@ 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, width = 0;
+	unsigned int x_res = 0, y_res = 0;
 
 	if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
 		return -1;
@@ -985,10 +1010,15 @@ static int elantech_set_input_params(struct psmouse *psmouse)
 		break;
 
 	case 4:
+		if (set_resolution_v4(psmouse, &x_res, &y_res))
+			return -1;
+
 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
 		/* For X to recognize me as touchpad. */
 		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);
+		input_abs_set_res(dev, ABS_X, x_res);
+		input_abs_set_res(dev, ABS_Y, y_res);
 		/*
 		 * range of pressure and width is the same as v2,
 		 * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility.
@@ -1001,6 +1031,8 @@ static int elantech_set_input_params(struct psmouse *psmouse)
 		input_mt_init_slots(dev, ETP_MAX_FINGERS);
 		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);
+		input_abs_set_res(dev, ABS_MT_POSITION_X, x_res);
+		input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res);
 		input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2,
 				     ETP_PMAX_V2, 0, 0);
 		/*
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index 08d00bd..46db3be 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -20,6 +20,7 @@
 #define ETP_FW_VERSION_QUERY		0x01
 #define ETP_CAPABILITIES_QUERY		0x02
 #define ETP_SAMPLE_QUERY		0x03
+#define ETP_RESOLUTION_QUERY		0x04
 
 /*
  * Command values for register reading or writing
-- 
1.7.8-rc2

Re: [PATCH 2/2] Input: elantech - add resolution query support for v4 hardware

From: Daniel Kurtz <hidden>
Date: 2011-11-18 08:09:15

Hi JJ,

On Thu, Nov 17, 2011 at 6:16 PM, JJ Ding [off-list ref] wrote:
quoted hunk
It turns out that v4's firmware provides a command so we can query
the resolution. Let's use it.

Signed-off-by: JJ Ding <redacted>
---
 drivers/input/mouse/elantech.c |   32 ++++++++++++++++++++++++++++++++
 drivers/input/mouse/elantech.h |    1 +
 2 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index dae020c..7c00c1a 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -931,6 +931,30 @@ static int elantech_set_range(struct psmouse *psmouse,
 }

 /*
+ * (value from firmware) * 10 + 790 = dpi
+ * we also have to convert dpi to dots/mm (*10/254 to avoid floating point)
+ */
+static inline unsigned int convert_res(unsigned int val)
+{
+       return (val * 10 + 790) * 10 / 254;
+}
+
+static int set_resolution_v4(struct psmouse *psmouse,
+                            unsigned int *x_res,
+                            unsigned int *y_res)
+{
+       unsigned char param[3];
+
+       if (elantech_send_cmd(psmouse, ETP_RESOLUTION_QUERY, param))
+               return -1;
+
+       *x_res = convert_res(param[1] & 0x0f);
+       *y_res = convert_res((param[1] & 0xf0) >> 4);
+
+       return 0;
+}
+
+/*
 * Set the appropriate event bits for the input subsystem
 */
 static int elantech_set_input_params(struct psmouse *psmouse)
@@ -938,6 +962,7 @@ 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, width = 0;
+       unsigned int x_res = 0, y_res = 0;

       if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
               return -1;
@@ -985,10 +1010,15 @@ static int elantech_set_input_params(struct psmouse *psmouse)
               break;

       case 4:
+               if (set_resolution_v4(psmouse, &x_res, &y_res))
+                       return -1;
You might consider allowing this command to fail, but just log a
warning message.
Then only do the input_abs_set_res() if x_res / y_res != 0.

Otherwise, for both patches in this set:

Reviewed-by: Daniel Kurtz <redacted>
quoted hunk
+
               __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
               /* For X to recognize me as touchpad. */
               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);
+               input_abs_set_res(dev, ABS_X, x_res);
+               input_abs_set_res(dev, ABS_Y, y_res);
               /*
                * range of pressure and width is the same as v2,
                * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility.
@@ -1001,6 +1031,8 @@ static int elantech_set_input_params(struct psmouse *psmouse)
               input_mt_init_slots(dev, ETP_MAX_FINGERS);
               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);
+               input_abs_set_res(dev, ABS_MT_POSITION_X, x_res);
+               input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res);
               input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2,
                                    ETP_PMAX_V2, 0, 0);
               /*
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index 08d00bd..46db3be 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -20,6 +20,7 @@
 #define ETP_FW_VERSION_QUERY           0x01
 #define ETP_CAPABILITIES_QUERY         0x02
 #define ETP_SAMPLE_QUERY               0x03
+#define ETP_RESOLUTION_QUERY           0x04

 /*
 * Command values for register reading or writing
--
1.7.8-rc2

Re: [PATCH 2/2] Input: elantech - add resolution query support for v4 hardware

From: JJ Ding <hidden>
Date: 2011-11-18 10:21:10

Hi Daniel,

Thanks for your suggestion, I'll send new patches to do this next week.

jj

On Fri, 18 Nov 2011 16:08:53 +0800, Daniel Kurtz [off-list ref] wrote:
Hi JJ,


You might consider allowing this command to fail, but just log a
warning message.
Then only do the input_abs_set_res() if x_res / y_res != 0.

Otherwise, for both patches in this set:

Reviewed-by: Daniel Kurtz <redacted>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help