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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [input/] [joystick/] [db9.c] - Blame information for rev 65

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

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * $Id: db9.c,v 1.13 2002/04/07 20:13:37 vojtech Exp $
3
 *
4
 *  Copyright (c) 1999-2001 Vojtech Pavlik
5
 *
6
 *  Based on the work of:
7
 *      Andree Borrmann         Mats Sjövall
8
 */
9
 
10
/*
11
 * Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver for Linux
12
 */
13
 
14
/*
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 2 of the License, or
18
 * (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program; if not, write to the Free Software
27
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
 *
29
 * Should you need to contact me, the author, you can do so either by
30
 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
31
 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
32
 */
33
 
34
#include <linux/kernel.h>
35
#include <linux/module.h>
36
#include <linux/moduleparam.h>
37
#include <linux/delay.h>
38
#include <linux/init.h>
39
#include <linux/parport.h>
40
#include <linux/input.h>
41
#include <linux/mutex.h>
42
 
43
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
44
MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
45
MODULE_LICENSE("GPL");
46
 
47
struct db9_config {
48
        int args[2];
49
        unsigned int nargs;
50
};
51
 
52
#define DB9_MAX_PORTS           3
53
static struct db9_config db9_cfg[DB9_MAX_PORTS] __initdata;
54
 
55
module_param_array_named(dev, db9_cfg[0].args, int, &db9_cfg[0].nargs, 0);
56
MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
57
module_param_array_named(dev2, db9_cfg[1].args, int, &db9_cfg[1].nargs, 0);
58
MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
59
module_param_array_named(dev3, db9_cfg[2].args, int, &db9_cfg[2].nargs, 0);
60
MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
61
 
62
#define DB9_ARG_PARPORT         0
63
#define DB9_ARG_MODE            1
64
 
65
#define DB9_MULTI_STICK         0x01
66
#define DB9_MULTI2_STICK        0x02
67
#define DB9_GENESIS_PAD         0x03
68
#define DB9_GENESIS5_PAD        0x05
69
#define DB9_GENESIS6_PAD        0x06
70
#define DB9_SATURN_PAD          0x07
71
#define DB9_MULTI_0802          0x08
72
#define DB9_MULTI_0802_2        0x09
73
#define DB9_CD32_PAD            0x0A
74
#define DB9_SATURN_DPP          0x0B
75
#define DB9_SATURN_DPP_2        0x0C
76
#define DB9_MAX_PAD             0x0D
77
 
78
#define DB9_UP                  0x01
79
#define DB9_DOWN                0x02
80
#define DB9_LEFT                0x04
81
#define DB9_RIGHT               0x08
82
#define DB9_FIRE1               0x10
83
#define DB9_FIRE2               0x20
84
#define DB9_FIRE3               0x40
85
#define DB9_FIRE4               0x80
86
 
87
#define DB9_NORMAL              0x0a
88
#define DB9_NOSELECT            0x08
89
 
90
#define DB9_GENESIS6_DELAY      14
91
#define DB9_REFRESH_TIME        HZ/100
92
 
93
#define DB9_MAX_DEVICES         2
94
 
95
struct db9_mode_data {
96
        const char *name;
97
        const short *buttons;
98
        int n_buttons;
99
        int n_pads;
100
        int n_axis;
101
        int bidirectional;
102
        int reverse;
103
};
104
 
105
struct db9 {
106
        struct input_dev *dev[DB9_MAX_DEVICES];
107
        struct timer_list timer;
108
        struct pardevice *pd;
109
        int mode;
110
        int used;
111
        struct mutex mutex;
112
        char phys[DB9_MAX_DEVICES][32];
113
};
114
 
115
static struct db9 *db9_base[3];
116
 
117
static const short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
118
static const short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
119
static const short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
120
static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
121
 
