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