scoutos / prex-0.9.0 / bsp / drv / dev / input / psaux.c @ 03e9c04a
History | View | Annotate | Download (5.14 KB)
1 | 03e9c04a | Brad Neuman | /*-
|
---|---|---|---|
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 | } |