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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * $Id: db9.c,v 1.1.1.1 2004-04-15 02:03:24 phoenix Exp $
3
 *
4
 *  Copyright (c) 1999 Vojtech Pavlik
5
 *
6
 *  Based on the work of:
7
 *      Andree Borrmann         Mats Sjövall
8
 *
9
 *  Sponsored by SuSE
10
 */
11
 
12
/*
13
 * Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver for Linux
14
 */
15
 
16
/*
17
 * This program is free software; you can redistribute it and/or modify
18
 * it under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation; either version 2 of the License, or
20
 * (at your option) any later version.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU General Public License
28
 * along with this program; if not, write to the Free Software
29
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30
 *
31
 * Should you need to contact me, the author, you can do so either by
32
 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
33
 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
34
 */
35
 
36
#include <linux/kernel.h>
37
#include <linux/module.h>
38
#include <linux/delay.h>
39
#include <linux/init.h>
40
#include <linux/parport.h>
41
#include <linux/input.h>
42
 
43
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
44
MODULE_LICENSE("GPL");
45
MODULE_PARM(db9, "2i");
46
MODULE_PARM(db9_2, "2i");
47
MODULE_PARM(db9_3, "2i");
48
 
49
#define DB9_MULTI_STICK         0x01
50
#define DB9_MULTI2_STICK        0x02
51
#define DB9_GENESIS_PAD         0x03
52
#define DB9_GENESIS5_PAD        0x05
53
#define DB9_GENESIS6_PAD        0x06
54
#define DB9_SATURN_PAD          0x07
55
#define DB9_MULTI_0802          0x08
56
#define DB9_MULTI_0802_2        0x09
57
#define DB9_CD32_PAD            0x0A
58
#define DB9_MAX_PAD             0x0B
59
 
60
#define DB9_UP                  0x01
61
#define DB9_DOWN                0x02
62
#define DB9_LEFT                0x04
63
#define DB9_RIGHT               0x08
64
#define DB9_FIRE1               0x10
65
#define DB9_FIRE2               0x20
66
#define DB9_FIRE3               0x40
67
#define DB9_FIRE4               0x80
68
 
69
#define DB9_NORMAL              0x0a
70
#define DB9_NOSELECT            0x08
71
 
72
#define DB9_SATURN0             0x00
73
#define DB9_SATURN1             0x02
74
#define DB9_SATURN2             0x04
75
#define DB9_SATURN3             0x06
76
 
77
#define DB9_GENESIS6_DELAY      14
78
#define DB9_REFRESH_TIME        HZ/100
79
 
80
static int db9[] __initdata = { -1, 0 };
81
static int db9_2[] __initdata = { -1, 0 };
82
static int db9_3[] __initdata = { -1, 0 };
83
 
84
struct db9 {
85
        struct input_dev dev[2];
86
        struct timer_list timer;
87
        struct pardevice *pd;
88
        int mode;
89
        int used;
90
};
91
 
92
static struct db9 *db9_base[3];
93
 
94
static short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
95
static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
96
static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
97
 
98
static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 8, 1, 1, 7 };
99
static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
100
                                        db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn };
101
static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
102
                                      NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
103
                                     "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad" };
104
 
