diff mbox series

Input: alps - blacklist the device which can't work with this driver

Message ID 20190428041632.11416-1-hui.wang@canonical.com (mailing list archive)
State New, archived
Headers show
Series Input: alps - blacklist the device which can't work with this driver | expand

Commit Message

Hui Wang April 28, 2019, 4:16 a.m. UTC
Recently I worked on a latest lenovo laptop, the trackpoint and 3
buttons belong to a alps device. After booting up, the device reports;
[    4.122673] psmouse serio1: alps: E6 report: 00 00 64
[    4.146342] psmouse serio1: alps: E7 report: 73 03 28
[    4.169612] psmouse serio1: alps: EC report: 73 01 03

Then this device is recognized by alps.c, but when I move the
trackpoint or press the buttons, the kernel will print:
"Rejected trackstick packet from non DualPoint device". and userspace
can't get any input event.

If I add a reg_val as the commit 567b9b549cfa, the error message will
disappear and the userspace can get the input event, but the cursor
moves too fast, it jumps around in the screen when moving the
trackpoint.

According to alps' explanation, this trackpoint is flashed a firmware
belong to trackpad. If we blacklist this device according to the
response of E7 and EC, this device will be driven by trackpoint.c,
then this device works well.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
---
 drivers/input/mouse/alps.c | 23 +++++++++++++++++++++++
 drivers/input/mouse/alps.h | 13 +++++++++++++
 2 files changed, 36 insertions(+)
diff mbox series

Patch

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 0a6f7ca883e7..b5bfffb30ede 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -138,6 +138,10 @@  static const struct alps_model_info alps_model_data[] = {
 	{ { 0x73, 0x02, 0x50 }, { ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS } },		/* Dell Vostro 1400 */
 };
 
+static const struct alps_blacklist_tbl alps_blacklist_data[] = {
+	{ { 0x73, 0x03, 0x28 }, { 0x73, 0x01, 0x03 } },
+};
+
 static const struct alps_protocol_info alps_v3_protocol_data = {
 	ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
 };
@@ -2864,6 +2868,22 @@  static const struct alps_protocol_info *alps_match_table(unsigned char *e7,
 	return NULL;
 }
 
+static int alps_match_blacklist(unsigned char *e7, unsigned char *ec)
+{
+	const struct alps_blacklist_tbl *blk_entry;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(alps_blacklist_data); i++) {
+		blk_entry = &alps_blacklist_data[i];
+
+		if (!memcmp(e7, blk_entry->signature, sizeof(blk_entry->signature)) &&
+		    !memcmp(ec, blk_entry->fw_ver, sizeof(blk_entry->fw_ver)))
+			return 1;
+	}
+
+	return 0;
+}
+
 static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
 {
 	const struct alps_protocol_info *protocol;
@@ -2894,6 +2914,9 @@  static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
 	    alps_exit_command_mode(psmouse))
 		return -EIO;
 
+	if (alps_match_blacklist(e7, ec))
+		return -EINVAL;
+
 	protocol = alps_match_table(e7, ec);
 	if (!protocol) {
 		if (e7[0] == 0x73 && e7[1] == 0x02 && e7[2] == 0x64 &&
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 79b6d69d1486..bdf098ce052e 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -194,6 +194,19 @@  struct alps_model_info {
 	struct alps_protocol_info protocol_info;
 };
 
+/**
+ * struct alps_blacklist_tbl - touchpad/trackpoint ID blacklist table
+ * @signature: E7 response string to match.
+ * @fw_ver: EC response string to match.
+ *
+ * Depends on response of E7 and EC to match the blacklist, if it matches,
+ * the alps driver will not handle this device.
+ */
+struct alps_blacklist_tbl {
+	u8 signature[3];
+	u8 fw_ver[3];
+};
+
 /**
  * struct alps_nibble_commands - encodings for register accesses
  * @command: PS/2 command used for the nibble