Subversion Repositories shark

Rev

Rev 547 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
538 mauro 1
/*
2
 *  Input driver event debug module - dumps all events into syslog
3
 */
4
 
5
/*
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
 */
20
 
21
#include <linuxcomp.h>
22
 
23
#include <linux/slab.h>
24
#include <linux/module.h>
25
#include <linux/input.h>
26
#include <linux/init.h>
27
#include <linux/device.h>
547 mauro 28
#include <linux/joystick.h>
538 mauro 29
 
30
//#define DEBUG_JOY
31
 
547 mauro 32
extern void shark_joy_exec(void);
33
 
538 mauro 34
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
35
MODULE_DESCRIPTION("Input driver joystick module");
36
MODULE_LICENSE("GPL");
37
 
547 mauro 38
#define JOYDEV_MINOR_BASE       0
39
#define JOYDEV_MINORS           4       
40
 
538 mauro 41
static char joystick_name[] = "joystick";
42
static struct input_handler joystick_handler;
43
 
547 mauro 44
struct joydev {
548 mauro 45
        /*int exist;
46
        int open;*/
547 mauro 47
        int minor;
48
        char name[16];
49
        struct js_corr corr[ABS_MAX];
50
        int nabs;
51
        int nkey;
52
        __u16 keymap[KEY_MAX - BTN_MISC];
53
        __u16 keypam[KEY_MAX - BTN_MISC];
54
        __u8 absmap[ABS_MAX];
55
        __u8 abspam[ABS_MAX];
56
        __s16 abs[ABS_MAX];
57
};
58
 
59
static struct joydev *joydev_table[JOYDEV_MINORS];
60
 
61
/* Buffer Ssize */
62
#define JOY_BUFFERSIZE 256
63
 
64
/* Buffer Mask ( i=(i+1)&MASK is better than i=(i+1)%SIZE ) */
65
#define JOY_BUFFERMASK 0xff
66
 
67
/* Circular Buffer */
68
static struct js_event jbuffer[JOY_BUFFERSIZE];
69
 
70
/*
71
 * Buffer Pointers
72
 * data is inserted to jhead
73
 * data is kept from jtail+1
74
 * (jhead point to jtail+1 when buffer is empty)
75
 */
76
static unsigned jtail, jhead;
77
 
548 mauro 78
//static int tmp_axe[4], axe[4];
547 mauro 79
 
80
/*
81
 * Get data from the joystick
82
 */
83
int joystick_get(int *type, int *number, int *value)
84
{
85
        if ( ((jtail+1) & JOY_BUFFERMASK) == ((jhead) & JOY_BUFFERMASK) )
86
                return -1;
87
        jtail = (jtail+1) & JOY_BUFFERMASK;
88
 
89
        *type   = jbuffer[jtail].type;
90
        *number = jbuffer[jtail].number;
91
        *value  = jbuffer[jtail].value;
92
 
93
#ifdef DEBUG_JOY
94
        printk(KERN_DEBUG "joystick.c: ( %3d %3d %3d)\n", *type, *number, *value);
95
#endif
96
        return 0;
97
}
98
 
99
static int joystick_correct(int value, struct js_corr *corr)
100
{
101
        switch (corr->type) {
102
                case JS_CORR_NONE:
103
                        break;
104
                case JS_CORR_BROKEN:
105
                        value = value > corr->coef[0] ? (value < corr->coef[1] ? 0 :
106
                                ((corr->coef[3] * (value - corr->coef[1])) >> 14)) :
107
                                ((corr->coef[2] * (value - corr->coef[0])) >> 14);
108
                        break;
109
                default:
110
                        return 0;
111
        }
112
 
113
        if (value < -32767) return -32767;
114
        if (value >  32767) return  32767;
115
 
116
        return value;
117
}
118
 
538 mauro 119
static void joystick_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
120
{
548 mauro 121
        struct joydev *joydev = handle->private;
122
 
547 mauro 123
        //printk(KERN_DEBUG "joystick.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", handle->dev->phys, type, code, value);
124
 
125
        switch (type) {
126
 
127
                case EV_KEY:
128
                        if (code < BTN_MISC || value == 2) return;
538 mauro 129
#ifdef DEBUG_JOY
547 mauro 130
                        printk(KERN_DEBUG "joystick.c: Event KEY. Code: %d, Value: %d\n", code, value);
538 mauro 131
#endif
547 mauro 132
                        if (jtail != jhead) {
133
                                jbuffer[jhead].type = JS_EVENT_BUTTON;
548 mauro 134
                                jbuffer[jhead].number = joydev->keymap[code - BTN_MISC];
547 mauro 135
                                jbuffer[jhead].value = value;
136
                                jhead = (jhead+1) & JOY_BUFFERMASK;
137
                        } else
138
                                return;
139
 
140
                        break;
141
 
142
                case EV_ABS:
143
#ifdef DEBUG_JOY
144
                        printk(KERN_DEBUG "joystick.c: Event ABS. Code: %d, Value: %d\n", code, value);
145
#endif
146
                        if (jtail != jhead) {
147
                                jbuffer[jhead].type = JS_EVENT_AXIS;
548 mauro 148
                                jbuffer[jhead].number = joydev->absmap[code];
149
                                jbuffer[jhead].value = joystick_correct(value, joydev->corr + jbuffer[jhead].number);
150
                                if (jbuffer[jhead].value == joydev->abs[jbuffer[jhead].number])
151
                                        return;
152
                                joydev->abs[jbuffer[jhead].number] = jbuffer[jhead].value;
547 mauro 153
                                jhead = (jhead+1) & JOY_BUFFERMASK;
154
                        } else
155
                                return;
156
 
157
                        break;
158
 
159
                case EV_SYN:
160
#ifdef DEBUG_JOY
161
                        printk(KERN_DEBUG "joystick.c: Event SYN\n");
162
#endif
163
                        return;
164
 
165
                default:
166
                        return;
167
        }
168
 
169
        shark_joy_exec();
538 mauro 170
}
171
 
