summary refs log tree commit diff
path: root/drivers/input
diff options
context:
space:
mode:
authorÉric Piel <E.A.B.Piel@tudelft.nl>2011-05-16 22:45:54 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-05-16 22:48:36 -0700
commitf941c705f68fa62f694678bf2efde64dfb9962bb (patch)
treea28ab3fe92f561df2e2998261dc20436be60b08a /drivers/input
parent71c6d18859ccb137343017ec995b76d9f62bd9b0 (diff)
downloadlinux-f941c705f68fa62f694678bf2efde64dfb9962bb.tar.gz
Input: elantech - export pressure and width when supported
Using the info of the Dell/Ubuntu driver, described in the protocol
document, report both width and pressure when pressing 1 and 3
fingers, for the versions of the touchpad which support it.

Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
Reviewed-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/mouse/elantech.c23
-rw-r--r--drivers/input/mouse/elantech.h6
2 files changed, 28 insertions, 1 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 04d9bf320a4f..5cde11f4ef5e 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -248,9 +248,10 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
  */
 static void elantech_report_absolute_v2(struct psmouse *psmouse)
 {
+	struct elantech_data *etd = psmouse->private;
 	struct input_dev *dev = psmouse->dev;
 	unsigned char *packet = psmouse->packet;
-	int fingers, x1, y1, x2, y2;
+	int fingers, x1, y1, x2, y2, width = 0, pres = 0;
 
 	/* byte 0: n1  n0   .   .   .   .   R   L */
 	fingers = (packet[0] & 0xc0) >> 6;
@@ -278,6 +279,8 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 		 */
 		input_report_abs(dev, ABS_Y,
 			ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]));
+		pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
+		width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4);
 		break;
 
 	case 2:
@@ -311,6 +314,10 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 		input_report_abs(dev, ABS_HAT0Y, y1);
 		input_report_abs(dev, ABS_HAT1X, x2);
 		input_report_abs(dev, ABS_HAT1Y, y2);
+
+		/* Unknown so just report sensible values */
+		pres = 127;
+		width = 7;
 		break;
 	}
 
@@ -320,6 +327,10 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 	input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4);
 	input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
 	input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+	if (etd->reports_pressure) {
+		input_report_abs(dev, ABS_PRESSURE, pres);
+		input_report_abs(dev, ABS_TOOL_WIDTH, width);
+	}
 
 	input_sync(dev);
 }
@@ -478,6 +489,12 @@ static void elantech_set_input_params(struct psmouse *psmouse)
 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
 		input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
 		input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
+		if (etd->reports_pressure) {
+			input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2,
+					     ETP_PMAX_V2, 0, 0);
+			input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2,
+					     ETP_WMAX_V2, 0, 0);
+		}
 		input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
 		input_set_abs_params(dev, ABS_HAT0Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0);
 		input_set_abs_params(dev, ABS_HAT1X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
@@ -725,6 +742,10 @@ int elantech_init(struct psmouse *psmouse)
 		etd->debug = 1;
 		/* Don't know how to do parity checking for version 2 */
 		etd->paritycheck = 0;
+
+		if (etd->fw_version >= 0x020800)
+			etd->reports_pressure = true;
+
 	} else {
 		etd->hw_version = 1;
 		etd->paritycheck = 1;
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index aa4aac5d2198..fabb2b99615c 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -77,6 +77,11 @@
 #define ETP_YMIN_V2			(   0 + ETP_EDGE_FUZZ_V2)
 #define ETP_YMAX_V2			( 768 - ETP_EDGE_FUZZ_V2)
 
+#define ETP_PMIN_V2			0
+#define ETP_PMAX_V2			255
+#define ETP_WMIN_V2			0
+#define ETP_WMAX_V2			15
+
 /*
  * For two finger touches the coordinate of each finger gets reported
  * separately but with reduced resolution.
@@ -102,6 +107,7 @@ struct elantech_data {
 	unsigned char capabilities;
 	bool paritycheck;
 	bool jumpy_cursor;
+	bool reports_pressure;
 	unsigned char hw_version;
 	unsigned int fw_version;
 	unsigned int single_finger_reports;