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