Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 02 Jan 2004 03:18:15 +0100
From:      Marcin Dalecki <mdcki@gmx.net>
To:        Arne Schwabe <arne@rfc2549.org>
Cc:        FreeBSD Current <freebsd-current@freebsd.org>
Subject:   Re: Synaptics Touchpad xfree driver hack :)
Message-ID:  <3FF4D4E7.4000400@gmx.net>
In-Reply-To: <86n097dco9.fsf@kamino.rfc1149.org>
References:  <86n097dco9.fsf@kamino.rfc1149.org>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------050300030306020904010207
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Arne Schwabe wrote:
> Hi,

A long long time ago ... I solved this problem in a way
relying on the fine mouse support infrastructure found in
FreeBSD (aka mounsd). Hardware management and sharig it
IMHO something kernels are for. This way even the mouse
on console will still be available. Patch attached...


_____________
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org"
> 
> 


--------------050300030306020904010207
Content-Type: text/plain;
 name="synaptics-002.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="synaptics-002.diff"

diff -urN src-old/sys/isa/psm.c src/sys/isa/psm.c
--- src-old/sys/isa/psm.c	Tue Dec 31 00:35:19 2002
+++ src/sys/isa/psm.c	Tue Dec 31 01:05:35 2002
@@ -277,6 +277,7 @@
 static probefunc_t enable_4dplus;
 static probefunc_t enable_mmanplus;
 static probefunc_t enable_versapad;
+static probefunc_t enable_synaptics;
 static int tame_mouse(struct psm_softc *, mousestatus_t *, unsigned char *);
 
 static struct {
@@ -309,6 +310,8 @@
       0x80, MOUSE_PS2_PACKETSIZE, enable_kmouse, },
     { MOUSE_MODEL_VERSAPAD,		/* Interlink electronics VersaPad */
       0xe8, MOUSE_PS2VERSA_PACKETSIZE, enable_versapad, },
+    { MOUSE_MODEL_SYNAPTICS,		/* Synaptics TouchPad */
+      0xc0, MOUSE_PS2SYNAP_PACKETSIZE, enable_synaptics, },
     { MOUSE_MODEL_GENERIC,
       0xc0, MOUSE_PS2_PACKETSIZE, NULL, },
 };
@@ -570,6 +573,7 @@
         { MOUSE_MODEL_EXPLORER,		"IntelliMouse Explorer" },
         { MOUSE_MODEL_4D,		"4D Mouse" },
         { MOUSE_MODEL_4DPLUS,		"4D+ Mouse" },
+	{ MOUSE_MODEL_SYNAPTICS,	"Synaptics TouchPad" },
         { MOUSE_MODEL_GENERIC,		"Generic PS/2 mouse" },
         { MOUSE_MODEL_UNKNOWN,		NULL },
     };
