walters / rpms / kernel

Forked from rpms/kernel 5 years ago
Clone
Josh Boyer 5c86018
From f822982515378982dc8d8e6058579288d0ee3cff Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 20:55:19 -0800
Josh Boyer 5c86018
Subject: [PATCH 01/15] Input: ALPS - document the alps.h data structures
Josh Boyer 5c86018
Josh Boyer 5c86018
Add kernel-doc markup.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.h | 74 ++++++++++++++++++++++++++++++++++++++--------
Josh Boyer 5c86018
 1 file changed, 61 insertions(+), 13 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
index ae1ac35..67be4e5 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.h
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
@@ -17,30 +17,78 @@
Josh Boyer 5c86018
 #define ALPS_PROTO_V3	2
Josh Boyer 5c86018
 #define ALPS_PROTO_V4	3
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+/**
Josh Boyer 5c86018
+ * struct alps_model_info - touchpad ID table
Josh Boyer 5c86018
+ * @signature: E7 response string to match.
Josh Boyer 5c86018
+ * @command_mode_resp: For V3/V4 touchpads, the final byte of the EC response
Josh Boyer 5c86018
+ *   (aka command mode response) identifies the firmware minor version.  This
Josh Boyer 5c86018
+ *   can be used to distinguish different hardware models which are not
Josh Boyer 5c86018
+ *   uniquely identifiable through their E7 responses.
Josh Boyer 5c86018
+ * @proto_version: Indicates V1/V2/V3/...
Josh Boyer 5c86018
+ * @byte0: Helps figure out whether a position report packet matches the
Josh Boyer 5c86018
+ *   known format for this model.  The first byte of the report, ANDed with
Josh Boyer 5c86018
+ *   mask0, should match byte0.
Josh Boyer 5c86018
+ * @mask0: The mask used to check the first byte of the report.
Josh Boyer 5c86018
+ * @flags: Additional device capabilities (passthrough port, trackstick, etc.).
Josh Boyer 5c86018
+ *
Josh Boyer 5c86018
+ * Many (but not all) ALPS touchpads can be identified by looking at the
Josh Boyer 5c86018
+ * values returned in the "E7 report" and/or the "EC report."  This table
Josh Boyer 5c86018
+ * lists a number of such touchpads.
Josh Boyer 5c86018
+ */
Josh Boyer 5c86018
 struct alps_model_info {
Josh Boyer 5c86018
-        unsigned char signature[3];
Josh Boyer 5c86018
-	unsigned char command_mode_resp; /* v3/v4 only */
Josh Boyer 5c86018
+	unsigned char signature[3];
Josh Boyer 5c86018
+	unsigned char command_mode_resp;
Josh Boyer 5c86018
 	unsigned char proto_version;
Josh Boyer 5c86018
-        unsigned char byte0, mask0;
Josh Boyer 5c86018
-        unsigned char flags;
Josh Boyer 5c86018
+	unsigned char byte0, mask0;
Josh Boyer 5c86018
+	unsigned char flags;
Josh Boyer 5c86018
 };
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+/**
Josh Boyer 5c86018
+ * struct alps_nibble_commands - encodings for register accesses
Josh Boyer 5c86018
+ * @command: PS/2 command used for the nibble
Josh Boyer 5c86018
+ * @data: Data supplied as an argument to the PS/2 command, if applicable
Josh Boyer 5c86018
+ *
Josh Boyer 5c86018
+ * The ALPS protocol uses magic sequences to transmit binary data to the
Josh Boyer 5c86018
+ * touchpad, as it is generally not OK to send arbitrary bytes out the
Josh Boyer 5c86018
+ * PS/2 port.  Each of the sequences in this table sends one nibble of the
Josh Boyer 5c86018
+ * register address or (write) data.  Different versions of the ALPS protocol
Josh Boyer 5c86018
+ * use slightly different encodings.
Josh Boyer 5c86018
+ */
Josh Boyer 5c86018
 struct alps_nibble_commands {
Josh Boyer 5c86018
 	int command;
Josh Boyer 5c86018
 	unsigned char data;
Josh Boyer 5c86018
 };
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+/**
Josh Boyer 5c86018
+ * struct alps_data - private data structure for the ALPS driver
Josh Boyer 5c86018
+ * @dev2: "Relative" device used to report trackstick or mouse activity.
Josh Boyer 5c86018
+ * @phys: Physical path for the relative device.
Josh Boyer 5c86018
+ * @i: Information on the detected touchpad model.
Josh Boyer 5c86018
+ * @nibble_commands: Command mapping used for touchpad register accesses.
Josh Boyer 5c86018
+ * @addr_command: Command used to tell the touchpad that a register address
Josh Boyer 5c86018
+ *   follows.
Josh Boyer 5c86018
+ * @prev_fin: Finger bit from previous packet.
Josh Boyer 5c86018
+ * @multi_packet: Multi-packet data in progress.
Josh Boyer 5c86018
+ * @multi_data: Saved multi-packet data.
Josh Boyer 5c86018
+ * @x1: First X coordinate from last MT report.
Josh Boyer 5c86018
+ * @x2: Second X coordinate from last MT report.
Josh Boyer 5c86018
+ * @y1: First Y coordinate from last MT report.
Josh Boyer 5c86018
+ * @y2: Second Y coordinate from last MT report.
Josh Boyer 5c86018
+ * @fingers: Number of fingers from last MT report.
Josh Boyer 5c86018
+ * @quirks: Bitmap of ALPS_QUIRK_*.
Josh Boyer 5c86018
+ * @timer: Timer for flushing out the final report packet in the stream.
Josh Boyer 5c86018
+ */
Josh Boyer 5c86018
 struct alps_data {
Josh Boyer 5c86018
-	struct input_dev *dev2;		/* Relative device */
Josh Boyer 5c86018
-	char phys[32];			/* Phys */
Josh Boyer 5c86018
-	const struct alps_model_info *i;/* Info */
Josh Boyer 5c86018
+	struct input_dev *dev2;
Josh Boyer 5c86018
+	char phys[32];
Josh Boyer 5c86018
+	const struct alps_model_info *i;
Josh Boyer 5c86018
 	const struct alps_nibble_commands *nibble_commands;
Josh Boyer 5c86018
-	int addr_command;		/* Command to set register address */
Josh Boyer 5c86018
-	int prev_fin;			/* Finger bit from previous packet */
Josh Boyer 5c86018
-	int multi_packet;		/* Multi-packet data in progress */
Josh Boyer 5c86018
-	unsigned char multi_data[6];	/* Saved multi-packet data */
Josh Boyer 5c86018
-	int x1, x2, y1, y2;		/* Coordinates from last MT report */
Josh Boyer 5c86018
-	int fingers;			/* Number of fingers from MT report */
Josh Boyer 5c86018
+	int addr_command;
Josh Boyer 5c86018
+	int prev_fin;
Josh Boyer 5c86018
+	int multi_packet;
Josh Boyer 5c86018
+	unsigned char multi_data[6];
Josh Boyer 5c86018
+	int x1, x2, y1, y2;
Josh Boyer 5c86018
+	int fingers;
Josh Boyer 5c86018
 	u8 quirks;
Josh Boyer 5c86018
 	struct timer_list timer;
Josh Boyer 5c86018
 };
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From 196069863604cb55061a02ad5f046c5e4054ba54 Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 20:56:33 -0800
Josh Boyer 5c86018
Subject: [PATCH 02/15] Input: ALPS - copy "model" info into alps_data struct
Josh Boyer 5c86018
Josh Boyer 5c86018
Not every type of ALPS touchpad is well-suited to table-based detection.
Josh Boyer 5c86018
Start moving the various alps_model_data attributes into the alps_data
Josh Boyer 5c86018
struct so that we don't need a unique table entry for every possible
Josh Boyer 5c86018
permutation of protocol version, flags, byte0/mask0, etc.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 63 +++++++++++++++++++++++-----------------------
Josh Boyer 5c86018
 drivers/input/mouse/alps.h | 14 +++++++++--