122
static const struct db9_mode_data db9_modes[] = {
123
        { NULL,                                  NULL,            0,  0,  0,  0,  0 },
124
        { "Multisystem joystick",                db9_multi_btn,   1,  1,  2,  1,  1 },
125
        { "Multisystem joystick (2 fire)",       db9_multi_btn,   2,  1,  2,  1,  1 },
126
        { "Genesis pad",                         db9_genesis_btn, 4,  1,  2,  1,  1 },
127
        { NULL,                                  NULL,            0,  0,  0,  0,  0 },
128
        { "Genesis 5 pad",                       db9_genesis_btn, 6,  1,  2,  1,  1 },
129
        { "Genesis 6 pad",                       db9_genesis_btn, 8,  1,  2,  1,  1 },
130
        { "Saturn pad",                          db9_cd32_btn,    9,  6,  7,  0,  1 },
131
        { "Multisystem (0.8.0.2) joystick",      db9_multi_btn,   1,  1,  2,  1,  1 },
132
        { "Multisystem (0.8.0.2-dual) joystick", db9_multi_btn,   1,  2,  2,  1,  1 },
133
        { "Amiga CD-32 pad",                     db9_cd32_btn,    7,  1,  2,  1,  1 },
134
        { "Saturn dpp",                          db9_cd32_btn,    9,  6,  7,  0,  0 },
135
        { "Saturn dpp dual",                     db9_cd32_btn,    9,  12, 7,  0,  0 },
136
};
137
 
138
/*
139
 * Saturn controllers
140
 */
141
#define DB9_SATURN_DELAY 300
142
static const int db9_saturn_byte[] = { 1, 1, 1, 2, 2, 2, 2, 2, 1 };
143
static const unsigned char db9_saturn_mask[] = { 0x04, 0x01, 0x02, 0x40, 0x20, 0x10, 0x08, 0x80, 0x08 };
144
 
145
/*
146
 * db9_saturn_write_sub() writes 2 bit data.
147
 */
148
static void db9_saturn_write_sub(struct parport *port, int type, unsigned char data, int powered, int pwr_sub)
149
{
150
        unsigned char c;
151
 
152
        switch (type) {
153
        case 1: /* DPP1 */
154
                c = 0x80 | 0x30 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | data;
155
                parport_write_data(port, c);
156
                break;
157
        case 2: /* DPP2 */
158
                c = 0x40 | data << 4 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | 0x03;
159
                parport_write_data(port, c);
160
                break;
161
        case 0:  /* DB9 */
162
                c = ((((data & 2) ? 2 : 0) | ((data & 1) ? 4 : 0)) ^ 0x02) | !powered;
163
                parport_write_control(port, c);
164
                break;
165
        }
166
}
167
 
168
/*
169
 * gc_saturn_read_sub() reads 4 bit data.
170
 */
171
static unsigned char db9_saturn_read_sub(struct parport *port, int type)
172
{
173
        unsigned char data;
174
 
175
        if (type) {
176
                /* DPP */
177
                data = parport_read_status(port) ^ 0x80;
178
                return (data & 0x80 ? 1 : 0) | (data & 0x40 ? 2 : 0)
179
                     | (data & 0x20 ? 4 : 0) | (data & 0x10 ? 8 : 0);
180
        } else {
181
                /* DB9 */
182
                data = parport_read_data(port) & 0x0f;
183
                return (data & 0x8 ? 1 : 0) | (data & 0x4 ? 2 : 0)
184
                     | (data & 0x2 ? 4 : 0) | (data & 0x1 ? 8 : 0);
185
        }
186
}
187
 
188
/*
189
 * db9_saturn_read_analog() sends clock and reads 8 bit data.
190
 */
191
static unsigned char db9_saturn_read_analog(struct parport *port, int type, int powered)
192
{
193
        unsigned char data;
194
 
195
        db9_saturn_write_sub(port, type, 0, powered, 0);
196
        udelay(DB9_SATURN_DELAY);
197
        data = db9_saturn_read_sub(port, type) << 4;
198
        db9_saturn_write_sub(port, type, 2, powered, 0);
199
        udelay(DB9_SATURN_DELAY);
200
        data |= db9_saturn_read_sub(port, type);
201
        return data;
202
}
203
 