@@ -1964,7 +1968,7 @@
      * the table to turn PS/2 mouse button bits (MOUSE_PS2_BUTTON?DOWN)
      * into `mousestatus' button bits (MOUSE_BUTTON?DOWN).
      */
-    static int butmap[8] = {
+    static const int butmap[8] = {
         0, 
 	MOUSE_BUTTON1DOWN, 
 	MOUSE_BUTTON3DOWN, 
@@ -1974,7 +1978,7 @@
 	MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN,
         MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN
     };
-    static int butmap_versapad[8] = {
+    static const int butmap_versapad[8] = {
 	0, 
 	MOUSE_BUTTON3DOWN, 
 	0, 
@@ -1987,18 +1991,18 @@
     register struct psm_softc *sc = arg;
     mousestatus_t ms;
     struct timeval tv;
-    int x, y, z;
+    int x, y, z, w;
     int c;
     int l;
     int x0, y0;
 
     /* read until there is nothing to read */
     while((c = read_aux_data_no_wait(sc->kbdc)) != -1) {
-    
+
         /* discard the byte if the device is not open */
         if ((sc->state & PSM_OPEN) == 0)
             continue;
-    
+
 	getmicrouptime(&tv);
 	if ((sc->inputbytes > 0) && timevalcmp(&tv, &sc->inputtimeout, >)) {
 	    log(LOG_DEBUG, "psmintr: delay too long; resetting byte count\n");
@@ -2014,9 +2018,9 @@
 	    continue;
 
 #if 0
-        log(LOG_DEBUG, "psmintr: %02x %02x %02x %02x %02x %02x\n",
-	    sc->ipacket[0], sc->ipacket[1], sc->ipacket[2],
-	    sc->ipacket[3], sc->ipacket[4], sc->ipacket[5]);
+	log(LOG_DEBUG, "psmintr: %02x %02x %02x %02x %02x %02x\n",
+		sc->ipacket[0], sc->ipacket[1], sc->ipacket[2],
+		sc->ipacket[3], sc->ipacket[4], sc->ipacket[5]);
 #endif
 
 	c = sc->ipacket[0];
@@ -2320,6 +2324,80 @@
 	    }
 	    break;
 
+	case MOUSE_MODEL_SYNAPTICS:
+	    /* TouchPad PS/2 absolute mode message format
+	     *
+	     *  Bits:        7   6   5   4   3   2   1   0 (LSB)
+	     *  ------------------------------------------------
+	     *  ipacket[0]:  1   0  W3  W2   0  W1   R   L
+	     *  ipacket[1]: Yb  Ya  Y9  Y8  Xb  Xa  X9  X8
+	     *  ipacket[2]: Z7  Z6  Z5  Z4  Z3  Z2  Z1  Z0
+	     *  ipacket[3]:  1   1  Yc  Xc   0  W0   D   U
+	     *  ipacket[4]: X7  X6  X5  X4  X3  X2  X1  X0
+	     *  ipacket[5]: Y7  Y6  Y5  Y4  Y3  Y2  Y1  Y0
+	     *
+	     * Legend:
+	     *  L: left physical mouse button
+	     *  R: right physical mouse button
+	     *  D: down button
+	     *  U: up button
+	     *  W: "wrist" value
+	     *  X: x position
+	     *  Y: x position
+	     *  Z: pressure
+	     *
+	     * Absolute reportable limits:    0 - 6143.
+	     * Typical bezel limites:	   1472 - 5472.
+	     * Typical edge marings:	   1632 - 5312.
+	     */
+
+	    /* Sanity check for out of sync packets. */
+	    if ((sc->ipacket[0] & 0xc8) != 0x80 || (sc->ipacket[3] & 0xc8) != 0xc0)
+		continue;
+
+	    ms.button = 0;
+	    x = y = x0 = y0 = 0;
+
+	    /* pressure */
+	    z = sc->ipacket[2];
+	    w = ((sc->ipacket[0] & 0x30) >> 2) |
+		((sc->ipacket[0] & 0x04) >> 1) |
+		((sc->ipacket[3] & 0x04) >> 2);
+
+	    ms.button = 0;
+	    if (sc->ipacket[0] & 0x01)
+		ms.button |= MOUSE_BUTTON1DOWN;
+	    if (sc->ipacket[0] & 0x02)
+		ms.button |= MOUSE_BUTTON3DOWN;
+	    if ((sc->ipacket[3] & 0x01) && !(sc->ipacket[0] & 0x01))
+		ms.button |= MOUSE_BUTTON2DOWN;
+	    if ((sc->ipacket[3] & 0x02) && !(sc->ipacket[0] & 0x02))
+		ms.button |= MOUSE_BUTTON4DOWN;
+
+	    /* There is a finger on the pad */
+	    if ((w >= 4 && w <= 7) && (z >= 16 && z < 128) ) {
+		x0 = ((sc->ipacket[3] & 0x10) << 8) | ((sc->ipacket[1] & 0x0f) << 8) | sc->ipacket[4];
+		y0 = ((sc->ipacket[3] & 0x20) << 7) | ((sc->ipacket[1] & 0xf0) << 4) | sc->ipacket[5];
+
+		if (sc->flags & PSM_FLAGS_FINGERDOWN) {
+		    x0 = (x0 + sc->xold * 3) / 4;
+		    y0 = (y0 + sc->yold * 3) / 4;
+
+		    x = (x0 - sc->xold) / 4;
+		    y = (y0 - sc->yold) / 4;
+		} else {
+		    sc->flags |= PSM_FLAGS_FINGERDOWN;
+		}
+
+		sc->xold = x0;
+		sc->yold = y0;
+	    } else {
+		sc->flags &= ~PSM_FLAGS_FINGERDOWN;
+	    }
+	    z = 0;
+
+	    break;
+
 	case MOUSE_MODEL_GENERIC:
 	default:
 	    break;
@@ -2804,6 +2882,105 @@
 	return FALSE;
     set_mouse_scaling(kbdc, 1);			/* set scale 1:1 */
 
+    sc->config |= PSM_CONFIG_HOOKRESUME | PSM_CONFIG_INITAFTERSUSPEND;
+
+    return TRUE;				/* PS/2 absolute mode */
+}
+
+/* Synaptics touch pad */
+static int
+enable_synaptics(struct psm_softc *sc)
+{
+    KBDC kbdc = sc->kbdc;
+    int res;
+    int data[4];
+    int info_rot180;
+    int info_portrait;
+    int info_sensor;
+    int info_hardware;
+    int info_new_abs;
+    int info_cap_pen;
+    int info_simple_cmd;
+    int info_geometry;
+
+    if (verbose >= 2)
+        log(LOG_DEBUG, "psm: ENABLE_SYNAPTICS\n");
+
+    /* Idenfity.
+     */
+    empty_aux_buffer(kbdc, 5);
+    mouse_ext_command(kbdc, 0x00);
+    if (get_mouse_status(kbdc, data, 0, 3) < 3)
+	return FALSE;
+    if (data[1] != 0x47)
+	return FALSE;
+
+    printf("Synaptics Touchpad:\n");
+    printf("  model:          %d\n", (data[2] >> 4) & 0x0f);
+    printf("  firmware ver.:  %d.%d\n", data[2] & 0x0f, data[0]);
+
+    /* Read Model ID.
+     */
+    empty_aux_buffer(kbdc, 5);
+    mouse_ext_command(kbdc, 0x03);
+    if (get_mouse_status(kbdc, data, 0, 3) < 3)
+	return FALSE;
+
+    info_rot180     = (data[0] & 0x80);
+    info_portrait   = (data[0] & 0x40);
+    info_sensor     = (data[0] & 0x003f);
+    info_hardware   = (data[1] & 0xfe) >> 1;
+    info_new_abs    = (data[2] & 0x80);
+    info_cap_pen    = (data[2] & 0x40);
+    info_simple_cmd = (data[2] & 0x20);
+    info_geometry   = (data[2] & 0x0f);
+
+    printf("  rot180:         %s\n", info_rot180 ? "Yes" : "No");
+    printf("  portrait:       %s\n", info_portrait ? "Yes" : "No");
+    printf("  sensor:         %d\n", info_sensor);
+    printf("  hardware:       %d\n", info_hardware);
+    printf("  newABS:         %s\n", info_new_abs ? "Yes" : "No");
+    printf("  capPen:         %s\n", info_cap_pen ? "Yes" : "No");
+    printf("  simpleCmd:      %s\n", info_simple_cmd ? "Yes" : "No");
+    printf("  geometry:       %d\n", info_geometry);
+
+    /* Read Capabilities.
+     */
+    empty_aux_buffer(kbdc, 5);
+    mouse_ext_command(kbdc, 0x02);
+    if (get_mouse_status(kbdc, data, 0, 3) < 3)
+	return FALSE;
+    if (data[1] != 0x47)
+	return FALSE;
+
+    printf("  capExtended:    %s\n", (data[0] & 0x80) ? "Yes" : "No");
+    printf("  capSleep:       %s\n", (data[2] & 0x10) ? "Yes" : "No");
+    printf("  capFourButtons: %s\n", (data[2] & 0x08) ? "Yes" : "No");
+    printf("  capMultiFinger: %s\n", (data[2] & 0x02) ? "Yes" : "No");
+    printf("  capPalmDetect:  %s\n", (data[2] & 0x01) ? "Yes" : "No");
+
+    /* Now we set the operating mode to absolute.
+     */
+#define SYN_BIT_ABSOLUTE_MODE	0x80
+#define SYN_BIT_HIGH_RATE	0x40
+#define SYN_BIT_SLEEP_MODE	0x08
+#define SYN_BIT_DISABLE_GESTURE 0x04
+#define SYN_BIT_W_MODE		0x01
+
+    empty_aux_buffer(kbdc, 5);
+    mouse_ext_command(kbdc, SYN_BIT_ABSOLUTE_MODE |
+	                    SYN_BIT_HIGH_RATE |
+	                    SYN_BIT_DISABLE_GESTURE |
+	                    SYN_BIT_W_MODE);
+    res = send_aux_command_and_data(kbdc, PSMC_SET_SAMPLING_RATE, 0x14);
+    if (res != PSM_ACK) {
+        log(LOG_ERR, "psm: setting Synaptics TouchPad mode failed,\n");
+	return FALSE;
+    }
+
+    set_mouse_scaling(kbdc, 1);			/* set scale 1:1 */
+
+    sc->hw.buttons = 4;
     sc->config |= PSM_CONFIG_HOOKRESUME | PSM_CONFIG_INITAFTERSUSPEND;
 
     return TRUE;				/* PS/2 absolute mode */
diff -urN src-old/sys/sys/mouse.h src/sys/sys/mouse.h
--- src-old/sys/sys/mouse.h	Tue Dec 31 00:35:19 2002
+++ src/sys/sys/mouse.h	Tue Dec 31 05:13:49 2002
@@ -119,6 +119,7 @@
 #define MOUSE_MODEL_EXPLORER		10
 #define MOUSE_MODEL_4D			11
 #define MOUSE_MODEL_4DPLUS		12
+#define MOUSE_MODEL_SYNAPTICS		13
 
 typedef struct mousemode {
 	int protocol;		/* MOUSE_PROTO_XXX */
@@ -139,7 +140,7 @@
  * Bus mouse protocols:
  *   bus, InPort
  * PS/2 mouse protocol:
- *   PS/2
+ *   PS/2, Synaptics TouchPad
  */
 #define MOUSE_PROTO_UNKNOWN	(-1)
 #define MOUSE_PROTO_MS		0	/* Microsoft Serial, 3 bytes */
@@ -159,6 +160,7 @@
 #define MOUSE_PROTO_KIDSPAD	14	/* Genius Kidspad */
 #define MOUSE_PROTO_VERSAPAD	15	/* Interlink VersaPad, 6 bytes */
 #define MOUSE_PROTO_JOGDIAL	16	/* Vaio's JogDial */
+#define MOUSE_PROTO_SYNAPTICS	17	/* Synaptics TouchPad, 6 bytes */
 
 #define MOUSE_RES_UNKNOWN	(-1)
 #define MOUSE_RES_DEFAULT	0
@@ -293,12 +295,15 @@
 #define MOUSE_PS2VERSA_BUTTON3DOWN	0x01	/* right */
 #define MOUSE_PS2VERSA_TAP		0x02
 
+/* Synaptics TouchPad (PS/2 I/F) data packet */
+#define MOUSE_PS2SYNAP_PACKETSIZE	6
+
 /* A4 Tech 4D Mouse (PS/2) data packet */
-#define MOUSE_4D_PACKETSIZE		3	
+#define MOUSE_4D_PACKETSIZE		3
 #define MOUSE_4D_WHEELBITS		0xf0
 
 /* A4 Tech 4D+ Mouse (PS/2) data packet */
-#define MOUSE_4DPLUS_PACKETSIZE		3	
+#define MOUSE_4DPLUS_PACKETSIZE		3
 #define MOUSE_4DPLUS_ZNEG		0x04	/* sign bit */
 #define MOUSE_4DPLUS_BUTTON4DOWN	0x08
 

--------------050300030306020904010207--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3FF4D4E7.4000400>