Prex Home / Browse Source - Prex Version: 0.9.0

root/bsp/drv/dev/input/psaux.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kmc_send_auxcmd
  2. kmc_write_aux
  3. psaux_isr
  4. psaux_open
  5. psaux_close
  6. psaux_read
  7. psaux_init

   1 /*-
   2  * Copyright (c) 2005-2009, Kohsuke Ohtani
   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  * 3. Neither the name of the author nor the names of any co-contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 /*
  31  * psaux.c - ps2 mouse support
  32  */
  33 
  34 /*
  35  * PS/2 mouse packet
  36  *
  37  *         Bit7   Bit6   Bit5   Bit4   Bit3  Bit2   Bit1   Bit0
  38  *  ------ ------ ------ ------ ------ ----- ------ ------ ------
  39  *  Byte 1 Yovf   Xovf   Ysign  Xsign    1   MidBtn RgtBtn LftBtn
  40  *  Byte 2 X movement
  41  *  Byte 3 Y movement
  42  */
  43 
  44 #include <driver.h>
  45 
  46 #include "i8042.h"
  47 
  48 /* #define DEBUG_MOUSE 1 */
  49 
  50 #ifdef DEBUG_MOUSE
  51 #define DPRINTF(a) printf a
  52 #else
  53 #define DPRINTF(a)
  54 #endif
  55 
  56 #define MOUSE_IRQ       12
  57 
  58 struct psaux_softc {
  59         device_t        dev;            /* device object */
  60         irq_t           irq;            /* handle for mouse irq */
  61         u_char          packet[3];      /* mouse packet */
  62         int             index;
  63 };
  64 
  65 static int psaux_init(struct driver *);
  66 static int psaux_open(device_t, int);
  67 static int psaux_close(device_t);
  68 static int psaux_read(device_t, char *, size_t *, int);
  69 
  70 static struct devops psaux_devops = {
  71         /* open */      psaux_open,
  72         /* close */     psaux_close,
  73         /* read */      psaux_read,
  74         /* write */     no_write,
  75         /* ioctl */     no_ioctl,
  76         /* devctl */    no_devctl,
  77 };
  78 
  79 struct driver psaux_driver = {
  80         /* name */      "psaux",
  81         /* devops */    &psaux_devops,
  82         /* devsz */     sizeof(struct psaux_softc),
  83         /* flags */     0,
  84         /* probe */     NULL,
  85         /* init */      psaux_init,
  86         /* shutdown */  NULL,
  87 };
  88 
  89 /*
  90  * Write aux device command
  91  */
  92 static void
  93 kmc_send_auxcmd(u_char val)
  94 {
  95 
  96         DPRINTF(("kmc_send_auxcmd: %x\n", val));
  97         kmc_wait_ibe();
  98         bus_write_8(KMC_CMD, 0x60);
  99         kmc_wait_ibe();
 100         bus_write_8(KMC_DATA, val);
 101 }
 102 
 103 /*
 104  * Returns 0 on success, -1 on failure.
 105  */
 106 static int
 107 kmc_write_aux(u_char val)
 108 {
 109         int rc = -1;
 110         int s;
 111 
 112         DPRINTF(("kmc_write_aux: val=%x\n", val));
 113         s = splhigh();
 114 
 115         /* Write the value to the device */
 116         kmc_wait_ibe();
 117         bus_write_8(KMC_CMD, 0xd4);
 118         kmc_wait_ibe();
 119         bus_write_8(KMC_DATA, val);
 120 
 121         /* Get the ack */
 122         kmc_wait_obf();
 123         if ((bus_read_8(KMC_STS) & 0x20) == 0x20) {
 124                 if (bus_read_8(KMC_DATA) == 0xfa)
 125                         rc = 0;
 126         }
 127         splx(s);
 128 #ifdef DEBUG_MOUSE
 129         if (rc)
 130                 printf("kmc_write_aux: error val=%x\n", val);
 131 #endif
 132         return rc;
 133 }
 134 
 135 /*
 136  * Interrupt handler
 137  */
 138 static int
 139 psaux_isr(void *arg)
 140 {
 141         struct psaux_softc *sc = arg;
 142         u_char dat, id;
 143 
 144         if ((bus_read_8(KMC_STS) & 0x21) != 0x21)
 145                 return 0;
 146 
 147         dat = bus_read_8(KMC_DATA);
 148         if (dat == 0xaa) {      /* BAT comp (reconnect) ? */
 149                 DPRINTF(("BAT comp"));
 150                 sc->index = 0;
 151                 kmc_wait_obf();
 152                 if ((bus_read_8(KMC_STS) & 0x20) == 0x20) {
 153                         id = bus_read_8(KMC_DATA);
 154                         DPRINTF(("Mouse ID=%x\n", id));
 155                 }
 156                 kmc_write_aux(0xf4);    /* Enable aux device */
 157                 return 0;
 158         }
 159 
 160         sc->packet[sc->index++] = dat;
 161         if (sc->index < 3)
 162                 return 0;
 163         sc->index = 0;
 164         DPRINTF(("mouse packet %x:%d:%d\n", sc->packet[0],
 165                  sc->packet[1], sc->packet[2]));
 166         return 0;
 167 }
 168 
 169 /*
 170  * Open
 171  */
 172 static int
 173 psaux_open(device_t dev, int mode)
 174 {
 175 
 176         DPRINTF(("psaux_open: dev=%x\n", dev));
 177         return 0;
 178 }
 179 
 180 /*
 181  * Close
 182  */
 183 static int
 184 psaux_close(device_t dev)
 185 {
 186         DPRINTF(("psaux_close: dev=%x\n", dev));
 187         return 0;
 188 }
 189 
 190 /*
 191  * Read
 192  */
 193 static int
 194 psaux_read(device_t dev, char *buf, size_t *nbyte, int blkno)
 195 {
 196 
 197         return 0;
 198 }
 199 
 200 static int
 201 psaux_init(struct driver *self)
 202 {
 203         struct psaux_softc *sc;
 204         device_t dev;
 205 
 206 #ifdef DEBUG
 207         printf("Mouse sampling rate=100 samples/sec\n");
 208 #endif
 209         dev = device_create(self, "mouse", D_CHR);
 210 
 211         sc = device_private(dev);
 212         sc->dev = dev;
 213         sc->index = 0;
 214 
 215         /* Allocate IRQ */
 216         sc->irq = irq_attach(MOUSE_IRQ, IPL_INPUT, 0, psaux_isr,
 217                              IST_NONE, sc);
 218 
 219         kmc_wait_ibe();
 220         bus_write_8(KMC_CMD, 0xa8);     /* Enable aux */
 221 
 222         kmc_write_aux(0xf3);    /* Set sample rate */
 223         kmc_write_aux(100);     /* 100 samples/sec */
 224 
 225         kmc_write_aux(0xe8);    /* Set resolution */
 226         kmc_write_aux(3);       /* 8 counts per mm */
 227         kmc_write_aux(0xe7);    /* 2:1 scaling */
 228 
 229         kmc_write_aux(0xf4);    /* Enable aux device */
 230         kmc_send_auxcmd(0x47);  /* Enable controller ints */
 231         return 0;
 232 }

/* [<][>][^][v][top][bottom][index][help] */