Josh Boyer 5c86018
 2 files changed, 43 insertions(+), 34 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index e229fa3..33ee6e0 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -122,10 +122,10 @@ static const struct alps_model_info alps_model_data[] = {
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 /* Packet formats are described in Documentation/input/alps.txt */
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-static bool alps_is_valid_first_byte(const struct alps_model_info *model,
Josh Boyer 5c86018
+static bool alps_is_valid_first_byte(struct alps_data *priv,
Josh Boyer 5c86018
 				     unsigned char data)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	return (data & model->mask0) == model->byte0;
Josh Boyer 5c86018
+	return (data & priv->mask0) == priv->byte0;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static void alps_report_buttons(struct psmouse *psmouse,
Josh Boyer 5c86018
@@ -158,14 +158,13 @@ static void alps_report_buttons(struct psmouse *psmouse,
Josh Boyer 5c86018
 static void alps_process_packet_v1_v2(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
-	const struct alps_model_info *model = priv->i;
Josh Boyer 5c86018
 	unsigned char *packet = psmouse->packet;
Josh Boyer 5c86018
 	struct input_dev *dev = psmouse->dev;
Josh Boyer 5c86018
 	struct input_dev *dev2 = priv->dev2;
Josh Boyer 5c86018
 	int x, y, z, ges, fin, left, right, middle;
Josh Boyer 5c86018
 	int back = 0, forward = 0;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model->proto_version == ALPS_PROTO_V1) {
Josh Boyer 5c86018
+	if (priv->proto_version == ALPS_PROTO_V1) {
Josh Boyer 5c86018
 		left = packet[2] & 0x10;
Josh Boyer 5c86018
 		right = packet[2] & 0x08;
Josh Boyer 5c86018
 		middle = 0;
Josh Boyer 5c86018
@@ -181,12 +180,12 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
Josh Boyer 5c86018
 		z = packet[5];
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model->flags & ALPS_FW_BK_1) {
Josh Boyer 5c86018
+	if (priv->flags & ALPS_FW_BK_1) {
Josh Boyer 5c86018
 		back = packet[0] & 0x10;
Josh Boyer 5c86018
 		forward = packet[2] & 4;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model->flags & ALPS_FW_BK_2) {
Josh Boyer 5c86018
+	if (priv->flags & ALPS_FW_BK_2) {
Josh Boyer 5c86018
 		back = packet[3] & 4;
Josh Boyer 5c86018
 		forward = packet[2] & 4;
Josh Boyer 5c86018
 		if ((middle = forward && back))
Josh Boyer 5c86018
@@ -196,7 +195,7 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
Josh Boyer 5c86018
 	ges = packet[2] & 1;
Josh Boyer 5c86018
 	fin = packet[2] & 2;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if ((model->flags & ALPS_DUALPOINT) && z == 127) {
Josh Boyer 5c86018
+	if ((priv->flags & ALPS_DUALPOINT) && z == 127) {
Josh Boyer 5c86018
 		input_report_rel(dev2, REL_X,  (x > 383 ? (x - 768) : x));
Josh Boyer 5c86018
 		input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -239,15 +238,15 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
Josh Boyer 5c86018
 	input_report_abs(dev, ABS_PRESSURE, z);
Josh Boyer 5c86018
 	input_report_key(dev, BTN_TOOL_FINGER, z > 0);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model->flags & ALPS_WHEEL)
Josh Boyer 5c86018
+	if (priv->flags & ALPS_WHEEL)
Josh Boyer 5c86018
 		input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
Josh Boyer 5c86018
+	if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
Josh Boyer 5c86018
 		input_report_key(dev, BTN_FORWARD, forward);
Josh Boyer 5c86018
 		input_report_key(dev, BTN_BACK, back);
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model->flags & ALPS_FOUR_BUTTONS) {
Josh Boyer 5c86018
+	if (priv->flags & ALPS_FOUR_BUTTONS) {
Josh Boyer 5c86018
 		input_report_key(dev, BTN_0, packet[2] & 4);
Josh Boyer 5c86018
 		input_report_key(dev, BTN_1, packet[0] & 0x10);
Josh Boyer 5c86018
 		input_report_key(dev, BTN_2, packet[3] & 4);
Josh Boyer 5c86018
@@ -699,9 +698,8 @@ static void alps_process_packet_v4(struct psmouse *psmouse)
Josh Boyer 5c86018
 static void alps_process_packet(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
-	const struct alps_model_info *model = priv->i;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	switch (model->proto_version) {
Josh Boyer 5c86018
+	switch (priv->proto_version) {
Josh Boyer 5c86018
 	case ALPS_PROTO_V1:
Josh Boyer 5c86018
 	case ALPS_PROTO_V2:
Josh Boyer 5c86018
 		alps_process_packet_v1_v2(psmouse);
Josh Boyer 5c86018
@@ -765,7 +763,7 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
Josh Boyer 5c86018
 		if (((psmouse->packet[3] |
Josh Boyer 5c86018
 		      psmouse->packet[4] |
Josh Boyer 5c86018
 		      psmouse->packet[5]) & 0x80) ||
Josh Boyer 5c86018
-		    (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) {
Josh Boyer 5c86018
+		    (!alps_is_valid_first_byte(priv, psmouse->packet[6]))) {
Josh Boyer 5c86018
 			psmouse_dbg(psmouse,
Josh Boyer 5c86018
 				    "refusing packet %4ph (suspected interleaved ps/2)\n",
Josh Boyer 5c86018
 				    psmouse->packet + 3);
Josh Boyer 5c86018
@@ -844,7 +842,6 @@ static void alps_flush_packet(unsigned long data)
Josh Boyer 5c86018
 static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
-	const struct alps_model_info *model = priv->i;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
Josh Boyer 5c86018
 		if (psmouse->pktcnt == 3) {
Josh Boyer 5c86018
@@ -857,15 +854,15 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	/* Check for PS/2 packet stuffed in the middle of ALPS packet. */
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if ((model->flags & ALPS_PS2_INTERLEAVED) &&
Josh Boyer 5c86018
+	if ((priv->flags & ALPS_PS2_INTERLEAVED) &&
Josh Boyer 5c86018
 	    psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) {
Josh Boyer 5c86018
 		return alps_handle_interleaved_ps2(psmouse);
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (!alps_is_valid_first_byte(model, psmouse->packet[0])) {
Josh Boyer 5c86018
+	if (!alps_is_valid_first_byte(priv, psmouse->packet[0])) {
Josh Boyer 5c86018
 		psmouse_dbg(psmouse,
Josh Boyer 5c86018
 			    "refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n",
Josh Boyer 5c86018
-			    psmouse->packet[0], model->mask0, model->byte0);
Josh Boyer 5c86018
+			    psmouse->packet[0], priv->mask0, priv->byte0);
Josh Boyer 5c86018
 		return PSMOUSE_BAD_DATA;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1190,16 +1187,16 @@ static int alps_poll(struct psmouse *psmouse)
Josh Boyer 5c86018
 	unsigned char buf[sizeof(psmouse->packet)];
Josh Boyer 5c86018
 	bool poll_failed;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (priv->i->flags & ALPS_PASS)
Josh Boyer 5c86018
+	if (priv->flags & ALPS_PASS)
Josh Boyer 5c86018
 		alps_passthrough_mode_v2(psmouse, true);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	poll_failed = ps2_command(&psmouse->ps2dev, buf,
Josh Boyer 5c86018
 				  PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (priv->i->flags & ALPS_PASS)
Josh Boyer 5c86018
+	if (priv->flags & ALPS_PASS)
Josh Boyer 5c86018
 		alps_passthrough_mode_v2(psmouse, false);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
Josh Boyer 5c86018
+	if (poll_failed || (buf[0] & priv->mask0) != priv->byte0)
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if ((psmouse->badbyte & 0xc8) == 0x08) {
Josh Boyer 5c86018
@@ -1217,9 +1214,8 @@ static int alps_poll(struct psmouse *psmouse)
Josh Boyer 5c86018
 static int alps_hw_init_v1_v2(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
-	const struct alps_model_info *model = priv->i;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if ((model->flags & ALPS_PASS) &&
Josh Boyer 5c86018
+	if ((priv->flags & ALPS_PASS) &&
Josh Boyer 5c86018
 	    alps_passthrough_mode_v2(psmouse, true)) {
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
@@ -1234,7 +1230,7 @@ static int alps_hw_init_v1_v2(struct psmouse *psmouse)
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if ((model->flags & ALPS_PASS) &&
Josh Boyer 5c86018
+	if ((priv->flags & ALPS_PASS) &&
Josh Boyer 5c86018
 	    alps_passthrough_mode_v2(psmouse, false)) {
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
@@ -1520,10 +1516,9 @@ error:
Josh Boyer 5c86018
 static int alps_hw_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
-	const struct alps_model_info *model = priv->i;
Josh Boyer 5c86018
 	int ret = -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	switch (model->proto_version) {
Josh Boyer 5c86018
+	switch (priv->proto_version) {
Josh Boyer 5c86018
 	case ALPS_PROTO_V1:
Josh Boyer 5c86018
 	case ALPS_PROTO_V2:
Josh Boyer 5c86018
 		ret = alps_hw_init_v1_v2(psmouse);
Josh Boyer 5c86018
@@ -1585,7 +1580,10 @@ int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 	if (!model)
Josh Boyer 5c86018
 		goto init_fail;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	priv->i = model;
Josh Boyer 5c86018
+	priv->proto_version = model->proto_version;
Josh Boyer 5c86018
+	priv->byte0 = model->byte0;
Josh Boyer 5c86018
+	priv->mask0 = model->mask0;
Josh Boyer 5c86018
+	priv->flags = model->flags;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (alps_hw_init(psmouse))
Josh Boyer 5c86018
 		goto init_fail;
Josh Boyer 5c86018
@@ -1609,7 +1607,7 @@ int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	switch (model->proto_version) {
Josh Boyer 5c86018
+	switch (priv->proto_version) {
Josh Boyer 5c86018
 	case ALPS_PROTO_V1:
Josh Boyer 5c86018
 	case ALPS_PROTO_V2:
Josh Boyer 5c86018
 		input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
Josh Boyer 5c86018
@@ -1633,17 +1631,17 @@ int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model->flags & ALPS_WHEEL) {
Josh Boyer 5c86018
+	if (priv->flags & ALPS_WHEEL) {
Josh Boyer 5c86018
 		dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
Josh Boyer 5c86018
 		dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
Josh Boyer 5c86018
+	if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
Josh Boyer 5c86018
 		dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
Josh Boyer 5c86018
 		dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model->flags & ALPS_FOUR_BUTTONS) {
Josh Boyer 5c86018
+	if (priv->flags & ALPS_FOUR_BUTTONS) {
Josh Boyer 5c86018
 		dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0);
Josh Boyer 5c86018
 		dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
Josh Boyer 5c86018
 		dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2);
Josh Boyer 5c86018
@@ -1654,7 +1652,8 @@ int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
Josh Boyer 5c86018
 	dev2->phys = priv->phys;
Josh Boyer 5c86018
-	dev2->name = (model->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
Josh Boyer 5c86018
+	dev2->name = (priv->flags & ALPS_DUALPOINT) ?
Josh Boyer 5c86018
+		     "DualPoint Stick" : "PS/2 Mouse";
Josh Boyer 5c86018
 	dev2->id.bustype = BUS_I8042;
Josh Boyer 5c86018
 	dev2->id.vendor  = 0x0002;
Josh Boyer 5c86018
 	dev2->id.product = PSMOUSE_ALPS;
Josh Boyer 5c86018
@@ -1673,7 +1672,7 @@ int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 	psmouse->poll = alps_poll;
Josh Boyer 5c86018
 	psmouse->disconnect = alps_disconnect;
Josh Boyer 5c86018
 	psmouse->reconnect = alps_reconnect;
Josh Boyer 5c86018
-	psmouse->pktsize = model->proto_version == ALPS_PROTO_V4 ? 8 : 6;
Josh Boyer 5c86018
+	psmouse->pktsize = priv->proto_version == ALPS_PROTO_V4 ? 8 : 6;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	/* We are having trouble resyncing ALPS touchpads so disable it for now */
Josh Boyer 5c86018
 	psmouse->resync_time = 0;
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
index 67be4e5..efd0eea 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.h
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
@@ -63,10 +63,15 @@ struct alps_nibble_commands {
Josh Boyer 5c86018
  * struct alps_data - private data structure for the ALPS driver
Josh Boyer 5c86018
  * @dev2: "Relative" device used to report trackstick or mouse activity.
Josh Boyer 5c86018
  * @phys: Physical path for the relative device.
Josh Boyer 5c86018
- * @i: Information on the detected touchpad model.
Josh Boyer 5c86018
  * @nibble_commands: Command mapping used for touchpad register accesses.
Josh Boyer 5c86018
  * @addr_command: Command used to tell the touchpad that a register address
Josh Boyer 5c86018
  *   follows.
Josh Boyer 5c86018
+ * @proto_version: Indicates V1/V2/V3/...
Josh Boyer 5c86018
+ * @byte0: Helps figure out whether a position report packet matches the
Josh Boyer 5c86018
+ *   known format for this model.  The first byte of the report, ANDed with
Josh Boyer 5c86018
+ *   mask0, should match byte0.
Josh Boyer 5c86018
+ * @mask0: The mask used to check the first byte of the report.
Josh Boyer 5c86018
+ * @flags: Additional device capabilities (passthrough port, trackstick, etc.).
Josh Boyer 5c86018
  * @prev_fin: Finger bit from previous packet.
Josh Boyer 5c86018
  * @multi_packet: Multi-packet data in progress.
Josh Boyer 5c86018
  * @multi_data: Saved multi-packet data.
Josh Boyer 5c86018
@@ -81,9 +86,14 @@ struct alps_nibble_commands {
Josh Boyer 5c86018
 struct alps_data {
Josh Boyer 5c86018
 	struct input_dev *dev2;
Josh Boyer 5c86018
 	char phys[32];
Josh Boyer 5c86018
-	const struct alps_model_info *i;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	/* these are autodetected when the device is identified */
Josh Boyer 5c86018
 	const struct alps_nibble_commands *nibble_commands;
Josh Boyer 5c86018
 	int addr_command;
Josh Boyer 5c86018
+	unsigned char proto_version;
Josh Boyer 5c86018
+	unsigned char byte0, mask0;
Josh Boyer 5c86018
+	unsigned char flags;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 	int prev_fin;
Josh Boyer 5c86018
 	int multi_packet;
Josh Boyer 5c86018
 	unsigned char multi_data[6];
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From b856c913996a38ced60bdf41aeae4da00882bf1f Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 20:57:04 -0800
Josh Boyer 5c86018
Subject: [PATCH 03/15] Input: ALPS - move alps_get_model() down below hw_init
Josh Boyer 5c86018
 code
Josh Boyer 5c86018
Josh Boyer 5c86018
This will minimize the number of forward declarations needed when
Josh Boyer 5c86018
alps_get_model() starts assigning function pointers.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 186 ++++++++++++++++++++++-----------------------
Josh Boyer 5c86018
 1 file changed, 93 insertions(+), 93 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index 33ee6e0..c473549 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -998,99 +998,6 @@ static inline int alps_exit_command_mode(struct psmouse *psmouse)
Josh Boyer 5c86018
 	return 0;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
Josh Boyer 5c86018
-{
Josh Boyer 5c86018
-	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
-	static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
Josh Boyer 5c86018
-	unsigned char param[4];
Josh Boyer 5c86018
-	const struct alps_model_info *model = NULL;
Josh Boyer 5c86018
-	int i;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	/*
Josh Boyer 5c86018
-	 * First try "E6 report".
Josh Boyer 5c86018
-	 * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed.
Josh Boyer 5c86018
-	 * The bits 0-2 of the first byte will be 1s if some buttons are
Josh Boyer 5c86018
-	 * pressed.
Josh Boyer 5c86018
-	 */
Josh Boyer 5c86018
-	param[0] = 0;
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	param[0] = param[1] = param[2] = 0xff;
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	psmouse_dbg(psmouse, "E6 report: %2.2x %2.2x %2.2x",
Josh Boyer 5c86018
-		    param[0], param[1], param[2]);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	if ((param[0] & 0xf8) != 0 || param[1] != 0 ||
Josh Boyer 5c86018
-	    (param[2] != 10 && param[2] != 100))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	/*
Josh Boyer 5c86018
-	 * Now try "E7 report". Allowed responses are in
Josh Boyer 5c86018
-	 * alps_model_data[].signature
Josh Boyer 5c86018
-	 */
Josh Boyer 5c86018
-	param[0] = 0;
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	param[0] = param[1] = param[2] = 0xff;
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	psmouse_dbg(psmouse, "E7 report: %2.2x %2.2x %2.2x",
Josh Boyer 5c86018
-		    param[0], param[1], param[2]);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	if (version) {
Josh Boyer 5c86018
-		for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
Josh Boyer 5c86018
-			/* empty */;
Josh Boyer 5c86018
-		*version = (param[0] << 8) | (param[1] << 4) | i;
Josh Boyer 5c86018
-	}
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
Josh Boyer 5c86018
-		if (!memcmp(param, alps_model_data[i].signature,
Josh Boyer 5c86018
-			    sizeof(alps_model_data[i].signature))) {
Josh Boyer 5c86018
-			model = alps_model_data + i;
Josh Boyer 5c86018
-			break;
Josh Boyer 5c86018
-		}
Josh Boyer 5c86018
-	}
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	if (model && model->proto_version > ALPS_PROTO_V2) {
Josh Boyer 5c86018
-		/*
Josh Boyer 5c86018
-		 * Need to check command mode response to identify
Josh Boyer 5c86018
-		 * model
Josh Boyer 5c86018
-		 */
Josh Boyer 5c86018
-		model = NULL;
Josh Boyer 5c86018
-		if (alps_enter_command_mode(psmouse, param)) {
Josh Boyer 5c86018
-			psmouse_warn(psmouse,
Josh Boyer 5c86018
-				     "touchpad failed to enter command mode\n");
Josh Boyer 5c86018
-		} else {
Josh Boyer 5c86018
-			for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
Josh Boyer 5c86018
-				if (alps_model_data[i].proto_version > ALPS_PROTO_V2 &&
Josh Boyer 5c86018
-				    alps_model_data[i].command_mode_resp == param[0]) {
Josh Boyer 5c86018
-					model = alps_model_data + i;
Josh Boyer 5c86018
-					break;
Josh Boyer 5c86018
-				}
Josh Boyer 5c86018
-			}
Josh Boyer 5c86018
-			alps_exit_command_mode(psmouse);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-			if (!model)
Josh Boyer 5c86018
-				psmouse_dbg(psmouse,
Josh Boyer 5c86018
-					    "Unknown command mode response %2.2x\n",
Josh Boyer 5c86018
-					    param[0]);
Josh Boyer 5c86018
-		}
Josh Boyer 5c86018
-	}
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	return model;
Josh Boyer 5c86018
-}
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 /*
Josh Boyer 5c86018
  * For DualPoint devices select the device that should respond to
Josh Boyer 5c86018
  * subsequent commands. It looks like glidepad is behind stickpointer,
Josh Boyer 5c86018
@@ -1534,6 +1441,99 @@ static int alps_hw_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 	return ret;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
+	static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
Josh Boyer 5c86018
+	unsigned char param[4];
Josh Boyer 5c86018
+	const struct alps_model_info *model = NULL;
Josh Boyer 5c86018
+	int i;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	/*
Josh Boyer 5c86018
+	 * First try "E6 report".
Josh Boyer 5c86018
+	 * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed.
Josh Boyer 5c86018
+	 * The bits 0-2 of the first byte will be 1s if some buttons are
Josh Boyer 5c86018
+	 * pressed.
Josh Boyer 5c86018
+	 */
Josh Boyer 5c86018
+	param[0] = 0;
Josh Boyer 5c86018
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11))
Josh Boyer 5c86018
+		return NULL;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	param[0] = param[1] = param[2] = 0xff;
Josh Boyer 5c86018
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
Josh Boyer 5c86018
+		return NULL;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	psmouse_dbg(psmouse, "E6 report: %2.2x %2.2x %2.2x",
Josh Boyer 5c86018
+		    param[0], param[1], param[2]);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	if ((param[0] & 0xf8) != 0 || param[1] != 0 ||
Josh Boyer 5c86018
+	    (param[2] != 10 && param[2] != 100))
Josh Boyer 5c86018
+		return NULL;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	/*
Josh Boyer 5c86018
+	 * Now try "E7 report". Allowed responses are in
Josh Boyer 5c86018
+	 * alps_model_data[].signature
Josh Boyer 5c86018
+	 */
Josh Boyer 5c86018
+	param[0] = 0;
Josh Boyer 5c86018
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21))
Josh Boyer 5c86018
+		return NULL;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	param[0] = param[1] = param[2] = 0xff;
Josh Boyer 5c86018
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
Josh Boyer 5c86018
+		return NULL;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	psmouse_dbg(psmouse, "E7 report: %2.2x %2.2x %2.2x",
Josh Boyer 5c86018
+		    param[0], param[1], param[2]);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	if (version) {
Josh Boyer 5c86018
+		for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
Josh Boyer 5c86018
+			/* empty */;
Josh Boyer 5c86018
+		*version = (param[0] << 8) | (param[1] << 4) | i;
Josh Boyer 5c86018
+	}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
Josh Boyer 5c86018
+		if (!memcmp(param, alps_model_data[i].signature,
Josh Boyer 5c86018
+			    sizeof(alps_model_data[i].signature))) {
Josh Boyer 5c86018
+			model = alps_model_data + i;
Josh Boyer 5c86018
+			break;
Josh Boyer 5c86018
+		}
Josh Boyer 5c86018
+	}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	if (model && model->proto_version > ALPS_PROTO_V2) {
Josh Boyer 5c86018
+		/*
Josh Boyer 5c86018
+		 * Need to check command mode response to identify
Josh Boyer 5c86018
+		 * model
Josh Boyer 5c86018
+		 */
Josh Boyer 5c86018
+		model = NULL;
Josh Boyer 5c86018
+		if (alps_enter_command_mode(psmouse, param)) {
Josh Boyer 5c86018
+			psmouse_warn(psmouse,
Josh Boyer 5c86018
+				     "touchpad failed to enter command mode\n");
Josh Boyer 5c86018
+		} else {
Josh Boyer 5c86018
+			for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
Josh Boyer 5c86018
+				if (alps_model_data[i].proto_version > ALPS_PROTO_V2 &&
Josh Boyer 5c86018
+				    alps_model_data[i].command_mode_resp == param[0]) {
Josh Boyer 5c86018
+					model = alps_model_data + i;
Josh Boyer 5c86018
+					break;
Josh Boyer 5c86018
+				}
Josh Boyer 5c86018
+			}
Josh Boyer 5c86018
+			alps_exit_command_mode(psmouse);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+			if (!model)
Josh Boyer 5c86018
+				psmouse_dbg(psmouse,
Josh Boyer 5c86018
+					    "Unknown command mode response %2.2x\n",
Josh Boyer 5c86018
+					    param[0]);
Josh Boyer 5c86018
+		}
Josh Boyer 5c86018
+	}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	return model;
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 static int alps_reconnect(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	const struct alps_model_info *model;
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From b719d56d5743e2c338568f4edb6eab17ea9c9eec Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:19:01 -0800
Josh Boyer 5c86018
Subject: [PATCH 04/15] Input: ALPS - introduce helper function for repeated
Josh Boyer 5c86018
 commands
Josh Boyer 5c86018
Josh Boyer 5c86018
Several ALPS driver init sequences repeat a command three times, then
Josh Boyer 5c86018
issue PSMOUSE_CMD_GETINFO to read the result.  Move this into a helper
Josh Boyer 5c86018
function to simplify the code.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 71 ++++++++++++++++++++--------------------------
Josh Boyer 5c86018
 1 file changed, 30 insertions(+), 41 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index c473549..1ca854b 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -964,24 +964,42 @@ static int alps_command_mode_write_reg(struct psmouse *psmouse, int addr,
Josh Boyer 5c86018
 	return __alps_command_mode_write_reg(psmouse, value);
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
Josh Boyer 5c86018
+			int repeated_command, unsigned char *param)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	param[0] = 0;
Josh Boyer 5c86018
+	if (init_command && ps2_command(ps2dev, param, init_command))
Josh Boyer 5c86018
+		return -EIO;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	if (ps2_command(ps2dev,  NULL, repeated_command) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev,  NULL, repeated_command) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev,  NULL, repeated_command))
Josh Boyer 5c86018
+		return -EIO;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	param[0] = param[1] = param[2] = 0xff;
Josh Boyer 5c86018
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
Josh Boyer 5c86018
+		return -EIO;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	psmouse_dbg(psmouse, "%2.2X report: %2.2x %2.2x %2.2x\n",
Josh Boyer 5c86018
+		    repeated_command, param[0], param[1], param[2]);
Josh Boyer 5c86018
+	return 0;
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 static int alps_enter_command_mode(struct psmouse *psmouse,
Josh Boyer 5c86018
 				   unsigned char *resp)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	unsigned char param[4];
Josh Boyer 5c86018
-	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
Josh Boyer 5c86018
+	if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_RESET_WRAP, param)) {
Josh Boyer 5c86018
 		psmouse_err(psmouse, "failed to enter command mode\n");
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (param[0] != 0x88 && param[1] != 0x07) {
Josh Boyer 5c86018
 		psmouse_dbg(psmouse,
Josh Boyer 5c86018
-			    "unknown response while entering command mode: %2.2x %2.2x %2.2x\n",
Josh Boyer 5c86018
-			    param[0], param[1], param[2]);
Josh Boyer 5c86018
+			    "unknown response while entering command mode\n");
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1041,18 +1059,10 @@ static int alps_absolute_mode_v1_v2(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static int alps_get_status(struct psmouse *psmouse, char *param)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	/* Get status: 0xF5 0xF5 0xF5 0xE9 */
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
Josh Boyer 5c86018
+	if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_DISABLE, param))
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	psmouse_dbg(psmouse, "Status: %2.2x %2.2x %2.2x",
Josh Boyer 5c86018
-		    param[0], param[1], param[2]);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	return 0;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1443,7 +1453,6 @@ static int alps_hw_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
 	static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
Josh Boyer 5c86018
 	unsigned char param[4];
Josh Boyer 5c86018
 	const struct alps_model_info *model = NULL;
Josh Boyer 5c86018
@@ -1455,20 +1464,10 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
Josh Boyer 5c86018
 	 * The bits 0-2 of the first byte will be 1s if some buttons are
Josh Boyer 5c86018
 	 * pressed.
Josh Boyer 5c86018
 	 */
Josh Boyer 5c86018
-	param[0] = 0;
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	param[0] = param[1] = param[2] = 0xff;
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
Josh Boyer 5c86018
+	if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, PSMOUSE_CMD_SETSCALE11,
Josh Boyer 5c86018
+			 param))
Josh Boyer 5c86018
 		return NULL;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	psmouse_dbg(psmouse, "E6 report: %2.2x %2.2x %2.2x",
Josh Boyer 5c86018
-		    param[0], param[1], param[2]);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	if ((param[0] & 0xf8) != 0 || param[1] != 0 ||
Josh Boyer 5c86018
 	    (param[2] != 10 && param[2] != 100))
Josh Boyer 5c86018
 		return NULL;
Josh Boyer 5c86018
@@ -1477,20 +1476,10 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
Josh Boyer 5c86018
 	 * Now try "E7 report". Allowed responses are in
Josh Boyer 5c86018
 	 * alps_model_data[].signature
Josh Boyer 5c86018
 	 */
Josh Boyer 5c86018
-	param[0] = 0;
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
Josh Boyer 5c86018
-	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	param[0] = param[1] = param[2] = 0xff;
Josh Boyer 5c86018
-	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
Josh Boyer 5c86018
+	if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, PSMOUSE_CMD_SETSCALE21,
Josh Boyer 5c86018
+			 param))
Josh Boyer 5c86018
 		return NULL;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	psmouse_dbg(psmouse, "E7 report: %2.2x %2.2x %2.2x",
Josh Boyer 5c86018
-		    param[0], param[1], param[2]);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	if (version) {
Josh Boyer 5c86018
 		for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
Josh Boyer 5c86018
 			/* empty */;
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From c7fd5d0e90f577072ece70651aeecb37f62f5fdb Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:19:59 -0800
Josh Boyer 5c86018
Subject: [PATCH 05/15] Input: ALPS - rework detection sequence
Josh Boyer 5c86018
Josh Boyer 5c86018
If the E6 report test passes, get the E7 and EC reports right away and
Josh Boyer 5c86018
then try to match an entry in the table.
Josh Boyer 5c86018
Josh Boyer 5c86018
Pass in the alps_data struct, so that the detection code will be able to
Josh Boyer 5c86018
set operating parameters based on information found during detection.
Josh Boyer 5c86018
Josh Boyer 5c86018
Change the version (psmouse->model) to report the protocol version only,
Josh Boyer 5c86018
in preparation for supporting models that do not show up in the ID table.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 124 +++++++++++++++++++--------------------------
Josh Boyer 5c86018
 drivers/input/mouse/alps.h |   8 +--
Josh Boyer 5c86018
 2 files changed, 56 insertions(+), 76 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index 1ca854b..e6a27a5 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -1451,86 +1451,76 @@ static int alps_hw_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 	return ret;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
Josh Boyer 5c86018
+static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv,
Josh Boyer 5c86018
+			    unsigned char *e7, unsigned char *ec)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
Josh Boyer 5c86018
-	unsigned char param[4];
Josh Boyer 5c86018
-	const struct alps_model_info *model = NULL;
Josh Boyer 5c86018
+	const struct alps_model_info *model;
Josh Boyer 5c86018
 	int i;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+	for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
Josh Boyer 5c86018
+		model = &alps_model_data[i];
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+		if (!memcmp(e7, model->signature, sizeof(model->signature)) &&
Josh Boyer 5c86018
+		    (!model->command_mode_resp ||
Josh Boyer 5c86018
+		     model->command_mode_resp == ec[2])) {
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+			priv->proto_version = model->proto_version;
Josh Boyer 5c86018
+			priv->flags = model->flags;
Josh Boyer 5c86018
+			priv->byte0 = model->byte0;
Josh Boyer 5c86018
+			priv->mask0 = model->mask0;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+			return 0;
Josh Boyer 5c86018
+		}
Josh Boyer 5c86018
+	}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	return -EINVAL;
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	unsigned char e6[4], e7[4], ec[4];
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 	/*
Josh Boyer 5c86018
 	 * First try "E6 report".
Josh Boyer 5c86018
 	 * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed.
Josh Boyer 5c86018
 	 * The bits 0-2 of the first byte will be 1s if some buttons are
Josh Boyer 5c86018
 	 * pressed.
Josh Boyer 5c86018
 	 */
Josh Boyer 5c86018
-	if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, PSMOUSE_CMD_SETSCALE11,
Josh Boyer 5c86018
-			 param))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
+	if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
Josh Boyer 5c86018
+			 PSMOUSE_CMD_SETSCALE11, e6))
Josh Boyer 5c86018
+		return -EIO;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if ((param[0] & 0xf8) != 0 || param[1] != 0 ||
Josh Boyer 5c86018
-	    (param[2] != 10 && param[2] != 100))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
+	if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && e6[2] != 100))
Josh Boyer 5c86018
+		return -EINVAL;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	/*
Josh Boyer 5c86018
-	 * Now try "E7 report". Allowed responses are in
Josh Boyer 5c86018
-	 * alps_model_data[].signature
Josh Boyer 5c86018
+	 * Now get the "E7" and "EC" reports.  These will uniquely identify
Josh Boyer 5c86018
+	 * most ALPS touchpads.
Josh Boyer 5c86018
 	 */
Josh Boyer 5c86018
-	if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, PSMOUSE_CMD_SETSCALE21,
Josh Boyer 5c86018
-			 param))
Josh Boyer 5c86018
-		return NULL;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	if (version) {
Josh Boyer 5c86018
-		for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
Josh Boyer 5c86018
-			/* empty */;
Josh Boyer 5c86018
-		*version = (param[0] << 8) | (param[1] << 4) | i;
Josh Boyer 5c86018
-	}
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
Josh Boyer 5c86018
-		if (!memcmp(param, alps_model_data[i].signature,
Josh Boyer 5c86018
-			    sizeof(alps_model_data[i].signature))) {
Josh Boyer 5c86018
-			model = alps_model_data + i;
Josh Boyer 5c86018
-			break;
Josh Boyer 5c86018
-		}
Josh Boyer 5c86018
-	}
Josh Boyer 5c86018
+	if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
Josh Boyer 5c86018
+			 PSMOUSE_CMD_SETSCALE21, e7) ||
Josh Boyer 5c86018
+	    alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
Josh Boyer 5c86018
+			 PSMOUSE_CMD_RESET_WRAP, ec) ||
Josh Boyer 5c86018
+	    alps_exit_command_mode(psmouse))
Josh Boyer 5c86018
+		return -EIO;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (model && model->proto_version > ALPS_PROTO_V2) {
Josh Boyer 5c86018
-		/*
Josh Boyer 5c86018
-		 * Need to check command mode response to identify
Josh Boyer 5c86018
-		 * model
Josh Boyer 5c86018
-		 */
Josh Boyer 5c86018
-		model = NULL;
Josh Boyer 5c86018
-		if (alps_enter_command_mode(psmouse, param)) {
Josh Boyer 5c86018
-			psmouse_warn(psmouse,
Josh Boyer 5c86018
-				     "touchpad failed to enter command mode\n");
Josh Boyer 5c86018
-		} else {
Josh Boyer 5c86018
-			for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
Josh Boyer 5c86018
-				if (alps_model_data[i].proto_version > ALPS_PROTO_V2 &&
Josh Boyer 5c86018
-				    alps_model_data[i].command_mode_resp == param[0]) {
Josh Boyer 5c86018
-					model = alps_model_data + i;
Josh Boyer 5c86018
-					break;
Josh Boyer 5c86018
-				}
Josh Boyer 5c86018
-			}
Josh Boyer 5c86018
-			alps_exit_command_mode(psmouse);
Josh Boyer 5c86018
+	if (alps_match_table(psmouse, priv, e7, ec) == 0)
Josh Boyer 5c86018
+		return 0;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-			if (!model)
Josh Boyer 5c86018
-				psmouse_dbg(psmouse,
Josh Boyer 5c86018
-					    "Unknown command mode response %2.2x\n",
Josh Boyer 5c86018
-					    param[0]);
Josh Boyer 5c86018
-		}
Josh Boyer 5c86018
-	}
Josh Boyer 5c86018
+	psmouse_info(psmouse,
Josh Boyer 5c86018
+		"Unknown ALPS touchpad: E7=%2.2x %2.2x %2.2x, EC=%2.2x %2.2x %2.2x\n",
Josh Boyer 5c86018
+		e7[0], e7[1], e7[2], ec[0], ec[1], ec[2]);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	return model;
Josh Boyer 5c86018
+	return -EINVAL;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static int alps_reconnect(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	const struct alps_model_info *model;
Josh Boyer 5c86018
+	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	psmouse_reset(psmouse);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	model = alps_get_model(psmouse, NULL);
Josh Boyer 5c86018
-	if (!model)
Josh Boyer 5c86018
+	if (alps_identify(psmouse, priv) < 0)
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	return alps_hw_init(psmouse);
Josh Boyer 5c86018
@@ -1549,9 +1539,7 @@ static void alps_disconnect(struct psmouse *psmouse)
Josh Boyer 5c86018
 int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv;
Josh Boyer 5c86018
-	const struct alps_model_info *model;
Josh Boyer 5c86018
 	struct input_dev *dev1 = psmouse->dev, *dev2;
Josh Boyer 5c86018
-	int version;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
Josh Boyer 5c86018
 	dev2 = input_allocate_device();
Josh Boyer 5c86018
@@ -1565,15 +1553,9 @@ int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	psmouse_reset(psmouse);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	model = alps_get_model(psmouse, &version);
Josh Boyer 5c86018
-	if (!model)
Josh Boyer 5c86018
+	if (alps_identify(psmouse, priv) < 0)
Josh Boyer 5c86018
 		goto init_fail;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	priv->proto_version = model->proto_version;
Josh Boyer 5c86018
-	priv->byte0 = model->byte0;
Josh Boyer 5c86018
-	priv->mask0 = model->mask0;
Josh Boyer 5c86018
-	priv->flags = model->flags;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	if (alps_hw_init(psmouse))
Josh Boyer 5c86018
 		goto init_fail;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1678,18 +1660,16 @@ init_fail:
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 int alps_detect(struct psmouse *psmouse, bool set_properties)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	int version;
Josh Boyer 5c86018
-	const struct alps_model_info *model;
Josh Boyer 5c86018
+	struct alps_data dummy;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	model = alps_get_model(psmouse, &version);
Josh Boyer 5c86018
-	if (!model)
Josh Boyer 5c86018
+	if (alps_identify(psmouse, &dummy) < 0)
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (set_properties) {
Josh Boyer 5c86018
 		psmouse->vendor = "ALPS";
Josh Boyer 5c86018
-		psmouse->name = model->flags & ALPS_DUALPOINT ?
Josh Boyer 5c86018
+		psmouse->name = dummy.flags & ALPS_DUALPOINT ?
Josh Boyer 5c86018
 				"DualPoint TouchPad" : "GlidePoint";
Josh Boyer 5c86018
-		psmouse->model = version;
Josh Boyer 5c86018
+		psmouse->model = dummy.proto_version << 8;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 	return 0;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
index efd0eea..a81b318 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.h
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
@@ -12,10 +12,10 @@
Josh Boyer 5c86018
 #ifndef _ALPS_H
Josh Boyer 5c86018
 #define _ALPS_H
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-#define ALPS_PROTO_V1	0
Josh Boyer 5c86018
-#define ALPS_PROTO_V2	1
Josh Boyer 5c86018
-#define ALPS_PROTO_V3	2
Josh Boyer 5c86018
-#define ALPS_PROTO_V4	3
Josh Boyer 5c86018
+#define ALPS_PROTO_V1	1
Josh Boyer 5c86018
+#define ALPS_PROTO_V2	2
Josh Boyer 5c86018
+#define ALPS_PROTO_V3	3
Josh Boyer 5c86018
+#define ALPS_PROTO_V4	4
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 /**
Josh Boyer 5c86018
  * struct alps_model_info - touchpad ID table
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From c7fb8a63ba1257e2ee829425ef7197c7cbe893a1 Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:22:08 -0800
Josh Boyer 5c86018
Subject: [PATCH 06/15] Input: ALPS - use function pointers for different
Josh Boyer 5c86018
 protocol handlers
Josh Boyer 5c86018
Josh Boyer 5c86018
In anticipation of adding more ALPS protocols and more per-device quirks,
Josh Boyer 5c86018
use function pointers instead of switch statements to call functions that
Josh Boyer 5c86018
differ from one device to the next.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 101 +++++++++++++++++++++------------------------
Josh Boyer 5c86018
 drivers/input/mouse/alps.h |   7 ++++
Josh Boyer 5c86018
 2 files changed, 54 insertions(+), 54 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index e6a27a5..fe45687 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -114,6 +114,11 @@ static const struct alps_model_info alps_model_data[] = {
Josh Boyer 5c86018
 	{ { 0x73, 0x02, 0x64 },	0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 },
Josh Boyer 5c86018
 };
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+static void alps_set_abs_params_st(struct alps_data *priv,
Josh Boyer 5c86018
+				   struct input_dev *dev1);
Josh Boyer 5c86018
+static void alps_set_abs_params_mt(struct alps_data *priv,
Josh Boyer 5c86018
+				   struct input_dev *dev1);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 /*
Josh Boyer 5c86018
  * XXX - this entry is suspicious. First byte has zero lower nibble,
Josh Boyer 5c86018
  * which is what a normal mouse would report. Also, the value 0x0e
Josh Boyer 5c86018
@@ -695,24 +700,6 @@ static void alps_process_packet_v4(struct psmouse *psmouse)
Josh Boyer 5c86018
 	input_sync(dev);
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-static void alps_process_packet(struct psmouse *psmouse)
Josh Boyer 5c86018
-{
Josh Boyer 5c86018
-	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	switch (priv->proto_version) {
Josh Boyer 5c86018
-	case ALPS_PROTO_V1:
Josh Boyer 5c86018
-	case ALPS_PROTO_V2:
Josh Boyer 5c86018
-		alps_process_packet_v1_v2(psmouse);
Josh Boyer 5c86018
-		break;
Josh Boyer 5c86018
-	case ALPS_PROTO_V3:
Josh Boyer 5c86018
-		alps_process_packet_v3(psmouse);
Josh Boyer 5c86018
-		break;
Josh Boyer 5c86018
-	case ALPS_PROTO_V4:
Josh Boyer 5c86018
-		alps_process_packet_v4(psmouse);
Josh Boyer 5c86018
-		break;
Josh Boyer 5c86018
-	}
Josh Boyer 5c86018
-}
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
Josh Boyer 5c86018
 					unsigned char packet[],
Josh Boyer 5c86018
 					bool report_buttons)
Josh Boyer 5c86018
@@ -770,7 +757,7 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
Josh Boyer 5c86018
 			return PSMOUSE_BAD_DATA;
Josh Boyer 5c86018
 		}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-		alps_process_packet(psmouse);
Josh Boyer 5c86018
+		priv->process_packet(psmouse);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 		/* Continue with the next packet */
Josh Boyer 5c86018
 		psmouse->packet[0] = psmouse->packet[6];
Josh Boyer 5c86018
@@ -814,6 +801,7 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
Josh Boyer 5c86018
 static void alps_flush_packet(unsigned long data)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct psmouse *psmouse = (struct psmouse *)data;
Josh Boyer 5c86018
+	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	serio_pause_rx(psmouse->ps2dev.serio);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -831,7 +819,7 @@ static void alps_flush_packet(unsigned long data)
Josh Boyer 5c86018
 				    "refusing packet %3ph (suspected interleaved ps/2)\n",
Josh Boyer 5c86018
 				    psmouse->packet + 3);
Josh Boyer 5c86018
 		} else {
Josh Boyer 5c86018
-			alps_process_packet(psmouse);
Josh Boyer 5c86018
+			priv->process_packet(psmouse);
Josh Boyer 5c86018
 		}
Josh Boyer 5c86018
 		psmouse->pktcnt = 0;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
@@ -876,7 +864,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (psmouse->pktcnt == psmouse->pktsize) {
Josh Boyer 5c86018
-		alps_process_packet(psmouse);
Josh Boyer 5c86018
+		priv->process_packet(psmouse);
Josh Boyer 5c86018
 		return PSMOUSE_FULL_PACKET;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1430,25 +1418,26 @@ error:
Josh Boyer 5c86018
 	return -1;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-static int alps_hw_init(struct psmouse *psmouse)
Josh Boyer 5c86018
+static void alps_set_defaults(struct alps_data *priv)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
-	int ret = -1;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	switch (priv->proto_version) {
Josh Boyer 5c86018
 	case ALPS_PROTO_V1:
Josh Boyer 5c86018
 	case ALPS_PROTO_V2:
Josh Boyer 5c86018
-		ret = alps_hw_init_v1_v2(psmouse);
Josh Boyer 5c86018
+		priv->hw_init = alps_hw_init_v1_v2;
Josh Boyer 5c86018
+		priv->process_packet = alps_process_packet_v1_v2;
Josh Boyer 5c86018
+		priv->set_abs_params = alps_set_abs_params_st;
Josh Boyer 5c86018
 		break;
Josh Boyer 5c86018
 	case ALPS_PROTO_V3:
Josh Boyer 5c86018
-		ret = alps_hw_init_v3(psmouse);
Josh Boyer 5c86018
+		priv->hw_init = alps_hw_init_v3;
Josh Boyer 5c86018
+		priv->process_packet = alps_process_packet_v3;
Josh Boyer 5c86018
+		priv->set_abs_params = alps_set_abs_params_mt;
Josh Boyer 5c86018
 		break;
Josh Boyer 5c86018
 	case ALPS_PROTO_V4:
Josh Boyer 5c86018
-		ret = alps_hw_init_v4(psmouse);
Josh Boyer 5c86018
+		priv->hw_init = alps_hw_init_v4;
Josh Boyer 5c86018
+		priv->process_packet = alps_process_packet_v4;
Josh Boyer 5c86018
+		priv->set_abs_params = alps_set_abs_params_mt;
Josh Boyer 5c86018
 		break;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	return ret;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv,
Josh Boyer 5c86018
@@ -1465,6 +1454,8 @@ static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv,
Josh Boyer 5c86018
 		     model->command_mode_resp == ec[2])) {
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 			priv->proto_version = model->proto_version;
Josh Boyer 5c86018
+			alps_set_defaults(priv);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 			priv->flags = model->flags;
Josh Boyer 5c86018
 			priv->byte0 = model->byte0;
Josh Boyer 5c86018
 			priv->mask0 = model->mask0;
Josh Boyer 5c86018
@@ -1523,7 +1514,7 @@ static int alps_reconnect(struct psmouse *psmouse)
Josh Boyer 5c86018
 	if (alps_identify(psmouse, priv) < 0)
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	return alps_hw_init(psmouse);
Josh Boyer 5c86018
+	return priv->hw_init(psmouse);
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static void alps_disconnect(struct psmouse *psmouse)
Josh Boyer 5c86018
@@ -1536,6 +1527,29 @@ static void alps_disconnect(struct psmouse *psmouse)
Josh Boyer 5c86018
 	kfree(priv);
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+static void alps_set_abs_params_st(struct alps_data *priv,
Josh Boyer 5c86018
+				   struct input_dev *dev1)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+static void alps_set_abs_params_mt(struct alps_data *priv,
Josh Boyer 5c86018
+				   struct input_dev *dev1)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
Josh Boyer 5c86018
+	input_mt_init_slots(dev1, 2, 0);
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0);
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit);
Josh Boyer 5c86018
+	set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
Josh Boyer 5c86018
+	set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0);
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0);
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv;
Josh Boyer 5c86018
@@ -1556,7 +1570,7 @@ int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 	if (alps_identify(psmouse, priv) < 0)
Josh Boyer 5c86018
 		goto init_fail;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (alps_hw_init(psmouse))
Josh Boyer 5c86018
+	if (priv->hw_init(psmouse))
Josh Boyer 5c86018
 		goto init_fail;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	/*
Josh Boyer 5c86018
@@ -1578,28 +1592,7 @@ int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	switch (priv->proto_version) {
Josh Boyer 5c86018
-	case ALPS_PROTO_V1:
Josh Boyer 5c86018
-	case ALPS_PROTO_V2:
Josh Boyer 5c86018
-		input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
Josh Boyer 5c86018
-		input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
Josh Boyer 5c86018
-		break;
Josh Boyer 5c86018
-	case ALPS_PROTO_V3:
Josh Boyer 5c86018
-	case ALPS_PROTO_V4:
Josh Boyer 5c86018
-		set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
Josh Boyer 5c86018
-		input_mt_init_slots(dev1, 2, 0);
Josh Boyer 5c86018
-		input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0);
Josh Boyer 5c86018
-		input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-		set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit);
Josh Boyer 5c86018
-		set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
Josh Boyer 5c86018
-		set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-		input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0);
Josh Boyer 5c86018
-		input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0);
Josh Boyer 5c86018
-		break;
Josh Boyer 5c86018
-	}
Josh Boyer 5c86018
-
Josh Boyer 5c86018
+	priv->set_abs_params(priv, dev1);
Josh Boyer 5c86018
 	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (priv->flags & ALPS_WHEEL) {
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
index a81b318..0934f8b 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.h
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
@@ -72,6 +72,9 @@ struct alps_nibble_commands {
Josh Boyer 5c86018
  *   mask0, should match byte0.
Josh Boyer 5c86018
  * @mask0: The mask used to check the first byte of the report.
Josh Boyer 5c86018
  * @flags: Additional device capabilities (passthrough port, trackstick, etc.).
Josh Boyer 5c86018
+ * @hw_init: Protocol-specific hardware init function.
Josh Boyer 5c86018
+ * @process_packet: Protocol-specific function to process a report packet.
Josh Boyer 5c86018
+ * @set_abs_params: Protocol-specific function to configure the input_dev.
Josh Boyer 5c86018
  * @prev_fin: Finger bit from previous packet.
Josh Boyer 5c86018
  * @multi_packet: Multi-packet data in progress.
Josh Boyer 5c86018
  * @multi_data: Saved multi-packet data.
Josh Boyer 5c86018
@@ -94,6 +97,10 @@ struct alps_data {
Josh Boyer 5c86018
 	unsigned char byte0, mask0;
Josh Boyer 5c86018
 	unsigned char flags;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+	int (*hw_init)(struct psmouse *psmouse);
Josh Boyer 5c86018
+	void (*process_packet)(struct psmouse *psmouse);
Josh Boyer 5c86018
+	void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 	int prev_fin;
Josh Boyer 5c86018
 	int multi_packet;
Josh Boyer 5c86018
 	unsigned char multi_data[6];
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From e2600c708bef8e1c8126ca9b8d4ce1f83c002688 Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:23:04 -0800
Josh Boyer 5c86018
Subject: [PATCH 07/15] Input: ALPS - move {addr,nibble}_command settings into
Josh Boyer 5c86018
 alps_set_defaults()
Josh Boyer 5c86018
Josh Boyer 5c86018
This allows alps_identify() to override these settings based on the
Josh Boyer 5c86018
device characteristics, if it is ever necessary.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 12 ++++--------
Josh Boyer 5c86018
 1 file changed, 4 insertions(+), 8 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index fe45687..2221a00 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -1190,14 +1190,10 @@ static int alps_absolute_mode_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static int alps_hw_init_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
 	int reg_val;
Josh Boyer 5c86018
 	unsigned char param[4];
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	priv->nibble_commands = alps_v3_nibble_commands;
Josh Boyer 5c86018
-	priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	if (alps_enter_command_mode(psmouse, NULL))
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1343,13 +1339,9 @@ static int alps_absolute_mode_v4(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static int alps_hw_init_v4(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
 	unsigned char param[4];
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	priv->nibble_commands = alps_v4_nibble_commands;
Josh Boyer 5c86018
-	priv->addr_command = PSMOUSE_CMD_DISABLE;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	if (alps_enter_command_mode(psmouse, NULL))
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1431,11 +1423,15 @@ static void alps_set_defaults(struct alps_data *priv)
Josh Boyer 5c86018
 		priv->hw_init = alps_hw_init_v3;
Josh Boyer 5c86018
 		priv->process_packet = alps_process_packet_v3;
Josh Boyer 5c86018
 		priv->set_abs_params = alps_set_abs_params_mt;
Josh Boyer 5c86018
+		priv->nibble_commands = alps_v3_nibble_commands;
Josh Boyer 5c86018
+		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
Josh Boyer 5c86018
 		break;
Josh Boyer 5c86018
 	case ALPS_PROTO_V4:
Josh Boyer 5c86018
 		priv->hw_init = alps_hw_init_v4;
Josh Boyer 5c86018
 		priv->process_packet = alps_process_packet_v4;
Josh Boyer 5c86018
 		priv->set_abs_params = alps_set_abs_params_mt;
Josh Boyer 5c86018
+		priv->nibble_commands = alps_v4_nibble_commands;
Josh Boyer 5c86018
+		priv->addr_command = PSMOUSE_CMD_DISABLE;
Josh Boyer 5c86018
 		break;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From df0bf385112a7b38c5c3d307bb9399f9f3b3bba2 Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:23:34 -0800
Josh Boyer 5c86018
Subject: [PATCH 08/15] Input: ALPS - rework detection of Pinnacle AGx
Josh Boyer 5c86018
 touchpads
Josh Boyer 5c86018
Josh Boyer 5c86018
The official ALPS driver uses the EC report, not the E7 report, to detect
Josh Boyer 5c86018
these devices.  Also, they check for a range of values; the original
Josh Boyer 5c86018
table-based code only checked for two specific ones.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 15 ++++++++++++---
Josh Boyer 5c86018
 1 file changed, 12 insertions(+), 3 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index 2221a00..eafeae2 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -109,8 +109,6 @@ static const struct alps_model_info alps_model_data[] = {
Josh Boyer 5c86018
 	{ { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },		/* Dell Vostro 1400 */
Josh Boyer 5c86018
 	{ { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff,
Josh Boyer 5c86018
 		ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },				/* Toshiba Tecra A11-11L */
Josh Boyer 5c86018
-	{ { 0x73, 0x02, 0x64 },	0x9b, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT },
Josh Boyer 5c86018
-	{ { 0x73, 0x02, 0x64 },	0x9d, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT },
Josh Boyer 5c86018
 	{ { 0x73, 0x02, 0x64 },	0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 },
Josh Boyer 5c86018
 };
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1412,6 +1410,10 @@ error:
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static void alps_set_defaults(struct alps_data *priv)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
+	priv->byte0 = 0x8f;
Josh Boyer 5c86018
+	priv->mask0 = 0x8f;
Josh Boyer 5c86018
+	priv->flags = ALPS_DUALPOINT;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 	switch (priv->proto_version) {
Josh Boyer 5c86018
 	case ALPS_PROTO_V1:
Josh Boyer 5c86018
 	case ALPS_PROTO_V2:
Josh Boyer 5c86018
@@ -1491,8 +1493,15 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
Josh Boyer 5c86018
 	    alps_exit_command_mode(psmouse))
Josh Boyer 5c86018
 		return -EIO;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (alps_match_table(psmouse, priv, e7, ec) == 0)
Josh Boyer 5c86018
+	if (alps_match_table(psmouse, priv, e7, ec) == 0) {
Josh Boyer 5c86018
+		return 0;
Josh Boyer 5c86018
+	} else if (ec[0] == 0x88 && ec[1] == 0x07 &&
Josh Boyer 5c86018
+		   ec[2] >= 0x90 && ec[2] <= 0x9d) {
Josh Boyer 5c86018
+		priv->proto_version = ALPS_PROTO_V3;
Josh Boyer 5c86018
+		alps_set_defaults(priv);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 		return 0;
Josh Boyer 5c86018
+	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	psmouse_info(psmouse,
Josh Boyer 5c86018
 		"Unknown ALPS touchpad: E7=%2.2x %2.2x %2.2x, EC=%2.2x %2.2x %2.2x\n",
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From 8e6493f800dc08a28abd59dfe63790aaade0c700 Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:24:22 -0800
Josh Boyer 5c86018
Subject: [PATCH 09/15] Input: ALPS - fix command mode check
Josh Boyer 5c86018
Josh Boyer 5c86018
Pinnacle class devices should return "88 07 xx" or "88 08 xx" when
Josh Boyer 5c86018
entering command mode.  If either the first byte or the second byte is
Josh Boyer 5c86018
invalid, return an error.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 2 +-
Josh Boyer 5c86018
 1 file changed, 1 insertion(+), 1 deletion(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index eafeae2..bfc1938 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -983,7 +983,7 @@ static int alps_enter_command_mode(struct psmouse *psmouse,
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (param[0] != 0x88 && param[1] != 0x07) {
Josh Boyer 5c86018
+	if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) {
Josh Boyer 5c86018
 		psmouse_dbg(psmouse,
Josh Boyer 5c86018
 			    "unknown response while entering command mode\n");
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From 0302b4c4a1b4201bf82a45c46084f3ccd0ee696f Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:24:55 -0800
Josh Boyer 5c86018
Subject: [PATCH 10/15] Input: ALPS - move pixel and bitmap info into alps_data
Josh Boyer 5c86018
 struct
Josh Boyer 5c86018
Josh Boyer 5c86018
Newer touchpads use different constants, so make them runtime-
Josh Boyer 5c86018
configurable.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 47 ++++++++++++++++++++++++----------------------
Josh Boyer 5c86018
 drivers/input/mouse/alps.h |  8 ++++++++
Josh Boyer 5c86018
 2 files changed, 33 insertions(+), 22 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index bfc1938..2cd8be7 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -27,12 +27,6 @@
Josh Boyer 5c86018
 /*
Josh Boyer 5c86018
  * Definitions for ALPS version 3 and 4 command mode protocol
Josh Boyer 5c86018
  */
Josh Boyer 5c86018
-#define ALPS_V3_X_MAX	2000
Josh Boyer 5c86018
-#define ALPS_V3_Y_MAX	1400
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-#define ALPS_BITMAP_X_BITS	15
Josh Boyer 5c86018
-#define ALPS_BITMAP_Y_BITS	11
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 #define ALPS_CMD_NIBBLE_10	0x01f2
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
Josh Boyer 5c86018
@@ -269,7 +263,8 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
Josh Boyer 5c86018
  * These points are returned in x1, y1, x2, and y2 when the return value
Josh Boyer 5c86018
  * is greater than 0.
Josh Boyer 5c86018
  */
Josh Boyer 5c86018
-static int alps_process_bitmap(unsigned int x_map, unsigned int y_map,
Josh Boyer 5c86018
+static int alps_process_bitmap(struct alps_data *priv,
Josh Boyer 5c86018
+			       unsigned int x_map, unsigned int y_map,
Josh Boyer 5c86018
 			       int *x1, int *y1, int *x2, int *y2)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_bitmap_point {
Josh Boyer 5c86018
@@ -311,7 +306,7 @@ static int alps_process_bitmap(unsigned int x_map, unsigned int y_map,
Josh Boyer 5c86018
 	 * y bitmap is reversed for what we need (lower positions are in
Josh Boyer 5c86018
 	 * higher bits), so we process from the top end.
Josh Boyer 5c86018
 	 */
Josh Boyer 5c86018
-	y_map = y_map << (sizeof(y_map) * BITS_PER_BYTE - ALPS_BITMAP_Y_BITS);
Josh Boyer 5c86018
+	y_map = y_map << (sizeof(y_map) * BITS_PER_BYTE - priv->y_bits);
Josh Boyer 5c86018
 	prev_bit = 0;
Josh Boyer 5c86018
 	point = &y_low;
Josh Boyer 5c86018
 	for (i = 0; y_map != 0; i++, y_map <<= 1) {
Josh Boyer 5c86018
@@ -357,16 +352,18 @@ static int alps_process_bitmap(unsigned int x_map, unsigned int y_map,
Josh Boyer 5c86018
 		}
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	*x1 = (ALPS_V3_X_MAX * (2 * x_low.start_bit + x_low.num_bits - 1)) /
Josh Boyer 5c86018
-	      (2 * (ALPS_BITMAP_X_BITS - 1));
Josh Boyer 5c86018
-	*y1 = (ALPS_V3_Y_MAX * (2 * y_low.start_bit + y_low.num_bits - 1)) /
Josh Boyer 5c86018
-	      (2 * (ALPS_BITMAP_Y_BITS - 1));
Josh Boyer 5c86018
+	*x1 = (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
Josh Boyer 5c86018
+	      (2 * (priv->x_bits - 1));
Josh Boyer 5c86018
+	*y1 = (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
Josh Boyer 5c86018
+	      (2 * (priv->y_bits - 1));
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (fingers > 1) {
Josh Boyer 5c86018
-		*x2 = (ALPS_V3_X_MAX * (2 * x_high.start_bit + x_high.num_bits - 1)) /
Josh Boyer 5c86018
-		      (2 * (ALPS_BITMAP_X_BITS - 1));
Josh Boyer 5c86018
-		*y2 = (ALPS_V3_Y_MAX * (2 * y_high.start_bit + y_high.num_bits - 1)) /
Josh Boyer 5c86018
-		      (2 * (ALPS_BITMAP_Y_BITS - 1));
Josh Boyer 5c86018
+		*x2 = (priv->x_max *
Josh Boyer 5c86018
+		       (2 * x_high.start_bit + x_high.num_bits - 1)) /
Josh Boyer 5c86018
+		      (2 * (priv->x_bits - 1));
Josh Boyer 5c86018
+		*y2 = (priv->y_max *
Josh Boyer 5c86018
+		       (2 * y_high.start_bit + y_high.num_bits - 1)) /
Josh Boyer 5c86018
+		      (2 * (priv->y_bits - 1));
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	return fingers;
Josh Boyer 5c86018
@@ -484,7 +481,8 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 				   ((packet[2] & 0x7f) << 1) |
Josh Boyer 5c86018
 				   (packet[4] & 0x01);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-			bmap_fingers = alps_process_bitmap(x_bitmap, y_bitmap,
Josh Boyer 5c86018
+			bmap_fingers = alps_process_bitmap(priv,
Josh Boyer 5c86018
+							   x_bitmap, y_bitmap,
Josh Boyer 5c86018
 							   &x1, &y1, &x2, &y2;;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 			/*
Josh Boyer 5c86018
@@ -641,7 +639,7 @@ static void alps_process_packet_v4(struct psmouse *psmouse)
Josh Boyer 5c86018
 			   ((priv->multi_data[3] & 0x1f) << 5) |
Josh Boyer 5c86018
 			    (priv->multi_data[1] & 0x1f);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-		fingers = alps_process_bitmap(x_bitmap, y_bitmap,
Josh Boyer 5c86018
+		fingers = alps_process_bitmap(priv, x_bitmap, y_bitmap,
Josh Boyer 5c86018
 					      &x1, &y1, &x2, &y2;;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 		/* Store MT data.*/
Josh Boyer 5c86018
@@ -1414,6 +1412,11 @@ static void alps_set_defaults(struct alps_data *priv)
Josh Boyer 5c86018
 	priv->mask0 = 0x8f;
Josh Boyer 5c86018
 	priv->flags = ALPS_DUALPOINT;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+	priv->x_max = 2000;
Josh Boyer 5c86018
+	priv->y_max = 1400;
Josh Boyer 5c86018
+	priv->x_bits = 15;
Josh Boyer 5c86018
+	priv->y_bits = 11;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 	switch (priv->proto_version) {
Josh Boyer 5c86018
 	case ALPS_PROTO_V1:
Josh Boyer 5c86018
 	case ALPS_PROTO_V2:
Josh Boyer 5c86018
@@ -1544,15 +1547,15 @@ static void alps_set_abs_params_mt(struct alps_data *priv,
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
Josh Boyer 5c86018
 	input_mt_init_slots(dev1, 2, 0);
Josh Boyer 5c86018
-	input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0);
Josh Boyer 5c86018
-	input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0);
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit);
Josh Boyer 5c86018
 	set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
Josh Boyer 5c86018
 	set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0);
Josh Boyer 5c86018
-	input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0);
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_X, 0, priv->x_max, 0, 0);
Josh Boyer 5c86018
+	input_set_abs_params(dev1, ABS_Y, 0, priv->y_max, 0, 0);
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 int alps_init(struct psmouse *psmouse)
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
index 0934f8b..5e638be 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.h
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
@@ -72,6 +72,10 @@ struct alps_nibble_commands {
Josh Boyer 5c86018
  *   mask0, should match byte0.
Josh Boyer 5c86018
  * @mask0: The mask used to check the first byte of the report.
Josh Boyer 5c86018
  * @flags: Additional device capabilities (passthrough port, trackstick, etc.).
Josh Boyer 5c86018
+ * @x_max: Largest possible X position value.
Josh Boyer 5c86018
+ * @y_max: Largest possible Y position value.
Josh Boyer 5c86018
+ * @x_bits: Number of X bits in the MT bitmap.
Josh Boyer 5c86018
+ * @y_bits: Number of Y bits in the MT bitmap.
Josh Boyer 5c86018
  * @hw_init: Protocol-specific hardware init function.
Josh Boyer 5c86018
  * @process_packet: Protocol-specific function to process a report packet.
Josh Boyer 5c86018
  * @set_abs_params: Protocol-specific function to configure the input_dev.
Josh Boyer 5c86018
@@ -96,6 +100,10 @@ struct alps_data {
Josh Boyer 5c86018
 	unsigned char proto_version;
Josh Boyer 5c86018
 	unsigned char byte0, mask0;
Josh Boyer 5c86018
 	unsigned char flags;
Josh Boyer 5c86018
+	int x_max;
Josh Boyer 5c86018
+	int y_max;
Josh Boyer 5c86018
+	int x_bits;
Josh Boyer 5c86018
+	int y_bits;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	int (*hw_init)(struct psmouse *psmouse);
Josh Boyer 5c86018
 	void (*process_packet)(struct psmouse *psmouse);
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From 3c9d054fef84ccc967445b330ab6012c6b6bd85b Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:26:11 -0800
Josh Boyer 5c86018
Subject: [PATCH 11/15] Input: ALPS - make the V3 packet field decoder
Josh Boyer 5c86018
 "pluggable"
Josh Boyer 5c86018
Josh Boyer 5c86018
A number of different ALPS touchpad protocols can reuse
Josh Boyer 5c86018
alps_process_touchpad_packet_v3() with small tweaks to the bitfield
Josh Boyer 5c86018
decoding.  Create a new priv->decode_fields() callback that handles the
Josh Boyer 5c86018
per-model differences.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 101 +++++++++++++++++++++++++--------------------
Josh Boyer 5c86018
 drivers/input/mouse/alps.h |  38 +++++++++++++++++
Josh Boyer 5c86018
 2 files changed, 95 insertions(+), 44 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index 2cd8be7..270b7de 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -447,17 +447,49 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 	return;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+static void alps_decode_buttons_v3(struct alps_fields *f, unsigned char *p)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	f->left = !!(p[3] & 0x01);
Josh Boyer 5c86018
+	f->right = !!(p[3] & 0x02);
Josh Boyer 5c86018
+	f->middle = !!(p[3] & 0x04);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	f->ts_left = !!(p[3] & 0x10);
Josh Boyer 5c86018
+	f->ts_right = !!(p[3] & 0x20);
Josh Boyer 5c86018
+	f->ts_middle = !!(p[3] & 0x40);
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	f->first_mp = !!(p[4] & 0x40);
Josh Boyer 5c86018
+	f->is_mp = !!(p[0] & 0x40);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	f->fingers = (p[5] & 0x3) + 1;
Josh Boyer 5c86018
+	f->x_map = ((p[4] & 0x7e) << 8) |
Josh Boyer 5c86018
+		   ((p[1] & 0x7f) << 2) |
Josh Boyer 5c86018
+		   ((p[0] & 0x30) >> 4);
Josh Boyer 5c86018
+	f->y_map = ((p[3] & 0x70) << 4) |
Josh Boyer 5c86018
+		   ((p[2] & 0x7f) << 1) |
Josh Boyer 5c86018
+		   (p[4] & 0x01);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	f->x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
Josh Boyer 5c86018
+	       ((p[0] & 0x30) >> 4);
Josh Boyer 5c86018
+	f->y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
Josh Boyer 5c86018
+	f->z = p[5] & 0x7f;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	alps_decode_buttons_v3(f, p);
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
 	unsigned char *packet = psmouse->packet;
Josh Boyer 5c86018
 	struct input_dev *dev = psmouse->dev;
Josh Boyer 5c86018
 	struct input_dev *dev2 = priv->dev2;
Josh Boyer 5c86018
-	int x, y, z;
Josh Boyer 5c86018
-	int left, right, middle;
Josh Boyer 5c86018
 	int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
Josh Boyer 5c86018
 	int fingers = 0, bmap_fingers;
Josh Boyer 5c86018
-	unsigned int x_bitmap, y_bitmap;
Josh Boyer 5c86018
+	struct alps_fields f;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	priv->decode_fields(&f, packet);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	/*
Josh Boyer 5c86018
 	 * There's no single feature of touchpad position and bitmap packets
Josh Boyer 5c86018
@@ -472,17 +504,10 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 		 * packet. Check for this, and when it happens process the
Josh Boyer 5c86018
 		 * position packet as usual.
Josh Boyer 5c86018
 		 */
Josh Boyer 5c86018
-		if (packet[0] & 0x40) {
Josh Boyer 5c86018
-			fingers = (packet[5] & 0x3) + 1;
Josh Boyer 5c86018
-			x_bitmap = ((packet[4] & 0x7e) << 8) |
Josh Boyer 5c86018
-				   ((packet[1] & 0x7f) << 2) |
Josh Boyer 5c86018
-				   ((packet[0] & 0x30) >> 4);
Josh Boyer 5c86018
-			y_bitmap = ((packet[3] & 0x70) << 4) |
Josh Boyer 5c86018
-				   ((packet[2] & 0x7f) << 1) |
Josh Boyer 5c86018
-				   (packet[4] & 0x01);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
+		if (f.is_mp) {
Josh Boyer 5c86018
+			fingers = f.fingers;
Josh Boyer 5c86018
 			bmap_fingers = alps_process_bitmap(priv,
Josh Boyer 5c86018
-							   x_bitmap, y_bitmap,
Josh Boyer 5c86018
+							   f.x_map, f.y_map,
Josh Boyer 5c86018
 							   &x1, &y1, &x2, &y2;;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 			/*
Josh Boyer 5c86018
@@ -493,7 +518,7 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 				fingers = bmap_fingers;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 			/* Now process position packet */
Josh Boyer 5c86018
-			packet = priv->multi_data;
Josh Boyer 5c86018
+			priv->decode_fields(&f, priv->multi_data);
Josh Boyer 5c86018
 		} else {
Josh Boyer 5c86018
 			priv->multi_packet = 0;
Josh Boyer 5c86018
 		}
Josh Boyer 5c86018
@@ -507,10 +532,10 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 	 * out misidentified bitmap packets, we reject anything with this
Josh Boyer 5c86018
 	 * bit set.
Josh Boyer 5c86018
 	 */
Josh Boyer 5c86018
-	if (packet[0] & 0x40)
Josh Boyer 5c86018
+	if (f.is_mp)
Josh Boyer 5c86018
 		return;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (!priv->multi_packet && (packet[4] & 0x40)) {
Josh Boyer 5c86018
+	if (!priv->multi_packet && f.first_mp) {
Josh Boyer 5c86018
 		priv->multi_packet = 1;
Josh Boyer 5c86018
 		memcpy(priv->multi_data, packet, sizeof(priv->multi_data));
Josh Boyer 5c86018
 		return;
Josh Boyer 5c86018
@@ -518,22 +543,13 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	priv->multi_packet = 0;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	left = packet[3] & 0x01;
Josh Boyer 5c86018
-	right = packet[3] & 0x02;
Josh Boyer 5c86018
-	middle = packet[3] & 0x04;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	x = ((packet[1] & 0x7f) << 4) | ((packet[4] & 0x30) >> 2) |
Josh Boyer 5c86018
-	    ((packet[0] & 0x30) >> 4);
Josh Boyer 5c86018
-	y = ((packet[2] & 0x7f) << 4) | (packet[4] & 0x0f);
Josh Boyer 5c86018
-	z = packet[5] & 0x7f;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	/*
Josh Boyer 5c86018
 	 * Sometimes the hardware sends a single packet with z = 0
Josh Boyer 5c86018
 	 * in the middle of a stream. Real releases generate packets
Josh Boyer 5c86018
 	 * with x, y, and z all zero, so these seem to be flukes.
Josh Boyer 5c86018
 	 * Ignore them.
Josh Boyer 5c86018
 	 */
Josh Boyer 5c86018
-	if (x && y && !z)
Josh Boyer 5c86018
+	if (f.x && f.y && !f.z)
Josh Boyer 5c86018
 		return;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	/*
Josh Boyer 5c86018
@@ -541,12 +557,12 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 	 * to rely on ST data.
Josh Boyer 5c86018
 	 */
Josh Boyer 5c86018
 	if (!fingers) {
Josh Boyer 5c86018
-		x1 = x;
Josh Boyer 5c86018
-		y1 = y;
Josh Boyer 5c86018
-		fingers = z > 0 ? 1 : 0;
Josh Boyer 5c86018
+		x1 = f.x;
Josh Boyer 5c86018
+		y1 = f.y;
Josh Boyer 5c86018
+		fingers = f.z > 0 ? 1 : 0;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (z >= 64)
Josh Boyer 5c86018
+	if (f.z >= 64)
Josh Boyer 5c86018
 		input_report_key(dev, BTN_TOUCH, 1);
Josh Boyer 5c86018
 	else
Josh Boyer 5c86018
 		input_report_key(dev, BTN_TOUCH, 0);
Josh Boyer 5c86018
@@ -555,26 +571,22 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	input_mt_report_finger_count(dev, fingers);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	input_report_key(dev, BTN_LEFT, left);
Josh Boyer 5c86018
-	input_report_key(dev, BTN_RIGHT, right);
Josh Boyer 5c86018
-	input_report_key(dev, BTN_MIDDLE, middle);
Josh Boyer 5c86018
+	input_report_key(dev, BTN_LEFT, f.left);
Josh Boyer 5c86018
+	input_report_key(dev, BTN_RIGHT, f.right);
Josh Boyer 5c86018
+	input_report_key(dev, BTN_MIDDLE, f.middle);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (z > 0) {
Josh Boyer 5c86018
-		input_report_abs(dev, ABS_X, x);
Josh Boyer 5c86018
-		input_report_abs(dev, ABS_Y, y);
Josh Boyer 5c86018
+	if (f.z > 0) {
Josh Boyer 5c86018
+		input_report_abs(dev, ABS_X, f.x);
Josh Boyer 5c86018
+		input_report_abs(dev, ABS_Y, f.y);
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
-	input_report_abs(dev, ABS_PRESSURE, z);
Josh Boyer 5c86018
+	input_report_abs(dev, ABS_PRESSURE, f.z);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	input_sync(dev);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) {
Josh Boyer 5c86018
-		left = packet[3] & 0x10;
Josh Boyer 5c86018
-		right = packet[3] & 0x20;
Josh Boyer 5c86018
-		middle = packet[3] & 0x40;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-		input_report_key(dev2, BTN_LEFT, left);
Josh Boyer 5c86018
-		input_report_key(dev2, BTN_RIGHT, right);
Josh Boyer 5c86018
-		input_report_key(dev2, BTN_MIDDLE, middle);
Josh Boyer 5c86018
+		input_report_key(dev2, BTN_LEFT, f.ts_left);
Josh Boyer 5c86018
+		input_report_key(dev2, BTN_RIGHT, f.ts_right);
Josh Boyer 5c86018
+		input_report_key(dev2, BTN_MIDDLE, f.ts_middle);
Josh Boyer 5c86018
 		input_sync(dev2);
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
@@ -1428,6 +1440,7 @@ static void alps_set_defaults(struct alps_data *priv)
Josh Boyer 5c86018
 		priv->hw_init = alps_hw_init_v3;
Josh Boyer 5c86018
 		priv->process_packet = alps_process_packet_v3;
Josh Boyer 5c86018
 		priv->set_abs_params = alps_set_abs_params_mt;
Josh Boyer 5c86018
+		priv->decode_fields = alps_decode_pinnacle;
Josh Boyer 5c86018
 		priv->nibble_commands = alps_v3_nibble_commands;
Josh Boyer 5c86018
 		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
Josh Boyer 5c86018
 		break;
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
index 5e638be..9704805 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.h
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
@@ -60,6 +60,42 @@ struct alps_nibble_commands {
Josh Boyer 5c86018
 };
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 /**
Josh Boyer 5c86018
+ * struct alps_fields - decoded version of the report packet
Josh Boyer 5c86018
+ * @x_map: Bitmap of active X positions for MT.
Josh Boyer 5c86018
+ * @y_map: Bitmap of active Y positions for MT.
Josh Boyer 5c86018
+ * @fingers: Number of fingers for MT.
Josh Boyer 5c86018
+ * @x: X position for ST.
Josh Boyer 5c86018
+ * @y: Y position for ST.
Josh Boyer 5c86018
+ * @z: Z position for ST.
Josh Boyer 5c86018
+ * @first_mp: Packet is the first of a multi-packet report.
Josh Boyer 5c86018
+ * @is_mp: Packet is part of a multi-packet report.
Josh Boyer 5c86018
+ * @left: Left touchpad button is active.
Josh Boyer 5c86018
+ * @right: Right touchpad button is active.
Josh Boyer 5c86018
+ * @middle: Middle touchpad button is active.
Josh Boyer 5c86018
+ * @ts_left: Left trackstick button is active.
Josh Boyer 5c86018
+ * @ts_right: Right trackstick button is active.
Josh Boyer 5c86018
+ * @ts_middle: Middle trackstick button is active.
Josh Boyer 5c86018
+ */
Josh Boyer 5c86018
+struct alps_fields {
Josh Boyer 5c86018
+	unsigned int x_map;
Josh Boyer 5c86018
+	unsigned int y_map;
Josh Boyer 5c86018
+	unsigned int fingers;
Josh Boyer 5c86018
+	unsigned int x;
Josh Boyer 5c86018
+	unsigned int y;
Josh Boyer 5c86018
+	unsigned int z;
Josh Boyer 5c86018
+	unsigned int first_mp:1;
Josh Boyer 5c86018
+	unsigned int is_mp:1;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	unsigned int left:1;
Josh Boyer 5c86018
+	unsigned int right:1;
Josh Boyer 5c86018
+	unsigned int middle:1;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	unsigned int ts_left:1;
Josh Boyer 5c86018
+	unsigned int ts_right:1;
Josh Boyer 5c86018
+	unsigned int ts_middle:1;
Josh Boyer 5c86018
+};
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+/**
Josh Boyer 5c86018
  * struct alps_data - private data structure for the ALPS driver
Josh Boyer 5c86018
  * @dev2: "Relative" device used to report trackstick or mouse activity.
Josh Boyer 5c86018
  * @phys: Physical path for the relative device.
Josh Boyer 5c86018
@@ -78,6 +114,7 @@ struct alps_nibble_commands {
Josh Boyer 5c86018
  * @y_bits: Number of Y bits in the MT bitmap.
Josh Boyer 5c86018
  * @hw_init: Protocol-specific hardware init function.
Josh Boyer 5c86018
  * @process_packet: Protocol-specific function to process a report packet.
Josh Boyer 5c86018
+ * @decode_fields: Protocol-specific function to read packet bitfields.
Josh Boyer 5c86018
  * @set_abs_params: Protocol-specific function to configure the input_dev.
Josh Boyer 5c86018
  * @prev_fin: Finger bit from previous packet.
Josh Boyer 5c86018
  * @multi_packet: Multi-packet data in progress.
Josh Boyer 5c86018
@@ -107,6 +144,7 @@ struct alps_data {
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	int (*hw_init)(struct psmouse *psmouse);
Josh Boyer 5c86018
 	void (*process_packet)(struct psmouse *psmouse);
Josh Boyer 5c86018
+	void (*decode_fields)(struct alps_fields *f, unsigned char *p);
Josh Boyer 5c86018
 	void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	int prev_fin;
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From 9e7c99b6c125653f53ef0999a176c3a79de21be8 Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:27:08 -0800
Josh Boyer 5c86018
Subject: [PATCH 12/15] Input: ALPS - add support for "Rushmore" touchpads
Josh Boyer 5c86018
Josh Boyer 5c86018
Rushmore touchpads are found on Dell E6230/E6430/E6530.  They use the V3
Josh Boyer 5c86018
protocol with slightly tweaked init sequences and report formats.
Josh Boyer 5c86018
Josh Boyer 5c86018
The E7 report is 73 03 0a, and the EC report is 88 08 1d
Josh Boyer 5c86018
Josh Boyer 5c86018
Credits: Emmanuel Thome reported the MT bitmap changes.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++
Josh Boyer 5c86018
 1 file changed, 52 insertions(+)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index 270b7de..bf2fa51 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -479,6 +479,14 @@ static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p)
Josh Boyer 5c86018
 	alps_decode_buttons_v3(f, p);
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	alps_decode_pinnacle(f, p);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	f->x_map |= (p[5] & 0x10) << 11;
Josh Boyer 5c86018
+	f->y_map |= (p[5] & 0x20) << 6;
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
@@ -1329,6 +1337,40 @@ error:
Josh Boyer 5c86018
 	return -1;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
+	int reg_val, ret = -1;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	if (alps_enter_command_mode(psmouse, NULL) ||
Josh Boyer 5c86018
+	    alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
Josh Boyer 5c86018
+	    alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
Josh Boyer 5c86018
+		goto error;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	reg_val = alps_command_mode_read_reg(psmouse, 0xc2c6);
Josh Boyer 5c86018
+	if (reg_val == -1)
Josh Boyer 5c86018
+		goto error;
Josh Boyer 5c86018
+	if (__alps_command_mode_write_reg(psmouse, reg_val & 0xfd))
Josh Boyer 5c86018
+		goto error;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64))
Josh Boyer 5c86018
+		goto error;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	/* enter absolute mode */
Josh Boyer 5c86018
+	reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4);
Josh Boyer 5c86018
+	if (reg_val == -1)
Josh Boyer 5c86018
+		goto error;
Josh Boyer 5c86018
+	if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02))
Josh Boyer 5c86018
+		goto error;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	alps_exit_command_mode(psmouse);
Josh Boyer 5c86018
+	return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+error:
Josh Boyer 5c86018
+	alps_exit_command_mode(psmouse);
Josh Boyer 5c86018
+	return ret;
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 /* Must be in command mode when calling this function */
Josh Boyer 5c86018
 static int alps_absolute_mode_v4(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
@@ -1511,6 +1553,16 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (alps_match_table(psmouse, priv, e7, ec) == 0) {
Josh Boyer 5c86018
 		return 0;
Josh Boyer 5c86018
+	} else if (ec[0] == 0x88 && ec[1] == 0x08) {
Josh Boyer 5c86018
+		priv->proto_version = ALPS_PROTO_V3;
Josh Boyer 5c86018
+		alps_set_defaults(priv);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+		priv->hw_init = alps_hw_init_rushmore_v3;
Josh Boyer 5c86018
+		priv->decode_fields = alps_decode_rushmore;
Josh Boyer 5c86018
+		priv->x_bits = 16;
Josh Boyer 5c86018
+		priv->y_bits = 12;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+		return 0;
Josh Boyer 5c86018
 	} else if (ec[0] == 0x88 && ec[1] == 0x07 &&
Josh Boyer 5c86018
 		   ec[2] >= 0x90 && ec[2] <= 0x9d) {
Josh Boyer 5c86018
 		priv->proto_version = ALPS_PROTO_V3;
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From e5ca58dc506fb7f64760b483ecd407593b764f3b Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Wed, 13 Feb 2013 22:28:07 -0800
Josh Boyer 5c86018
Subject: [PATCH 13/15] Input: ALPS - enable trackstick on Rushmore touchpads
Josh Boyer 5c86018
Josh Boyer 5c86018
Separate out the common trackstick probe/setup sequences, then call them
Josh Boyer 5c86018
from each of the v3 init functions.
Josh Boyer 5c86018
Josh Boyer 5c86018
Credits: Emmanual Thome furnished the information on the trackstick init
Josh Boyer 5c86018
and how it affected the report format.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Tested-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 185 ++++++++++++++++++++++++++++-----------------
Josh Boyer 5c86018
 1 file changed, 115 insertions(+), 70 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index bf2fa51..7b99fc7 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -29,6 +29,9 @@
Josh Boyer 5c86018
  */
Josh Boyer 5c86018
 #define ALPS_CMD_NIBBLE_10	0x01f2
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+#define ALPS_REG_BASE_RUSHMORE	0xc2c0
Josh Boyer 5c86018
+#define ALPS_REG_BASE_PINNACLE	0x0000
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
Josh Boyer 5c86018
 	{ PSMOUSE_CMD_SETPOLL,		0x00 }, /* 0 */
Josh Boyer 5c86018
 	{ PSMOUSE_CMD_RESET_DIS,	0x00 }, /* 1 */
Josh Boyer 5c86018
@@ -1166,26 +1169,31 @@ static int alps_hw_init_v1_v2(struct psmouse *psmouse)
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 /*
Josh Boyer 5c86018
- * Enable or disable passthrough mode to the trackstick. Must be in
Josh Boyer 5c86018
- * command mode when calling this function.
Josh Boyer 5c86018
+ * Enable or disable passthrough mode to the trackstick.
Josh Boyer 5c86018
  */
Josh Boyer 5c86018
-static int alps_passthrough_mode_v3(struct psmouse *psmouse, bool enable)
Josh Boyer 5c86018
+static int alps_passthrough_mode_v3(struct psmouse *psmouse,
Josh Boyer 5c86018
+				    int reg_base, bool enable)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	int reg_val;
Josh Boyer 5c86018
+	int reg_val, ret = -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	reg_val = alps_command_mode_read_reg(psmouse, 0x0008);
Josh Boyer 5c86018
-	if (reg_val == -1)
Josh Boyer 5c86018
+	if (alps_enter_command_mode(psmouse, NULL))
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
Josh Boyer 5c86018
+	if (reg_val == -1)
Josh Boyer 5c86018
+		goto error;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 	if (enable)
Josh Boyer 5c86018
 		reg_val |= 0x01;
Josh Boyer 5c86018
 	else
Josh Boyer 5c86018
 		reg_val &= ~0x01;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (__alps_command_mode_write_reg(psmouse, reg_val))
Josh Boyer 5c86018
-		return -1;
Josh Boyer 5c86018
+	ret = __alps_command_mode_write_reg(psmouse, reg_val);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	return 0;
Josh Boyer 5c86018
+error:
Josh Boyer 5c86018
+	if (alps_exit_command_mode(psmouse))
Josh Boyer 5c86018
+		ret = -1;
Josh Boyer 5c86018
+	return ret;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 /* Must be in command mode when calling this function */
Josh Boyer 5c86018
@@ -1204,69 +1212,102 @@ static int alps_absolute_mode_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 	return 0;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-static int alps_hw_init_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
+static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
-	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
-	int reg_val;
Josh Boyer 5c86018
-	unsigned char param[4];
Josh Boyer 5c86018
+	int ret = -EIO, reg_val;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (alps_enter_command_mode(psmouse, NULL))
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	/* Check for trackstick */
Josh Boyer 5c86018
-	reg_val = alps_command_mode_read_reg(psmouse, 0x0008);
Josh Boyer 5c86018
+	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
Josh Boyer 5c86018
 	if (reg_val == -1)
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
-	if (reg_val & 0x80) {
Josh Boyer 5c86018
-		if (alps_passthrough_mode_v3(psmouse, true))
Josh Boyer 5c86018
-			goto error;
Josh Boyer 5c86018
-		if (alps_exit_command_mode(psmouse))
Josh Boyer 5c86018
-			goto error;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	/* bit 7: trackstick is present */
Josh Boyer 5c86018
+	ret = reg_val & 0x80 ? 0 : -ENODEV;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+error:
Josh Boyer 5c86018
+	alps_exit_command_mode(psmouse);
Josh Boyer 5c86018
+	return ret;
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
+	int ret = 0;
Josh Boyer 5c86018
+	unsigned char param[4];
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	if (alps_passthrough_mode_v3(psmouse, reg_base, true))
Josh Boyer 5c86018
+		return -EIO;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	/*
Josh Boyer 5c86018
+	 * E7 report for the trackstick
Josh Boyer 5c86018
+	 *
Josh Boyer 5c86018
+	 * There have been reports of failures to seem to trace back
Josh Boyer 5c86018
+	 * to the above trackstick check failing. When these occur
Josh Boyer 5c86018
+	 * this E7 report fails, so when that happens we continue
Josh Boyer 5c86018
+	 * with the assumption that there isn't a trackstick after
Josh Boyer 5c86018
+	 * all.
Josh Boyer 5c86018
+	 */
Josh Boyer 5c86018
+	if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) {
Josh Boyer 5c86018
+		psmouse_warn(psmouse, "trackstick E7 report failed\n");
Josh Boyer 5c86018
+		ret = -ENODEV;
Josh Boyer 5c86018
+	} else {
Josh Boyer 5c86018
+		psmouse_dbg(psmouse,
Josh Boyer 5c86018
+			    "trackstick E7 report: %2.2x %2.2x %2.2x\n",
Josh Boyer 5c86018
+			    param[0], param[1], param[2]);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 		/*
Josh Boyer 5c86018
-		 * E7 report for the trackstick
Josh Boyer 5c86018
-		 *
Josh Boyer 5c86018
-		 * There have been reports of failures to seem to trace back
Josh Boyer 5c86018
-		 * to the above trackstick check failing. When these occur
Josh Boyer 5c86018
-		 * this E7 report fails, so when that happens we continue
Josh Boyer 5c86018
-		 * with the assumption that there isn't a trackstick after
Josh Boyer 5c86018
-		 * all.
Josh Boyer 5c86018
+		 * Not sure what this does, but it is absolutely
Josh Boyer 5c86018
+		 * essential. Without it, the touchpad does not
Josh Boyer 5c86018
+		 * work at all and the trackstick just emits normal
Josh Boyer 5c86018
+		 * PS/2 packets.
Josh Boyer 5c86018
 		 */
Josh Boyer 5c86018
-		param[0] = 0x64;
Josh Boyer 5c86018
-		if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
Josh Boyer 5c86018
-		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
Josh Boyer 5c86018
-		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
Josh Boyer 5c86018
-		    ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
Josh Boyer 5c86018
-			psmouse_warn(psmouse, "trackstick E7 report failed\n");
Josh Boyer 5c86018
-		} else {
Josh Boyer 5c86018
-			psmouse_dbg(psmouse,
Josh Boyer 5c86018
-				    "trackstick E7 report: %2.2x %2.2x %2.2x\n",
Josh Boyer 5c86018
-				    param[0], param[1], param[2]);
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-			/*
Josh Boyer 5c86018
-			 * Not sure what this does, but it is absolutely
Josh Boyer 5c86018
-			 * essential. Without it, the touchpad does not
Josh Boyer 5c86018
-			 * work at all and the trackstick just emits normal
Josh Boyer 5c86018
-			 * PS/2 packets.
Josh Boyer 5c86018
-			 */
Josh Boyer 5c86018
-			if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
-			    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
-			    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
-			    alps_command_mode_send_nibble(psmouse, 0x9) ||
Josh Boyer 5c86018
-			    alps_command_mode_send_nibble(psmouse, 0x4)) {
Josh Boyer 5c86018
-				psmouse_err(psmouse,
Josh Boyer 5c86018
-					    "Error sending magic E6 sequence\n");
Josh Boyer 5c86018
-				goto error_passthrough;
Josh Boyer 5c86018
-			}
Josh Boyer 5c86018
+		if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
+		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
+		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
Josh Boyer 5c86018
+		    alps_command_mode_send_nibble(psmouse, 0x9) ||
Josh Boyer 5c86018
+		    alps_command_mode_send_nibble(psmouse, 0x4)) {
Josh Boyer 5c86018
+			psmouse_err(psmouse,
Josh Boyer 5c86018
+				    "Error sending magic E6 sequence\n");
Josh Boyer 5c86018
+			ret = -EIO;
Josh Boyer 5c86018
+			goto error;
Josh Boyer 5c86018
 		}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-		if (alps_enter_command_mode(psmouse, NULL))
Josh Boyer 5c86018
-			goto error_passthrough;
Josh Boyer 5c86018
-		if (alps_passthrough_mode_v3(psmouse, false))
Josh Boyer 5c86018
-			goto error;
Josh Boyer 5c86018
+		/*
Josh Boyer 5c86018
+		 * This ensures the trackstick packets are in the format
Josh Boyer 5c86018
+		 * supported by this driver. If bit 1 isn't set the packet
Josh Boyer 5c86018
+		 * format is different.
Josh Boyer 5c86018
+		 */
Josh Boyer 5c86018
+		if (alps_enter_command_mode(psmouse, NULL) ||
Josh Boyer 5c86018
+		    alps_command_mode_write_reg(psmouse,
Josh Boyer 5c86018
+						reg_base + 0x08, 0x82) ||
Josh Boyer 5c86018
+		    alps_exit_command_mode(psmouse))
Josh Boyer 5c86018
+			ret = -EIO;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (alps_absolute_mode_v3(psmouse)) {
Josh Boyer 5c86018
+error:
Josh Boyer 5c86018
+	if (alps_passthrough_mode_v3(psmouse, reg_base, false))
Josh Boyer 5c86018
+		ret = -EIO;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	return ret;
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+static int alps_hw_init_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
+	int reg_val;
Josh Boyer 5c86018
+	unsigned char param[4];
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	reg_val = alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE);
Josh Boyer 5c86018
+	if (reg_val == -EIO)
Josh Boyer 5c86018
+		goto error;
Josh Boyer 5c86018
+	if (reg_val == 0 &&
Josh Boyer 5c86018
+	    alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
Josh Boyer 5c86018
+		goto error;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	if (alps_enter_command_mode(psmouse, NULL) ||
Josh Boyer 5c86018
+	    alps_absolute_mode_v3(psmouse)) {
Josh Boyer 5c86018
 		psmouse_err(psmouse, "Failed to enter absolute mode\n");
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
@@ -1303,14 +1344,6 @@ static int alps_hw_init_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 	if (alps_command_mode_write_reg(psmouse, 0x0162, 0x04))
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	/*
Josh Boyer 5c86018
-	 * This ensures the trackstick packets are in the format
Josh Boyer 5c86018
-	 * supported by this driver. If bit 1 isn't set the packet
Josh Boyer 5c86018
-	 * format is different.
Josh Boyer 5c86018
-	 */
Josh Boyer 5c86018
-	if (alps_command_mode_write_reg(psmouse, 0x0008, 0x82))
Josh Boyer 5c86018
-		goto error;
Josh Boyer 5c86018
-
Josh Boyer 5c86018
 	alps_exit_command_mode(psmouse);
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	/* Set rate and enable data reporting */
Josh Boyer 5c86018
@@ -1323,10 +1356,6 @@ static int alps_hw_init_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	return 0;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-error_passthrough:
Josh Boyer 5c86018
-	/* Something failed while in passthrough mode, so try to get out */
Josh Boyer 5c86018
-	if (!alps_enter_command_mode(psmouse, NULL))
Josh Boyer 5c86018
-		alps_passthrough_mode_v3(psmouse, false);
Josh Boyer 5c86018
 error:
Josh Boyer 5c86018
 	/*
Josh Boyer 5c86018
 	 * Leaving the touchpad in command mode will essentially render
Josh Boyer 5c86018
@@ -1339,9 +1368,19 @@ error:
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
+	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
 	int reg_val, ret = -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+	if (priv->flags & ALPS_DUALPOINT) {
Josh Boyer 5c86018
+		reg_val = alps_setup_trackstick_v3(psmouse,
Josh Boyer 5c86018
+						   ALPS_REG_BASE_RUSHMORE);
Josh Boyer 5c86018
+		if (reg_val == -EIO)
Josh Boyer 5c86018
+			goto error;
Josh Boyer 5c86018
+		if (reg_val == -ENODEV)
Josh Boyer 5c86018
+			priv->flags &= ~ALPS_DUALPOINT;
Josh Boyer 5c86018
+	}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 	if (alps_enter_command_mode(psmouse, NULL) ||
Josh Boyer 5c86018
 	    alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
Josh Boyer 5c86018
 	    alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
Josh Boyer 5c86018
@@ -1562,6 +1601,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
Josh Boyer 5c86018
 		priv->x_bits = 16;
Josh Boyer 5c86018
 		priv->y_bits = 12;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+		/* hack to make addr_command, nibble_command available */
Josh Boyer 5c86018
+		psmouse->private = priv;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+		if (alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE))
Josh Boyer 5c86018
+			priv->flags &= ~ALPS_DUALPOINT;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 		return 0;
Josh Boyer 5c86018
 	} else if (ec[0] == 0x88 && ec[1] == 0x07 &&
Josh Boyer 5c86018
 		   ec[2] >= 0x90 && ec[2] <= 0x9d) {
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From db7192fa07fa5c70c9849d8f658a7ff696cff99d Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
Date: Sat, 16 Feb 2013 22:40:03 -0800
Josh Boyer 5c86018
Subject: [PATCH 14/15] Input: ALPS - Remove unused argument to
Josh Boyer 5c86018
 alps_enter_command_mode()
Josh Boyer 5c86018
Josh Boyer 5c86018
Now that alps_identify() explicitly issues an EC report using
Josh Boyer 5c86018
alps_rpt_cmd(), we no longer need to look at the magic numbers returned
Josh Boyer 5c86018
by alps_enter_command_mode().
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 18 +++++++-----------
Josh Boyer 5c86018
 1 file changed, 7 insertions(+), 11 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index 7b99fc7..9c97531 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -994,8 +994,7 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
Josh Boyer 5c86018
 	return 0;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-static int alps_enter_command_mode(struct psmouse *psmouse,
Josh Boyer 5c86018
-				   unsigned char *resp)
Josh Boyer 5c86018
+static int alps_enter_command_mode(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	unsigned char param[4];
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1009,9 +1008,6 @@ static int alps_enter_command_mode(struct psmouse *psmouse,
Josh Boyer 5c86018
 			    "unknown response while entering command mode\n");
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
-
Josh Boyer 5c86018
-	if (resp)
Josh Boyer 5c86018
-		*resp = param[2];
Josh Boyer 5c86018
 	return 0;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1176,7 +1172,7 @@ static int alps_passthrough_mode_v3(struct psmouse *psmouse,
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	int reg_val, ret = -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (alps_enter_command_mode(psmouse, NULL))
Josh Boyer 5c86018
+	if (alps_enter_command_mode(psmouse))
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
Josh Boyer 5c86018
@@ -1216,7 +1212,7 @@ static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	int ret = -EIO, reg_val;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (alps_enter_command_mode(psmouse, NULL))
Josh Boyer 5c86018
+	if (alps_enter_command_mode(psmouse))
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
Josh Boyer 5c86018
@@ -1279,7 +1275,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
Josh Boyer 5c86018
 		 * supported by this driver. If bit 1 isn't set the packet
Josh Boyer 5c86018
 		 * format is different.
Josh Boyer 5c86018
 		 */
Josh Boyer 5c86018
-		if (alps_enter_command_mode(psmouse, NULL) ||
Josh Boyer 5c86018
+		if (alps_enter_command_mode(psmouse) ||
Josh Boyer 5c86018
 		    alps_command_mode_write_reg(psmouse,
Josh Boyer 5c86018
 						reg_base + 0x08, 0x82) ||
Josh Boyer 5c86018
 		    alps_exit_command_mode(psmouse))
Josh Boyer 5c86018
@@ -1306,7 +1302,7 @@ static int alps_hw_init_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 	    alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (alps_enter_command_mode(psmouse, NULL) ||
Josh Boyer 5c86018
+	if (alps_enter_command_mode(psmouse) ||
Josh Boyer 5c86018
 	    alps_absolute_mode_v3(psmouse)) {
Josh Boyer 5c86018
 		psmouse_err(psmouse, "Failed to enter absolute mode\n");
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
@@ -1381,7 +1377,7 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 			priv->flags &= ~ALPS_DUALPOINT;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (alps_enter_command_mode(psmouse, NULL) ||
Josh Boyer 5c86018
+	if (alps_enter_command_mode(psmouse) ||
Josh Boyer 5c86018
 	    alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
Josh Boyer 5c86018
 	    alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
@@ -1431,7 +1427,7 @@ static int alps_hw_init_v4(struct psmouse *psmouse)
Josh Boyer 5c86018
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
 	unsigned char param[4];
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (alps_enter_command_mode(psmouse, NULL))
Josh Boyer 5c86018
+	if (alps_enter_command_mode(psmouse))
Josh Boyer 5c86018
 		goto error;
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (alps_absolute_mode_v4(psmouse)) {
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018
Josh Boyer 5c86018
Josh Boyer 5c86018
From 10740a25bb3b895b5de7773f926a978416b38409 Mon Sep 17 00:00:00 2001
Josh Boyer 5c86018
From: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Date: Sat, 16 Feb 2013 22:40:04 -0800
Josh Boyer 5c86018
Subject: [PATCH 15/15] Input: ALPS - Add "Dolphin V1" touchpad support
Josh Boyer 5c86018
Josh Boyer 5c86018
These touchpads use a different protocol; they have been seen on Dell
Josh Boyer 5c86018
N5110, Dell 17R SE, and others.
Josh Boyer 5c86018
Josh Boyer 5c86018
The official ALPS driver identifies them by looking for an exact match
Josh Boyer 5c86018
on the E7 report: 73 03 50.  Dolphin V1 returns an EC report of
Josh Boyer 5c86018
73 01 xx (02 and 0d have been seen); Dolphin V2 returns an EC report of
Josh Boyer 5c86018
73 02 xx (02 has been seen).
Josh Boyer 5c86018
Josh Boyer 5c86018
Dolphin V2 probably needs a different initialization sequence and/or
Josh Boyer 5c86018
report parser, so it is left for a future commit.
Josh Boyer 5c86018
Josh Boyer 5c86018
Signed-off-by: Dave Turvene <dturvene@dahetral.com>
Josh Boyer 5c86018
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Josh Boyer 5c86018
---
Josh Boyer 5c86018
 drivers/input/mouse/alps.c | 67 ++++++++++++++++++++++++++++++++++++++++++++--
Josh Boyer 5c86018
 drivers/input/mouse/alps.h |  1 +
Josh Boyer 5c86018
 2 files changed, 66 insertions(+), 2 deletions(-)
Josh Boyer 5c86018
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
index 9c97531..0238e0e 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.c
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.c
Josh Boyer 5c86018
@@ -490,6 +490,29 @@ static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p)
Josh Boyer 5c86018
 	f->y_map |= (p[5] & 0x20) << 6;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	f->first_mp = !!(p[0] & 0x02);
Josh Boyer 5c86018
+	f->is_mp = !!(p[0] & 0x20);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	f->fingers = ((p[0] & 0x6) >> 1 |
Josh Boyer 5c86018
+		     (p[0] & 0x10) >> 2);
Josh Boyer 5c86018
+	f->x_map = ((p[2] & 0x60) >> 5) |
Josh Boyer 5c86018
+		   ((p[4] & 0x7f) << 2) |
Josh Boyer 5c86018
+		   ((p[5] & 0x7f) << 9) |
Josh Boyer 5c86018
+		   ((p[3] & 0x07) << 16) |
Josh Boyer 5c86018
+		   ((p[3] & 0x70) << 15) |
Josh Boyer 5c86018
+		   ((p[0] & 0x01) << 22);
Josh Boyer 5c86018
+	f->y_map = (p[1] & 0x7f) |
Josh Boyer 5c86018
+		   ((p[2] & 0x1f) << 7);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
Josh Boyer 5c86018
+	f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
Josh Boyer 5c86018
+	f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	alps_decode_buttons_v3(f, p);
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	struct alps_data *priv = psmouse->private;
Josh Boyer 5c86018
@@ -874,7 +897,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	/* Bytes 2 - pktsize should have 0 in the highest bit */
Josh Boyer 5c86018
-	if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
Josh Boyer 5c86018
+	if (priv->proto_version != ALPS_PROTO_V5 &&
Josh Boyer 5c86018
+	    psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
Josh Boyer 5c86018
 	    (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
Josh Boyer 5c86018
 		psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
Josh Boyer 5c86018
 			    psmouse->pktcnt - 1,
Josh Boyer 5c86018
@@ -1003,7 +1027,8 @@ static int alps_enter_command_mode(struct psmouse *psmouse)
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 
Josh Boyer 5c86018
-	if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) {
Josh Boyer 5c86018
+	if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
Josh Boyer 5c86018
+	    param[0] != 0x73) {
Josh Boyer 5c86018
 		psmouse_dbg(psmouse,
Josh Boyer 5c86018
 			    "unknown response while entering command mode\n");
Josh Boyer 5c86018
 		return -1;
Josh Boyer 5c86018
@@ -1495,6 +1520,23 @@ error:
Josh Boyer 5c86018
 	return -1;
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
+static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
Josh Boyer 5c86018
+{
Josh Boyer 5c86018
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
Josh Boyer 5c86018
+	unsigned char param[2];
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	/* This is dolphin "v1" as empirically defined by florin9doi */
Josh Boyer 5c86018
+	param[0] = 0x64;
Josh Boyer 5c86018
+	param[1] = 0x28;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
Josh Boyer 5c86018
+	    ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
Josh Boyer 5c86018
+		return -1;
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+	return 0;
Josh Boyer 5c86018
+}
Josh Boyer 5c86018
+
Josh Boyer 5c86018
 static void alps_set_defaults(struct alps_data *priv)
Josh Boyer 5c86018
 {
Josh Boyer 5c86018
 	priv->byte0 = 0x8f;
Josh Boyer 5c86018
@@ -1528,6 +1570,21 @@ static void alps_set_defaults(struct alps_data *priv)
Josh Boyer 5c86018
 		priv->nibble_commands = alps_v4_nibble_commands;
Josh Boyer 5c86018
 		priv->addr_command = PSMOUSE_CMD_DISABLE;
Josh Boyer 5c86018
 		break;
Josh Boyer 5c86018
+	case ALPS_PROTO_V5:
Josh Boyer 5c86018
+		priv->hw_init = alps_hw_init_dolphin_v1;
Josh Boyer 5c86018
+		priv->process_packet = alps_process_packet_v3;
Josh Boyer 5c86018
+		priv->decode_fields = alps_decode_dolphin;
Josh Boyer 5c86018
+		priv->set_abs_params = alps_set_abs_params_mt;
Josh Boyer 5c86018
+		priv->nibble_commands = alps_v3_nibble_commands;
Josh Boyer 5c86018
+		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
Josh Boyer 5c86018
+		priv->byte0 = 0xc8;
Josh Boyer 5c86018
+		priv->mask0 = 0xc8;
Josh Boyer 5c86018
+		priv->flags = 0;
Josh Boyer 5c86018
+		priv->x_max = 1360;
Josh Boyer 5c86018
+		priv->y_max = 660;
Josh Boyer 5c86018
+		priv->x_bits = 23;
Josh Boyer 5c86018
+		priv->y_bits = 12;
Josh Boyer 5c86018
+		break;
Josh Boyer 5c86018
 	}
Josh Boyer 5c86018
 }
Josh Boyer 5c86018
 
Josh Boyer 5c86018
@@ -1588,6 +1645,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 	if (alps_match_table(psmouse, priv, e7, ec) == 0) {
Josh Boyer 5c86018
 		return 0;
Josh Boyer 5c86018
+	} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
Josh Boyer 5c86018
+		   ec[0] == 0x73 && ec[1] == 0x01) {
Josh Boyer 5c86018
+		priv->proto_version = ALPS_PROTO_V5;
Josh Boyer 5c86018
+		alps_set_defaults(priv);
Josh Boyer 5c86018
+
Josh Boyer 5c86018
+		return 0;
Josh Boyer 5c86018
 	} else if (ec[0] == 0x88 && ec[1] == 0x08) {
Josh Boyer 5c86018
 		priv->proto_version = ALPS_PROTO_V3;
Josh Boyer 5c86018
 		alps_set_defaults(priv);
Josh Boyer 5c86018
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
index 9704805..eee5985 100644
Josh Boyer 5c86018
--- a/drivers/input/mouse/alps.h
Josh Boyer 5c86018
+++ b/drivers/input/mouse/alps.h
Josh Boyer 5c86018
@@ -16,6 +16,7 @@
Josh Boyer 5c86018
 #define ALPS_PROTO_V2	2
Josh Boyer 5c86018
 #define ALPS_PROTO_V3	3
Josh Boyer 5c86018
 #define ALPS_PROTO_V4	4
Josh Boyer 5c86018
+#define ALPS_PROTO_V5	5
Josh Boyer 5c86018
 
Josh Boyer 5c86018
 /**
Josh Boyer 5c86018
  * struct alps_model_info - touchpad ID table
Josh Boyer 5c86018
-- 
Josh Boyer 5c86018
1.8.1.2
Josh Boyer 5c86018