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>