Annotation of prex/dev/i386/pc/mouse.c, Revision 1.1.1.1
1.1 nbrk 1: /*-
2: * Copyright (c) 2005, 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: * mouse.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: #include <cpufunc.h>
46:
47: #include "kmc.h"
48:
49: /* #define DEBUG_MOUSE 1 */
50:
51: #ifdef DEBUG_MOUSE
52: #define DPRINTF(a) printf a
53: #else
54: #define DPRINTF(a)
55: #endif
56:
57: #define MOUSE_IRQ 12
58:
59: static int mouse_init(void);
60: static int mouse_open(device_t, int);
61: static int mouse_close(device_t);
62: static int mouse_read(device_t, char *, size_t *, int);
63:
64: /*
65: * Driver structure
66: */
67: struct driver mouse_drv = {
68: /* name */ "PS/2 Mouse",
69: /* order */ 6,
70: /* init */ mouse_init,
71: };
72:
73: /*
74: * Device I/O table
75: */
76: static struct devio mouse_io = {
77: /* open */ mouse_open,
78: /* close */ mouse_close,
79: /* read */ mouse_read,
80: /* write */ NULL,
81: /* ioctl */ NULL,
82: /* event */ NULL,
83: };
84:
85: static device_t mouse_dev; /* Mouse object */
86: static irq_t mouse_irq; /* Handle for mouse irq */
87: static u_char packet[3]; /* Mouse packet */
88: static int index = 0;
89:
90: /*
91: * Write aux device command
92: */
93: static void
94: aux_command(u_char val)
95: {
96:
97: DPRINTF(("aux_command: %x\n", val));
98: wait_ibe();
99: outb(0x60, KMC_CMD);
100: wait_ibe();
101: outb(val, KMC_DATA);
102: }
103:
104: /*
105: * Returns 0 on success, -1 on failure.
106: */
107: static int
108: aux_write(u_char val)
109: {
110: int rc = -1;
111:
112: DPRINTF(("aux_write: val=%x\n", val));
113: irq_lock();
114:
115: /* Write the value to the device */
116: wait_ibe();
117: outb(0xd4, KMC_CMD);
118: wait_ibe();
119: outb(val, KMC_DATA);
120:
121: /* Get the ack */
122: wait_obf();
123: if ((inb(KMC_STS) & 0x20) == 0x20) {
124: if (inb(KMC_DATA) == 0xfa)
125: rc = 0;
126: }
127: irq_unlock();
128: #ifdef DEBUG_MOUSE
129: if (rc)
130: printf("aux_write: error val=%x\n", val);
131: #endif
132: return rc;
133: }
134:
135: /*
136: * Interrupt handler
137: */
138: static int
139: mouse_isr(int irq)
140: {
141: u_char dat, id;
142:
143: if ((inb(KMC_STS) & 0x21) != 0x21)
144: return 0;
145:
146: dat = inb(KMC_DATA);
147: if (dat == 0xaa) { /* BAT comp (reconnect) ? */
148: DPRINTF(("BAT comp"));
149: index = 0;
150: wait_obf();
151: if ((inb(KMC_STS) & 0x20) == 0x20) {
152: id = inb(KMC_DATA);
153: DPRINTF(("Mouse ID=%x\n", id));
154: }
155: aux_write(0xf4); /* Enable aux device */
156: return 0;
157: }
158:
159: packet[index++] = dat;
160: if (index < 3)
161: return 0;
162: index = 0;
163: DPRINTF(("mouse packet %x:%d:%d\n", packet[0], packet[1], packet[2]));
164: return 0;
165: }
166:
167: /*
168: * Open
169: */
170: static int
171: mouse_open(device_t dev, int mode)
172: {
173: DPRINTF(("mouse_open: dev=%x\n", dev));
174: return 0;
175: }
176:
177: /*
178: * Close
179: */
180: static int
181: mouse_close(device_t dev)
182: {
183: DPRINTF(("mouse_close: dev=%x\n", dev));
184: return 0;
185: }
186:
187: /*
188: * Read
189: */
190: static int
191: mouse_read(device_t dev, char *buf, size_t *nbyte, int blkno)
192: {
193: return 0;
194: }
195:
196: /*
197: * Initialize
198: */
199: static int
200: mouse_init(void)
201: {
202:
203: #ifdef DEBUG
204: printk("Mouse sampling rate=100 samples/sec\n");
205: #endif
206: /* Create device object */
207: mouse_dev = device_create(&mouse_io, "mouse", DF_CHR);
208: ASSERT(mouse_dev);
209:
210: /* Allocate IRQ */
211: mouse_irq = irq_attach(MOUSE_IRQ, IPL_INPUT, 0, mouse_isr, NULL);
212: ASSERT(mouse_irq != IRQ_NULL);
213:
214: wait_ibe();
215: outb(0xa8, KMC_CMD); /* Enable aux */
216:
217: aux_write(0xf3); /* Set sample rate */
218: aux_write(100); /* 100 samples/sec */
219:
220: aux_write(0xe8); /* Set resolution */
221: aux_write(3); /* 8 counts per mm */
222: aux_write(0xe7); /* 2:1 scaling */
223:
224: aux_write(0xf4); /* Enable aux device */
225: aux_command(0x47); /* Enable controller ints */
226: return 0;
227: }
CVSweb