1 /* 2 * Joystick device driver for the input driver suite. 3 * 4 * Copyright (c) 1999-2002 Vojtech Pavlik 5 * Copyright (c) 1999 Colin Van Dyke 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 as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 */ 12 13 #include <asm/io.h> 14 #include <asm/system.h> 15 #include <linux/delay.h> 16 #include <linux/errno.h> 17 #include <linux/joystick.h> 18 #include <linux/input.h> 19 #include <linux/kernel.h> 20 #include <linux/major.h> 21 #include <linux/slab.h> 22 #include <linux/mm.h> 23 #include <linux/miscdevice.h> 24 #include <linux/module.h> 25 #include <linux/poll.h> 26 #include <linux/init.h> 27 #include <linux/smp_lock.h> 28 #include <linux/device.h> 29 30 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 31 MODULE_DESCRIPTION("Joystick device interfaces"); 32 MODULE_SUPPORTED_DEVICE("input/js"); 33 MODULE_LICENSE("GPL"); 34 35 #define JOYDEV_MINOR_BASE 0 36 #define JOYDEV_MINORS 16 37 #define JOYDEV_BUFFER_SIZE 64 38 39 struct joydev { 40 int exist; 41 int open; 42 int minor; 43 char name[16]; 44 struct input_handle handle; 45 wait_queue_head_t wait; 46 struct list_head client_list; 47 struct js_corr corr[ABS_MAX + 1]; 48 struct JS_DATA_SAVE_TYPE glue; 49 int nabs; 50 int nkey; 51 __u16 keymap[KEY_MAX - BTN_MISC + 1]; 52 __u16 keypam[KEY_MAX - BTN_MISC + 1]; 53 __u8 absmap[ABS_MAX + 1]; 54 __u8 abspam[ABS_MAX + 1]; 55 __s16 abs[ABS_MAX + 1]; 56 }; 57 58 struct joydev_client { 59 struct js_event buffer[JOYDEV_BUFFER_SIZE]; 60 int head; 61 int tail; 62 int startup; 63 struct fasync_struct *fasync; 64 struct joydev *joydev; 65 struct list_head node; 66 }; 67 68 static struct joydev *joydev_table[JOYDEV_MINORS]; 69 70 static int joydev_correct(int value, struct js_corr *corr) 71 { 72 switch (corr->type) { 73 case JS_CORR_NONE: 74 break; 75 case JS_CORR_BROKEN: 76 value = value > corr->coef[0] ? (value < corr->coef[1] ? 0 : 77 ((corr->coef[3] * (value - corr->coef[1])) >> 14)) : 78 ((corr->coef[2] * (value - corr->coef[0])) >> 14); 79 break; 80 default: 81 return 0; 82 } 83 84 return value < -32767 ? -32767 : (value > 32767 ? 32767 : value); 85 } 86 87 static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) 88 { 89 struct joydev *joydev = handle->private; 90 struct joydev_client *client; 91 struct js_event event; 92 93 switch (type) { 94 95 case EV_KEY: 96 if (code < BTN_MISC || value == 2) 97 return; 98 event.type = JS_EVENT_BUTTON; 99 event.number = joydev->keymap[code - BTN_MISC]; 100 event.value = value; 101 break; 102 103 case EV_ABS: 104 event.type = JS_EVENT_AXIS; 105 event.number = joydev->absmap[code]; 106 event.value = joydev_correct(value, joydev->corr + event.number); 107 if (event.value == joydev->abs[event.number]) 108 return; 109 joydev->abs[event.number] = event.value; 110 break; 111 112 default: 113 return; 114 } 115 116 event.time = jiffies_to_msecs(jiffies); 117 118 list_for_each_entry(client, &joydev->client_list, node) { 119 120 memcpy(client->buffer + client->head, &event, sizeof(struct js_event)); 121 122 if (client->startup == joydev->nabs + joydev->nkey) 123 if (client->tail == (client->head = (client->head + 1) & (JOYDEV_BUFFER_SIZE - 1))) 124 client->startup = 0; 125 126 kill_fasync(&client->fasync, SIGIO, POLL_IN); 127 } 128 129 wake_up_interruptible(&joydev->wait); 130 } 131 132 static int joydev_fasync(int fd, struct file *file, int on) 133 { 134 int retval; 135 struct joydev_client *client = file->private_data; 136 137 retval = fasync_helper(fd, file, on, &client->fasync); 138 139 return retval < 0 ? retval : 0; 140 } 141 142 static void joydev_free(struct joydev *joydev) 143 { 144 joydev_table[joydev->minor] = NULL; 145 kfree(joydev); 146 } 147 148 static int joydev_release(struct inode *inode, struct file *file) 149 { 150 struct joydev_client *client = file->private_data; 151 struct joydev *joydev = client->joydev; 152 153 joydev_fasync(-1, file, 0); 154 155 list_del(&client->node); 156 kfree(client); 157 158 if (!--joydev->open) { 159 if (joydev->exist) 160 input_close_device(&joydev->handle); 161 else 162 joydev_free(joydev); 163 } 164 165 return 0; 166 } 167 168 static int joydev_open(struct inode *inode, struct file *file) 169 { 170 struct joydev_client *client; 171 struct joydev *joydev; 172 int i = iminor(inode) - JOYDEV_MINOR_BASE; 173 int error; 174 175 if (i >= JOYDEV_MINORS) 176 return -ENODEV; 177 178 joydev = joydev_table[i]; 179 if (!joydev || !joydev->exist) 180 return -ENODEV; 181 182 client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); 183 if (!client) 184 return -ENOMEM; 185 186 client->joydev = joydev; 187 list_add_tail(&client->node, &joydev->client_list); 188 189 if (!joydev->open++ && joydev->exist) { 190 error = input_open_device(&joydev->handle); 191 if (error) { 192 list_del(&client->node); 193 kfree(client); 194 return error; 195 } 196 } 197 198 file->private_data = client; 199 return 0; 200 } 201 202 static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 203 { 204 return -EINVAL; 205 } 206 207 static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 208 { 209 struct joydev_client *client = file->private_data; 210 struct joydev *joydev = client->joydev; 211 struct input_dev *input = joydev->handle.dev; 212 int retval = 0; 213 214 if (!joydev->exist) 215 return -ENODEV; 216 217 if (count < sizeof(struct js_event)) 218 return -EINVAL; 219 220 if (count == sizeof(struct JS_DATA_TYPE)) { 221 222 struct JS_DATA_TYPE data; 223 int i; 224 225 for (data.buttons = i = 0; i < 32 && i < joydev->nkey; i++) 226 data.buttons |= test_bit(joydev->keypam[i], input->key) ? (1 << i) : 0; 227 data.x = (joydev->abs[0] / 256 + 128) >> joydev->glue.JS_CORR.x; 228 data.y = (joydev->abs[1] / 256 + 128) >> joydev->glue.JS_CORR.y; 229 230 if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE))) 231 return -EFAULT; 232 233 client->startup = 0; 234 client->tail = client->head; 235 236 return sizeof(struct JS_DATA_TYPE); 237 } 238 239 if (client->startup == joydev->nabs + joydev->nkey && 240 client->head == client->tail && (file->f_flags & O_NONBLOCK)) 241 return -EAGAIN; 242 243 retval = wait_event_interruptible(joydev->wait, 244 !joydev->exist || 245 client->startup < joydev->nabs + joydev->nkey || 246 client->head != client->tail); 247 if (retval) 248 return retval; 249 250 if (!joydev->exist) 251 return -ENODEV; 252 253 while (client->startup < joydev->nabs + joydev->nkey && retval + sizeof(struct js_event) <= count) { 254 255 struct js_event event; 256 257 event.time = jiffies_to_msecs(jiffies); 258 259 if (client->startup < joydev->nkey) { 260 event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; 261 event.number = client->startup; 262 event.value = !!test_bit(joydev->keypam[event.number], input->key); 263 } else { 264 event.type = JS_EVENT_AXIS | JS_EVENT_INIT; 265 event.number = client->startup - joydev->nkey; 266 event.value = joydev->abs[event.number]; 267 } 268 269 if (copy_to_user(buf + retval, &event, sizeof(struct js_event))) 270 return -EFAULT; 271 272 client->startup++; 273 retval += sizeof(struct js_event); 274 } 275 276 while (client->head != client->tail && retval + sizeof(struct js_event) <= count) { 277 278 if (copy_to_user(buf + retval, client->buffer + client->tail, sizeof(struct js_event))) 279 return -EFAULT; 280 281 client->tail = (client->tail + 1) & (JOYDEV_BUFFER_SIZE - 1); 282 retval += sizeof(struct js_event); 283 } 284 285 return retval; 286 } 287 288 /* No kernel lock - fine */ 289 static unsigned int joydev_poll(struct file *file, poll_table *wait) 290 { 291 struct joydev_client *client = file->private_data; 292 struct joydev *joydev = client->joydev; 293 294 poll_wait(file, &joydev->wait, wait); 295 return ((client->head != client->tail || client->startup < joydev->nabs + joydev->nkey) ? 296 (POLLIN | POLLRDNORM) : 0) | (joydev->exist ? 0 : (POLLHUP | POLLERR)); 297 } 298 299 static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp) 300 { 301 struct input_dev *dev = joydev->handle.dev; 302 int i, j; 303 304 switch (cmd) { 305 306 case JS_SET_CAL: 307 return copy_from_user(&joydev->glue.JS_CORR, argp, 308 sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; 309 310 case JS_GET_CAL: 311 return copy_to_user(argp, &joydev->glue.JS_CORR, 312 sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; 313 314 case JS_SET_TIMEOUT: 315 return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); 316 317 case JS_GET_TIMEOUT: 318 return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); 319 320 case JSIOCGVERSION: 321 return put_user(JS_VERSION, (__u32 __user *) argp); 322 323 case JSIOCGAXES: 324 return put_user(joydev->nabs, (__u8 __user *) argp); 325 326 case JSIOCGBUTTONS: 327 return put_user(joydev->nkey, (__u8 __user *) argp); 328 329 case JSIOCSCORR: 330 if (copy_from_user(joydev->corr, argp, 331 sizeof(joydev->corr[0]) * joydev->nabs)) 332 return -EFAULT; 333 for (i = 0; i < joydev->nabs; i++) { 334 j = joydev->abspam[i]; 335 joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); 336 } 337 return 0; 338 339 case JSIOCGCORR: 340 return copy_to_user(argp, joydev->corr, 341 sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0; 342 343 case JSIOCSAXMAP: 344 if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1))) 345 return -EFAULT; 346 for (i = 0; i < joydev->nabs; i++) { 347 if (joydev->abspam[i] > ABS_MAX) 348 return -EINVAL; 349 joydev->absmap[joydev->abspam[i]] = i; 350 } 351 return 0; 352 353 case JSIOCGAXMAP: 354 return copy_to_user(argp, joydev->abspam, 355 sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0; 356 357 case JSIOCSBTNMAP: 358 if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1))) 359 return -EFAULT; 360 for (i = 0; i < joydev->nkey; i++) { 361 if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) 362 return -EINVAL; 363 joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; 364 } 365 return 0; 366 367 case JSIOCGBTNMAP: 368 return copy_to_user(argp, joydev->keypam, 369 sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0; 370 371 default: 372 if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) { 373 int len; 374 if (!dev->name) 375 return 0; 376 len = strlen(dev->name) + 1; 377 if (len > _IOC_SIZE(cmd)) 378 len = _IOC_SIZE(cmd); 379 if (copy_to_user(argp, dev->name, len)) 380 return -EFAULT; 381 return len; 382 } 383 } 384 return -EINVAL; 385 } 386 387 #ifdef CONFIG_COMPAT 388 static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 389 { 390 struct joydev_client *client = file->private_data; 391 struct joydev *joydev = client->joydev; 392 void __user *argp = (void __user *)arg; 393 s32 tmp32; 394 struct JS_DATA_SAVE_TYPE_32 ds32; 395 int err; 396 397 if (!joydev->exist) 398 return -ENODEV; 399 400 switch(cmd) { 401 case JS_SET_TIMELIMIT: 402 err = get_user(tmp32, (s32 __user *) arg); 403 if (err == 0) 404 joydev->glue.JS_TIMELIMIT = tmp32; 405 break; 406 case JS_GET_TIMELIMIT: 407 tmp32 = joydev->glue.JS_TIMELIMIT; 408 err = put_user(tmp32, (s32 __user *) arg); 409 break; 410 411 case JS_SET_ALL: 412 err = copy_from_user(&ds32, argp, 413 sizeof(ds32)) ? -EFAULT : 0; 414 if (err == 0) { 415 joydev->glue.JS_TIMEOUT = ds32.JS_TIMEOUT; 416 joydev->glue.BUSY = ds32.BUSY; 417 joydev->glue.JS_EXPIRETIME = ds32.JS_EXPIRETIME; 418 joydev->glue.JS_TIMELIMIT = ds32.JS_TIMELIMIT; 419 joydev->glue.JS_SAVE = ds32.JS_SAVE; 420 joydev->glue.JS_CORR = ds32.JS_CORR; 421 } 422 break; 423 424 case JS_GET_ALL: 425 ds32.JS_TIMEOUT = joydev->glue.JS_TIMEOUT; 426 ds32.BUSY = joydev->glue.BUSY; 427 ds32.JS_EXPIRETIME = joydev->glue.JS_EXPIRETIME; 428 ds32.JS_TIMELIMIT = joydev->glue.JS_TIMELIMIT; 429 ds32.JS_SAVE = joydev->glue.JS_SAVE; 430 ds32.JS_CORR = joydev->glue.JS_CORR; 431 432 err = copy_to_user(argp, &ds32, sizeof(ds32)) ? -EFAULT : 0; 433 break; 434 435 default: 436 err = joydev_ioctl_common(joydev, cmd, argp); 437 } 438 return err; 439 } 440 #endif /* CONFIG_COMPAT */ 441 442 static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 443 { 444 struct joydev_client *client = file->private_data; 445 struct joydev *joydev = client->joydev; 446 void __user *argp = (void __user *)arg; 447 448 if (!joydev->exist) 449 return -ENODEV; 450 451 switch(cmd) { 452 case JS_SET_TIMELIMIT: 453 return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg); 454 case JS_GET_TIMELIMIT: 455 return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg); 456 case JS_SET_ALL: 457 return copy_from_user(&joydev->glue, argp, 458 sizeof(joydev->glue)) ? -EFAULT : 0; 459 case JS_GET_ALL: 460 return copy_to_user(argp, &joydev->glue, 461 sizeof(joydev->glue)) ? -EFAULT : 0; 462 default: 463 return joydev_ioctl_common(joydev, cmd, argp); 464 } 465 } 466 467 static const struct file_operations joydev_fops = { 468 .owner = THIS_MODULE, 469 .read = joydev_read, 470 .write = joydev_write, 471 .poll = joydev_poll, 472 .open = joydev_open, 473 .release = joydev_release, 474 .ioctl = joydev_ioctl, 475 #ifdef CONFIG_COMPAT 476 .compat_ioctl = joydev_compat_ioctl, 477 #endif 478 .fasync = joydev_fasync, 479 }; 480 481 static int joydev_connect(struct input_handler *handler, struct input_dev *dev, 482 const struct input_device_id *id) 483 { 484 struct joydev *joydev; 485 struct class_device *cdev; 486 dev_t devt; 487 int i, j, t, minor; 488 int error; 489 490 for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); 491 if (minor == JOYDEV_MINORS) { 492 printk(KERN_ERR "joydev: no more free joydev devices\n"); 493 return -ENFILE; 494 } 495 496 joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL); 497 if (!joydev) 498 return -ENOMEM; 499 500 INIT_LIST_HEAD(&joydev->client_list); 501 init_waitqueue_head(&joydev->wait); 502 503 joydev->minor = minor; 504 joydev->exist = 1; 505 joydev->handle.dev = dev; 506 joydev->handle.name = joydev->name; 507 joydev->handle.handler = handler; 508 joydev->handle.private = joydev; 509 sprintf(joydev->name, "js%d", minor); 510 511 for (i = 0; i < ABS_MAX + 1; i++) 512 if (test_bit(i, dev->absbit)) { 513 joydev->absmap[i] = joydev->nabs; 514 joydev->abspam[joydev->nabs] = i; 515 joydev->nabs++; 516 } 517 518 for (i = BTN_JOYSTICK - BTN_MISC; i < KEY_MAX - BTN_MISC + 1; i++) 519 if (test_bit(i + BTN_MISC, dev->keybit)) { 520 joydev->keymap[i] = joydev->nkey; 521 joydev->keypam[joydev->nkey] = i + BTN_MISC; 522 joydev->nkey++; 523 } 524 525 for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++) 526 if (test_bit(i + BTN_MISC, dev->keybit)) { 527 joydev->keymap[i] = joydev->nkey; 528 joydev->keypam[joydev->nkey] = i + BTN_MISC; 529 joydev->nkey++; 530 } 531 532 for (i = 0; i < joydev->nabs; i++) { 533 j = joydev->abspam[i]; 534 if (dev->absmax[j] == dev->absmin[j]) { 535 joydev->corr[i].type = JS_CORR_NONE; 536 joydev->abs[i] = dev->abs[j]; 537 continue; 538 } 539 joydev->corr[i].type = JS_CORR_BROKEN; 540 joydev->corr[i].prec = dev->absfuzz[j]; 541 joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j]; 542 joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j]; 543 if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]))) 544 continue; 545 joydev->corr[i].coef[2] = (1 << 29) / t; 546 joydev->corr[i].coef[3] = (1 << 29) / t; 547 548 joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); 549 } 550 551 joydev_table[minor] = joydev; 552 553 devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), 554 555 cdev = class_device_create(&input_class, &dev->cdev, devt, 556 dev->cdev.dev, joydev->name); 557 if (IS_ERR(cdev)) { 558 error = PTR_ERR(cdev); 559 goto err_free_joydev; 560 } 561 562 /* temporary symlink to keep userspace happy */ 563 error = sysfs_create_link(&input_class.subsys.kobj, 564 &cdev->kobj, joydev->name); 565 if (error) 566 goto err_cdev_destroy; 567 568 error = input_register_handle(&joydev->handle); 569 if (error) 570 goto err_remove_link; 571 572 return 0; 573 574 err_remove_link: 575 sysfs_remove_link(&input_class.subsys.kobj, joydev->name); 576 err_cdev_destroy: 577 class_device_destroy(&input_class, devt); 578 err_free_joydev: 579 joydev_table[minor] = NULL; 580 kfree(joydev); 581 return error; 582 } 583 584 585 static void joydev_disconnect(struct input_handle *handle) 586 { 587 struct joydev *joydev = handle->private; 588 struct joydev_client *client; 589 590 input_unregister_handle(handle); 591 592 sysfs_remove_link(&input_class.subsys.kobj, joydev->name); 593 class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); 594 joydev->exist = 0; 595 596 if (joydev->open) { 597 input_close_device(handle); 598 wake_up_interruptible(&joydev->wait); 599 list_for_each_entry(client, &joydev->client_list, node) 600 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 601 } else 602 joydev_free(joydev); 603 } 604 605 static const struct input_device_id joydev_blacklist[] = { 606 { 607 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, 608 .evbit = { BIT(EV_KEY) }, 609 .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, 610 }, /* Avoid itouchpads, touchscreens and tablets */ 611 { } /* Terminating entry */ 612 }; 613 614 static const struct input_device_id joydev_ids[] = { 615 { 616 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, 617 .evbit = { BIT(EV_ABS) }, 618 .absbit = { BIT(ABS_X) }, 619 }, 620 { 621 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, 622 .evbit = { BIT(EV_ABS) }, 623 .absbit = { BIT(ABS_WHEEL) }, 624 }, 625 { 626 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, 627 .evbit = { BIT(EV_ABS) }, 628 .absbit = { BIT(ABS_THROTTLE) }, 629 }, 630 { } /* Terminating entry */ 631 }; 632 633 MODULE_DEVICE_TABLE(input, joydev_ids); 634 635 static struct input_handler joydev_handler = { 636 .event = joydev_event, 637 .connect = joydev_connect, 638 .disconnect = joydev_disconnect, 639 .fops = &joydev_fops, 640 .minor = JOYDEV_MINOR_BASE, 641 .name = "joydev", 642 .id_table = joydev_ids, 643 .blacklist = joydev_blacklist, 644 }; 645 646 static int __init joydev_init(void) 647 { 648 return input_register_handler(&joydev_handler); 649 } 650 651 static void __exit joydev_exit(void) 652 { 653 input_unregister_handler(&joydev_handler); 654 } 655 656 module_init(joydev_init); 657 module_exit(joydev_exit); 658