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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [input/] [input.c] - Blame information for rev 1275

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

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * $Id: input.c,v 1.1.1.1 2004-04-15 02:18:56 phoenix Exp $
3
 *
4
 *  Copyright (c) 1999-2001 Vojtech Pavlik
5
 *
6
 *  The input layer module itself
7
 *
8
 *  Sponsored by SuSE
9
 */
10
 
11
/*
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
 *
26
 * Should you need to contact me, the author, you can do so either by
27
 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
28
 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
29
 */
30
 
31
#include <linux/init.h>
32
#include <linux/sched.h>
33
#include <linux/smp_lock.h>
34
#include <linux/input.h>
35
#include <linux/module.h>
36
#include <linux/random.h>
37
 
38
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
39
MODULE_DESCRIPTION("Input layer module");
40
MODULE_LICENSE("GPL");
41
 
42
 
43
EXPORT_SYMBOL(input_register_device);
44
EXPORT_SYMBOL(input_unregister_device);
45
EXPORT_SYMBOL(input_register_handler);
46
EXPORT_SYMBOL(input_unregister_handler);
47
EXPORT_SYMBOL(input_register_minor);
48
EXPORT_SYMBOL(input_unregister_minor);
49
EXPORT_SYMBOL(input_open_device);
50
EXPORT_SYMBOL(input_close_device);
51
EXPORT_SYMBOL(input_event);
52
 
53
#define INPUT_MAJOR     13
54
#define INPUT_DEVICES   256
55
 
56
static struct input_dev *input_dev;
57
static struct input_handler *input_handler;
58
static struct input_handler *input_table[8];
59
static devfs_handle_t input_devfs_handle;
60
static int input_number;
61
static long input_devices[NBITS(INPUT_DEVICES)];
62
 
63
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
64
{
65
        struct input_handle *handle = dev->handle;
66
 
67
/*
68
 * Filter non-events, and bad input values out.
69
 */
70
 
71
        if (type > EV_MAX || !test_bit(type, dev->evbit))
72
                return;
73
 
74
        switch (type) {
75
 
76
                case EV_KEY:
77
 
78
                        if (code > KEY_MAX || !test_bit(code, dev->keybit) || !!test_bit(code, dev->key) == value)
79
                                return;
80
 
81
                        if (value == 2) break;
82
 
83
                        change_bit(code, dev->key);
84
 
85
                        if (test_bit(EV_REP, dev->evbit) && dev->timer.function) {
86
                                if (value) {
87
                                        mod_timer(&dev->timer, jiffies + dev->rep[REP_DELAY]);
88
                                        dev->repeat_key = code;
89
                                        break;
90
                                }
91
                                if (dev->repeat_key == code)
92
                                        del_timer(&dev->timer);
93
                        }
94
 
95
                        break;
96
 
97
                case EV_ABS:
98
 
99
                        if (code > ABS_MAX || !test_bit(code, dev->absbit))
100
                                return;
101
 
102
                        if (dev->absfuzz[code]) {
103
                                if ((value > dev->abs[code] - (dev->absfuzz[code] >> 1)) &&
104
                                    (value < dev->abs[code] + (dev->absfuzz[code] >> 1)))
105
                                        return;
106
 
107
                                if ((value > dev->abs[code] - dev->absfuzz[code]) &&
108
                                    (value < dev->abs[code] + dev->absfuzz[code]))
109
                                        value = (dev->abs[code] * 3 + value) >> 2;
110
 
111
                                if ((value > dev->abs[code] - (dev->absfuzz[code] << 1)) &&
112
                                    (value < dev->abs[code] + (dev->absfuzz[code] << 1)))
113
                                        value = (dev->abs[code] + value) >> 1;
114
                        }
115
 
116
                        if (dev->abs[code] == value)
117
                                return;
118
 
119
                        dev->abs[code] = value;
120
                        break;
121
 
122
                case EV_REL:
123
 
124
                        if (code > REL_MAX || !test_bit(code, dev->relbit) || (value == 0))
125
                                return;
126
 
127
                        break;
128
 
129
                case EV_MSC:
130
 
131
                        if (code > MSC_MAX || !test_bit(code, dev->mscbit))
132
                                return;
133
 
134
                        if (dev->event) dev->event(dev, type, code, value);
135
 
136
                        break;
137
 
138
                case EV_LED:
139
 
140
                        if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value)
141
                                return;
142
 
143
                        change_bit(code, dev->led);
144
                        if (dev->event) dev->event(dev, type, code, value);
145
 
146
                        break;
147
 
148
                case EV_SND:
149
 
150
                        if (code > SND_MAX || !test_bit(code, dev->sndbit) || !!test_bit(code, dev->snd) == value)
151
                                return;
152
 
153
                        change_bit(code, dev->snd);
154
                        if (dev->event) dev->event(dev, type, code, value);
155
 
156
                        break;
157
 
158
                case EV_REP:
159
 
160
                        if (code > REP_MAX || dev->rep[code] == value) return;
161
 
162
                        dev->rep[code] = value;
163
                        if (dev->event) dev->event(dev, type, code, value);
164
 
165
                        break;
166
 
167
                case EV_FF:
168
                        if (dev->event) dev->event(dev, type, code, value);
169
                        break;
170
        }