204
/*
205
 * db9_saturn_read_packet() reads whole saturn packet at connector
206
 * and returns device identifier code.
207
 */
208
static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered)
209
{
210
        int i, j;
211
        unsigned char tmp;
212
 
213
        db9_saturn_write_sub(port, type, 3, powered, 0);
214
        data[0] = db9_saturn_read_sub(port, type);
215
        switch (data[0] & 0x0f) {
216
        case 0xf:
217
                /* 1111  no pad */
218
                return data[0] = 0xff;
219
        case 0x4: case 0x4 | 0x8:
220
                /* ?100 : digital controller */
221
                db9_saturn_write_sub(port, type, 0, powered, 1);
222
                data[2] = db9_saturn_read_sub(port, type) << 4;
223
                db9_saturn_write_sub(port, type, 2, powered, 1);
224
                data[1] = db9_saturn_read_sub(port, type) << 4;
225
                db9_saturn_write_sub(port, type, 1, powered, 1);
226
                data[1] |= db9_saturn_read_sub(port, type);
227
                db9_saturn_write_sub(port, type, 3, powered, 1);
228
                /* data[2] |= db9_saturn_read_sub(port, type); */
229
                data[2] |= data[0];
230
                return data[0] = 0x02;
231
        case 0x1:
232
                /* 0001 : analog controller or multitap */
233
                db9_saturn_write_sub(port, type, 2, powered, 0);
234
                udelay(DB9_SATURN_DELAY);
235
                data[0] = db9_saturn_read_analog(port, type, powered);
236
                if (data[0] != 0x41) {
237
                        /* read analog controller */
238
                        for (i = 0; i < (data[0] & 0x0f); i++)
239
                                data[i + 1] = db9_saturn_read_analog(port, type, powered);
240
                        db9_saturn_write_sub(port, type, 3, powered, 0);
241
                        return data[0];
242
                } else {
243
                        /* read multitap */
244
                        if (db9_saturn_read_analog(port, type, powered) != 0x60)
245
                                return data[0] = 0xff;
246
                        for (i = 0; i < 60; i += 10) {
247
                                data[i] = db9_saturn_read_analog(port, type, powered);
248
                                if (data[i] != 0xff)
249
                                        /* read each pad */
250
                                        for (j = 0; j < (data[i] & 0x0f); j++)
251
                                                data[i + j + 1] = db9_saturn_read_analog(port, type, powered);
252
                        }
253
                        db9_saturn_write_sub(port, type, 3, powered, 0);
254
                        return 0x41;
255
                }
256
        case 0x0:
257
                /* 0000 : mouse */
258
                db9_saturn_write_sub(port, type, 2, powered, 0);
259
                udelay(DB9_SATURN_DELAY);
260
                tmp = db9_saturn_read_analog(port, type, powered);
261
                if (tmp == 0xff) {
262
                        for (i = 0; i < 3; i++)
263
                                data[i + 1] = db9_saturn_read_analog(port, type, powered);
264
                        db9_saturn_write_sub(port, type, 3, powered, 0);
265
                        return data[0] = 0xe3;
266
                }
267
        default:
268
                return data[0];
269
        }
270
}
271
 
272
/*
273
 * db9_saturn_report() analyzes packet and reports.
274
 */
