5c86018
From db7192fa07fa5c70c9849d8f658a7ff696cff99d Mon Sep 17 00:00:00 2001
5c86018
From: Kevin Cernekee <cernekee@gmail.com>
5c86018
Date: Sat, 16 Feb 2013 22:40:03 -0800
5c86018
Subject: [PATCH 14/15] Input: ALPS - Remove unused argument to
5c86018
 alps_enter_command_mode()
5c86018
5c86018
Now that alps_identify() explicitly issues an EC report using
5c86018
alps_rpt_cmd(), we no longer need to look at the magic numbers returned
5c86018
by alps_enter_command_mode().
5c86018
5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
5c86018
---
5c86018
 drivers/input/mouse/alps.c | 18 +++++++-----------
5c86018
 1 file changed, 7 insertions(+), 11 deletions(-)
5c86018
5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
5c86018
index 7b99fc7..9c97531 100644
5c86018
--- a/drivers/input/mouse/alps.c
5c86018
+++ b/drivers/input/mouse/alps.c
5c86018
@@ -994,8 +994,7 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
5c86018
 	return 0;
5c86018
 }
5c86018
 
5c86018
-static int alps_enter_command_mode(struct psmouse *psmouse,
5c86018
-				   unsigned char *resp)
5c86018
+static int alps_enter_command_mode(struct psmouse *psmouse)
5c86018
 {
5c86018
 	unsigned char param[4];
5c86018
 
5c86018
@@ -1009,9 +1008,6 @@ static int alps_enter_command_mode(struct psmouse *psmouse,
5c86018
 			    "unknown response while entering command mode\n");
5c86018
 		return -1;
5c86018
 	}
5c86018
-
5c86018
-	if (resp)
5c86018
-		*resp = param[2];
5c86018
 	return 0;
5c86018
 }
5c86018
 