105
static void db9_timer(unsigned long private)
106
{
107
        struct db9 *db9 = (void *) private;
108
        struct parport *port = db9->pd->port;
109
        struct input_dev *dev = db9->dev;
110
        int data, i;
111
 
112
        switch(db9->mode) {
113
                case DB9_MULTI_0802_2:
114
 
115
                        data = parport_read_data(port) >> 3;
116
 
117
                        input_report_abs(dev + 1, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
118
                        input_report_abs(dev + 1, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
119
                        input_report_key(dev + 1, BTN_TRIGGER, ~data & DB9_FIRE1);
120
 
121
                case DB9_MULTI_0802:
122
 
123
                        data = parport_read_status(port) >> 3;
124
 
125
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
126
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
127
                        input_report_key(dev, BTN_TRIGGER, data & DB9_FIRE1);
128
                        break;
129
 
130
                case DB9_MULTI_STICK:
131
 
132
                        data = parport_read_data(port);
133
 
134
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
135
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
136
                        input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1);
137
                        break;
138
 
139
                case DB9_MULTI2_STICK:
140
 
141
                        data = parport_read_data(port);
142
 
143
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
144
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
145
                        input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1);
146
                        input_report_key(dev, BTN_THUMB,   ~data & DB9_FIRE2);
147
                        break;
148
 
149
                case DB9_GENESIS_PAD:
150
 
151
                        parport_write_control(port, DB9_NOSELECT);
152
                        data = parport_read_data(port);
153
 
154
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
155
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
156
                        input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
157
                        input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
158
 
159
                        parport_write_control(port, DB9_NORMAL);
160
                        data=parport_read_data(port);
161
 
162
                        input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
163
                        input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
164
                        break;
165
 
166
                case DB9_GENESIS5_PAD:
167
 
168
                        parport_write_control(port, DB9_NOSELECT);
169
                        data=parport_read_data(port);
170
 
171
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
172
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
173
                        input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
174
                        input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
175
 
176
                        parport_write_control(port, DB9_NORMAL);
177
                        data=parport_read_data(port);
178
 
179
                        input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
180
                        input_report_key(dev, BTN_X,     ~data & DB9_FIRE2);
181
                        input_report_key(dev, BTN_Y,     ~data & DB9_LEFT);
182
                        input_report_key(dev, BTN_START, ~data & DB9_RIGHT);
183
                        break;
184
 
185
                case DB9_GENESIS6_PAD:
186
 
187
                        parport_write_control(port, DB9_NOSELECT); /* 1 */
188
                        udelay(DB9_GENESIS6_DELAY);
189
                        data=parport_read_data(port);
190
 
191
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
192
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
193
                        input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
194
                        input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
195
 
196
                        parport_write_control(port, DB9_NORMAL);
197
                        udelay(DB9_GENESIS6_DELAY);
198
                        data=parport_read_data(port);
199
 
200
                        input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
201
                        input_report_key(dev, BTN_X, ~data & DB9_FIRE2);
202
 
203
                        parport_write_control(port, DB9_NOSELECT); /* 2 */
204
                        udelay(DB9_GENESIS6_DELAY);
205
                        parport_write_control(port, DB9_NORMAL);
206
                        udelay(DB9_GENESIS6_DELAY);
207
                        parport_write_control(port, DB9_NOSELECT); /* 3 */
208
                        udelay(DB9_GENESIS6_DELAY);
209
                        data=parport_read_data(port);
210
 
211
                        input_report_key(dev, BTN_Y,     ~data & DB9_LEFT);
212
                        input_report_key(dev, BTN_Z,     ~data & DB9_DOWN);
213
                        input_report_key(dev, BTN_MODE,  ~data & DB9_UP);
214
                        input_report_key(dev, BTN_START, ~data & DB9_RIGHT);
215
 
216
                        parport_write_control(port, DB9_NORMAL);
217
                        udelay(DB9_GENESIS6_DELAY);
218
                        parport_write_control(port, DB9_NOSELECT); /* 4 */
219
                        udelay(DB9_GENESIS6_DELAY);
220
                        parport_write_control(port, DB9_NORMAL);
221
                        break;
222
 
223
                case DB9_SATURN_PAD:
224
 
225
                        parport_write_control(port, DB9_SATURN0);
226
                        data = parport_read_data(port);
227
 
228
                        input_report_key(dev, BTN_Y,  ~data & DB9_LEFT);
229
                        input_report_key(dev, BTN_Z,  ~data & DB9_DOWN);
230
                        input_report_key(dev, BTN_TL, ~data & DB9_UP);
231
                        input_report_key(dev, BTN_TR, ~data & DB9_RIGHT);
232
 
233
                        parport_write_control(port, DB9_SATURN2);
234
                        data = parport_read_data(port);
235
 
236
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
237
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
238
 
239
                        parport_write_control(port, DB9_NORMAL);
240
                        data = parport_read_data(port);
241
 
242
                        input_report_key(dev, BTN_A, ~data & DB9_LEFT);
243
                        input_report_key(dev, BTN_B, ~data & DB9_UP);
244
                        input_report_key(dev, BTN_C, ~data & DB9_DOWN);
245
                        input_report_key(dev, BTN_X, ~data & DB9_RIGHT);
246
                        break;
247
 
248
                case DB9_CD32_PAD:
249
 
250
                        data=parport_read_data(port);
251
 
252
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
253
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
254
 
255
                        parport_write_control(port, 0x0a);
256
 
257
                        for (i = 0; i < 7; i++) {
258
                                data = parport_read_data(port);
259
                                parport_write_control(port, 0x02);
260
                                parport_write_control(port, 0x0a);
261
                                input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
262
                                }
263
 
264
                        parport_write_control(port, 0x00);
265
                        break;
266
                }
267
 
268
        mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
269
}
270
 
271
static int db9_open(struct input_dev *dev)
272
{
273
        struct db9 *db9 = dev->private;
274
        struct parport *port = db9->pd->port;
275
 
276
        if (!db9->used++) {
277
                parport_claim(db9->pd);
278
                parport_write_data(port, 0xff);
279
                parport_data_reverse(port);
280
                parport_write_control(port, DB9_NORMAL);
281
                mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
282
        }
283
 
284
        return 0;
285
}
286
 
287
static void db9_close(struct input_dev *dev)
288
{
289
        struct db9 *db9 = dev->private;
290
        struct parport *port = db9->pd->port;
291
 
292
        if (!--db9->used) {
293
                del_timer(&db9->timer);
294
                parport_write_control(port, 0x00);
295
                parport_data_forward(port);
296
                parport_release(db9->pd);
297
        }
298
}
299
 
