All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] Input: ALPS - Remove unused argument to alps_enter_command_mode()
@ 2013-02-17  6:40 Kevin Cernekee
  2013-02-17  6:40 ` [PATCH 2/3] Input: ALPS - Add "Dolphin V1" touchpad support Kevin Cernekee
  2013-02-17  6:40 ` [WIP 3/3] Input: ALPS - Add "Dolphin V2" " Kevin Cernekee
  0 siblings, 2 replies; 3+ messages in thread
From: Kevin Cernekee @ 2013-02-17  6:40 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: seth.forshee, emmanuel.thome, dturvene, vincent.vanackere,
	bgamari, jacmet, linux-input

Now that alps_identify() explicitly issues an EC report using
alps_rpt_cmd(), we no longer need to look at the magic numbers returned
by alps_enter_command_mode().

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
 drivers/input/mouse/alps.c |   18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)


Baseline for this series:
git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next


diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 7b99fc7..9c97531 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -994,8 +994,7 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
 	return 0;
 }
 
-static int alps_enter_command_mode(struct psmouse *psmouse,
-				   unsigned char *resp)
+static int alps_enter_command_mode(struct psmouse *psmouse)
 {
 	unsigned char param[4];
 
@@ -1009,9 +1008,6 @@ static int alps_enter_command_mode(struct psmouse *psmouse,
 			    "unknown response while entering command mode\n");
 		return -1;
 	}
-
-	if (resp)
-		*resp = param[2];
 	return 0;
 }
 
