Subversion Repositories shark

Rev

Rev 538 | Go to most recent revision | 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 {
45
        int exist;
46
        int open;
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
 
78
static int tmp_axe[4], axe[4];
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
int joystick_enable()
100
{
101
        struct list_head *node;
102
 
103
        list_for_each(node,&joystick_handler.h_list) {
104
                struct input_handle *handle = to_handle_h(node);
105
                struct joydev *joydev = handle->private;
106
 
107
                joydev->open = 1;
108
 
109
                input_open_device(handle);
110
        }
111
 
112
        return 0;
113
}
114
 
115
int joystick_disable()
116
{
117
        struct list_head *node;
118
 
119
        list_for_each(node,&joystick_handler.h_list) {
120
                struct input_handle *handle = to_handle_h(node);
121
                struct joydev *joydev = handle->private;
122
 
123
                joydev->open = 0;
124
 
125
                input_close_device(handle);
126
 
127
        }
128
 
129
        return 0;
130
}
131
 
132
static int joystick_correct(int value, struct js_corr *corr)
133
{
134
        switch (corr->type) {
135
                case JS_CORR_NONE:
136
                        break;
137
                case JS_CORR_BROKEN:
138
                        value = value > corr->coef[0] ? (value < corr->coef[1] ? 0 :
139
                                ((corr->coef[3] * (value - corr->coef[1])) >> 14)) :
140
                                ((corr->coef[2] * (value - corr->coef[0])) >> 14);
141
                        break;
142
                default:
143
                        return 0;
144
        }
145
 
146
        if (value < -32767) return -32767;
147
        if (value >  32767) return  32767;
148
 
149
        return value;
150
}
151
 
538 mauro 152
static void joystick_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
153
{
547 mauro 154
        //printk(KERN_DEBUG "joystick.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", handle->dev->phys, type, code, value);
155
 
156
        switch (type) {
157
 
158
                case EV_KEY:
159
                        if (code < BTN_MISC || value == 2) return;
538 mauro 160
#ifdef DEBUG_JOY
547 mauro 161
                        printk(KERN_DEBUG "joystick.c: Event KEY. Code: %d, Value: %d\n", code, value);
538 mauro 162
#endif
547 mauro 163
                        if (jtail != jhead) {
164
                                jbuffer[jhead].type = JS_EVENT_BUTTON;
165
                                jbuffer[jhead].number = code - BTN_MISC;        /* TODO */
166
                                jbuffer[jhead].value = value;
167
                                jhead = (jhead+1) & JOY_BUFFERMASK;
168
                        } else
169
                                return;
170
 
171
                        break;
172
 
173
                case EV_ABS:
174
#ifdef DEBUG_JOY
175
                        printk(KERN_DEBUG "joystick.c: Event ABS. Code: %d, Value: %d\n", code, value);
176
#endif
177
                        tmp_axe[code] = value;
178
                        if (tmp_axe[code] == axe[code])
179
                                return;
180
                        axe[code] = tmp_axe[code];
181
 
182
                        if (jtail != jhead) {
183
                                jbuffer[jhead].type = JS_EVENT_AXIS;
184
                                jbuffer[jhead].number = code;                   /* TODO */
185
                                jbuffer[jhead].value = value;
186
                                jhead = (jhead+1) & JOY_BUFFERMASK;
187
                        } else
188
                                return;
189
 
190
                        break;
191
 
192
                case EV_SYN:
193
#ifdef DEBUG_JOY
194
                        printk(KERN_DEBUG "joystick.c: Event SYN\n");
195
#endif
196
                        return;
197
 
198
                default:
199
                        return;
200
        }
201
 
202
        shark_joy_exec();
538 mauro 203
}
204
 
205
static struct input_handle *joystick_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
206
{
207
        struct input_handle *handle;
547 mauro 208
        struct joydev *joydev;
209
        int i, j, t, minor;
538 mauro 210
 
211
        /* Avoid tablets */
212
        if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
213
                return NULL;
214
 
547 mauro 215
        for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
216
        if (minor == JOYDEV_MINORS) {
217
                printk(KERN_ERR "joydev: no more free joydev devices\n");
218
                return NULL;
219
        }
220
        if (!(joydev = kmalloc(sizeof(struct joydev), GFP_KERNEL)))
221
                return NULL;
222
        memset(joydev, 0, sizeof(struct joydev));
223
 
538 mauro 224
        if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
225
                return NULL;
226
        memset(handle, 0, sizeof(struct input_handle));
227
 
228
        handle->dev = dev;
229
        handle->handler = handler;
230
        handle->name = joystick_name;
547 mauro 231
        handle->private = joydev;
232
 
233
        joydev->minor = minor;
234
        joydev->exist = 1;
235
        sprintf26(joydev->name, "js%d", minor);
538 mauro 236
 
547 mauro 237
        for (i = 0; i < ABS_MAX; i++)
238
                if (test_bit(i, dev->absbit)) {
239
                        joydev->absmap[i] = joydev->nabs;
240
                        joydev->abspam[joydev->nabs] = i;
241
                        joydev->nabs++;
242
                }
538 mauro 243
 
547 mauro 244
        for (i = BTN_JOYSTICK - BTN_MISC; i < KEY_MAX - BTN_MISC; i++)
245
                if (test_bit(i + BTN_MISC, dev->keybit)) {
246
                        joydev->keymap[i] = joydev->nkey;
247
                        joydev->keypam[joydev->nkey] = i + BTN_MISC;
248
                        joydev->nkey++;
249
                }
250
 
251
        for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++)
252
                if (test_bit(i + BTN_MISC, dev->keybit)) {
253
                        joydev->keymap[i] = joydev->nkey;
254
                        joydev->keypam[joydev->nkey] = i + BTN_MISC;
255
                        joydev->nkey++;
256
                }
257
 
258
        for (i = 0; i < joydev->nabs; i++) {
259
                j = joydev->abspam[i];
260
                if (dev->absmax[j] == dev->absmin[j]) {
261
                        joydev->corr[i].type = JS_CORR_NONE;
262
                        continue;
263
                }
264
                joydev->corr[i].type = JS_CORR_BROKEN;
265
                joydev->corr[i].prec = dev->absfuzz[j];
266
                joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
267
                joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
268
                if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j])))
