mse.c revision 12521
1285612Sdelphij/* 2258945Sroberto * Copyright 1992 by the University of Guelph 3258945Sroberto * 4285612Sdelphij * Permission to use, copy and modify this 5285612Sdelphij * software and its documentation for any purpose and without 6258945Sroberto * fee is hereby granted, provided that the above copyright 7258945Sroberto * notice appear in all copies and that both that copyright 8258945Sroberto * notice and this permission notice appear in supporting 9258945Sroberto * documentation. 10258945Sroberto * University of Guelph makes no representations about the suitability of 11258945Sroberto * this software for any purpose. It is provided "as is" 12258945Sroberto * without express or implied warranty. 13258945Sroberto * 14258945Sroberto * $Id: mse.c,v 1.17 1995/11/29 10:47:46 julian Exp $ 15258945Sroberto */ 16258945Sroberto/* 17258945Sroberto * Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and 18258945Sroberto * the X386 port, courtesy of 19258945Sroberto * Rick Macklem, rick@snowhite.cis.uoguelph.ca 20258945Sroberto * Caveats: The driver currently uses spltty(), but doesn't use any 21258945Sroberto * generic tty code. It could use splmse() (that only masks off the 22258945Sroberto * bus mouse interrupt, but that would require hacking in i386/isa/icu.s. 23285612Sdelphij * (This may be worth the effort, since the Logitech generates 30/60 24285612Sdelphij * interrupts/sec continuously while it is open.) 25285612Sdelphij * NB: The ATI has NOT been tested yet! 26285612Sdelphij */ 27285612Sdelphij 28285612Sdelphij/* 29285612Sdelphij * Modification history: 30285612Sdelphij * Sep 6, 1994 -- Lars Fredriksen(fredriks@mcs.com) 31285612Sdelphij * improved probe based on input from Logitech. 32285612Sdelphij * 33285612Sdelphij * Oct 19, 1992 -- E. Stark (stark@cs.sunysb.edu) 34285612Sdelphij * fixes to make it work with Microsoft InPort busmouse 35285612Sdelphij * 36285612Sdelphij * Jan, 1993 -- E. Stark (stark@cs.sunysb.edu) 37285612Sdelphij * added patches for new "select" interface 38285612Sdelphij * 39285612Sdelphij * May 4, 1993 -- E. Stark (stark@cs.sunysb.edu) 40285612Sdelphij * changed position of some spl()'s in mseread 41285612Sdelphij * 42285612Sdelphij * October 8, 1993 -- E. Stark (stark@cs.sunysb.edu) 43285612Sdelphij * limit maximum negative x/y value to -127 to work around XFree problem 44285612Sdelphij * that causes spurious button pushes. 45285612Sdelphij */ 46285612Sdelphij 47285612Sdelphij#include "mse.h" 48285612Sdelphij#if NMSE > 0 49285612Sdelphij#include <sys/param.h> 50285612Sdelphij#include <sys/systm.h> 51285612Sdelphij#include <sys/proc.h> 52285612Sdelphij#include <sys/user.h> 53285612Sdelphij#include <sys/buf.h> 54285612Sdelphij#include <sys/kernel.h> 55285612Sdelphij#include <sys/ioctl.h> 56285612Sdelphij#include <sys/uio.h> 57285612Sdelphij#include <sys/devconf.h> 58285612Sdelphij 59285612Sdelphij#include <machine/clock.h> 60285612Sdelphij 61285612Sdelphij#include <i386/isa/isa_device.h> 62285612Sdelphij#include <i386/isa/icu.h> 63285612Sdelphij 64285612Sdelphij#ifdef JREMOD 65285612Sdelphij#include <sys/conf.h> 66285612Sdelphij#include <sys/kernel.h> 67285612Sdelphij#ifdef DEVFS 68285612Sdelphij#include <sys/devfsext.h> 69285612Sdelphij#endif /*DEVFS*/ 70285612Sdelphij#define CDEV_MAJOR 27 71285612Sdelphij#endif /*JREMOD*/ 72285612Sdelphij 73285612Sdelphijstatic int mseprobe(struct isa_device *); 74285612Sdelphijstatic int mseattach(struct isa_device *); 75285612Sdelphij 76285612Sdelphijstruct isa_driver msedriver = { 77285612Sdelphij mseprobe, mseattach, "mse" 78258945Sroberto}; 79258945Sroberto 80258945Sroberto/* 81258945Sroberto * Software control structure for mouse. The sc_enablemouse(), 82258945Sroberto * sc_disablemouse() and sc_getmouse() routines must be called spl'd(). 83258945Sroberto */ 84258945Sroberto#define PROTOBYTES 5 85258945Srobertostruct mse_softc { 86258945Sroberto int sc_flags; 87258945Sroberto int sc_mousetype; 88258945Sroberto struct selinfo sc_selp; 89258945Sroberto u_int sc_port; 90258945Sroberto void (*sc_enablemouse)(); 91258945Sroberto void (*sc_disablemouse)(); 92258945Sroberto void (*sc_getmouse)(); 93258945Sroberto int sc_deltax; 94258945Sroberto int sc_deltay; 95258945Sroberto int sc_obuttons; 96258945Sroberto int sc_buttons; 97258945Sroberto int sc_bytesread; 98258945Sroberto u_char sc_bytes[PROTOBYTES]; 99258945Sroberto} mse_sc[NMSE]; 100280849Scy 101285612Sdelphij/* Flags */ 102280849Scy#define MSESC_OPEN 0x1 103280849Scy#define MSESC_WANT 0x2 104280849Scy 105280849Scy/* and Mouse Types */ 106280849Scy#define MSE_LOGITECH 0x1 107280849Scy#define MSE_ATIINPORT 0x2 108280849Scy#define MSE_LOGI_SIG 0xA5 109280849Scy 110280849Scy#define MSE_PORTA 0 111280849Scy#define MSE_PORTB 1 112280849Scy#define MSE_PORTC 2 113280849Scy#define MSE_PORTD 3 114280849Scy 115280849Scy#define MSE_UNIT(dev) (minor(dev) >> 1) 116280849Scy#define MSE_NBLOCKIO(dev) (minor(dev) & 0x1) 117316722Sdelphij 118280849Scy/* 119280849Scy * Logitech bus mouse definitions 120280849Scy */ 121280849Scy#define MSE_SETUP 0x91 /* What does this mean? */ 122280849Scy /* The definition for the control port */ 123280849Scy /* is as follows: */ 124280849Scy 125280849Scy /* D7 = Mode set flag (1 = active) */ 126289997Sglebius /* D6,D5 = Mode selection (port A) */ 127280849Scy /* 00 = Mode 0 = Basic I/O */ 128280849Scy /* 01 = Mode 1 = Strobed I/O */ 129280849Scy /* 10 = Mode 2 = Bi-dir bus */ 130285612Sdelphij /* D4 = Port A direction (1 = input)*/ 131280849Scy /* D3 = Port C (upper 4 bits) */ 132280849Scy /* direction. (1 = input) */ 133285612Sdelphij /* D2 = Mode selection (port B & C) */ 134285612Sdelphij /* 0 = Mode 0 = Basic I/O */ 135280849Scy /* 1 = Mode 1 = Strobed I/O */ 136280849Scy /* D1 = Port B direction (1 = input)*/ 137280849Scy /* D0 = Port C (lower 4 bits) */ 138258945Sroberto /* direction. (1 = input) */ 139258945Sroberto 140285612Sdelphij /* So 91 means Basic I/O on all 3 ports,*/ 141258945Sroberto /* Port A is an input port, B is an */ 142258945Sroberto /* output port, C is split with upper */ 143258945Sroberto /* 4 bits being an output port and lower*/ 144258945Sroberto /* 4 bits an input port, and enable the */ 145280849Scy /* sucker. */ 146280849Scy /* Courtesy Intel 8255 databook. Lars */ 147280849Scy#define MSE_HOLD 0x80 148280849Scy#define MSE_RXLOW 0x00 149258945Sroberto#define MSE_RXHIGH 0x20 150258945Sroberto#define MSE_RYLOW 0x40 151258945Sroberto#define MSE_RYHIGH 0x60 152258945Sroberto#define MSE_DISINTR 0x10 153258945Sroberto#define MSE_INTREN 0x00 154258945Sroberto 155280849Scystatic int mse_probelogi(); 156280849Scystatic void mse_enablelogi(), mse_disablelogi(), mse_getlogi(); 157280849Scy 158285612Sdelphij/* 159285612Sdelphij * ATI Inport mouse definitions 160280849Scy */ 161285612Sdelphij#define MSE_INPORT_RESET 0x80 162285612Sdelphij#define MSE_INPORT_STATUS 0x00 163285612Sdelphij#define MSE_INPORT_DX 0x01 164285612Sdelphij#define MSE_INPORT_DY 0x02 165285612Sdelphij#define MSE_INPORT_MODE 0x07 166285612Sdelphij#define MSE_INPORT_HOLD 0x20 167285612Sdelphij#define MSE_INPORT_INTREN 0x09 168285612Sdelphij 169285612Sdelphijstatic int mse_probeati(); 170285612Sdelphijstatic void mse_enableati(), mse_disableati(), mse_getati(); 171285612Sdelphij 172285612Sdelphij#define MSEPRI (PZERO + 3) 173285612Sdelphij 174258945Sroberto/* 175280849Scy * Table of mouse types. 176258945Sroberto * Keep the Logitech last, since I haven't figured out how to probe it 177258945Sroberto * properly yet. (Someday I'll have the documentation.) 178258945Sroberto */ 179258945Srobertostruct mse_types { 180280849Scy int m_type; /* Type of bus mouse */ 181280849Scy int (*m_probe)(); /* Probe routine to test for it */ 182280849Scy void (*m_enable)(); /* Start routine */ 183280849Scy void (*m_disable)(); /* Disable interrupts routine */ 184285612Sdelphij void (*m_get)(); /* and get mouse status */ 185285612Sdelphij} mse_types[] = { 186285612Sdelphij { MSE_ATIINPORT, mse_probeati, mse_enableati, mse_disableati, mse_getati }, 187285612Sdelphij { MSE_LOGITECH, mse_probelogi, mse_enablelogi, mse_disablelogi, mse_getlogi }, 188258945Sroberto { 0, }, 189280849Scy}; 190280849Scy 191280849Scystatic struct kern_devconf kdc_mse[NMSE] = { { 192285612Sdelphij 0, 0, 0, /* filled in by dev_attach */ 193285612Sdelphij "mse", 0, { MDDT_ISA, 0, "tty" }, 194285612Sdelphij isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, 195285612Sdelphij &kdc_isa0, /* parent */ 196258945Sroberto 0, /* parentdata */ 197258945Sroberto DC_UNCONFIGURED, /* state */ 198285612Sdelphij "ATI or Logitech bus mouse adapter", 199285612Sdelphij DC_CLS_MISC /* class */ 200285612Sdelphij} }; 201285612Sdelphij 202285612Sdelphijstatic inline void 203258945Srobertomse_registerdev(struct isa_device *id) 204258945Sroberto{ 205258945Sroberto if(id->id_unit) 206258945Sroberto kdc_mse[id->id_unit] = kdc_mse[0]; 207258945Sroberto kdc_mse[id->id_unit].kdc_unit = id->id_unit; 208258945Sroberto kdc_mse[id->id_unit].kdc_isa = id; 209258945Sroberto dev_attach(&kdc_mse[id->id_unit]); 210258945Sroberto} 211258945Sroberto 212258945Srobertoint 213258945Srobertomseprobe(idp) 214258945Sroberto register struct isa_device *idp; 215258945Sroberto{ 216258945Sroberto register struct mse_softc *sc = &mse_sc[idp->id_unit]; 217258945Sroberto register int i; 218258945Sroberto 219258945Sroberto mse_registerdev(idp); 220258945Sroberto /* 221258945Sroberto * Check for each mouse type in the table. 222258945Sroberto */ 223258945Sroberto i = 0; 224285612Sdelphij while (mse_types[i].m_type) { 225285612Sdelphij if ((*mse_types[i].m_probe)(idp)) { 226285612Sdelphij sc->sc_mousetype = mse_types[i].m_type; 227285612Sdelphij sc->sc_enablemouse = mse_types[i].m_enable; 228285612Sdelphij sc->sc_disablemouse = mse_types[i].m_disable; 229285612Sdelphij sc->sc_getmouse = mse_types[i].m_get; 230258945Sroberto return (1); 231280849Scy } 232258945Sroberto i++; 233280849Scy } 234280849Scy return (0); 235285612Sdelphij} 236285612Sdelphij 237285612Sdelphijint 238285612Sdelphijmseattach(idp) 239285612Sdelphij struct isa_device *idp; 240285612Sdelphij{ 241285612Sdelphij struct mse_softc *sc = &mse_sc[idp->id_unit]; 242285612Sdelphij 243285612Sdelphij sc->sc_port = idp->id_iobase; 244285612Sdelphij kdc_mse[idp->id_unit].kdc_state = DC_IDLE; 245285612Sdelphij return (1); 246285612Sdelphij} 247285612Sdelphij 248285612Sdelphij/* 249285612Sdelphij * Exclusive open the mouse, initialize it and enable interrupts. 250285612Sdelphij */ 251285612Sdelphijint 252258945Srobertomseopen(dev, flags, fmt, p) 253258945Sroberto dev_t dev; 254285612Sdelphij int flags; 255285612Sdelphij int fmt; 256285612Sdelphij struct proc *p; 257285612Sdelphij{ 258258945Sroberto register struct mse_softc *sc; 259258945Sroberto int s; 260280849Scy 261258945Sroberto if (MSE_UNIT(dev) >= NMSE) 262280849Scy return (ENXIO); 263258945Sroberto sc = &mse_sc[MSE_UNIT(dev)]; 264258945Sroberto if (sc->sc_flags & MSESC_OPEN) 265258945Sroberto return (EBUSY); 266258945Sroberto sc->sc_flags |= MSESC_OPEN; 267258945Sroberto kdc_mse[MSE_UNIT(dev)].kdc_state = DC_BUSY; 268289997Sglebius sc->sc_obuttons = sc->sc_buttons = 0x7; 269280849Scy sc->sc_deltax = sc->sc_deltay = 0; 270280849Scy sc->sc_bytesread = PROTOBYTES; 271280849Scy 272280849Scy /* 273280849Scy * Initialize mouse interface and enable interrupts. 274258945Sroberto */ 275258945Sroberto s = spltty(); 276258945Sroberto (*sc->sc_enablemouse)(sc->sc_port); 277289997Sglebius splx(s); 278280849Scy return (0); 279258945Sroberto} 280280849Scy 281258945Sroberto/* 282258945Sroberto * mseclose: just turn off mouse innterrupts. 283280849Scy */ 284280849Scyint 285258945Srobertomseclose(dev, flags, fmt, p) 286258945Sroberto dev_t dev; 287258945Sroberto int flags; 288258945Sroberto int fmt; 289258945Sroberto struct proc *p; 290258945Sroberto{ 291258945Sroberto struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)]; 292258945Sroberto int s; 293258945Sroberto 294258945Sroberto s = spltty(); 295258945Sroberto (*sc->sc_disablemouse)(sc->sc_port); 296258945Sroberto sc->sc_flags &= ~MSESC_OPEN; 297258945Sroberto kdc_mse[MSE_UNIT(dev)].kdc_state = DC_IDLE; 298258945Sroberto splx(s); 299258945Sroberto return(0); 300280849Scy} 301280849Scy 302280849Scy/* 303280849Scy * mseread: return mouse info using the MSC serial protocol, but without 304280849Scy * using bytes 4 and 5. 305258945Sroberto * (Yes this is cheesy, but it makes the X386 server happy, so...) 306285612Sdelphij */ 307280849Scyint 308280849Scymseread(dev, uio, ioflag) 309258945Sroberto dev_t dev; 310258945Sroberto struct uio *uio; 311258945Sroberto int ioflag; 312258945Sroberto{ 313258945Sroberto register struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)]; 314258945Sroberto int xfer, s, error; 315280849Scy 316280849Scy /* 317280849Scy * If there are no protocol bytes to be read, set up a new protocol 318280849Scy * packet. 319280849Scy */ 320258945Sroberto s = spltty(); /* XXX Should be its own spl, but where is imlXX() */ 321280849Scy if (sc->sc_bytesread >= PROTOBYTES) { 322280849Scy while (sc->sc_deltax == 0 && sc->sc_deltay == 0 && 323280849Scy (sc->sc_obuttons ^ sc->sc_buttons) == 0) { 324258945Sroberto if (MSE_NBLOCKIO(dev)) { 325258945Sroberto splx(s); 326258945Sroberto return (0); 327258945Sroberto } 328258945Sroberto sc->sc_flags |= MSESC_WANT; 329258945Sroberto if (error = tsleep((caddr_t)sc, MSEPRI | PCATCH, 330258945Sroberto "mseread", 0)) { 331280849Scy splx(s); 332258945Sroberto return (error); 333258945Sroberto } 334258945Sroberto } 335289997Sglebius 336258945Sroberto /* 337316722Sdelphij * Generate protocol bytes. 338258945Sroberto * For some reason X386 expects 5 bytes but never uses 339258945Sroberto * the fourth or fifth? 340258945Sroberto */ 341258945Sroberto sc->sc_bytes[0] = 0x80 | (sc->sc_buttons & ~0xf8); 342258945Sroberto if (sc->sc_deltax > 127) 343258945Sroberto sc->sc_deltax = 127; 344258945Sroberto if (sc->sc_deltax < -127) 345258945Sroberto sc->sc_deltax = -127; 346258945Sroberto sc->sc_deltay = -sc->sc_deltay; /* Otherwise mousey goes wrong way */ 347258945Sroberto if (sc->sc_deltay > 127) 348258945Sroberto sc->sc_deltay = 127; 349258945Sroberto if (sc->sc_deltay < -127) 350258945Sroberto sc->sc_deltay = -127; 351258945Sroberto sc->sc_bytes[1] = sc->sc_deltax; 352280849Scy sc->sc_bytes[2] = sc->sc_deltay; 353258945Sroberto sc->sc_bytes[3] = sc->sc_bytes[4] = 0; 354258945Sroberto sc->sc_obuttons = sc->sc_buttons; 355258945Sroberto sc->sc_deltax = sc->sc_deltay = 0; 356280849Scy sc->sc_bytesread = 0; 357280849Scy } 358280849Scy splx(s); 359280849Scy xfer = min(uio->uio_resid, PROTOBYTES - sc->sc_bytesread); 360280849Scy if (error = uiomove(&sc->sc_bytes[sc->sc_bytesread], xfer, uio)) 361280849Scy return (error); 362280849Scy sc->sc_bytesread += xfer; 363280849Scy return(0); 364280849Scy} 365280849Scy 366280849Scy/* 367280849Scy * mseselect: check for mouse input to be processed. 368280849Scy */ 369280849Scyint 370280849Scymseselect(dev, rw, p) 371280849Scy dev_t dev; 372280849Scy int rw; 373280849Scy struct proc *p; 374280849Scy{ 375280849Scy register struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)]; 376280849Scy int s; 377280849Scy 378280849Scy s = spltty(); 379280849Scy if (sc->sc_bytesread != PROTOBYTES || sc->sc_deltax != 0 || 380280849Scy sc->sc_deltay != 0 || (sc->sc_obuttons ^ sc->sc_buttons) != 0) { 381280849Scy splx(s); 382280849Scy return (1); 383280849Scy } 384280849Scy 385280849Scy /* 386280849Scy * Since this is an exclusive open device, any previous proc. 387280849Scy * pointer is trash now, so we can just assign it. 388280849Scy */ 389280849Scy selrecord(p, &sc->sc_selp); 390280849Scy splx(s); 391280849Scy return (0); 392280849Scy} 393280849Scy 394280849Scy/* 395280849Scy * mseintr: update mouse status. sc_deltax and sc_deltay are accumulative. 396280849Scy */ 397280849Scyvoid 398280849Scymseintr(unit) 399280849Scy int unit; 400280849Scy{ 401316722Sdelphij register struct mse_softc *sc = &mse_sc[unit]; 402316722Sdelphij pid_t p; 403316722Sdelphij 404280849Scy#ifdef DEBUG 405280849Scy static int mse_intrcnt = 0; 406280849Scy if((mse_intrcnt++ % 10000) == 0) 407280849Scy printf("mseintr\n"); 408280849Scy#endif /* DEBUG */ 409280849Scy if ((sc->sc_flags & MSESC_OPEN) == 0) 410280849Scy return; 411280849Scy 412280849Scy (*sc->sc_getmouse)(sc->sc_port, &sc->sc_deltax, &sc->sc_deltay, &sc->sc_buttons); 413280849Scy 414280849Scy /* 415258945Sroberto * If mouse state has changed, wake up anyone wanting to know. 416258945Sroberto */ 417258945Sroberto if (sc->sc_deltax != 0 || sc->sc_deltay != 0 || 418258945Sroberto (sc->sc_obuttons ^ sc->sc_buttons) != 0) { 419258945Sroberto if (sc->sc_flags & MSESC_WANT) { 420258945Sroberto sc->sc_flags &= ~MSESC_WANT; 421258945Sroberto wakeup((caddr_t)sc); 422258945Sroberto } 423258945Sroberto selwakeup(&sc->sc_selp); 424258945Sroberto } 425258945Sroberto} 426258945Sroberto 427258945Sroberto/* 428285612Sdelphij * Routines for the Logitech mouse. 429258945Sroberto */ 430258945Sroberto/* 431280849Scy * Test for a Logitech bus mouse and return 1 if it is. 432280849Scy * (until I know how to use the signature port properly, just disable 433258945Sroberto * interrupts and return 1) 434258945Sroberto */ 435280849Scystatic int 436258945Srobertomse_probelogi(idp) 437258945Sroberto register struct isa_device *idp; 438258945Sroberto{ 439258945Sroberto 440258945Sroberto int sig; 441258945Sroberto 442258945Sroberto outb(idp->id_iobase + MSE_PORTD, MSE_SETUP); 443280849Scy /* set the signature port */ 444280849Scy outb(idp->id_iobase + MSE_PORTB, MSE_LOGI_SIG); 445280849Scy 446280849Scy DELAY(30000); /* 30 ms delay */ 447280849Scy sig = inb(idp->id_iobase + MSE_PORTB) & 0xFF; 448280849Scy if (sig == MSE_LOGI_SIG) { 449280849Scy outb(idp->id_iobase + MSE_PORTC, MSE_DISINTR); 450258945Sroberto return(1); 451258945Sroberto } else { 452280849Scy printf("mse%d: wrong signature %x\n",idp->id_unit,sig); 453280849Scy return(0); 454280849Scy } 455280849Scy} 456280849Scy 457280849Scy/* 458280849Scy * Initialize Logitech mouse and enable interrupts. 459280849Scy */ 460280849Scystatic void 461280849Scymse_enablelogi(port) 462285612Sdelphij register u_int port; 463285612Sdelphij{ 464285612Sdelphij int dx, dy, but; 465285612Sdelphij 466285612Sdelphij outb(port + MSE_PORTD, MSE_SETUP); 467258945Sroberto mse_getlogi(port, &dx, &dy, &but); 468280849Scy} 469258945Sroberto 470258945Sroberto/* 471258945Sroberto * Disable interrupts for Logitech mouse. 472258945Sroberto */ 473258945Srobertostatic void 474258945Srobertomse_disablelogi(port) 475258945Sroberto register u_int port; 476258945Sroberto{ 477258945Sroberto 478258945Sroberto outb(port + MSE_PORTC, MSE_DISINTR); 479258945Sroberto} 480258945Sroberto 481258945Sroberto/* 482258945Sroberto * Get the current dx, dy and button up/down state. 483258945Sroberto */ 484258945Srobertostatic void 485258945Srobertomse_getlogi(port, dx, dy, but) 486258945Sroberto register u_int port; 487258945Sroberto int *dx; 488258945Sroberto int *dy; 489258945Sroberto int *but; 490258945Sroberto{ 491258945Sroberto register char x, y; 492258945Sroberto 493258945Sroberto outb(port + MSE_PORTC, MSE_HOLD | MSE_RXLOW); 494258945Sroberto x = inb(port + MSE_PORTA); 495258945Sroberto *but = (x >> 5) & 0x7; 496258945Sroberto x &= 0xf; 497258945Sroberto outb(port + MSE_PORTC, MSE_HOLD | MSE_RXHIGH); 498258945Sroberto x |= (inb(port + MSE_PORTA) << 4); 499258945Sroberto outb(port + MSE_PORTC, MSE_HOLD | MSE_RYLOW); 500258945Sroberto y = (inb(port + MSE_PORTA) & 0xf); 501258945Sroberto outb(port + MSE_PORTC, MSE_HOLD | MSE_RYHIGH); 502258945Sroberto y |= (inb(port + MSE_PORTA) << 4); 503258945Sroberto *dx += x; 504258945Sroberto *dy += y; 505258945Sroberto outb(port + MSE_PORTC, MSE_INTREN); 506258945Sroberto} 507258945Sroberto 508258945Sroberto/* 509258945Sroberto * Routines for the ATI Inport bus mouse. 510258945Sroberto */ 511258945Sroberto/* 512258945Sroberto * Test for a ATI Inport bus mouse and return 1 if it is. 513258945Sroberto * (do not enable interrupts) 514258945Sroberto */ 515258945Srobertostatic int 516258945Srobertomse_probeati(idp) 517258945Sroberto register struct isa_device *idp; 518258945Sroberto{ 519258945Sroberto int i; 520258945Sroberto 521258945Sroberto for (i = 0; i < 2; i++) 522258945Sroberto if (inb(idp->id_iobase + MSE_PORTC) == 0xde) 523258945Sroberto return (1); 524258945Sroberto return (0); 525280849Scy} 526280849Scy 527280849Scy/* 528258945Sroberto * Initialize ATI Inport mouse and enable interrupts. 529258945Sroberto */ 530258945Srobertostatic void 531258945Srobertomse_enableati(port) 532258945Sroberto register u_int port; 533280849Scy{ 534280849Scy 535280849Scy outb(port + MSE_PORTA, MSE_INPORT_RESET); 536316722Sdelphij outb(port + MSE_PORTA, MSE_INPORT_MODE); 537280849Scy outb(port + MSE_PORTB, MSE_INPORT_INTREN); 538316722Sdelphij} 539316722Sdelphij 540280849Scy/* 541280849Scy * Disable interrupts for ATI Inport mouse. 542280849Scy */ 543280849Scystatic void 544280849Scymse_disableati(port) 545280849Scy register u_int port; 546280849Scy{ 547280849Scy 548280849Scy outb(port + MSE_PORTA, MSE_INPORT_MODE); 549280849Scy outb(port + MSE_PORTB, 0); 550280849Scy} 551280849Scy 552258945Sroberto/* 553280849Scy * Get current dx, dy and up/down button state. 554280849Scy */ 555280849Scystatic void 556280849Scymse_getati(port, dx, dy, but) 557280849Scy register u_int port; 558280849Scy int *dx; 559280849Scy int *dy; 560258945Sroberto int *but; 561280849Scy{ 562280849Scy register char byte; 563280849Scy 564280849Scy outb(port + MSE_PORTA, MSE_INPORT_MODE); 565280849Scy outb(port + MSE_PORTB, MSE_INPORT_HOLD); 566280849Scy outb(port + MSE_PORTA, MSE_INPORT_STATUS); 567258945Sroberto *but = ~(inb(port + MSE_PORTB) & 0x7); 568280849Scy outb(port + MSE_PORTA, MSE_INPORT_DX); 569280849Scy byte = inb(port + MSE_PORTB); 570280849Scy *dx += byte; 571280849Scy outb(port + MSE_PORTA, MSE_INPORT_DY); 572280849Scy byte = inb(port + MSE_PORTB); 573258945Sroberto *dy += byte; 574280849Scy outb(port + MSE_PORTA, MSE_INPORT_MODE); 575280849Scy outb(port + MSE_PORTB, MSE_INPORT_INTREN); 576280849Scy} 577280849Scy 578280849Scy#ifdef JREMOD 579280849Scystruct cdevsw mse_cdevsw = 580280849Scy { mseopen, mseclose, mseread, nowrite, /*27*/ 581280849Scy noioc, nostop, nullreset, nodevtotty,/* mse */ 582258945Sroberto mseselect, nommap, NULL }; 583280849Scy 584280849Scystatic mse_devsw_installed = 0; 585280849Scy 586258945Srobertostatic void mse_drvinit(void *unused) 587258945Sroberto{ 588258945Sroberto dev_t dev; 589258945Sroberto 590258945Sroberto if( ! mse_devsw_installed ) { 591280849Scy dev = makedev(CDEV_MAJOR,0); 592258945Sroberto cdevsw_add(&dev,&mse_cdevsw,NULL); 593258945Sroberto mse_devsw_installed = 1; 594258945Sroberto#ifdef DEVFS 595258945Sroberto { 596258945Sroberto int x; 597258945Sroberto/* default for a simple device with no probe routine (usually delete this) */ 598258945Sroberto x=devfs_add_devsw( 599258945Sroberto/* path name devsw minor type uid gid perm*/ 600258945Sroberto "/", "mse", major(dev), 0, DV_CHR, 0, 0, 0600); 601258945Sroberto } 602258945Sroberto#endif 603258945Sroberto } 604258945Sroberto} 605258945Sroberto 606258945SrobertoSYSINIT(msedev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,mse_drvinit,NULL) 607258945Sroberto 608258945Sroberto#endif /* JREMOD */ 609258945Sroberto 610258945Sroberto#endif /* NMSE */ 611285612Sdelphij