@@ -1176,7 +1172,7 @@ static int alps_passthrough_mode_v3(struct psmouse *psmouse,
 {
 	int reg_val, ret = -1;
 
-	if (alps_enter_command_mode(psmouse, NULL))
+	if (alps_enter_command_mode(psmouse))
 		return -1;
 
 	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
@@ -1216,7 +1212,7 @@ static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base)
 {
 	int ret = -EIO, reg_val;
 
-	if (alps_enter_command_mode(psmouse, NULL))
+	if (alps_enter_command_mode(psmouse))
 		goto error;
 
 	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
@@ -1279,7 +1275,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
 		 * supported by this driver. If bit 1 isn't set the packet
 		 * format is different.
 		 */
-		if (alps_enter_command_mode(psmouse, NULL) ||
+		if (alps_enter_command_mode(psmouse) ||
 		    alps_command_mode_write_reg(psmouse,
 						reg_base + 0x08, 0x82) ||
 		    alps_exit_command_mode(psmouse))
@@ -1306,7 +1302,7 @@ static int alps_hw_init_v3(struct psmouse *psmouse)
 	    alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
 		goto error;
 
-	if (alps_enter_command_mode(psmouse, NULL) ||
+	if (alps_enter_command_mode(psmouse) ||
 	    alps_absolute_mode_v3(psmouse)) {
 		psmouse_err(psmouse, "Failed to enter absolute mode\n");
 		goto error;
@@ -1381,7 +1377,7 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
 			priv->flags &= ~ALPS_DUALPOINT;
 	}
 
-	if (alps_enter_command_mode(psmouse, NULL) ||
+	if (alps_enter_command_mode(psmouse) ||
 	    alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
 	    alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
 		goto error;
@@ -1431,7 +1427,7 @@ static int alps_hw_init_v4(struct psmouse *psmouse)
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
 
-	if (alps_enter_command_mode(psmouse, NULL))
+	if (alps_enter_command_mode(psmouse))
 		goto error;
 
 	if (alps_absolute_mode_v4(psmouse)) {
-- 
1.7.10.4


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

* [PATCH 2/3] Input: ALPS - Add "Dolphin V1" touchpad support
  2013-02-17  6:40 [PATCH 1/3] Input: ALPS - Remove unused argument to alps_enter_command_mode() Kevin Cernekee
@ 2013-02-17  6:40 ` Kevin Cernekee
  2013-02-17  6:40 ` [WIP 3/3] Input: ALPS - Add "Dolphin V2" " Kevin Cernekee
  1 sibling, 0 replies; 3+ messages in thread
From: Kevin Cernekee @ 2013-02-17  6:40 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: seth.forshee, emmanuel.thome, dturvene, vincent.vanackere,
	bgamari, jacmet, linux-input

From: Dave Turvene <dturvene@dahetral.com>

These touchpads use a different protocol; they have been seen on Dell
N5110, Dell 17R SE, and others.

The official ALPS driver identifies them by looking for an exact match
on the E7 report: 73 03 50.  Dolphin V1 returns an EC report of
73 01 xx (02 and 0d have been seen); Dolphin V2 returns an EC report of
73 02 xx (02 has been seen).

Dolphin V2 probably needs a different initialization sequence and/or
report parser, so it is left for a future commit.

Signed-off-by: Dave Turvene <dturvene@dahetral.com>
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
 drivers/input/mouse/alps.c |   67 ++++++++++++++++++++++++++++++++++++++++++--
 drivers/input/mouse/alps.h |    1 +
 2 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 9c97531..0238e0e 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -490,6 +490,29 @@ static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p)
 	f->y_map |= (p[5] & 0x20) << 6;
 }
 
+static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p)
+{
+	f->first_mp = !!(p[0] & 0x02);
+	f->is_mp = !!(p[0] & 0x20);
+
+	f->fingers = ((p[0] & 0x6) >> 1 |
+		     (p[0] & 0x10) >> 2);
+	f->x_map = ((p[2] & 0x60) >> 5) |
+		   ((p[4] & 0x7f) << 2) |
+		   ((p[5] & 0x7f) << 9) |
+		   ((p[3] & 0x07) << 16) |
+		   ((p[3] & 0x70) << 15) |
+		   ((p[0] & 0x01) << 22);
+	f->y_map = (p[1] & 0x7f) |
+		   ((p[2] & 0x1f) << 7);
+
+	f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
+	f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
+	f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
+
+	alps_decode_buttons_v3(f, p);
+}
+
 static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
@@ -874,7 +897,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
 	}
 
 	/* Bytes 2 - pktsize should have 0 in the highest bit */
-	if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
+	if (priv->proto_version != ALPS_PROTO_V5 &&
+	    psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
 	    (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
 		psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
 			    psmouse->pktcnt - 1,
@@ -1003,7 +1027,8 @@ static int alps_enter_command_mode(struct psmouse *psmouse)
 		return -1;
 	}
 
-	if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) {
+	if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
+	    param[0] != 0x73) {
 		psmouse_dbg(psmouse,
 			    "unknown response while entering command mode\n");
 		return -1;
@@ -1495,6 +1520,23 @@ error:
 	return -1;
 }
 
+static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char param[2];
+
+	/* This is dolphin "v1" as empirically defined by florin9doi */
+	param[0] = 0x64;
+	param[1] = 0x28;
+
+	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
+	    ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
+	    ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
+		return -1;
+
+	return 0;
+}
+
 static void alps_set_defaults(struct alps_data *priv)
 {
 	priv->byte0 = 0x8f;
@@ -1528,6 +1570,21 @@ static void alps_set_defaults(struct alps_data *priv)
 		priv->nibble_commands = alps_v4_nibble_commands;
 		priv->addr_command = PSMOUSE_CMD_DISABLE;
 		break;
+	case ALPS_PROTO_V5:
+		priv->hw_init = alps_hw_init_dolphin_v1;
+		priv->process_packet = alps_process_packet_v3;
+		priv->decode_fields = alps_decode_dolphin;
+		priv->set_abs_params = alps_set_abs_params_mt;
+		priv->nibble_commands = alps_v3_nibble_commands;
+		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
+		priv->byte0 = 0xc8;
+		priv->mask0 = 0xc8;
+		priv->flags = 0;
+		priv->x_max = 1360;
+		priv->y_max = 660;
+		priv->x_bits = 23;
+		priv->y_bits = 12;
+		break;
 	}
 }
 
@@ -1588,6 +1645,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
 
 	if (alps_match_table(psmouse, priv, e7, ec) == 0) {
 		return 0;
+	} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
+		   ec[0] == 0x73 && ec[1] == 0x01) {
+		priv->proto_version = ALPS_PROTO_V5;
+		alps_set_defaults(priv);
+
+		return 0;
 	} else if (ec[0] == 0x88 && ec[1] == 0x08) {
 		priv->proto_version = ALPS_PROTO_V3;
 		alps_set_defaults(priv);
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 9704805..eee5985 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -16,6 +16,7 @@
 #define ALPS_PROTO_V2	2
 #define ALPS_PROTO_V3	3
 #define ALPS_PROTO_V4	4
+#define ALPS_PROTO_V5	5
 
 /**
  * struct alps_model_info - touchpad ID table
-- 
1.7.10.4


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

* [WIP 3/3] Input: ALPS - Add "Dolphin V2" touchpad support
  2013-02-17  6:40 [PATCH 1/3] Input: ALPS - Remove unused argument to alps_enter_command_mode() Kevin Cernekee
  2013-02-17  6:40 ` [PATCH 2/3] Input: ALPS - Add "Dolphin V1" touchpad support Kevin Cernekee
@ 2013-02-17  6:40 ` Kevin Cernekee
  1 sibling, 0 replies; 3+ messages in thread
From: Kevin Cernekee @ 2013-02-17  6:40 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: seth.forshee, emmanuel.thome, dturvene, vincent.vanackere,
	bgamari, jacmet, linux-input

Another ALPS variant; seen on the Fujitsu A512.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Signed-off-by: Vincent Vanackere <vincent.vanackere@gmail.com>
---
 drivers/input/mouse/alps.c |   79 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 78 insertions(+), 1 deletion(-)


This is a work-in-progress and not ready to be merged yet.  See:

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/606238
https://bugs.freedesktop.org/show_bug.cgi?id=59478

The init sequence is probably "mostly OK" but the pressure values read
near the edges are not accurate, so edge scrolling does not work well.
Maybe this is fixable by changing some of the register settings, maybe
the report decoder is slightly off, or maybe the software will actually
need to scale z based on the x/y values.

One thing that might be worth trying is to select the native V2 report
format (short cmd 0x89) instead of the V1 format (short cmd 0x85).  This
probably affects the bit assignments and may require writing a new
alps_decode_* function.

I don't actually have access to any of the "Dolphin" based systems, so
I'm not able to make much progress on my own here.  Hopefully it's a
useful starting point though.


diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 0238e0e..d288f4c 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -1520,6 +1520,17 @@ error:
 	return -1;
 }
 
+static int alps_short_cmd_v5(struct psmouse *psmouse, u8 init_command, u8 cmd)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+
+	if (ps2_command(ps2dev, NULL, init_command) ||
+	    ps2_command(ps2dev, NULL, init_command) ||
+	    __alps_command_mode_write_reg(psmouse, cmd))
+		return -EIO;
+	return 0;
+}
+
 static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
@@ -1537,6 +1548,69 @@ static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
 	return 0;
 }
 
+static int alps_hw_init_dolphin_v2(struct psmouse *psmouse)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+
+	/* sample rate */
+	if (alps_short_cmd_v5(psmouse, PSMOUSE_CMD_SETSTREAM, 0x55))
+		goto error;
+
+	/* idle count */
+	if (alps_short_cmd_v5(psmouse, PSMOUSE_CMD_SETSTREAM, 0x64))
+		goto error;
+
+	/* button swap */
+	if (alps_short_cmd_v5(psmouse, PSMOUSE_CMD_SETSTREAM, 0x47))
+		goto error;
+
+	/* data priority */
+	if (alps_short_cmd_v5(psmouse, PSMOUSE_CMD_SETSTREAM, 0x43))
+		goto error;
+
+	/* power mode */
+	if (alps_short_cmd_v5(psmouse, PSMOUSE_CMD_SETPOLL, 0x57))
+		goto error;
+
+	/*
+	 * TODO: For Dolphin V2 touchpads, the threshold should be calculated
+	 * from the OTP settings instead.
+	 */
+	if (alps_enter_command_mode(psmouse) ||
+	    alps_command_mode_write_reg(psmouse, 0x001f, 0x09) ||
+	    alps_command_mode_write_reg(psmouse, 0x0020, 0x09) ||
+	    alps_command_mode_write_reg(psmouse, 0x0022, 0x80) ||
+	    alps_exit_command_mode(psmouse))
+		goto error;
+
+	/* select V1 packet format */
+	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    alps_short_cmd_v5(psmouse, PSMOUSE_CMD_SETSTREAM, 0x85))
+		goto error;
+
+	/* XY and gesture */
+	if (alps_short_cmd_v5(psmouse, PSMOUSE_CMD_SETSTREAM, 0x73))
+		goto error;
+
+	/* profile sequence */
+	if (alps_short_cmd_v5(psmouse, PSMOUSE_CMD_SETSTREAM, 0x94))
+		goto error;
+
+	/* final init */
+	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
+	    alps_command_mode_send_nibble(psmouse, 0x7) ||
+	    alps_command_mode_send_nibble(psmouse, 0xf) ||
+	    alps_command_mode_send_nibble(psmouse, 0xe) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
+		goto error;
+
+	return 0;
+
+error:
+	alps_exit_command_mode(psmouse);
+	return -1;
+}
+
 static void alps_set_defaults(struct alps_data *priv)
 {
 	priv->byte0 = 0x8f;
@@ -1646,10 +1720,13 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
 	if (alps_match_table(psmouse, priv, e7, ec) == 0) {
 		return 0;
 	} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
-		   ec[0] == 0x73 && ec[1] == 0x01) {
+		   ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) {
 		priv->proto_version = ALPS_PROTO_V5;
 		alps_set_defaults(priv);
 
+		if (ec[1] == 0x02)
+			priv->hw_init = alps_hw_init_dolphin_v2;
+
 		return 0;
 	} else if (ec[0] == 0x88 && ec[1] == 0x08) {
 		priv->proto_version = ALPS_PROTO_V3;
-- 
1.7.10.4


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

end of thread, other threads:[~2013-02-17  6:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-17  6:40 [PATCH 1/3] Input: ALPS - Remove unused argument to alps_enter_command_mode() Kevin Cernekee
2013-02-17  6:40 ` [PATCH 2/3] Input: ALPS - Add "Dolphin V1" touchpad support Kevin Cernekee
2013-02-17  6:40 ` [WIP 3/3] Input: ALPS - Add "Dolphin V2" " Kevin Cernekee

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.