1 /* 2 * Input driver to ExplorerPS/2 device driver module. 3 * 4 * Copyright (c) 1999-2002 Vojtech Pavlik 5 * Copyright (c) 2004 Dmitry Torokhov 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as published by 9 * the Free Software Foundation. 10 */ 11 12 #define MOUSEDEV_MINOR_BASE 32 13 #define MOUSEDEV_MINORS 32 14 #define MOUSEDEV_MIX 31 15 16 #include <linux/slab.h> 17 #include <linux/poll.h> 18 #include <linux/module.h> 19 #include <linux/moduleparam.h> 20 #include <linux/init.h> 21 #include <linux/input.h> 22 #include <linux/random.h> 23 #include <linux/major.h> 24 #include <linux/device.h> 25 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX 26 #include <linux/miscdevice.h> 27 #endif 28 29 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 30 MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces"); 31 MODULE_LICENSE("GPL"); 32 33 #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X 34 #define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024 35 #endif 36 #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_Y 37 #define CONFIG_INPUT_MOUSEDEV_SCREEN_Y 768 38 #endif 39 40 static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X; 41 module_param(xres, uint, 0644); 42 MODULE_PARM_DESC(xres, "Horizontal screen resolution"); 43 44 static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y; 45 module_param(yres, uint, 0644); 46 MODULE_PARM_DESC(yres, "Vertical screen resolution"); 47 48 static unsigned tap_time = 200; 49 module_param(tap_time, uint, 0644); 50 MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)"); 51 52 struct mousedev_hw_data { 53 int dx, dy, dz; 54 int x, y; 55 int abs_event; 56 unsigned long buttons; 57 }; 58 59 struct mousedev { 60 int exist; 61 int open; 62 int minor; 63 char name[16]; 64 wait_queue_head_t wait; 65 struct list_head client_list; 66 struct input_handle handle; 67 68 struct list_head mixdev_node; 69 int mixdev_open; 70 71 struct mousedev_hw_data packet; 72 unsigned int pkt_count; 73 int old_x[4], old_y[4]; 74 int frac_dx, frac_dy; 75 unsigned long touch; 76 }; 77 78 enum mousedev_emul { 79 MOUSEDEV_EMUL_PS2, 80 MOUSEDEV_EMUL_IMPS, 81 MOUSEDEV_EMUL_EXPS 82 }; 83 84 struct mousedev_motion { 85 int dx, dy, dz; 86 unsigned long buttons; 87 }; 88 89 #define PACKET_QUEUE_LEN 16 90 struct mousedev_client { 91 struct fasync_struct *fasync; 92 struct mousedev *mousedev; 93 struct list_head node; 94 95 struct mousedev_motion packets[PACKET_QUEUE_LEN]; 96 unsigned int head, tail; 97 spinlock_t packet_lock; 98 int pos_x, pos_y; 99 100 signed char ps2[6]; 101 unsigned char ready, buffer, bufsiz; 102 unsigned char imexseq, impsseq; 103 enum mousedev_emul mode; 104 unsigned long last_buttons; 105 }; 106 107 #define MOUSEDEV_SEQ_LEN 6 108 109 static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 }; 110 static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 }; 111 112 static struct input_handler mousedev_handler; 113 114 static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; 115 static struct mousedev mousedev_mix; 116 static LIST_HEAD(mousedev_mix_list); 117 118 #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) 119 #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) 120 121 static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value) 122 { 123 int size, tmp; 124 enum { FRACTION_DENOM = 128 }; 125 126 switch (code) { 127 case ABS_X: 128 fx(0) = value; 129 if (mousedev->touch && mousedev->pkt_count >= 2) { 130 size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; 131 if (size == 0) 132 size = 256 * 2; 133 tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size; 134 tmp += mousedev->frac_dx; 135 mousedev->packet.dx = tmp / FRACTION_DENOM; 136 mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM; 137 } 138 break; 139 140 case ABS_Y: 141 fy(0) = value; 142 if (mousedev->touch && mousedev->pkt_count >= 2) { 143 /* use X size to keep the same scale */ 144 size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; 145 if (size == 0) 146 size = 256 * 2; 147 tmp = -((value - fy(2)) * (256 * FRACTION_DENOM)) / size; 148 tmp += mousedev->frac_dy; 149 mousedev->packet.dy = tmp / FRACTION_DENOM; 150 mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM; 151 } 152 break; 153 } 154 } 155 156 static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value) 157 { 158 int size; 159 160 switch (code) { 161 case ABS_X: 162 size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; 163 if (size == 0) 164 size = xres ? : 1; 165 if (value > dev->absmax[ABS_X]) 166 value = dev->absmax[ABS_X]; 167 if (value < dev->absmin[ABS_X]) 168 value = dev->absmin[ABS_X]; 169 mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size; 170 mousedev->packet.abs_event = 1; 171 break; 172 173 case ABS_Y: 174 size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; 175 if (size == 0) 176 size = yres ? : 1; 177 if (value > dev->absmax[ABS_Y]) 178 value = dev->absmax[ABS_Y]; 179 if (value < dev->absmin[ABS_Y]) 180 value = dev->absmin[ABS_Y]; 181 mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size; 182 mousedev->packet.abs_event = 1; 183 break; 184 } 185 } 186 187 static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value) 188 { 189 switch (code) { 190 case REL_X: mousedev->packet.dx += value; break; 191 case REL_Y: mousedev->packet.dy -= value; break; 192 case REL_WHEEL: mousedev->packet.dz -= value; break; 193 } 194 } 195 196 static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value) 197 { 198 int index; 199 200 switch (code) { 201 case BTN_TOUCH: 202 case BTN_0: 203 case BTN_LEFT: index = 0; break; 204 case BTN_STYLUS: 205 case BTN_1: 206 case BTN_RIGHT: index = 1; break; 207 case BTN_2: 208 case BTN_FORWARD: 209 case BTN_STYLUS2: 210 case BTN_MIDDLE: index = 2; break; 211 case BTN_3: 212 case BTN_BACK: 213 case BTN_SIDE: index = 3; break; 214 case BTN_4: 215 case BTN_EXTRA: index = 4; break; 216 default: return; 217 } 218 219 if (value) { 220 set_bit(index, &mousedev->packet.buttons); 221 set_bit(index, &mousedev_mix.packet.buttons); 222 } else { 223 clear_bit(index, &mousedev->packet.buttons); 224 clear_bit(index, &mousedev_mix.packet.buttons); 225 } 226 } 227 228 static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_hw_data *packet) 229 { 230 struct mousedev_client *client; 231 struct mousedev_motion *p; 232 unsigned long flags; 233 int wake_readers = 0; 234 235 list_for_each_entry(client, &mousedev->client_list, node) { 236 spin_lock_irqsave(&client->packet_lock, flags); 237 238 p = &client->packets[client->head]; 239 if (client->ready && p->buttons != mousedev->packet.buttons) { 240 unsigned int new_head = (client->head + 1) % PACKET_QUEUE_LEN; 241 if (new_head != client->tail) { 242 p = &client->packets[client->head = new_head]; 243 memset(p, 0, sizeof(struct mousedev_motion)); 244 } 245 } 246 247 if (packet->abs_event) { 248 p->dx += packet->x - client->pos_x; 249 p->dy += packet->y - client->pos_y; 250 client->pos_x = packet->x; 251 client->pos_y = packet->y; 252 } 253 254 client->pos_x += packet->dx; 255 client->pos_x = client->pos_x < 0 ? 0 : (client->pos_x >= xres ? xres : client->pos_x); 256 client->pos_y += packet->dy; 257 client->pos_y = client->pos_y < 0 ? 0 : (client->pos_y >= yres ? yres : client->pos_y); 258 259 p->dx += packet->dx; 260 p->dy += packet->dy; 261 p->dz += packet->dz; 262 p->buttons = mousedev->packet.buttons; 263 264 if (p->dx || p->dy || p->dz || p->buttons != client->last_buttons) 265 client->ready = 1; 266 267 spin_unlock_irqrestore(&client->packet_lock, flags); 268 269 if (client->ready) { 270 kill_fasync(&client->fasync, SIGIO, POLL_IN); 271 wake_readers = 1; 272 } 273 } 274 275 if (wake_readers) 276 wake_up_interruptible(&mousedev->wait); 277 } 278 279 static void mousedev_touchpad_touch(struct mousedev *mousedev, int value) 280 { 281 if (!value) { 282 if (mousedev->touch && 283 time_before(jiffies, mousedev->touch + msecs_to_jiffies(tap_time))) { 284 /* 285 * Toggle left button to emulate tap. 286 * We rely on the fact that mousedev_mix always has 0 287 * motion packet so we won't mess current position. 288 */ 289 set_bit(0, &mousedev->packet.buttons); 290 set_bit(0, &mousedev_mix.packet.buttons); 291 mousedev_notify_readers(mousedev, &mousedev_mix.packet); 292 mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet); 293 clear_bit(0, &mousedev->packet.buttons); 294 clear_bit(0, &mousedev_mix.packet.buttons); 295 } 296 mousedev->touch = mousedev->pkt_count = 0; 297 mousedev->frac_dx = 0; 298 mousedev->frac_dy = 0; 299 300 } else if (!mousedev->touch) 301 mousedev->touch = jiffies; 302 } 303 304 static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) 305 { 306 struct mousedev *mousedev = handle->private; 307 308 switch (type) { 309 case EV_ABS: 310 /* Ignore joysticks */ 311 if (test_bit(BTN_TRIGGER, handle->dev->keybit)) 312 return; 313 314 if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) 315 mousedev_touchpad_event(handle->dev, mousedev, code, value); 316 else 317 mousedev_abs_event(handle->dev, mousedev, code, value); 318 319 break; 320 321 case EV_REL: 322 mousedev_rel_event(mousedev, code, value); 323 break; 324 325 case EV_KEY: 326 if (value != 2) { 327 if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) 328 mousedev_touchpad_touch(mousedev, value); 329 else 330 mousedev_key_event(mousedev, code, value); 331 } 332 break; 333 334 case EV_SYN: 335 if (code == SYN_REPORT) { 336 if (mousedev->touch) { 337 mousedev->pkt_count++; 338 /* Input system eats duplicate events, but we need all of them 339 * to do correct averaging so apply present one forward 340 */ 341 fx(0) = fx(1); 342 fy(0) = fy(1); 343 } 344 345 mousedev_notify_readers(mousedev, &mousedev->packet); 346 mousedev_notify_readers(&mousedev_mix, &mousedev->packet); 347 348 mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0; 349 mousedev->packet.abs_event = 0; 350 } 351 break; 352 } 353 } 354 355 static int mousedev_fasync(int fd, struct file *file, int on) 356 { 357 int retval; 358 struct mousedev_client *client = file->private_data; 359 360 retval = fasync_helper(fd, file, on, &client->fasync); 361 362 return retval < 0 ? retval : 0; 363 } 364 365 static void mousedev_free(struct mousedev *mousedev) 366 { 367 mousedev_table[mousedev->minor] = NULL; 368 kfree(mousedev); 369 } 370 371 static int mixdev_add_device(struct mousedev *mousedev) 372 { 373 int error; 374 375 if (mousedev_mix.open) { 376 error = input_open_device(&mousedev->handle); 377 if (error) 378 return error; 379 380 mousedev->open++; 381 mousedev->mixdev_open++; 382 } 383 384 list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); 385 386 return 0; 387 } 388 389 static void mixdev_remove_device(struct mousedev *mousedev) 390 { 391 if (mousedev->mixdev_open) { 392 mousedev->mixdev_open = 0; 393 if (!--mousedev->open && mousedev->exist) 394 input_close_device(&mousedev->handle); 395 } 396 397 list_del_init(&mousedev->mixdev_node); 398 } 399 400 static void mixdev_open_devices(void) 401 { 402 struct mousedev *mousedev; 403 404 list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { 405 if (mousedev->exist && !mousedev->open) { 406 if (input_open_device(&mousedev->handle)) 407 continue; 408 409 mousedev->open++; 410 mousedev->mixdev_open++; 411 } 412 } 413 } 414 415 static void mixdev_close_devices(void) 416 { 417 struct mousedev *mousedev, *next; 418 419 list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) { 420 if (mousedev->mixdev_open) { 421 mousedev->mixdev_open = 0; 422 if (!--mousedev->open) { 423 if (mousedev->exist) 424 input_close_device(&mousedev->handle); 425 else 426 mousedev_free(mousedev); 427 } 428 } 429 } 430 } 431 432 static int mousedev_release(struct inode *inode, struct file *file) 433 { 434 struct mousedev_client *client = file->private_data; 435 struct mousedev *mousedev = client->mousedev; 436 437 mousedev_fasync(-1, file, 0); 438 439 list_del(&client->node); 440 kfree(client); 441 442 if (!--mousedev->open) { 443 if (mousedev->minor == MOUSEDEV_MIX) 444 mixdev_close_devices(); 445 else if (mousedev->exist) 446 input_close_device(&mousedev->handle); 447 else 448 mousedev_free(mousedev); 449 } 450 451 return 0; 452 } 453 454 455 static int mousedev_open(struct inode *inode, struct file *file) 456 { 457 struct mousedev_client *client; 458 struct mousedev *mousedev; 459 int error; 460 int i; 461 462 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX 463 if (imajor(inode) == MISC_MAJOR) 464 i = MOUSEDEV_MIX; 465 else 466 #endif 467 i = iminor(inode) - MOUSEDEV_MINOR_BASE; 468 469 if (i >= MOUSEDEV_MINORS) 470 return -ENODEV; 471 472 mousedev = mousedev_table[i]; 473 if (!mousedev) 474 return -ENODEV; 475 476 client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); 477 if (!client) 478 return -ENOMEM; 479 480 spin_lock_init(&client->packet_lock); 481 client->pos_x = xres / 2; 482 client->pos_y = yres / 2; 483 client->mousedev = mousedev; 484 list_add_tail(&client->node, &mousedev->client_list); 485 486 if (!mousedev->open++) { 487 if (mousedev->minor == MOUSEDEV_MIX) 488 mixdev_open_devices(); 489 else if (mousedev->exist) { 490 error = input_open_device(&mousedev->handle); 491 if (error) { 492 list_del(&client->node); 493 kfree(client); 494 return error; 495 } 496 } 497 } 498 499 file->private_data = client; 500 return 0; 501 } 502 503 static inline int mousedev_limit_delta(int delta, int limit) 504 { 505 return delta > limit ? limit : (delta < -limit ? -limit : delta); 506 } 507 508 static void mousedev_packet(struct mousedev_client *client, signed char *ps2_data) 509 { 510 struct mousedev_motion *p; 511 unsigned long flags; 512 513 spin_lock_irqsave(&client->packet_lock, flags); 514 p = &client->packets[client->tail]; 515 516 ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07); 517 ps2_data[1] = mousedev_limit_delta(p->dx, 127); 518 ps2_data[2] = mousedev_limit_delta(p->dy, 127); 519 p->dx -= ps2_data[1]; 520 p->dy -= ps2_data[2]; 521 522 switch (client->mode) { 523 case MOUSEDEV_EMUL_EXPS: 524 ps2_data[3] = mousedev_limit_delta(p->dz, 7); 525 p->dz -= ps2_data[3]; 526 ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1); 527 client->bufsiz = 4; 528 break; 529 530 case MOUSEDEV_EMUL_IMPS: 531 ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); 532 ps2_data[3] = mousedev_limit_delta(p->dz, 127); 533 p->dz -= ps2_data[3]; 534 client->bufsiz = 4; 535 break; 536 537 case MOUSEDEV_EMUL_PS2: 538 default: 539 ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); 540 p->dz = 0; 541 client->bufsiz = 3; 542 break; 543 } 544 545 if (!p->dx && !p->dy && !p->dz) { 546 if (client->tail == client->head) { 547 client->ready = 0; 548 client->last_buttons = p->buttons; 549 } else 550 client->tail = (client->tail + 1) % PACKET_QUEUE_LEN; 551 } 552 553 spin_unlock_irqrestore(&client->packet_lock, flags); 554 } 555 556 557 static ssize_t mousedev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 558 { 559 struct mousedev_client *client = file->private_data; 560 unsigned char c; 561 unsigned int i; 562 563 for (i = 0; i < count; i++) { 564 565 if (get_user(c, buffer + i)) 566 return -EFAULT; 567 568 if (c == mousedev_imex_seq[client->imexseq]) { 569 if (++client->imexseq == MOUSEDEV_SEQ_LEN) { 570 client->imexseq = 0; 571 client->mode = MOUSEDEV_EMUL_EXPS; 572 } 573 } else 574 client->imexseq = 0; 575 576 if (c == mousedev_imps_seq[client->impsseq]) { 577 if (++client->impsseq == MOUSEDEV_SEQ_LEN) { 578 client->impsseq = 0; 579 client->mode = MOUSEDEV_EMUL_IMPS; 580 } 581 } else 582 client->impsseq = 0; 583 584 client->ps2[0] = 0xfa; 585 586 switch (c) { 587 588 case 0xeb: /* Poll */ 589 mousedev_packet(client, &client->ps2[1]); 590 client->bufsiz++; /* account for leading ACK */ 591 break; 592 593 case 0xf2: /* Get ID */ 594 switch (client->mode) { 595 case MOUSEDEV_EMUL_PS2: client->ps2[1] = 0; break; 596 case MOUSEDEV_EMUL_IMPS: client->ps2[1] = 3; break; 597 case MOUSEDEV_EMUL_EXPS: client->ps2[1] = 4; break; 598 } 599 client->bufsiz = 2; 600 break; 601 602 case 0xe9: /* Get info */ 603 client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200; 604 client->bufsiz = 4; 605 break; 606 607 case 0xff: /* Reset */ 608 client->impsseq = client->imexseq = 0; 609 client->mode = MOUSEDEV_EMUL_PS2; 610 client->ps2[1] = 0xaa; client->ps2[2] = 0x00; 611 client->bufsiz = 3; 612 break; 613 614 default: 615 client->bufsiz = 1; 616 break; 617 } 618 619 client->buffer = client->bufsiz; 620 } 621 622 kill_fasync(&client->fasync, SIGIO, POLL_IN); 623 624 wake_up_interruptible(&client->mousedev->wait); 625 626 return count; 627 } 628 629 static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) 630 { 631 struct mousedev_client *client = file->private_data; 632 int retval = 0; 633 634 if (!client->ready && !client->buffer && (file->f_flags & O_NONBLOCK)) 635 return -EAGAIN; 636 637 retval = wait_event_interruptible(client->mousedev->wait, 638 !client->mousedev->exist || client->ready || client->buffer); 639 640 if (retval) 641 return retval; 642 643 if (!client->mousedev->exist) 644 return -ENODEV; 645 646 if (!client->buffer && client->ready) { 647 mousedev_packet(client, client->ps2); 648 client->buffer = client->bufsiz; 649 } 650 651 if (count > client->buffer) 652 count = client->buffer; 653 654 client->buffer -= count; 655 656 if (copy_to_user(buffer, client->ps2 + client->bufsiz - client->buffer - count, count)) 657 return -EFAULT; 658 659 return count; 660 } 661 662 /* No kernel lock - fine */ 663 static unsigned int mousedev_poll(struct file *file, poll_table *wait) 664 { 665 struct mousedev_client *client = file->private_data; 666 struct mousedev *mousedev = client->mousedev; 667 668 poll_wait(file, &mousedev->wait, wait); 669 return ((client->ready || client->buffer) ? (POLLIN | POLLRDNORM) : 0) | 670 (mousedev->exist ? 0 : (POLLHUP | POLLERR)); 671 } 672 673 static const struct file_operations mousedev_fops = { 674 .owner = THIS_MODULE, 675 .read = mousedev_read, 676 .write = mousedev_write, 677 .poll = mousedev_poll, 678 .open = mousedev_open, 679 .release = mousedev_release, 680 .fasync = mousedev_fasync, 681 }; 682 683 static int mousedev_connect(struct input_handler *handler, struct input_dev *dev, 684 const struct input_device_id *id) 685 { 686 struct mousedev *mousedev; 687 struct class_device *cdev; 688 dev_t devt; 689 int minor; 690 int error; 691 692 for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); 693 if (minor == MOUSEDEV_MINORS) { 694 printk(KERN_ERR "mousedev: no more free mousedev devices\n"); 695 return -ENFILE; 696 } 697 698 mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); 699 if (!mousedev) 700 return -ENOMEM; 701 702 INIT_LIST_HEAD(&mousedev->client_list); 703 INIT_LIST_HEAD(&mousedev->mixdev_node); 704 init_waitqueue_head(&mousedev->wait); 705 706 mousedev->minor = minor; 707 mousedev->exist = 1; 708 mousedev->handle.dev = dev; 709 mousedev->handle.name = mousedev->name; 710 mousedev->handle.handler = handler; 711 mousedev->handle.private = mousedev; 712 sprintf(mousedev->name, "mouse%d", minor); 713 714 mousedev_table[minor] = mousedev; 715 716 devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), 717 718 cdev = class_device_create(&input_class, &dev->cdev, devt, 719 dev->cdev.dev, mousedev->name); 720 if (IS_ERR(cdev)) { 721 error = PTR_ERR(cdev); 722 goto err_free_mousedev; 723 } 724 725 /* temporary symlink to keep userspace happy */ 726 error = sysfs_create_link(&input_class.subsys.kobj, 727 &cdev->kobj, mousedev->name); 728 if (error) 729 goto err_cdev_destroy; 730 731 error = input_register_handle(&mousedev->handle); 732 if (error) 733 goto err_remove_link; 734 735 error = mixdev_add_device(mousedev); 736 if (error) 737 goto err_unregister_handle; 738 739 return 0; 740 741 err_unregister_handle: 742 input_unregister_handle(&mousedev->handle); 743 err_remove_link: 744 sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); 745 err_cdev_destroy: 746 class_device_destroy(&input_class, devt); 747 err_free_mousedev: 748 mousedev_table[minor] = NULL; 749 kfree(mousedev); 750 return error; 751 } 752 753 static void mousedev_disconnect(struct input_handle *handle) 754 { 755 struct mousedev *mousedev = handle->private; 756 struct mousedev_client *client; 757 758 input_unregister_handle(handle); 759 760 sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); 761 class_device_destroy(&input_class, 762 MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); 763 mousedev->exist = 0; 764 765 mixdev_remove_device(mousedev); 766 767 if (mousedev->open) { 768 input_close_device(handle); 769 wake_up_interruptible(&mousedev->wait); 770 list_for_each_entry(client, &mousedev->client_list, node) 771 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 772 } else 773 mousedev_free(mousedev); 774 } 775 776 static const struct input_device_id mousedev_ids[] = { 777 { 778 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT, 779 .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, 780 .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) }, 781 .relbit = { BIT(REL_X) | BIT(REL_Y) }, 782 }, /* A mouse like device, at least one button, two relative axes */ 783 { 784 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT, 785 .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, 786 .relbit = { BIT(REL_WHEEL) }, 787 }, /* A separate scrollwheel */ 788 { 789 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, 790 .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, 791 .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, 792 .absbit = { BIT(ABS_X) | BIT(ABS_Y) }, 793 }, /* A tablet like device, at least touch detection, two absolute axes */ 794 { 795 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, 796 .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, 797 .keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) }, 798 .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_TOOL_WIDTH) }, 799 }, /* A touchpad */ 800 801 { }, /* Terminating entry */ 802 }; 803 804 MODULE_DEVICE_TABLE(input, mousedev_ids); 805 806 static struct input_handler mousedev_handler = { 807 .event = mousedev_event, 808 .connect = mousedev_connect, 809 .disconnect = mousedev_disconnect, 810 .fops = &mousedev_fops, 811 .minor = MOUSEDEV_MINOR_BASE, 812 .name = "mousedev", 813 .id_table = mousedev_ids, 814 }; 815 816 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX 817 static struct miscdevice psaux_mouse = { 818 PSMOUSE_MINOR, "psaux", &mousedev_fops 819 }; 820 static int psaux_registered; 821 #endif 822 823 static int __init mousedev_init(void) 824 { 825 struct class_device *cdev; 826 int error; 827 828 error = input_register_handler(&mousedev_handler); 829 if (error) 830 return error; 831 832 memset(&mousedev_mix, 0, sizeof(struct mousedev)); 833 INIT_LIST_HEAD(&mousedev_mix.client_list); 834 init_waitqueue_head(&mousedev_mix.wait); 835 mousedev_table[MOUSEDEV_MIX] = &mousedev_mix; 836 mousedev_mix.exist = 1; 837 mousedev_mix.minor = MOUSEDEV_MIX; 838 839 cdev = class_device_create(&input_class, NULL, 840 MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice"); 841 if (IS_ERR(cdev)) { 842 input_unregister_handler(&mousedev_handler); 843 return PTR_ERR(cdev); 844 } 845 846 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX 847 error = misc_register(&psaux_mouse); 848 if (error) 849 printk(KERN_WARNING "mice: could not register psaux device, " 850 "error: %d\n", error); 851 else 852 psaux_registered = 1; 853 #endif 854 855 printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n"); 856 857 return 0; 858 } 859 860 static void __exit mousedev_exit(void) 861 { 862 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX 863 if (psaux_registered) 864 misc_deregister(&psaux_mouse); 865 #endif 866 class_device_destroy(&input_class, 867 MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX)); 868 input_unregister_handler(&mousedev_handler); 869 } 870 871 module_init(mousedev_init); 872 module_exit(mousedev_exit); 873