The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/mse.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright 1992 by the University of Guelph
    3  *
    4  * Permission to use, copy and modify this
    5  * software and its documentation for any purpose and without
    6  * fee is hereby granted, provided that the above copyright
    7  * notice appear in all copies and that both that copyright
    8  * notice and this permission notice appear in supporting
    9  * documentation.
   10  * University of Guelph makes no representations about the suitability of
   11  * this software for any purpose.  It is provided "as is"
   12  * without express or implied warranty.
   13  *
   14  * $FreeBSD: src/sys/i386/isa/mse.c,v 1.28.2.3 1999/09/05 08:13:14 peter Exp $
   15  */
   16 /*
   17  * Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and
   18  * the X386 port, courtesy of
   19  * Rick Macklem, rick@snowhite.cis.uoguelph.ca
   20  * Caveats: The driver currently uses spltty(), but doesn't use any
   21  * generic tty code. It could use splmse() (that only masks off the
   22  * bus mouse interrupt, but that would require hacking in i386/isa/icu.s.
   23  * (This may be worth the effort, since the Logitech generates 30/60
   24  * interrupts/sec continuously while it is open.)
   25  * NB: The ATI has NOT been tested yet!
   26  */
   27 
   28 /*
   29  * Modification history:
   30  * Sep 6, 1994 -- Lars Fredriksen(fredriks@mcs.com)
   31  *   improved probe based on input from Logitech.
   32  *
   33  * Oct 19, 1992 -- E. Stark (stark@cs.sunysb.edu)
   34  *   fixes to make it work with Microsoft InPort busmouse
   35  *
   36  * Jan, 1993 -- E. Stark (stark@cs.sunysb.edu)
   37  *   added patches for new "select" interface
   38  *
   39  * May 4, 1993 -- E. Stark (stark@cs.sunysb.edu)
   40  *   changed position of some spl()'s in mseread
   41  *
   42  * October 8, 1993 -- E. Stark (stark@cs.sunysb.edu)
   43  *   limit maximum negative x/y value to -127 to work around XFree problem
   44  *   that causes spurious button pushes.
   45  */
   46 
   47 #include "mse.h"
   48 #if NMSE > 0
   49 #include <sys/param.h>
   50 #include <sys/systm.h>
   51 #include <sys/conf.h>
   52 #include <sys/proc.h>
   53 #include <sys/buf.h>
   54 #include <sys/kernel.h>
   55 #include <sys/ioctl.h>
   56 #include <sys/uio.h>
   57 #ifdef DEVFS
   58 #include <sys/devfsext.h>
   59 #endif /*DEVFS*/
   60 
   61 #include <machine/clock.h>
   62 #include <machine/mouse.h>
   63 
   64 #include <i386/isa/isa_device.h>
   65 
   66 /* driver configuration flags (config) */
   67 #define MSE_CONFIG_ACCEL        0x00f0  /* acceleration factor */
   68 #define MSE_CONFIG_FLAGS        (MSE_CONFIG_ACCEL)
   69 
   70 static int mseprobe(struct isa_device *);
   71 static int mseattach(struct isa_device *);
   72 
   73 struct  isa_driver msedriver = {
   74         mseprobe, mseattach, "mse"
   75 };
   76 
   77 static  d_open_t        mseopen;
   78 static  d_close_t       mseclose;
   79 static  d_read_t        mseread;
   80 static  d_ioctl_t       mseioctl;
   81 static  d_select_t      mseselect;
   82 
   83 #define CDEV_MAJOR 27
   84 static struct cdevsw mse_cdevsw = 
   85         { mseopen,      mseclose,       mseread,        nowrite,        /*27*/
   86           mseioctl,     nostop,         nullreset,      nodevtotty,/* mse */
   87           mseselect,    nommap,         NULL,   "mse",  NULL,   -1 };
   88 
   89 
   90 /*
   91  * Software control structure for mouse. The sc_enablemouse(),
   92  * sc_disablemouse() and sc_getmouse() routines must be called spl'd().
   93  */
   94 static struct mse_softc {
   95         int     sc_flags;
   96         int     sc_mousetype;
   97         struct  selinfo sc_selp;
   98         u_int   sc_port;
   99         void    (*sc_enablemouse) __P((u_int port));
  100         void    (*sc_disablemouse) __P((u_int port));
  101         void    (*sc_getmouse) __P((u_int port, int *dx, int *dy, int *but));
  102         int     sc_deltax;
  103         int     sc_deltay;
  104         int     sc_obuttons;
  105         int     sc_buttons;
  106         int     sc_bytesread;
  107         u_char  sc_bytes[MOUSE_SYS_PACKETSIZE];
  108         mousehw_t       hw;
  109         mousemode_t     mode;
  110         mousestatus_t   status;
  111 #ifdef DEVFS
  112         void    *devfs_token;
  113         void    *n_devfs_token;
  114 #endif
  115 } mse_sc[NMSE];
  116 
  117 /* Flags */
  118 #define MSESC_OPEN      0x1
  119 #define MSESC_WANT      0x2
  120 
  121 /* and Mouse Types */
  122 #define MSE_NONE        0       /* don't move this! */
  123 #define MSE_LOGITECH    0x1
  124 #define MSE_ATIINPORT   0x2
  125 #define MSE_LOGI_SIG    0xA5
  126 
  127 #define MSE_PORTA       0
  128 #define MSE_PORTB       1
  129 #define MSE_PORTC       2
  130 #define MSE_PORTD       3
  131 
  132 #define MSE_UNIT(dev)           (minor(dev) >> 1)
  133 #define MSE_NBLOCKIO(dev)       (minor(dev) & 0x1)
  134 
  135 /*
  136  * Logitech bus mouse definitions
  137  */
  138 #define MSE_SETUP       0x91    /* What does this mean? */
  139                                 /* The definition for the control port */
  140                                 /* is as follows: */
  141 
  142                                 /* D7    =  Mode set flag (1 = active)  */
  143                                 /* D6,D5 =  Mode selection (port A)     */
  144                                 /*          00 = Mode 0 = Basic I/O     */
  145                                 /*          01 = Mode 1 = Strobed I/O   */
  146                                 /*          10 = Mode 2 = Bi-dir bus    */
  147                                 /* D4    =  Port A direction (1 = input)*/
  148                                 /* D3    =  Port C (upper 4 bits)       */
  149                                 /*          direction. (1 = input)      */
  150                                 /* D2    =  Mode selection (port B & C) */
  151                                 /*          0 = Mode 0 = Basic I/O      */
  152                                 /*          1 = Mode 1 = Strobed I/O    */
  153                                 /* D1    =  Port B direction (1 = input)*/
  154                                 /* D0    =  Port C (lower 4 bits)       */
  155                                 /*          direction. (1 = input)      */
  156 
  157                                 /* So 91 means Basic I/O on all 3 ports,*/
  158                                 /* Port A is an input port, B is an     */
  159                                 /* output port, C is split with upper   */
  160                                 /* 4 bits being an output port and lower*/
  161                                 /* 4 bits an input port, and enable the */
  162                                 /* sucker.                              */
  163                                 /* Courtesy Intel 8255 databook. Lars   */
  164 #define MSE_HOLD        0x80
  165 #define MSE_RXLOW       0x00
  166 #define MSE_RXHIGH      0x20
  167 #define MSE_RYLOW       0x40
  168 #define MSE_RYHIGH      0x60
  169 #define MSE_DISINTR     0x10
  170 #define MSE_INTREN      0x00
  171 
  172 static int mse_probelogi __P((struct isa_device *idp));
  173 static void mse_disablelogi __P((u_int port));
  174 static void mse_getlogi __P((u_int port, int *dx, int *dy, int *but));
  175 static void mse_enablelogi __P((u_int port));
  176 
  177 /*
  178  * ATI Inport mouse definitions
  179  */
  180 #define MSE_INPORT_RESET        0x80
  181 #define MSE_INPORT_STATUS       0x00
  182 #define MSE_INPORT_DX           0x01
  183 #define MSE_INPORT_DY           0x02
  184 #define MSE_INPORT_MODE         0x07
  185 #define MSE_INPORT_HOLD         0x20
  186 #define MSE_INPORT_INTREN       0x09
  187 
  188 static int mse_probeati __P((struct isa_device *idp));
  189 static void mse_enableati __P((u_int port));
  190 static void mse_disableati __P((u_int port));
  191 static void mse_getati __P((u_int port, int *dx, int *dy, int *but));
  192 
  193 #define MSEPRI  (PZERO + 3)
  194 
  195 /*
  196  * Table of mouse types.
  197  * Keep the Logitech last, since I haven't figured out how to probe it
  198  * properly yet. (Someday I'll have the documentation.)
  199  */
  200 static struct mse_types {
  201         int     m_type;         /* Type of bus mouse */
  202         int     (*m_probe) __P((struct isa_device *idp));
  203                                 /* Probe routine to test for it */
  204         void    (*m_enable) __P((u_int port));
  205                                 /* Start routine */
  206         void    (*m_disable) __P((u_int port));
  207                                 /* Disable interrupts routine */
  208         void    (*m_get) __P((u_int port, int *dx, int *dy, int *but));
  209                                 /* and get mouse status */
  210         mousehw_t   m_hw;       /* buttons iftype type model hwid */
  211         mousemode_t m_mode;     /* proto rate res accel level size mask */
  212 } mse_types[] = {
  213         { MSE_ATIINPORT, 
  214           mse_probeati, mse_enableati, mse_disableati, mse_getati,
  215           { 2, MOUSE_IF_INPORT, MOUSE_MOUSE, MOUSE_MODEL_GENERIC, 0, },
  216           { MOUSE_PROTO_INPORT, -1, -1, 0, 0, MOUSE_MSC_PACKETSIZE, 
  217             { MOUSE_MSC_SYNCMASK, MOUSE_MSC_SYNC, }, }, },
  218         { MSE_LOGITECH, 
  219           mse_probelogi, mse_enablelogi, mse_disablelogi, mse_getlogi,
  220           { 2, MOUSE_IF_BUS, MOUSE_MOUSE, MOUSE_MODEL_GENERIC, 0, },
  221           { MOUSE_PROTO_BUS, -1, -1, 0, 0, MOUSE_MSC_PACKETSIZE, 
  222             { MOUSE_MSC_SYNCMASK, MOUSE_MSC_SYNC, }, }, },
  223         { 0, },
  224 };
  225 
  226 int
  227 mseprobe(idp)
  228         register struct isa_device *idp;
  229 {
  230         register struct mse_softc *sc = &mse_sc[idp->id_unit];
  231         register int i;
  232 
  233         /*
  234          * Check for each mouse type in the table.
  235          */
  236         i = 0;
  237         while (mse_types[i].m_type) {
  238                 if ((*mse_types[i].m_probe)(idp)) {
  239                         sc->sc_mousetype = mse_types[i].m_type;
  240                         sc->sc_enablemouse = mse_types[i].m_enable;
  241                         sc->sc_disablemouse = mse_types[i].m_disable;
  242                         sc->sc_getmouse = mse_types[i].m_get;
  243                         sc->hw = mse_types[i].m_hw;
  244                         sc->mode = mse_types[i].m_mode;
  245                         return (1);
  246                 }
  247                 i++;
  248         }
  249         return (0);
  250 }
  251 
  252 int
  253 mseattach(idp)
  254         struct isa_device *idp;
  255 {
  256         int unit = idp->id_unit;
  257         struct mse_softc *sc = &mse_sc[unit];
  258 
  259         sc->sc_port = idp->id_iobase;
  260         sc->mode.accelfactor = (idp->id_flags & MSE_CONFIG_ACCEL) >> 4;
  261 #ifdef  DEVFS
  262         sc->devfs_token = 
  263                 devfs_add_devswf(&mse_cdevsw, unit << 1, DV_CHR, 0, 0, 
  264                                  0600, "mse%d", unit);
  265         sc->n_devfs_token = 
  266                 devfs_add_devswf(&mse_cdevsw, (unit<<1)+1, DV_CHR,0, 0, 
  267                                  0600, "nmse%d", unit);
  268 #endif
  269         return (1);
  270 }
  271 
  272 /*
  273  * Exclusive open the mouse, initialize it and enable interrupts.
  274  */
  275 static  int
  276 mseopen(dev, flags, fmt, p)
  277         dev_t dev;
  278         int flags;
  279         int fmt;
  280         struct proc *p;
  281 {
  282         register struct mse_softc *sc;
  283         int s;
  284 
  285         if (MSE_UNIT(dev) >= NMSE)
  286                 return (ENXIO);
  287         sc = &mse_sc[MSE_UNIT(dev)];
  288         if (sc->sc_mousetype == MSE_NONE)
  289                 return (ENXIO);
  290         if (sc->sc_flags & MSESC_OPEN)
  291                 return (EBUSY);
  292         sc->sc_flags |= MSESC_OPEN;
  293         sc->sc_obuttons = sc->sc_buttons = MOUSE_MSC_BUTTONS;
  294         sc->sc_deltax = sc->sc_deltay = 0;
  295         sc->sc_bytesread = sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;
  296         sc->mode.level = 0;
  297         sc->status.flags = 0;
  298         sc->status.button = sc->status.obutton = 0;
  299         sc->status.dx = sc->status.dy = sc->status.dz = 0;
  300 
  301         /*
  302          * Initialize mouse interface and enable interrupts.
  303          */
  304         s = spltty();
  305         (*sc->sc_enablemouse)(sc->sc_port);
  306         splx(s);
  307         return (0);
  308 }
  309 
  310 /*
  311  * mseclose: just turn off mouse innterrupts.
  312  */
  313 static  int
  314 mseclose(dev, flags, fmt, p)
  315         dev_t dev;
  316         int flags;
  317         int fmt;
  318         struct proc *p;
  319 {
  320         struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)];
  321         int s;
  322 
  323         s = spltty();
  324         (*sc->sc_disablemouse)(sc->sc_port);
  325         sc->sc_flags &= ~MSESC_OPEN;
  326         splx(s);
  327         return(0);
  328 }
  329 
  330 /*
  331  * mseread: return mouse info using the MSC serial protocol, but without
  332  * using bytes 4 and 5.
  333  * (Yes this is cheesy, but it makes the X386 server happy, so...)
  334  */
  335 static  int
  336 mseread(dev, uio, ioflag)
  337         dev_t dev;
  338         struct uio *uio;
  339         int ioflag;
  340 {
  341         register struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)];
  342         int xfer, s, error;
  343 
  344         /*
  345          * If there are no protocol bytes to be read, set up a new protocol
  346          * packet.
  347          */
  348         s = spltty(); /* XXX Should be its own spl, but where is imlXX() */
  349         if (sc->sc_bytesread >= sc->mode.packetsize) {
  350                 while (sc->sc_deltax == 0 && sc->sc_deltay == 0 &&
  351                        (sc->sc_obuttons ^ sc->sc_buttons) == 0) {
  352                         if (MSE_NBLOCKIO(dev)) {
  353                                 splx(s);
  354                                 return (0);
  355                         }
  356                         sc->sc_flags |= MSESC_WANT;
  357                         if (error = tsleep((caddr_t)sc, MSEPRI | PCATCH,
  358                                 "mseread", 0)) {
  359                                 splx(s);
  360                                 return (error);
  361                         }
  362                 }
  363 
  364                 /*
  365                  * Generate protocol bytes.
  366                  * For some reason X386 expects 5 bytes but never uses
  367                  * the fourth or fifth?
  368                  */
  369                 sc->sc_bytes[0] = sc->mode.syncmask[1] 
  370                     | (sc->sc_buttons & ~sc->mode.syncmask[0]);
  371                 if (sc->sc_deltax > 127)
  372                         sc->sc_deltax = 127;
  373                 if (sc->sc_deltax < -127)
  374                         sc->sc_deltax = -127;
  375                 sc->sc_deltay = -sc->sc_deltay; /* Otherwise mousey goes wrong way */
  376                 if (sc->sc_deltay > 127)
  377                         sc->sc_deltay = 127;
  378                 if (sc->sc_deltay < -127)
  379                         sc->sc_deltay = -127;
  380                 sc->sc_bytes[1] = sc->sc_deltax;
  381                 sc->sc_bytes[2] = sc->sc_deltay;
  382                 sc->sc_bytes[3] = sc->sc_bytes[4] = 0;
  383                 sc->sc_bytes[5] = sc->sc_bytes[6] = 0;
  384                 sc->sc_bytes[7] = MOUSE_SYS_EXTBUTTONS;
  385                 sc->sc_obuttons = sc->sc_buttons;
  386                 sc->sc_deltax = sc->sc_deltay = 0;
  387                 sc->sc_bytesread = 0;
  388         }
  389         splx(s);
  390         xfer = min(uio->uio_resid, sc->mode.packetsize - sc->sc_bytesread);
  391         if (error = uiomove(&sc->sc_bytes[sc->sc_bytesread], xfer, uio))
  392                 return (error);
  393         sc->sc_bytesread += xfer;
  394         return(0);
  395 }
  396 
  397 /*
  398  * mseioctl: process ioctl commands.
  399  */
  400 static int
  401 mseioctl(dev, cmd, addr, flag, p)
  402         dev_t dev;
  403         int cmd;
  404         caddr_t addr;
  405         int flag;
  406         struct proc *p;
  407 {
  408         register struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)];
  409         mousestatus_t status;
  410         int err = 0;
  411         int s;
  412 
  413         switch (cmd) {
  414 
  415         case MOUSE_GETHWINFO:
  416                 s = spltty();
  417                 *(mousehw_t *)addr = sc->hw;
  418                 if (sc->mode.level == 0)
  419                         ((mousehw_t *)addr)->model = MOUSE_MODEL_GENERIC;
  420                 splx(s);
  421                 break;
  422 
  423         case MOUSE_GETMODE:
  424                 s = spltty();
  425                 *(mousemode_t *)addr = sc->mode;
  426                 switch (sc->mode.level) {
  427                 case 0:
  428                         break;
  429                 case 1:
  430                         ((mousemode_t *)addr)->protocol = MOUSE_PROTO_SYSMOUSE;
  431                         ((mousemode_t *)addr)->syncmask[0] = MOUSE_SYS_SYNCMASK;
  432                         ((mousemode_t *)addr)->syncmask[1] = MOUSE_SYS_SYNC;
  433                         break;
  434                 }
  435                 splx(s);
  436                 break;
  437 
  438         case MOUSE_SETMODE:
  439                 switch (((mousemode_t *)addr)->level) {
  440                 case 0:
  441                 case 1:
  442                         break;
  443                 default:
  444                         return (EINVAL);
  445                 }
  446                 if (((mousemode_t *)addr)->accelfactor < -1)
  447                         return (EINVAL);
  448                 else if (((mousemode_t *)addr)->accelfactor >= 0)
  449                         sc->mode.accelfactor = 
  450                             ((mousemode_t *)addr)->accelfactor;
  451                 sc->mode.level = ((mousemode_t *)addr)->level;
  452                 switch (sc->mode.level) {
  453                 case 0:
  454                         sc->sc_bytesread = sc->mode.packetsize 
  455                             = MOUSE_MSC_PACKETSIZE;
  456                         break;
  457                 case 1:
  458                         sc->sc_bytesread = sc->mode.packetsize 
  459                             = MOUSE_SYS_PACKETSIZE;
  460                         break;
  461                 }
  462                 break;
  463 
  464         case MOUSE_GETLEVEL:
  465                 *(int *)addr = sc->mode.level;
  466                 break;
  467 
  468         case MOUSE_SETLEVEL:
  469                 switch (*(int *)addr) {
  470                 case 0:
  471                         sc->mode.level = *(int *)addr;
  472                         sc->sc_bytesread = sc->mode.packetsize 
  473                             = MOUSE_MSC_PACKETSIZE;
  474                         break;
  475                 case 1:
  476                         sc->mode.level = *(int *)addr;
  477                         sc->sc_bytesread = sc->mode.packetsize 
  478                             = MOUSE_SYS_PACKETSIZE;
  479                         break;
  480                 default:
  481                         return (EINVAL);
  482                 }
  483                 break;
  484 
  485         case MOUSE_GETSTATUS:
  486                 s = spltty();
  487                 status = sc->status;
  488                 sc->status.flags = 0;
  489                 sc->status.obutton = sc->status.button;
  490                 sc->status.button = 0;
  491                 sc->status.dx = 0;
  492                 sc->status.dy = 0;
  493                 sc->status.dz = 0;
  494                 splx(s);
  495                 *(mousestatus_t *)addr = status;
  496                 break;
  497 
  498         case MOUSE_READSTATE:
  499         case MOUSE_READDATA:
  500                 return (ENODEV);
  501 
  502 #if (defined(MOUSE_GETVARS))
  503         case MOUSE_GETVARS:
  504         case MOUSE_SETVARS:
  505                 return (ENODEV);
  506 #endif
  507 
  508         default:
  509                 return (ENOTTY);
  510         }
  511         return (err);
  512 }
  513 
  514 /*
  515  * mseselect: check for mouse input to be processed.
  516  */
  517 static  int
  518 mseselect(dev, rw, p)
  519         dev_t dev;
  520         int rw;
  521         struct proc *p;
  522 {
  523         register struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)];
  524         int s;
  525 
  526         s = spltty();
  527         if (sc->sc_bytesread != sc->mode.packetsize || sc->sc_deltax != 0 ||
  528             sc->sc_deltay != 0 || (sc->sc_obuttons ^ sc->sc_buttons) != 0) {
  529                 splx(s);
  530                 return (1);
  531         }
  532 
  533         /*
  534          * Since this is an exclusive open device, any previous proc.
  535          * pointer is trash now, so we can just assign it.
  536          */
  537         selrecord(p, &sc->sc_selp);
  538         splx(s);
  539         return (0);
  540 }
  541 
  542 /*
  543  * mseintr: update mouse status. sc_deltax and sc_deltay are accumulative.
  544  */
  545 void
  546 mseintr(unit)
  547         int unit;
  548 {
  549         /*
  550          * the table to turn MouseSystem button bits (MOUSE_MSC_BUTTON?UP)
  551          * into `mousestatus' button bits (MOUSE_BUTTON?DOWN).
  552          */
  553         static int butmap[8] = {
  554                 0, 
  555                 MOUSE_BUTTON3DOWN, 
  556                 MOUSE_BUTTON2DOWN, 
  557                 MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN, 
  558                 MOUSE_BUTTON1DOWN, 
  559                 MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, 
  560                 MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN,
  561                 MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN
  562         };
  563         register struct mse_softc *sc = &mse_sc[unit];
  564         int dx, dy, but;
  565         int sign;
  566 
  567 #ifdef DEBUG
  568         static int mse_intrcnt = 0;
  569         if((mse_intrcnt++ % 10000) == 0)
  570                 printf("mseintr\n");
  571 #endif /* DEBUG */
  572         if ((sc->sc_flags & MSESC_OPEN) == 0)
  573                 return;
  574 
  575         (*sc->sc_getmouse)(sc->sc_port, &dx, &dy, &but);
  576         if (sc->mode.accelfactor > 0) {
  577                 sign = (dx < 0);
  578                 dx = dx * dx / sc->mode.accelfactor;
  579                 if (dx == 0)
  580                         dx = 1;
  581                 if (sign)
  582                         dx = -dx;
  583                 sign = (dy < 0);
  584                 dy = dy * dy / sc->mode.accelfactor;
  585                 if (dy == 0)
  586                         dy = 1;
  587                 if (sign)
  588                         dy = -dy;
  589         }
  590         sc->sc_deltax += dx;
  591         sc->sc_deltay += dy;
  592         sc->sc_buttons = but;
  593 
  594         but = butmap[~but & MOUSE_MSC_BUTTONS];
  595         sc->status.dx += dx;
  596         sc->status.dy += dy;
  597         sc->status.flags |= ((dx || dy) ? MOUSE_POSCHANGED : 0)
  598             | (sc->status.button ^ but);
  599         sc->status.button = but;
  600 
  601         /*
  602          * If mouse state has changed, wake up anyone wanting to know.
  603          */
  604         if (sc->sc_deltax != 0 || sc->sc_deltay != 0 ||
  605             (sc->sc_obuttons ^ sc->sc_buttons) != 0) {
  606                 if (sc->sc_flags & MSESC_WANT) {
  607                         sc->sc_flags &= ~MSESC_WANT;
  608                         wakeup((caddr_t)sc);
  609                 }
  610                 selwakeup(&sc->sc_selp);
  611         }
  612 }
  613 
  614 /*
  615  * Routines for the Logitech mouse.
  616  */
  617 /*
  618  * Test for a Logitech bus mouse and return 1 if it is.
  619  * (until I know how to use the signature port properly, just disable
  620  *  interrupts and return 1)
  621  */
  622 static int
  623 mse_probelogi(idp)
  624         register struct isa_device *idp;
  625 {
  626 
  627         int sig;
  628 
  629         outb(idp->id_iobase + MSE_PORTD, MSE_SETUP);
  630                 /* set the signature port */
  631         outb(idp->id_iobase + MSE_PORTB, MSE_LOGI_SIG);
  632 
  633         DELAY(30000); /* 30 ms delay */
  634         sig = inb(idp->id_iobase + MSE_PORTB) & 0xFF;
  635         if (sig == MSE_LOGI_SIG) {
  636                 outb(idp->id_iobase + MSE_PORTC, MSE_DISINTR);
  637                 return(1);
  638         } else {
  639                 if (bootverbose)
  640                         printf("mse%d: wrong signature %x\n",idp->id_unit,sig);
  641                 return(0);
  642         }
  643 }
  644 
  645 /*
  646  * Initialize Logitech mouse and enable interrupts.
  647  */
  648 static void
  649 mse_enablelogi(port)
  650         register u_int port;
  651 {
  652         int dx, dy, but;
  653 
  654         outb(port + MSE_PORTD, MSE_SETUP);
  655         mse_getlogi(port, &dx, &dy, &but);
  656 }
  657 
  658 /*
  659  * Disable interrupts for Logitech mouse.
  660  */
  661 static void
  662 mse_disablelogi(port)
  663         register u_int port;
  664 {
  665 
  666         outb(port + MSE_PORTC, MSE_DISINTR);
  667 }
  668 
  669 /*
  670  * Get the current dx, dy and button up/down state.
  671  */
  672 static void
  673 mse_getlogi(port, dx, dy, but)
  674         register u_int port;
  675         int *dx;
  676         int *dy;
  677         int *but;
  678 {
  679         register char x, y;
  680 
  681         outb(port + MSE_PORTC, MSE_HOLD | MSE_RXLOW);
  682         x = inb(port + MSE_PORTA);
  683         *but = (x >> 5) & MOUSE_MSC_BUTTONS;
  684         x &= 0xf;
  685         outb(port + MSE_PORTC, MSE_HOLD | MSE_RXHIGH);
  686         x |= (inb(port + MSE_PORTA) << 4);
  687         outb(port + MSE_PORTC, MSE_HOLD | MSE_RYLOW);
  688         y = (inb(port + MSE_PORTA) & 0xf);
  689         outb(port + MSE_PORTC, MSE_HOLD | MSE_RYHIGH);
  690         y |= (inb(port + MSE_PORTA) << 4);
  691         *dx = x;
  692         *dy = y;
  693         outb(port + MSE_PORTC, MSE_INTREN);
  694 }
  695 
  696 /*
  697  * Routines for the ATI Inport bus mouse.
  698  */
  699 /*
  700  * Test for a ATI Inport bus mouse and return 1 if it is.
  701  * (do not enable interrupts)
  702  */
  703 static int
  704 mse_probeati(idp)
  705         register struct isa_device *idp;
  706 {
  707         int i;
  708 
  709         for (i = 0; i < 2; i++)
  710                 if (inb(idp->id_iobase + MSE_PORTC) == 0xde)
  711                         return (1);
  712         return (0);
  713 }
  714 
  715 /*
  716  * Initialize ATI Inport mouse and enable interrupts.
  717  */
  718 static void
  719 mse_enableati(port)
  720         register u_int port;
  721 {
  722 
  723         outb(port + MSE_PORTA, MSE_INPORT_RESET);
  724         outb(port + MSE_PORTA, MSE_INPORT_MODE);
  725         outb(port + MSE_PORTB, MSE_INPORT_INTREN);
  726 }
  727 
  728 /*
  729  * Disable interrupts for ATI Inport mouse.
  730  */
  731 static void
  732 mse_disableati(port)
  733         register u_int port;
  734 {
  735 
  736         outb(port + MSE_PORTA, MSE_INPORT_MODE);
  737         outb(port + MSE_PORTB, 0);
  738 }
  739 
  740 /*
  741  * Get current dx, dy and up/down button state.
  742  */
  743 static void
  744 mse_getati(port, dx, dy, but)
  745         register u_int port;
  746         int *dx;
  747         int *dy;
  748         int *but;
  749 {
  750         register char byte;
  751 
  752         outb(port + MSE_PORTA, MSE_INPORT_MODE);
  753         outb(port + MSE_PORTB, MSE_INPORT_HOLD);
  754         outb(port + MSE_PORTA, MSE_INPORT_STATUS);
  755         *but = ~inb(port + MSE_PORTB) & MOUSE_MSC_BUTTONS;
  756         outb(port + MSE_PORTA, MSE_INPORT_DX);
  757         byte = inb(port + MSE_PORTB);
  758         *dx = byte;
  759         outb(port + MSE_PORTA, MSE_INPORT_DY);
  760         byte = inb(port + MSE_PORTB);
  761         *dy = byte;
  762         outb(port + MSE_PORTA, MSE_INPORT_MODE);
  763         outb(port + MSE_PORTB, MSE_INPORT_INTREN);
  764 }
  765 
  766 static mse_devsw_installed = 0;
  767 
  768 static void     mse_drvinit(void *unused)
  769 {
  770         dev_t dev;
  771 
  772         if( ! mse_devsw_installed ) {
  773                 dev = makedev(CDEV_MAJOR, 0);
  774                 cdevsw_add(&dev,&mse_cdevsw, NULL);
  775                 mse_devsw_installed = 1;
  776         }
  777 }
  778 
  779 SYSINIT(msedev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,mse_drvinit,NULL)
  780 
  781 
  782 #endif /* NMSE */

Cache object: f39c94f35c7ef40f61d60c6f9accd72f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.