OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [char/] [amigamouse.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 * Amiga Mouse Driver for Linux 68k by Michael Rausch
3
 * based upon:
4
 *
5
 * Logitech Bus Mouse Driver for Linux
6
 * by James Banks
7
 *
8
 * Mods by Matthew Dillon
9
 *   calls verify_area()
10
 *   tracks better when X is busy or paging
11
 *
12
 * Heavily modified by David Giller
13
 *   changed from queue- to counter- driven
14
 *   hacked out a (probably incorrect) mouse_select
15
 *
16
 * Modified again by Nathan Laredo to interface with
17
 *   0.96c-pl1 IRQ handling changes (13JUL92)
18
 *   didn't bother touching select code.
19
 *
20
 * Modified the select() code blindly to conform to the VFS
21
 *   requirements. 92.07.14 - Linus. Somebody should test it out.
22
 *
23
 * Modified by Johan Myreen to make room for other mice (9AUG92)
24
 *   removed assignment chr_fops[10] = &mouse_fops; see mouse.c
25
 *   renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public.
26
 *   renamed this file mouse.c => busmouse.c
27
 *
28
 * Modified for use in the 1.3 kernels by Jes Sorensen.
29
 */
30
 
31
#include <linux/module.h>
32
 
33
#include <linux/types.h>
34
#include <linux/kernel.h>
35
#include <linux/sched.h>
36
#include <linux/mm.h>
37
#include <linux/signal.h>
38
#include <linux/errno.h>
39
#include <linux/miscdevice.h>
40
#include <linux/random.h>
41
 
42
#include <asm/system.h>
43
#include <asm/segment.h>
44
#include <asm/irq.h>
45
#include <asm/amigamouse.h>
46
#include <asm/amigahw.h>
47
#include <asm/amigaints.h>
48
#include <asm/bootinfo.h>
49
 
50
#define MSE_INT_ON()    mouseint_allowed = 1
51
#define MSE_INT_OFF()   mouseint_allowed = 0
52
 
53
 
54
static struct mouse_status mouse;
55
 
56
static int mouseint_allowed;
57
 
58
static void mouse_interrupt(int irq, struct pt_regs *fp, void *dummy)
59
{
60
        static int lastx=0, lasty=0;
61
        int dx, dy;
62
        int nx, ny;
63
        unsigned char buttons;
64
 
65
        unsigned short joy0dat, potgor;
66
 
67
        if(!mouseint_allowed)
68
                return;
69
        MSE_INT_OFF();
70
 
71
        /*
72
         *  This routine assumes, just like Kickstart, that the mouse
73
         *  has not moved more than 127 ticks since last VBL.
74
         */
75
 
76
        joy0dat = custom.joy0dat;
77
 
78
        nx = joy0dat & 0xff;
79
        ny = joy0dat >> 8;
80
 
81
        dx = nx - lastx;
82
        if (dx < - 127)
83
                dx = (256 + nx) - lastx;
84
 
85
        if (dx > 127)
86
                dx = (nx - 256) - lastx;
87
 
88
        dy = ny - lasty;
89
        if (dy < - 127)
90
                dy = (256 + ny) - lasty;
91
 
92
        if (dy > 127)
93
                dy = (ny - 256) - lasty;
94
 
95
        lastx = nx;
96
        lasty = ny;
97
 
98
#if 0
99
        dx = -lastdx;
100
        dx += (lastdx = joy0dat & 0xff);
101
        if (dx < -127)
102
            dx = -255-dx;               /* underrun */
103
        else
104
        if (dx > 127)
105
            dx = 255-dx;                /* overflow */
106
 
107
        dy = -lastdy;
108
        dy += (lastdy = joy0dat >> 8);
109
        if (dy < -127)
110
            dy = -255-dy;
111
        else
112
        if (dy > 127)
113
            dy = 255-dy;
114
#endif
115
 
116
 
117
        potgor = custom.potgor;
118
        buttons = (ciaa.pra & 0x40 ? 4 : 0) |    /* left button; note that the bits are low-active, as are the expected results -> double negation */
119
#if 1
120
                  (potgor & 0x0100 ? 2 : 0) |    /* middle button; emulation goes here */
121
#endif
122
                  (potgor & 0x0400 ? 1 : 0);     /* right button */
123
 
124
 
125
        if (dx != 0 || dy != 0 || buttons != mouse.buttons) {
126
          add_mouse_randomness((buttons << 16) + (dy << 8) + dx);
127
          mouse.buttons = buttons;
128
          mouse.dx += dx;
129
          mouse.dy -= dy;
130
          mouse.ready = 1;
131
          wake_up_interruptible(&mouse.wait);
132
 
133
          /*
134
           * keep dx/dy reasonable, but still able to track when X (or
135
           * whatever) must page or is busy (i.e. long waits between
136
           * reads)
137
           */
138
          if (mouse.dx < -2048)
139
              mouse.dx = -2048;
140
          else
141
          if (mouse.dx >  2048)
142
              mouse.dx =  2048;
143
 
144
          if (mouse.dy < -2048)
145
              mouse.dy = -2048;
146
          else
147
          if (mouse.dy >  2048)
148
              mouse.dy =  2048;
149
 
150
          if (mouse.fasyncptr)
151
              kill_fasync(mouse.fasyncptr, SIGIO);
152
        }
153
        MSE_INT_ON();
154
}
155
 
156
static int fasync_mouse(struct inode *inode, struct file *filp, int on)
157
{
158
        int retval;
159
 
160
        retval = fasync_helper(inode, filp, on, &mouse.fasyncptr);
161
        if (retval < 0)
162
                return retval;
163
        return 0;
164
}
165
 
166
/*
167
 * close access to the mouse
168
 */
169
 
170
static void close_mouse(struct inode * inode, struct file * file)
171
{
172
        fasync_mouse(inode, file, 0);
173
        if (--mouse.active)
174
          return;
175
        MSE_INT_OFF();
176
        MOD_DEC_USE_COUNT;
177
}
178
 
179
/*
180
 * open access to the mouse, currently only one open is
181
 * allowed.
182
 */
183
 
184
static int open_mouse(struct inode * inode, struct file * file)
185
{
186
  if (!mouse.present)
187
    return -EINVAL;
188
  if (mouse.active++)
189
    return 0;
190
  mouse.ready = 0;
191
  mouse.dx = 0;
192
  mouse.dy = 0;
193
  mouse.buttons = 0x87;
194
  mouse.active = 1;
195
  MOD_INC_USE_COUNT;
196
  MSE_INT_ON();
197
  return 0;
198
}
199
 
200
/*
201
 * writes are disallowed
202
 */
203
 
204
static int write_mouse(struct inode * inode, struct file * file, const char * buffer, int count)
205
{
206
        return -EINVAL;
207
}
208
 
209
/*
210
 * read mouse data.  Currently never blocks.
211
 */
212
 
213
static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
214
{
215
        int r;
216
        int dx;
217
        int dy;
218
        unsigned char buttons;
219
 
220
        if (count < 3)
221
                return -EINVAL;
222
        if ((r = verify_area(VERIFY_WRITE, buffer, count)))
223
                return r;
224
        if (!mouse.ready)
225
                return -EAGAIN;
226
 
227
        /*
228
         * Obtain the current mouse parameters and limit as appropriate for
229
         * the return data format.  Interrupts are only disabled while
230
         * obtaining the parameters, NOT during the puts_fs_byte() calls,
231
         * so paging in put_fs_byte() does not effect mouse tracking.
232
         */
233
 
234
        MSE_INT_OFF();
235
        dx = mouse.dx;
236
        dy = mouse.dy;
237
        if (dx < -127)
238
            dx = -127;
239
        else
240
        if (dx > 127)
241
            dx = 127;
242
        if (dy < -127)
243
            dy = -127;
244
        else
245
        if (dy > 127)
246
            dy = 127;
247
        buttons = mouse.buttons;
248
        mouse.dx -= dx;
249
        mouse.dy -= dy;
250
        mouse.ready = 0;
251
        MSE_INT_ON();
252
 
253
        put_fs_byte(buttons | 0x80, buffer);
254
        put_fs_byte((char)dx, buffer + 1);
255
        put_fs_byte((char)dy, buffer + 2);
256
        for (r = 3; r < count; r++)
257
            put_fs_byte(0x00, buffer + r);
258
        return r;
259
}
260
 
261
/*
262
 * select for mouse input
263
 */
264
 
265
static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
266
{
267
        if (sel_type == SEL_IN) {
268
                if (mouse.ready)
269
                        return 1;
270
                select_wait(&mouse.wait, wait);
271
        }
272
        return 0;
273
}
274
 
275
struct file_operations amiga_mouse_fops = {
276
        NULL,           /* mouse_seek */
277
        read_mouse,
278
        write_mouse,
279
        NULL,           /* mouse_readdir */
280
        mouse_select,   /* mouse_select */
281
        NULL,           /* mouse_ioctl */
282
        NULL,           /* mouse_mmap */
283
        open_mouse,
284
        close_mouse,
285
        NULL,
286
        fasync_mouse,
287
};
288
 
289
static struct miscdevice amiga_mouse = {
290
        AMIGAMOUSE_MINOR, "amigamouse", &amiga_mouse_fops
291
};
292
 
293
int amiga_mouse_init(void)
294
{
295
        if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE))
