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

Cache object: 2977b0d307f76082718a2b9390c35d2b


[ 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.