linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] [2.5.68] [BUG #18] Add Synaptics touchpad tweaking to psmouse driver
@ 2003-04-22  2:46 Stuffed Crust
  2003-04-23 17:03 ` CaT
  2003-04-23 17:13 ` Christoph Hellwig
  0 siblings, 2 replies; 7+ messages in thread
From: Stuffed Crust @ 2003-04-22  2:46 UTC (permalink / raw)
  To: linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1157 bytes --]

One of the side-effects of the new input layer is that the old usermode 
tools for manipulating the touchpad configuration don't work any more.

Most importantly, the ability to disable the tap-to-click "feature".
And this has been long-recognized, as bug #18.  :)

So, here's my crack at scratching this itch.  it defaults to disabling 
the tap-to-click, but there's a module parameter to re-enable it.

I started writing this from the perspective of a full-native synaptics
driver, using the absolute mode of operation, which will let us do all
sorts of yummy things like corner taps and virtual scroll wheels and
sensitivity and whatnot... Anyone else working on this, before I wade
further in?

All of the new code is wrapped in #ifdef SYNAPTICS.

It should work on all models of the touchpad, old and new, but I've only 
tested this on my rev5.7 touchpad (Dell Inspiron 4100)

Feedback welcome!

 - Pizza
-- 
Solomon Peachy                                   pizza@f*cktheusers.org
                                                           ICQ #1318444
Quidquid latine dictum sit, altum viditur                 Melbourne, FL