171
 
172
/*
173
 * Distribute the event to handler modules.
174
 */
175
 
176
        while (handle) {
177
                if (handle->open)
178
                        handle->handler->event(handle, type, code, value);
179
                handle = handle->dnext;
180
        }
181
}
182
 
183
static void input_repeat_key(unsigned long data)
184
{
185
        struct input_dev *dev = (void *) data;
186
        input_event(dev, EV_KEY, dev->repeat_key, 2);
187
        mod_timer(&dev->timer, jiffies + dev->rep[REP_PERIOD]);
188
}
189
 
190
int input_open_device(struct input_handle *handle)
191
{
192
        handle->open++;
193
        if (handle->dev->open)
194
                return handle->dev->open(handle->dev);
195
        return 0;
196
}
197
 
198
void input_close_device(struct input_handle *handle)
199
{
200
        if (handle->dev->close)
201
                handle->dev->close(handle->dev);
202
        handle->open--;
203
}
204
 
205
static void input_link_handle(struct input_handle *handle)
206
{
207
        handle->dnext = handle->dev->handle;
208
        handle->hnext = handle->handler->handle;
209
        handle->dev->handle = handle;
210
        handle->handler->handle = handle;
211
}
212
 
213
static void input_unlink_handle(struct input_handle *handle)
214
{
215
        struct input_handle **handleptr;
216
 
217
        handleptr = &handle->dev->handle;
218
        while (*handleptr && (*handleptr != handle))
219
                handleptr = &((*handleptr)->dnext);
220
        *handleptr = (*handleptr)->dnext;
221
 
222
        handleptr = &handle->handler->handle;
223
        while (*handleptr && (*handleptr != handle))
224
                handleptr = &((*handleptr)->hnext);
225
        *handleptr = (*handleptr)->hnext;
226
}
227
 
228
void input_register_device(struct input_dev *dev)
229
{
230
        struct input_handler *handler = input_handler;
231
        struct input_handle *handle;
232
 
233
/*
234
 * Initialize repeat timer to default values.
235
 */
236
 
237
        init_timer(&dev->timer);
238
        dev->timer.data = (long) dev;
239
        dev->timer.function = input_repeat_key;
240
        dev->rep[REP_DELAY] = HZ/4;
241
        dev->rep[REP_PERIOD] = HZ/33;
242
 
243
/*
244
 * Add the device.
245
 */
246
 
247
        if (input_number >= INPUT_DEVICES) {
248
                printk(KERN_WARNING "input: ran out of input device numbers!\n");
249
                dev->number = input_number;
250
        } else {
251
                dev->number = find_first_zero_bit(input_devices, INPUT_DEVICES);
252
                set_bit(dev->number, input_devices);
253
        }
254
 
255
        dev->next = input_dev;
256
        input_dev = dev;
257
        input_number++;
258
 
259
/*
260
 * Notify handlers.
261
 */
262
 
263
        while (handler) {
264
                if ((handle = handler->connect(handler, dev)))
265
                        input_link_handle(handle);
266
                handler = handler->next;
267
        }
268
}
269
 
270
void input_unregister_device(struct input_dev *dev)
271
{
272
        struct input_handle *handle = dev->handle;
273
        struct input_dev **devptr = &input_dev;
274
        struct input_handle *dnext;
275
 
276
/*
277
 * Kill any pending repeat timers.
278
 */
279
 
280
        del_timer(&dev->timer);
281
 
282
/*
283
 * Notify handlers.
284
 */
285
 
286
        while (handle) {
287
                dnext = handle->dnext;
288
                input_unlink_handle(handle);
289
                handle->handler->disconnect(handle);
290
                handle = dnext;
291
        }
292
 
293
/*
294
 * Remove the device.
295
 */
296
 
297
        while (*devptr && (*devptr != dev))
298
                devptr = &((*devptr)->next);
299
        *devptr = (*devptr)->next;
300
 
301
        input_number--;
302
 
303
        if (dev->number < INPUT_DEVICES)
304
                clear_bit(dev->number, input_devices);
305
}
306
 
