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/dev/adb/adb_mouse.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (C) 2008 Nathan Whitehorn
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   17  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  *
   25  * $FreeBSD: releng/8.3/sys/dev/adb/adb_mouse.c 200427 2009-12-12 02:34:00Z nwhitehorn $
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/module.h>
   32 #include <sys/bus.h>
   33 #include <sys/conf.h>
   34 #include <sys/mouse.h>
   35 #include <sys/poll.h>
   36 #include <sys/condvar.h>
   37 #include <sys/selinfo.h>
   38 #include <sys/sysctl.h>
   39 #include <sys/uio.h>
   40 #include <sys/fcntl.h>
   41 #include <sys/kernel.h>
   42 
   43 #include <machine/bus.h>
   44 
   45 #include <vm/vm.h>
   46 #include <vm/pmap.h>
   47 
   48 #include "adb.h"
   49 
   50 #define CDEV_GET_SOFTC(x) (x)->si_drv1
   51 
   52 static int adb_mouse_probe(device_t dev);
   53 static int adb_mouse_attach(device_t dev);
   54 static int adb_mouse_detach(device_t dev);
   55 static void adb_init_trackpad(device_t dev);
   56 static int adb_tapping_sysctl(SYSCTL_HANDLER_ARGS);
   57 
   58 static d_open_t  ams_open;
   59 static d_close_t ams_close;
   60 static d_read_t  ams_read;
   61 static d_ioctl_t ams_ioctl;
   62 static d_poll_t  ams_poll;
   63 
   64 static u_int adb_mouse_receive_packet(device_t dev, u_char status, 
   65     u_char command, u_char reg, int len, u_char *data);
   66 
   67 struct adb_mouse_softc {
   68         device_t sc_dev;
   69 
   70         struct mtx sc_mtx;
   71         struct cv  sc_cv;
   72 
   73         int flags;
   74 #define AMS_EXTENDED    0x1
   75 #define AMS_TOUCHPAD    0x2
   76         uint16_t dpi;
   77 
   78         mousehw_t hw;
   79         mousemode_t mode;
   80         u_char id[4];
   81 
   82         int buttons;
   83         u_int sc_tapping;
   84         int button_buf;
   85         int last_buttons;
   86         int xdelta, ydelta;
   87 
   88         int8_t packet[8];
   89         size_t packet_read_len;
   90 
   91         struct cdev *cdev;
   92         struct selinfo rsel;
   93 };
   94 
   95 static device_method_t adb_mouse_methods[] = {
   96         /* Device interface */
   97         DEVMETHOD(device_probe,         adb_mouse_probe),
   98         DEVMETHOD(device_attach,        adb_mouse_attach),
   99         DEVMETHOD(device_detach,        adb_mouse_detach),
  100         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
  101         DEVMETHOD(device_suspend,       bus_generic_suspend),
  102         DEVMETHOD(device_resume,        bus_generic_resume),
  103 
  104         /* ADB interface */
  105         DEVMETHOD(adb_receive_packet,   adb_mouse_receive_packet),
  106 
  107         { 0, 0 }
  108 };
  109 
  110 static driver_t adb_mouse_driver = {
  111         "ams",
  112         adb_mouse_methods,
  113         sizeof(struct adb_mouse_softc),
  114 };
  115 
  116 static devclass_t adb_mouse_devclass;
  117 
  118 DRIVER_MODULE(ams, adb, adb_mouse_driver, adb_mouse_devclass, 0, 0);
  119 
  120 static struct cdevsw ams_cdevsw = {
  121         .d_version =    D_VERSION,
  122         .d_flags   =    0,
  123         .d_open    =    ams_open,
  124         .d_close   =    ams_close,
  125         .d_read    =    ams_read,
  126         .d_ioctl   =    ams_ioctl,
  127         .d_poll    =    ams_poll,
  128         .d_name    =    "ams",
  129 };
  130 
  131 static int 
  132 adb_mouse_probe(device_t dev)
  133 {
  134         uint8_t type;
  135 
  136         type = adb_get_device_type(dev);
  137 
  138         if (type != ADB_DEVICE_MOUSE)
  139                 return (ENXIO);
  140 
  141         device_set_desc(dev,"ADB Mouse");
  142         return (0);
  143 }
  144         
  145 static int 
  146 adb_mouse_attach(device_t dev) 
  147 {
  148         struct adb_mouse_softc *sc;
  149         char *description = "Unknown Pointing Device";
  150 
  151         size_t r1_len;
  152         u_char r1[8];
  153 
  154         sc = device_get_softc(dev);
  155         sc->sc_dev = dev;
  156 
  157         mtx_init(&sc->sc_mtx,"ams",MTX_DEF,0);
  158         cv_init(&sc->sc_cv,"ams");
  159 
  160         sc->flags = 0;
  161 
  162         sc->hw.buttons = 2;
  163         sc->hw.iftype = MOUSE_IF_UNKNOWN;
  164         sc->hw.type = MOUSE_UNKNOWN;
  165         sc->hw.model = sc->hw.hwid = 0;
  166 
  167         sc->mode.protocol = MOUSE_PROTO_SYSMOUSE;
  168         sc->mode.rate = -1;
  169         sc->mode.resolution = 100;
  170         sc->mode.accelfactor = 0;
  171         sc->mode.level = 0;
  172         sc->mode.packetsize = 5;
  173 
  174         sc->buttons = 0;
  175         sc->sc_tapping = 0;
  176         sc->button_buf = 0;
  177         sc->last_buttons = 0;
  178         sc->packet_read_len = 0;
  179 
  180         /* Try to switch to extended protocol */
  181         adb_set_device_handler(dev,4);
  182 
  183         switch(adb_get_device_handler(dev)) {
  184         case 1:
  185                 sc->mode.resolution = 100;
  186                 break;
  187         case 2:
  188                 sc->mode.resolution = 200;
  189                 break;
  190         case 4:
  191                 r1_len = adb_read_register(dev,1,r1);
  192                 if (r1_len < 8)
  193                         break;
  194 
  195                 sc->flags |= AMS_EXTENDED;
  196                 memcpy(&sc->hw.hwid,r1,4);
  197                 sc->mode.resolution = (r1[4] << 8) | r1[5];
  198 
  199                 switch (r1[6]) {
  200                 case 0:
  201                         sc->hw.type = MOUSE_PAD;
  202                         description = "Tablet";
  203                         break;
  204                 case 1:
  205                         sc->hw.type = MOUSE_MOUSE;
  206                         description = "Mouse";
  207                         break;
  208                 case 2:
  209                         sc->hw.type = MOUSE_TRACKBALL;
  210                         description = "Trackball";
  211                         break;
  212                 case 3:
  213                         sc->flags |= AMS_TOUCHPAD;
  214                         sc->hw.type = MOUSE_PAD;
  215                         adb_init_trackpad(dev);
  216                         description = "Touchpad";
  217                         break;
  218                 }
  219 
  220                 sc->hw.buttons = r1[7];
  221 
  222                 device_printf(dev,"%d-button %d-dpi %s\n",
  223                     sc->hw.buttons, sc->mode.resolution,description);
  224 
  225                 /*
  226                  * Check for one of MacAlly's non-compliant 2-button mice.
  227                  * These claim to speak the extended mouse protocol, but
  228                  * instead speak the standard protocol and only when their
  229                  * handler is set to 0x42.
  230                  */
  231 
  232                 if (sc->hw.hwid == 0x4b4f4954) {
  233                         adb_set_device_handler(dev,0x42);
  234 
  235                         if (adb_get_device_handler(dev) == 0x42) {
  236                                 device_printf(dev, "MacAlly 2-Button Mouse\n");
  237                                 sc->flags &= ~AMS_EXTENDED;
  238                         }
  239                 }
  240                         
  241                 break;
  242         }
  243 
  244         sc->cdev = make_dev(&ams_cdevsw, device_get_unit(dev),
  245                        UID_ROOT, GID_OPERATOR, 0644, "ams%d", 
  246                        device_get_unit(dev));
  247         sc->cdev->si_drv1 = sc;
  248 
  249         adb_set_autopoll(dev,1);
  250 
  251         return (0);
  252 }
  253 
  254 static int 
  255 adb_mouse_detach(device_t dev) 
  256 {
  257         struct adb_mouse_softc *sc;
  258 
  259         adb_set_autopoll(dev,0);
  260 
  261         sc = device_get_softc(dev);
  262         destroy_dev(sc->cdev);
  263 
  264         mtx_destroy(&sc->sc_mtx);
  265         cv_destroy(&sc->sc_cv);
  266 
  267         return (0);
  268 }
  269 
  270 static void
  271 adb_init_trackpad(device_t dev)
  272 {
  273         struct adb_mouse_softc *sc;
  274         struct sysctl_ctx_list *ctx;
  275         struct sysctl_oid *tree;
  276 
  277         size_t r1_len;
  278         u_char r1[8];
  279         u_char r2[8];
  280 
  281         sc = device_get_softc(dev);
  282 
  283         r1_len = adb_read_register(dev, 1, r1);
  284 
  285         /* An Extended Mouse register1 must return 8 bytes. */
  286         if (r1_len != 8)
  287                 return;
  288 
  289         if((r1[6] != 0x0d))
  290         {
  291                 r1[6] = 0x0d;
  292                 
  293                 adb_write_register(dev, 1, 8, r1); 
  294       
  295                 r1_len = adb_read_register(dev, 1, r1);
  296       
  297                 if (r1[6] != 0x0d)
  298                 {
  299                         device_printf(dev, "ADB Mouse = 0x%x "
  300                                       "(non-Extended Mode)\n", r1[6]);
  301                         return;
  302                 } else {
  303                         device_printf(dev, "ADB Mouse = 0x%x "
  304                                       "(Extended Mode)\n", r1[6]);
  305                         
  306                         /* Set ADB Extended Features to default values,
  307                            enabled. */
  308                         r2[0] = 0x19; /* Clicking: 0x19 disabled 0x99 enabled */
  309                         r2[1] = 0x94; /* Dragging: 0x14 disabled 0x94 enabled */
  310                         r2[2] = 0x19;
  311                         r2[3] = 0xff; /* DragLock: 0xff disabled 0xb2 enabled */
  312                         r2[4] = 0xb2;
  313                         r2[5] = 0x8a;
  314                         r2[6] = 0x1b;
  315                        
  316                         r2[7] = 0x57;  /* 0x57 bits 3:0 for W mode */
  317                         
  318                         adb_write_register(dev, 2, 8, r2);
  319                         
  320                 }
  321         }
  322 
  323         /*
  324          * Set up sysctl
  325          */
  326         ctx = device_get_sysctl_ctx(dev);
  327         tree = device_get_sysctl_tree(dev);
  328         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tapping",
  329                         CTLTYPE_INT | CTLFLAG_RW, sc, 0, adb_tapping_sysctl,
  330                         "I", "Tapping the pad causes button events");
  331         return;
  332 }
  333 
  334 static u_int 
  335 adb_mouse_receive_packet(device_t dev, u_char status, u_char command, 
  336     u_char reg, int len, u_char *data) 
  337 {
  338         struct adb_mouse_softc *sc;
  339         int i = 0;
  340         int xdelta, ydelta;
  341         int buttons, tmp_buttons;
  342 
  343         sc = device_get_softc(dev);
  344 
  345         if (command != ADB_COMMAND_TALK || reg != 0 || len < 2)
  346                 return (0);
  347 
  348         ydelta = data[0] & 0x7f;
  349         xdelta = data[1] & 0x7f;
  350 
  351         buttons = 0;
  352         buttons |= !(data[0] & 0x80);
  353         buttons |= !(data[1] & 0x80) << 1;
  354 
  355         if (sc->flags & AMS_EXTENDED) {
  356                 for (i = 2; i < len && i < 5; i++) {
  357                         xdelta |= (data[i] & 0x07) << (3*i + 1);
  358                         ydelta |= (data[i] & 0x70) << (3*i - 3);
  359 
  360                         buttons |= !(data[i] & 0x08) << (2*i - 2);
  361                         buttons |= !(data[i] & 0x80) << (2*i - 1);
  362                 }
  363         } else {
  364                 len = 2; /* Ignore extra data */
  365         }
  366 
  367         /* Do sign extension as necessary */
  368         if (xdelta & (0x40 << 3*(len-2)))
  369                 xdelta |= 0xffffffc0 << 3*(len - 2);
  370         if (ydelta & (0x40 << 3*(len-2)))
  371                 ydelta |= 0xffffffc0 << 3*(len - 2);
  372 
  373         if ((sc->flags & AMS_TOUCHPAD) && (sc->sc_tapping == 1)) {
  374                 tmp_buttons = buttons;
  375                 if (buttons == 0x12) {
  376                         /* Map a double tap on button 3.
  377                            Keep the button state for the next sequence.
  378                            A double tap sequence is followed by a single tap
  379                            sequence.
  380                         */
  381                         tmp_buttons = 0x3;
  382                         sc->button_buf = tmp_buttons;
  383                 } else if (buttons == 0x2) {
  384                         /* Map a single tap on button 2. But only if it is
  385                            not a successor from a double tap.
  386                         */
  387                         if (sc->button_buf != 0x3) 
  388                                 tmp_buttons = 0x2;
  389                         else
  390                                 tmp_buttons = 0;
  391 
  392                         sc->button_buf = 0;
  393                 }
  394                 buttons = tmp_buttons;
  395         }
  396 
  397         /*
  398          * Some mice report high-numbered buttons on the wrong button number,
  399          * so set the highest-numbered real button as pressed if there are
  400          * mysterious high-numbered ones set.
  401          *
  402          * Don't do this for touchpads, because touchpads also trigger
  403          * high button events when they are touched.
  404          */
  405 
  406         if (buttons & ~((1 << sc->hw.buttons) - 1)
  407             && !(sc->flags & AMS_TOUCHPAD)) {
  408                 buttons |= 1 << (sc->hw.buttons - 1);
  409         }
  410         buttons &= (1 << sc->hw.buttons) - 1;
  411 
  412         mtx_lock(&sc->sc_mtx);
  413 
  414         /* Add in our new deltas, and take into account
  415            Apple's opposite meaning for Y axis motion */
  416 
  417         sc->xdelta += xdelta;
  418         sc->ydelta -= ydelta;
  419 
  420         sc->buttons = buttons;
  421 
  422         mtx_unlock(&sc->sc_mtx);
  423 
  424         cv_broadcast(&sc->sc_cv);
  425         selwakeuppri(&sc->rsel, PZERO);
  426 
  427         return (0);
  428 }
  429 
  430 static int
  431 ams_open(struct cdev *dev, int flag, int fmt, struct thread *p)
  432 {
  433         struct adb_mouse_softc *sc;
  434 
  435         sc = CDEV_GET_SOFTC(dev);
  436         if (sc == NULL)
  437                 return (ENXIO);
  438 
  439         mtx_lock(&sc->sc_mtx);
  440         sc->packet_read_len = 0;
  441         sc->xdelta = 0;
  442         sc->ydelta = 0;
  443         sc->buttons = 0;
  444         mtx_unlock(&sc->sc_mtx);
  445 
  446         return (0);
  447 }
  448 
  449 static int
  450 ams_close(struct cdev *dev, int flag, int fmt, struct thread *p)
  451 {
  452         struct adb_mouse_softc *sc;
  453 
  454         sc = CDEV_GET_SOFTC(dev);
  455 
  456         cv_broadcast(&sc->sc_cv);
  457         selwakeuppri(&sc->rsel, PZERO);
  458         return (0);
  459 }
  460 
  461 static int
  462 ams_poll(struct cdev *dev, int events, struct thread *p)
  463 {
  464         struct adb_mouse_softc *sc;
  465 
  466         sc = CDEV_GET_SOFTC(dev);
  467         if (sc == NULL)
  468                 return (EIO);
  469 
  470         if (events & (POLLIN | POLLRDNORM)) {
  471                 mtx_lock(&sc->sc_mtx);
  472                 
  473                 if (sc->xdelta == 0 && sc->ydelta == 0 && 
  474                    sc->buttons == sc->last_buttons) {
  475                         selrecord(p, &sc->rsel);
  476                         events = 0;
  477                 } else {
  478                         events &= (POLLIN | POLLRDNORM);
  479                 }
  480 
  481                 mtx_unlock(&sc->sc_mtx);
  482         }
  483 
  484         return events;
  485 }
  486 
  487 static int
  488 ams_read(struct cdev *dev, struct uio *uio, int flag)
  489 {
  490         struct adb_mouse_softc *sc;
  491         size_t len;
  492         int8_t outpacket[8];
  493         int error;
  494 
  495         sc = CDEV_GET_SOFTC(dev);
  496         if (sc == NULL)
  497                 return (EIO);
  498 
  499         if (uio->uio_resid <= 0)
  500                 return (0);
  501 
  502         mtx_lock(&sc->sc_mtx);
  503 
  504         if (!sc->packet_read_len) {
  505                 if (sc->xdelta == 0 && sc->ydelta == 0 && 
  506                    sc->buttons == sc->last_buttons) {
  507 
  508                         if (flag & O_NONBLOCK) {
  509                                 mtx_unlock(&sc->sc_mtx);
  510                                 return EWOULDBLOCK;
  511                         }
  512 
  513         
  514                         /* Otherwise, block on new data */
  515                         error = cv_wait_sig(&sc->sc_cv, &sc->sc_mtx);
  516                         if (error) {
  517                                 mtx_unlock(&sc->sc_mtx);
  518                                 return (error);
  519                         }
  520                 }
  521 
  522                 sc->packet[0] = 1 << 7;
  523                 sc->packet[0] |= (!(sc->buttons & 1)) << 2;
  524                 sc->packet[0] |= (!(sc->buttons & 4)) << 1;
  525                 sc->packet[0] |= (!(sc->buttons & 2));
  526 
  527                 if (sc->xdelta > 127) {
  528                         sc->packet[1] = 127;
  529                         sc->packet[3] = sc->xdelta - 127;
  530                 } else if (sc->xdelta < -127) {
  531                         sc->packet[1] = -127;
  532                         sc->packet[3] = sc->xdelta + 127;
  533                 } else {
  534                         sc->packet[1] = sc->xdelta;
  535                         sc->packet[3] = 0;
  536                 }
  537 
  538                 if (sc->ydelta > 127) {
  539                         sc->packet[2] = 127;
  540                         sc->packet[4] = sc->ydelta - 127;
  541                 } else if (sc->ydelta < -127) {
  542                         sc->packet[2] = -127;
  543                         sc->packet[4] = sc->ydelta + 127;
  544                 } else {
  545                         sc->packet[2] = sc->ydelta;
  546                         sc->packet[4] = 0;
  547                 }
  548 
  549                 /* No Z movement */
  550                 sc->packet[5] = 0;
  551                 sc->packet[6] = 0; 
  552 
  553                 sc->packet[7] = ~((uint8_t)(sc->buttons >> 3)) & 0x7f;
  554 
  555 
  556                 sc->last_buttons = sc->buttons;
  557                 sc->xdelta = 0;
  558                 sc->ydelta = 0;
  559 
  560                 sc->packet_read_len = sc->mode.packetsize;
  561         }
  562 
  563         len = (sc->packet_read_len > uio->uio_resid) ? 
  564                 uio->uio_resid : sc->packet_read_len;
  565 
  566         memcpy(outpacket,sc->packet + 
  567                 (sc->mode.packetsize - sc->packet_read_len),len);
  568         sc->packet_read_len -= len;
  569 
  570         mtx_unlock(&sc->sc_mtx);
  571 
  572         uiomove(outpacket,len,uio);
  573 
  574         return (0);
  575 }
  576 
  577 
  578 static int
  579 ams_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, 
  580     struct thread *p)
  581 {
  582         struct adb_mouse_softc *sc;
  583         mousemode_t mode;
  584 
  585         sc = CDEV_GET_SOFTC(dev);
  586         if (sc == NULL)
  587                 return (EIO);
  588 
  589         switch (cmd) {
  590         case MOUSE_GETHWINFO:
  591                 *(mousehw_t *)addr = sc->hw;
  592                 break;
  593         case MOUSE_GETMODE:
  594                 *(mousemode_t *)addr = sc->mode;
  595                 break;
  596         case MOUSE_SETMODE:
  597                 mode = *(mousemode_t *)addr;
  598                 addr = (caddr_t)&mode.level;
  599 
  600                 /* Fallthrough */
  601 
  602         case MOUSE_SETLEVEL:
  603                 if (*(int *)addr == -1)
  604                         break;
  605                 else if (*(int *)addr == 1) {
  606                         sc->mode.level = 1;
  607                         sc->mode.packetsize = 8;
  608                         break;
  609                 } else if (*(int *)addr == 0) {
  610                         sc->mode.level = 0;
  611                         sc->mode.packetsize = 5;
  612                         break;
  613                 }
  614         
  615                 return EINVAL;
  616         case MOUSE_GETLEVEL:
  617                 *(int *)addr = sc->mode.level;
  618                 break;
  619         
  620         case MOUSE_GETSTATUS: {
  621                 mousestatus_t *status = (mousestatus_t *) addr;
  622 
  623                 mtx_lock(&sc->sc_mtx);
  624 
  625                 status->button = sc->buttons;
  626                 status->obutton = sc->last_buttons;
  627                 
  628                 status->flags = status->button ^ status->obutton;
  629 
  630                 if (sc->xdelta != 0 || sc->ydelta)
  631                         status->flags |= MOUSE_POSCHANGED;
  632                 if (status->button != status->obutton)
  633                         status->flags |= MOUSE_BUTTONSCHANGED;
  634 
  635                 status->dx = sc->xdelta;
  636                 status->dy = sc->ydelta;
  637                 status->dz = 0;
  638 
  639                 sc->xdelta = 0;
  640                 sc->ydelta = 0;
  641                 sc->last_buttons = sc->buttons;
  642 
  643                 mtx_unlock(&sc->sc_mtx);
  644 
  645                 break; }
  646         default:
  647                 return ENOTTY;
  648         }
  649 
  650         return (0);
  651 }
  652 
  653 static int
  654 adb_tapping_sysctl(SYSCTL_HANDLER_ARGS)
  655 {
  656         struct adb_mouse_softc *sc = arg1;
  657         device_t dev;
  658         int error;
  659         u_char r2[8];
  660         u_int tapping;
  661 
  662         dev = sc->sc_dev;
  663         tapping = sc->sc_tapping;
  664 
  665         error = sysctl_handle_int(oidp, &tapping, 0, req);
  666 
  667         if (error || !req->newptr)
  668                 return (error);
  669 
  670         if (tapping == 1) {
  671                 adb_read_register(dev, 2, r2);
  672                 r2[0] = 0x99; /* enable tapping. */
  673                 adb_write_register(dev, 2, 8, r2);
  674                 sc->sc_tapping = 1;
  675         } else if (tapping == 0) {
  676                 adb_read_register(dev, 2, r2);
  677                 r2[0] = 0x19; /* disable tapping. */
  678                 adb_write_register(dev, 2, 8, r2);
  679                 sc->sc_tapping = 0;
  680         }
  681         else
  682                 return (EINVAL);
  683 
  684         return (0);
  685 }

Cache object: 03252c40244be2f1807e8eb92ae85c10


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