~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/input/input.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * $Id: input.c,v 1.7 2000/05/28 17:31:36 vojtech Exp $
  3  *
  4  *  Copyright (c) 1999-2000 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 
 41 EXPORT_SYMBOL(input_register_device);
 42 EXPORT_SYMBOL(input_unregister_device);
 43 EXPORT_SYMBOL(input_register_handler);
 44 EXPORT_SYMBOL(input_unregister_handler);
 45 EXPORT_SYMBOL(input_register_minor);
 46 EXPORT_SYMBOL(input_unregister_minor);
 47 EXPORT_SYMBOL(input_open_device);
 48 EXPORT_SYMBOL(input_close_device);
 49 EXPORT_SYMBOL(input_event);
 50 
 51 #define INPUT_MAJOR     13
 52 #define INPUT_DEVICES   256
 53 
 54 static struct input_dev *input_dev;
 55 static struct input_handler *input_handler;
 56 static struct input_handler *input_table[8];
 57 static devfs_handle_t input_devfs_handle;
 58 static int input_number;
 59 static long input_devices[NBITS(INPUT_DEVICES)];
 60 
 61 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 62 {
 63         struct input_handle *handle = dev->handle;
 64 
 65 /*
 66  * Filter non-events, and bad input values out.
 67  */
 68 
 69         if (type > EV_MAX || !test_bit(type, dev->evbit))
 70                 return;
 71 
 72         switch (type) {
 73 
 74                 case EV_KEY:
 75 
 76                         if (code > KEY_MAX || !test_bit(code, dev->keybit) || !!test_bit(code, dev->key) == value)
 77                                 return;
 78 
 79                         if (value == 2) break;
 80 
 81                         change_bit(code, dev->key);
 82 
 83                         if (test_bit(EV_REP, dev->evbit) && dev->timer.function) {
 84                                 if (value) {
 85                                         mod_timer(&dev->timer, jiffies + dev->rep[REP_DELAY]);
 86                                         dev->repeat_key = code;
 87                                         break;
 88                                 }
 89                                 if (dev->repeat_key == code)
 90                                         del_timer(&dev->timer);
 91                         }
 92 
 93                         break;
 94                 
 95                 case EV_ABS:
 96 
 97                         if (code > ABS_MAX || !test_bit(code, dev->absbit))
 98                                 return;
 99 
100                         if (dev->absfuzz[code]) {
101                                 if ((value > dev->abs[code] - (dev->absfuzz[code] >> 1)) &&
102                                     (value < dev->abs[code] + (dev->absfuzz[code] >> 1)))
103                                         return;
104 
105                                 if ((value > dev->abs[code] - dev->absfuzz[code]) &&
106                                     (value < dev->abs[code] + dev->absfuzz[code]))
107                                         value = (dev->abs[code] * 3 + value) >> 2;
108 
109                                 if ((value > dev->abs[code] - (dev->absfuzz[code] << 1)) &&
110                                     (value < dev->abs[code] + (dev->absfuzz[code] << 1)))
111                                         value = (dev->abs[code] + value) >> 1;
112                         }
113 
114                         if (dev->abs[code] == value)
115                                 return;
116 
117                         dev->abs[code] = value;
118                         break;
119 
120                 case EV_REL:
121 
122                         if (code > REL_MAX || !test_bit(code, dev->relbit) || (value == 0))
123                                 return;
124 
125                         break;
126 
127                 case EV_LED:
128         
129                         if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value)
130                                 return;
131 
132                         change_bit(code, dev->led);
133                         if (dev->event) dev->event(dev, type, code, value);     
134         
135                         break;
136 
137                 case EV_SND:
138         
139                         if (code > SND_MAX || !test_bit(code, dev->sndbit) || !!test_bit(code, dev->snd) == value)
140                                 return;
141 
142                         change_bit(code, dev->snd);
143                         if (dev->event) dev->event(dev, type, code, value);     
144         
145                         break;
146 
147                 case EV_REP:
148 
149                         if (code > REP_MAX || dev->rep[code] == value) return;
150 
151                         dev->rep[code] = value;
152                         if (dev->event) dev->event(dev, type, code, value);
153 
154                         break;
155         }
156 /*
157  * Add randomness.
158  */
159 
160 #if 0 /* BUG */
161         add_input_randomness(((unsigned long) dev) ^ (type << 24) ^ (code << 16) ^ value);
162 #endif
163 
164 /*
165  * Distribute the event to handler modules.
166  */
167 
168         while (handle) {
169                 if (handle->open)
170                         handle->handler->event(handle, type, code, value);
171                 handle = handle->dnext;
172         }
173 }
174 
175 static void input_repeat_key(unsigned long data)
176 {
177         struct input_dev *dev = (void *) data;
178         input_event(dev, EV_KEY, dev->repeat_key, 2);
179         mod_timer(&dev->timer, jiffies + dev->rep[REP_PERIOD]);
180 }
181 
182 int input_open_device(struct input_handle *handle)
183 {
184         handle->open++;
185         if (handle->dev->open)
186                 return handle->dev->open(handle->dev);
187         return 0;
188 }
189 
190 void input_close_device(struct input_handle *handle)
191 {
192         if (handle->dev->close)
193                 handle->dev->close(handle->dev);
194         handle->open--;
195 }
196 
197 static void input_link_handle(struct input_handle *handle)
198 {
199         handle->dnext = handle->dev->handle;
200         handle->hnext = handle->handler->handle;
201         handle->dev->handle = handle;
202         handle->handler->handle = handle;
203 }
204 
205 static void input_unlink_handle(struct input_handle *handle)
206 {
207         struct input_handle **handleptr;
208 
209         handleptr = &handle->dev->handle;
210         while (*handleptr && (*handleptr != handle))
211                 handleptr = &((*handleptr)->dnext);
212         *handleptr = (*handleptr)->dnext;
213 
214         handleptr = &handle->handler->handle;
215         while (*handleptr && (*handleptr != handle))
216                 handleptr = &((*handleptr)->hnext);
217         *handleptr = (*handleptr)->hnext;
218 }
219 
220 void input_register_device(struct input_dev *dev)
221 {
222         struct input_handler *handler = input_handler;
223         struct input_handle *handle;
224 
225 /*
226  * Initialize repeat timer to default values.
227  */
228 
229         init_timer(&dev->timer);
230         dev->timer.data = (long) dev;
231         dev->timer.function = input_repeat_key;
232         dev->rep[REP_DELAY] = HZ/4;
233         dev->rep[REP_PERIOD] = HZ/33;
234 
235 /*
236  * Add the device.
237  */
238 
239         if (input_number >= INPUT_DEVICES) {
240                 printk(KERN_WARNING "input: ran out of input device numbers!\n");
241                 dev->number = input_number;
242         } else {
243                 dev->number = find_first_zero_bit(input_devices, INPUT_DEVICES);
244                 set_bit(dev->number, input_devices);
245         }
246                 
247         dev->next = input_dev;  
248         input_dev = dev;
249         input_number++;
250 
251 /*
252  * Notify handlers.
253  */
254 
255         while (handler) {
256                 if ((handle = handler->connect(handler, dev)))
257                         input_link_handle(handle);
258                 handler = handler->next;
259         }
260 }
261 
262 void input_unregister_device(struct input_dev *dev)
263 {
264         struct input_handle *handle = dev->handle;
265         struct input_dev **devptr = &input_dev;
266         struct input_handle *dnext;
267 
268 /*
269  * Kill any pending repeat timers.
270  */
271 
272         del_timer(&dev->timer);
273 
274 /*
275  * Notify handlers.
276  */
277 
278         while (handle) {
279                 dnext = handle->dnext;
280                 input_unlink_handle(handle);
281                 handle->handler->disconnect(handle);
282                 handle = dnext;
283         }
284 
285 /*
286  * Remove the device.
287  */
288 
289         while (*devptr && (*devptr != dev))
290                 devptr = &((*devptr)->next);
291         *devptr = (*devptr)->next;
292 
293         input_number--;
294 
295         if (dev->number < INPUT_DEVICES)
296                 clear_bit(dev->number, input_devices);
297 }
298 
299 void input_register_handler(struct input_handler *handler)
300 {
301         struct input_dev *dev = input_dev;
302         struct input_handle *handle;
303 
304 /*
305  * Add minors if needed.
306  */
307 
308         if (handler->fops != NULL)
309                 input_table[handler->minor >> 5] = handler;
310 
311 /*
312  * Add the handler.
313  */
314 
315         handler->next = input_handler;  
316         input_handler = handler;
317         
318 /*
319  * Notify it about all existing devices.
320  */
321 
322         while (dev) {
323                 if ((handle = handler->connect(handler, dev)))
324                         input_link_handle(handle);
325                 dev = dev->next;
326         }
327 }
328 
329 void input_unregister_handler(struct input_handler *handler)
330 {
331         struct input_handler **handlerptr = &input_handler;
332         struct input_handle *handle = handler->handle;
333         struct input_handle *hnext;
334 
335 /*
336  * Tell the handler to disconnect from all devices it keeps open.
337  */
338 
339         while (handle) {
340                 hnext = handle->hnext;
341                 input_unlink_handle(handle);
342                 handler->disconnect(handle);
343                 handle = hnext;
344         }
345 
346 /*
347  * Remove it.
348  */
349 
350         while (*handlerptr && (*handlerptr != handler))
351                 handlerptr = &((*handlerptr)->next);
352 
353         *handlerptr = (*handlerptr)->next;
354 
355 /*
356  * Remove minors.
357  */
358 
359         if (handler->fops != NULL)
360                 input_table[handler->minor >> 5] = NULL;
361 }
362 
363 static int input_open_file(struct inode *inode, struct file *file)
364 {
365         struct input_handler *handler = input_table[MINOR(inode->i_rdev) >> 5];
366         struct file_operations *old_fops, *new_fops = NULL;
367         int err;
368 
369         /* No load-on-demand here? */
370         if (!handler || !(new_fops = fops_get(handler->fops)))
371                 return -ENODEV;
372 
373         /*
374          * That's _really_ odd. Usually NULL ->open means "nothing special",
375          * not "no device". Oh, well...
376          */
377         if (!new_fops->open) {
378                 fops_put(new_fops);
379                 return -ENODEV;
380         }
381         old_fops = file->f_op;
382         file->f_op = new_fops;
383 
384         lock_kernel();
385         err = new_fops->open(inode, file);
386         unlock_kernel();
387 
388         if (err) {
389                 fops_put(file->f_op);
390                 file->f_op = fops_get(old_fops);
391         }
392         fops_put(old_fops);
393         return err;
394 }
395 
396 static struct file_operations input_fops = {
397         owner: THIS_MODULE,
398         open: input_open_file,
399 };
400 
401 devfs_handle_t input_register_minor(char *name, int minor, int minor_base)
402 {
403         char devfs_name[16];
404         sprintf(devfs_name, name, minor);
405         return devfs_register(input_devfs_handle, devfs_name, DEVFS_FL_DEFAULT, INPUT_MAJOR, minor + minor_base,
406                 S_IFCHR | S_IRUGO | S_IWUSR, &input_fops, NULL);
407 }
408 
409 void input_unregister_minor(devfs_handle_t handle)
410 {
411         devfs_unregister(handle);
412 }
413 
414 static int __init input_init(void)
415 {
416         if (devfs_register_chrdev(INPUT_MAJOR, "input", &input_fops)) {
417                 printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
418                 return -EBUSY;
419         }
420         input_devfs_handle = devfs_mk_dir(NULL, "input", NULL);
421         return 0;
422 }
423 
424 static void __exit input_exit(void)
425 {
426         devfs_unregister(input_devfs_handle);
427         if (devfs_unregister_chrdev(INPUT_MAJOR, "input"))
428                 printk(KERN_ERR "input: can't unregister char major %d", INPUT_MAJOR);
429 }
430 
431 module_init(input_init);
432 module_exit(input_exit);
433 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.