[-- Attachment #1.2: psmouse_syn.diff --]
[-- Type: text/plain, Size: 8199 bytes --]

--- psmouse.ORIG	2003-04-21 20:03:25.000000000 -0400
+++ psmouse.c	2003-04-21 22:42:19.000000000 -0400
@@ -10,6 +10,11 @@
  * the Free Software Foundation.
  */
 
+/* 
+ * Initial Snaptics support by Solomon Peachy (pizza@shaftnet.org)
+ */
+#define SYNAPTICS
+
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -25,6 +30,11 @@
 
 static int psmouse_noext;
 
+#ifdef SYNAPTICS
+static int synaptics_tap = 0;
+MODULE_PARM(synaptics_tap, "1i");
+#endif
+
 #define PSMOUSE_CMD_SETSCALE11	0x00e6
 #define PSMOUSE_CMD_SETRES	0x10e8
 #define PSMOUSE_CMD_GETINFO	0x03e9
@@ -33,6 +43,7 @@
 #define PSMOUSE_CMD_GETID	0x02f2
 #define PSMOUSE_CMD_SETRATE	0x10f3
 #define PSMOUSE_CMD_ENABLE	0x00f4
+#define PSMOUSE_CMD_DISABLE	0x00f5
 #define PSMOUSE_CMD_RESET_DIS	0x00f6
 #define PSMOUSE_CMD_RESET_BAT	0x02ff
 
@@ -40,6 +51,52 @@
 #define PSMOUSE_RET_ACK		0xfa
 #define PSMOUSE_RET_NAK		0xfe
 
+#ifdef SYNAPTICS
+
+/* Synaptics special queries */
+#define STP_QRY_IDENTIFY	0x00
+#define STP_QRY_READ_MODES	0x01
+#define STP_QRY_READ_CAPS	0x02
+#define STP_QRY_READ_MODEL_ID	0x03
+#define STP_QRY_READ_SN_PREFIX	0x06
+#define STP_QRY_READ_SN_SUFFIX	0x07
+#define STP_QRY_READ_RES	0x08
+
+/* Model ID bits */
+#define STP_INFO_ROT180(id)	(((id) & 0x800000) >> 23)
+#define STP_INFO_PORTRAIT(id)	(((id) & 0x400000) >> 22)
+#define STP_INFO_SENSOR(id)	(((id) & 0x3F0000) >> 16)
+#define STP_INFO_HARDWARE(id)	(((id) & 0x00FE00) >> 9)
+#define STP_INFO_NEW_ABS(id)	(((id) & 0x000080) >> 7)
+#define STP_INFO_CAP_PEN(id)	(((id) & 0x000040) >> 6)
+#define STP_INFO_SIMPLE_CMD(id)	(((id) & 0x000020) >> 5)
+#define STP_INFO_GEOMETRY(id)	 ((id) & 0x00000F)
+
+#define STP_SET_MODE_ABSOLUTE(m, a)	(((m) &~ 0x80) | ((a) << 7))
+#define STP_SET_MODE_RATE(m, a)		(((m) &~ 0x40) | ((a) << 6))
+#define STP_SET_MODE_SLEEP(m, a)	(((m) &~ 0x08) | ((a) << 3))
+#define STP_SET_MODE_GESTURE(m, a)	(((m) &~ 0x04) | ((!a) << 2))
+#define STP_SET_MODE_PACKSIZE(m, a)	(((m) &~ 0x02) | ((a) << 1))
+#define STP_SET_MODE_WMODE(m, a)	(((m) &~ 0x01) | (a))
+
+#define STP_SET_OMODE_CORNER(m, a)	(((m) &~ 0x80000000) | ((a) << 31))
+#define STP_SET_OMODE_Z_THRESH(m, a)	(((m) &~ 0x70000000) | ((a) << 28))
+#define STP_SET_OMODE_TAP_MODE(m, a)	(((m) &~ 0x0C000000) | ((a) << 26))
+#define STP_SET_OMODE_EDGE_MOTN(m, a)	(((m) &~ 0x03000000) | ((a) << 24))
+#define STP_SET_OMODE_ABSOLUTE(m, a)	(((m) &~ 0x00800000) | ((a) << 23))
+#define STP_SET_OMODE_RATE(m, a)	(((m) &~ 0x00400000) | ((a) << 22))
+#define STP_SET_OMODE_BAUD(m, a)	(((m) &~ 0x00080000) | ((a) << 19))
+#define STP_SET_OMODE_3_BUTTON(m, a)	(((m) &~ 0x00040000) | ((a) << 18))
+#define STP_SET_OMODE_MIDDLE(m, a)	(((m) &~ 0x00020000) | ((a) << 17))
+#define STP_SET_OMODE_HOP(m, a)		(((m) &~ 0x00010000) | ((a) << 16))
+#define STP_SET_OMODE_RIGHT_MGN(m, a)	(((m) &~ 0x0000F000) | ((a) << 12))
+#define STP_SET_OMODE_LEFT_MGN(m, a)	(((m) &~ 0x00000F00) | ((a) << 8))
+#define STP_SET_OMODE_TOP_MGN(m, a)	(((m) &~ 0x000000F0) | ((a) << 4))
+#define STP_SET_OMODE_BOTTOM_MGN(m, a)	(((m) &~ 0x0000000F) |  (a))
+#define QUAD_MODE_BYTE		0x0302
+
+#endif
+
 struct psmouse {
 	struct input_dev dev;
 	struct serio *serio;
@@ -57,8 +114,22 @@
 	char error;
 	char devname[64];
 	char phys[32];
+
+#ifdef SYNAPTICS
+	unsigned int fw_version;
+	unsigned int single_mode_byte;
+	unsigned int model_id;
+	unsigned int modes;
+	unsigned int caps;
+#endif
 };
 
+#ifdef SYNAPTICS
+static void synaptics_command(struct psmouse *psmouse, unsigned char cmd);
+static void synaptics_set_mode(struct psmouse *psmouse, unsigned int mode);
+unsigned int synaptics_get_mode(struct psmouse *psmouse);
+#endif
+
 #define PSMOUSE_PS2	1
 #define PSMOUSE_PS2PP	2
 #define PSMOUSE_PS2TPP	3
@@ -345,6 +416,54 @@
                   thing up. */
                psmouse->vendor = "Synaptics";
                psmouse->name = "TouchPad";
+
+#ifdef SYNAPTICS
+	       param[0] = 0;
+	       synaptics_command(psmouse, STP_QRY_IDENTIFY);
+	       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+	       psmouse->fw_version = ((param[2] & 0x0f) << 8) | param[0];
+
+	       synaptics_command(psmouse, STP_QRY_READ_MODEL_ID);
+	       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+
+	       psmouse->model_id = ((param[1] & 0x1) ? 0x1 :
+				    (((unsigned int) param[0] << 16) |
+				     ((unsigned int) param[1] << 8) |
+				     ((unsigned int) param[2])));
+
+	       psmouse->single_mode_byte = STP_INFO_SIMPLE_CMD (psmouse->model_id);
+	       /* Fetch capabilities */
+	       synaptics_command(psmouse, STP_QRY_READ_MODEL_ID);
+	       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+	       psmouse->caps = (((unsigned int) param[0] << 8) | 
+				(unsigned int) param[2]);
+
+	       printk(KERN_INFO "Found Synaptics Touchpad rev %d.%d\n",
+		      (psmouse->fw_version >> 8) & 0x0f,
+		      (psmouse->fw_version & 0xff));
+
+	       /* pull the modes down */
+	       psmouse->modes = synaptics_get_mode(psmouse);
+
+	       /* Now, disable tap-to-click and enable high rate. */
+	       
+	       if (psmouse->single_mode_byte) {
+		       psmouse->modes = STP_SET_MODE_GESTURE(psmouse->modes, synaptics_tap);
+		       psmouse->modes = STP_SET_MODE_RATE(psmouse->modes, 1);
+
+		       synaptics_set_mode(psmouse, psmouse->modes);
+	       } else {
+		       psmouse->modes = STP_SET_OMODE_TAP_MODE(psmouse->modes, synaptics_tap);
+		       psmouse->modes = STP_SET_OMODE_RATE(psmouse->modes, 1);
+
+		       synaptics_set_mode(psmouse, psmouse->modes);
+	       }
+			       
+	       psmouse->modes = synaptics_get_mode(psmouse);
+#else
+	       printk(KERN_INFO "Found Synaptics touchpad, support disabled\n");
+#endif
+
                return PSMOUSE_PS2;
        }
 