275
static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *devs[], int n, int max_pads)
276
{
277
        struct input_dev *dev;
278
        int tmp, i, j;
279
 
280
        tmp = (id == 0x41) ? 60 : 10;
281
        for (j = 0; j < tmp && n < max_pads; j += 10, n++) {
282
                dev = devs[n];
283
                switch (data[j]) {
284
                case 0x16: /* multi controller (analog 4 axis) */
285
                        input_report_abs(dev, db9_abs[5], data[j + 6]);
286
                case 0x15: /* mission stick (analog 3 axis) */
287
                        input_report_abs(dev, db9_abs[3], data[j + 4]);
288
                        input_report_abs(dev, db9_abs[4], data[j + 5]);
289
                case 0x13: /* racing controller (analog 1 axis) */
290
                        input_report_abs(dev, db9_abs[2], data[j + 3]);
291
                case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */
292
                case 0x02: /* digital pad (digital 2 axis + buttons) */
293
                        input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
294
                        input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
295
                        for (i = 0; i < 9; i++)
296
                                input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
297
                        break;
298
                case 0x19: /* mission stick x2 (analog 6 axis + buttons) */
299
                        input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
300
                        input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
301
                        for (i = 0; i < 9; i++)
302
                                input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
303
                        input_report_abs(dev, db9_abs[2], data[j + 3]);
304
                        input_report_abs(dev, db9_abs[3], data[j + 4]);
305
                        input_report_abs(dev, db9_abs[4], data[j + 5]);
306
                        /*
307
                        input_report_abs(dev, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1));
308
                        input_report_abs(dev, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1));
309
                        */
310
                        input_report_abs(dev, db9_abs[6], data[j + 7]);
311
                        input_report_abs(dev, db9_abs[7], data[j + 8]);
312
                        input_report_abs(dev, db9_abs[5], data[j + 9]);
313
                        break;
314
                case 0xd3: /* sankyo ff (analog 1 axis + stop btn) */
315
                        input_report_key(dev, BTN_A, data[j + 3] & 0x80);
316
                        input_report_abs(dev, db9_abs[2], data[j + 3] & 0x7f);
317
                        break;
318
                case 0xe3: /* shuttle mouse (analog 2 axis + buttons. signed value) */
319
                        input_report_key(dev, BTN_START, data[j + 1] & 0x08);
320
                        input_report_key(dev, BTN_A, data[j + 1] & 0x04);
321
                        input_report_key(dev, BTN_C, data[j + 1] & 0x02);
322
                        input_report_key(dev, BTN_B, data[j + 1] & 0x01);
323
                        input_report_abs(dev, db9_abs[2], data[j + 2] ^ 0x80);
324
                        input_report_abs(dev, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */
325
                        break;
326
                case 0xff:
327
                default: /* no pad */
328
                        input_report_abs(dev, db9_abs[0], 0);
329
                        input_report_abs(dev, db9_abs[1], 0);
330
                        for (i = 0; i < 9; i++)
331
                                input_report_key(dev, db9_cd32_btn[i], 0);
332
                        break;
333
                }
334
        }
335
        return n;
336
}
337
 
338
static int db9_saturn(int mode, struct parport *port, struct input_dev *devs[])
339
{
340
        unsigned char id, data[60];
341
        int type, n, max_pads;
342
        int tmp, i;
343
 
344
        switch (mode) {
345
        case DB9_SATURN_PAD:
346
                type = 0;
347
                n = 1;
348
                break;
349
        case DB9_SATURN_DPP:
350
                type = 1;
351
                n = 1;
352
                break;
353
        case DB9_SATURN_DPP_2:
354
                type = 1;
355
                n = 2;
356
                break;
357
        default:
358
                return -1;
359
        }
360
        max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES);
361
        for (tmp = 0, i = 0; i < n; i++) {
362
                id = db9_saturn_read_packet(port, data, type + i, 1);
363
                tmp = db9_saturn_report(id, data, devs, tmp, max_pads);
364
        }
365
        return 0;
366
}
367
 
