diff options
25 files changed, 336 insertions, 247 deletions
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 807dcd1555a6..724f46ed612f 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
| @@ -230,7 +230,7 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
| 230 | input_report_key(input, BTN_RIGHT, 0); | 230 | input_report_key(input, BTN_RIGHT, 0); |
| 231 | input_report_key(input, BTN_MIDDLE, 0); | 231 | input_report_key(input, BTN_MIDDLE, 0); |
| 232 | input_report_abs(input, ABS_DISTANCE, | 232 | input_report_abs(input, ABS_DISTANCE, |
| 233 | input->absmax[ABS_DISTANCE]); | 233 | input_abs_get_max(input, ABS_DISTANCE)); |
| 234 | } else { | 234 | } else { |
| 235 | input_report_key(input, BTN_TOUCH, 0); | 235 | input_report_key(input, BTN_TOUCH, 0); |
| 236 | input_report_key(input, BTN_STYLUS, 0); | 236 | input_report_key(input, BTN_STYLUS, 0); |
| @@ -383,38 +383,37 @@ move_on: | |||
| 383 | 383 | ||
| 384 | /* Basics */ | 384 | /* Basics */ |
| 385 | input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL); | 385 | input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL); |
| 386 | input->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | | 386 | |
| 387 | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE); | 387 | __set_bit(REL_WHEEL, input->relbit); |
| 388 | input->relbit[0] |= BIT(REL_WHEEL); | 388 | |
| 389 | set_bit(BTN_TOOL_PEN, input->keybit); | 389 | __set_bit(BTN_TOOL_PEN, input->keybit); |
| 390 | set_bit(BTN_TOUCH, input->keybit); | 390 | __set_bit(BTN_TOUCH, input->keybit); |
| 391 | set_bit(BTN_STYLUS, input->keybit); | 391 | __set_bit(BTN_STYLUS, input->keybit); |
| 392 | set_bit(BTN_STYLUS2, input->keybit); | 392 | __set_bit(BTN_STYLUS2, input->keybit); |
| 393 | set_bit(BTN_LEFT, input->keybit); | 393 | __set_bit(BTN_LEFT, input->keybit); |
| 394 | set_bit(BTN_RIGHT, input->keybit); | 394 | __set_bit(BTN_RIGHT, input->keybit); |
| 395 | set_bit(BTN_MIDDLE, input->keybit); | 395 | __set_bit(BTN_MIDDLE, input->keybit); |
| 396 | 396 | ||
| 397 | /* Pad */ | 397 | /* Pad */ |
| 398 | input->evbit[0] |= BIT(EV_MSC); | 398 | input->evbit[0] |= BIT(EV_MSC); |
| 399 | input->mscbit[0] |= BIT(MSC_SERIAL); | ||
| 400 | set_bit(BTN_0, input->keybit); | ||
| 401 | set_bit(BTN_1, input->keybit); | ||
| 402 | set_bit(BTN_TOOL_FINGER, input->keybit); | ||
| 403 | 399 | ||
| 404 | /* Distance, rubber and mouse */ | 400 | __set_bit(MSC_SERIAL, input->mscbit); |
| 405 | input->absbit[0] |= BIT(ABS_DISTANCE); | ||
| 406 | set_bit(BTN_TOOL_RUBBER, input->keybit); | ||
| 407 | set_bit(BTN_TOOL_MOUSE, input->keybit); | ||
| 408 | 401 | ||
| 409 | input->absmax[ABS_PRESSURE] = 511; | 402 | __set_bit(BTN_0, input->keybit); |
| 410 | input->absmax[ABS_DISTANCE] = 32; | 403 | __set_bit(BTN_1, input->keybit); |
| 404 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
| 411 | 405 | ||
| 412 | input->absmax[ABS_X] = 16704; | 406 | /* Distance, rubber and mouse */ |
| 413 | input->absmax[ABS_Y] = 12064; | 407 | __set_bit(BTN_TOOL_RUBBER, input->keybit); |
| 414 | input->absfuzz[ABS_X] = 4; | 408 | __set_bit(BTN_TOOL_MOUSE, input->keybit); |
| 415 | input->absfuzz[ABS_Y] = 4; | 409 | |
| 410 | input_set_abs_params(input, ABS_X, 0, 16704, 4, 0); | ||
| 411 | input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0); | ||
| 412 | input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0); | ||
| 413 | input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0); | ||
| 416 | 414 | ||
| 417 | return 0; | 415 | return 0; |
| 416 | |||
| 418 | err_free: | 417 | err_free: |
| 419 | kfree(wdata); | 418 | kfree(wdata); |
| 420 | return ret; | 419 | return ret; |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 054edf346e0b..c908c5f83645 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -492,13 +492,15 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p) | |||
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | #define OLD_KEY_MAX 0x1ff | 494 | #define OLD_KEY_MAX 0x1ff |
| 495 | static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user *p, int compat_mode) | 495 | static int handle_eviocgbit(struct input_dev *dev, |
| 496 | unsigned int type, unsigned int size, | ||
| 497 | void __user *p, int compat_mode) | ||
| 496 | { | 498 | { |
| 497 | static unsigned long keymax_warn_time; | 499 | static unsigned long keymax_warn_time; |
| 498 | unsigned long *bits; | 500 | unsigned long *bits; |
| 499 | int len; | 501 | int len; |
| 500 | 502 | ||
| 501 | switch (_IOC_NR(cmd) & EV_MAX) { | 503 | switch (type) { |
| 502 | 504 | ||
| 503 | case 0: bits = dev->evbit; len = EV_MAX; break; | 505 | case 0: bits = dev->evbit; len = EV_MAX; break; |
| 504 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; | 506 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; |
| @@ -517,7 +519,7 @@ static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user | |||
| 517 | * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len' | 519 | * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len' |
| 518 | * should be in bytes, not in bits. | 520 | * should be in bytes, not in bits. |
| 519 | */ | 521 | */ |
| 520 | if ((_IOC_NR(cmd) & EV_MAX) == EV_KEY && _IOC_SIZE(cmd) == OLD_KEY_MAX) { | 522 | if (type == EV_KEY && size == OLD_KEY_MAX) { |
| 521 | len = OLD_KEY_MAX; | 523 | len = OLD_KEY_MAX; |
| 522 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) | 524 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) |
| 523 | printk(KERN_WARNING | 525 | printk(KERN_WARNING |
| @@ -528,7 +530,7 @@ static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user | |||
| 528 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); | 530 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); |
| 529 | } | 531 | } |
| 530 | 532 | ||
| 531 | return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode); | 533 | return bits_to_user(bits, len, size, p, compat_mode); |
| 532 | } | 534 | } |
| 533 | #undef OLD_KEY_MAX | 535 | #undef OLD_KEY_MAX |
| 534 | 536 | ||
| @@ -542,8 +544,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 542 | struct ff_effect effect; | 544 | struct ff_effect effect; |
| 543 | int __user *ip = (int __user *)p; | 545 | int __user *ip = (int __user *)p; |
| 544 | unsigned int i, t, u, v; | 546 | unsigned int i, t, u, v; |
| 547 | unsigned int size; | ||
| 545 | int error; | 548 | int error; |
| 546 | 549 | ||
| 550 | /* First we check for fixed-length commands */ | ||
| 547 | switch (cmd) { | 551 | switch (cmd) { |
| 548 | 552 | ||
| 549 | case EVIOCGVERSION: | 553 | case EVIOCGVERSION: |
| @@ -610,112 +614,102 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 610 | return evdev_grab(evdev, client); | 614 | return evdev_grab(evdev, client); |
| 611 | else | 615 | else |
| 612 | return evdev_ungrab(evdev, client); | 616 | return evdev_ungrab(evdev, client); |
| 617 | } | ||
| 613 | 618 | ||
| 614 | default: | 619 | size = _IOC_SIZE(cmd); |
| 615 | |||
| 616 | if (_IOC_TYPE(cmd) != 'E') | ||
| 617 | return -EINVAL; | ||
| 618 | |||
| 619 | if (_IOC_DIR(cmd) == _IOC_READ) { | ||
| 620 | 620 | ||
| 621 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) | 621 | /* Now check variable-length commands */ |
| 622 | return handle_eviocgbit(dev, cmd, p, compat_mode); | 622 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
| 623 | 623 | ||
| 624 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) | 624 | switch (EVIOC_MASK_SIZE(cmd)) { |
| 625 | return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd), | ||
| 626 | p, compat_mode); | ||
| 627 | 625 | ||
| 628 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) | 626 | case EVIOCGKEY(0): |
| 629 | return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd), | 627 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); |
| 630 | p, compat_mode); | ||
| 631 | 628 | ||
| 632 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) | 629 | case EVIOCGLED(0): |
| 633 | return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd), | 630 | return bits_to_user(dev->led, LED_MAX, size, p, compat_mode); |
| 634 | p, compat_mode); | ||
| 635 | 631 | ||
| 636 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) | 632 | case EVIOCGSND(0): |
| 637 | return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd), | 633 | return bits_to_user(dev->snd, SND_MAX, size, p, compat_mode); |
| 638 | p, compat_mode); | ||
| 639 | 634 | ||
| 640 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) | 635 | case EVIOCGSW(0): |
| 641 | return str_to_user(dev->name, _IOC_SIZE(cmd), p); | 636 | return bits_to_user(dev->sw, SW_MAX, size, p, compat_mode); |
| 642 | 637 | ||
| 643 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) | 638 | case EVIOCGNAME(0): |
| 644 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); | 639 | return str_to_user(dev->name, size, p); |
| 645 | 640 | ||
| 646 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) | 641 | case EVIOCGPHYS(0): |
| 647 | return str_to_user(dev->uniq, _IOC_SIZE(cmd), p); | 642 | return str_to_user(dev->phys, size, p); |
| 648 | 643 | ||
| 649 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { | 644 | case EVIOCGUNIQ(0): |
| 645 | return str_to_user(dev->uniq, size, p); | ||
| 650 | 646 | ||
| 651 | t = _IOC_NR(cmd) & ABS_MAX; | 647 | case EVIOC_MASK_SIZE(EVIOCSFF): |
| 648 | if (input_ff_effect_from_user(p, size, &effect)) | ||
| 649 | return -EFAULT; | ||
| 652 | 650 | ||
| 653 | abs.value = dev->abs[t]; | 651 | error = input_ff_upload(dev, &effect, file); |
| 654 | abs.minimum = dev->absmin[t]; | ||
| 655 | abs.maximum = dev->absmax[t]; | ||
| 656 | abs.fuzz = dev->absfuzz[t]; | ||
| 657 | abs.flat = dev->absflat[t]; | ||
| 658 | abs.resolution = dev->absres[t]; | ||
| 659 | 652 | ||
| 660 | if (copy_to_user(p, &abs, min_t(size_t, | 653 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) |
| 661 | _IOC_SIZE(cmd), | 654 | return -EFAULT; |
| 662 | sizeof(struct input_absinfo)))) | ||
| 663 | return -EFAULT; | ||
| 664 | 655 | ||
| 665 | return 0; | 656 | return error; |
| 666 | } | 657 | } |
| 667 | 658 | ||
| 668 | } | 659 | /* Multi-number variable-length handlers */ |
| 660 | if (_IOC_TYPE(cmd) != 'E') | ||
| 661 | return -EINVAL; | ||
| 669 | 662 | ||
| 670 | if (_IOC_DIR(cmd) == _IOC_WRITE) { | 663 | if (_IOC_DIR(cmd) == _IOC_READ) { |
| 671 | 664 | ||
| 672 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) { | 665 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) |
| 666 | return handle_eviocgbit(dev, | ||
| 667 | _IOC_NR(cmd) & EV_MAX, size, | ||
| 668 | p, compat_mode); | ||
| 673 | 669 | ||
| 674 | if (input_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect)) | 670 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { |
| 675 | return -EFAULT; | ||
| 676 | 671 | ||
| 677 | error = input_ff_upload(dev, &effect, file); | 672 | t = _IOC_NR(cmd) & ABS_MAX; |
| 673 | abs = dev->absinfo[t]; | ||
| 678 | 674 | ||
| 679 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) | 675 | if (copy_to_user(p, &abs, min_t(size_t, |
| 680 | return -EFAULT; | 676 | size, sizeof(struct input_absinfo)))) |
| 677 | return -EFAULT; | ||
| 681 | 678 | ||
| 682 | return error; | 679 | return 0; |
| 683 | } | 680 | } |
| 681 | } | ||
| 684 | 682 | ||
| 685 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { | 683 | if (_IOC_DIR(cmd) == _IOC_READ) { |
| 686 | 684 | ||
| 687 | t = _IOC_NR(cmd) & ABS_MAX; | 685 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { |
| 688 | 686 | ||
| 689 | if (copy_from_user(&abs, p, min_t(size_t, | 687 | t = _IOC_NR(cmd) & ABS_MAX; |
| 690 | _IOC_SIZE(cmd), | ||
| 691 | sizeof(struct input_absinfo)))) | ||
| 692 | return -EFAULT; | ||
| 693 | 688 | ||
| 694 | /* We can't change number of reserved MT slots */ | 689 | if (copy_from_user(&abs, p, min_t(size_t, |
| 695 | if (t == ABS_MT_SLOT) | 690 | size, sizeof(struct input_absinfo)))) |
| 696 | return -EINVAL; | 691 | return -EFAULT; |
| 697 | 692 | ||
| 698 | /* | 693 | if (size < sizeof(struct input_absinfo)) |
| 699 | * Take event lock to ensure that we are not | 694 | abs.resolution = 0; |
| 700 | * changing device parameters in the middle | ||
| 701 | * of event. | ||
| 702 | */ | ||
| 703 | spin_lock_irq(&dev->event_lock); | ||
| 704 | 695 | ||
| 705 | dev->abs[t] = abs.value; | 696 | /* We can't change number of reserved MT slots */ |
| 706 | dev->absmin[t] = abs.minimum; | 697 | if (t == ABS_MT_SLOT) |
| 707 | dev->absmax[t] = abs.maximum; | 698 | return -EINVAL; |
| 708 | dev->absfuzz[t] = abs.fuzz; | ||
| 709 | dev->absflat[t] = abs.flat; | ||
| 710 | dev->absres[t] = _IOC_SIZE(cmd) < sizeof(struct input_absinfo) ? | ||
| 711 | 0 : abs.resolution; | ||
| 712 | 699 | ||
| 713 | spin_unlock_irq(&dev->event_lock); | 700 | /* |
| 701 | * Take event lock to ensure that we are not | ||
| 702 | * changing device parameters in the middle | ||
| 703 | * of event. | ||
| 704 | */ | ||
| 705 | spin_lock_irq(&dev->event_lock); | ||
| 706 | dev->absinfo[t] = abs; | ||
| 707 | spin_unlock_irq(&dev->event_lock); | ||
| 714 | 708 | ||
| 715 | return 0; | 709 | return 0; |
| 716 | } | ||
| 717 | } | 710 | } |
| 718 | } | 711 | } |
| 712 | |||
| 719 | return -EINVAL; | 713 | return -EINVAL; |
| 720 | } | 714 | } |
| 721 | 715 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index e1243b4b32a5..a9b025f4147a 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -182,7 +182,7 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
| 182 | is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST; | 182 | is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST; |
| 183 | 183 | ||
| 184 | if (!is_mt_event) { | 184 | if (!is_mt_event) { |
| 185 | pold = &dev->abs[code]; | 185 | pold = &dev->absinfo[code].value; |
| 186 | } else if (dev->mt) { | 186 | } else if (dev->mt) { |
| 187 | struct input_mt_slot *mtslot = &dev->mt[dev->slot]; | 187 | struct input_mt_slot *mtslot = &dev->mt[dev->slot]; |
| 188 | pold = &mtslot->abs[code - ABS_MT_FIRST]; | 188 | pold = &mtslot->abs[code - ABS_MT_FIRST]; |
| @@ -196,7 +196,7 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
| 196 | 196 | ||
| 197 | if (pold) { | 197 | if (pold) { |
| 198 | *pval = input_defuzz_abs_event(*pval, *pold, | 198 | *pval = input_defuzz_abs_event(*pval, *pold, |
| 199 | dev->absfuzz[code]); | 199 | dev->absinfo[code].fuzz); |
| 200 | if (*pold == *pval) | 200 | if (*pold == *pval) |
| 201 | return INPUT_IGNORE_EVENT; | 201 | return INPUT_IGNORE_EVENT; |
| 202 | 202 | ||
| @@ -204,8 +204,8 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | /* Flush pending "slot" event */ | 206 | /* Flush pending "slot" event */ |
| 207 | if (is_mt_event && dev->slot != dev->abs[ABS_MT_SLOT]) { | 207 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { |
| 208 | dev->abs[ABS_MT_SLOT] = dev->slot; | 208 | input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); |
| 209 | input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); | 209 | input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| @@ -391,6 +391,43 @@ void input_inject_event(struct input_handle *handle, | |||
| 391 | EXPORT_SYMBOL(input_inject_event); | 391 | EXPORT_SYMBOL(input_inject_event); |
| 392 | 392 | ||
| 393 | /** | 393 | /** |
| 394 | * input_alloc_absinfo - allocates array of input_absinfo structs | ||
| 395 | * @dev: the input device emitting absolute events | ||
| 396 | * | ||
| 397 | * If the absinfo struct the caller asked for is already allocated, this | ||
| 398 | * functions will not do anything. | ||
| 399 | */ | ||
| 400 | void input_alloc_absinfo(struct input_dev *dev) | ||
| 401 | { | ||
| 402 | if (!dev->absinfo) | ||
| 403 | dev->absinfo = kcalloc(ABS_CNT, sizeof(struct input_absinfo), | ||
| 404 | GFP_KERNEL); | ||
| 405 | |||
| 406 | WARN(!dev->absinfo, "%s(): kcalloc() failed?\n", __func__); | ||
| 407 | } | ||
| 408 | EXPORT_SYMBOL(input_alloc_absinfo); | ||
| 409 | |||
| 410 | void input_set_abs_params(struct input_dev *dev, unsigned int axis, | ||
| 411 | int min, int max, int fuzz, int flat) | ||
| 412 | { | ||
| 413 | struct input_absinfo *absinfo; | ||
| 414 | |||
| 415 | input_alloc_absinfo(dev); | ||
| 416 | if (!dev->absinfo) | ||
| 417 | return; | ||
| 418 | |||
| 419 | absinfo = &dev->absinfo[axis]; | ||
| 420 | absinfo->minimum = min; | ||
| 421 | absinfo->maximum = max; | ||
| 422 | absinfo->fuzz = fuzz; | ||
| 423 | absinfo->flat = flat; | ||
| 424 | |||
| 425 | dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis); | ||
| 426 | } | ||
| 427 | EXPORT_SYMBOL(input_set_abs_params); | ||
| 428 | |||
| 429 | |||
| 430 | /** | ||
| 394 | * input_grab_device - grabs device for exclusive use | 431 | * input_grab_device - grabs device for exclusive use |
| 395 | * @handle: input handle that wants to own the device | 432 | * @handle: input handle that wants to own the device |
| 396 | * | 433 | * |
| @@ -1308,6 +1345,7 @@ static void input_dev_release(struct device *device) | |||
| 1308 | 1345 | ||
| 1309 | input_ff_destroy(dev); | 1346 | input_ff_destroy(dev); |
| 1310 | input_mt_destroy_slots(dev); | 1347 | input_mt_destroy_slots(dev); |
| 1348 | kfree(dev->absinfo); | ||
| 1311 | kfree(dev); | 1349 | kfree(dev); |
| 1312 | 1350 | ||
| 1313 | module_put(THIS_MODULE); | 1351 | module_put(THIS_MODULE); |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 63834585c283..d85bd8a7967d 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
| @@ -530,7 +530,7 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
| 530 | { | 530 | { |
| 531 | struct input_dev *dev = joydev->handle.dev; | 531 | struct input_dev *dev = joydev->handle.dev; |
| 532 | size_t len; | 532 | size_t len; |
| 533 | int i, j; | 533 | int i; |
| 534 | const char *name; | 534 | const char *name; |
| 535 | 535 | ||
| 536 | /* Process fixed-sized commands. */ | 536 | /* Process fixed-sized commands. */ |
| @@ -562,12 +562,11 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
| 562 | case JSIOCSCORR: | 562 | case JSIOCSCORR: |
| 563 | if (copy_from_user(joydev->corr, argp, | 563 | if (copy_from_user(joydev->corr, argp, |
| 564 | sizeof(joydev->corr[0]) * joydev->nabs)) | 564 | sizeof(joydev->corr[0]) * joydev->nabs)) |
| 565 | return -EFAULT; | 565 | return -EFAULT; |
| 566 | 566 | ||
| 567 | for (i = 0; i < joydev->nabs; i++) { | 567 | for (i = 0; i < joydev->nabs; i++) { |
| 568 | j = joydev->abspam[i]; | 568 | int val = input_abs_get_val(dev, joydev->abspam[i]); |
| 569 | joydev->abs[i] = joydev_correct(dev->abs[j], | 569 | joydev->abs[i] = joydev_correct(val, &joydev->corr[i]); |
| 570 | &joydev->corr[i]); | ||
| 571 | } | 570 | } |
| 572 | return 0; | 571 | return 0; |
| 573 | 572 | ||
| @@ -848,25 +847,27 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
| 848 | 847 | ||
| 849 | for (i = 0; i < joydev->nabs; i++) { | 848 | for (i = 0; i < joydev->nabs; i++) { |
| 850 | j = joydev->abspam[i]; | 849 | j = joydev->abspam[i]; |
| 851 | if (dev->absmax[j] == dev->absmin[j]) { | 850 | if (input_abs_get_max(dev, j) == input_abs_get_min(dev, j)) { |
| 852 | joydev->corr[i].type = JS_CORR_NONE; | 851 | joydev->corr[i].type = JS_CORR_NONE; |
| 853 | joydev->abs[i] = dev->abs[j]; | 852 | joydev->abs[i] = input_abs_get_val(dev, j); |
| 854 | continue; | 853 | continue; |
| 855 | } | 854 | } |
| 856 | joydev->corr[i].type = JS_CORR_BROKEN; | 855 | joydev->corr[i].type = JS_CORR_BROKEN; |
| 857 | joydev->corr[i].prec = dev->absfuzz[j]; | 856 | joydev->corr[i].prec = input_abs_get_fuzz(dev, j); |
| 858 | joydev->corr[i].coef[0] = | 857 | |
| 859 | (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j]; | 858 | t = (input_abs_get_max(dev, j) + input_abs_get_min(dev, j)) / 2; |
| 860 | joydev->corr[i].coef[1] = | 859 | joydev->corr[i].coef[0] = t - input_abs_get_flat(dev, j); |
| 861 | (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j]; | 860 | joydev->corr[i].coef[1] = t + input_abs_get_flat(dev, j); |
| 862 | 861 | ||
| 863 | t = (dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]; | 862 | t = (input_abs_get_max(dev, j) - input_abs_get_min(dev, j)) / 2 |
| 863 | - 2 * input_abs_get_flat(dev, j); | ||
| 864 | if (t) { | 864 | if (t) { |
| 865 | joydev->corr[i].coef[2] = (1 << 29) / t; | 865 | joydev->corr[i].coef[2] = (1 << 29) / t; |
| 866 | joydev->corr[i].coef[3] = (1 << 29) / t; | 866 | joydev->corr[i].coef[3] = (1 << 29) / t; |
| 867 | 867 | ||
| 868 | joydev->abs[i] = joydev_correct(dev->abs[j], | 868 | joydev->abs[i] = |
| 869 | joydev->corr + i); | 869 | joydev_correct(input_abs_get_val(dev, j), |
| 870 | joydev->corr + i); | ||
| 870 | } | 871 | } |
| 871 | } | 872 | } |
| 872 | 873 | ||
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 6489f4010c4f..d259b41354b8 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c | |||
| @@ -342,7 +342,8 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
| 342 | 342 | ||
| 343 | for (i = 0; i < 4; i++) { | 343 | for (i = 0; i < 4; i++) { |
| 344 | if (i < 2) | 344 | if (i < 2) |
| 345 | input_set_abs_params(input_dev, axes[i], 48, input_dev->abs[axes[i]] * 2 - 48, 0, 8); | 345 | input_set_abs_params(input_dev, axes[i], |
| 346 | 48, input_abs_get_val(input_dev, axes[i]) * 2 - 48, 0, 8); | ||
| 346 | else | 347 | else |
| 347 | input_set_abs_params(input_dev, axes[i], 2, 253, 0, 0); | 348 | input_set_abs_params(input_dev, axes[i], 2, 253, 0, 0); |
| 348 | input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); | 349 | input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); |
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index 89c4c084d4ad..b992fbf91f2f 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c | |||
| @@ -452,7 +452,7 @@ static void adi_init_center(struct adi *adi) | |||
| 452 | for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) { | 452 | for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) { |
| 453 | 453 | ||
| 454 | t = adi->abs[i]; | 454 | t = adi->abs[i]; |
| 455 | x = adi->dev->abs[t]; | 455 | x = input_abs_get_val(adi->dev, t); |
| 456 | 456 | ||
| 457 | if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE) | 457 | if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE) |
| 458 | x = i < adi->axes10 ? 512 : 128; | 458 | x = i < adi->axes10 ? 512 : 128; |
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index 05022f07ec77..e90694fe0d5c 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c | |||
| @@ -139,8 +139,8 @@ static int __init amijoy_init(void) | |||
| 139 | amijoy_dev[i]->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | | 139 | amijoy_dev[i]->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | |
| 140 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 140 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); |
| 141 | for (j = 0; j < 2; j++) { | 141 | for (j = 0; j < 2; j++) { |
| 142 | amijoy_dev[i]->absmin[ABS_X + j] = -1; | 142 | XXinput_set_abs_params(amijoy_dev[i], ABS_X + j, |
| 143 | amijoy_dev[i]->absmax[ABS_X + j] = 1; | 143 | -1, 1, 0, 0); |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | err = input_register_device(amijoy_dev[i]); | 146 | err = input_register_device(amijoy_dev[i]); |
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 45ac70eae0aa..0536b1b2f018 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c | |||
| @@ -318,11 +318,8 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
| 318 | for (i = 0; i < gf2k_axes[gf2k->id]; i++) | 318 | for (i = 0; i < gf2k_axes[gf2k->id]; i++) |
| 319 | set_bit(gf2k_abs[i], input_dev->absbit); | 319 | set_bit(gf2k_abs[i], input_dev->absbit); |
| 320 | 320 | ||
| 321 | for (i = 0; i < gf2k_hats[gf2k->id]; i++) { | 321 | for (i = 0; i < gf2k_hats[gf2k->id]; i++) |
| 322 | set_bit(ABS_HAT0X + i, input_dev->absbit); | 322 | input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); |
| 323 | input_dev->absmin[ABS_HAT0X + i] = -1; | ||
| 324 | input_dev->absmax[ABS_HAT0X + i] = 1; | ||
| 325 | } | ||
| 326 | 323 | ||
| 327 | for (i = 0; i < gf2k_joys[gf2k->id]; i++) | 324 | for (i = 0; i < gf2k_joys[gf2k->id]; i++) |
| 328 | set_bit(gf2k_btn_joy[i], input_dev->keybit); | 325 | set_bit(gf2k_btn_joy[i], input_dev->keybit); |
| @@ -334,11 +331,14 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
| 334 | gf2k_read(gf2k, data); | 331 | gf2k_read(gf2k, data); |
| 335 | 332 | ||
| 336 | for (i = 0; i < gf2k_axes[gf2k->id]; i++) { | 333 | for (i = 0; i < gf2k_axes[gf2k->id]; i++) { |
| 337 | input_dev->absmax[gf2k_abs[i]] = (i < 2) ? input_dev->abs[gf2k_abs[i]] * 2 - 32 : | 334 | int max = i < 2 ? |
| 338 | input_dev->abs[gf2k_abs[0]] + input_dev->abs[gf2k_abs[1]] - 32; | 335 | input_abs_get_val(input_dev, gf2k_abs[i]) * 2 : |
| 339 | input_dev->absmin[gf2k_abs[i]] = 32; | 336 | input_abs_get_val(input_dev, gf2k_abs[0]) + |
| 340 | input_dev->absfuzz[gf2k_abs[i]] = 8; | 337 | input_abs_get_val(input_dev, gf2k_abs[1]); |
| 341 | input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0; | 338 | int flat = i < 2 ? 24 : 0; |
| 339 | |||
| 340 | input_set_abs_params(input_dev, gf2k_abs[i], | ||
| 341 | 32, max - 32, 8, flat); | ||
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | err = input_register_device(gf2k->dev); | 344 | err = input_register_device(gf2k->dev); |
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index 2478289aeeea..16fb19d1ca25 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c | |||
| @@ -270,18 +270,14 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d | |||
| 270 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 270 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
| 271 | 271 | ||
| 272 | for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) { | 272 | for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) { |
| 273 | set_bit(t, input_dev->absbit); | 273 | if (i < interact_type[interact->type].b8) |
| 274 | if (i < interact_type[interact->type].b8) { | 274 | input_set_abs_params(input_dev, t, 0, 255, 0, 0); |
| 275 | input_dev->absmin[t] = 0; | 275 | else |
| 276 | input_dev->absmax[t] = 255; | 276 | input_set_abs_params(input_dev, t, -1, 1, 0, 0); |
| 277 | } else { | ||
| 278 | input_dev->absmin[t] = -1; | ||
| 279 | input_dev->absmax[t] = 1; | ||
| 280 | } | ||
| 281 | } | 277 | } |
| 282 | 278 | ||
| 283 | for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++) | 279 | for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++) |
| 284 | set_bit(t, input_dev->keybit); | 280 | __set_bit(t, input_dev->keybit); |
| 285 | 281 | ||
| 286 | err = input_register_device(interact->dev); | 282 | err = input_register_device(interact->dev); |
| 287 | if (err) | 283 | if (err) |
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index ca13a6bec33e..b8d86115644b 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c | |||
| @@ -761,17 +761,21 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
| 761 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 761 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
| 762 | 762 | ||
| 763 | for (j = 0; (bits = sw_bit[sw->type][j]); j++) { | 763 | for (j = 0; (bits = sw_bit[sw->type][j]); j++) { |
| 764 | int min, max, fuzz, flat; | ||
| 765 | |||
| 764 | code = sw_abs[sw->type][j]; | 766 | code = sw_abs[sw->type][j]; |
| 765 | set_bit(code, input_dev->absbit); | 767 | min = bits == 1 ? -1 : 0; |
| 766 | input_dev->absmax[code] = (1 << bits) - 1; | 768 | max = (1 << bits) - 1; |
| 767 | input_dev->absmin[code] = (bits == 1) ? -1 : 0; | 769 | fuzz = (bits >> 1) >= 2 ? 1 << ((bits >> 1) - 2) : 0; |
| 768 | input_dev->absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0; | 770 | flat = code == ABS_THROTTLE || bits < 5 ? |
| 769 | if (code != ABS_THROTTLE) | 771 | 0 : 1 << (bits - 5); |
| 770 | input_dev->absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0; | 772 | |
| 773 | input_set_abs_params(input_dev, code, | ||
| 774 | min, max, fuzz, flat); | ||
| 771 | } | 775 | } |
| 772 | 776 | ||
| 773 | for (j = 0; (code = sw_btn[sw->type][j]); j++) | 777 | for (j = 0; (code = sw_btn[sw->type][j]); j++) |
| 774 | set_bit(code, input_dev->keybit); | 778 | __set_bit(code, input_dev->keybit); |
| 775 | 779 | ||
| 776 | dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k); | 780 | dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k); |
| 777 | 781 | ||
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 269a846f3694..f9fb7fa10af3 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
| @@ -148,6 +148,7 @@ static const struct xpad_device { | |||
| 148 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX }, | 148 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX }, |
| 149 | { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX }, | 149 | { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX }, |
| 150 | { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, | 150 | { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
| 151 | { 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, | ||
| 151 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX }, | 152 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX }, |
| 152 | { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, | 153 | { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, |
| 153 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, | 154 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index a9fd147f2ba7..6069abe31e42 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
| @@ -39,6 +39,8 @@ struct gpio_keys_drvdata { | |||
| 39 | struct input_dev *input; | 39 | struct input_dev *input; |
| 40 | struct mutex disable_lock; | 40 | struct mutex disable_lock; |
| 41 | unsigned int n_buttons; | 41 | unsigned int n_buttons; |
| 42 | int (*enable)(struct device *dev); | ||
| 43 | void (*disable)(struct device *dev); | ||
| 42 | struct gpio_button_data data[0]; | 44 | struct gpio_button_data data[0]; |
| 43 | }; | 45 | }; |
| 44 | 46 | ||
| @@ -423,6 +425,21 @@ fail2: | |||
| 423 | return error; | 425 | return error; |
| 424 | } | 426 | } |
| 425 | 427 | ||
| 428 | static int gpio_keys_open(struct input_dev *input) | ||
| 429 | { | ||
| 430 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); | ||
| 431 | |||
| 432 | return ddata->enable ? ddata->enable(input->dev.parent) : 0; | ||
| 433 | } | ||
| 434 | |||
| 435 | static void gpio_keys_close(struct input_dev *input) | ||
| 436 | { | ||
| 437 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); | ||
| 438 | |||
| 439 | if (ddata->disable) | ||
| 440 | ddata->disable(input->dev.parent); | ||
| 441 | } | ||
| 442 | |||
| 426 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 443 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
| 427 | { | 444 | { |
| 428 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 445 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
| @@ -444,13 +461,18 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
| 444 | 461 | ||
| 445 | ddata->input = input; | 462 | ddata->input = input; |
| 446 | ddata->n_buttons = pdata->nbuttons; | 463 | ddata->n_buttons = pdata->nbuttons; |
| 464 | ddata->enable = pdata->enable; | ||
| 465 | ddata->disable = pdata->disable; | ||
| 447 | mutex_init(&ddata->disable_lock); | 466 | mutex_init(&ddata->disable_lock); |
| 448 | 467 | ||
| 449 | platform_set_drvdata(pdev, ddata); | 468 | platform_set_drvdata(pdev, ddata); |
| 469 | input_set_drvdata(input, ddata); | ||
| 450 | 470 | ||
| 451 | input->name = pdev->name; | 471 | input->name = pdev->name; |
| 452 | input->phys = "gpio-keys/input0"; | 472 | input->phys = "gpio-keys/input0"; |
| 453 | input->dev.parent = &pdev->dev; | 473 | input->dev.parent = &pdev->dev; |
| 474 | input->open = gpio_keys_open; | ||
| 475 | input->close = gpio_keys_close; | ||
| 454 | 476 | ||
| 455 | input->id.bustype = BUS_HOST; | 477 | input->id.bustype = BUS_HOST; |
| 456 | input->id.vendor = 0x0001; | 478 | input->id.vendor = 0x0001; |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index c83f4b2ec7d3..ddd5afd301d4 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
| @@ -232,15 +232,16 @@ static void hil_dev_handle_ptr_events(struct hil_dev *ptr) | |||
| 232 | if (absdev) { | 232 | if (absdev) { |
| 233 | val = lo + (hi << 8); | 233 | val = lo + (hi << 8); |
| 234 | #ifdef TABLET_AUTOADJUST | 234 | #ifdef TABLET_AUTOADJUST |
| 235 | if (val < dev->absmin[ABS_X + i]) | 235 | if (val < input_abs_min(dev, ABS_X + i)) |
| 236 | dev->absmin[ABS_X + i] = val; | 236 | input_abs_set_min(dev, ABS_X + i, val); |
| 237 | if (val > dev->absmax[ABS_X + i]) | 237 | if (val > input_abs_max(dev, ABS_X + i)) |
| 238 | dev->absmax[ABS_X + i] = val; | 238 | XXinput_abs_set_max(dev, ABS_X + i, val); |
| 239 | #endif | 239 | #endif |
| 240 | if (i%3) val = dev->absmax[ABS_X + i] - val; | 240 | if (i % 3) |
| 241 | val = input_abs_max(dev, ABS_X + i) - val; | ||
| 241 | input_report_abs(dev, ABS_X + i, val); | 242 | input_report_abs(dev, ABS_X + i, val); |
| 242 | } else { | 243 | } else { |
| 243 | val = (int) (((int8_t)lo) | ((int8_t)hi << 8)); | 244 | val = (int) (((int8_t) lo) | ((int8_t) hi << 8)); |
| 244 | if (i % 3) | 245 | if (i % 3) |
| 245 | val *= -1; | 246 | val *= -1; |
| 246 | input_report_rel(dev, REL_X + i, val); | 247 | input_report_rel(dev, REL_X + i, val); |
| @@ -387,9 +388,11 @@ static void hil_dev_pointer_setup(struct hil_dev *ptr) | |||
| 387 | 388 | ||
| 388 | #ifdef TABLET_AUTOADJUST | 389 | #ifdef TABLET_AUTOADJUST |
| 389 | for (i = 0; i < ABS_MAX; i++) { | 390 | for (i = 0; i < ABS_MAX; i++) { |
| 390 | int diff = input_dev->absmax[ABS_X + i] / 10; | 391 | int diff = input_abs_max(input_dev, ABS_X + i) / 10; |
| 391 | input_dev->absmin[ABS_X + i] += diff; | 392 | input_abs_set_min(input_dev, ABS_X + i, |
| 392 | input_dev->absmax[ABS_X + i] -= diff; | 393 | input_abs_min(input_dev, ABS_X + i) + diff) |
| 394 | XXinput_abs_set_max(input_dev, ABS_X + i, | ||
| 395 | input_abs_max(input_dev, ABS_X + i) - diff) | ||
| 393 | } | 396 | } |
| 394 | #endif | 397 | #endif |
| 395 | 398 | ||
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index e2ca01708080..de5900d50788 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c | |||
| @@ -724,7 +724,6 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, | |||
| 724 | pdata = &ac->pdata; | 724 | pdata = &ac->pdata; |
| 725 | 725 | ||
| 726 | ac->input = input_dev; | 726 | ac->input = input_dev; |
| 727 | ac->disabled = true; | ||
| 728 | ac->dev = dev; | 727 | ac->dev = dev; |
| 729 | ac->irq = irq; | 728 | ac->irq = irq; |
| 730 | ac->bops = bops; | 729 | ac->bops = bops; |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index b71eb55f2dbc..bb53fd33cd1c 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
| @@ -304,21 +304,25 @@ static int uinput_validate_absbits(struct input_dev *dev) | |||
| 304 | if (!test_bit(cnt, dev->absbit)) | 304 | if (!test_bit(cnt, dev->absbit)) |
| 305 | continue; | 305 | continue; |
| 306 | 306 | ||
| 307 | if ((dev->absmax[cnt] <= dev->absmin[cnt])) { | 307 | if (input_abs_get_max(dev, cnt) <= input_abs_get_min(dev, cnt)) { |
| 308 | printk(KERN_DEBUG | 308 | printk(KERN_DEBUG |
| 309 | "%s: invalid abs[%02x] min:%d max:%d\n", | 309 | "%s: invalid abs[%02x] min:%d max:%d\n", |
| 310 | UINPUT_NAME, cnt, | 310 | UINPUT_NAME, cnt, |
| 311 | dev->absmin[cnt], dev->absmax[cnt]); | 311 | input_abs_get_min(dev, cnt), |
| 312 | input_abs_get_max(dev, cnt)); | ||
| 312 | retval = -EINVAL; | 313 | retval = -EINVAL; |
| 313 | break; | 314 | break; |
| 314 | } | 315 | } |
| 315 | 316 | ||
| 316 | if (dev->absflat[cnt] > (dev->absmax[cnt] - dev->absmin[cnt])) { | 317 | if (input_abs_get_flat(dev, cnt) > |
| 318 | input_abs_get_max(dev, cnt) - input_abs_get_min(dev, cnt)) { | ||
| 317 | printk(KERN_DEBUG | 319 | printk(KERN_DEBUG |
| 318 | "%s: absflat[%02x] out of range: %d " | 320 | "%s: abs_flat #%02x out of range: %d " |
| 319 | "(min:%d/max:%d)\n", | 321 | "(min:%d/max:%d)\n", |
| 320 | UINPUT_NAME, cnt, dev->absflat[cnt], | 322 | UINPUT_NAME, cnt, |
| 321 | dev->absmin[cnt], dev->absmax[cnt]); | 323 | input_abs_get_flat(dev, cnt), |
| 324 | input_abs_get_min(dev, cnt), | ||
| 325 | input_abs_get_max(dev, cnt)); | ||
| 322 | retval = -EINVAL; | 326 | retval = -EINVAL; |
| 323 | break; | 327 | break; |
| 324 | } | 328 | } |
| @@ -343,7 +347,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
| 343 | struct uinput_user_dev *user_dev; | 347 | struct uinput_user_dev *user_dev; |
| 344 | struct input_dev *dev; | 348 | struct input_dev *dev; |
| 345 | char *name; | 349 | char *name; |
| 346 | int size; | 350 | int i, size; |
| 347 | int retval; | 351 | int retval; |
| 348 | 352 | ||
| 349 | if (count != sizeof(struct uinput_user_dev)) | 353 | if (count != sizeof(struct uinput_user_dev)) |
| @@ -387,11 +391,12 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
| 387 | dev->id.product = user_dev->id.product; | 391 | dev->id.product = user_dev->id.product; |
| 388 | dev->id.version = user_dev->id.version; | 392 | dev->id.version = user_dev->id.version; |
| 389 | 393 | ||
| 390 | size = sizeof(int) * ABS_CNT; | 394 | for (i = 0; i < ABS_CNT; i++) { |
| 391 | memcpy(dev->absmax, user_dev->absmax, size); | 395 | input_abs_set_max(dev, i, user_dev->absmax[i]); |
| 392 | memcpy(dev->absmin, user_dev->absmin, size); | 396 | input_abs_set_min(dev, i, user_dev->absmin[i]); |
| 393 | memcpy(dev->absfuzz, user_dev->absfuzz, size); | 397 | input_abs_set_fuzz(dev, i, user_dev->absfuzz[i]); |
| 394 | memcpy(dev->absflat, user_dev->absflat, size); | 398 | input_abs_set_flat(dev, i, user_dev->absflat[i]); |
| 399 | } | ||
| 395 | 400 | ||
| 396 | /* check if absmin/absmax/absfuzz/absflat are filled as | 401 | /* check if absmin/absmax/absfuzz/absflat are filled as |
| 397 | * told in Documentation/input/input-programming.txt */ | 402 | * told in Documentation/input/input-programming.txt */ |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index b18862b2a70e..48311204ba51 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
| @@ -185,7 +185,6 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
| 185 | struct elantech_data *etd = psmouse->private; | 185 | struct elantech_data *etd = psmouse->private; |
| 186 | unsigned char *packet = psmouse->packet; | 186 | unsigned char *packet = psmouse->packet; |
| 187 | int fingers; | 187 | int fingers; |
| 188 | static int old_fingers; | ||
| 189 | 188 | ||
| 190 | if (etd->fw_version < 0x020000) { | 189 | if (etd->fw_version < 0x020000) { |
| 191 | /* | 190 | /* |
| @@ -203,10 +202,13 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
| 203 | } | 202 | } |
| 204 | 203 | ||
| 205 | if (etd->jumpy_cursor) { | 204 | if (etd->jumpy_cursor) { |
| 206 | /* Discard packets that are likely to have bogus coordinates */ | 205 | if (fingers != 1) { |
| 207 | if (fingers > old_fingers) { | 206 | etd->single_finger_reports = 0; |
| 207 | } else if (etd->single_finger_reports < 2) { | ||
| 208 | /* Discard first 2 reports of one finger, bogus */ | ||
| 209 | etd->single_finger_reports++; | ||
| 208 | elantech_debug("discarding packet\n"); | 210 | elantech_debug("discarding packet\n"); |
| 209 | goto discard_packet_v1; | 211 | return; |
| 210 | } | 212 | } |
| 211 | } | 213 | } |
| 212 | 214 | ||
| @@ -238,9 +240,6 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
| 238 | } | 240 | } |
| 239 | 241 | ||
| 240 | input_sync(dev); | 242 | input_sync(dev); |
| 241 | |||
| 242 | discard_packet_v1: | ||
| 243 | old_fingers = fingers; | ||
| 244 | } | 243 | } |
| 245 | 244 | ||
| 246 | /* | 245 | /* |
| @@ -258,6 +257,14 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
| 258 | input_report_key(dev, BTN_TOUCH, fingers != 0); | 257 | input_report_key(dev, BTN_TOUCH, fingers != 0); |
| 259 | 258 | ||
| 260 | switch (fingers) { | 259 | switch (fingers) { |
| 260 | case 3: | ||
| 261 | /* | ||
| 262 | * Same as one finger, except report of more than 3 fingers: | ||
| 263 | * byte 3: n4 . w1 w0 . . . . | ||
| 264 | */ | ||
| 265 | if (packet[3] & 0x80) | ||
| 266 | fingers = 4; | ||
| 267 | /* pass through... */ | ||
| 261 | case 1: | 268 | case 1: |
| 262 | /* | 269 | /* |
| 263 | * byte 1: . . . . . x10 x9 x8 | 270 | * byte 1: . . . . . x10 x9 x8 |
| @@ -310,6 +317,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
| 310 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 317 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
| 311 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | 318 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); |
| 312 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | 319 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); |
| 320 | input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); | ||
| 313 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 321 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); |
| 314 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 322 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
| 315 | 323 | ||
| @@ -467,6 +475,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
| 467 | break; | 475 | break; |
| 468 | 476 | ||
| 469 | case 2: | 477 | case 2: |
| 478 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | ||
| 470 | input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); | 479 | input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); |
| 471 | input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); | 480 | input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); |
| 472 | input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0); | 481 | input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0); |
| @@ -733,13 +742,13 @@ int elantech_init(struct psmouse *psmouse) | |||
| 733 | etd->capabilities = param[0]; | 742 | etd->capabilities = param[0]; |
| 734 | 743 | ||
| 735 | /* | 744 | /* |
| 736 | * This firmware seems to suffer from misreporting coordinates when | 745 | * This firmware suffers from misreporting coordinates when |
| 737 | * a touch action starts causing the mouse cursor or scrolled page | 746 | * a touch action starts causing the mouse cursor or scrolled page |
| 738 | * to jump. Enable a workaround. | 747 | * to jump. Enable a workaround. |
| 739 | */ | 748 | */ |
| 740 | if (etd->fw_version == 0x020022) { | 749 | if (etd->fw_version == 0x020022 || etd->fw_version == 0x020600) { |
| 741 | pr_info("firmware version 2.0.34 detected, enabling jumpy cursor workaround\n"); | 750 | pr_info("firmware version 2.0.34/2.6.0 detected, enabling jumpy cursor workaround\n"); |
| 742 | etd->jumpy_cursor = 1; | 751 | etd->jumpy_cursor = true; |
| 743 | } | 752 | } |
| 744 | 753 | ||
| 745 | if (elantech_set_absolute_mode(psmouse)) { | 754 | if (elantech_set_absolute_mode(psmouse)) { |
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index ac57bde1bb9f..aa4aac5d2198 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
| @@ -100,10 +100,11 @@ struct elantech_data { | |||
| 100 | unsigned char reg_26; | 100 | unsigned char reg_26; |
| 101 | unsigned char debug; | 101 | unsigned char debug; |
| 102 | unsigned char capabilities; | 102 | unsigned char capabilities; |
| 103 | unsigned char paritycheck; | 103 | bool paritycheck; |
| 104 | unsigned char jumpy_cursor; | 104 | bool jumpy_cursor; |
| 105 | unsigned char hw_version; | 105 | unsigned char hw_version; |
| 106 | unsigned int fw_version; | 106 | unsigned int fw_version; |
| 107 | unsigned int single_finger_reports; | ||
| 107 | unsigned char parity[256]; | 108 | unsigned char parity[256]; |
| 108 | }; | 109 | }; |
| 109 | 110 | ||
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index 3941f97cfa60..7b02b652e267 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c | |||
| @@ -145,8 +145,8 @@ static int __init pc110pad_init(void) | |||
| 145 | pc110pad_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); | 145 | pc110pad_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); |
| 146 | pc110pad_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 146 | pc110pad_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
| 147 | 147 | ||
| 148 | pc110pad_dev->absmax[ABS_X] = 0x1ff; | 148 | input_abs_set_max(pc110pad_dev, ABS_X, 0x1ff); |
| 149 | pc110pad_dev->absmax[ABS_Y] = 0x0ff; | 149 | input_abs_set_max(pc110pad_dev, ABS_Y, 0x0ff); |
| 150 | 150 | ||
| 151 | pc110pad_dev->open = pc110pad_open; | 151 | pc110pad_dev->open = pc110pad_open; |
| 152 | pc110pad_dev->close = pc110pad_close; | 152 | pc110pad_dev->close = pc110pad_close; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 8c324403b9f2..96b70a43515f 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -635,8 +635,8 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
| 635 | __clear_bit(REL_X, dev->relbit); | 635 | __clear_bit(REL_X, dev->relbit); |
| 636 | __clear_bit(REL_Y, dev->relbit); | 636 | __clear_bit(REL_Y, dev->relbit); |
| 637 | 637 | ||
| 638 | dev->absres[ABS_X] = priv->x_res; | 638 | input_abs_set_res(dev, ABS_X, priv->x_res); |
| 639 | dev->absres[ABS_Y] = priv->y_res; | 639 | input_abs_set_res(dev, ABS_Y, priv->y_res); |
| 640 | 640 | ||
| 641 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | 641 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
| 642 | /* Clickpads report only left button */ | 642 | /* Clickpads report only left button */ |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index d8f68f77007b..83c24cca234a 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/random.h> | 22 | #include <linux/random.h> |
| 23 | #include <linux/major.h> | 23 | #include <linux/major.h> |
| 24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
| 25 | #include <linux/kernel.h> | ||
| 25 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 26 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
| 26 | #include <linux/miscdevice.h> | 27 | #include <linux/miscdevice.h> |
| 27 | #endif | 28 | #endif |
| @@ -134,11 +135,14 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
| 134 | switch (code) { | 135 | switch (code) { |
| 135 | 136 | ||
| 136 | case ABS_X: | 137 | case ABS_X: |
| 138 | |||
| 137 | fx(0) = value; | 139 | fx(0) = value; |
| 138 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 140 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
| 139 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; | 141 | size = input_abs_get_min(dev, ABS_X) - |
| 142 | input_abs_get_max(dev, ABS_X); | ||
| 140 | if (size == 0) | 143 | if (size == 0) |
| 141 | size = 256 * 2; | 144 | size = 256 * 2; |
| 145 | |||
| 142 | tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size; | 146 | tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size; |
| 143 | tmp += mousedev->frac_dx; | 147 | tmp += mousedev->frac_dx; |
| 144 | mousedev->packet.dx = tmp / FRACTION_DENOM; | 148 | mousedev->packet.dx = tmp / FRACTION_DENOM; |
| @@ -150,10 +154,12 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
| 150 | case ABS_Y: | 154 | case ABS_Y: |
| 151 | fy(0) = value; | 155 | fy(0) = value; |
| 152 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 156 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
| 153 | /* use X size to keep the same scale */ | 157 | /* use X size for ABS_Y to keep the same scale */ |
| 154 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; | 158 | size = input_abs_get_min(dev, ABS_X) - |
| 159 | input_abs_get_max(dev, ABS_X); | ||
| 155 | if (size == 0) | 160 | if (size == 0) |
| 156 | size = 256 * 2; | 161 | size = 256 * 2; |
| 162 | |||
| 157 | tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size; | 163 | tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size; |
| 158 | tmp += mousedev->frac_dy; | 164 | tmp += mousedev->frac_dy; |
| 159 | mousedev->packet.dy = tmp / FRACTION_DENOM; | 165 | mousedev->packet.dy = tmp / FRACTION_DENOM; |
| @@ -167,33 +173,35 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
| 167 | static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, | 173 | static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, |
| 168 | unsigned int code, int value) | 174 | unsigned int code, int value) |
| 169 | { | 175 | { |
| 170 | int size; | 176 | int min, max, size; |
| 171 | 177 | ||
| 172 | switch (code) { | 178 | switch (code) { |
| 173 | 179 | ||
| 174 | case ABS_X: | 180 | case ABS_X: |
| 175 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; | 181 | min = input_abs_get_min(dev, ABS_X); |
| 182 | max = input_abs_get_max(dev, ABS_X); | ||
| 183 | |||
| 184 | size = max - min; | ||
| 176 | if (size == 0) | 185 | if (size == 0) |
| 177 | size = xres ? : 1; | 186 | size = xres ? : 1; |
| 178 | if (value > dev->absmax[ABS_X]) | 187 | |
| 179 | value = dev->absmax[ABS_X]; | 188 | clamp(value, min, max); |
| 180 | if (value < dev->absmin[ABS_X]) | 189 | |
| 181 | value = dev->absmin[ABS_X]; | 190 | mousedev->packet.x = ((value - min) * xres) / size; |
| 182 | mousedev->packet.x = | ||
| 183 | ((value - dev->absmin[ABS_X]) * xres) / size; | ||
| 184 | mousedev->packet.abs_event = 1; | 191 | mousedev->packet.abs_event = 1; |
| 185 | break; | 192 | break; |
| 186 | 193 | ||
| 187 | case ABS_Y: | 194 | case ABS_Y: |
| 188 | size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; | 195 | min = input_abs_get_min(dev, ABS_Y); |
| 196 | max = input_abs_get_max(dev, ABS_Y); | ||
| 197 | |||
| 198 | size = max - min; | ||
| 189 | if (size == 0) | 199 | if (size == 0) |
| 190 | size = yres ? : 1; | 200 | size = yres ? : 1; |
| 191 | if (value > dev->absmax[ABS_Y]) | 201 | |
| 192 | value = dev->absmax[ABS_Y]; | 202 | clamp(value, min, max); |
| 193 | if (value < dev->absmin[ABS_Y]) | 203 | |
| 194 | value = dev->absmin[ABS_Y]; | 204 | mousedev->packet.y = yres - ((value - min) * yres) / size; |
| 195 | mousedev->packet.y = yres - | ||
| 196 | ((value - dev->absmin[ABS_Y]) * yres) / size; | ||
| 197 | mousedev->packet.abs_event = 1; | 205 | mousedev->packet.abs_event = 1; |
| 198 | break; | 206 | break; |
| 199 | } | 207 | } |
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 51b80b08d467..57b25b84d1fc 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
| @@ -987,20 +987,17 @@ static int aiptek_program_tablet(struct aiptek *aiptek) | |||
| 987 | /* Query getXextension */ | 987 | /* Query getXextension */ |
| 988 | if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0) | 988 | if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0) |
| 989 | return ret; | 989 | return ret; |
| 990 | aiptek->inputdev->absmin[ABS_X] = 0; | 990 | input_set_abs_params(aiptek->inputdev, ABS_X, 0, ret - 1, 0, 0); |
| 991 | aiptek->inputdev->absmax[ABS_X] = ret - 1; | ||
| 992 | 991 | ||
| 993 | /* Query getYextension */ | 992 | /* Query getYextension */ |
| 994 | if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0) | 993 | if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0) |
| 995 | return ret; | 994 | return ret; |
| 996 | aiptek->inputdev->absmin[ABS_Y] = 0; | 995 | input_set_abs_params(aiptek->inputdev, ABS_Y, 0, ret - 1, 0, 0); |
| 997 | aiptek->inputdev->absmax[ABS_Y] = ret - 1; | ||
| 998 | 996 | ||
| 999 | /* Query getPressureLevels */ | 997 | /* Query getPressureLevels */ |
| 1000 | if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0) | 998 | if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0) |
| 1001 | return ret; | 999 | return ret; |
| 1002 | aiptek->inputdev->absmin[ABS_PRESSURE] = 0; | 1000 | input_set_abs_params(aiptek->inputdev, ABS_PRESSURE, 0, ret - 1, 0, 0); |
| 1003 | aiptek->inputdev->absmax[ABS_PRESSURE] = ret - 1; | ||
| 1004 | 1001 | ||
| 1005 | /* Depending on whether we are in absolute or relative mode, we will | 1002 | /* Depending on whether we are in absolute or relative mode, we will |
| 1006 | * do a switchToTablet(absolute) or switchToMouse(relative) command. | 1003 | * do a switchToTablet(absolute) or switchToMouse(relative) command. |
| @@ -1054,8 +1051,8 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr | |||
| 1054 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1051 | struct aiptek *aiptek = dev_get_drvdata(dev); |
| 1055 | 1052 | ||
| 1056 | return snprintf(buf, PAGE_SIZE, "%dx%d\n", | 1053 | return snprintf(buf, PAGE_SIZE, "%dx%d\n", |
| 1057 | aiptek->inputdev->absmax[ABS_X] + 1, | 1054 | input_abs_get_max(aiptek->inputdev, ABS_X) + 1, |
| 1058 | aiptek->inputdev->absmax[ABS_Y] + 1); | 1055 | input_abs_get_max(aiptek->inputdev, ABS_Y) + 1); |
| 1059 | } | 1056 | } |
| 1060 | 1057 | ||
| 1061 | /* These structs define the sysfs files, param #1 is the name of the | 1058 | /* These structs define the sysfs files, param #1 is the name of the |
| @@ -1843,7 +1840,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1843 | for (i = 0; i < ARRAY_SIZE(speeds); ++i) { | 1840 | for (i = 0; i < ARRAY_SIZE(speeds); ++i) { |
| 1844 | aiptek->curSetting.programmableDelay = speeds[i]; | 1841 | aiptek->curSetting.programmableDelay = speeds[i]; |
| 1845 | (void)aiptek_program_tablet(aiptek); | 1842 | (void)aiptek_program_tablet(aiptek); |
| 1846 | if (aiptek->inputdev->absmax[ABS_X] > 0) { | 1843 | if (input_abs_get_max(aiptek->inputdev, ABS_X) > 0) { |
| 1847 | dev_info(&intf->dev, | 1844 | dev_info(&intf->dev, |
| 1848 | "Aiptek using %d ms programming speed\n", | 1845 | "Aiptek using %d ms programming speed\n", |
| 1849 | aiptek->curSetting.programmableDelay); | 1846 | aiptek->curSetting.programmableDelay); |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index ce0b4608dad9..40d77ba8fdc1 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -687,10 +687,10 @@ static void wacom_tpc_finger_in(struct wacom_wac *wacom, char *data, int idx) | |||
| 687 | * protocol. | 687 | * protocol. |
| 688 | */ | 688 | */ |
| 689 | if (wacom->last_finger != finger) { | 689 | if (wacom->last_finger != finger) { |
| 690 | if (x == input->abs[ABS_X]) | 690 | if (x == input_abs_get_val(input, ABS_X)) |
| 691 | x++; | 691 | x++; |
| 692 | 692 | ||
| 693 | if (y == input->abs[ABS_Y]) | 693 | if (y == input_abs_get_val(input, ABS_Y)) |
| 694 | y++; | 694 | y++; |
| 695 | } | 695 | } |
| 696 | 696 | ||
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 4eb7df0b7f87..5ec0946938fe 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c | |||
| @@ -75,7 +75,7 @@ static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg, | |||
| 75 | unsigned char len, unsigned char *value) | 75 | unsigned char len, unsigned char *value) |
| 76 | { | 76 | { |
| 77 | struct i2c_client *client = tsc->client; | 77 | struct i2c_client *client = tsc->client; |
| 78 | unsigned int ret; | 78 | int ret; |
| 79 | unsigned char i2c_data[6]; | 79 | unsigned char i2c_data[6]; |
| 80 | 80 | ||
| 81 | BUG_ON(len > 5); | 81 | BUG_ON(len > 5); |
| @@ -86,7 +86,7 @@ static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg, | |||
| 86 | ret = i2c_master_send(client, i2c_data, len + 1); | 86 | ret = i2c_master_send(client, i2c_data, len + 1); |
| 87 | if (ret != 1) { | 87 | if (ret != 1) { |
| 88 | dev_err(&client->dev, "i2c write data cmd failed\n"); | 88 | dev_err(&client->dev, "i2c write data cmd failed\n"); |
| 89 | return ret; | 89 | return ret ? ret : -EIO; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | return 0; | 92 | return 0; |
| @@ -96,7 +96,7 @@ static int cy8ctmg110_read_regs(struct cy8ctmg110 *tsc, | |||
| 96 | unsigned char *data, unsigned char len, unsigned char cmd) | 96 | unsigned char *data, unsigned char len, unsigned char cmd) |
| 97 | { | 97 | { |
| 98 | struct i2c_client *client = tsc->client; | 98 | struct i2c_client *client = tsc->client; |
| 99 | unsigned int ret; | 99 | int ret; |
| 100 | struct i2c_msg msg[2] = { | 100 | struct i2c_msg msg[2] = { |
| 101 | /* first write slave position to i2c devices */ | 101 | /* first write slave position to i2c devices */ |
| 102 | { client->addr, 0, 1, &cmd }, | 102 | { client->addr, 0, 1, &cmd }, |
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index cd0b3f30f48e..ce73a30113b4 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h | |||
| @@ -17,6 +17,8 @@ struct gpio_keys_platform_data { | |||
| 17 | struct gpio_keys_button *buttons; | 17 | struct gpio_keys_button *buttons; |
| 18 | int nbuttons; | 18 | int nbuttons; |
| 19 | unsigned int rep:1; /* enable input subsystem auto repeat */ | 19 | unsigned int rep:1; /* enable input subsystem auto repeat */ |
| 20 | int (*enable)(struct device *dev); | ||
| 21 | void (*disable)(struct device *dev); | ||
| 20 | }; | 22 | }; |
| 21 | 23 | ||
| 22 | #endif | 24 | #endif |
diff --git a/include/linux/input.h b/include/linux/input.h index 339d043ccb53..896a92227bc4 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
| @@ -776,6 +776,7 @@ struct input_absinfo { | |||
| 776 | #define REP_DELAY 0x00 | 776 | #define REP_DELAY 0x00 |
| 777 | #define REP_PERIOD 0x01 | 777 | #define REP_PERIOD 0x01 |
| 778 | #define REP_MAX 0x01 | 778 | #define REP_MAX 0x01 |
| 779 | #define REP_CNT (REP_MAX+1) | ||
| 779 | 780 | ||
| 780 | /* | 781 | /* |
| 781 | * Sounds | 782 | * Sounds |
| @@ -1099,21 +1100,18 @@ struct input_mt_slot { | |||
| 1099 | * @repeat_key: stores key code of the last key pressed; used to implement | 1100 | * @repeat_key: stores key code of the last key pressed; used to implement |
| 1100 | * software autorepeat | 1101 | * software autorepeat |
| 1101 | * @timer: timer for software autorepeat | 1102 | * @timer: timer for software autorepeat |
| 1102 | * @abs: current values for reports from absolute axes | ||
| 1103 | * @rep: current values for autorepeat parameters (delay, rate) | 1103 | * @rep: current values for autorepeat parameters (delay, rate) |
| 1104 | * @mt: pointer to array of struct input_mt_slot holding current values | 1104 | * @mt: pointer to array of struct input_mt_slot holding current values |
| 1105 | * of tracked contacts | 1105 | * of tracked contacts |
| 1106 | * @mtsize: number of MT slots the device uses | 1106 | * @mtsize: number of MT slots the device uses |
| 1107 | * @slot: MT slot currently being transmitted | 1107 | * @slot: MT slot currently being transmitted |
| 1108 | * @absinfo: array of &struct absinfo elements holding information | ||
| 1109 | * about absolute axes (current value, min, max, flat, fuzz, | ||
| 1110 | * resolution) | ||
| 1108 | * @key: reflects current state of device's keys/buttons | 1111 | * @key: reflects current state of device's keys/buttons |
| 1109 | * @led: reflects current state of device's LEDs | 1112 | * @led: reflects current state of device's LEDs |
| 1110 | * @snd: reflects current state of sound effects | 1113 | * @snd: reflects current state of sound effects |
| 1111 | * @sw: reflects current state of device's switches | 1114 | * @sw: reflects current state of device's switches |
| 1112 | * @absmax: maximum values for events coming from absolute axes | ||
| 1113 | * @absmin: minimum values for events coming from absolute axes | ||
| 1114 | * @absfuzz: describes noisiness for axes | ||
| 1115 | * @absflat: size of the center flat position (used by joydev) | ||
| 1116 | * @absres: resolution used for events coming form absolute axes | ||
| 1117 | * @open: this method is called when the very first user calls | 1115 | * @open: this method is called when the very first user calls |
| 1118 | * input_open_device(). The driver must prepare the device | 1116 | * input_open_device(). The driver must prepare the device |
| 1119 | * to start generating events (start polling thread, | 1117 | * to start generating events (start polling thread, |
| @@ -1180,24 +1178,19 @@ struct input_dev { | |||
| 1180 | unsigned int repeat_key; | 1178 | unsigned int repeat_key; |
| 1181 | struct timer_list timer; | 1179 | struct timer_list timer; |
| 1182 | 1180 | ||
| 1183 | int abs[ABS_CNT]; | 1181 | int rep[REP_CNT]; |
| 1184 | int rep[REP_MAX + 1]; | ||
| 1185 | 1182 | ||
| 1186 | struct input_mt_slot *mt; | 1183 | struct input_mt_slot *mt; |
| 1187 | int mtsize; | 1184 | int mtsize; |
| 1188 | int slot; | 1185 | int slot; |
| 1189 | 1186 | ||
| 1187 | struct input_absinfo *absinfo; | ||
| 1188 | |||
| 1190 | unsigned long key[BITS_TO_LONGS(KEY_CNT)]; | 1189 | unsigned long key[BITS_TO_LONGS(KEY_CNT)]; |
| 1191 | unsigned long led[BITS_TO_LONGS(LED_CNT)]; | 1190 | unsigned long led[BITS_TO_LONGS(LED_CNT)]; |
| 1192 | unsigned long snd[BITS_TO_LONGS(SND_CNT)]; | 1191 | unsigned long snd[BITS_TO_LONGS(SND_CNT)]; |
| 1193 | unsigned long sw[BITS_TO_LONGS(SW_CNT)]; | 1192 | unsigned long sw[BITS_TO_LONGS(SW_CNT)]; |
| 1194 | 1193 | ||
| 1195 | int absmax[ABS_CNT]; | ||
| 1196 | int absmin[ABS_CNT]; | ||
| 1197 | int absfuzz[ABS_CNT]; | ||
| 1198 | int absflat[ABS_CNT]; | ||
| 1199 | int absres[ABS_CNT]; | ||
| 1200 | |||
| 1201 | int (*open)(struct input_dev *dev); | 1194 | int (*open)(struct input_dev *dev); |
| 1202 | void (*close)(struct input_dev *dev); | 1195 | void (*close)(struct input_dev *dev); |
| 1203 | int (*flush)(struct input_dev *dev, struct file *file); | 1196 | int (*flush)(struct input_dev *dev, struct file *file); |
| @@ -1459,16 +1452,32 @@ static inline void input_set_events_per_packet(struct input_dev *dev, int n_even | |||
| 1459 | dev->hint_events_per_packet = n_events; | 1452 | dev->hint_events_per_packet = n_events; |
| 1460 | } | 1453 | } |
| 1461 | 1454 | ||
| 1462 | static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat) | 1455 | void input_alloc_absinfo(struct input_dev *dev); |
| 1463 | { | 1456 | void input_set_abs_params(struct input_dev *dev, unsigned int axis, |
| 1464 | dev->absmin[axis] = min; | 1457 | int min, int max, int fuzz, int flat); |
| 1465 | dev->absmax[axis] = max; | 1458 | |
| 1466 | dev->absfuzz[axis] = fuzz; | 1459 | #define INPUT_GENERATE_ABS_ACCESSORS(_suffix, _item) \ |
| 1467 | dev->absflat[axis] = flat; | 1460 | static inline int input_abs_get_##_suffix(struct input_dev *dev, \ |
| 1468 | 1461 | unsigned int axis) \ | |
| 1469 | dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis); | 1462 | { \ |
| 1463 | return dev->absinfo ? dev->absinfo[axis]._item : 0; \ | ||
| 1464 | } \ | ||
| 1465 | \ | ||
| 1466 | static inline void input_abs_set_##_suffix(struct input_dev *dev, \ | ||
| 1467 | unsigned int axis, int val) \ | ||
| 1468 | { \ | ||
| 1469 | input_alloc_absinfo(dev); \ | ||
| 1470 | if (dev->absinfo) \ | ||
| 1471 | dev->absinfo[axis]._item = val; \ | ||
| 1470 | } | 1472 | } |
| 1471 | 1473 | ||
| 1474 | INPUT_GENERATE_ABS_ACCESSORS(val, value) | ||
| 1475 | INPUT_GENERATE_ABS_ACCESSORS(min, minimum) | ||
| 1476 | INPUT_GENERATE_ABS_ACCESSORS(max, maximum) | ||
| 1477 | INPUT_GENERATE_ABS_ACCESSORS(fuzz, fuzz) | ||
| 1478 | INPUT_GENERATE_ABS_ACCESSORS(flat, flat) | ||
| 1479 | INPUT_GENERATE_ABS_ACCESSORS(res, resolution) | ||
| 1480 | |||
| 1472 | int input_get_keycode(struct input_dev *dev, | 1481 | int input_get_keycode(struct input_dev *dev, |
| 1473 | unsigned int scancode, unsigned int *keycode); | 1482 | unsigned int scancode, unsigned int *keycode); |
| 1474 | int input_set_keycode(struct input_dev *dev, | 1483 | int input_set_keycode(struct input_dev *dev, |
