Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 08 Jun 2000 10:23:07 +0200
From:      Graham Wheeler <gram@cequrux.com>
To:        freebsd-stable@freebsd.org
Subject:   PS/2 mouse driver updates - can someone commit these?
Message-ID:  <c1421c9e261a0caccccabc25671069de@cequrux.com>

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

Hi folks

I have modified the psm driver to add support for Synaptics touch pads,
which are used on, amongst other things, Compaq laptops. My touchpad was
being detected as a Intellimouse and was having lots of problems with
synchronisation. The changes I made seem to make it behave even better
than the MS-Windows driver provided by Synaptics themselves (although
that does admittedly run in absolute mode and support a whole bunch of
advanced features and extra buttons which won't work with the code I
added).

In the process I noticed that there is a bug, in that the
GENERIC_MOUSE_ENTRY macro was defined to be an incorrect value. This
value changes with my patch in any case, so I haven't included a
separate fix.

Those who know something about PS/2 mouse packets will notice that I am
not using the overflow bits in my synchronisation check. It seems that
overflow can occur much more frequently with a touch pad than with a
real mouse, and using the overflow bits in the synchronisation mask
caused frequent loss of synchronisation. I suspect that this could be
biting a number of people, even with normal mice, given the regular
occurence of messages on the FreeBSD lists about the "psmintr: out of
sync" error logs. The psm.c code should really be reworked to be more
robust in the way it handled packets with overflow bits set, rather than
just dropping them and attempting to resync. My own experience is that
synchronisation is much better if these bits are excluded from the sync
mask, but that may only be practical when using two button mice, as two
button mice still leave two bits in the first byte that can be used for
sync purposes. 

There are two separate patch files attached; one simply defines a new
index for the Synaptics device (mouse.h), and the other includes the
necessary additions to support the device (psm.c).

One strange bit of behaviour with the Synaptics device is that between
the three bytes that make up a PS/2 packet in stream mode, there always
seems to be an extra zero byte. This will get dropped as part of the
normal synchronisation check, but I added special code to make the byte
get dropped silently, rather than to log an out-of-sync message.
Out-of-sync messages will still be logged if a non-sync byte is found
that is not zero-valued. I've sent mail to Synaptics to see if they can
explain this behaviour but haven't had a response yet.

Anyway, its good to have the touchpad working. Now if only a few more
XFree86 4.0 bugs got sorted out...

regards
gram
-- 
Dr Graham Wheeler                        E-mail: gram@cequrux.com
Director, Research and Development       WWW:    http://www.cequrux.com
CEQURUX Technologies                     Phone:  +27(21)423-6065
Firewalls/VPN Specialists                Fax:    +27(21)424-3656
--------------F2AA6794AFC1689924E74CAF
Content-Type: text/plain; charset=us-ascii;
 name="patch1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch1"

*** sys/i386/include/mouse.h.orig	Tue Jun  6 22:09:27 2000
--- sys/i386/include/mouse.h	Tue Jun  6 22:46:54 2000
***************
*** 118,125 ****
--- 118,126 ----
  #define MOUSE_MODEL_VERSAPAD		9
  #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 */
  	int rate;		/* report rate (per sec), -1 if unknown */

--------------F2AA6794AFC1689924E74CAF
Content-Type: text/plain; charset=us-ascii;
 name="patch2"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch2"

*** sys/isa/psm.c.orig	Tue Jun  6 22:01:56 2000
--- sys/isa/psm.c	Wed Jun  7 15:03:26 2000
***************
*** 58,65 ****
--- 58,68 ----
   *  - 30 July 1997. Added APM support.
   *  - 5 March 1997. Defined driver configuration flags (PSM_CONFIG_XXX). 
   *    Improved sync check logic.
   *    Vendor specific support routines.
+  *
+  * Synaptics Touchpad support added by Graham Wheeler <gram@cequrux.com>
+  * - June 2000
   */
  
  #include "opt_psm.h"
  
***************
*** 258,265 ****
--- 261,269 ----
  static probefunc_t enable_4dmouse;
  static probefunc_t enable_4dplus;
  static probefunc_t enable_mmanplus;
  static probefunc_t enable_versapad;
+ static probefunc_t enable_synaptics;
  static int tame_mouse __P((struct psm_softc *, mousestatus_t *, unsigned char *));
  
  static struct {
      int                 model;
***************
*** 282,289 ****
--- 286,295 ----
      { MOUSE_MODEL_4D,			/* A4 Tech 4D Mouse */
        0x08, MOUSE_4D_PACKETSIZE, enable_4dmouse, },
      { MOUSE_MODEL_4DPLUS,		/* A4 Tech 4D+ Mouse */
        0xc8, MOUSE_4DPLUS_PACKETSIZE, enable_4dplus, },
+     { MOUSE_MODEL_SYNAPTICS,		/* Synaptics touchpad		*/
+       0x0c, MOUSE_PS2_PACKETSIZE, enable_synaptics, },
      { MOUSE_MODEL_INTELLI,		/* Microsoft IntelliMouse */
        0x08, MOUSE_PS2INTELLI_PACKETSIZE, enable_msintelli, },
      { MOUSE_MODEL_GLIDEPOINT,		/* ALPS GlidePoint */
        0xc0, MOUSE_PS2_PACKETSIZE, enable_aglide, },
***************
*** 293,301 ****
        0xe8, MOUSE_PS2VERSA_PACKETSIZE, enable_versapad, },
      { MOUSE_MODEL_GENERIC,
        0xc0, MOUSE_PS2_PACKETSIZE, NULL, },
  };