172
static struct input_handle *joystick_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
173
{
174
        struct input_handle *handle;
547 mauro 175
        struct joydev *joydev;
176
        int i, j, t, minor;
538 mauro 177
 
178
        /* Avoid tablets */
179
        if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
180
                return NULL;
181
 
547 mauro 182
        for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
183
        if (minor == JOYDEV_MINORS) {
184
                printk(KERN_ERR "joydev: no more free joydev devices\n");
185
                return NULL;
186
        }
187
        if (!(joydev = kmalloc(sizeof(struct joydev), GFP_KERNEL)))
188
                return NULL;
189
        memset(joydev, 0, sizeof(struct joydev));
190
 
538 mauro 191
        if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
192
                return NULL;
193
        memset(handle, 0, sizeof(struct input_handle));
194
 
195
        handle->dev = dev;
196
        handle->handler = handler;
197
        handle->name = joystick_name;
547 mauro 198
        handle->private = joydev;
199
 
200
        joydev->minor = minor;
201
        sprintf26(joydev->name, "js%d", minor);
538 mauro 202
 
547 mauro 203
        for (i = 0; i < ABS_MAX; i++)
204
                if (test_bit(i, dev->absbit)) {
205
                        joydev->absmap[i] = joydev->nabs;
206
                        joydev->abspam[joydev->nabs] = i;
207
                        joydev->nabs++;
208
                }
538 mauro 209
 
547 mauro 210
        for (i = BTN_JOYSTICK - BTN_MISC; i < KEY_MAX - BTN_MISC; i++)
211
                if (test_bit(i + BTN_MISC, dev->keybit)) {
212
                        joydev->keymap[i] = joydev->nkey;
213
                        joydev->keypam[joydev->nkey] = i + BTN_MISC;
214
                        joydev->nkey++;
215
                }
216
 
217
        for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++)
218
                if (test_bit(i + BTN_MISC, dev->keybit)) {
219
                        joydev->keymap[i] = joydev->nkey;
220
                        joydev->keypam[joydev->nkey] = i + BTN_MISC;
221
                        joydev->nkey++;
222
                }
223
 
224
        for (i = 0; i < joydev->nabs; i++) {
225
                j = joydev->abspam[i];
226
                if (dev->absmax[j] == dev->absmin[j]) {
227
                        joydev->corr[i].type = JS_CORR_NONE;
228
                        continue;
229
                }
230
                joydev->corr[i].type = JS_CORR_BROKEN;
231
                joydev->corr[i].prec = dev->absfuzz[j];
232
                joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
233
                joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
234
                if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j])))
235
                        continue;
236
                joydev->corr[i].coef[2] = (1 << 29) / t;
237
                joydev->corr[i].coef[3] = (1 << 29) / t;
238
 
239
                joydev->abs[i] = joystick_correct(dev->abs[j], joydev->corr + i);
240
        }
241
 
242
        joydev_table[minor] = joydev;
243
 
548 mauro 244
        input_open_device(handle);
547 mauro 245
 
538 mauro 246
#ifdef DEBUG_JOY
247
        printk(KERN_DEBUG "joystick.c: Connected device: \"%s\", %s\n", dev->name, dev->phys);
248
#endif
249
 
250
        return handle;
251
}
252
 
253
static void joystick_disconnect(struct input_handle *handle)
254
{
547 mauro 255
        struct joydev *joydev = handle->private;
256
 
257
        joydev_table[joydev->minor] = NULL;
258
        kfree(joydev);
259
 
260
        input_close_device(handle);
261
 
262
        kfree(handle);
263
 
538 mauro 264
#ifdef DEBUG_JOY
265
        printk(KERN_DEBUG "joystick.c: Disconnected device: %s\n", handle->dev->phys);
266
#endif  
267
}
268
 
269
static struct input_device_id joystick_ids[] = {
270
        {
271
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
272
                .evbit = { BIT(EV_ABS) },
273
                .absbit = { BIT(ABS_X) },
274
        },
275
        {
276
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
277
                .evbit = { BIT(EV_ABS) },
278
                .absbit = { BIT(ABS_WHEEL) },
279
        },
280
        {
281
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
282
                .evbit = { BIT(EV_ABS) },
283
                .absbit = { BIT(ABS_THROTTLE) },
284
        },
285
        { },    /* Terminating entry */
286
};
287
 
288
MODULE_DEVICE_TABLE(input, joystick_ids);
289
 
290
static struct input_handler joystick_handler = {
291
        .event =        joystick_event,
292
        .connect =      joystick_connect,
293
        .disconnect =   joystick_disconnect,
294
        .name =         "joystick",
295
        .id_table =     joystick_ids,
296
};
297
 
298
int __init joystick_init(void)
299
{
547 mauro 300
        /* Initialize Buffer Variables */
301
        jhead=1;
302
        jtail=0;
303
 
538 mauro 304
        input_register_handler(&joystick_handler);
305
        return 0;
306
}
307
 
308
void __exit joystick_exit(void)
309
{
310
        input_unregister_handler(&joystick_handler);
311
}
312
 
313
module_init(joystick_init);
314
module_exit(joystick_exit);