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/mse/mse_cbus.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) 2004 M. Warner Losh
    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 AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  */
   28 
   29 /*-
   30  * Copyright 1992 by the University of Guelph
   31  *
   32  * Permission to use, copy and modify this
   33  * software and its documentation for any purpose and without
   34  * fee is hereby granted, provided that the above copyright
   35  * notice appear in all copies and that both that copyright
   36  * notice and this permission notice appear in supporting
   37  * documentation.
   38  * University of Guelph makes no representations about the suitability of
   39  * this software for any purpose.  It is provided "as is"
   40  * without express or implied warranty.
   41  */
   42 /*
   43  * Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and
   44  * the X386 port, courtesy of
   45  * Rick Macklem, rick@snowhite.cis.uoguelph.ca
   46  * Caveats: The driver currently uses spltty(), but doesn't use any
   47  * generic tty code. It could use splmse() (that only masks off the
   48  * bus mouse interrupt, but that would require hacking in i386/isa/icu.s.
   49  * (This may be worth the effort, since the Logitech generates 30/60
   50  * interrupts/sec continuously while it is open.)
   51  * NB: The ATI has NOT been tested yet!
   52  */
   53 
   54 /*
   55  * Modification history:
   56  * Sep 6, 1994 -- Lars Fredriksen(fredriks@mcs.com)
   57  *   improved probe based on input from Logitech.
   58  *
   59  * Oct 19, 1992 -- E. Stark (stark@cs.sunysb.edu)
   60  *   fixes to make it work with Microsoft InPort busmouse
   61  *
   62  * Jan, 1993 -- E. Stark (stark@cs.sunysb.edu)
   63  *   added patches for new "select" interface
   64  *
   65  * May 4, 1993 -- E. Stark (stark@cs.sunysb.edu)
   66  *   changed position of some spl()'s in mseread
   67  *
   68  * October 8, 1993 -- E. Stark (stark@cs.sunysb.edu)
   69  *   limit maximum negative x/y value to -127 to work around XFree problem
   70  *   that causes spurious button pushes.
   71  */
   72 
   73 #include <sys/param.h>
   74 #include <sys/systm.h>
   75 #include <sys/conf.h>
   76 #include <sys/kernel.h>
   77 #include <sys/module.h>
   78 #include <sys/bus.h>
   79 #include <sys/poll.h>
   80 #include <sys/selinfo.h>
   81 #include <sys/uio.h>
   82 #include <sys/mouse.h>
   83 
   84 #include <machine/bus.h>
   85 #include <machine/resource.h>
   86 #include <sys/rman.h>
   87 
   88 #include <isa/isavar.h>
   89 
   90 #include <dev/mse/msevar.h>
   91 
   92 static  int             mse_cbus_probe(device_t dev);
   93 static  int             mse_cbus_attach(device_t dev);
   94 static  int             mse_cbus_detach(device_t dev);
   95 
   96 static  device_method_t mse_methods[] = {
   97         DEVMETHOD(device_probe,         mse_cbus_probe),
   98         DEVMETHOD(device_attach,        mse_cbus_attach),
   99         DEVMETHOD(device_detach,        mse_cbus_detach),
  100         { 0, 0 }
  101 };
  102 
  103 static  driver_t        mse_driver = {
  104         "mse",
  105         mse_methods,
  106         sizeof(mse_softc_t),
  107 };
  108 
  109 DRIVER_MODULE(mse, isa, mse_driver, mse_devclass, 0, 0);
  110 
  111 static struct isa_pnp_id mse_ids[] = {
  112 #if 0
  113         { 0x001fa3b8, "PC-98 bus mouse" },              /* NEC1F00 */
  114 #endif
  115         { 0 }
  116 };
  117 
  118 /*
  119  * PC-9801 Bus mouse definitions
  120  */
  121 
  122 #define MODE    MSE_PORTD
  123 #define HC      MSE_PORTD
  124 #define INT     MSE_PORTD
  125 
  126 #define XL      0x00
  127 #define XH      0x20
  128 #define YL      0x40
  129 #define YH      0x60
  130 
  131 #define INT_ENABLE      0x8
  132 #define INT_DISABLE     0x9
  133 #define HC_NO_CLEAR     0xe
  134 #define HC_CLEAR        0xf
  135 
  136 static  bus_addr_t      mse_port[] = {0, 2, 4, 6};
  137 
  138 static  int             mse_probe98m(device_t dev, mse_softc_t *sc);
  139 static  void            mse_disable98m(bus_space_tag_t t, bus_space_handle_t h);
  140 static  void            mse_get98m(bus_space_tag_t t, bus_space_handle_t h,
  141                             int *dx, int *dy, int *but);
  142 static  void            mse_enable98m(bus_space_tag_t t, bus_space_handle_t h);
  143 
  144 static struct mse_types mse_types[] = {
  145         { MSE_98BUSMOUSE,
  146           mse_probe98m, mse_enable98m, mse_disable98m, mse_get98m,
  147           { 2, MOUSE_IF_BUS, MOUSE_MOUSE, MOUSE_MODEL_GENERIC, 0, },
  148           { MOUSE_PROTO_BUS, -1, -1, 0, 0, MOUSE_MSC_PACKETSIZE, 
  149             { MOUSE_MSC_SYNCMASK, MOUSE_MSC_SYNC, }, }, },
  150         { 0, },
  151 };
  152 
  153 static int
  154 mse_cbus_probe(device_t dev)
  155 {
  156         mse_softc_t *sc;
  157         int error;
  158         int rid;
  159         int i;
  160 
  161         /* check PnP IDs */
  162         error = ISA_PNP_PROBE(device_get_parent(dev), dev, mse_ids);
  163         if (error == ENXIO)
  164                 return error;
  165 
  166         sc = device_get_softc(dev);
  167         rid = 0;
  168         sc->sc_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, mse_port,
  169                                           MSE_IOSIZE, RF_ACTIVE);
  170         if (sc->sc_port == NULL)
  171                 return ENXIO;
  172         if (isa_load_resourcev(sc->sc_port, mse_port, MSE_IOSIZE)) {
  173                 bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port);
  174                 return ENXIO;
  175         }
  176         sc->sc_iot = rman_get_bustag(sc->sc_port);
  177         sc->sc_ioh = rman_get_bushandle(sc->sc_port);
  178 
  179         /*
  180          * Check for each mouse type in the table.
  181          */
  182         i = 0;
  183         while (mse_types[i].m_type) {
  184                 if ((*mse_types[i].m_probe)(dev, sc)) {
  185                         sc->sc_mousetype = mse_types[i].m_type;
  186                         sc->sc_enablemouse = mse_types[i].m_enable;
  187                         sc->sc_disablemouse = mse_types[i].m_disable;
  188                         sc->sc_getmouse = mse_types[i].m_get;
  189                         sc->hw = mse_types[i].m_hw;
  190                         sc->mode = mse_types[i].m_mode;
  191                         bus_release_resource(dev, SYS_RES_IOPORT, rid,
  192                                              sc->sc_port);
  193                         device_set_desc(dev, "Bus/InPort Mouse");
  194                         return 0;
  195                 }
  196                 i++;
  197         }
  198         bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port);
  199         return ENXIO;
  200 }
  201 
  202 static int
  203 mse_cbus_attach(device_t dev)
  204 {
  205         mse_softc_t *sc;
  206         int rid;
  207 
  208         sc = device_get_softc(dev);
  209 
  210         rid = 0;
  211         sc->sc_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, mse_port,
  212                                           MSE_IOSIZE, RF_ACTIVE);
  213         if (sc->sc_port == NULL)
  214                 return ENXIO;
  215         if (isa_load_resourcev(sc->sc_port, mse_port, MSE_IOSIZE)) {
  216                 bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port);
  217                 return ENXIO;
  218         }
  219         sc->sc_iot = rman_get_bustag(sc->sc_port);
  220         sc->sc_ioh = rman_get_bushandle(sc->sc_port);
  221 
  222         return (mse_common_attach(dev));
  223 }
  224 
  225 static int
  226 mse_cbus_detach(device_t dev)
  227 {
  228         mse_softc_t *sc;
  229         int rid;
  230 
  231         sc = device_get_softc(dev);
  232         if (sc->sc_flags & MSESC_OPEN)
  233                 return EBUSY;
  234 
  235         rid = 0;
  236         BUS_TEARDOWN_INTR(device_get_parent(dev), dev, sc->sc_intr, sc->sc_ih);
  237         bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr);
  238         bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port);
  239 
  240         destroy_dev(sc->sc_dev);
  241         destroy_dev(sc->sc_ndev);
  242 
  243         return 0;
  244 }
  245 
  246 /*
  247  * Routines for the PC98 bus mouse.
  248  */
  249 
  250 /*
  251  * Test for a PC98 bus mouse and return 1 if it is.
  252  * (do not enable interrupts)
  253  */
  254 static int
  255 mse_probe98m(device_t dev, mse_softc_t *sc)
  256 {
  257         /* mode set */
  258         bus_space_write_1(sc->sc_iot, sc->sc_ioh, MODE, 0x93);
  259 
  260         /* initialize */
  261         /* INT disable */
  262         bus_space_write_1(sc->sc_iot, sc->sc_ioh, INT, INT_DISABLE);
  263         /* HC = 0 */
  264         bus_space_write_1(sc->sc_iot, sc->sc_ioh, HC, HC_NO_CLEAR);
  265         /* HC = 1 */
  266         bus_space_write_1(sc->sc_iot, sc->sc_ioh, HC, HC_CLEAR);
  267 
  268         return (1);
  269 }
  270 
  271 /*
  272  * Initialize PC98 bus mouse and enable interrupts.
  273  */
  274 static void
  275 mse_enable98m(bus_space_tag_t tag, bus_space_handle_t handle)
  276 {
  277         bus_space_write_1(tag, handle, INT, INT_ENABLE);    /* INT enable */
  278         bus_space_write_1(tag, handle, HC, HC_NO_CLEAR);    /* HC = 0 */
  279         bus_space_write_1(tag, handle, HC, HC_CLEAR);       /* HC = 1 */
  280 }
  281  
  282 /*
  283  * Disable interrupts for PC98 Bus mouse.
  284  */
  285 static void
  286 mse_disable98m(bus_space_tag_t tag, bus_space_handle_t handle)
  287 {
  288         bus_space_write_1(tag, handle, INT, INT_DISABLE);   /* INT disable */
  289         bus_space_write_1(tag, handle, HC, HC_NO_CLEAR);    /* HC = 0 */
  290         bus_space_write_1(tag, handle, HC, HC_CLEAR);       /* HC = 1 */
  291 }
  292 
  293 /*
  294  * Get current dx, dy and up/down button state.
  295  */
  296 static void
  297 mse_get98m(bus_space_tag_t tag, bus_space_handle_t handle, int *dx, int *dy,
  298     int *but)
  299 {
  300         register char x, y;
  301 
  302         bus_space_write_1(tag, handle, INT, INT_DISABLE);   /* INT disable */
  303 
  304         bus_space_write_1(tag, handle, HC, HC_CLEAR);       /* HC = 1 */
  305 
  306         /* X low */
  307         bus_space_write_1(tag, handle, MSE_PORTC, 0x90 | XL);
  308         x = bus_space_read_1(tag, handle, MSE_PORTA) & 0x0f;
  309         /* X high */
  310         bus_space_write_1(tag, handle, MSE_PORTC, 0x90 | XH);
  311         x |= ((bus_space_read_1(tag, handle, MSE_PORTA)  & 0x0f) << 4);
  312 
  313         /* Y low */
  314         bus_space_write_1(tag, handle, MSE_PORTC, 0x90 | YL);
  315         y = (bus_space_read_1(tag, handle, MSE_PORTA) & 0x0f);
  316         /* Y high */
  317         bus_space_write_1(tag, handle, MSE_PORTC, 0x90 | YH);
  318         y |= ((bus_space_read_1(tag, handle, MSE_PORTA) & 0x0f) << 4);
  319 
  320         *but = (bus_space_read_1(tag, handle, MSE_PORTA) >> 5) & 7;
  321 
  322         *dx = x;
  323         *dy = y;
  324 
  325         bus_space_write_1(tag, handle, HC, HC_NO_CLEAR);    /* HC = 0 */
  326 
  327         bus_space_write_1(tag, handle, INT, INT_ENABLE);    /* INT enable */
  328 }

Cache object: 9ef6bd30bd20b378619da78a06695bea


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