368
static void db9_timer(unsigned long private)
369
{
370
        struct db9 *db9 = (void *) private;
371
        struct parport *port = db9->pd->port;
372
        struct input_dev *dev = db9->dev[0];
373
        struct input_dev *dev2 = db9->dev[1];
374
        int data, i;
375
 
376
        switch (db9->mode) {
377
                case DB9_MULTI_0802_2:
378
 
379
                        data = parport_read_data(port) >> 3;
380
 
381
                        input_report_abs(dev2, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
382
                        input_report_abs(dev2, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
383
                        input_report_key(dev2, BTN_TRIGGER, ~data & DB9_FIRE1);
384
 
385
                case DB9_MULTI_0802:
386
 
387
                        data = parport_read_status(port) >> 3;
388
 
389
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
390
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
391
                        input_report_key(dev, BTN_TRIGGER, data & DB9_FIRE1);
392
                        break;
393
 
394
                case DB9_MULTI_STICK:
395
 
396
                        data = parport_read_data(port);
397
 
398
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
399
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
400
                        input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1);
401
                        break;
402
 
403
                case DB9_MULTI2_STICK:
404
 
405
                        data = parport_read_data(port);
406
 
407
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
408
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
409
                        input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1);
410
                        input_report_key(dev, BTN_THUMB,   ~data & DB9_FIRE2);
411
                        break;
412
 
413
                case DB9_GENESIS_PAD:
414
 
415
                        parport_write_control(port, DB9_NOSELECT);
416
                        data = parport_read_data(port);
417
 
418
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
419
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
420
                        input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
421
                        input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
422
 
423
                        parport_write_control(port, DB9_NORMAL);
424
                        data = parport_read_data(port);
425
 
426
                        input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
427
                        input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
428
                        break;
429
 
430
                case DB9_GENESIS5_PAD:
431
 
432
                        parport_write_control(port, DB9_NOSELECT);
433
                        data = parport_read_data(port);
434
 
435
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
436
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
437
                        input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
438
                        input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
439
 
440
                        parport_write_control(port, DB9_NORMAL);
441
                        data = parport_read_data(port);
442
 
443
                        input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
444
                        input_report_key(dev, BTN_X,     ~data & DB9_FIRE2);
445
                        input_report_key(dev, BTN_Y,     ~data & DB9_LEFT);
446
                        input_report_key(dev, BTN_START, ~data & DB9_RIGHT);
447
                        break;
448
 
449
                case DB9_GENESIS6_PAD:
450
 
451
                        parport_write_control(port, DB9_NOSELECT); /* 1 */
452
                        udelay(DB9_GENESIS6_DELAY);
453
                        data = parport_read_data(port);
454
 
455
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
456
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
457
                        input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
458
                        input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
459
 
460
                        parport_write_control(port, DB9_NORMAL);
461
                        udelay(DB9_GENESIS6_DELAY);
462
                        data = parport_read_data(port);
463
 
464
                        input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
465
                        input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
466
 
467
                        parport_write_control(port, DB9_NOSELECT); /* 2 */
468
                        udelay(DB9_GENESIS6_DELAY);
469
                        parport_write_control(port, DB9_NORMAL);
470
                        udelay(DB9_GENESIS6_DELAY);
471
                        parport_write_control(port, DB9_NOSELECT); /* 3 */
472
                        udelay(DB9_GENESIS6_DELAY);
473
                        data=parport_read_data(port);
474
 
475
                        input_report_key(dev, BTN_X,    ~data & DB9_LEFT);
476
                        input_report_key(dev, BTN_Y,    ~data & DB9_DOWN);
477
                        input_report_key(dev, BTN_Z,    ~data & DB9_UP);
478
                        input_report_key(dev, BTN_MODE, ~data & DB9_RIGHT);
479
 
480
                        parport_write_control(port, DB9_NORMAL);
481
                        udelay(DB9_GENESIS6_DELAY);
482
                        parport_write_control(port, DB9_NOSELECT); /* 4 */
483
                        udelay(DB9_GENESIS6_DELAY);
484
                        parport_write_control(port, DB9_NORMAL);
485
                        break;
486
 
487
                case DB9_SATURN_PAD:
488
                case DB9_SATURN_DPP:
489
                case DB9_SATURN_DPP_2:
490
 
491
                        db9_saturn(db9->mode, port, db9->dev);
492
                        break;
493
 
494
                case DB9_CD32_PAD:
495
 
496
                        data = parport_read_data(port);
497
 
498
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
499
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
500
 
501
                        parport_write_control(port, 0x0a);
502
 
503
                        for (i = 0; i < 7; i++) {
504
                                data = parport_read_data(port);
505
                                parport_write_control(port, 0x02);
506
                                parport_write_control(port, 0x0a);
507
                                input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
508
                        }
509
 
510
                        parport_write_control(port, 0x00);
511
                        break;
512
                }
513
 
514
        input_sync(dev);
515
 
516
        mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
517
}
518
 