5c86018
@@ -1176,7 +1172,7 @@ static int alps_passthrough_mode_v3(struct psmouse *psmouse,
5c86018
 {
5c86018
 	int reg_val, ret = -1;
5c86018
 
5c86018
-	if (alps_enter_command_mode(psmouse, NULL))
5c86018
+	if (alps_enter_command_mode(psmouse))
5c86018
 		return -1;
5c86018
 
5c86018
 	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
5c86018
@@ -1216,7 +1212,7 @@ static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base)
5c86018
 {
5c86018
 	int ret = -EIO, reg_val;
5c86018
 
5c86018
-	if (alps_enter_command_mode(psmouse, NULL))
5c86018
+	if (alps_enter_command_mode(psmouse))
5c86018
 		goto error;
5c86018
 
5c86018
 	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
5c86018
@@ -1279,7 +1275,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
5c86018
 		 * supported by this driver. If bit 1 isn't set the packet
5c86018
 		 * format is different.
5c86018
 		 */
5c86018
-		if (alps_enter_command_mode(psmouse, NULL) ||
5c86018
+		if (alps_enter_command_mode(psmouse) ||
5c86018
 		    alps_command_mode_write_reg(psmouse,
5c86018
 						reg_base + 0x08, 0x82) ||
5c86018
 		    alps_exit_command_mode(psmouse))
5c86018
@@ -1306,7 +1302,7 @@ static int alps_hw_init_v3(struct psmouse *psmouse)
5c86018
 	    alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
5c86018
 		goto error;
5c86018
 
5c86018
-	if (alps_enter_command_mode(psmouse, NULL) ||
5c86018
+	if (alps_enter_command_mode(psmouse) ||
5c86018
 	    alps_absolute_mode_v3(psmouse)) {
5c86018
 		psmouse_err(psmouse, "Failed to enter absolute mode\n");
5c86018
 		goto error;
5c86018
@@ -1381,7 +1377,7 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
5c86018
 			priv->flags &= ~ALPS_DUALPOINT;
5c86018
 	}
5c86018
 
5c86018
-	if (alps_enter_command_mode(psmouse, NULL) ||
5c86018
+	if (alps_enter_command_mode(psmouse) ||
5c86018
 	    alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
5c86018
 	    alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
5c86018
 		goto error;
5c86018
@@ -1431,7 +1427,7 @@ static int alps_hw_init_v4(struct psmouse *psmouse)
5c86018
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
5c86018
 	unsigned char param[4];
5c86018
 
5c86018
-	if (alps_enter_command_mode(psmouse, NULL))
5c86018
+	if (alps_enter_command_mode(psmouse))
5c86018
 		goto error;
5c86018
 
5c86018
 	if (alps_absolute_mode_v4(psmouse)) {
5c86018
-- 
5c86018
1.8.1.2
5c86018
5c86018
5c86018
From 10740a25bb3b895b5de7773f926a978416b38409 Mon Sep 17 00:00:00 2001
5c86018
From: Dave Turvene <dturvene@dahetral.com>
5c86018
Date: Sat, 16 Feb 2013 22:40:04 -0800
5c86018
Subject: [PATCH 15/15] Input: ALPS - Add "Dolphin V1" touchpad support
5c86018
5c86018
These touchpads use a different protocol; they have been seen on Dell
5c86018
N5110, Dell 17R SE, and others.
5c86018
5c86018
The official ALPS driver identifies them by looking for an exact match
5c86018
on the E7 report: 73 03 50.  Dolphin V1 returns an EC report of
5c86018
73 01 xx (02 and 0d have been seen); Dolphin V2 returns an EC report of
5c86018
73 02 xx (02 has been seen).
5c86018
5c86018
Dolphin V2 probably needs a different initialization sequence and/or
5c86018
report parser, so it is left for a future commit.
5c86018
5c86018
Signed-off-by: Dave Turvene <dturvene@dahetral.com>
5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
5c86018
---
5c86018
 drivers/input/mouse/alps.c | 67 ++++++++++++++++++++++++++++++++++++++++++++--
5c86018
 drivers/input/mouse/alps.h |  1 +
5c86018
 2 files changed, 66 insertions(+), 2 deletions(-)
5c86018
5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
5c86018
index 9c97531..0238e0e 100644
5c86018
--- a/drivers/input/mouse/alps.c
5c86018
+++ b/drivers/input/mouse/alps.c
5c86018
@@ -490,6 +490,29 @@ static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p)
5c86018
 	f->y_map |= (p[5] & 0x20) << 6;
5c86018
 }
5c86018
 
5c86018
+static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p)
5c86018
+{
5c86018
+	f->first_mp = !!(p[0] & 0x02);
5c86018
+	f->is_mp = !!(p[0] & 0x20);
5c86018
+
5c86018
+	f->fingers = ((p[0] & 0x6) >> 1 |
5c86018
+		     (p[0] & 0x10) >> 2);
5c86018
+	f->x_map = ((p[2] & 0x60) >> 5) |
5c86018
+		   ((p[4] & 0x7f) << 2) |
5c86018
+		   ((p[5] & 0x7f) << 9) |
5c86018
+		   ((p[3] & 0x07) << 16) |
5c86018
+		   ((p[3] & 0x70) << 15) |
5c86018
+		   ((p[0] & 0x01) << 22);
5c86018
+	f->y_map = (p[1] & 0x7f) |
5c86018
+		   ((p[2] & 0x1f) << 7);
5c86018
+
5c86018
+	f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
5c86018
+	f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
5c86018
+	f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
5c86018
+
5c86018
+	alps_decode_buttons_v3(f, p);
5c86018
+}
5c86018
+
5c86018
 static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
5c86018
 {
5c86018
 	struct alps_data *priv = psmouse->private;
5c86018
@@ -874,7 +897,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
5c86018
 	}
5c86018
 
5c86018
 	/* Bytes 2 - pktsize should have 0 in the highest bit */
5c86018
-	if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
5c86018
+	if (priv->proto_version != ALPS_PROTO_V5 &&
5c86018
+	    psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
5c86018
 	    (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
5c86018
 		psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
5c86018
 			    psmouse->pktcnt - 1,
5c86018
@@ -1003,7 +1027,8 @@ static int alps_enter_command_mode(struct psmouse *psmouse)
5c86018
 		return -1;
5c86018
 	}
5c86018
 
5c86018
-	if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) {
5c86018
+	if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
5c86018
+	    param[0] != 0x73) {
5c86018
 		psmouse_dbg(psmouse,
5c86018
 			    "unknown response while entering command mode\n");
5c86018
 		return -1;
5c86018
@@ -1495,6 +1520,23 @@ error:
5c86018
 	return -1;
5c86018
 }
5c86018
 
5c86018
+static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
5c86018
+{
5c86018
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
5c86018
+	unsigned char param[2];
5c86018
+
5c86018
+	/* This is dolphin "v1" as empirically defined by florin9doi */
5c86018
+	param[0] = 0x64;
5c86018
+	param[1] = 0x28;
5c86018
+
5c86018
+	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
5c86018
+	    ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
5c86018
+	    ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
5c86018
+		return -1;
5c86018
+
5c86018
+	return 0;
5c86018
+}
5c86018
+
5c86018
 static void alps_set_defaults(struct alps_data *priv)
5c86018
 {
5c86018
 	priv->byte0 = 0x8f;
5c86018
@@ -1528,6 +1570,21 @@ static void alps_set_defaults(struct alps_data *priv)
5c86018
 		priv->nibble_commands = alps_v4_nibble_commands;
5c86018
 		priv->addr_command = PSMOUSE_CMD_DISABLE;
5c86018
 		break;
5c86018
+	case ALPS_PROTO_V5:
5c86018
+		priv->hw_init = alps_hw_init_dolphin_v1;
5c86018
+		priv->process_packet = alps_process_packet_v3;
5c86018
+		priv->decode_fields = alps_decode_dolphin;
5c86018
+		priv->set_abs_params = alps_set_abs_params_mt;
5c86018
+		priv->nibble_commands = alps_v3_nibble_commands;
5c86018
+		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
5c86018
+		priv->byte0 = 0xc8;
5c86018
+		priv->mask0 = 0xc8;
5c86018
+		priv->flags = 0;
5c86018
+		priv->x_max = 1360;
5c86018
+		priv->y_max = 660;
5c86018
+		priv->x_bits = 23;
5c86018
+		priv->y_bits = 12;
5c86018
+		break;
5c86018
 	}
5c86018
 }
5c86018
 
5c86018
@@ -1588,6 +1645,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
5c86018
 
5c86018
 	if (alps_match_table(psmouse, priv, e7, ec) == 0) {
5c86018
 		return 0;
5c86018
+	} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
5c86018
+		   ec[0] == 0x73 && ec[1] == 0x01) {
5c86018
+		priv->proto_version = ALPS_PROTO_V5;
5c86018
+		alps_set_defaults(priv);
5c86018
+
5c86018
+		return 0;
5c86018
 	} else if (ec[0] == 0x88 && ec[1] == 0x08) {
5c86018
 		priv->proto_version = ALPS_PROTO_V3;
5c86018
 		alps_set_defaults(priv);
5c86018
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
5c86018
index 9704805..eee5985 100644
5c86018
--- a/drivers/input/mouse/alps.h
5c86018
+++ b/drivers/input/mouse/alps.h
5c86018
@@ -16,6 +16,7 @@
5c86018
 #define ALPS_PROTO_V2	2
5c86018
 #define ALPS_PROTO_V3	3
5c86018
 #define ALPS_PROTO_V4	4
5c86018
+#define ALPS_PROTO_V5	5
5c86018
 
5c86018
 /**
5c86018
  * struct alps_model_info - touchpad ID table
5c86018
-- 
5c86018
1.8.1.2
5c86018