300
static struct db9 __init *db9_probe(int *config)
301
{
302
        struct db9 *db9;
303
        struct parport *pp;
304
        int i, j;
305
 
306
        if (config[0] < 0)
307
                return NULL;
308
        if (config[1] < 1 || config[1] >= DB9_MAX_PAD || !db9_buttons[config[1]]) {
309
                printk(KERN_ERR "db9.c: bad config\n");
310
                return NULL;
311
        }
312
 
313
        for (pp = parport_enumerate(); pp && (config[0] > 0); pp = pp->next)
314
                config[0]--;
315
 
316
        if (!pp) {
317
                printk(KERN_ERR "db9.c: no such parport\n");
318
                return NULL;
319
        }
320
 
321
        if (!(pp->modes & PARPORT_MODE_TRISTATE) && config[1] != DB9_MULTI_0802) {
322
                printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
323
                return NULL;
324
        }
325
 
326
        if (!(db9 = kmalloc(sizeof(struct db9), GFP_KERNEL)))
327
                return NULL;
328
        memset(db9, 0, sizeof(struct db9));
329
 
330
        db9->mode = config[1];
331
        init_timer(&db9->timer);
332
        db9->timer.data = (long) db9;
333
        db9->timer.function = db9_timer;
334
 
335
        db9->pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
336
 
337
        if (!db9->pd) {
338
                printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
339
                kfree(db9);
340
                return NULL;
341
        }
342
 
343
        for (i = 0; i < 1 + (db9->mode == DB9_MULTI_0802_2); i++) {
344
 
345
                db9->dev[i].private = db9;
346
                db9->dev[i].open = db9_open;
347
                db9->dev[i].close = db9_close;
348
 
349
                db9->dev[i].name = db9_name[db9->mode];
350
                db9->dev[i].idbus = BUS_PARPORT;
351
                db9->dev[i].idvendor = 0x0002;
352
                db9->dev[i].idproduct = config[1];
353
                db9->dev[i].idversion = 0x0100;
354
 
355
                db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
356
                db9->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
357
 
358
                for (j = 0; j < db9_buttons[db9->mode]; j++)
359
                        set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
360
 
361
                db9->dev[i].absmin[ABS_X] = -1; db9->dev[i].absmax[ABS_X] = 1;
362
                db9->dev[i].absmin[ABS_Y] = -1; db9->dev[i].absmax[ABS_Y] = 1;
363
 
364
                input_register_device(db9->dev + i);
365
                printk(KERN_INFO "input%d: %s on %s\n",
366
                        db9->dev[i].number, db9_name[db9->mode], db9->pd->port->name);
367
        }
368
 
369
        return db9;
370
}
371
 
372
#ifndef MODULE
373
int __init db9_setup(char *str)
374
{
375
        int i, ints[3];
376
        get_options(str, ARRAY_SIZE(ints), ints);
377
        for (i = 0; i <= ints[0] && i < 2; i++) db9[i] = ints[i + 1];
378
        return 1;
379
}
380
int __init db9_setup_2(char *str)
381
{
382
        int i, ints[3];
383
        get_options(str, ARRAY_SIZE(ints), ints);
384
        for (i = 0; i <= ints[0] && i < 2; i++) db9_2[i] = ints[i + 1];
385
        return 1;
386
}
387
int __init db9_setup_3(char *str)
388
{
389
        int i, ints[3];
390
        get_options(str, ARRAY_SIZE(ints), ints);
391
        for (i = 0; i <= ints[0] && i < 2; i++) db9_3[i] = ints[i + 1];
392
        return 1;
393
}
394
__setup("db9=", db9_setup);
395
__setup("db9_2=", db9_setup_2);
396
__setup("db9_3=", db9_setup_3);
397
#endif
398
 
399
int __init db9_init(void)
400
{
401
        db9_base[0] = db9_probe(db9);
402
        db9_base[1] = db9_probe(db9_2);
403
        db9_base[2] = db9_probe(db9_3);
404
 
405
        if (db9_base[0] || db9_base[1] || db9_base[2])
406
                return 0;
407
 
408
        return -ENODEV;
409
}
410
 
411
void __exit db9_exit(void)
412
{
413
        int i, j;
414
 
415
        for (i = 0; i < 3; i++)
416
                if (db9_base[i]) {
417
                        for (j = 0; j < 1 + (db9_base[i]->mode == DB9_MULTI_0802_2); j++)
418
                                input_unregister_device(db9_base[i]->dev + j);
419
                parport_unregister_device(db9_base[i]->pd);
420
        }
421
}
422
 
423
module_init(db9_init);
424
module_exit(db9_exit);

powered by: WebSVN 2.1.0

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