Statistics
| Branch: | Revision:

scoutos / prex-0.9.0 / bsp / drv / dev / input / psaux.c @ 03e9c04a

History | View | Annotate | Download (5.14 KB)

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
}