All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Input: synaptics - add retry mechanism for reconnect
@ 2013-02-18  8:40 Chung-yih Wang
  2013-02-19 18:50 ` Dmitry Torokhov
  0 siblings, 1 reply; 3+ messages in thread
From: Chung-yih Wang @ 2013-02-18  8:40 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Daniel Kurtz, Henrik Rydberg, Seth Forshee,
	Benjamin Herrenschmidt, linux-kernel, Chung-yih Wang

On the Samsung Series 5 Chromebook, the Synaptics ClickPad will sometimes not
send an "0xFA" PS/2 ACK in response to a command byte during the reconnect
sequence following a resume from suspend. From our experiments, the failure can
happen during any byte of any of the commands in the reconnect batch.

This failure results in a timeout in the psmouse driver. In addition, the
ClickPad will often also respond to the next PS/2 command byte with an "0xFE"
PS/2 RESEND response.

This patch makes the synaptics reconnect-at-resume more tolerant to such
failures.

Signed-off-by: Chung-yih Wang <cywang@chromium.org>
---
 drivers/input/mouse/synaptics.c |   79 ++++++++++++++++++++++++++-------------
 1 files changed, 53 insertions(+), 26 deletions(-)

diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 2f78538..2ee19a5 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -72,33 +72,65 @@
  ****************************************************************************/
 
 /*
+ * Send a "synaptics" command to the device and retry on PS/2 communication
+ * error
+ */
+static int synaptics_send_cmd_retry(struct psmouse *psmouse, unsigned char cmd,
+				    unsigned char *param, int param_c)
+{
+	int tries = 2;
+	do {
+		if (!psmouse_sliced_command(psmouse, cmd) &&
+		    !ps2_command(&psmouse->ps2dev, param, param_c)) {
+			return 0;
+		}
+		/*
+		 * If the touchpad did not ACK a previous command byte,
+		 * it may also respond to the next command byte with 'FE'.
+		 * Send a dummy command to clear this possible 'FE'.
+		 */
+		ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
+	} while (--tries > 0);
+	psmouse_err(psmouse, "synaptics_retry failed cmd:0x%02x param_c 0x%x",
+		    cmd, param_c);
+	return -1;
+}
+
+/*
  * Set the synaptics touchpad mode byte by special commands
  */
 static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
 {
 	unsigned char param[1];
 
-	if (psmouse_sliced_command(psmouse, mode))
-		return -1;
 	param[0] = SYN_PS_SET_MODE2;
-	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE))
-		return -1;
-	return 0;
+	return synaptics_send_cmd_retry(psmouse, mode,
+					param, PSMOUSE_CMD_SETRATE);
 }
 
 int synaptics_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
+	int tries = 2;
 
-	param[0] = 0;
+	do {
+		param[0] = 0;
+		if (!ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) &&
+		    !ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) &&
+		    !ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) &&
+		    !ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) &&
+		    !ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
+			goto ps2_command_success;
+		}
+		/* dummy command to reset the communication channel */
+		ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
+	} while (--tries > 0);
 
-	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-	ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
+	psmouse_err(psmouse, "synaptics_retry failed in detect()");
+	return -1;
 
+ps2_command_success:
 	if (param[1] != 0x47)
 		return -ENODEV;
 
@@ -137,11 +169,7 @@ static int synaptics_invert_y(int y)
  */
 static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param)
 {
-	if (psmouse_sliced_command(psmouse, c))
-		return -1;
-	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO))
-		return -1;
-	return 0;
+	return synaptics_send_cmd_retry(psmouse, c, param, PSMOUSE_CMD_GETINFO);
 }
 
 /*
@@ -332,11 +360,10 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
 	      SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)))
 		return 0;
 
-	if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
-		return -1;
-
-	if (ps2_command(&psmouse->ps2dev, &param, PSMOUSE_CMD_SETRATE))
+	if (synaptics_send_cmd_retry(psmouse, SYN_QUE_MODEL,
+				     &param, PSMOUSE_CMD_SETRATE)) {
 		return -1;
+	}
 
 	/* Advanced gesture mode also sends multi finger data */
 	priv->capabilities |= BIT(1);
@@ -393,11 +420,8 @@ static int synaptics_pt_write(struct serio *serio, unsigned char c)
 	struct psmouse *parent = serio_get_drvdata(serio->parent);
 	char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
 
-	if (psmouse_sliced_command(parent, c))
-		return -1;
-	if (ps2_command(&parent->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE))
-		return -1;
-	return 0;
+	return synaptics_send_cmd_retry(parent, c,
+					&rate_param, PSMOUSE_CMD_SETRATE);
 }
 
 static int synaptics_pt_start(struct serio *serio)
@@ -1383,7 +1407,10 @@ static int synaptics_reconnect(struct psmouse *psmouse)
 	int error;
 
 	do {
-		psmouse_reset(psmouse);
+		if (psmouse_reset(psmouse))
+			psmouse_err(psmouse, "psmouse_reset() failed.\n");
+
+
 		if (retry) {
 			/*
 			 * On some boxes, right after resuming, the touchpad
-- 
1.7.8.6


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

* Re: [PATCH] Input: synaptics - add retry mechanism for reconnect
  2013-02-18  8:40 [PATCH] Input: synaptics - add retry mechanism for reconnect Chung-yih Wang
@ 2013-02-19 18:50 ` Dmitry Torokhov
       [not found]   ` <CAM2ehZYJAkcJ2tVGhi+vOaA5YK9vr7bf6iQETPANLnLqSRN9jg@mail.gmail.com>
  0 siblings, 1 reply; 3+ messages in thread
From: Dmitry Torokhov @ 2013-02-19 18:50 UTC (permalink / raw)
  To: Chung-yih Wang
  Cc: linux-input, Daniel Kurtz, Henrik Rydberg, Seth Forshee,
	Benjamin Herrenschmidt, linux-kernel

Hi Chung-yih,

On Mon, Feb 18, 2013 at 04:40:21PM +0800, Chung-yih Wang wrote:
> On the Samsung Series 5 Chromebook, the Synaptics ClickPad will sometimes not
> send an "0xFA" PS/2 ACK in response to a command byte during the reconnect
> sequence following a resume from suspend. From our experiments, the failure can
> happen during any byte of any of the commands in the reconnect batch.
> 
> This failure results in a timeout in the psmouse driver. In addition, the
> ClickPad will often also respond to the next PS/2 command byte with an "0xFE"
> PS/2 RESEND response.

Since you control the firmware of the device can you figure out under
what condition the touchpad does not acknowledge the commands sent to it
and fix it there?

Thanks.

-- 
Dmitry

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

* Re: [PATCH] Input: synaptics - add retry mechanism for reconnect
       [not found]   ` <CAM2ehZYJAkcJ2tVGhi+vOaA5YK9vr7bf6iQETPANLnLqSRN9jg@mail.gmail.com>
