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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * $Id: stinger.c,v 1.1.1.1 2004-04-15 02:03:30 phoenix Exp $
3
 *
4
 *  Copyright (c) 2000-2001 Vojtech Pavlik
5
 *  Copyright (c) 2000 Mark Fletcher
6
 *
7
 *  Sponsored by SuSE
8
 */
9
 
10
/*
11
 * Gravis Stinger gamepad driver for Linux
12
 */
13
 
14
/*
15
 * This program is free warftware; 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, Ucitelska 1576, Prague 8, 182 00 Czech Republic
32
 */
33
 
34
#include <linux/kernel.h>
35
#include <linux/module.h>
36
#include <linux/slab.h>
37
#include <linux/input.h>
38
#include <linux/serio.h>
39
#include <linux/init.h>
40
 
41
/*
42
 * Constants.
43
 */
44
 
45
#define STINGER_MAX_LENGTH 8
46
 
47
static char *stinger_name = "Gravis Stinger";
48
 
49
/*
50
 * Per-Stinger data.
51
 */
52
 
53
struct stinger {
54
        struct input_dev dev;
55
        int idx;
56
        unsigned char data[STINGER_MAX_LENGTH];
57
};
58
 
59
/*
60
 * stinger_process_packet() decodes packets the driver receives from the
61
 * Stinger. It updates the data accordingly.
62
 */
63
 
64
static void stinger_process_packet(struct stinger *stinger)
65
{
66
        struct input_dev *dev = &stinger->dev;
67
        unsigned char *data = stinger->data;
68
 
69
        if (!stinger->idx) return;
70
 
71
        input_report_key(dev, BTN_A,      ((data[0] & 0x20) >> 5));
72
        input_report_key(dev, BTN_B,      ((data[0] & 0x10) >> 4));
73
        input_report_key(dev, BTN_C,      ((data[0] & 0x08) >> 3));
74
        input_report_key(dev, BTN_X,      ((data[0] & 0x04) >> 2));
75
        input_report_key(dev, BTN_Y,      ((data[3] & 0x20) >> 5));
76
        input_report_key(dev, BTN_Z,      ((data[3] & 0x10) >> 4));
77
        input_report_key(dev, BTN_TL,     ((data[3] & 0x08) >> 3));
78
        input_report_key(dev, BTN_TR,     ((data[3] & 0x04) >> 2));
79
        input_report_key(dev, BTN_SELECT, ((data[3] & 0x02) >> 1));
80
        input_report_key(dev, BTN_START,   (data[3] & 0x01));
81
 
82
        input_report_abs(dev, ABS_X, (data[1] & 0x3F) - ((data[0] & 0x01) << 6));
83
        input_report_abs(dev, ABS_Y, ((data[0] & 0x02) << 5) - (data[2] & 0x3F));
84
 
85
        return;
86
}
87
 
88
/*
89
 * stinger_interrupt() is called by the low level driver when characters
90
 * are ready for us. We then buffer them for further processing, or call the
91
 * packet processing routine.
92
 */
93
 
94
static void stinger_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
95
{
96
        struct stinger* stinger = serio->private;
97
 
98
        /* All Stinger packets are 4 bytes */
99
 
100
        if (stinger->idx < STINGER_MAX_LENGTH)
101
                stinger->data[stinger->idx++] = data;
102
 
103
        if (stinger->idx == 4) {
104
                stinger_process_packet(stinger);
105
                stinger->idx = 0;
106
        }
107
 
108
        return;
109
}
110
 
111
/*
112
 * stinger_disconnect() is the opposite of stinger_connect()
113
 */
114
 
115
static void stinger_disconnect(struct serio *serio)
116
{
117
        struct stinger* stinger = serio->private;
118
        input_unregister_device(&stinger->dev);
119
        serio_close(serio);
120
        kfree(stinger);
121
}
122
 
123
/*
124
 * stinger_connect() is the routine that is called when someone adds a
125
 * new serio device. It looks for the Stinger, and if found, registers
126
 * it as an input device.
127
 */
128
 
129
static void stinger_connect(struct serio *serio, struct serio_dev *dev)
130
{
131
        struct stinger *stinger;
132
        int i;
133
 
134
        if (serio->type != (SERIO_RS232 | SERIO_STINGER))
135
                return;
136
 
137
        if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL)))
138
                return;
139
 
140
        memset(stinger, 0, sizeof(struct stinger));
141
 
142
        stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
143
        stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \
144
                                           BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \
145
                                           BIT(BTN_START) | BIT(BTN_SELECT);
146
        stinger->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
147
 
148
        stinger->dev.name = stinger_name;
149
        stinger->dev.idbus = BUS_RS232;
150
        stinger->dev.idvendor = SERIO_STINGER;
151
        stinger->dev.idproduct = 0x0001;
152
        stinger->dev.idversion = 0x0100;
153
 
154
        for (i = 0; i < 2; i++) {
155
                stinger->dev.absmax[ABS_X+i] =  64;
156
                stinger->dev.absmin[ABS_X+i] = -64;
157
                stinger->dev.absflat[ABS_X+i] = 4;
158
        }
159
 
160
        stinger->dev.private = stinger;
161
 
162
        serio->private = stinger;
163
 
164
        if (serio_open(serio, dev)) {
165
                kfree(stinger);
166
                return;
167
        }
168
 
169
        input_register_device(&stinger->dev);
170
 
171
        printk(KERN_INFO "input%d: %s on serio%d\n", stinger->dev.number, stinger_name, serio->number);
172
}
173
 
174
/*
175
 * The serio device structure.
176
 */
177
 
178
static struct serio_dev stinger_dev = {
179
        interrupt:      stinger_interrupt,
180
        connect:        stinger_connect,
181
        disconnect:     stinger_disconnect,
182
};
183
 
184
/*
185
 * The functions for inserting/removing us as a module.
186
 */
187
 
188
int __init stinger_init(void)
189
{
190
        serio_register_device(&stinger_dev);
191
        return 0;
192
}
193
 
194
void __exit stinger_exit(void)
195
{
196
        serio_unregister_device(&stinger_dev);
197
}
198
 
199
module_init(stinger_init);
200
module_exit(stinger_exit);
201
 
202
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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