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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [joystick/] [lightning.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * $Id: lightning.c,v 1.1.1.1 2004-04-15 02:03:27 phoenix Exp $
3
 *
4
 *  Copyright (c) 1998-2001 Vojtech Pavlik
5
 *
6
 *  Sponsored by SuSE
7
 */
8
 
9
/*
10
 * PDPI Lightning 4 gamecard driver for Linux.
11
 */
12
 
13
/*
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
 *
28
 * Should you need to contact me, the author, you can do so either by
29
 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
30
 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
31
 */
32
 
33
#include <asm/io.h>
34
#include <linux/delay.h>
35
#include <linux/errno.h>
36
#include <linux/ioport.h>
37
#include <linux/kernel.h>
38
#include <linux/module.h>
39
#include <linux/init.h>
40
#include <linux/gameport.h>
41
#include <linux/slab.h>
42
 
43
#define L4_PORT                 0x201
44
#define L4_SELECT_ANALOG        0xa4
45
#define L4_SELECT_DIGITAL       0xa5
46
#define L4_SELECT_SECONDARY     0xa6
47
#define L4_CMD_ID               0x80
48
#define L4_CMD_GETCAL           0x92
49
#define L4_CMD_SETCAL           0x93
50
#define L4_ID                   0x04
51
#define L4_BUSY                 0x01
52
#define L4_TIMEOUT              80      /* 80 us */
53
 
54
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
55
MODULE_LICENSE("GPL");
56
 
57
struct l4 {
58
        struct gameport gameport;
59
        unsigned char port;
60
} *l4_port[8];
61
 
62
/*
63
 * l4_wait_ready() waits for the L4 to become ready.
64
 */
65
 
66
static int l4_wait_ready(void)
67
{
68
        unsigned int t;
69
        t = L4_TIMEOUT;
70
        while ((inb(L4_PORT) & L4_BUSY) && t > 0) t--;
71
        return -(t<=0);
72
}
73
 
74
/*
75
 * l4_cooked_read() reads data from the Lightning 4.
76
 */
77
 
78
static int l4_cooked_read(struct gameport *gameport, int *axes, int *buttons)
79
{
80
        struct l4 *l4 = gameport->driver;
81
        unsigned char status;
82
        int i, result = -1;
83
 
84
        outb(L4_SELECT_ANALOG, L4_PORT);
85
        outb(L4_SELECT_DIGITAL + (l4->port >> 2), L4_PORT);
86
 
87
        if (inb(L4_PORT) & L4_BUSY) goto fail;
88
        outb(l4->port & 3, L4_PORT);
89
 
90
        if (l4_wait_ready()) goto fail;
91
        status = inb(L4_PORT);
92
 
93
        for (i = 0; i < 4; i++)
94
                if (status & (1 << i)) {
95
                        if (l4_wait_ready()) goto fail;
96
                        axes[i] = inb(L4_PORT);
97
                        if (axes[i] > 252) axes[i] = -1;
98
                }
99
 
100
        if (status & 0x10) {
101
                if (l4_wait_ready()) goto fail;
102
                *buttons = inb(L4_PORT) & 0x0f;
103
        }
104
 
105
        result = 0;
106
 
107
fail:   outb(L4_SELECT_ANALOG, L4_PORT);
108
        return result;
109
}
110
 
111
static int l4_open(struct gameport *gameport, int mode)
112
{
113
        struct l4 *l4 = gameport->driver;
114
        if (l4->port != 0 && mode != GAMEPORT_MODE_COOKED)
115
                return -1;
116
        outb(L4_SELECT_ANALOG, L4_PORT);
117
        return 0;
118
}
119
 
120
/*
121
 * l4_getcal() reads the L4 with calibration values.
122
 */
123
 
124
static int l4_getcal(int port, int *cal)
125
{
126
        int i, result = -1;
127
 
128
        outb(L4_SELECT_ANALOG, L4_PORT);
129
        outb(L4_SELECT_DIGITAL + (port >> 2), L4_PORT);
130
 
131
        if (inb(L4_PORT) & L4_BUSY) goto fail;
132
        outb(L4_CMD_GETCAL, L4_PORT);
133
 
134
        if (l4_wait_ready()) goto fail;
135
        if (inb(L4_PORT) != L4_SELECT_DIGITAL + (port >> 2)) goto fail;
136
 
137
        if (l4_wait_ready()) goto fail;
138
        outb(port & 3, L4_PORT);
139
 
140
        for (i = 0; i < 4; i++) {
141
                if (l4_wait_ready()) goto fail;
142
                cal[i] = inb(L4_PORT);
143
        }
144
 
145
        result = 0;
146
 
147
fail:   outb(L4_SELECT_ANALOG, L4_PORT);
148
        return result;
149
}
150
 
151
/*
152
 * l4_setcal() programs the L4 with calibration values.
153
 */
154
 
155
static int l4_setcal(int port, int *cal)
156
{
157
        int i, result = -1;
158
 
159
        outb(L4_SELECT_ANALOG, L4_PORT);
160
        outb(L4_SELECT_DIGITAL + (port >> 2), L4_PORT);
161
 
162
        if (inb(L4_PORT) & L4_BUSY) goto fail;
163
        outb(L4_CMD_SETCAL, L4_PORT);
164
 
165
        if (l4_wait_ready()) goto fail;
166
        if (inb(L4_PORT) != L4_SELECT_DIGITAL + (port >> 2)) goto fail;
167
 
168
        if (l4_wait_ready()) goto fail;
169
        outb(port & 3, L4_PORT);
170
 
171
        for (i = 0; i < 4; i++) {
172
                if (l4_wait_ready()) goto fail;
173
                outb(cal[i], L4_PORT);
174
        }
175
 
176
        result = 0;
177
 
178
fail:   outb(L4_SELECT_ANALOG, L4_PORT);
179
        return result;
180
}
181
 
182
/*
183
 * l4_calibrate() calibrates the L4 for the attached device, so
184
 * that the device's resistance fits into the L4's 8-bit range.
185
 */
186
 
187
static int l4_calibrate(struct gameport *gameport, int *axes, int *max)
188
{
189
        int i, t;
190
        int cal[4];
191
        struct l4 *l4 = gameport->driver;
192
 
193
        if (l4_getcal(l4->port, cal))
194
                return -1;
195
 
196
        for (i = 0; i < 4; i++) {
197
                t = (max[i] * cal[i]) / 200;
198
                t = (t < 1) ? 1 : ((t > 255) ? 255 : t);
199
                axes[i] = (axes[i] < 0) ? -1 : (axes[i] * cal[i]) / t;
200
                axes[i] = (axes[i] > 252) ? 252 : axes[i];
201
                cal[i] = t;
202
        }
203
 
204
        if (l4_setcal(l4->port, cal))
205
                return -1;
206
 
207
        return 0;
208
}
209
 
210
int __init l4_init(void)
211
{
212
        int cal[4] = {255,255,255,255};
213
        int i, j, rev, cards = 0;
214
        struct gameport *gameport;
215
        struct l4 *l4;
216
 
217
        if (!request_region(L4_PORT, 1, "lightning"))
218
                return -1;
219
 
220
        for (i = 0; i < 2; i++) {
221
 
222
                outb(L4_SELECT_ANALOG, L4_PORT);
223
                outb(L4_SELECT_DIGITAL + i, L4_PORT);
224
 
225
                if (inb(L4_PORT) & L4_BUSY) continue;
226
                outb(L4_CMD_ID, L4_PORT);
227
 
228
                if (l4_wait_ready()) continue;
229
                if (inb(L4_PORT) != L4_SELECT_DIGITAL + i) continue;
230
 
231
                if (l4_wait_ready()) continue;
232
                if (inb(L4_PORT) != L4_ID) continue;
233
 
234
                if (l4_wait_ready()) continue;
235
                rev = inb(L4_PORT);
236
 
237
                if (!rev) continue;
238
 
239
                if (!(l4_port[i * 4] = kmalloc(sizeof(struct l4) * 4, GFP_KERNEL))) {
240
                        printk(KERN_ERR "lightning: Out of memory allocating ports.\n");
241
                        continue;
242
                }
243
                memset(l4_port[i * 4], 0, sizeof(struct l4) * 4);
244
 
245
                for (j = 0; j < 4; j++) {
246
 
247
                        l4 = l4_port[i * 4 + j] = l4_port[i * 4] + j;
248
                        l4->port = i * 4 + j;
249
 
250
                        gameport = &l4->gameport;
251
                        gameport->driver = l4;
252
                        gameport->open = l4_open;
253
                        gameport->cooked_read = l4_cooked_read;
254
                        gameport->calibrate = l4_calibrate;
255
 
256
                        if (!i && !j)
257
                                gameport->io = L4_PORT;
258
 
259
                        if (rev > 0x28)         /* on 2.9+ the setcal command works correctly */
260
                                l4_setcal(l4->port, cal);
261
 
262
                        gameport_register_port(gameport);
263
                }
264
 
265
                printk(KERN_INFO "gameport%d,%d,%d,%d: PDPI Lightning 4 %s card v%d.%d at %#x\n",
266
                        l4_port[i * 4 + 0]->gameport.number, l4_port[i * 4 + 1]->gameport.number,
267
                        l4_port[i * 4 + 2]->gameport.number, l4_port[i * 4 + 3]->gameport.number,
268
                        i ? "secondary" : "primary", rev >> 4, rev, L4_PORT);
269
 
270
                cards++;
271
        }
272
 
273
        outb(L4_SELECT_ANALOG, L4_PORT);
274
 
275
        if (!cards) {
276
                release_region(L4_PORT, 1);
277
                return -1;
278
        }
279
 
280
        return 0;
281
}
282
 
283
void __init l4_exit(void)
284
{
285
        int i;
286
        int cal[4] = {59, 59, 59, 59};
287
 
288
        for (i = 0; i < 8; i++)
289
                if (l4_port[i]) {
290
                        l4_setcal(l4_port[i]->port, cal);
291
                        gameport_unregister_port(&l4_port[i]->gameport);
292
                }
293
        outb(L4_SELECT_ANALOG, L4_PORT);
294
        release_region(L4_PORT, 1);
295
}
296
 
297
module_init(l4_init);
298
module_exit(l4_exit);

powered by: WebSVN 2.1.0

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