519
static int db9_open(struct input_dev *dev)
520
{
521
        struct db9 *db9 = input_get_drvdata(dev);
522
        struct parport *port = db9->pd->port;
523
        int err;
524
 
525
        err = mutex_lock_interruptible(&db9->mutex);
526
        if (err)
527
                return err;
528
 
529
        if (!db9->used++) {
530
                parport_claim(db9->pd);
531
                parport_write_data(port, 0xff);
532
                if (db9_modes[db9->mode].reverse) {
533
                        parport_data_reverse(port);
534
                        parport_write_control(port, DB9_NORMAL);
535
                }
536
                mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
537
        }
538
 
539
        mutex_unlock(&db9->mutex);
540
        return 0;
541
}
542
 
543
static void db9_close(struct input_dev *dev)
544
{
545
        struct db9 *db9 = input_get_drvdata(dev);
546
        struct parport *port = db9->pd->port;
547
 
548
        mutex_lock(&db9->mutex);
549
        if (!--db9->used) {
550
                del_timer_sync(&db9->timer);
551
                parport_write_control(port, 0x00);
552
                parport_data_forward(port);
553
                parport_release(db9->pd);
554
        }
555
        mutex_unlock(&db9->mutex);
556
}
557
 
558
static struct db9 __init *db9_probe(int parport, int mode)
559
{
560
        struct db9 *db9;
561
        const struct db9_mode_data *db9_mode;
562
        struct parport *pp;
563
        struct pardevice *pd;
564
        struct input_dev *input_dev;
565
        int i, j;
566
        int err;
567
 
568
        if (mode < 1 || mode >= DB9_MAX_PAD || !db9_modes[mode].n_buttons) {
569
                printk(KERN_ERR "db9.c: Bad device type %d\n", mode);
570
                err = -EINVAL;
571
                goto err_out;
572
        }
573
 
574
        db9_mode = &db9_modes[mode];
575
 
576
        pp = parport_find_number(parport);
577
        if (!pp) {
578
                printk(KERN_ERR "db9.c: no such parport\n");
579
                err = -ENODEV;
580
                goto err_out;
581
        }
582
 
583
        if (db9_mode->bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) {
584
                printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
585
                err = -EINVAL;
586
                goto err_put_pp;
587
        }
588
 
589
        pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
590
        if (!pd) {
591
                printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
592
                err = -EBUSY;
593
                goto err_put_pp;
594
        }
595
 
596
        db9 = kzalloc(sizeof(struct db9), GFP_KERNEL);
597
        if (!db9) {
598
                printk(KERN_ERR "db9.c: Not enough memory\n");
599
                err = -ENOMEM;
600
                goto err_unreg_pardev;
601
        }
602
 
603
        mutex_init(&db9->mutex);
604
        db9->pd = pd;
605
        db9->mode = mode;
606
        init_timer(&db9->timer);
607
        db9->timer.data = (long) db9;
608
        db9->timer.function = db9_timer;
609
 
610
        for (i = 0; i < (min(db9_mode->n_pads, DB9_MAX_DEVICES)); i++) {
611
 
612
                db9->dev[i] = input_dev = input_allocate_device();
613
                if (!input_dev) {
614
                        printk(KERN_ERR "db9.c: Not enough memory for input device\n");
615
                        err = -ENOMEM;
616
                        goto err_unreg_devs;
617
                }
618
 
619
                snprintf(db9->phys[i], sizeof(db9->phys[i]),
620
                         "%s/input%d", db9->pd->port->name, i);
621
 
622
                input_dev->name = db9_mode->name;
623
                input_dev->phys = db9->phys[i];
624
                input_dev->id.bustype = BUS_PARPORT;
625
                input_dev->id.vendor = 0x0002;
626
                input_dev->id.product = mode;
627
                input_dev->id.version = 0x0100;
628
 
629
                input_set_drvdata(input_dev, db9);
630
 
631
                input_dev->open = db9_open;
632
                input_dev->close = db9_close;
633
 
634
                input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
635
                for (j = 0; j < db9_mode->n_buttons; j++)
636
                        set_bit(db9_mode->buttons[j], input_dev->keybit);
637
                for (j = 0; j < db9_mode->n_axis; j++) {
638
                        if (j < 2)
639
                                input_set_abs_params(input_dev, db9_abs[j], -1, 1, 0, 0);
640
                        else
641
                                input_set_abs_params(input_dev, db9_abs[j], 1, 255, 0, 0);
642
                }
643
 
644
                err = input_register_device(input_dev);
645
                if (err)
646
                        goto err_free_dev;
647
        }
648
 
649
        parport_put_port(pp);
650
        return db9;
651
 
652
 err_free_dev:
653
        input_free_device(db9->dev[i]);
654
 err_unreg_devs:
655
        while (--i >= 0)
656
                input_unregister_device(db9->dev[i]);
657
        kfree(db9);
658
 err_unreg_pardev:
659
        parport_unregister_device(pd);
660
 err_put_pp:
661
        parport_put_port(pp);
662
 err_out:
663
        return ERR_PTR(err);
664
}
665
 
