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