307
void input_register_handler(struct input_handler *handler)
308
{
309
        struct input_dev *dev = input_dev;
310
        struct input_handle *handle;
311
 
312
/*
313
 * Add minors if needed.
314
 */
315
 
316
        if (handler->fops != NULL)
317
                input_table[handler->minor >> 5] = handler;
318
 
319
/*
320
 * Add the handler.
321
 */
322
 
323
        handler->next = input_handler;
324
        input_handler = handler;
325
 
326
/*
327
 * Notify it about all existing devices.
328
 */
329
 
330
        while (dev) {
331
                if ((handle = handler->connect(handler, dev)))
332
                        input_link_handle(handle);
333
                dev = dev->next;
334
        }
335
}
336
 
337
void input_unregister_handler(struct input_handler *handler)
338
{
339
        struct input_handler **handlerptr = &input_handler;
340
        struct input_handle *handle = handler->handle;
341
        struct input_handle *hnext;
342
 
343
/*
344
 * Tell the handler to disconnect from all devices it keeps open.
345
 */
346
 
347
        while (handle) {
348
                hnext = handle->hnext;
349
                input_unlink_handle(handle);
350
                handler->disconnect(handle);
351
                handle = hnext;
352
        }
353
 
354
/*
355
 * Remove it.
356
 */
357
 
358
        while (*handlerptr && (*handlerptr != handler))
359
                handlerptr = &((*handlerptr)->next);
360
 
361
        *handlerptr = (*handlerptr)->next;
362
 
363
/*
364
 * Remove minors.
365
 */
366
 
367
        if (handler->fops != NULL)
368
                input_table[handler->minor >> 5] = NULL;
369
}
370
 
371
static int input_open_file(struct inode *inode, struct file *file)
372
{
373
        struct input_handler *handler = input_table[MINOR(inode->i_rdev) >> 5];
374
        struct file_operations *old_fops, *new_fops = NULL;
375
        int err;
376
 
377
        /* No load-on-demand here? */
378
        if (!handler || !(new_fops = fops_get(handler->fops)))
379
                return -ENODEV;
380
 
381
        /*
382
         * That's _really_ odd. Usually NULL ->open means "nothing special",
383
         * not "no device". Oh, well...
384
         */
385
        if (!new_fops->open) {
386
                fops_put(new_fops);
387
                return -ENODEV;
388
        }
389
        old_fops = file->f_op;
390
        file->f_op = new_fops;
391
 
392
        lock_kernel();
393
        err = new_fops->open(inode, file);
394
        unlock_kernel();
395
 
396
        if (err) {
397
                fops_put(file->f_op);
398
                file->f_op = fops_get(old_fops);
399
        }
400
        fops_put(old_fops);
401
        return err;
402
}
403
 
404
static struct file_operations input_fops = {
405
        owner: THIS_MODULE,
406
        open: input_open_file,
407
};
408
 
409
devfs_handle_t input_register_minor(char *name, int minor, int minor_base)
410
{
411
        char devfs_name[16];
412
        sprintf(devfs_name, name, minor);
413
        return devfs_register(input_devfs_handle, devfs_name, DEVFS_FL_DEFAULT, INPUT_MAJOR, minor + minor_base,
414
                S_IFCHR | S_IRUGO | S_IWUSR, &input_fops, NULL);
415
}
416
 
417
void input_unregister_minor(devfs_handle_t handle)
418
{
419
        devfs_unregister(handle);
420
}
421
 
422
static int __init input_init(void)
423
{
424
        if (devfs_register_chrdev(INPUT_MAJOR, "input", &input_fops)) {
425
                printk(KERN_ERR "input: unable to register char major %d\n", INPUT_MAJOR);
426
                return -EBUSY;
427
        }
428
        input_devfs_handle = devfs_mk_dir(NULL, "input", NULL);
429
        return 0;
430
}
431
 
432
static void __exit input_exit(void)
433
{
434
        devfs_unregister(input_devfs_handle);
435
        if (devfs_unregister_chrdev(INPUT_MAJOR, "input"))
436
                printk(KERN_ERR "input: can't unregister char major %d", INPUT_MAJOR);
437
}
438
 
439
module_init(input_init);
440
module_exit(input_exit);

powered by: WebSVN 2.1.0

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