34af6ad
From 4ab16f30317966f892342e8821a6dc26070d1a06 Mon Sep 17 00:00:00 2001
34af6ad
From: Hans de Goede <hdegoede@redhat.com>
34af6ad
Date: Fri, 27 Jun 2014 18:50:33 +0200
34af6ad
Subject: [PATCH] psmouse: Add support for detecting FocalTech PS/2 touchpads
34af6ad
34af6ad
The Asus X450 and X550 laptops use a PS/2 touchpad from a new manufacturer
34af6ad
called FocalTech:
34af6ad
34af6ad
https://bugzilla.kernel.org/show_bug.cgi?id=77391
34af6ad
https://bugzilla.redhat.com/show_bug.cgi?id=1110011
34af6ad
34af6ad
The protocol for these devices is not known at this time, but even without
34af6ad
knowing the protocol they need some special handling. They get upset by some
34af6ad
of our other PS/2 device probing, and once upset generate random mouse events
34af6ad
making things unusable even with an external mouse.
34af6ad
34af6ad
This patch adds detection of these devices based on their pnp ids, and when
34af6ad
they are detected, treats them as a bare ps/2 mouse. Doing things this way
34af6ad
they at least work in their ps/2 mouse emulation mode.
34af6ad
34af6ad
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
34af6ad
---
34af6ad
 drivers/input/mouse/Makefile       |  2 +-
34af6ad
 drivers/input/mouse/focaltech.c    | 44 ++++++++++++++++++++++++++++++++++++++
34af6ad
 drivers/input/mouse/focaltech.h    | 21 ++++++++++++++++++
34af6ad
 drivers/input/mouse/psmouse-base.c | 10 +++++++++
34af6ad
 4 files changed, 76 insertions(+), 1 deletion(-)
34af6ad
 create mode 100644 drivers/input/mouse/focaltech.c
34af6ad
 create mode 100644 drivers/input/mouse/focaltech.h
34af6ad
34af6ad
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
34af6ad
index c25efdb3f288..dda507f8b3a2 100644
34af6ad
--- a/drivers/input/mouse/Makefile
34af6ad
+++ b/drivers/input/mouse/Makefile
34af6ad
@@ -23,7 +23,7 @@ obj-$(CONFIG_MOUSE_SYNAPTICS_I2C)	+= synaptics_i2c.o
34af6ad
 obj-$(CONFIG_MOUSE_SYNAPTICS_USB)	+= synaptics_usb.o
34af6ad
 obj-$(CONFIG_MOUSE_VSXXXAA)		+= vsxxxaa.o
34af6ad
 
34af6ad
-psmouse-objs := psmouse-base.o synaptics.o
34af6ad
+psmouse-objs := psmouse-base.o synaptics.o focaltech.o
34af6ad
 
34af6ad
 psmouse-$(CONFIG_MOUSE_PS2_ALPS)	+= alps.o
34af6ad
 psmouse-$(CONFIG_MOUSE_PS2_ELANTECH)	+= elantech.o
