linux-old/drivers/input/input.c
<<
>>
Prefs
   1/*
   2 * $Id: input.c,v 1.20 2001/05/17 15:50:27 vojtech 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
  38MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
  39MODULE_DESCRIPTION("Input layer module");
  40MODULE_LICENSE("GPL");
  41
  42
  43EXPORT_SYMBOL(input_register_device);
  44EXPORT_SYMBOL(input_unregister_device);
  45EXPORT_SYMBOL(input_register_handler);
  46EXPORT_SYMBOL(input_unregister_handler);
  47EXPORT_SYMBOL(input_register_minor);
  48EXPORT_SYMBOL(input_unregister_minor);
  49EXPORT_SYMBOL(input_open_device);
  50EXPORT_SYMBOL(input_close_device);
  51EXPORT_SYMBOL(input_event);
  52
  53#define INPUT_MAJOR     13
  54#define INPUT_DEVICES   256
  55
  56static struct input_dev *input_dev;
  57static struct input_handler *input_handler;
  58static struct input_handler *input_table[8];
  59static devfs_handle_t input_devfs_handle;
  60static int input_number;
  61static long input_devices[NBITS(INPUT_DEVICES)];
  62
  63void 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
 183static 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
 190int 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
 198void input_close_device(struct input_handle *handle)
 199{
 200        if (handle->dev->close)
 201                handle->dev->close(handle->dev);
 202        handle->open--;
 203}
 204
 205static 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
 213static 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
 228void 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
 270void 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
 307void 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
 337void 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
 371static 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
 404static struct file_operations input_fops = {
 405        owner: THIS_MODULE,
 406        open: input_open_file,
 407};
 408
 409devfs_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
 417void input_unregister_minor(devfs_handle_t handle)
 418{
 419        devfs_unregister(handle);
 420}
 421
 422static 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
 432static 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
 439module_init(input_init);
 440module_exit(input_exit);
 441
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.