diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-28 16:09:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-28 16:09:47 -0400 |
commit | 84860bf0644d7c45afe7ddbd30731c3e3c371fae (patch) | |
tree | d6c4b98a9c3fd9981e7fcc5d7729c9e01e327767 /drivers/input/joystick/analog.c | |
parent | 8caf89157d64f1eedba37113afb4b303b2b3e301 (diff) | |
parent | 6fbfddcb52d8d9fa2cd209f5ac2a1c87497d55b5 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
Diffstat (limited to 'drivers/input/joystick/analog.c')
-rw-r--r-- | drivers/input/joystick/analog.c | 96 |
1 files changed, 43 insertions, 53 deletions
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 64b1313a3c66..c75ac6eb1ffb 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c | |||
@@ -111,7 +111,7 @@ static short analog_joy_btn[] = { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN | |||
111 | static unsigned char analog_chf[] = { 0xf, 0x0, 0x1, 0x9, 0x2, 0x4, 0xc, 0x8, 0x3, 0x5, 0xb, 0x7, 0xd, 0xe, 0xa, 0x6 }; | 111 | static unsigned char analog_chf[] = { 0xf, 0x0, 0x1, 0x9, 0x2, 0x4, 0xc, 0x8, 0x3, 0x5, 0xb, 0x7, 0xd, 0xe, 0xa, 0x6 }; |
112 | 112 | ||
113 | struct analog { | 113 | struct analog { |
114 | struct input_dev dev; | 114 | struct input_dev *dev; |
115 | int mask; | 115 | int mask; |
116 | short *buttons; | 116 | short *buttons; |
117 | char name[ANALOG_MAX_NAME_LENGTH]; | 117 | char name[ANALOG_MAX_NAME_LENGTH]; |
@@ -182,7 +182,7 @@ static unsigned long analog_faketime = 0; | |||
182 | 182 | ||
183 | static void analog_decode(struct analog *analog, int *axes, int *initial, int buttons) | 183 | static void analog_decode(struct analog *analog, int *axes, int *initial, int buttons) |
184 | { | 184 | { |
185 | struct input_dev *dev = &analog->dev; | 185 | struct input_dev *dev = analog->dev; |
186 | int i, j; | 186 | int i, j; |
187 | 187 | ||
188 | if (analog->mask & ANALOG_HAT_FCS) | 188 | if (analog->mask & ANALOG_HAT_FCS) |
@@ -428,27 +428,30 @@ static void analog_name(struct analog *analog) | |||
428 | * analog_init_device() | 428 | * analog_init_device() |
429 | */ | 429 | */ |
430 | 430 | ||
431 | static void analog_init_device(struct analog_port *port, struct analog *analog, int index) | 431 | static int analog_init_device(struct analog_port *port, struct analog *analog, int index) |
432 | { | 432 | { |
433 | struct input_dev *input_dev; | ||
433 | int i, j, t, v, w, x, y, z; | 434 | int i, j, t, v, w, x, y, z; |
434 | 435 | ||
435 | analog_name(analog); | 436 | analog_name(analog); |
436 | sprintf(analog->phys, "%s/input%d", port->gameport->phys, index); | 437 | sprintf(analog->phys, "%s/input%d", port->gameport->phys, index); |
437 | analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn; | 438 | analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn; |
438 | 439 | ||
439 | init_input_dev(&analog->dev); | 440 | analog->dev = input_dev = input_allocate_device(); |
441 | if (!input_dev) | ||
442 | return -ENOMEM; | ||
440 | 443 | ||
441 | analog->dev.name = analog->name; | 444 | input_dev->name = analog->name; |
442 | analog->dev.phys = analog->phys; | 445 | input_dev->phys = analog->phys; |
443 | analog->dev.id.bustype = BUS_GAMEPORT; | 446 | input_dev->id.bustype = BUS_GAMEPORT; |
444 | analog->dev.id.vendor = GAMEPORT_ID_VENDOR_ANALOG; | 447 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG; |
445 | analog->dev.id.product = analog->mask >> 4; | 448 | input_dev->id.product = analog->mask >> 4; |
446 | analog->dev.id.version = 0x0100; | 449 | input_dev->id.version = 0x0100; |
447 | 450 | ||
448 | analog->dev.open = analog_open; | 451 | input_dev->open = analog_open; |
449 | analog->dev.close = analog_close; | 452 | input_dev->close = analog_close; |
450 | analog->dev.private = port; | 453 | input_dev->private = port; |
451 | analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 454 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
452 | 455 | ||
453 | for (i = j = 0; i < 4; i++) | 456 | for (i = j = 0; i < 4; i++) |
454 | if (analog->mask & (1 << i)) { | 457 | if (analog->mask & (1 << i)) { |
@@ -461,8 +464,6 @@ static void analog_init_device(struct analog_port *port, struct analog *analog, | |||
461 | v = (x >> 3); | 464 | v = (x >> 3); |
462 | w = (x >> 3); | 465 | w = (x >> 3); |
463 | 466 | ||
464 | set_bit(t, analog->dev.absbit); | ||
465 | |||
466 | if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3))) | 467 | if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3))) |
467 | x = y; | 468 | x = y; |
468 | 469 | ||
@@ -472,11 +473,7 @@ static void analog_init_device(struct analog_port *port, struct analog *analog, | |||
472 | w = (x >> 4); | 473 | w = (x >> 4); |
473 | } | 474 | } |
474 | 475 | ||
475 | analog->dev.absmax[t] = (x << 1) - v; | 476 | input_set_abs_params(input_dev, t, v, (x << 1) - v, port->fuzz, w); |
476 | analog->dev.absmin[t] = v; | ||
477 | analog->dev.absfuzz[t] = port->fuzz; | ||
478 | analog->dev.absflat[t] = w; | ||
479 | |||
480 | j++; | 477 | j++; |
481 | } | 478 | } |
482 | 479 | ||
@@ -484,41 +481,30 @@ static void analog_init_device(struct analog_port *port, struct analog *analog, | |||
484 | if (analog->mask & analog_exts[i]) | 481 | if (analog->mask & analog_exts[i]) |
485 | for (x = 0; x < 2; x++) { | 482 | for (x = 0; x < 2; x++) { |
486 | t = analog_hats[j++]; | 483 | t = analog_hats[j++]; |
487 | set_bit(t, analog->dev.absbit); | 484 | input_set_abs_params(input_dev, t, -1, 1, 0, 0); |
488 | analog->dev.absmax[t] = 1; | ||
489 | analog->dev.absmin[t] = -1; | ||
490 | } | 485 | } |
491 | 486 | ||
492 | for (i = j = 0; i < 4; i++) | 487 | for (i = j = 0; i < 4; i++) |
493 | if (analog->mask & (0x10 << i)) | 488 | if (analog->mask & (0x10 << i)) |
494 | set_bit(analog->buttons[j++], analog->dev.keybit); | 489 | set_bit(analog->buttons[j++], input_dev->keybit); |
495 | 490 | ||
496 | if (analog->mask & ANALOG_BTNS_CHF) | 491 | if (analog->mask & ANALOG_BTNS_CHF) |
497 | for (i = 0; i < 2; i++) | 492 | for (i = 0; i < 2; i++) |
498 | set_bit(analog->buttons[j++], analog->dev.keybit); | 493 | set_bit(analog->buttons[j++], input_dev->keybit); |
499 | 494 | ||
500 | if (analog->mask & ANALOG_HBTN_CHF) | 495 | if (analog->mask & ANALOG_HBTN_CHF) |
501 | for (i = 0; i < 4; i++) | 496 | for (i = 0; i < 4; i++) |
502 | set_bit(analog->buttons[j++], analog->dev.keybit); | 497 | set_bit(analog->buttons[j++], input_dev->keybit); |
503 | 498 | ||
504 | for (i = 0; i < 4; i++) | 499 | for (i = 0; i < 4; i++) |
505 | if (analog->mask & (ANALOG_BTN_TL << i)) | 500 | if (analog->mask & (ANALOG_BTN_TL << i)) |
506 | set_bit(analog_pads[i], analog->dev.keybit); | 501 | set_bit(analog_pads[i], input_dev->keybit); |
507 | 502 | ||
508 | analog_decode(analog, port->axes, port->initial, port->buttons); | 503 | analog_decode(analog, port->axes, port->initial, port->buttons); |
509 | 504 | ||
510 | input_register_device(&analog->dev); | 505 | input_register_device(analog->dev); |
511 | 506 | ||
512 | printk(KERN_INFO "input: %s at %s", analog->name, port->gameport->phys); | 507 | return 0; |
513 | |||
514 | if (port->cooked) | ||
515 | printk(" [ADC port]\n"); | ||
516 | else | ||
517 | printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME, | ||
518 | port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed, | ||
519 | port->speed > 10000 ? "M" : "k", | ||
520 | port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000) | ||
521 | : (port->loop * 1000000) / port->speed); | ||
522 | } | 508 | } |
523 | 509 | ||
524 | /* | 510 | /* |
@@ -659,37 +645,41 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv | |||
659 | return - ENOMEM; | 645 | return - ENOMEM; |
660 | 646 | ||
661 | err = analog_init_port(gameport, drv, port); | 647 | err = analog_init_port(gameport, drv, port); |
662 | if (err) { | 648 | if (err) |
663 | kfree(port); | 649 | goto fail1; |
664 | return err; | ||
665 | } | ||
666 | 650 | ||
667 | err = analog_init_masks(port); | 651 | err = analog_init_masks(port); |
668 | if (err) { | 652 | if (err) |
669 | gameport_close(gameport); | 653 | goto fail2; |
670 | gameport_set_drvdata(gameport, NULL); | ||
671 | kfree(port); | ||
672 | return err; | ||
673 | } | ||
674 | 654 | ||
675 | gameport_set_poll_handler(gameport, analog_poll); | 655 | gameport_set_poll_handler(gameport, analog_poll); |
676 | gameport_set_poll_interval(gameport, 10); | 656 | gameport_set_poll_interval(gameport, 10); |
677 | 657 | ||
678 | for (i = 0; i < 2; i++) | 658 | for (i = 0; i < 2; i++) |
679 | if (port->analog[i].mask) | 659 | if (port->analog[i].mask) { |
680 | analog_init_device(port, port->analog + i, i); | 660 | err = analog_init_device(port, port->analog + i, i); |
661 | if (err) | ||
662 | goto fail3; | ||
663 | } | ||
681 | 664 | ||
682 | return 0; | 665 | return 0; |
666 | |||
667 | fail3: while (--i >= 0) | ||
668 | input_unregister_device(port->analog[i].dev); | ||
669 | fail2: gameport_close(gameport); | ||
670 | fail1: gameport_set_drvdata(gameport, NULL); | ||
671 | kfree(port); | ||
672 | return err; | ||
683 | } | 673 | } |
684 | 674 | ||
685 | static void analog_disconnect(struct gameport *gameport) | 675 | static void analog_disconnect(struct gameport *gameport) |
686 | { | 676 | { |
687 | int i; | ||
688 | struct analog_port *port = gameport_get_drvdata(gameport); | 677 | struct analog_port *port = gameport_get_drvdata(gameport); |
678 | int i; | ||
689 | 679 | ||
690 | for (i = 0; i < 2; i++) | 680 | for (i = 0; i < 2; i++) |
691 | if (port->analog[i].mask) | 681 | if (port->analog[i].mask) |
692 | input_unregister_device(&port->analog[i].dev); | 682 | input_unregister_device(port->analog[i].dev); |
693 | gameport_close(gameport); | 683 | gameport_close(gameport); |
694 | gameport_set_drvdata(gameport, NULL); | 684 | gameport_set_drvdata(gameport, NULL); |
695 | printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on %s failed\n", | 685 | printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on %s failed\n", |