34af6ad
diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
34af6ad
new file mode 100644
34af6ad
index 000000000000..d83a23554d63
34af6ad
--- /dev/null
34af6ad
+++ b/drivers/input/mouse/focaltech.c
34af6ad
@@ -0,0 +1,44 @@
34af6ad
+/*
34af6ad
+ * Focaltech TouchPad PS/2 mouse driver
34af6ad
+ *
34af6ad
+ * Copyright (c) 2014 Red Hat Inc.
34af6ad
+ *
34af6ad
+ * This program is free software; you can redistribute it and/or modify
34af6ad
+ * it under the terms of the GNU General Public License as published by
34af6ad
+ * the Free Software Foundation; either version 2 of the License, or
34af6ad
+ * (at your option) any later version.
34af6ad
+ *
34af6ad
+ * Red Hat authors:
34af6ad
+ *
34af6ad
+ * Hans de Goede <hdegoede@redhat.com>
34af6ad
+ */
34af6ad
+
34af6ad
+/*
34af6ad
+ * The Focaltech PS/2 touchpad protocol is unknown. This drivers deals with
34af6ad
+ * detection only, to avoid further detection attempts confusing the touchpad
34af6ad
+ * this way it at least works in PS/2 mouse compatibility mode.
34af6ad
+ */
34af6ad
+
34af6ad
+#include <linux/device.h>
34af6ad
+#include <linux/libps2.h>
34af6ad
+#include "psmouse.h"
34af6ad
+
34af6ad
+static const char * const focaltech_pnp_ids[] = {
34af6ad
+	"FLT0101",
34af6ad
+	"FLT0102",
34af6ad
+	"FLT0103",
34af6ad
+	NULL
34af6ad
+};
34af6ad
+
34af6ad
+int focaltech_detect(struct psmouse *psmouse, bool set_properties)
34af6ad
+{
34af6ad
+	if (!psmouse_matches_pnp_id(psmouse, focaltech_pnp_ids))
34af6ad
+		return -ENODEV;
34af6ad
+
34af6ad
+	if (set_properties) {
34af6ad
+		psmouse->vendor = "FocalTech";
34af6ad
+		psmouse->name = "FocalTech Touchpad in mouse emulation mode";
34af6ad
+	}
34af6ad
+
34af6ad
+	return 0;
34af6ad
+}
34af6ad
diff --git a/drivers/input/mouse/focaltech.h b/drivers/input/mouse/focaltech.h
34af6ad
new file mode 100644
34af6ad
index 000000000000..0d0fc49451fe
34af6ad
--- /dev/null
34af6ad
+++ b/drivers/input/mouse/focaltech.h
34af6ad
@@ -0,0 +1,21 @@
34af6ad
+/*
34af6ad
+ * Focaltech TouchPad PS/2 mouse driver
34af6ad
+ *
34af6ad
+ * Copyright (c) 2014 Red Hat Inc.
34af6ad
+ *
34af6ad
+ * This program is free software; you can redistribute it and/or modify
34af6ad
+ * it under the terms of the GNU General Public License as published by
34af6ad
+ * the Free Software Foundation; either version 2 of the License, or
34af6ad
+ * (at your option) any later version.
34af6ad
+ *
34af6ad
+ * Red Hat authors:
34af6ad
+ *
34af6ad
+ * Hans de Goede <hdegoede@redhat.com>
34af6ad
+ */
34af6ad
+
34af6ad
+#ifndef _FOCALTECH_H
34af6ad
+#define _FOCALTECH_H
34af6ad
+
34af6ad
+int focaltech_detect(struct psmouse *psmouse, bool set_properties);
34af6ad
+
34af6ad
+#endif
34af6ad
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
34af6ad
index bc1bc2653f15..0730209cddb0 100644
34af6ad
--- a/drivers/input/mouse/psmouse-base.c
34af6ad
+++ b/drivers/input/mouse/psmouse-base.c
34af6ad
@@ -35,6 +35,7 @@
34af6ad
 #include "elantech.h"
34af6ad
 #include "sentelic.h"
34af6ad
 #include "cypress_ps2.h"
34af6ad
+#include "focaltech.h"
34af6ad
 
34af6ad
 #define DRIVER_DESC	"PS/2 mouse driver"
34af6ad
 
34af6ad
@@ -720,6 +721,13 @@ static int psmouse_extensions(struct psmouse *psmouse,
34af6ad
 {
34af6ad
 	bool synaptics_hardware = false;
34af6ad
 
34af6ad
+/* Always check for focaltech, this is safe as it uses pnp-id matching */
34af6ad
+	if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) {
34af6ad
+		/* Not supported yet, use bare protocol */
34af6ad
+		psmouse_max_proto = max_proto = PSMOUSE_PS2;
34af6ad
+		goto reset_to_defaults;
34af6ad
+	}
34af6ad
+
34af6ad
 /*
34af6ad
  * We always check for lifebook because it does not disturb mouse
34af6ad
  * (it only checks DMI information).
34af6ad
@@ -871,6 +879,8 @@ static int psmouse_extensions(struct psmouse *psmouse,
34af6ad
 		}
34af6ad
 	}
34af6ad
 
34af6ad
+reset_to_defaults:
34af6ad
+
34af6ad
 /*
34af6ad
  * Reset to defaults in case the device got confused by extended
34af6ad
  * protocol probes. Note that we follow up with full reset because
34af6ad
-- 
34af6ad
1.9.3
34af6ad