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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 * Microsoft busmouse driver based on Logitech driver (see busmouse.c)
3
 *
4
 * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92)
5
 *
6
 * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net)
7
 *    8/28/92
8
 *
9
 * Microsoft Bus Mouse support folded into 0.97pl4 code
10
 *    by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
11
 * Changes:  Logitech and Microsoft support in the same kernel.
12
 *           Defined new constants in busmouse.h for MS mice.
13
 *           Added int mse_busmouse_type to distinguish busmouse types
14
 *           Added a couple of new functions to handle differences in using
15
 *             MS vs. Logitech (where the int variable wasn't appropriate).
16
 *
17
 * Modified by Peter Cervasio (address above) (26SEP92)
18
 * Changes:  Included code to (properly?) detect when a Microsoft mouse is
19
 *           really attached to the machine.  Don't know what this does to
20
 *           Logitech bus mice, but all it does is read ports.
21
 *
22
 * Modified by Christoph Niemann (niemann@rubdv15.etdv.ruhr-uni-bochum.de)
23
 * Changes:  Better interrupt-handler (like in busmouse.c).
24
 *           Some changes to reduce code-size.
25
 *           Changed detection code to use inb_p() instead of doing empty
26
 *           loops to delay i/o.
27
 *
28
 * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
29
 *
30
 * version 0.3b
31
 */
32
 
33
#include <linux/module.h>
34
 
35
#include <linux/kernel.h>
36
#include <linux/ioport.h>
37
#include <linux/sched.h>
38
#include <linux/busmouse.h>
39
#include <linux/signal.h>
40
#include <linux/errno.h>
41
#include <linux/miscdevice.h>
42
#include <linux/random.h>
43
 
44
#include <asm/io.h>
45
#include <asm/segment.h>
46
#include <asm/system.h>
47
#include <asm/irq.h>
48
 
49
static struct mouse_status mouse;
50
static int mouse_irq = MOUSE_IRQ;
51
 
52
void msmouse_setup(char *str, int *ints)
53
{
54
        if (ints[0] > 0)
55
                mouse_irq=ints[1];
56
}
57
 
58
static void ms_mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs)
59
{
60
        char dx, dy;
61
        unsigned char buttons;
62
 
63
        outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
64
        outb((inb(MS_MSE_DATA_PORT) | 0x20), MS_MSE_DATA_PORT);
65
 
66
        outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT);
67
        dx = inb(MS_MSE_DATA_PORT);
68
 
69
        outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT);
70
        dy = inb(MS_MSE_DATA_PORT);
71
 
72
        outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT);
73
        buttons = ~(inb(MS_MSE_DATA_PORT)) & 0x07;
74
 
75
        outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
76
        outb((inb(MS_MSE_DATA_PORT) & 0xdf), MS_MSE_DATA_PORT);
77
 
78
        if (dx != 0 || dy != 0 || buttons != mouse.buttons || ((~buttons) & 0x07)) {
79
                add_mouse_randomness((buttons << 16) + (dy << 8) + dx);
80
                mouse.buttons = buttons;
81
                mouse.dx += dx;
82
                mouse.dy += dy;
83
                mouse.ready = 1;
84
                wake_up_interruptible(&mouse.wait);
85
                if (mouse.fasyncptr)
86
                        kill_fasync(mouse.fasyncptr, SIGIO);
87
        }
88
}
89
 
90
static int fasync_mouse(struct inode *inode, struct file *filp, int on)
91
{
92
        int retval;
93
 
94
        retval = fasync_helper(inode, filp, on, &mouse.fasyncptr);
95
        if (retval < 0)
96
                return retval;
97
        return 0;
98
}
99
 
100
static void release_mouse(struct inode * inode, struct file * file)
101
{
102
        fasync_mouse(inode, file, 0);
103
        if (--mouse.active)
104
                return;
105
        MS_MSE_INT_OFF();
106
        mouse.ready = 0;
107
        free_irq(mouse_irq, NULL);
108
        MOD_DEC_USE_COUNT;
109
}
110
 
