Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 06 Jul 2000 10:18:31 +0200
From:      Graham Wheeler <gram@cequrux.com>
To:        "Jordan K. Hubbard" <jkh@zippy.osd.bsdi.com>, Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>, freebsd-stable@freebsd.org
Subject:   Re: FreeBSD-4.0S/psmintr out of sync/Synaptics Touchpad
Message-ID:  <252f164763d80f7d24a27596529b8450@cequrux.com>
References:  <41892.962825101@localhost>

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

As Jordan as reported a similar problem (or the same problem) with a
regular Logitech mouse in -current, I thought it would be worth posting
my current patches.

Yesterday I once again had the behaviour of the past weekend, so I now
have added a flag to indicate the type of sync problem currently being
experienced so that the driver can adapt on the fly. It's still not
perfect, but its quite close now (I think the occasional aberattions I
see occur at points where the mode variable gets toggled).

Because this is starting to get messy, I have attached both a patch and
the first 120 lines of my version of the psmintr routine.

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
--------------715AA62B84C7D3D2EAB84DD8
Content-Type: text/plain; charset=us-ascii;
 name="psm.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="psm.patch"

*** psm.c.orig	Tue Jun  6 22:01:56 2000
--- psm.c	Thu Jul  6 09:58:39 2000
***************
*** 59,64 ****
--- 59,67 ----
   *  - 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"
***************
*** 259,264 ****
--- 262,268 ----
  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 {
***************
*** 283,288 ****
--- 287,294 ----
        0x08, MOUSE_4D_PACKETSIZE, enable_4dmouse, },
      { MOUSE_MODEL_4DPLUS,		/* A4 Tech 4D+ Mouse */
        0xc8, MOUSE_4DPLUS_PACKETSIZE, enable_4dplus, },
+     { MOUSE_MODEL_SYNAPTICS,		/* Synaptics touchpad		*/
+       0xc8, MOUSE_PS2_PACKETSIZE*/, enable_synaptics, },
      { MOUSE_MODEL_INTELLI,		/* Microsoft IntelliMouse */
        0x08, MOUSE_PS2INTELLI_PACKETSIZE, enable_msintelli, },
      { MOUSE_MODEL_GLIDEPOINT,		/* ALPS GlidePoint */
***************
*** 294,300 ****
      { MOUSE_MODEL_GENERIC,
        0xc0, MOUSE_PS2_PACKETSIZE, NULL, },
  };
! #define GENERIC_MOUSE_ENTRY	7
  
  /* device driver declarateion */
  static device_method_t psm_methods[] = {
--- 300,306 ----
      { MOUSE_MODEL_GENERIC,
        0xc0, MOUSE_PS2_PACKETSIZE, NULL, },
  };
! #define GENERIC_MOUSE_ENTRY	11	
  
  /* device driver declarateion */
  static device_method_t psm_methods[] = {
***************
*** 560,565 ****
--- 566,572 ----
          { 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 },
      };
***************
*** 1867,1872 ****
--- 1874,1881 ----
  	MOUSE_BUTTON1DOWN,
  	MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN
      };
+     static int syncerrs = 0;
+     static int synaptics_sync_hack_mode = 0;
      register struct psm_softc *sc = arg;
      mousestatus_t ms;
      int x, y, z;
***************
*** 1881,1902 ****
          if ((sc->state & PSM_OPEN) == 0)
              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]);
!             continue;
  	}
  
          sc->ipacket[sc->inputbytes++] = c;
