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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 * ATI XL Bus Mouse Driver for Linux
3
 * by Bob Harris (rth@sparta.com)
4
 *
5
 * Uses VFS interface for linux 0.98 (01OCT92)
6
 *
7
 * Modified by Chris Colohan (colohan@eecg.toronto.edu)
8
 * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
9
 *
10
 * version 0.3a
11
 */
12
 
13
#include <linux/module.h>
14
 
15
#include <linux/kernel.h>
16
#include <linux/sched.h>
17
#include <linux/signal.h>
18
#include <linux/errno.h>
19
#include <linux/miscdevice.h>
20
#include <linux/random.h>
21
 
22
#include <asm/io.h>
23
#include <asm/segment.h>
24
#include <asm/system.h>
25
#include <asm/irq.h>
26
 
27
#define ATIXL_MOUSE_IRQ         5 /* H/W interrupt # set up on ATIXL board */
28
#define ATIXL_BUSMOUSE          3 /* Minor device # (mknod c 10 3 /dev/bm) */
29
 
30
/* ATI XL Inport Busmouse Definitions */
31
 
32
#define ATIXL_MSE_DATA_PORT             0x23d
33
#define ATIXL_MSE_SIGNATURE_PORT        0x23e
34
#define ATIXL_MSE_CONTROL_PORT          0x23c
35
 
36
#define ATIXL_MSE_READ_BUTTONS          0x00
37
#define ATIXL_MSE_READ_X                0x01
38
#define ATIXL_MSE_READ_Y                0x02
39
 
40
/* Some nice ATI XL macros */
41
 
42
/* Select IR7, HOLD UPDATES (INT ENABLED), save X,Y */
43
#define ATIXL_MSE_DISABLE_UPDATE() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \
44
        outb( (0x20 | inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); }
45
 
46
/* Select IR7, Enable updates (INT ENABLED) */
47
#define ATIXL_MSE_ENABLE_UPDATE() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \
48
         outb( (0xdf & inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); }
49
 
50
/* Select IR7 - Mode Register, NO INTERRUPTS */
51
#define ATIXL_MSE_INT_OFF() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \
52
        outb( (0xe7 & inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); }
53
 
54
/* Select IR7 - Mode Register, DATA INTERRUPTS ENABLED */
55
#define ATIXL_MSE_INT_ON() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \
56
        outb( (0x08 | inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); }
57
 
58
/* Same general mouse structure */
59
 
60
static struct mouse_status {
61
        char buttons;
62
        char latch_buttons;
63
        int dx;
64
        int dy;
65
        int present;
66
        int ready;
67
        int active;
68
        struct wait_queue *wait;
69
        struct fasync_struct *fasync;
70
} mouse;
71
 
72
void mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs)
73
{
74
        char dx, dy, buttons;
75
 
76
        ATIXL_MSE_DISABLE_UPDATE(); /* Note that interrupts are still enabled */
77
        outb(ATIXL_MSE_READ_X, ATIXL_MSE_CONTROL_PORT); /* Select IR1 - X movement */
78
        dx = inb( ATIXL_MSE_DATA_PORT);
79
        outb(ATIXL_MSE_READ_Y, ATIXL_MSE_CONTROL_PORT); /* Select IR2 - Y movement */
80
        dy = inb( ATIXL_MSE_DATA_PORT);
81
        outb(ATIXL_MSE_READ_BUTTONS, ATIXL_MSE_CONTROL_PORT); /* Select IR0 - Button Status */
82
        buttons = inb( ATIXL_MSE_DATA_PORT);
83
        if (dx != 0 || dy != 0 || buttons != mouse.latch_buttons) {
84
                add_mouse_randomness((buttons << 16) + (dy << 8) + dx);
85
                mouse.latch_buttons |= buttons;
86
                mouse.dx += dx;
87
                mouse.dy += dy;
88
                mouse.ready = 1;
89
                wake_up_interruptible(&mouse.wait);
90
                if (mouse.fasync)
91
                        kill_fasync(mouse.fasync, SIGIO);
92
        }
93
        ATIXL_MSE_ENABLE_UPDATE();
94
}
95
 
96
static int fasync_mouse(struct inode *inode, struct file *filp, int on)
97
{
98
        int retval;
99
 
100
        retval = fasync_helper(inode, filp, on, &mouse.fasync);
101
        if (retval < 0)
102
                return retval;
103
        return 0;
104
}
105
 
106
static void release_mouse(struct inode * inode, struct file * file)
107
{
108
        fasync_mouse(inode, file, 0);
109
        if (--mouse.active)
110
                return;
111
        ATIXL_MSE_INT_OFF(); /* Interrupts are really shut down here */
112
        mouse.ready = 0;
113
        free_irq(ATIXL_MOUSE_IRQ, NULL);
114
        MOD_DEC_USE_COUNT;
115
}
116
 