111
static int open_mouse(struct inode * inode, struct file * file)
112
{
113
        if (!mouse.present)
114
                return -EINVAL;
115
        if (mouse.active++)
116
                return 0;
117
        if (request_irq(mouse_irq, ms_mouse_interrupt, 0, "MS Busmouse", NULL)) {
118
                mouse.active--;
119
                return -EBUSY;
120
        }
121
        mouse.ready = mouse.dx = mouse.dy = 0;
122
        mouse.buttons = 0x80;
123
        outb(MS_MSE_START, MS_MSE_CONTROL_PORT);
124
        MOD_INC_USE_COUNT;
125
        MS_MSE_INT_ON();
126
        return 0;
127
}
128
 
129
 
130
static int write_mouse(struct inode * inode, struct file * file, const char * buffer, int count)
131
{
132
        return -EINVAL;
133
}
134
 
135
static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
136
{
137
        int i, dx, dy;
138
 
139
        if (count < 3)
140
                return -EINVAL;
141
        if (!mouse.ready)
142
                return -EAGAIN;
143
        put_user(mouse.buttons | 0x80, buffer);
144
        dx = mouse.dx < -127 ? -127 : mouse.dx > 127 ?  127 :  mouse.dx;
145
        dy = mouse.dy < -127 ?  127 : mouse.dy > 127 ? -127 : -mouse.dy;
146
        put_user((char)dx, buffer + 1);
147
        put_user((char)dy, buffer + 2);
148
        for (i = 3; i < count; i++)
149
                put_user(0x00, buffer + i);
150
        mouse.dx -= dx;
151
        mouse.dy += dy;
152
        mouse.ready = 0;
153
        return i;
154
}
155
 
156
static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
157
{
158
        if (sel_type != SEL_IN)
159
                return 0;
160
        if (mouse.ready)
161
                return 1;
162
        select_wait(&mouse.wait,wait);
163
        return 0;
164
}
165
 
166
struct file_operations ms_bus_mouse_fops = {
167
        NULL,           /* mouse_seek */
168
        read_mouse,
169
        write_mouse,
170
        NULL,           /* mouse_readdir */
171
        mouse_select,   /* mouse_select */
172
        NULL,           /* mouse_ioctl */
173
        NULL,           /* mouse_mmap */
174
        open_mouse,
175
        release_mouse,
176
        NULL,
177
        fasync_mouse,
178
};
179
 
180
static struct miscdevice ms_bus_mouse = {
181
        MICROSOFT_BUSMOUSE, "msbusmouse", &ms_bus_mouse_fops
182
};
183
 
184
int ms_bus_mouse_init(void)
185
{
186
        int mse_byte, i;
187
 
188
        mouse.present = mouse.active = mouse.ready = 0;
189
        mouse.buttons = 0x80;
190
        mouse.dx = mouse.dy = 0;
191
        mouse.wait = NULL;
192
 
193
        if (check_region(MS_MSE_CONTROL_PORT, 0x04))
194
                return -ENODEV;
195
 
196
        if (inb_p(MS_MSE_SIGNATURE_PORT) == 0xde) {
197
 
198
                mse_byte = inb_p(MS_MSE_SIGNATURE_PORT);
199
 
200
                for (i = 0; i < 4; i++) {
201
                        if (inb_p(MS_MSE_SIGNATURE_PORT) == 0xde) {
202
                                if (inb_p(MS_MSE_SIGNATURE_PORT) == mse_byte)
203
                                        mouse.present = 1;
204
                                else
205
                                        mouse.present = 0;
206
                        } else
207
                                mouse.present = 0;
208
                }
209
        }
210
        if (mouse.present == 0)
211
                return -EIO;
212
        MS_MSE_INT_OFF();
213
        request_region(MS_MSE_CONTROL_PORT, 0x04, "MS Busmouse");
214
        printk(KERN_INFO "Microsoft BusMouse detected and installed.\n");
215
        misc_register(&ms_bus_mouse);
216
        return 0;
217
}
218
 
219
#ifdef MODULE
220
int init_module(void)
221
{
222
        return ms_bus_mouse_init();
223
}
224
 
225
void cleanup_module(void)
226
{
227
        misc_deregister(&ms_bus_mouse);
228
        release_region(MS_MSE_CONTROL_PORT, 0x04);
229
}
230
#endif
231
 

powered by: WebSVN 2.1.0

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