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-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 (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/10.2/sys/dev/adb/adb_mouse.c 262668 2014-03-01 21:50:23Z jhibbits $
   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", NULL, MTX_DEF);
  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                    sc->packet_read_len == 0) {
  476                         selrecord(p, &sc->rsel);
  477                         events = 0;
  478                 } else {
  479                         events &= (POLLIN | POLLRDNORM);
  480                 }
  481 
  482                 mtx_unlock(&sc->sc_mtx);
  483         }
  484 
  485         return events;
  486 }
  487 
  488 static int
  489 ams_read(struct cdev *dev, struct uio *uio, int flag)
  490 {
  491         struct adb_mouse_softc *sc;
  492         size_t len;
  493         int8_t outpacket[8];
  494         int error;
  495 
  496         sc = CDEV_GET_SOFTC(dev);
  497         if (sc == NULL)
  498                 return (EIO);
  499 
  500         if (uio->uio_resid <= 0)
  501                 return (0);
  502 
  503         mtx_lock(&sc->sc_mtx);
  504 
  505         if (!sc->packet_read_len) {
  506                 if (sc->xdelta == 0 && sc->ydelta == 0 && 
  507                    sc->buttons == sc->last_buttons) {
  508 
  509                         if (flag & O_NONBLOCK) {
  510                                 mtx_unlock(&sc->sc_mtx);
  511                                 return EWOULDBLOCK;
  512                         }
  513 
  514         
  515                         /* Otherwise, block on new data */
  516                         error = cv_wait_sig(&sc->sc_cv, &sc->sc_mtx);
  517                         if (error) {
  518                                 mtx_unlock(&sc->sc_mtx);
  519                                 return (error);
  520                         }
  521                 }
  522 
  523                 sc->packet[0] = 1 << 7;
  524                 sc->packet[0] |= (!(sc->buttons & 1)) << 2;
  525                 sc->packet[0] |= (!(sc->buttons & 4)) << 1;
  526                 sc->packet[0] |= (!(sc->buttons & 2));
  527 
  528                 if (sc->xdelta > 127) {
  529                         sc->packet[1] = 127;
  530                         sc->packet[3] = sc->xdelta - 127;
  531                 } else if (sc->xdelta < -127) {
  532                         sc->packet[1] = -127;
  533                         sc->packet[3] = sc->xdelta + 127;
  534                 } else {
  535                         sc->packet[1] = sc->xdelta;
  536                         sc->packet[3] = 0;
  537                 }
  538 
  539                 if (sc->ydelta > 127) {
  540                         sc->packet[2] = 127;
  541                         sc->packet[4] = sc->ydelta - 127;
  542                 } else if (sc->ydelta < -127) {
  543                         sc->packet[2] = -127;
  544                         sc->packet[4] = sc->ydelta + 127;
  545                 } else {
  546                         sc->packet[2] = sc->ydelta;
  547                         sc->packet[4] = 0;
  548                 }
  549 
  550                 /* No Z movement */
  551                 sc->packet[5] = 0;
  552                 sc->packet[6] = 0; 
  553 
  554                 sc->packet[7] = ~((uint8_t)(sc->buttons >> 3)) & 0x7f;
  555 
  556 
  557                 sc->last_buttons = sc->buttons;
  558                 sc->xdelta = 0;
  559                 sc->ydelta = 0;
  560 
  561                 sc->packet_read_len = sc->mode.packetsize;
  562         }
  563 
  564         len = (sc->packet_read_len > uio->uio_resid) ? 
  565                 uio->uio_resid : sc->packet_read_len;
  566 
  567         memcpy(outpacket,sc->packet + 
  568                 (sc->mode.packetsize - sc->packet_read_len),len);
  569         sc->packet_read_len -= len;
  570 
  571         mtx_unlock(&sc->sc_mtx);
  572 
  573         error = uiomove(outpacket,len,uio);
  574 
  575         return (error);
  576 }
  577 
  578 
  579 static int
  580 ams_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, 
  581     struct thread *p)
  582 {
  583         struct adb_mouse_softc *sc;
  584         mousemode_t mode;
  585 
  586         sc = CDEV_GET_SOFTC(dev);
  587         if (sc == NULL)
  588                 return (EIO);
  589 
  590         switch (cmd) {
  591         case MOUSE_GETHWINFO:
  592                 *(mousehw_t *)addr = sc->hw;
  593                 break;
  594         case MOUSE_GETMODE:
  595                 *(mousemode_t *)addr = sc->mode;
  596                 break;
  597         case MOUSE_SETMODE:
  598                 mode = *(mousemode_t *)addr;
  599                 addr = (caddr_t)&mode.level;
  600 
  601                 /* Fallthrough */
  602 
  603         case MOUSE_SETLEVEL:
  604                 if (*(int *)addr == -1)
  605                         break;
  606                 else if (*(int *)addr == 1) {
  607                         sc->mode.level = 1;
  608                         sc->mode.packetsize = 8;
  609                         break;
  610                 } else if (*(int *)addr == 0) {
  611                         sc->mode.level = 0;
  612                         sc->mode.packetsize = 5;
  613                         break;
  614                 }
  615         
  616                 return EINVAL;
  617         case MOUSE_GETLEVEL:
  618                 *(int *)addr = sc->mode.level;
  619                 break;
  620         
  621         case MOUSE_GETSTATUS: {
  622                 mousestatus_t *status = (mousestatus_t *) addr;
  623 
  624                 mtx_lock(&sc->sc_mtx);
  625 
  626                 status->button = sc->buttons;
  627                 status->obutton = sc->last_buttons;
  628                 
  629                 status->flags = status->button ^ status->obutton;
  630 
  631                 if (sc->xdelta != 0 || sc->ydelta)
  632                         status->flags |= MOUSE_POSCHANGED;
  633                 if (status->button != status->obutton)
  634                         status->flags |= MOUSE_BUTTONSCHANGED;
  635 
  636                 status->dx = sc->xdelta;
  637                 status->dy = sc->ydelta;
  638                 status->dz = 0;
  639 
  640                 sc->xdelta = 0;
  641                 sc->ydelta = 0;
  642                 sc->last_buttons = sc->buttons;
  643 
  644                 mtx_unlock(&sc->sc_mtx);
  645 
  646                 break; }
  647         default:
  648                 return ENOTTY;
  649         }
  650 
  651         return (0);
  652 }
  653 
  654 static int
  655 adb_tapping_sysctl(SYSCTL_HANDLER_ARGS)
  656 {
  657         struct adb_mouse_softc *sc = arg1;
  658         device_t dev;
  659         int error;
  660         u_char r2[8];
  661         u_int tapping;
  662 
  663         dev = sc->sc_dev;
  664         tapping = sc->sc_tapping;
  665 
  666         error = sysctl_handle_int(oidp, &tapping, 0, req);
  667 
  668         if (error || !req->newptr)
  669                 return (error);
  670 
  671         if (tapping == 1) {
  672                 adb_read_register(dev, 2, r2);
  673                 r2[0] = 0x99; /* enable tapping. */
  674                 adb_write_register(dev, 2, 8, r2);
  675                 sc->sc_tapping = 1;
  676         } else if (tapping == 0) {
  677                 adb_read_register(dev, 2, r2);
  678                 r2[0] = 0x19; /* disable tapping. */
  679                 adb_write_register(dev, 2, 8, r2);
  680                 sc->sc_tapping = 0;
  681         }
  682         else
  683                 return (EINVAL);
  684 
  685         return (0);
  686 }

Cache object: 6a1429b07977def576cb6fd3c2b8e2d2


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