@ 2013-04-10 13:24     ` James M Leddy
  0 siblings, 0 replies; 3+ messages in thread
From: James M Leddy @ 2013-04-10 13:24 UTC (permalink / raw)
  To: "Chung-Yih Wang (王崇懿)"
  Cc: Dmitry Torokhov, Daniel Kurtz, Henrik Rydberg, Seth Forshee,
	Benjamin Herrenschmidt, linux-kernel, eric.miao, daniel.manrique,
	haitao.zhang

I'll have someone test it out. Thanks for the patch.

On 04/10/2013 01:40 AM, Chung-Yih Wang (王崇懿) wrote:
> Hi Eric Miao, James Leddy and Daniel Manrique,
> 
> If possible, could you give it a try for the patch I have on your device(s)?
> https://patchwork.kernel.org/patch/2156601/
> 
> I think we may address similar issue here. The synaptics device may not
> respond to the commands in synaptics_reconnect() for stress test of
> suspend/resume, so my patch is trying to do 
> the 'retry' for all requests in the reconnect path if one fails.
> 
> 
> 
> On Wed, Feb 20, 2013 at 2:50 AM, Dmitry Torokhov
> <dmitry.torokhov@gmail.com <mailto:dmitry.torokhov@gmail.com>> wrote:
> 
>     Hi Chung-yih,
> 
>     On Mon, Feb 18, 2013 at 04:40:21PM +0800, Chung-yih Wang wrote:
>     > On the Samsung Series 5 Chromebook, the Synaptics ClickPad will
>     sometimes not
>     > send an "0xFA" PS/2 ACK in response to a command byte during the
>     reconnect
>     > sequence following a resume from suspend. From our experiments,
>     the failure can
>     > happen during any byte of any of the commands in the reconnect batch.
>     >
>     > This failure results in a timeout in the psmouse driver. In
>     addition, the
>     > ClickPad will often also respond to the next PS/2 command byte
>     with an "0xFE"
>     > PS/2 RESEND response.
> 
>     Since you control the firmware of the device can you figure out under
>     what condition the touchpad does not acknowledge the commands sent to it
>     and fix it there?
> 
>     Thanks.
> 
>     --
>     Dmitry
> 
> 


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

end of thread, other threads:[~2013-04-10 13:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-18  8:40 [PATCH] Input: synaptics - add retry mechanism for reconnect Chung-yih Wang
2013-02-19 18:50 ` Dmitry Torokhov
     [not found]   ` <CAM2ehZYJAkcJ2tVGhi+vOaA5YK9vr7bf6iQETPANLnLqSRN9jg@mail.gmail.com>
2013-04-10 13:24     ` James M Leddy

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.