296
                return -ENODEV;
297
 
298
        custom.joytest = 0;      /* reset counters */
299
 
300
        MSE_INT_OFF();
301
 
302
        mouse.active = 0;
303
        mouse.ready = 0;
304
        mouse.buttons = 0x87;
305
        mouse.dx = 0;
306
        mouse.dy = 0;
307
        mouse.wait = NULL;
308
 
309
        /*
310
         *  use VBL to poll mouse deltas
311
         */
312
 
313
        if(!add_isr(IRQ_AMIGA_VERTB, mouse_interrupt, 0, NULL, "Amiga mouse"))
314
        {
315
                mouse.present = 0;
316
                printk(KERN_INFO "Installing Amiga mouse failed.\n");
317
                return -EIO;
318
        }
319
 
320
        mouse.present = 1;
321
 
322
        printk(KERN_INFO "Amiga mouse installed.\n");
323
        misc_register(&amiga_mouse);
324
        return 0;
325
}
326
 
327
#ifdef MODULE
328
#include <asm/bootinfo.h>
329
 
330
int init_module(void)
331
{
332
        return amiga_mouse_init();
333
}
334
 
335
void cleanup_module(void)
336
{
337
  remove_isr(IRQ_AMIGA_VERTB, mouse_interrupt, NULL);
338
  misc_deregister(&amiga_mouse);
339
}
340
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.