117
static int open_mouse(struct inode * inode, struct file * file)
118
{
119
        if (!mouse.present)
120
                return -EINVAL;
121
        if (mouse.active++)
122
                return 0;
123
        if (request_irq(ATIXL_MOUSE_IRQ, mouse_interrupt, 0, "ATIXL mouse", NULL)) {
124
                mouse.active--;
125
                return -EBUSY;
126
        }
127
        mouse.ready = 0;
128
        mouse.dx = 0;
129
        mouse.dy = 0;
130
        mouse.buttons = mouse.latch_buttons = 0;
131
        ATIXL_MSE_INT_ON(); /* Interrupts are really enabled here */
132
        MOD_INC_USE_COUNT;
133
        return 0;
134
}
135
 
136
 
137
static int write_mouse(struct inode * inode, struct file * file, const char * buffer, int count)
138
{
139
        return -EINVAL;
140
}
141
 
142
static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
143
{
144
        int i;
145
 
146
        if (count < 3)
147
                return -EINVAL;
148
        if (!mouse.ready)
149
                return -EAGAIN;
150
        ATIXL_MSE_DISABLE_UPDATE();
151
        /* Allowed interrupts to occur during data gathering - shouldn't hurt */
152
        put_user((char)(~mouse.latch_buttons&7) | 0x80 , buffer);
153
        if (mouse.dx < -127)
154
                mouse.dx = -127;
155
        if (mouse.dx > 127)
156
                mouse.dx =  127;
157
        put_user((char)mouse.dx, buffer + 1);
158
        if (mouse.dy < -127)
159
                mouse.dy = -127;
160
        if (mouse.dy > 127)
161
                mouse.dy =  127;
162
        put_user((char)-mouse.dy, buffer + 2);
163
        for(i = 3; i < count; i++)
164
                put_user(0x00, buffer + i);
165
        mouse.dx = 0;
166
        mouse.dy = 0;
167
        mouse.latch_buttons = mouse.buttons;
168
        mouse.ready = 0;
169
        ATIXL_MSE_ENABLE_UPDATE();
170
        return i; /* i data bytes returned */
171
}
172
 
173
static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
174
{
175
        if (sel_type != SEL_IN)
176
                return 0;
177
        if (mouse.ready)
178
                return 1;
179
        select_wait(&mouse.wait,wait);
180
        return 0;
181
}
182
 
183
struct file_operations atixl_busmouse_fops = {
184
        NULL,           /* mouse_seek */
185
        read_mouse,
186
        write_mouse,
187
        NULL,           /* mouse_readdir */
188
        mouse_select,   /* mouse_select */
189
        NULL,           /* mouse_ioctl */
190
        NULL,           /* mouse_mmap */
191
        open_mouse,
192
        release_mouse,
193
        NULL,
194
        fasync_mouse,
195
};
196
 
197
static struct miscdevice atixl_mouse = {
198
        ATIXL_BUSMOUSE, "atixl", &atixl_busmouse_fops
199
};
200
 
201
 
202
int atixl_busmouse_init(void)
203
{
204
        unsigned char a,b,c;
205
 
206
        a = inb( ATIXL_MSE_SIGNATURE_PORT );    /* Get signature */
207
        b = inb( ATIXL_MSE_SIGNATURE_PORT );
208
        c = inb( ATIXL_MSE_SIGNATURE_PORT );
209
        if (( a != b ) && ( a == c ))
210
                printk(KERN_INFO "\nATI Inport ");
211
        else{
212
                mouse.present = 0;
213
                return -EIO;
214
        }
215
        outb(0x80, ATIXL_MSE_CONTROL_PORT);     /* Reset the Inport device */
216
        outb(0x07, ATIXL_MSE_CONTROL_PORT);     /* Select Internal Register 7 */
217
        outb(0x0a, ATIXL_MSE_DATA_PORT);        /* Data Interrupts 8+, 1=30hz, 2=50hz, 3=100hz, 4=200hz rate */
218
        mouse.present = 1;
219
        mouse.active = 0;
220
        mouse.ready = 0;
221
        mouse.buttons = mouse.latch_buttons = 0;
222
        mouse.dx = mouse.dy = 0;
223
        mouse.wait = NULL;
224
        printk("Bus mouse detected and installed.\n");
225
        misc_register(&atixl_mouse);
226
        return 0;
227
}
228
 
229
#ifdef MODULE
230
 
231
int init_module(void)
232
{
233
        return atixl_busmouse_init();
234
}
235
 
236
void cleanup_module(void)
237
{
238
        misc_deregister(&atixl_mouse);
239
}
240
#endif

powered by: WebSVN 2.1.0

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