Import 2.3.11pre5
[davej-history.git] / drivers / char / adbmouse.c
blob77bbbbd69a99ad60f510fe12d2620ee2007e7803
1 /*
2 * Macintosh ADB Mouse driver for Linux
4 * 27 Oct 1997 Michael Schmitz
5 * logitech fixes by anthony tong
6 * further hacking by Paul Mackerras
8 * Apple mouse protocol according to:
10 * Device code shamelessly stolen from:
13 * Atari Mouse Driver for Linux
14 * by Robert de Vries (robert@and.nl) 19Jul93
16 * 16 Nov 1994 Andreas Schwab
17 * Compatibility with busmouse
18 * Support for three button mouse (shamelessly stolen from MiNT)
19 * third button wired to one of the joystick directions on joystick 1
21 * 1996/02/11 Andreas Schwab
22 * Module support
23 * Allow multiple open's
26 #include <linux/module.h>
28 #include <linux/sched.h>
29 #include <linux/errno.h>
30 #include <linux/miscdevice.h>
31 #include <linux/mm.h>
32 #include <linux/random.h>
33 #include <linux/poll.h>
34 #include <linux/init.h>
36 #include <asm/adb_mouse.h>
37 #include <asm/uaccess.h>
38 #ifdef __powerpc__
39 #include <asm/processor.h>
40 #endif
41 #ifdef __mc68000__
42 #include <asm/setup.h>
43 #endif
45 static struct mouse_status mouse;
46 static unsigned char adb_mouse_buttons[16];
48 extern void (*adb_mouse_interrupt_hook)(unsigned char *, int);
49 extern int adb_emulate_buttons;
50 extern int adb_button2_keycode;
51 extern int adb_button3_keycode;
53 extern int console_loglevel;
56 * XXX: need to figure out what ADB mouse packets mean ...
57 * This is the stuff stolen from the Atari driver ...
59 static void adb_mouse_interrupt(unsigned char *buf, int nb)
61 int buttons, id;
64 Handler 1 -- 100cpi original Apple mouse protocol.
65 Handler 2 -- 200cpi original Apple mouse protocol.
67 For Apple's standard one-button mouse protocol the data array will
68 contain the following values:
70 BITS COMMENTS
71 data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
72 data[1] = bxxx xxxx First button and x-axis motion.
73 data[2] = byyy yyyy Second button and y-axis motion.
75 Handler 4 -- Apple Extended mouse protocol.
77 For Apple's 3-button mouse protocol the data array will contain the
78 following values:
80 BITS COMMENTS
81 data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
82 data[1] = bxxx xxxx Left button and x-axis motion.
83 data[2] = byyy yyyy Second button and y-axis motion.
84 data[3] = byyy bxxx Third button and fourth button.
85 Y is additional high bits of y-axis motion.
86 X is additional high bits of x-axis motion.
88 This procedure also gets called from the keyboard code if we
89 are emulating mouse buttons with keys. In this case data[0] == 0
90 (data[0] cannot be 0 for a real ADB packet).
92 'buttons' here means 'button down' states!
93 Button 1 (left) : bit 2, busmouse button 3
94 Button 2 (middle): bit 1, busmouse button 2
95 Button 3 (right) : bit 0, busmouse button 1
98 /* x/y and buttons swapped */
100 if (console_loglevel >= 8)
101 printk("KERN_DEBUG adb_mouse: %s data; ", buf[0]? "real": "fake");
103 id = (buf[0] >> 4) & 0xf;
104 buttons = adb_mouse_buttons[id];
106 /* button 1 (left, bit 2) */
107 buttons = (buttons&3) | (buf[1] & 0x80 ? 4 : 0); /* 1+2 unchanged */
109 /* button 2 (middle) */
110 buttons = (buttons&5) | (buf[2] & 0x80 ? 2 : 0); /* 2+3 unchanged */
112 /* button 3 (right) present?
113 * on a logitech mouseman, the right and mid buttons sometimes behave
114 * strangely until they both have been pressed after booting. */
115 /* data valid only if extended mouse format ! */
116 if (nb >= 4)
117 buttons = (buttons&6) | (buf[3] & 0x80 ? 1 : 0); /* 1+3 unchanged */
119 add_mouse_randomness(((~buttons&7) << 16) + ((buf[2]&0x7f) << 8) + (buf[1]&0x7f));
121 adb_mouse_buttons[id] = buttons;
122 /* a button is down if it is down on any mouse */
123 for (id = 0; id < 16; ++id)
124 buttons &= adb_mouse_buttons[id];
126 mouse.buttons = buttons;
127 mouse.dx += ((buf[2]&0x7f) < 64 ? (buf[2]&0x7f) : (buf[2]&0x7f)-128 );
128 mouse.dy -= ((buf[1]&0x7f) < 64 ? (buf[1]&0x7f) : (buf[1]&0x7f)-128 );
130 if (console_loglevel >= 8)
131 printk(" %X %X %X buttons %x dx %d dy %d \n",
132 buf[1], buf[2], buf[3], mouse.buttons, mouse.dx, mouse.dy);
134 mouse.ready = 1;
135 wake_up_interruptible(&mouse.wait);
136 if (mouse.fasyncptr)
137 kill_fasync(mouse.fasyncptr, SIGIO);
140 static int fasync_mouse(int fd, struct file *filp, int on)
142 int retval;
144 retval = fasync_helper(fd, filp, on, &mouse.fasyncptr);
145 if (retval < 0)
146 return retval;
147 return 0;
150 static int release_mouse(struct inode *inode, struct file *file)
152 fasync_mouse(-1, file, 0);
153 if (--mouse.active)
154 return 0;
156 adb_mouse_interrupt_hook = NULL;
157 MOD_DEC_USE_COUNT;
158 return 0;
161 static int open_mouse(struct inode *inode, struct file *file)
163 int id;
165 if (mouse.active++)
166 return 0;
168 mouse.ready = 0;
170 mouse.dx = mouse.dy = 0;
171 for (id = 0; id < 16; ++id)
172 adb_mouse_buttons[id] = 7; /* all buttons up */
173 MOD_INC_USE_COUNT;
174 adb_mouse_interrupt_hook = adb_mouse_interrupt;
175 return 0;
178 static ssize_t write_mouse(struct file *file, const char *buffer,
179 size_t count, loff_t *ppos)
181 return -EINVAL;
184 static ssize_t read_mouse(struct file *file, char *buffer, size_t count,
185 loff_t *ppos)
187 int dx, dy, buttons;
189 if (count < 3)
190 return -EINVAL;
191 if (!mouse.ready)
192 return -EAGAIN;
193 dx = mouse.dx;
194 dy = mouse.dy;
195 buttons = mouse.buttons;
196 if (dx > 127)
197 dx = 127;
198 else if (dx < -128)
199 dx = -128;
200 if (dy > 127)
201 dy = 127;
202 else if (dy < -128)
203 dy = -128;
204 mouse.dx -= dx;
205 mouse.dy -= dy;
206 if (mouse.dx == 0 && mouse.dy == 0)
207 mouse.ready = 0;
208 if (put_user(buttons | 0x80, buffer++) ||
209 put_user((char) dx, buffer++) ||
210 put_user((char) dy, buffer++))
211 return -EFAULT;
212 if (count > 3)
213 if (clear_user(buffer, count - 3))
214 return -EFAULT;
215 return count;
218 static unsigned int mouse_poll(struct file *file, poll_table *wait)
220 poll_wait(file, &mouse.wait, wait);
221 if (mouse.ready)
222 return POLLIN | POLLRDNORM;
223 return 0;
226 struct file_operations adb_mouse_fops = {
227 NULL, /* mouse_seek */
228 read_mouse,
229 write_mouse,
230 NULL, /* mouse_readdir */
231 mouse_poll,
232 NULL, /* mouse_ioctl */
233 NULL, /* mouse_mmap */
234 open_mouse,
235 NULL, /* flush */
236 release_mouse,
237 NULL,
238 fasync_mouse,
241 #define ADB_MOUSE_MINOR 10
243 static struct miscdevice adb_mouse = {
244 ADB_MOUSE_MINOR, "adbmouse", &adb_mouse_fops
247 __initfunc(int adb_mouse_init(void))
249 mouse.active = 0;
250 mouse.ready = 0;
251 init_waitqueue_head(&mouse.wait);
253 #ifdef __powerpc__
254 if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
255 return -ENODEV;
256 #endif
257 #ifdef __mc68000__
258 if (!MACH_IS_MAC)
259 return -ENODEV;
260 #endif
261 printk(KERN_INFO "Macintosh ADB mouse driver installed.\n");
262 misc_register(&adb_mouse);
263 return 0;
268 * XXX this function is misnamed.
269 * It is called if the kernel is booted with the adb_buttons=xxx
270 * option, which is about using ADB keyboard buttons to emulate
271 * mouse buttons. -- paulus
273 __initfunc(void adb_mouse_setup(char *str, int *ints))
275 if (ints[0] >= 1) {
276 adb_emulate_buttons = ints[1] > 0;
277 if (ints[1] > 1)
278 adb_button2_keycode = ints[1];
279 if (ints[0] >= 2)
280 adb_button3_keycode = ints[2];
284 #ifdef MODULE
285 #include <asm/setup.h>
287 int init_module(void)
289 return adb_mouse_init();
292 void cleanup_module(void)
294 misc_deregister(&adb_mouse);
296 #endif