@@ -682,5 +801,78 @@
 	serio_unregister_device(&psmouse_dev);
 }
 
+#ifdef SYNAPTICS
+void synaptics_command(struct psmouse *psmouse, unsigned char cmd) 
+{
+	unsigned char param[4];
+
+	param[0] = (cmd & 0xC0) >> 6;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = (cmd & 0x30) >> 4;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = (cmd & 0x0C) >> 2;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = (cmd & 0x03);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+void synaptics_set_mode(struct psmouse *psmouse, unsigned int mode)
+{
+	unsigned char param[4];
+//	printk(KERN_INFO "Synaptics set mode: %08x\n", mode);
+  
+	psmouse_command(psmouse, param, PSMOUSE_CMD_DISABLE);
+	
+	if (psmouse->single_mode_byte) {
+		synaptics_command(psmouse, mode & 0xff);
+		param[0] = 20;
+		psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+	} else {
+		synaptics_command(psmouse, (mode >> 24) & 0xff);
+		param[0] = 10;
+		psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+		synaptics_command(psmouse, (mode >> 16) & 0xff);
+		param[0] = 20;
+		psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+		if (psmouse->fw_version < QUAD_MODE_BYTE) {
+			synaptics_command(psmouse, (mode >> 8) & 0xff);
+			param[0] = 40;
+			psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+			synaptics_command(psmouse, mode & 0xff);
+			param[0] = 60;
+			psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+		}
+	}
+
+	psmouse_command(psmouse, param, PSMOUSE_CMD_ENABLE);
+}
+
+unsigned int synaptics_get_mode(struct psmouse *psmouse)
+{
+	unsigned char param[4];
+	unsigned int retval = 0;
+	
+	synaptics_command(psmouse, STP_QRY_READ_MODES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+	
+	param[1] = 0;
+	
+	if (psmouse->single_mode_byte) {
+		retval = param[2];
+	} else {
+		retval = ((param[0] << 24) |
+			  (param[2] << 16));
+		
+		if (psmouse->fw_version < QUAD_MODE_BYTE) {
+			synaptics_command(psmouse, STP_QRY_READ_CAPS);
+			psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+			retval |= ((param[0] << 8) |
+				   (param[2]));
+		} 
+	}
+	return retval;
+}
+#endif
+
 module_init(psmouse_init);
 module_exit(psmouse_exit);

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread
* RE: [PATCH] [2.5.68] [BUG #18] Add Synaptics touchpad tweaking to psmouse driver
@ 2003-04-25  0:58 Perez-Gonzalez, Inaky
  2003-04-25  1:34 ` Stuffed Crust
  0 siblings, 1 reply; 7+ messages in thread
From: Perez-Gonzalez, Inaky @ 2003-04-25  0:58 UTC (permalink / raw)
  To: 'Stuffed Crust', 'lkml (linux-kernel@vger.kernel.org)'


-----Original Message-----
> From: Stuffed Crust [mailto:pizza@shaftnet.org]
>
> Um, it doesn't reduce functionality.  There's a module parameter to
> enable/disable the tap-to-click.  :)

Can that be made a /sysfs tunable?

Iñaky Pérez-González -- Not speaking for Intel -- all opinions are my own
(and my fault)

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

end of thread, other threads:[~2003-04-25  1:24 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-22  2:46 [PATCH] [2.5.68] [BUG #18] Add Synaptics touchpad tweaking to psmouse driver Stuffed Crust
2003-04-23 17:03 ` CaT
2003-04-23 17:10   ` Stuffed Crust
2003-04-23 17:13 ` Christoph Hellwig
2003-04-23 17:37   ` Stuffed Crust
2003-04-25  0:58 Perez-Gonzalez, Inaky
2003-04-25  1:34 ` Stuffed Crust

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).