!         if (sc->inputbytes < sc->mode.packetsize) 
  	    continue;
  
  #if 0
          log(LOG_DEBUG, "psmintr: %02x %02x %02x %02x %02x %02x\n",
  	    sc->ipacket[0], sc->ipacket[1], sc->ipacket[2],
--- 1890,1960 ----
          if ((sc->state & PSM_OPEN) == 0)
              continue;
      
+         if (syncerrs>0)
+ 	{
+ 	    log(LOG_DEBUG, "psmintr: read %04x (mode %d).\n", c, synaptics_sync_hack_mode);
+ 	    if (--syncerrs == 0)
+ 		log(LOG_DEBUG, "psmintr: stopping logging reads\n");;
+ 	}
+ 	if (c==0 && sc->inputbytes == 0 &&
+ 		sc->hw.model == MOUSE_MODEL_SYNAPTICS)
+ 	{
+ 	    if (synaptics_sync_hack_mode)
+ 	    {
+ 		synaptics_sync_hack_mode = 0;
+                 log(LOG_DEBUG, "psmintr: synaptics_sync_hack_mode 1->0\n");
+ 		syncerrs = 10; /* log the next ten reads */
+ 	    }
+ 	    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) 
!         {
! 	    if (sc->hw.model == MOUSE_MODEL_SYNAPTICS)
! 	    {
! 		if ((c&0xCC)!=0x08)
! 		{
! 	    	    if (synaptics_sync_hack_mode ==0)
! 		    {
! 			synaptics_sync_hack_mode = 1;
!                 	log(LOG_DEBUG, "psmintr: synaptics_sync_hack_mode 0->1\n");
! 	                syncerrs = 10; /* log next ten reads */
! 		    }
!                     log(LOG_DEBUG, "psmintr: %04x out of sync.\n", c);
!                     continue;
! 		}
! 	    }
! 	    else if (((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]);
!                 continue;
! 	    }
  	}
  
          sc->ipacket[sc->inputbytes++] = c;
! 
! 	/* If synaptics_sync_hack_mode is one, we read an extra byte */
! 
!         if (sc->inputbytes < (sc->mode.packetsize+synaptics_sync_hack_mode)) 
  	    continue;
  
+ 	if (synaptics_sync_hack_mode == 1)
+ 	{
+ 	    if (sc->ipacket[1]==0)
+ 	    {
+ 		/* Drop the byte after the status byte from the packet */
+ 	        sc->ipacket[1] = sc->ipacket[2];
+ 	        sc->ipacket[2] = sc->ipacket[3];
+ 	    }
+ 	}
+ 
  #if 0
          log(LOG_DEBUG, "psmintr: %02x %02x %02x %02x %02x %02x\n",
  	    sc->ipacket[0], sc->ipacket[1], sc->ipacket[2],
***************
*** 2180,2185 ****
--- 2238,2244 ----
  	    }
  	    break;
  
+ 	case MOUSE_MODEL_SYNAPTICS: /* nothing special yet */
  	case MOUSE_MODEL_GENERIC:
  	default:
  	    break;
***************
*** 2642,2647 ****
--- 2701,2763 ----
      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




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

static void
psmintr(void *arg)
{
    /*
     * the table to turn PS/2 mouse button bits (MOUSE_PS2_BUTTON?DOWN)
     * into `mousestatus' button bits (MOUSE_BUTTON?DOWN).
     */
    static int butmap[8] = {
        0, 
	MOUSE_BUTTON1DOWN, 
	MOUSE_BUTTON3DOWN, 
	MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, 
	MOUSE_BUTTON2DOWN, 
	MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN, 
	MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN,
        MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN
    };
    static int butmap_versapad[8] = {
	0, 
	MOUSE_BUTTON3DOWN, 
	0, 
	MOUSE_BUTTON3DOWN, 
	MOUSE_BUTTON1DOWN, 
	MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, 
	MOUSE_BUTTON1DOWN,
	MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN
    };
    static int syncerrs = 0;
    static int synaptics_sync_hack_mode = 0;
    register struct psm_softc *sc = arg;
    mousestatus_t ms;
    int x, y, z;
    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;
    
        if (syncerrs>0)
	{
	    log(LOG_DEBUG, "psmintr: read %04x (mode %d).\n", c, synaptics_sync_hack_mode);
	    if (--syncerrs == 0)
		log(LOG_DEBUG, "psmintr: stopping logging reads\n");;
	}
	if (c==0 && sc->inputbytes == 0 &&
		sc->hw.model == MOUSE_MODEL_SYNAPTICS)
	{
	    if (synaptics_sync_hack_mode)
	    {
		synaptics_sync_hack_mode = 0;
                log(LOG_DEBUG, "psmintr: synaptics_sync_hack_mode 1->0\n");
		syncerrs = 10; /* log the next ten reads */
	    }
	    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) 
        {
	    if (sc->hw.model == MOUSE_MODEL_SYNAPTICS)
	    {
		if ((c&0xCC)!=0x08)
		{
	    	    if (synaptics_sync_hack_mode ==0)
		    {
			synaptics_sync_hack_mode = 1;
                	log(LOG_DEBUG, "psmintr: synaptics_sync_hack_mode 0->1\n");
	                syncerrs = 10; /* log next ten reads */
		    }
                    log(LOG_DEBUG, "psmintr: %04x out of sync.\n", c);
                    continue;
		}
	    }
	    else if (((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]);
                continue;
	    }
	}

        sc->ipacket[sc->inputbytes++] = c;

	/* If synaptics_sync_hack_mode is one, we read an extra byte */

        if (sc->inputbytes < (sc->mode.packetsize+synaptics_sync_hack_mode)) 
	    continue;

	if (synaptics_sync_hack_mode == 1)
	{
	    if (sc->ipacket[1]==0)
	    {
		/* Drop the byte after the status byte from the packet */
	        sc->ipacket[1] = sc->ipacket[2];
	        sc->ipacket[2] = sc->ipacket[3];
	    }
	}

#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]);
#endif

	c = sc->ipacket[0];

	/* 
	 * A kludge for Kensington device! 
	 * The MSB of the horizontal count appears to be stored in 
	 * a strange place.

--------------715AA62B84C7D3D2EAB84DD8--



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?252f164763d80f7d24a27596529b8450>