Import 2.1.118
[davej-history.git] / drivers / char / atarimouse.c
blob33d71d3769d44e8ddbc09ba7f56ae55817e4caaa
1 /*
2 * Atari Mouse Driver for Linux
3 * by Robert de Vries (robert@and.nl) 19Jul93
5 * 16 Nov 1994 Andreas Schwab
6 * Compatibility with busmouse
7 * Support for three button mouse (shamelessly stolen from MiNT)
8 * third button wired to one of the joystick directions on joystick 1
10 * 1996/02/11 Andreas Schwab
11 * Module support
12 * Allow multiple open's
15 #include <linux/module.h>
17 #include <linux/sched.h>
18 #include <linux/errno.h>
19 #include <linux/miscdevice.h>
20 #include <linux/mm.h>
21 #include <linux/random.h>
22 #include <linux/poll.h>
23 #include <linux/init.h>
24 #include <linux/busmouse.h>
26 #include <asm/setup.h>
27 #include <asm/atarikb.h>
28 #include <asm/uaccess.h>
30 static struct mouse_status mouse;
31 static int mouse_threshold[2] = {2,2};
32 MODULE_PARM(mouse_threshold, "2i");
33 extern int atari_mouse_buttons;
35 static void atari_mouse_interrupt(char *buf)
37 int buttons;
39 /* ikbd_mouse_disable(); */
41 buttons = ((buf[0] & 1 ? 1 : 0)
42 | (buf[0] & 2 ? 4 : 0)
43 | (atari_mouse_buttons & 2));
44 atari_mouse_buttons = buttons;
45 add_mouse_randomness((buttons << 16) + (buf[2] << 8) + buf[1]);
46 mouse.buttons = ~buttons & 7;
47 mouse.dx += buf[1];
48 mouse.dy -= buf[2];
49 mouse.ready = 1;
50 wake_up_interruptible(&mouse.wait);
51 if (mouse.fasyncptr)
52 kill_fasync(mouse.fasyncptr, SIGIO);
54 /* ikbd_mouse_rel_pos(); */
57 static int fasync_mouse(int fd, struct file *filp, int on)
59 int retval;
60 retval = fasync_helper(fd, filp, on, &mouse.fasyncptr);
61 if (retval < 0)
62 return retval;
63 return 0;
66 static int release_mouse(struct inode *inode, struct file *file)
68 fasync_mouse(-1, file, 0);
69 if (--mouse.active)
70 return 0;
71 ikbd_mouse_disable();
73 atari_mouse_interrupt_hook = NULL;
74 MOD_DEC_USE_COUNT;
75 return 0;
78 static int open_mouse(struct inode *inode, struct file *file)
80 if (mouse.active++)
81 return 0;
82 mouse.ready = 0;
83 mouse.dx = mouse.dy = 0;
84 atari_mouse_buttons = 0;
85 ikbd_mouse_y0_top ();
86 ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]);
87 ikbd_mouse_rel_pos();
88 MOD_INC_USE_COUNT;
89 atari_mouse_interrupt_hook = atari_mouse_interrupt;
90 return 0;
93 static ssize_t write_mouse(struct file *file, const char *buffer,
94 size_t count, loff_t *ppos)
96 return -EINVAL;
99 static ssize_t read_mouse(struct file * file, char * buffer,
100 size_t count, loff_t *ppos)
102 int dx, dy, buttons;
104 if (count < 3)
105 return -EINVAL;
106 if (!mouse.ready)
107 return -EAGAIN;
108 /* ikbd_mouse_disable */
109 dx = mouse.dx;
110 dy = mouse.dy;
111 buttons = mouse.buttons;
112 if (dx > 127)
113 dx = 127;
114 else if (dx < -128)
115 dx = -128;
116 if (dy > 127)
117 dy = 127;
118 else if (dy < -128)
119 dy = -128;
120 mouse.dx -= dx;
121 mouse.dy -= dy;
122 if (mouse.dx == 0 && mouse.dy == 0)
123 mouse.ready = 0;
124 /* ikbd_mouse_rel_pos(); */
125 if (put_user(buttons | 0x80, buffer++) ||
126 put_user((char) dx, buffer++) ||
127 put_user((char) dy, buffer++))
128 return -EFAULT;
129 if (count > 3)
130 if (clear_user(buffer, count - 3))
131 return -EFAULT;
132 return count;
135 static unsigned int mouse_poll(struct file *file, poll_table *wait)
137 poll_wait(file, &mouse.wait, wait);
138 if (mouse.ready)
139 return POLLIN | POLLRDNORM;
140 return 0;
143 struct file_operations atari_mouse_fops = {
144 NULL, /* mouse_seek */
145 read_mouse,
146 write_mouse,
147 NULL, /* mouse_readdir */
148 mouse_poll,
149 NULL, /* mouse_ioctl */
150 NULL, /* mouse_mmap */
151 open_mouse,
152 NULL, /* flush */
153 release_mouse,
154 NULL,
155 fasync_mouse,
158 static struct miscdevice atari_mouse = {
159 ATARIMOUSE_MINOR, "atarimouse", &atari_mouse_fops
162 __initfunc(int atari_mouse_init(void))
164 int r;
166 if (!MACH_IS_ATARI)
167 return -ENODEV;
169 mouse.active = 0;
170 mouse.ready = 0;
171 mouse.wait = NULL;
173 r = misc_register(&atari_mouse);
174 if (r)
175 return r;
177 printk(KERN_INFO "Atari mouse installed.\n");
178 return 0;
182 #define MIN_THRESHOLD 1
183 #define MAX_THRESHOLD 20 /* more seems not reasonable... */
185 __initfunc(void atari_mouse_setup( char *str, int *ints ))
187 if (ints[0] < 1) {
188 printk( "atari_mouse_setup: no arguments!\n" );
189 return;
191 else if (ints[0] > 2) {
192 printk( "atari_mouse_setup: too many arguments\n" );
195 if (ints[1] < MIN_THRESHOLD || ints[1] > MAX_THRESHOLD)
196 printk( "atari_mouse_setup: bad threshold value (ignored)\n" );
197 else {
198 mouse_threshold[0] = ints[1];
199 mouse_threshold[1] = ints[1];
200 if (ints[0] > 1) {
201 if (ints[2] < MIN_THRESHOLD || ints[2] > MAX_THRESHOLD)
202 printk("atari_mouse_setup: bad threshold value (ignored)\n" );
203 else
204 mouse_threshold[1] = ints[2];
210 #ifdef MODULE
211 int init_module(void)
213 return atari_mouse_init();
216 void cleanup_module(void)
218 misc_deregister(&atari_mouse);
220 #endif