666
static void db9_remove(struct db9 *db9)
667
{
668
        int i;
669
 
670
        for (i = 0; i < min(db9_modes[db9->mode].n_pads, DB9_MAX_DEVICES); i++)
671
                input_unregister_device(db9->dev[i]);
672
        parport_unregister_device(db9->pd);
673
        kfree(db9);
674
}
675
 
676
static int __init db9_init(void)
677
{
678
        int i;
679
        int have_dev = 0;
680
        int err = 0;
681
 
682
        for (i = 0; i < DB9_MAX_PORTS; i++) {
683
                if (db9_cfg[i].nargs == 0 || db9_cfg[i].args[DB9_ARG_PARPORT] < 0)
684
                        continue;
685
 
686
                if (db9_cfg[i].nargs < 2) {
687
                        printk(KERN_ERR "db9.c: Device type must be specified.\n");
688
                        err = -EINVAL;
689
                        break;
690
                }
691
 
692
                db9_base[i] = db9_probe(db9_cfg[i].args[DB9_ARG_PARPORT],
693
                                        db9_cfg[i].args[DB9_ARG_MODE]);
694
                if (IS_ERR(db9_base[i])) {
695
                        err = PTR_ERR(db9_base[i]);
696
                        break;
697
                }
698
 
699
                have_dev = 1;
700
        }
701
 
702
        if (err) {
703
                while (--i >= 0)
704
                        if (db9_base[i])
705
                                db9_remove(db9_base[i]);
706
                return err;
707
        }
708
 
709
        return have_dev ? 0 : -ENODEV;
710
}
711
 
712
static void __exit db9_exit(void)
713
{
714
        int i;
715
 
716
        for (i = 0; i < DB9_MAX_PORTS; i++)
717
                if (db9_base[i])
718
                        db9_remove(db9_base[i]);
719
}
720
 
721
module_init(db9_init);
722
module_exit(db9_exit);

powered by: WebSVN 2.1.0

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