! #define GENERIC_MOUSE_ENTRY	7
  
  /* device driver declarateion */
  static device_method_t psm_methods[] = {
  	/* Device interface */
--- 299,307 ----
        0xe8, MOUSE_PS2VERSA_PACKETSIZE, enable_versapad, },
      { MOUSE_MODEL_GENERIC,
        0xc0, MOUSE_PS2_PACKETSIZE, NULL, },
  };
! #define GENERIC_MOUSE_ENTRY	11	
  
  /* device driver declarateion */
  static device_method_t psm_methods[] = {
  	/* Device interface */
***************
*** 559,566 ****
--- 565,573 ----
          { MOUSE_MODEL_VERSAPAD,		"VersaPad" },
          { MOUSE_MODEL_EXPLORER,		"IntelliMouse Explorer" },
          { MOUSE_MODEL_4D,		"4D Mouse" },
          { MOUSE_MODEL_4DPLUS,		"4D+ Mouse" },
+         { MOUSE_MODEL_SYNAPTICS,	"Synaptics PS/2 Touchpad in Relative Mode" },
          { MOUSE_MODEL_GENERIC,		"Generic PS/2 mouse" },
          { MOUSE_MODEL_UNKNOWN,		NULL },
      };
      int i;
***************
*** 1880,1892 ****
--- 1887,1907 ----
          /* discard the byte if the device is not open */
          if ((sc->state & PSM_OPEN) == 0)
              continue;
      
+ 	 /* Synaptics touchpad seems to always insert a zero byte
+ 	    between stream mode data packets. Skip these... */
+ 
+ 	if (c==0 && sc->inputbytes == 0 &&
+ 		sc->hw.model == MOUSE_MODEL_SYNAPTICS)
+ 	    continue;
+ 
          /* 
  	 * Check sync bits. We check for overflow bits and the bit 3
  	 * for most mice. True, the code doesn't work if overflow 
  	 * condition occurs. But we expect it rarely happens...
  	 */
+ 
  	if ((sc->inputbytes == 0) 
  		&& ((c & sc->mode.syncmask[0]) != sc->mode.syncmask[1])) {
              log(LOG_DEBUG, "psmintr: out of sync (%04x != %04x).\n", 
  		c & sc->mode.syncmask[0], sc->mode.syncmask[1]);
***************
*** 2179,2186 ****
--- 2194,2202 ----
  		ms.button |= ms.obutton & MOUSE_EXTBUTTONS;
  	    }
  	    break;
  
+ 	case MOUSE_MODEL_SYNAPTICS: /* nothing special yet */
  	case MOUSE_MODEL_GENERIC:
  	default:
  	    break;
  	}
***************
*** 2641,2648 ****
--- 2657,2721 ----
  
      sc->config |= PSM_CONFIG_HOOKRESUME | PSM_CONFIG_INITAFTERSUSPEND;
  
      return TRUE;				/* PS/2 absolute mode */
+ }
+ 
+ static int 
+ synaptics_extended_command(KBDC kbdc, unsigned cmd, int data[3])
+ {
+     set_mouse_resolution(kbdc, (cmd>>6)&0x3);
+     set_mouse_resolution(kbdc, (cmd>>4)&0x3);
+     set_mouse_resolution(kbdc, (cmd>>2)&0x3);
+     set_mouse_resolution(kbdc, (cmd>>0)&0x3);
+     return (get_mouse_status(kbdc, data, 0, 3) == 3) ? 0 : -1;
+ }
+ 
+ static int
+ enable_synaptics(struct psm_softc *sc)
+ {
+     KBDC kbdc = sc->kbdc;
+     int data[3], minor = 0, major = 0;
+ 
+     if (synaptics_extended_command(kbdc, 0, data) < 0)
+ 	return FALSE;
+     if (data[1] != 0x47)
+         return FALSE;
+ #if PSM_DEBUG >= 1
+     major = data[2]&0xf;
+     minor = data[0];
+     if (synaptics_extended_command(kbdc, 3, data) == 0)
+     {
+         static char *synaptic_pads[] = {
+ 		0,
+                 "TM41xx134 Standard",
+                 "TM41xxx156 Mini",
+                 "TM41xx180 Super",
+ 		0,
+ 		0,
+ 		0,
+                 "Flexible",
+                 "TM41xx220 Ultra-Thin",
+                 "TM41xx230 Wide",
+ 		0,
+                 "TM41xx240 Stamp",
+                 "TM41xx140 Submini",
+                 "TBD Multiswitch",
+ 		0,
+                 "TM41xx301 Advanced Technology",
+                 "TM41xx221 Ultra-Thin"
+ 	};
+         char *model = "(Unknown)";
+ 	int m = data[0] & 0x3F;
+ 	if (m >= 0 && m <= 16 && synaptic_pads[m])
+ 	    model = synaptic_pads[m];
+         printf("psm: Synaptics %s Touchpad v%d.%d\n", model, major, minor);
+     }
+ #else
+     (void)major;
+     (void)minor;
+ #endif
+     return TRUE;
  }
  
  static int
  psmresume(device_t dev)

--------------F2AA6794AFC1689924E74CAF--



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




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