269
                        continue;
270
                joydev->corr[i].coef[2] = (1 << 29) / t;
271
                joydev->corr[i].coef[3] = (1 << 29) / t;
272
 
273
                joydev->abs[i] = joystick_correct(dev->abs[j], joydev->corr + i);
274
        }
275
 
276
        joydev_table[minor] = joydev;
277
 
278
        //input_open_device(handle);
279
 
538 mauro 280
#ifdef DEBUG_JOY
281
        printk(KERN_DEBUG "joystick.c: Connected device: \"%s\", %s\n", dev->name, dev->phys);
282
#endif
283
 
284
        return handle;
285
}
286
 
287
static void joystick_disconnect(struct input_handle *handle)
288
{
547 mauro 289
        struct joydev *joydev = handle->private;
290
 
291
        joydev_table[joydev->minor] = NULL;
292
        kfree(joydev);
293
 
294
        input_close_device(handle);
295
 
296
        kfree(handle);
297
 
538 mauro 298
#ifdef DEBUG_JOY
299
        printk(KERN_DEBUG "joystick.c: Disconnected device: %s\n", handle->dev->phys);
300
#endif  
301
}
302
 
303
static struct input_device_id joystick_ids[] = {
304
        {
305
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
306
                .evbit = { BIT(EV_ABS) },
307
                .absbit = { BIT(ABS_X) },
308
        },
309
        {
310
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
311
                .evbit = { BIT(EV_ABS) },
312
                .absbit = { BIT(ABS_WHEEL) },
313
        },
314
        {
315
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
316
                .evbit = { BIT(EV_ABS) },
317
                .absbit = { BIT(ABS_THROTTLE) },
318
        },
319
        { },    /* Terminating entry */
320
};
321
 
322
MODULE_DEVICE_TABLE(input, joystick_ids);
323
 
324
static struct input_handler joystick_handler = {
325
        .event =        joystick_event,
326
        .connect =      joystick_connect,
327
        .disconnect =   joystick_disconnect,
328
        .name =         "joystick",
329
        .id_table =     joystick_ids,
330
};
331
 
332
int __init joystick_init(void)
333
{
547 mauro 334
        /* Initialize Buffer Variables */
335
        jhead=1;
336
        jtail=0;
337
 
538 mauro 338
        input_register_handler(&joystick_handler);
339
        return 0;
340
}
341
 
342
void __exit joystick_exit(void)
343
{
344
        input_unregister_handler(&joystick_handler);
345
}
346
 
347
module_init(joystick_init);
348
module_exit(joystick_exit);