diff options
Diffstat (limited to 'drivers/input')
200 files changed, 21353 insertions, 6216 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 258c639571b5..e3f7fc6f9565 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -10,7 +10,8 @@ | |||
10 | 10 | ||
11 | #define EVDEV_MINOR_BASE 64 | 11 | #define EVDEV_MINOR_BASE 64 |
12 | #define EVDEV_MINORS 32 | 12 | #define EVDEV_MINORS 32 |
13 | #define EVDEV_BUFFER_SIZE 64 | 13 | #define EVDEV_MIN_BUFFER_SIZE 64U |
14 | #define EVDEV_BUF_PACKETS 8 | ||
14 | 15 | ||
15 | #include <linux/poll.h> | 16 | #include <linux/poll.h> |
16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
@@ -23,26 +24,27 @@ | |||
23 | #include "input-compat.h" | 24 | #include "input-compat.h" |
24 | 25 | ||
25 | struct evdev { | 26 | struct evdev { |
26 | int exist; | ||
27 | int open; | 27 | int open; |
28 | int minor; | 28 | int minor; |
29 | struct input_handle handle; | 29 | struct input_handle handle; |
30 | wait_queue_head_t wait; | 30 | wait_queue_head_t wait; |
31 | struct evdev_client *grab; | 31 | struct evdev_client __rcu *grab; |
32 | struct list_head client_list; | 32 | struct list_head client_list; |
33 | spinlock_t client_lock; /* protects client_list */ | 33 | spinlock_t client_lock; /* protects client_list */ |
34 | struct mutex mutex; | 34 | struct mutex mutex; |
35 | struct device dev; | 35 | struct device dev; |
36 | bool exist; | ||
36 | }; | 37 | }; |
37 | 38 | ||
38 | struct evdev_client { | 39 | struct evdev_client { |
39 | struct input_event buffer[EVDEV_BUFFER_SIZE]; | ||
40 | int head; | 40 | int head; |
41 | int tail; | 41 | int tail; |
42 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ | 42 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ |
43 | struct fasync_struct *fasync; | 43 | struct fasync_struct *fasync; |
44 | struct evdev *evdev; | 44 | struct evdev *evdev; |
45 | struct list_head node; | 45 | struct list_head node; |
46 | int bufsize; | ||
47 | struct input_event buffer[]; | ||
46 | }; | 48 | }; |
47 | 49 | ||
48 | static struct evdev *evdev_table[EVDEV_MINORS]; | 50 | static struct evdev *evdev_table[EVDEV_MINORS]; |
@@ -52,11 +54,15 @@ static void evdev_pass_event(struct evdev_client *client, | |||
52 | struct input_event *event) | 54 | struct input_event *event) |
53 | { | 55 | { |
54 | /* | 56 | /* |
55 | * Interrupts are disabled, just acquire the lock | 57 | * Interrupts are disabled, just acquire the lock. |
58 | * Make sure we don't leave with the client buffer | ||
59 | * "empty" by having client->head == client->tail. | ||
56 | */ | 60 | */ |
57 | spin_lock(&client->buffer_lock); | 61 | spin_lock(&client->buffer_lock); |
58 | client->buffer[client->head++] = *event; | 62 | do { |
59 | client->head &= EVDEV_BUFFER_SIZE - 1; | 63 | client->buffer[client->head++] = *event; |
64 | client->head &= client->bufsize - 1; | ||
65 | } while (client->head == client->tail); | ||
60 | spin_unlock(&client->buffer_lock); | 66 | spin_unlock(&client->buffer_lock); |
61 | 67 | ||
62 | if (event->type == EV_SYN) | 68 | if (event->type == EV_SYN) |
@@ -242,11 +248,21 @@ static int evdev_release(struct inode *inode, struct file *file) | |||
242 | return 0; | 248 | return 0; |
243 | } | 249 | } |
244 | 250 | ||
251 | static unsigned int evdev_compute_buffer_size(struct input_dev *dev) | ||
252 | { | ||
253 | unsigned int n_events = | ||
254 | max(dev->hint_events_per_packet * EVDEV_BUF_PACKETS, | ||
255 | EVDEV_MIN_BUFFER_SIZE); | ||
256 | |||
257 | return roundup_pow_of_two(n_events); | ||
258 | } | ||
259 | |||
245 | static int evdev_open(struct inode *inode, struct file *file) | 260 | static int evdev_open(struct inode *inode, struct file *file) |
246 | { | 261 | { |
247 | struct evdev *evdev; | 262 | struct evdev *evdev; |
248 | struct evdev_client *client; | 263 | struct evdev_client *client; |
249 | int i = iminor(inode) - EVDEV_MINOR_BASE; | 264 | int i = iminor(inode) - EVDEV_MINOR_BASE; |
265 | unsigned int bufsize; | ||
250 | int error; | 266 | int error; |
251 | 267 | ||
252 | if (i >= EVDEV_MINORS) | 268 | if (i >= EVDEV_MINORS) |
@@ -263,12 +279,17 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
263 | if (!evdev) | 279 | if (!evdev) |
264 | return -ENODEV; | 280 | return -ENODEV; |
265 | 281 | ||
266 | client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); | 282 | bufsize = evdev_compute_buffer_size(evdev->handle.dev); |
283 | |||
284 | client = kzalloc(sizeof(struct evdev_client) + | ||
285 | bufsize * sizeof(struct input_event), | ||
286 | GFP_KERNEL); | ||
267 | if (!client) { | 287 | if (!client) { |
268 | error = -ENOMEM; | 288 | error = -ENOMEM; |
269 | goto err_put_evdev; | 289 | goto err_put_evdev; |
270 | } | 290 | } |
271 | 291 | ||
292 | client->bufsize = bufsize; | ||
272 | spin_lock_init(&client->buffer_lock); | 293 | spin_lock_init(&client->buffer_lock); |
273 | client->evdev = evdev; | 294 | client->evdev = evdev; |
274 | evdev_attach_client(evdev, client); | 295 | evdev_attach_client(evdev, client); |
@@ -278,6 +299,8 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
278 | goto err_free_client; | 299 | goto err_free_client; |
279 | 300 | ||
280 | file->private_data = client; | 301 | file->private_data = client; |
302 | nonseekable_open(inode, file); | ||
303 | |||
281 | return 0; | 304 | return 0; |
282 | 305 | ||
283 | err_free_client: | 306 | err_free_client: |
@@ -332,7 +355,7 @@ static int evdev_fetch_next_event(struct evdev_client *client, | |||
332 | have_event = client->head != client->tail; | 355 | have_event = client->head != client->tail; |
333 | if (have_event) { | 356 | if (have_event) { |
334 | *event = client->buffer[client->tail++]; | 357 | *event = client->buffer[client->tail++]; |
335 | client->tail &= EVDEV_BUFFER_SIZE - 1; | 358 | client->tail &= client->bufsize - 1; |
336 | } | 359 | } |
337 | 360 | ||
338 | spin_unlock_irq(&client->buffer_lock); | 361 | spin_unlock_irq(&client->buffer_lock); |
@@ -380,10 +403,15 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait) | |||
380 | { | 403 | { |
381 | struct evdev_client *client = file->private_data; | 404 | struct evdev_client *client = file->private_data; |
382 | struct evdev *evdev = client->evdev; | 405 | struct evdev *evdev = client->evdev; |
406 | unsigned int mask; | ||
383 | 407 | ||
384 | poll_wait(file, &evdev->wait, wait); | 408 | poll_wait(file, &evdev->wait, wait); |
385 | return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) | | 409 | |
386 | (evdev->exist ? 0 : (POLLHUP | POLLERR)); | 410 | mask = evdev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR; |
411 | if (client->head != client->tail) | ||
412 | mask |= POLLIN | POLLRDNORM; | ||
413 | |||
414 | return mask; | ||
387 | } | 415 | } |
388 | 416 | ||
389 | #ifdef CONFIG_COMPAT | 417 | #ifdef CONFIG_COMPAT |
@@ -464,13 +492,15 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p) | |||
464 | } | 492 | } |
465 | 493 | ||
466 | #define OLD_KEY_MAX 0x1ff | 494 | #define OLD_KEY_MAX 0x1ff |
467 | 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) | ||
468 | { | 498 | { |
469 | static unsigned long keymax_warn_time; | 499 | static unsigned long keymax_warn_time; |
470 | unsigned long *bits; | 500 | unsigned long *bits; |
471 | int len; | 501 | int len; |
472 | 502 | ||
473 | switch (_IOC_NR(cmd) & EV_MAX) { | 503 | switch (type) { |
474 | 504 | ||
475 | case 0: bits = dev->evbit; len = EV_MAX; break; | 505 | case 0: bits = dev->evbit; len = EV_MAX; break; |
476 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; | 506 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; |
@@ -489,7 +519,7 @@ static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user | |||
489 | * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len' | 519 | * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len' |
490 | * should be in bytes, not in bits. | 520 | * should be in bytes, not in bits. |
491 | */ | 521 | */ |
492 | if ((_IOC_NR(cmd) & EV_MAX) == EV_KEY && _IOC_SIZE(cmd) == OLD_KEY_MAX) { | 522 | if (type == EV_KEY && size == OLD_KEY_MAX) { |
493 | len = OLD_KEY_MAX; | 523 | len = OLD_KEY_MAX; |
494 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) | 524 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) |
495 | printk(KERN_WARNING | 525 | printk(KERN_WARNING |
@@ -500,10 +530,84 @@ static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user | |||
500 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); | 530 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); |
501 | } | 531 | } |
502 | 532 | ||
503 | return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode); | 533 | return bits_to_user(bits, len, size, p, compat_mode); |
504 | } | 534 | } |
505 | #undef OLD_KEY_MAX | 535 | #undef OLD_KEY_MAX |
506 | 536 | ||
537 | static int evdev_handle_get_keycode(struct input_dev *dev, | ||
538 | void __user *p, size_t size) | ||
539 | { | ||
540 | struct input_keymap_entry ke; | ||
541 | int error; | ||
542 | |||
543 | memset(&ke, 0, sizeof(ke)); | ||
544 | |||
545 | if (size == sizeof(unsigned int[2])) { | ||
546 | /* legacy case */ | ||
547 | int __user *ip = (int __user *)p; | ||
548 | |||
549 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | ||
550 | return -EFAULT; | ||
551 | |||
552 | ke.len = sizeof(unsigned int); | ||
553 | ke.flags = 0; | ||
554 | |||
555 | error = input_get_keycode(dev, &ke); | ||
556 | if (error) | ||
557 | return error; | ||
558 | |||
559 | if (put_user(ke.keycode, ip + 1)) | ||
560 | return -EFAULT; | ||
561 | |||
562 | } else { | ||
563 | size = min(size, sizeof(ke)); | ||
564 | |||
565 | if (copy_from_user(&ke, p, size)) | ||
566 | return -EFAULT; | ||
567 | |||
568 | error = input_get_keycode(dev, &ke); | ||
569 | if (error) | ||
570 | return error; | ||
571 | |||
572 | if (copy_to_user(p, &ke, size)) | ||
573 | return -EFAULT; | ||
574 | } | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | static int evdev_handle_set_keycode(struct input_dev *dev, | ||
579 | void __user *p, size_t size) | ||
580 | { | ||
581 | struct input_keymap_entry ke; | ||
582 | |||
583 | memset(&ke, 0, sizeof(ke)); | ||
584 | |||
585 | if (size == sizeof(unsigned int[2])) { | ||
586 | /* legacy case */ | ||
587 | int __user *ip = (int __user *)p; | ||
588 | |||
589 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | ||
590 | return -EFAULT; | ||
591 | |||
592 | if (get_user(ke.keycode, ip + 1)) | ||
593 | return -EFAULT; | ||
594 | |||
595 | ke.len = sizeof(unsigned int); | ||
596 | ke.flags = 0; | ||
597 | |||
598 | } else { | ||
599 | size = min(size, sizeof(ke)); | ||
600 | |||
601 | if (copy_from_user(&ke, p, size)) | ||
602 | return -EFAULT; | ||
603 | |||
604 | if (ke.len > sizeof(ke.scancode)) | ||
605 | return -EINVAL; | ||
606 | } | ||
607 | |||
608 | return input_set_keycode(dev, &ke); | ||
609 | } | ||
610 | |||
507 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, | 611 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, |
508 | void __user *p, int compat_mode) | 612 | void __user *p, int compat_mode) |
509 | { | 613 | { |
@@ -513,9 +617,11 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
513 | struct input_absinfo abs; | 617 | struct input_absinfo abs; |
514 | struct ff_effect effect; | 618 | struct ff_effect effect; |
515 | int __user *ip = (int __user *)p; | 619 | int __user *ip = (int __user *)p; |
516 | int i, t, u, v; | 620 | unsigned int i, t, u, v; |
621 | unsigned int size; | ||
517 | int error; | 622 | int error; |
518 | 623 | ||
624 | /* First we check for fixed-length commands */ | ||
519 | switch (cmd) { | 625 | switch (cmd) { |
520 | 626 | ||
521 | case EVIOCGVERSION: | 627 | case EVIOCGVERSION: |
@@ -548,25 +654,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
548 | 654 | ||
549 | return 0; | 655 | return 0; |
550 | 656 | ||
551 | case EVIOCGKEYCODE: | ||
552 | if (get_user(t, ip)) | ||
553 | return -EFAULT; | ||
554 | |||
555 | error = input_get_keycode(dev, t, &v); | ||
556 | if (error) | ||
557 | return error; | ||
558 | |||
559 | if (put_user(v, ip + 1)) | ||
560 | return -EFAULT; | ||
561 | |||
562 | return 0; | ||
563 | |||
564 | case EVIOCSKEYCODE: | ||
565 | if (get_user(t, ip) || get_user(v, ip + 1)) | ||
566 | return -EFAULT; | ||
567 | |||
568 | return input_set_keycode(dev, t, v); | ||
569 | |||
570 | case EVIOCRMFF: | 657 | case EVIOCRMFF: |
571 | return input_ff_erase(dev, (int)(unsigned long) p, file); | 658 | return input_ff_erase(dev, (int)(unsigned long) p, file); |
572 | 659 | ||
@@ -582,108 +669,113 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
582 | return evdev_grab(evdev, client); | 669 | return evdev_grab(evdev, client); |
583 | else | 670 | else |
584 | return evdev_ungrab(evdev, client); | 671 | return evdev_ungrab(evdev, client); |
672 | } | ||
585 | 673 | ||
586 | default: | 674 | size = _IOC_SIZE(cmd); |
587 | 675 | ||
588 | if (_IOC_TYPE(cmd) != 'E') | 676 | /* Now check variable-length commands */ |
589 | return -EINVAL; | 677 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
678 | switch (EVIOC_MASK_SIZE(cmd)) { | ||
590 | 679 | ||
591 | if (_IOC_DIR(cmd) == _IOC_READ) { | 680 | case EVIOCGKEY(0): |
681 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); | ||
592 | 682 | ||
593 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) | 683 | case EVIOCGLED(0): |
594 | return handle_eviocgbit(dev, cmd, p, compat_mode); | 684 | return bits_to_user(dev->led, LED_MAX, size, p, compat_mode); |
595 | 685 | ||
596 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) | 686 | case EVIOCGSND(0): |
597 | return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd), | 687 | return bits_to_user(dev->snd, SND_MAX, size, p, compat_mode); |
598 | p, compat_mode); | ||
599 | 688 | ||
600 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) | 689 | case EVIOCGSW(0): |
601 | return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd), | 690 | return bits_to_user(dev->sw, SW_MAX, size, p, compat_mode); |
602 | p, compat_mode); | ||
603 | 691 | ||
604 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) | 692 | case EVIOCGNAME(0): |
605 | return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd), | 693 | return str_to_user(dev->name, size, p); |
606 | p, compat_mode); | ||
607 | 694 | ||
608 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) | 695 | case EVIOCGPHYS(0): |
609 | return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd), | 696 | return str_to_user(dev->phys, size, p); |
610 | p, compat_mode); | ||
611 | 697 | ||
612 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) | 698 | case EVIOCGUNIQ(0): |
613 | return str_to_user(dev->name, _IOC_SIZE(cmd), p); | 699 | return str_to_user(dev->uniq, size, p); |
614 | 700 | ||
615 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) | 701 | case EVIOC_MASK_SIZE(EVIOCSFF): |
616 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); | 702 | if (input_ff_effect_from_user(p, size, &effect)) |
703 | return -EFAULT; | ||
617 | 704 | ||
618 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) | 705 | error = input_ff_upload(dev, &effect, file); |
619 | return str_to_user(dev->uniq, _IOC_SIZE(cmd), p); | ||
620 | 706 | ||
621 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { | 707 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) |
708 | return -EFAULT; | ||
622 | 709 | ||
623 | t = _IOC_NR(cmd) & ABS_MAX; | 710 | return error; |
624 | 711 | ||
625 | abs.value = dev->abs[t]; | 712 | case EVIOC_MASK_SIZE(EVIOCGKEYCODE): |
626 | abs.minimum = dev->absmin[t]; | 713 | return evdev_handle_get_keycode(dev, p, size); |
627 | abs.maximum = dev->absmax[t]; | ||
628 | abs.fuzz = dev->absfuzz[t]; | ||
629 | abs.flat = dev->absflat[t]; | ||
630 | abs.resolution = dev->absres[t]; | ||
631 | 714 | ||
632 | if (copy_to_user(p, &abs, min_t(size_t, | 715 | case EVIOC_MASK_SIZE(EVIOCSKEYCODE): |
633 | _IOC_SIZE(cmd), | 716 | return evdev_handle_set_keycode(dev, p, size); |
634 | sizeof(struct input_absinfo)))) | 717 | } |
635 | return -EFAULT; | ||
636 | 718 | ||
637 | return 0; | 719 | /* Multi-number variable-length handlers */ |
638 | } | 720 | if (_IOC_TYPE(cmd) != 'E') |
721 | return -EINVAL; | ||
639 | 722 | ||
640 | } | 723 | if (_IOC_DIR(cmd) == _IOC_READ) { |
641 | 724 | ||
642 | if (_IOC_DIR(cmd) == _IOC_WRITE) { | 725 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) |
726 | return handle_eviocgbit(dev, | ||
727 | _IOC_NR(cmd) & EV_MAX, size, | ||
728 | p, compat_mode); | ||
643 | 729 | ||
644 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) { | 730 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { |
645 | 731 | ||
646 | if (input_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect)) | 732 | if (!dev->absinfo) |
647 | return -EFAULT; | 733 | return -EINVAL; |
648 | 734 | ||
649 | error = input_ff_upload(dev, &effect, file); | 735 | t = _IOC_NR(cmd) & ABS_MAX; |
736 | abs = dev->absinfo[t]; | ||
650 | 737 | ||
651 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) | 738 | if (copy_to_user(p, &abs, min_t(size_t, |
652 | return -EFAULT; | 739 | size, sizeof(struct input_absinfo)))) |
740 | return -EFAULT; | ||
653 | 741 | ||
654 | return error; | 742 | return 0; |
655 | } | 743 | } |
744 | } | ||
656 | 745 | ||
657 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { | 746 | if (_IOC_DIR(cmd) == _IOC_WRITE) { |
658 | 747 | ||
659 | t = _IOC_NR(cmd) & ABS_MAX; | 748 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { |
660 | 749 | ||
661 | if (copy_from_user(&abs, p, min_t(size_t, | 750 | if (!dev->absinfo) |
662 | _IOC_SIZE(cmd), | 751 | return -EINVAL; |
663 | sizeof(struct input_absinfo)))) | ||
664 | return -EFAULT; | ||
665 | 752 | ||
666 | /* | 753 | t = _IOC_NR(cmd) & ABS_MAX; |
667 | * Take event lock to ensure that we are not | ||
668 | * changing device parameters in the middle | ||
669 | * of event. | ||
670 | */ | ||
671 | spin_lock_irq(&dev->event_lock); | ||
672 | 754 | ||
673 | dev->abs[t] = abs.value; | 755 | if (copy_from_user(&abs, p, min_t(size_t, |
674 | dev->absmin[t] = abs.minimum; | 756 | size, sizeof(struct input_absinfo)))) |
675 | dev->absmax[t] = abs.maximum; | 757 | return -EFAULT; |
676 | dev->absfuzz[t] = abs.fuzz; | 758 | |
677 | dev->absflat[t] = abs.flat; | 759 | if (size < sizeof(struct input_absinfo)) |
678 | dev->absres[t] = _IOC_SIZE(cmd) < sizeof(struct input_absinfo) ? | 760 | abs.resolution = 0; |
679 | 0 : abs.resolution; | ||
680 | 761 | ||
681 | spin_unlock_irq(&dev->event_lock); | 762 | /* We can't change number of reserved MT slots */ |
763 | if (t == ABS_MT_SLOT) | ||
764 | return -EINVAL; | ||
682 | 765 | ||
683 | return 0; | 766 | /* |
684 | } | 767 | * Take event lock to ensure that we are not |
768 | * changing device parameters in the middle | ||
769 | * of event. | ||
770 | */ | ||
771 | spin_lock_irq(&dev->event_lock); | ||
772 | dev->absinfo[t] = abs; | ||
773 | spin_unlock_irq(&dev->event_lock); | ||
774 | |||
775 | return 0; | ||
685 | } | 776 | } |
686 | } | 777 | } |
778 | |||
687 | return -EINVAL; | 779 | return -EINVAL; |
688 | } | 780 | } |
689 | 781 | ||
@@ -735,7 +827,8 @@ static const struct file_operations evdev_fops = { | |||
735 | .compat_ioctl = evdev_ioctl_compat, | 827 | .compat_ioctl = evdev_ioctl_compat, |
736 | #endif | 828 | #endif |
737 | .fasync = evdev_fasync, | 829 | .fasync = evdev_fasync, |
738 | .flush = evdev_flush | 830 | .flush = evdev_flush, |
831 | .llseek = no_llseek, | ||
739 | }; | 832 | }; |
740 | 833 | ||
741 | static int evdev_install_chrdev(struct evdev *evdev) | 834 | static int evdev_install_chrdev(struct evdev *evdev) |
@@ -766,7 +859,7 @@ static void evdev_remove_chrdev(struct evdev *evdev) | |||
766 | static void evdev_mark_dead(struct evdev *evdev) | 859 | static void evdev_mark_dead(struct evdev *evdev) |
767 | { | 860 | { |
768 | mutex_lock(&evdev->mutex); | 861 | mutex_lock(&evdev->mutex); |
769 | evdev->exist = 0; | 862 | evdev->exist = false; |
770 | mutex_unlock(&evdev->mutex); | 863 | mutex_unlock(&evdev->mutex); |
771 | } | 864 | } |
772 | 865 | ||
@@ -815,7 +908,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
815 | init_waitqueue_head(&evdev->wait); | 908 | init_waitqueue_head(&evdev->wait); |
816 | 909 | ||
817 | dev_set_name(&evdev->dev, "event%d", minor); | 910 | dev_set_name(&evdev->dev, "event%d", minor); |
818 | evdev->exist = 1; | 911 | evdev->exist = true; |
819 | evdev->minor = minor; | 912 | evdev->minor = minor; |
820 | 913 | ||
821 | evdev->handle.dev = input_get_device(dev); | 914 | evdev->handle.dev = input_get_device(dev); |
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index b2f07aa1604b..03078c08309a 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
32 | #include <linux/slab.h> | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * Check that the effect_id is a valid effect and whether the user | 35 | * Check that the effect_id is a valid effect and whether the user |
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index f967008f332e..1d881c96ba8f 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg) | 26 | #define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg) |
27 | 27 | ||
28 | #include <linux/slab.h> | ||
28 | #include <linux/input.h> | 29 | #include <linux/input.h> |
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
30 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index b04930f7ea7d..422aa0a6b77f 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c | |||
@@ -46,7 +46,7 @@ struct emu { | |||
46 | int size; | 46 | int size; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static struct pci_device_id emu_tbl[] = { | 49 | static const struct pci_device_id emu_tbl[] = { |
50 | 50 | ||
51 | { 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */ | 51 | { 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */ |
52 | { 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */ | 52 | { 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */ |
@@ -59,44 +59,52 @@ MODULE_DEVICE_TABLE(pci, emu_tbl); | |||
59 | 59 | ||
60 | static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 60 | static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
61 | { | 61 | { |
62 | int ioport, iolen; | ||
63 | struct emu *emu; | 62 | struct emu *emu; |
64 | struct gameport *port; | 63 | struct gameport *port; |
65 | 64 | int error; | |
66 | if (pci_enable_device(pdev)) | ||
67 | return -EBUSY; | ||
68 | |||
69 | ioport = pci_resource_start(pdev, 0); | ||
70 | iolen = pci_resource_len(pdev, 0); | ||
71 | |||
72 | if (!request_region(ioport, iolen, "emu10k1-gp")) | ||
73 | return -EBUSY; | ||
74 | 65 | ||
75 | emu = kzalloc(sizeof(struct emu), GFP_KERNEL); | 66 | emu = kzalloc(sizeof(struct emu), GFP_KERNEL); |
76 | port = gameport_allocate_port(); | 67 | port = gameport_allocate_port(); |
77 | if (!emu || !port) { | 68 | if (!emu || !port) { |
78 | printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); | 69 | printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); |
79 | release_region(ioport, iolen); | 70 | error = -ENOMEM; |
80 | kfree(emu); | 71 | goto err_out_free; |
81 | gameport_free_port(port); | ||
82 | return -ENOMEM; | ||
83 | } | 72 | } |
84 | 73 | ||
85 | emu->io = ioport; | 74 | error = pci_enable_device(pdev); |
86 | emu->size = iolen; | 75 | if (error) |
76 | goto err_out_free; | ||
77 | |||
78 | emu->io = pci_resource_start(pdev, 0); | ||
79 | emu->size = pci_resource_len(pdev, 0); | ||
80 | |||
87 | emu->dev = pdev; | 81 | emu->dev = pdev; |
88 | emu->gameport = port; | 82 | emu->gameport = port; |
89 | 83 | ||
90 | gameport_set_name(port, "EMU10K1"); | 84 | gameport_set_name(port, "EMU10K1"); |
91 | gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); | 85 | gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); |
92 | port->dev.parent = &pdev->dev; | 86 | port->dev.parent = &pdev->dev; |
93 | port->io = ioport; | 87 | port->io = emu->io; |
88 | |||
89 | if (!request_region(emu->io, emu->size, "emu10k1-gp")) { | ||
90 | printk(KERN_ERR "emu10k1-gp: unable to grab region 0x%x-0x%x\n", | ||
91 | emu->io, emu->io + emu->size - 1); | ||
92 | error = -EBUSY; | ||
93 | goto err_out_disable_dev; | ||
94 | } | ||
94 | 95 | ||
95 | pci_set_drvdata(pdev, emu); | 96 | pci_set_drvdata(pdev, emu); |
96 | 97 | ||
97 | gameport_register_port(port); | 98 | gameport_register_port(port); |
98 | 99 | ||
99 | return 0; | 100 | return 0; |
101 | |||
102 | err_out_disable_dev: | ||
103 | pci_disable_device(pdev); | ||
104 | err_out_free: | ||
105 | gameport_free_port(port); | ||
106 | kfree(emu); | ||
107 | return error; | ||
100 | } | 108 | } |
101 | 109 | ||
102 | static void __devexit emu_remove(struct pci_dev *pdev) | 110 | static void __devexit emu_remove(struct pci_dev *pdev) |
@@ -106,6 +114,8 @@ static void __devexit emu_remove(struct pci_dev *pdev) | |||
106 | gameport_unregister_port(emu->gameport); | 114 | gameport_unregister_port(emu->gameport); |
107 | release_region(emu->io, emu->size); | 115 | release_region(emu->io, emu->size); |
108 | kfree(emu); | 116 | kfree(emu); |
117 | |||
118 | pci_disable_device(pdev); | ||
109 | } | 119 | } |
110 | 120 | ||
111 | static struct pci_driver emu_driver = { | 121 | static struct pci_driver emu_driver = { |
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 8a1810f88b9e..a3b70ff21018 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
@@ -133,14 +133,14 @@ static void __devexit fm801_gp_remove(struct pci_dev *pci) | |||
133 | { | 133 | { |
134 | struct fm801_gp *gp = pci_get_drvdata(pci); | 134 | struct fm801_gp *gp = pci_get_drvdata(pci); |
135 | 135 | ||
136 | if (gp) { | 136 | gameport_unregister_port(gp->gameport); |
137 | gameport_unregister_port(gp->gameport); | 137 | release_resource(gp->res_port); |
138 | release_resource(gp->res_port); | 138 | kfree(gp); |
139 | kfree(gp); | 139 | |
140 | } | 140 | pci_disable_device(pci); |
141 | } | 141 | } |
142 | 142 | ||
143 | static struct pci_device_id fm801_gp_id_table[] = { | 143 | static const struct pci_device_id fm801_gp_id_table[] = { |
144 | { PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 144 | { PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
145 | { 0 } | 145 | { 0 } |
146 | }; | 146 | }; |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index ac11be08585e..46239e47a260 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * the Free Software Foundation. | 11 | * the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/stddef.h> | 16 | #include <linux/stddef.h> |
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
@@ -57,11 +59,11 @@ static unsigned int get_time_pit(void) | |||
57 | unsigned long flags; | 59 | unsigned long flags; |
58 | unsigned int count; | 60 | unsigned int count; |
59 | 61 | ||
60 | spin_lock_irqsave(&i8253_lock, flags); | 62 | raw_spin_lock_irqsave(&i8253_lock, flags); |
61 | outb_p(0x00, 0x43); | 63 | outb_p(0x00, 0x43); |
62 | count = inb_p(0x40); | 64 | count = inb_p(0x40); |
63 | count |= inb_p(0x40) << 8; | 65 | count |= inb_p(0x40) << 8; |
64 | spin_unlock_irqrestore(&i8253_lock, flags); | 66 | raw_spin_unlock_irqrestore(&i8253_lock, flags); |
65 | 67 | ||
66 | return count; | 68 | return count; |
67 | } | 69 | } |
@@ -190,9 +192,8 @@ static int gameport_bind_driver(struct gameport *gameport, struct gameport_drive | |||
190 | 192 | ||
191 | error = device_bind_driver(&gameport->dev); | 193 | error = device_bind_driver(&gameport->dev); |
192 | if (error) { | 194 | if (error) { |
193 | printk(KERN_WARNING | 195 | dev_warn(&gameport->dev, |
194 | "gameport: device_bind_driver() failed " | 196 | "device_bind_driver() failed for %s (%s) and %s, error: %d\n", |
195 | "for %s (%s) and %s, error: %d\n", | ||
196 | gameport->phys, gameport->name, | 197 | gameport->phys, gameport->name, |
197 | drv->description, error); | 198 | drv->description, error); |
198 | drv->disconnect(gameport); | 199 | drv->disconnect(gameport); |
@@ -209,9 +210,9 @@ static void gameport_find_driver(struct gameport *gameport) | |||
209 | 210 | ||
210 | error = device_attach(&gameport->dev); | 211 | error = device_attach(&gameport->dev); |
211 | if (error < 0) | 212 | if (error < 0) |
212 | printk(KERN_WARNING | 213 | dev_warn(&gameport->dev, |
213 | "gameport: device_attach() failed for %s (%s), error: %d\n", | 214 | "device_attach() failed for %s (%s), error: %d\n", |
214 | gameport->phys, gameport->name, error); | 215 | gameport->phys, gameport->name, error); |
215 | } | 216 | } |
216 | 217 | ||
217 | 218 | ||
@@ -262,17 +263,14 @@ static int gameport_queue_event(void *object, struct module *owner, | |||
262 | 263 | ||
263 | event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); | 264 | event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); |
264 | if (!event) { | 265 | if (!event) { |
265 | printk(KERN_ERR | 266 | pr_err("Not enough memory to queue event %d\n", event_type); |
266 | "gameport: Not enough memory to queue event %d\n", | ||
267 | event_type); | ||
268 | retval = -ENOMEM; | 267 | retval = -ENOMEM; |
269 | goto out; | 268 | goto out; |
270 | } | 269 | } |
271 | 270 | ||
272 | if (!try_module_get(owner)) { | 271 | if (!try_module_get(owner)) { |
273 | printk(KERN_WARNING | 272 | pr_warning("Can't get module reference, dropping event %d\n", |
274 | "gameport: Can't get module reference, dropping event %d\n", | 273 | event_type); |
275 | event_type); | ||
276 | kfree(event); | 274 | kfree(event); |
277 | retval = -EINVAL; | 275 | retval = -EINVAL; |
278 | goto out; | 276 | goto out; |
@@ -298,14 +296,12 @@ static void gameport_free_event(struct gameport_event *event) | |||
298 | 296 | ||
299 | static void gameport_remove_duplicate_events(struct gameport_event *event) | 297 | static void gameport_remove_duplicate_events(struct gameport_event *event) |
300 | { | 298 | { |
301 | struct list_head *node, *next; | 299 | struct gameport_event *e, *next; |
302 | struct gameport_event *e; | ||
303 | unsigned long flags; | 300 | unsigned long flags; |
304 | 301 | ||
305 | spin_lock_irqsave(&gameport_event_lock, flags); | 302 | spin_lock_irqsave(&gameport_event_lock, flags); |
306 | 303 | ||
307 | list_for_each_safe(node, next, &gameport_event_list) { | 304 | list_for_each_entry_safe(e, next, &gameport_event_list, node) { |
308 | e = list_entry(node, struct gameport_event, node); | ||
309 | if (event->object == e->object) { | 305 | if (event->object == e->object) { |
310 | /* | 306 | /* |
311 | * If this event is of different type we should not | 307 | * If this event is of different type we should not |
@@ -315,7 +311,7 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) | |||
315 | if (event->type != e->type) | 311 | if (event->type != e->type) |
316 | break; | 312 | break; |
317 | 313 | ||
318 | list_del_init(node); | 314 | list_del_init(&e->node); |
319 | gameport_free_event(e); | 315 | gameport_free_event(e); |
320 | } | 316 | } |
321 | } | 317 | } |
@@ -325,23 +321,18 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) | |||
325 | 321 | ||
326 | static struct gameport_event *gameport_get_event(void) | 322 | static struct gameport_event *gameport_get_event(void) |
327 | { | 323 | { |
328 | struct gameport_event *event; | 324 | struct gameport_event *event = NULL; |
329 | struct list_head *node; | ||
330 | unsigned long flags; | 325 | unsigned long flags; |
331 | 326 | ||
332 | spin_lock_irqsave(&gameport_event_lock, flags); | 327 | spin_lock_irqsave(&gameport_event_lock, flags); |
333 | 328 | ||
334 | if (list_empty(&gameport_event_list)) { | 329 | if (!list_empty(&gameport_event_list)) { |
335 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 330 | event = list_first_entry(&gameport_event_list, |
336 | return NULL; | 331 | struct gameport_event, node); |
332 | list_del_init(&event->node); | ||
337 | } | 333 | } |
338 | 334 | ||
339 | node = gameport_event_list.next; | ||
340 | event = list_entry(node, struct gameport_event, node); | ||
341 | list_del_init(node); | ||
342 | |||
343 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 335 | spin_unlock_irqrestore(&gameport_event_lock, flags); |
344 | |||
345 | return event; | 336 | return event; |
346 | } | 337 | } |
347 | 338 | ||
@@ -360,16 +351,14 @@ static void gameport_handle_event(void) | |||
360 | if ((event = gameport_get_event())) { | 351 | if ((event = gameport_get_event())) { |
361 | 352 | ||
362 | switch (event->type) { | 353 | switch (event->type) { |
363 | case GAMEPORT_REGISTER_PORT: | ||
364 | gameport_add_port(event->object); | ||
365 | break; | ||
366 | 354 | ||
367 | case GAMEPORT_ATTACH_DRIVER: | 355 | case GAMEPORT_REGISTER_PORT: |
368 | gameport_attach_driver(event->object); | 356 | gameport_add_port(event->object); |
369 | break; | 357 | break; |
370 | 358 | ||
371 | default: | 359 | case GAMEPORT_ATTACH_DRIVER: |
372 | break; | 360 | gameport_attach_driver(event->object); |
361 | break; | ||
373 | } | 362 | } |
374 | 363 | ||
375 | gameport_remove_duplicate_events(event); | 364 | gameport_remove_duplicate_events(event); |
@@ -385,16 +374,14 @@ static void gameport_handle_event(void) | |||
385 | */ | 374 | */ |
386 | static void gameport_remove_pending_events(void *object) | 375 | static void gameport_remove_pending_events(void *object) |
387 | { | 376 | { |
388 | struct list_head *node, *next; | 377 | struct gameport_event *event, *next; |
389 | struct gameport_event *event; | ||
390 | unsigned long flags; | 378 | unsigned long flags; |
391 | 379 | ||
392 | spin_lock_irqsave(&gameport_event_lock, flags); | 380 | spin_lock_irqsave(&gameport_event_lock, flags); |
393 | 381 | ||
394 | list_for_each_safe(node, next, &gameport_event_list) { | 382 | list_for_each_entry_safe(event, next, &gameport_event_list, node) { |
395 | event = list_entry(node, struct gameport_event, node); | ||
396 | if (event->object == object) { | 383 | if (event->object == object) { |
397 | list_del_init(node); | 384 | list_del_init(&event->node); |
398 | gameport_free_event(event); | 385 | gameport_free_event(event); |
399 | } | 386 | } |
400 | } | 387 | } |
@@ -441,7 +428,6 @@ static int gameport_thread(void *nothing) | |||
441 | kthread_should_stop() || !list_empty(&gameport_event_list)); | 428 | kthread_should_stop() || !list_empty(&gameport_event_list)); |
442 | } while (!kthread_should_stop()); | 429 | } while (!kthread_should_stop()); |
443 | 430 | ||
444 | printk(KERN_DEBUG "gameport: kgameportd exiting\n"); | ||
445 | return 0; | 431 | return 0; |
446 | } | 432 | } |
447 | 433 | ||
@@ -453,6 +439,7 @@ static int gameport_thread(void *nothing) | |||
453 | static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf) | 439 | static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf) |
454 | { | 440 | { |
455 | struct gameport *gameport = to_gameport_port(dev); | 441 | struct gameport *gameport = to_gameport_port(dev); |
442 | |||
456 | return sprintf(buf, "%s\n", gameport->name); | 443 | return sprintf(buf, "%s\n", gameport->name); |
457 | } | 444 | } |
458 | 445 | ||
@@ -521,7 +508,8 @@ static void gameport_init_port(struct gameport *gameport) | |||
521 | 508 | ||
522 | mutex_init(&gameport->drv_mutex); | 509 | mutex_init(&gameport->drv_mutex); |
523 | device_initialize(&gameport->dev); | 510 | device_initialize(&gameport->dev); |
524 | dev_set_name(&gameport->dev, "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1); | 511 | dev_set_name(&gameport->dev, "gameport%lu", |
512 | (unsigned long)atomic_inc_return(&gameport_no) - 1); | ||
525 | gameport->dev.bus = &gameport_bus; | 513 | gameport->dev.bus = &gameport_bus; |
526 | gameport->dev.release = gameport_release_port; | 514 | gameport->dev.release = gameport_release_port; |
527 | if (gameport->parent) | 515 | if (gameport->parent) |
@@ -550,19 +538,17 @@ static void gameport_add_port(struct gameport *gameport) | |||
550 | list_add_tail(&gameport->node, &gameport_list); | 538 | list_add_tail(&gameport->node, &gameport_list); |
551 | 539 | ||
552 | if (gameport->io) | 540 | if (gameport->io) |
553 | printk(KERN_INFO "gameport: %s is %s, io %#x, speed %dkHz\n", | 541 | dev_info(&gameport->dev, "%s is %s, io %#x, speed %dkHz\n", |
554 | gameport->name, gameport->phys, gameport->io, gameport->speed); | 542 | gameport->name, gameport->phys, gameport->io, gameport->speed); |
555 | else | 543 | else |
556 | printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n", | 544 | dev_info(&gameport->dev, "%s is %s, speed %dkHz\n", |
557 | gameport->name, gameport->phys, gameport->speed); | 545 | gameport->name, gameport->phys, gameport->speed); |
558 | 546 | ||
559 | error = device_add(&gameport->dev); | 547 | error = device_add(&gameport->dev); |
560 | if (error) | 548 | if (error) |
561 | printk(KERN_ERR | 549 | dev_err(&gameport->dev, |
562 | "gameport: device_add() failed for %s (%s), error: %d\n", | 550 | "device_add() failed for %s (%s), error: %d\n", |
563 | gameport->phys, gameport->name, error); | 551 | gameport->phys, gameport->name, error); |
564 | else | ||
565 | gameport->registered = 1; | ||
566 | } | 552 | } |
567 | 553 | ||
568 | /* | 554 | /* |
@@ -584,10 +570,8 @@ static void gameport_destroy_port(struct gameport *gameport) | |||
584 | gameport->parent = NULL; | 570 | gameport->parent = NULL; |
585 | } | 571 | } |
586 | 572 | ||
587 | if (gameport->registered) { | 573 | if (device_is_registered(&gameport->dev)) |
588 | device_del(&gameport->dev); | 574 | device_del(&gameport->dev); |
589 | gameport->registered = 0; | ||
590 | } | ||
591 | 575 | ||
592 | list_del_init(&gameport->node); | 576 | list_del_init(&gameport->node); |
593 | 577 | ||
@@ -705,8 +689,7 @@ static void gameport_attach_driver(struct gameport_driver *drv) | |||
705 | 689 | ||
706 | error = driver_attach(&drv->driver); | 690 | error = driver_attach(&drv->driver); |
707 | if (error) | 691 | if (error) |
708 | printk(KERN_ERR | 692 | pr_err("driver_attach() failed for %s, error: %d\n", |
709 | "gameport: driver_attach() failed for %s, error: %d\n", | ||
710 | drv->driver.name, error); | 693 | drv->driver.name, error); |
711 | } | 694 | } |
712 | 695 | ||
@@ -727,8 +710,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner | |||
727 | 710 | ||
728 | error = driver_register(&drv->driver); | 711 | error = driver_register(&drv->driver); |
729 | if (error) { | 712 | if (error) { |
730 | printk(KERN_ERR | 713 | pr_err("driver_register() failed for %s, error: %d\n", |
731 | "gameport: driver_register() failed for %s, error: %d\n", | ||
732 | drv->driver.name, error); | 714 | drv->driver.name, error); |
733 | return error; | 715 | return error; |
734 | } | 716 | } |
@@ -828,7 +810,7 @@ static int __init gameport_init(void) | |||
828 | 810 | ||
829 | error = bus_register(&gameport_bus); | 811 | error = bus_register(&gameport_bus); |
830 | if (error) { | 812 | if (error) { |
831 | printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error); | 813 | pr_err("failed to register gameport bus, error: %d\n", error); |
832 | return error; | 814 | return error; |
833 | } | 815 | } |
834 | 816 | ||
@@ -836,7 +818,7 @@ static int __init gameport_init(void) | |||
836 | if (IS_ERR(gameport_task)) { | 818 | if (IS_ERR(gameport_task)) { |
837 | bus_unregister(&gameport_bus); | 819 | bus_unregister(&gameport_bus); |
838 | error = PTR_ERR(gameport_task); | 820 | error = PTR_ERR(gameport_task); |
839 | printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error); | 821 | pr_err("Failed to start kgameportd, error: %d\n", error); |
840 | return error; | 822 | return error; |
841 | } | 823 | } |
842 | 824 | ||
diff --git a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c index 06ad36ed3483..85d6ee09f11f 100644 --- a/drivers/input/gameport/lightning.c +++ b/drivers/input/gameport/lightning.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/gameport.h> | 36 | #include <linux/gameport.h> |
37 | #include <linux/slab.h> | ||
38 | 37 | ||
39 | #define L4_PORT 0x201 | 38 | #define L4_PORT 0x201 |
40 | #define L4_SELECT_ANALOG 0xa4 | 39 | #define L4_SELECT_ANALOG 0xa4 |
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c index db556b71ddda..7c217848613e 100644 --- a/drivers/input/gameport/ns558.c +++ b/drivers/input/gameport/ns558.c | |||
@@ -166,7 +166,7 @@ static int ns558_isa_probe(int io) | |||
166 | 166 | ||
167 | #ifdef CONFIG_PNP | 167 | #ifdef CONFIG_PNP |
168 | 168 | ||
169 | static struct pnp_device_id pnp_devids[] = { | 169 | static const struct pnp_device_id pnp_devids[] = { |
170 | { .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */ | 170 | { .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */ |
171 | { .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */ | 171 | { .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */ |
172 | { .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */ | 172 | { .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */ |
diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h index 47cd9eaee66a..4d8ea32e8a00 100644 --- a/drivers/input/input-compat.h +++ b/drivers/input/input-compat.h | |||
@@ -21,8 +21,6 @@ | |||
21 | you why the ifdefs are needed? Think about it again. -AK */ | 21 | you why the ifdefs are needed? Think about it again. -AK */ |
22 | #ifdef CONFIG_X86_64 | 22 | #ifdef CONFIG_X86_64 |
23 | # define INPUT_COMPAT_TEST is_compat_task() | 23 | # define INPUT_COMPAT_TEST is_compat_task() |
24 | #elif defined(CONFIG_IA64) | ||
25 | # define INPUT_COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current)) | ||
26 | #elif defined(CONFIG_S390) | 24 | #elif defined(CONFIG_S390) |
27 | # define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT) | 25 | # define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT) |
28 | #elif defined(CONFIG_MIPS) | 26 | #elif defined(CONFIG_MIPS) |
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index aa6713b4a988..10c9b0a845f0 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/jiffies.h> | 11 | #include <linux/jiffies.h> |
12 | #include <linux/slab.h> | ||
12 | #include <linux/mutex.h> | 13 | #include <linux/mutex.h> |
13 | #include <linux/input-polldev.h> | 14 | #include <linux/input-polldev.h> |
14 | 15 | ||
@@ -100,6 +101,12 @@ static void input_close_polled_device(struct input_dev *input) | |||
100 | struct input_polled_dev *dev = input_get_drvdata(input); | 101 | struct input_polled_dev *dev = input_get_drvdata(input); |
101 | 102 | ||
102 | cancel_delayed_work_sync(&dev->work); | 103 | cancel_delayed_work_sync(&dev->work); |
104 | /* | ||
105 | * Clean up work struct to remove references to the workqueue. | ||
106 | * It may be destroyed by the next call. This causes problems | ||
107 | * at next device open-close in case of poll_interval == 0. | ||
108 | */ | ||
109 | INIT_DELAYED_WORK(&dev->work, dev->work.work.func); | ||
103 | input_polldev_stop_workqueue(); | 110 | input_polldev_stop_workqueue(); |
104 | 111 | ||
105 | if (dev->close) | 112 | if (dev->close) |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 86cb2d2196ff..d092ef9291da 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/input.h> | 15 | #include <linux/input.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/slab.h> | ||
17 | #include <linux/random.h> | 18 | #include <linux/random.h> |
18 | #include <linux/major.h> | 19 | #include <linux/major.h> |
19 | #include <linux/proc_fs.h> | 20 | #include <linux/proc_fs.h> |
@@ -32,25 +33,6 @@ MODULE_LICENSE("GPL"); | |||
32 | 33 | ||
33 | #define INPUT_DEVICES 256 | 34 | #define INPUT_DEVICES 256 |
34 | 35 | ||
35 | /* | ||
36 | * EV_ABS events which should not be cached are listed here. | ||
37 | */ | ||
38 | static unsigned int input_abs_bypass_init_data[] __initdata = { | ||
39 | ABS_MT_TOUCH_MAJOR, | ||
40 | ABS_MT_TOUCH_MINOR, | ||
41 | ABS_MT_WIDTH_MAJOR, | ||
42 | ABS_MT_WIDTH_MINOR, | ||
43 | ABS_MT_ORIENTATION, | ||
44 | ABS_MT_POSITION_X, | ||
45 | ABS_MT_POSITION_Y, | ||
46 | ABS_MT_TOOL_TYPE, | ||
47 | ABS_MT_BLOB_ID, | ||
48 | ABS_MT_TRACKING_ID, | ||
49 | ABS_MT_PRESSURE, | ||
50 | 0 | ||
51 | }; | ||
52 | static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)]; | ||
53 | |||
54 | static LIST_HEAD(input_dev_list); | 36 | static LIST_HEAD(input_dev_list); |
55 | static LIST_HEAD(input_handler_list); | 37 | static LIST_HEAD(input_handler_list); |
56 | 38 | ||
@@ -87,12 +69,14 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) | |||
87 | } | 69 | } |
88 | 70 | ||
89 | /* | 71 | /* |
90 | * Pass event through all open handles. This function is called with | 72 | * Pass event first through all filters and then, if event has not been |
73 | * filtered out, through all open handles. This function is called with | ||
91 | * dev->event_lock held and interrupts disabled. | 74 | * dev->event_lock held and interrupts disabled. |
92 | */ | 75 | */ |
93 | static void input_pass_event(struct input_dev *dev, | 76 | static void input_pass_event(struct input_dev *dev, |
94 | unsigned int type, unsigned int code, int value) | 77 | unsigned int type, unsigned int code, int value) |
95 | { | 78 | { |
79 | struct input_handler *handler; | ||
96 | struct input_handle *handle; | 80 | struct input_handle *handle; |
97 | 81 | ||
98 | rcu_read_lock(); | 82 | rcu_read_lock(); |
@@ -100,11 +84,25 @@ static void input_pass_event(struct input_dev *dev, | |||
100 | handle = rcu_dereference(dev->grab); | 84 | handle = rcu_dereference(dev->grab); |
101 | if (handle) | 85 | if (handle) |
102 | handle->handler->event(handle, type, code, value); | 86 | handle->handler->event(handle, type, code, value); |
103 | else | 87 | else { |
104 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) | 88 | bool filtered = false; |
105 | if (handle->open) | 89 | |
106 | handle->handler->event(handle, | 90 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) { |
107 | type, code, value); | 91 | if (!handle->open) |
92 | continue; | ||
93 | |||
94 | handler = handle->handler; | ||
95 | if (!handler->filter) { | ||
96 | if (filtered) | ||
97 | break; | ||
98 | |||
99 | handler->event(handle, type, code, value); | ||
100 | |||
101 | } else if (handler->filter(handle, type, code, value)) | ||
102 | filtered = true; | ||
103 | } | ||
104 | } | ||
105 | |||
108 | rcu_read_unlock(); | 106 | rcu_read_unlock(); |
109 | } | 107 | } |
110 | 108 | ||
@@ -164,6 +162,56 @@ static void input_stop_autorepeat(struct input_dev *dev) | |||
164 | #define INPUT_PASS_TO_DEVICE 2 | 162 | #define INPUT_PASS_TO_DEVICE 2 |
165 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) | 163 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) |
166 | 164 | ||
165 | static int input_handle_abs_event(struct input_dev *dev, | ||
166 | unsigned int code, int *pval) | ||
167 | { | ||
168 | bool is_mt_event; | ||
169 | int *pold; | ||
170 | |||
171 | if (code == ABS_MT_SLOT) { | ||
172 | /* | ||
173 | * "Stage" the event; we'll flush it later, when we | ||
174 | * get actual touch data. | ||
175 | */ | ||
176 | if (*pval >= 0 && *pval < dev->mtsize) | ||
177 | dev->slot = *pval; | ||
178 | |||
179 | return INPUT_IGNORE_EVENT; | ||
180 | } | ||
181 | |||
182 | is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST; | ||
183 | |||
184 | if (!is_mt_event) { | ||
185 | pold = &dev->absinfo[code].value; | ||
186 | } else if (dev->mt) { | ||
187 | struct input_mt_slot *mtslot = &dev->mt[dev->slot]; | ||
188 | pold = &mtslot->abs[code - ABS_MT_FIRST]; | ||
189 | } else { | ||
190 | /* | ||
191 | * Bypass filtering for multi-touch events when | ||
192 | * not employing slots. | ||
193 | */ | ||
194 | pold = NULL; | ||
195 | } | ||
196 | |||
197 | if (pold) { | ||
198 | *pval = input_defuzz_abs_event(*pval, *pold, | ||
199 | dev->absinfo[code].fuzz); | ||
200 | if (*pold == *pval) | ||
201 | return INPUT_IGNORE_EVENT; | ||
202 | |||
203 | *pold = *pval; | ||
204 | } | ||
205 | |||
206 | /* Flush pending "slot" event */ | ||
207 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { | ||
208 | input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); | ||
209 | input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); | ||
210 | } | ||
211 | |||
212 | return INPUT_PASS_TO_HANDLERS; | ||
213 | } | ||
214 | |||
167 | static void input_handle_event(struct input_dev *dev, | 215 | static void input_handle_event(struct input_dev *dev, |
168 | unsigned int type, unsigned int code, int value) | 216 | unsigned int type, unsigned int code, int value) |
169 | { | 217 | { |
@@ -179,12 +227,12 @@ static void input_handle_event(struct input_dev *dev, | |||
179 | 227 | ||
180 | case SYN_REPORT: | 228 | case SYN_REPORT: |
181 | if (!dev->sync) { | 229 | if (!dev->sync) { |
182 | dev->sync = 1; | 230 | dev->sync = true; |
183 | disposition = INPUT_PASS_TO_HANDLERS; | 231 | disposition = INPUT_PASS_TO_HANDLERS; |
184 | } | 232 | } |
185 | break; | 233 | break; |
186 | case SYN_MT_REPORT: | 234 | case SYN_MT_REPORT: |
187 | dev->sync = 0; | 235 | dev->sync = false; |
188 | disposition = INPUT_PASS_TO_HANDLERS; | 236 | disposition = INPUT_PASS_TO_HANDLERS; |
189 | break; | 237 | break; |
190 | } | 238 | } |
@@ -216,21 +264,9 @@ static void input_handle_event(struct input_dev *dev, | |||
216 | break; | 264 | break; |
217 | 265 | ||
218 | case EV_ABS: | 266 | case EV_ABS: |
219 | if (is_event_supported(code, dev->absbit, ABS_MAX)) { | 267 | if (is_event_supported(code, dev->absbit, ABS_MAX)) |
220 | 268 | disposition = input_handle_abs_event(dev, code, &value); | |
221 | if (test_bit(code, input_abs_bypass)) { | ||
222 | disposition = INPUT_PASS_TO_HANDLERS; | ||
223 | break; | ||
224 | } | ||
225 | |||
226 | value = input_defuzz_abs_event(value, | ||
227 | dev->abs[code], dev->absfuzz[code]); | ||
228 | 269 | ||
229 | if (dev->abs[code] != value) { | ||
230 | dev->abs[code] = value; | ||
231 | disposition = INPUT_PASS_TO_HANDLERS; | ||
232 | } | ||
233 | } | ||
234 | break; | 270 | break; |
235 | 271 | ||
236 | case EV_REL: | 272 | case EV_REL: |
@@ -281,7 +317,7 @@ static void input_handle_event(struct input_dev *dev, | |||
281 | } | 317 | } |
282 | 318 | ||
283 | if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) | 319 | if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) |
284 | dev->sync = 0; | 320 | dev->sync = false; |
285 | 321 | ||
286 | if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) | 322 | if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) |
287 | dev->event(dev, type, code, value); | 323 | dev->event(dev, type, code, value); |
@@ -355,6 +391,43 @@ void input_inject_event(struct input_handle *handle, | |||
355 | EXPORT_SYMBOL(input_inject_event); | 391 | EXPORT_SYMBOL(input_inject_event); |
356 | 392 | ||
357 | /** | 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 | /** | ||
358 | * input_grab_device - grabs device for exclusive use | 431 | * input_grab_device - grabs device for exclusive use |
359 | * @handle: input handle that wants to own the device | 432 | * @handle: input handle that wants to own the device |
360 | * | 433 | * |
@@ -511,12 +584,30 @@ void input_close_device(struct input_handle *handle) | |||
511 | EXPORT_SYMBOL(input_close_device); | 584 | EXPORT_SYMBOL(input_close_device); |
512 | 585 | ||
513 | /* | 586 | /* |
587 | * Simulate keyup events for all keys that are marked as pressed. | ||
588 | * The function must be called with dev->event_lock held. | ||
589 | */ | ||
590 | static void input_dev_release_keys(struct input_dev *dev) | ||
591 | { | ||
592 | int code; | ||
593 | |||
594 | if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) { | ||
595 | for (code = 0; code <= KEY_MAX; code++) { | ||
596 | if (is_event_supported(code, dev->keybit, KEY_MAX) && | ||
597 | __test_and_clear_bit(code, dev->key)) { | ||
598 | input_pass_event(dev, EV_KEY, code, 0); | ||
599 | } | ||
600 | } | ||
601 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | /* | ||
514 | * Prepare device for unregistering | 606 | * Prepare device for unregistering |
515 | */ | 607 | */ |
516 | static void input_disconnect_device(struct input_dev *dev) | 608 | static void input_disconnect_device(struct input_dev *dev) |
517 | { | 609 | { |
518 | struct input_handle *handle; | 610 | struct input_handle *handle; |
519 | int code; | ||
520 | 611 | ||
521 | /* | 612 | /* |
522 | * Mark device as going away. Note that we take dev->mutex here | 613 | * Mark device as going away. Note that we take dev->mutex here |
@@ -535,15 +626,7 @@ static void input_disconnect_device(struct input_dev *dev) | |||
535 | * generate events even after we done here but they will not | 626 | * generate events even after we done here but they will not |
536 | * reach any handlers. | 627 | * reach any handlers. |
537 | */ | 628 | */ |
538 | if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) { | 629 | input_dev_release_keys(dev); |
539 | for (code = 0; code <= KEY_MAX; code++) { | ||
540 | if (is_event_supported(code, dev->keybit, KEY_MAX) && | ||
541 | __test_and_clear_bit(code, dev->key)) { | ||
542 | input_pass_event(dev, EV_KEY, code, 0); | ||
543 | } | ||
544 | } | ||
545 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | ||
546 | } | ||
547 | 630 | ||
548 | list_for_each_entry(handle, &dev->h_list, d_node) | 631 | list_for_each_entry(handle, &dev->h_list, d_node) |
549 | handle->open = 0; | 632 | handle->open = 0; |
@@ -551,76 +634,141 @@ static void input_disconnect_device(struct input_dev *dev) | |||
551 | spin_unlock_irq(&dev->event_lock); | 634 | spin_unlock_irq(&dev->event_lock); |
552 | } | 635 | } |
553 | 636 | ||
554 | static int input_fetch_keycode(struct input_dev *dev, int scancode) | 637 | /** |
638 | * input_scancode_to_scalar() - converts scancode in &struct input_keymap_entry | ||
639 | * @ke: keymap entry containing scancode to be converted. | ||
640 | * @scancode: pointer to the location where converted scancode should | ||
641 | * be stored. | ||
642 | * | ||
643 | * This function is used to convert scancode stored in &struct keymap_entry | ||
644 | * into scalar form understood by legacy keymap handling methods. These | ||
645 | * methods expect scancodes to be represented as 'unsigned int'. | ||
646 | */ | ||
647 | int input_scancode_to_scalar(const struct input_keymap_entry *ke, | ||
648 | unsigned int *scancode) | ||
649 | { | ||
650 | switch (ke->len) { | ||
651 | case 1: | ||
652 | *scancode = *((u8 *)ke->scancode); | ||
653 | break; | ||
654 | |||
655 | case 2: | ||
656 | *scancode = *((u16 *)ke->scancode); | ||
657 | break; | ||
658 | |||
659 | case 4: | ||
660 | *scancode = *((u32 *)ke->scancode); | ||
661 | break; | ||
662 | |||
663 | default: | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | |||
667 | return 0; | ||
668 | } | ||
669 | EXPORT_SYMBOL(input_scancode_to_scalar); | ||
670 | |||
671 | /* | ||
672 | * Those routines handle the default case where no [gs]etkeycode() is | ||
673 | * defined. In this case, an array indexed by the scancode is used. | ||
674 | */ | ||
675 | |||
676 | static unsigned int input_fetch_keycode(struct input_dev *dev, | ||
677 | unsigned int index) | ||
555 | { | 678 | { |
556 | switch (dev->keycodesize) { | 679 | switch (dev->keycodesize) { |
557 | case 1: | 680 | case 1: |
558 | return ((u8 *)dev->keycode)[scancode]; | 681 | return ((u8 *)dev->keycode)[index]; |
559 | 682 | ||
560 | case 2: | 683 | case 2: |
561 | return ((u16 *)dev->keycode)[scancode]; | 684 | return ((u16 *)dev->keycode)[index]; |
562 | 685 | ||
563 | default: | 686 | default: |
564 | return ((u32 *)dev->keycode)[scancode]; | 687 | return ((u32 *)dev->keycode)[index]; |
565 | } | 688 | } |
566 | } | 689 | } |
567 | 690 | ||
568 | static int input_default_getkeycode(struct input_dev *dev, | 691 | static int input_default_getkeycode(struct input_dev *dev, |
569 | int scancode, int *keycode) | 692 | struct input_keymap_entry *ke) |
570 | { | 693 | { |
694 | unsigned int index; | ||
695 | int error; | ||
696 | |||
571 | if (!dev->keycodesize) | 697 | if (!dev->keycodesize) |
572 | return -EINVAL; | 698 | return -EINVAL; |
573 | 699 | ||
574 | if (scancode >= dev->keycodemax) | 700 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) |
701 | index = ke->index; | ||
702 | else { | ||
703 | error = input_scancode_to_scalar(ke, &index); | ||
704 | if (error) | ||
705 | return error; | ||
706 | } | ||
707 | |||
708 | if (index >= dev->keycodemax) | ||
575 | return -EINVAL; | 709 | return -EINVAL; |
576 | 710 | ||
577 | *keycode = input_fetch_keycode(dev, scancode); | 711 | ke->keycode = input_fetch_keycode(dev, index); |
712 | ke->index = index; | ||
713 | ke->len = sizeof(index); | ||
714 | memcpy(ke->scancode, &index, sizeof(index)); | ||
578 | 715 | ||
579 | return 0; | 716 | return 0; |
580 | } | 717 | } |
581 | 718 | ||
582 | static int input_default_setkeycode(struct input_dev *dev, | 719 | static int input_default_setkeycode(struct input_dev *dev, |
583 | int scancode, int keycode) | 720 | const struct input_keymap_entry *ke, |
721 | unsigned int *old_keycode) | ||
584 | { | 722 | { |
585 | int old_keycode; | 723 | unsigned int index; |
724 | int error; | ||
586 | int i; | 725 | int i; |
587 | 726 | ||
588 | if (scancode >= dev->keycodemax) | 727 | if (!dev->keycodesize) |
589 | return -EINVAL; | 728 | return -EINVAL; |
590 | 729 | ||
591 | if (!dev->keycodesize) | 730 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { |
731 | index = ke->index; | ||
732 | } else { | ||
733 | error = input_scancode_to_scalar(ke, &index); | ||
734 | if (error) | ||
735 | return error; | ||
736 | } | ||
737 | |||
738 | if (index >= dev->keycodemax) | ||
592 | return -EINVAL; | 739 | return -EINVAL; |
593 | 740 | ||
594 | if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) | 741 | if (dev->keycodesize < sizeof(dev->keycode) && |
742 | (ke->keycode >> (dev->keycodesize * 8))) | ||
595 | return -EINVAL; | 743 | return -EINVAL; |
596 | 744 | ||
597 | switch (dev->keycodesize) { | 745 | switch (dev->keycodesize) { |
598 | case 1: { | 746 | case 1: { |
599 | u8 *k = (u8 *)dev->keycode; | 747 | u8 *k = (u8 *)dev->keycode; |
600 | old_keycode = k[scancode]; | 748 | *old_keycode = k[index]; |
601 | k[scancode] = keycode; | 749 | k[index] = ke->keycode; |
602 | break; | 750 | break; |
603 | } | 751 | } |
604 | case 2: { | 752 | case 2: { |
605 | u16 *k = (u16 *)dev->keycode; | 753 | u16 *k = (u16 *)dev->keycode; |
606 | old_keycode = k[scancode]; | 754 | *old_keycode = k[index]; |
607 | k[scancode] = keycode; | 755 | k[index] = ke->keycode; |
608 | break; | 756 | break; |
609 | } | 757 | } |
610 | default: { | 758 | default: { |
611 | u32 *k = (u32 *)dev->keycode; | 759 | u32 *k = (u32 *)dev->keycode; |
612 | old_keycode = k[scancode]; | 760 | *old_keycode = k[index]; |
613 | k[scancode] = keycode; | 761 | k[index] = ke->keycode; |
614 | break; | 762 | break; |
615 | } | 763 | } |
616 | } | 764 | } |
617 | 765 | ||
618 | clear_bit(old_keycode, dev->keybit); | 766 | __clear_bit(*old_keycode, dev->keybit); |
619 | set_bit(keycode, dev->keybit); | 767 | __set_bit(ke->keycode, dev->keybit); |
620 | 768 | ||
621 | for (i = 0; i < dev->keycodemax; i++) { | 769 | for (i = 0; i < dev->keycodemax; i++) { |
622 | if (input_fetch_keycode(dev, i) == old_keycode) { | 770 | if (input_fetch_keycode(dev, i) == *old_keycode) { |
623 | set_bit(old_keycode, dev->keybit); | 771 | __set_bit(*old_keycode, dev->keybit); |
624 | break; /* Setting the bit twice is useless, so break */ | 772 | break; /* Setting the bit twice is useless, so break */ |
625 | } | 773 | } |
626 | } | 774 | } |
@@ -631,53 +779,92 @@ static int input_default_setkeycode(struct input_dev *dev, | |||
631 | /** | 779 | /** |
632 | * input_get_keycode - retrieve keycode currently mapped to a given scancode | 780 | * input_get_keycode - retrieve keycode currently mapped to a given scancode |
633 | * @dev: input device which keymap is being queried | 781 | * @dev: input device which keymap is being queried |
634 | * @scancode: scancode (or its equivalent for device in question) for which | 782 | * @ke: keymap entry |
635 | * keycode is needed | ||
636 | * @keycode: result | ||
637 | * | 783 | * |
638 | * This function should be called by anyone interested in retrieving current | 784 | * This function should be called by anyone interested in retrieving current |
639 | * keymap. Presently keyboard and evdev handlers use it. | 785 | * keymap. Presently evdev handlers use it. |
640 | */ | 786 | */ |
641 | int input_get_keycode(struct input_dev *dev, int scancode, int *keycode) | 787 | int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke) |
642 | { | 788 | { |
643 | if (scancode < 0) | 789 | unsigned long flags; |
644 | return -EINVAL; | 790 | int retval; |
791 | |||
792 | spin_lock_irqsave(&dev->event_lock, flags); | ||
645 | 793 | ||
646 | return dev->getkeycode(dev, scancode, keycode); | 794 | if (dev->getkeycode) { |
795 | /* | ||
796 | * Support for legacy drivers, that don't implement the new | ||
797 | * ioctls | ||
798 | */ | ||
799 | u32 scancode = ke->index; | ||
800 | |||
801 | memcpy(ke->scancode, &scancode, sizeof(scancode)); | ||
802 | ke->len = sizeof(scancode); | ||
803 | retval = dev->getkeycode(dev, scancode, &ke->keycode); | ||
804 | } else { | ||
805 | retval = dev->getkeycode_new(dev, ke); | ||
806 | } | ||
807 | |||
808 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
809 | return retval; | ||
647 | } | 810 | } |
648 | EXPORT_SYMBOL(input_get_keycode); | 811 | EXPORT_SYMBOL(input_get_keycode); |
649 | 812 | ||
650 | /** | 813 | /** |
651 | * input_get_keycode - assign new keycode to a given scancode | 814 | * input_set_keycode - attribute a keycode to a given scancode |
652 | * @dev: input device which keymap is being updated | 815 | * @dev: input device which keymap is being updated |
653 | * @scancode: scancode (or its equivalent for device in question) | 816 | * @ke: new keymap entry |
654 | * @keycode: new keycode to be assigned to the scancode | ||
655 | * | 817 | * |
656 | * This function should be called by anyone needing to update current | 818 | * This function should be called by anyone needing to update current |
657 | * keymap. Presently keyboard and evdev handlers use it. | 819 | * keymap. Presently keyboard and evdev handlers use it. |
658 | */ | 820 | */ |
659 | int input_set_keycode(struct input_dev *dev, int scancode, int keycode) | 821 | int input_set_keycode(struct input_dev *dev, |
822 | const struct input_keymap_entry *ke) | ||
660 | { | 823 | { |
661 | unsigned long flags; | 824 | unsigned long flags; |
662 | int old_keycode; | 825 | unsigned int old_keycode; |
663 | int retval; | 826 | int retval; |
664 | 827 | ||
665 | if (scancode < 0) | 828 | if (ke->keycode > KEY_MAX) |
666 | return -EINVAL; | ||
667 | |||
668 | if (keycode < 0 || keycode > KEY_MAX) | ||
669 | return -EINVAL; | 829 | return -EINVAL; |
670 | 830 | ||
671 | spin_lock_irqsave(&dev->event_lock, flags); | 831 | spin_lock_irqsave(&dev->event_lock, flags); |
672 | 832 | ||
673 | retval = dev->getkeycode(dev, scancode, &old_keycode); | 833 | if (dev->setkeycode) { |
674 | if (retval) | 834 | /* |
675 | goto out; | 835 | * Support for legacy drivers, that don't implement the new |
836 | * ioctls | ||
837 | */ | ||
838 | unsigned int scancode; | ||
839 | |||
840 | retval = input_scancode_to_scalar(ke, &scancode); | ||
841 | if (retval) | ||
842 | goto out; | ||
843 | |||
844 | /* | ||
845 | * We need to know the old scancode, in order to generate a | ||
846 | * keyup effect, if the set operation happens successfully | ||
847 | */ | ||
848 | if (!dev->getkeycode) { | ||
849 | retval = -EINVAL; | ||
850 | goto out; | ||
851 | } | ||
852 | |||
853 | retval = dev->getkeycode(dev, scancode, &old_keycode); | ||
854 | if (retval) | ||
855 | goto out; | ||
856 | |||
857 | retval = dev->setkeycode(dev, scancode, ke->keycode); | ||
858 | } else { | ||
859 | retval = dev->setkeycode_new(dev, ke, &old_keycode); | ||
860 | } | ||
676 | 861 | ||
677 | retval = dev->setkeycode(dev, scancode, keycode); | ||
678 | if (retval) | 862 | if (retval) |
679 | goto out; | 863 | goto out; |
680 | 864 | ||
865 | /* Make sure KEY_RESERVED did not get enabled. */ | ||
866 | __clear_bit(KEY_RESERVED, dev->keybit); | ||
867 | |||
681 | /* | 868 | /* |
682 | * Simulate keyup event if keycode is not present | 869 | * Simulate keyup event if keycode is not present |
683 | * in the keymap anymore | 870 | * in the keymap anymore |
@@ -705,12 +892,13 @@ EXPORT_SYMBOL(input_set_keycode); | |||
705 | if (i != BITS_TO_LONGS(max)) \ | 892 | if (i != BITS_TO_LONGS(max)) \ |
706 | continue; | 893 | continue; |
707 | 894 | ||
708 | static const struct input_device_id *input_match_device(const struct input_device_id *id, | 895 | static const struct input_device_id *input_match_device(struct input_handler *handler, |
709 | struct input_dev *dev) | 896 | struct input_dev *dev) |
710 | { | 897 | { |
898 | const struct input_device_id *id; | ||
711 | int i; | 899 | int i; |
712 | 900 | ||
713 | for (; id->flags || id->driver_info; id++) { | 901 | for (id = handler->id_table; id->flags || id->driver_info; id++) { |
714 | 902 | ||
715 | if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) | 903 | if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) |
716 | if (id->bustype != dev->id.bustype) | 904 | if (id->bustype != dev->id.bustype) |
@@ -738,7 +926,8 @@ static const struct input_device_id *input_match_device(const struct input_devic | |||
738 | MATCH_BIT(ffbit, FF_MAX); | 926 | MATCH_BIT(ffbit, FF_MAX); |
739 | MATCH_BIT(swbit, SW_MAX); | 927 | MATCH_BIT(swbit, SW_MAX); |
740 | 928 | ||
741 | return id; | 929 | if (!handler->match || handler->match(handler, dev)) |
930 | return id; | ||
742 | } | 931 | } |
743 | 932 | ||
744 | return NULL; | 933 | return NULL; |
@@ -749,10 +938,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
749 | const struct input_device_id *id; | 938 | const struct input_device_id *id; |
750 | int error; | 939 | int error; |
751 | 940 | ||
752 | if (handler->blacklist && input_match_device(handler->blacklist, dev)) | 941 | id = input_match_device(handler, dev); |
753 | return -ENODEV; | ||
754 | |||
755 | id = input_match_device(handler->id_table, dev); | ||
756 | if (!id) | 942 | if (!id) |
757 | return -ENODEV; | 943 | return -ENODEV; |
758 | 944 | ||
@@ -988,6 +1174,8 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v) | |||
988 | union input_seq_state *state = (union input_seq_state *)&seq->private; | 1174 | union input_seq_state *state = (union input_seq_state *)&seq->private; |
989 | 1175 | ||
990 | seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); | 1176 | seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); |
1177 | if (handler->filter) | ||
1178 | seq_puts(seq, " (filter)"); | ||
991 | if (handler->fops) | 1179 | if (handler->fops) |
992 | seq_printf(seq, " Minor=%d", handler->minor); | 1180 | seq_printf(seq, " Minor=%d", handler->minor); |
993 | seq_putc(seq, '\n'); | 1181 | seq_putc(seq, '\n'); |
@@ -1252,6 +1440,8 @@ static void input_dev_release(struct device *device) | |||
1252 | struct input_dev *dev = to_input_dev(device); | 1440 | struct input_dev *dev = to_input_dev(device); |
1253 | 1441 | ||
1254 | input_ff_destroy(dev); | 1442 | input_ff_destroy(dev); |
1443 | input_mt_destroy_slots(dev); | ||
1444 | kfree(dev->absinfo); | ||
1255 | kfree(dev); | 1445 | kfree(dev); |
1256 | 1446 | ||
1257 | module_put(THIS_MODULE); | 1447 | module_put(THIS_MODULE); |
@@ -1407,6 +1597,15 @@ static int input_dev_resume(struct device *dev) | |||
1407 | 1597 | ||
1408 | mutex_lock(&input_dev->mutex); | 1598 | mutex_lock(&input_dev->mutex); |
1409 | input_dev_reset(input_dev, true); | 1599 | input_dev_reset(input_dev, true); |
1600 | |||
1601 | /* | ||
1602 | * Keys that have been pressed at suspend time are unlikely | ||
1603 | * to be still pressed when we resume. | ||
1604 | */ | ||
1605 | spin_lock_irq(&input_dev->event_lock); | ||
1606 | input_dev_release_keys(input_dev); | ||
1607 | spin_unlock_irq(&input_dev->event_lock); | ||
1608 | |||
1410 | mutex_unlock(&input_dev->mutex); | 1609 | mutex_unlock(&input_dev->mutex); |
1411 | 1610 | ||
1412 | return 0; | 1611 | return 0; |
@@ -1492,6 +1691,52 @@ void input_free_device(struct input_dev *dev) | |||
1492 | EXPORT_SYMBOL(input_free_device); | 1691 | EXPORT_SYMBOL(input_free_device); |
1493 | 1692 | ||
1494 | /** | 1693 | /** |
1694 | * input_mt_create_slots() - create MT input slots | ||
1695 | * @dev: input device supporting MT events and finger tracking | ||
1696 | * @num_slots: number of slots used by the device | ||
1697 | * | ||
1698 | * This function allocates all necessary memory for MT slot handling in the | ||
1699 | * input device, and adds ABS_MT_SLOT to the device capabilities. All slots | ||
1700 | * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1. | ||
1701 | */ | ||
1702 | int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots) | ||
1703 | { | ||
1704 | int i; | ||
1705 | |||
1706 | if (!num_slots) | ||
1707 | return 0; | ||
1708 | |||
1709 | dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL); | ||
1710 | if (!dev->mt) | ||
1711 | return -ENOMEM; | ||
1712 | |||
1713 | dev->mtsize = num_slots; | ||
1714 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); | ||
1715 | |||
1716 | /* Mark slots as 'unused' */ | ||
1717 | for (i = 0; i < num_slots; i++) | ||
1718 | dev->mt[i].abs[ABS_MT_TRACKING_ID - ABS_MT_FIRST] = -1; | ||
1719 | |||
1720 | return 0; | ||
1721 | } | ||
1722 | EXPORT_SYMBOL(input_mt_create_slots); | ||
1723 | |||
1724 | /** | ||
1725 | * input_mt_destroy_slots() - frees the MT slots of the input device | ||
1726 | * @dev: input device with allocated MT slots | ||
1727 | * | ||
1728 | * This function is only needed in error path as the input core will | ||
1729 | * automatically free the MT slots when the device is destroyed. | ||
1730 | */ | ||
1731 | void input_mt_destroy_slots(struct input_dev *dev) | ||
1732 | { | ||
1733 | kfree(dev->mt); | ||
1734 | dev->mt = NULL; | ||
1735 | dev->mtsize = 0; | ||
1736 | } | ||
1737 | EXPORT_SYMBOL(input_mt_destroy_slots); | ||
1738 | |||
1739 | /** | ||
1495 | * input_set_capability - mark device as capable of a certain event | 1740 | * input_set_capability - mark device as capable of a certain event |
1496 | * @dev: device that is capable of emitting or accepting event | 1741 | * @dev: device that is capable of emitting or accepting event |
1497 | * @type: type of the event (EV_KEY, EV_REL, etc...) | 1742 | * @type: type of the event (EV_KEY, EV_REL, etc...) |
@@ -1551,6 +1796,25 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int | |||
1551 | } | 1796 | } |
1552 | EXPORT_SYMBOL(input_set_capability); | 1797 | EXPORT_SYMBOL(input_set_capability); |
1553 | 1798 | ||
1799 | #define INPUT_CLEANSE_BITMASK(dev, type, bits) \ | ||
1800 | do { \ | ||
1801 | if (!test_bit(EV_##type, dev->evbit)) \ | ||
1802 | memset(dev->bits##bit, 0, \ | ||
1803 | sizeof(dev->bits##bit)); \ | ||
1804 | } while (0) | ||
1805 | |||
1806 | static void input_cleanse_bitmasks(struct input_dev *dev) | ||
1807 | { | ||
1808 | INPUT_CLEANSE_BITMASK(dev, KEY, key); | ||
1809 | INPUT_CLEANSE_BITMASK(dev, REL, rel); | ||
1810 | INPUT_CLEANSE_BITMASK(dev, ABS, abs); | ||
1811 | INPUT_CLEANSE_BITMASK(dev, MSC, msc); | ||
1812 | INPUT_CLEANSE_BITMASK(dev, LED, led); | ||
1813 | INPUT_CLEANSE_BITMASK(dev, SND, snd); | ||
1814 | INPUT_CLEANSE_BITMASK(dev, FF, ff); | ||
1815 | INPUT_CLEANSE_BITMASK(dev, SW, sw); | ||
1816 | } | ||
1817 | |||
1554 | /** | 1818 | /** |
1555 | * input_register_device - register device with input core | 1819 | * input_register_device - register device with input core |
1556 | * @dev: device to be registered | 1820 | * @dev: device to be registered |
@@ -1570,13 +1834,19 @@ int input_register_device(struct input_dev *dev) | |||
1570 | const char *path; | 1834 | const char *path; |
1571 | int error; | 1835 | int error; |
1572 | 1836 | ||
1837 | /* Every input device generates EV_SYN/SYN_REPORT events. */ | ||
1573 | __set_bit(EV_SYN, dev->evbit); | 1838 | __set_bit(EV_SYN, dev->evbit); |
1574 | 1839 | ||
1840 | /* KEY_RESERVED is not supposed to be transmitted to userspace. */ | ||
1841 | __clear_bit(KEY_RESERVED, dev->keybit); | ||
1842 | |||
1843 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ | ||
1844 | input_cleanse_bitmasks(dev); | ||
1845 | |||
1575 | /* | 1846 | /* |
1576 | * If delay and period are pre-set by the driver, then autorepeating | 1847 | * If delay and period are pre-set by the driver, then autorepeating |
1577 | * is handled by the driver itself and we don't do it in input.c. | 1848 | * is handled by the driver itself and we don't do it in input.c. |
1578 | */ | 1849 | */ |
1579 | |||
1580 | init_timer(&dev->timer); | 1850 | init_timer(&dev->timer); |
1581 | if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { | 1851 | if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { |
1582 | dev->timer.data = (long) dev; | 1852 | dev->timer.data = (long) dev; |
@@ -1585,11 +1855,11 @@ int input_register_device(struct input_dev *dev) | |||
1585 | dev->rep[REP_PERIOD] = 33; | 1855 | dev->rep[REP_PERIOD] = 33; |
1586 | } | 1856 | } |
1587 | 1857 | ||
1588 | if (!dev->getkeycode) | 1858 | if (!dev->getkeycode && !dev->getkeycode_new) |
1589 | dev->getkeycode = input_default_getkeycode; | 1859 | dev->getkeycode_new = input_default_getkeycode; |
1590 | 1860 | ||
1591 | if (!dev->setkeycode) | 1861 | if (!dev->setkeycode && !dev->setkeycode_new) |
1592 | dev->setkeycode = input_default_setkeycode; | 1862 | dev->setkeycode_new = input_default_setkeycode; |
1593 | 1863 | ||
1594 | dev_set_name(&dev->dev, "input%ld", | 1864 | dev_set_name(&dev->dev, "input%ld", |
1595 | (unsigned long) atomic_inc_return(&input_no) - 1); | 1865 | (unsigned long) atomic_inc_return(&input_no) - 1); |
@@ -1776,7 +2046,16 @@ int input_register_handle(struct input_handle *handle) | |||
1776 | error = mutex_lock_interruptible(&dev->mutex); | 2046 | error = mutex_lock_interruptible(&dev->mutex); |
1777 | if (error) | 2047 | if (error) |
1778 | return error; | 2048 | return error; |
1779 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | 2049 | |
2050 | /* | ||
2051 | * Filters go to the head of the list, normal handlers | ||
2052 | * to the tail. | ||
2053 | */ | ||
2054 | if (handler->filter) | ||
2055 | list_add_rcu(&handle->d_node, &dev->h_list); | ||
2056 | else | ||
2057 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | ||
2058 | |||
1780 | mutex_unlock(&dev->mutex); | 2059 | mutex_unlock(&dev->mutex); |
1781 | 2060 | ||
1782 | /* | 2061 | /* |
@@ -1827,57 +2106,50 @@ static int input_open_file(struct inode *inode, struct file *file) | |||
1827 | const struct file_operations *old_fops, *new_fops = NULL; | 2106 | const struct file_operations *old_fops, *new_fops = NULL; |
1828 | int err; | 2107 | int err; |
1829 | 2108 | ||
1830 | lock_kernel(); | 2109 | err = mutex_lock_interruptible(&input_mutex); |
2110 | if (err) | ||
2111 | return err; | ||
2112 | |||
1831 | /* No load-on-demand here? */ | 2113 | /* No load-on-demand here? */ |
1832 | handler = input_table[iminor(inode) >> 5]; | 2114 | handler = input_table[iminor(inode) >> 5]; |
1833 | if (!handler || !(new_fops = fops_get(handler->fops))) { | 2115 | if (handler) |
1834 | err = -ENODEV; | 2116 | new_fops = fops_get(handler->fops); |
1835 | goto out; | 2117 | |
1836 | } | 2118 | mutex_unlock(&input_mutex); |
1837 | 2119 | ||
1838 | /* | 2120 | /* |
1839 | * That's _really_ odd. Usually NULL ->open means "nothing special", | 2121 | * That's _really_ odd. Usually NULL ->open means "nothing special", |
1840 | * not "no device". Oh, well... | 2122 | * not "no device". Oh, well... |
1841 | */ | 2123 | */ |
1842 | if (!new_fops->open) { | 2124 | if (!new_fops || !new_fops->open) { |
1843 | fops_put(new_fops); | 2125 | fops_put(new_fops); |
1844 | err = -ENODEV; | 2126 | err = -ENODEV; |
1845 | goto out; | 2127 | goto out; |
1846 | } | 2128 | } |
2129 | |||
1847 | old_fops = file->f_op; | 2130 | old_fops = file->f_op; |
1848 | file->f_op = new_fops; | 2131 | file->f_op = new_fops; |
1849 | 2132 | ||
1850 | err = new_fops->open(inode, file); | 2133 | err = new_fops->open(inode, file); |
1851 | |||
1852 | if (err) { | 2134 | if (err) { |
1853 | fops_put(file->f_op); | 2135 | fops_put(file->f_op); |
1854 | file->f_op = fops_get(old_fops); | 2136 | file->f_op = fops_get(old_fops); |
1855 | } | 2137 | } |
1856 | fops_put(old_fops); | 2138 | fops_put(old_fops); |
1857 | out: | 2139 | out: |
1858 | unlock_kernel(); | ||
1859 | return err; | 2140 | return err; |
1860 | } | 2141 | } |
1861 | 2142 | ||
1862 | static const struct file_operations input_fops = { | 2143 | static const struct file_operations input_fops = { |
1863 | .owner = THIS_MODULE, | 2144 | .owner = THIS_MODULE, |
1864 | .open = input_open_file, | 2145 | .open = input_open_file, |
2146 | .llseek = noop_llseek, | ||
1865 | }; | 2147 | }; |
1866 | 2148 | ||
1867 | static void __init input_init_abs_bypass(void) | ||
1868 | { | ||
1869 | const unsigned int *p; | ||
1870 | |||
1871 | for (p = input_abs_bypass_init_data; *p; p++) | ||
1872 | input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p); | ||
1873 | } | ||
1874 | |||
1875 | static int __init input_init(void) | 2149 | static int __init input_init(void) |
1876 | { | 2150 | { |
1877 | int err; | 2151 | int err; |
1878 | 2152 | ||
1879 | input_init_abs_bypass(); | ||
1880 | |||
1881 | err = class_register(&input_class); | 2153 | err = class_register(&input_class); |
1882 | if (err) { | 2154 | if (err) { |
1883 | printk(KERN_ERR "input: unable to register input_dev class\n"); | 2155 | printk(KERN_ERR "input: unable to register input_dev class\n"); |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b1bd6dd32286..9d424cebfd2c 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -37,7 +37,6 @@ MODULE_LICENSE("GPL"); | |||
37 | #define JOYDEV_BUFFER_SIZE 64 | 37 | #define JOYDEV_BUFFER_SIZE 64 |
38 | 38 | ||
39 | struct joydev { | 39 | struct joydev { |
40 | int exist; | ||
41 | int open; | 40 | int open; |
42 | int minor; | 41 | int minor; |
43 | struct input_handle handle; | 42 | struct input_handle handle; |
@@ -46,16 +45,17 @@ struct joydev { | |||
46 | spinlock_t client_lock; /* protects client_list */ | 45 | spinlock_t client_lock; /* protects client_list */ |
47 | struct mutex mutex; | 46 | struct mutex mutex; |
48 | struct device dev; | 47 | struct device dev; |
48 | bool exist; | ||
49 | 49 | ||
50 | struct js_corr corr[ABS_MAX + 1]; | 50 | struct js_corr corr[ABS_CNT]; |
51 | struct JS_DATA_SAVE_TYPE glue; | 51 | struct JS_DATA_SAVE_TYPE glue; |
52 | int nabs; | 52 | int nabs; |
53 | int nkey; | 53 | int nkey; |
54 | __u16 keymap[KEY_MAX - BTN_MISC + 1]; | 54 | __u16 keymap[KEY_MAX - BTN_MISC + 1]; |
55 | __u16 keypam[KEY_MAX - BTN_MISC + 1]; | 55 | __u16 keypam[KEY_MAX - BTN_MISC + 1]; |
56 | __u8 absmap[ABS_MAX + 1]; | 56 | __u8 absmap[ABS_CNT]; |
57 | __u8 abspam[ABS_MAX + 1]; | 57 | __u8 abspam[ABS_CNT]; |
58 | __s16 abs[ABS_MAX + 1]; | 58 | __s16 abs[ABS_CNT]; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | struct joydev_client { | 61 | struct joydev_client { |
@@ -286,6 +286,8 @@ static int joydev_open(struct inode *inode, struct file *file) | |||
286 | goto err_free_client; | 286 | goto err_free_client; |
287 | 287 | ||
288 | file->private_data = client; | 288 | file->private_data = client; |
289 | nonseekable_open(inode, file); | ||
290 | |||
289 | return 0; | 291 | return 0; |
290 | 292 | ||
291 | err_free_client: | 293 | err_free_client: |
@@ -481,6 +483,9 @@ static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev, | |||
481 | 483 | ||
482 | memcpy(joydev->abspam, abspam, len); | 484 | memcpy(joydev->abspam, abspam, len); |
483 | 485 | ||
486 | for (i = 0; i < joydev->nabs; i++) | ||
487 | joydev->absmap[joydev->abspam[i]] = i; | ||
488 | |||
484 | out: | 489 | out: |
485 | kfree(abspam); | 490 | kfree(abspam); |
486 | return retval; | 491 | return retval; |
@@ -528,7 +533,7 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
528 | { | 533 | { |
529 | struct input_dev *dev = joydev->handle.dev; | 534 | struct input_dev *dev = joydev->handle.dev; |
530 | size_t len; | 535 | size_t len; |
531 | int i, j; | 536 | int i; |
532 | const char *name; | 537 | const char *name; |
533 | 538 | ||
534 | /* Process fixed-sized commands. */ | 539 | /* Process fixed-sized commands. */ |
@@ -560,12 +565,11 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
560 | case JSIOCSCORR: | 565 | case JSIOCSCORR: |
561 | if (copy_from_user(joydev->corr, argp, | 566 | if (copy_from_user(joydev->corr, argp, |
562 | sizeof(joydev->corr[0]) * joydev->nabs)) | 567 | sizeof(joydev->corr[0]) * joydev->nabs)) |
563 | return -EFAULT; | 568 | return -EFAULT; |
564 | 569 | ||
565 | for (i = 0; i < joydev->nabs; i++) { | 570 | for (i = 0; i < joydev->nabs; i++) { |
566 | j = joydev->abspam[i]; | 571 | int val = input_abs_get_val(dev, joydev->abspam[i]); |
567 | joydev->abs[i] = joydev_correct(dev->abs[j], | 572 | joydev->abs[i] = joydev_correct(val, &joydev->corr[i]); |
568 | &joydev->corr[i]); | ||
569 | } | 573 | } |
570 | return 0; | 574 | return 0; |
571 | 575 | ||
@@ -735,6 +739,7 @@ static const struct file_operations joydev_fops = { | |||
735 | .compat_ioctl = joydev_compat_ioctl, | 739 | .compat_ioctl = joydev_compat_ioctl, |
736 | #endif | 740 | #endif |
737 | .fasync = joydev_fasync, | 741 | .fasync = joydev_fasync, |
742 | .llseek = no_llseek, | ||
738 | }; | 743 | }; |
739 | 744 | ||
740 | static int joydev_install_chrdev(struct joydev *joydev) | 745 | static int joydev_install_chrdev(struct joydev *joydev) |
@@ -758,7 +763,7 @@ static void joydev_remove_chrdev(struct joydev *joydev) | |||
758 | static void joydev_mark_dead(struct joydev *joydev) | 763 | static void joydev_mark_dead(struct joydev *joydev) |
759 | { | 764 | { |
760 | mutex_lock(&joydev->mutex); | 765 | mutex_lock(&joydev->mutex); |
761 | joydev->exist = 0; | 766 | joydev->exist = false; |
762 | mutex_unlock(&joydev->mutex); | 767 | mutex_unlock(&joydev->mutex); |
763 | } | 768 | } |
764 | 769 | ||
@@ -775,6 +780,20 @@ static void joydev_cleanup(struct joydev *joydev) | |||
775 | input_close_device(handle); | 780 | input_close_device(handle); |
776 | } | 781 | } |
777 | 782 | ||
783 | |||
784 | static bool joydev_match(struct input_handler *handler, struct input_dev *dev) | ||
785 | { | ||
786 | /* Avoid touchpads and touchscreens */ | ||
787 | if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit)) | ||
788 | return false; | ||
789 | |||
790 | /* Avoid tablets, digitisers and similar devices */ | ||
791 | if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit)) | ||
792 | return false; | ||
793 | |||
794 | return true; | ||
795 | } | ||
796 | |||
778 | static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | 797 | static int joydev_connect(struct input_handler *handler, struct input_dev *dev, |
779 | const struct input_device_id *id) | 798 | const struct input_device_id *id) |
780 | { | 799 | { |
@@ -801,16 +820,15 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
801 | init_waitqueue_head(&joydev->wait); | 820 | init_waitqueue_head(&joydev->wait); |
802 | 821 | ||
803 | dev_set_name(&joydev->dev, "js%d", minor); | 822 | dev_set_name(&joydev->dev, "js%d", minor); |
804 | joydev->exist = 1; | 823 | joydev->exist = true; |
805 | joydev->minor = minor; | 824 | joydev->minor = minor; |
806 | 825 | ||
807 | joydev->exist = 1; | ||
808 | joydev->handle.dev = input_get_device(dev); | 826 | joydev->handle.dev = input_get_device(dev); |
809 | joydev->handle.name = dev_name(&joydev->dev); | 827 | joydev->handle.name = dev_name(&joydev->dev); |
810 | joydev->handle.handler = handler; | 828 | joydev->handle.handler = handler; |
811 | joydev->handle.private = joydev; | 829 | joydev->handle.private = joydev; |
812 | 830 | ||
813 | for (i = 0; i < ABS_MAX + 1; i++) | 831 | for (i = 0; i < ABS_CNT; i++) |
814 | if (test_bit(i, dev->absbit)) { | 832 | if (test_bit(i, dev->absbit)) { |
815 | joydev->absmap[i] = joydev->nabs; | 833 | joydev->absmap[i] = joydev->nabs; |
816 | joydev->abspam[joydev->nabs] = i; | 834 | joydev->abspam[joydev->nabs] = i; |
@@ -833,25 +851,27 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
833 | 851 | ||
834 | for (i = 0; i < joydev->nabs; i++) { | 852 | for (i = 0; i < joydev->nabs; i++) { |
835 | j = joydev->abspam[i]; | 853 | j = joydev->abspam[i]; |
836 | if (dev->absmax[j] == dev->absmin[j]) { | 854 | if (input_abs_get_max(dev, j) == input_abs_get_min(dev, j)) { |
837 | joydev->corr[i].type = JS_CORR_NONE; | 855 | joydev->corr[i].type = JS_CORR_NONE; |
838 | joydev->abs[i] = dev->abs[j]; | 856 | joydev->abs[i] = input_abs_get_val(dev, j); |
839 | continue; | 857 | continue; |
840 | } | 858 | } |
841 | joydev->corr[i].type = JS_CORR_BROKEN; | 859 | joydev->corr[i].type = JS_CORR_BROKEN; |
842 | joydev->corr[i].prec = dev->absfuzz[j]; | 860 | joydev->corr[i].prec = input_abs_get_fuzz(dev, j); |
843 | joydev->corr[i].coef[0] = | ||
844 | (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j]; | ||
845 | joydev->corr[i].coef[1] = | ||
846 | (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j]; | ||
847 | 861 | ||
848 | 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 | joydev->corr[i].coef[0] = t - input_abs_get_flat(dev, j); | ||
864 | joydev->corr[i].coef[1] = t + input_abs_get_flat(dev, j); | ||
865 | |||
866 | t = (input_abs_get_max(dev, j) - input_abs_get_min(dev, j)) / 2 | ||
867 | - 2 * input_abs_get_flat(dev, j); | ||
849 | if (t) { | 868 | if (t) { |
850 | joydev->corr[i].coef[2] = (1 << 29) / t; | 869 | joydev->corr[i].coef[2] = (1 << 29) / t; |
851 | joydev->corr[i].coef[3] = (1 << 29) / t; | 870 | joydev->corr[i].coef[3] = (1 << 29) / t; |
852 | 871 | ||
853 | joydev->abs[i] = joydev_correct(dev->abs[j], | 872 | joydev->abs[i] = |
854 | joydev->corr + i); | 873 | joydev_correct(input_abs_get_val(dev, j), |
874 | joydev->corr + i); | ||
855 | } | 875 | } |
856 | } | 876 | } |
857 | 877 | ||
@@ -894,22 +914,6 @@ static void joydev_disconnect(struct input_handle *handle) | |||
894 | put_device(&joydev->dev); | 914 | put_device(&joydev->dev); |
895 | } | 915 | } |
896 | 916 | ||
897 | static const struct input_device_id joydev_blacklist[] = { | ||
898 | { | ||
899 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
900 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
901 | .evbit = { BIT_MASK(EV_KEY) }, | ||
902 | .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, | ||
903 | }, /* Avoid itouchpads and touchscreens */ | ||
904 | { | ||
905 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
906 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
907 | .evbit = { BIT_MASK(EV_KEY) }, | ||
908 | .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) }, | ||
909 | }, /* Avoid tablets, digitisers and similar devices */ | ||
910 | { } /* Terminating entry */ | ||
911 | }; | ||
912 | |||
913 | static const struct input_device_id joydev_ids[] = { | 917 | static const struct input_device_id joydev_ids[] = { |
914 | { | 918 | { |
915 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | 919 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | |
@@ -929,6 +933,24 @@ static const struct input_device_id joydev_ids[] = { | |||
929 | .evbit = { BIT_MASK(EV_ABS) }, | 933 | .evbit = { BIT_MASK(EV_ABS) }, |
930 | .absbit = { BIT_MASK(ABS_THROTTLE) }, | 934 | .absbit = { BIT_MASK(ABS_THROTTLE) }, |
931 | }, | 935 | }, |
936 | { | ||
937 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
938 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
939 | .evbit = { BIT_MASK(EV_KEY) }, | ||
940 | .keybit = {[BIT_WORD(BTN_JOYSTICK)] = BIT_MASK(BTN_JOYSTICK) }, | ||
941 | }, | ||
942 | { | ||
943 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
944 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
945 | .evbit = { BIT_MASK(EV_KEY) }, | ||
946 | .keybit = { [BIT_WORD(BTN_GAMEPAD)] = BIT_MASK(BTN_GAMEPAD) }, | ||
947 | }, | ||
948 | { | ||
949 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
950 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
951 | .evbit = { BIT_MASK(EV_KEY) }, | ||
952 | .keybit = { [BIT_WORD(BTN_TRIGGER_HAPPY)] = BIT_MASK(BTN_TRIGGER_HAPPY) }, | ||
953 | }, | ||
932 | { } /* Terminating entry */ | 954 | { } /* Terminating entry */ |
933 | }; | 955 | }; |
934 | 956 | ||
@@ -936,13 +958,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids); | |||
936 | 958 | ||
937 | static struct input_handler joydev_handler = { | 959 | static struct input_handler joydev_handler = { |
938 | .event = joydev_event, | 960 | .event = joydev_event, |
961 | .match = joydev_match, | ||
939 | .connect = joydev_connect, | 962 | .connect = joydev_connect, |
940 | .disconnect = joydev_disconnect, | 963 | .disconnect = joydev_disconnect, |
941 | .fops = &joydev_fops, | 964 | .fops = &joydev_fops, |
942 | .minor = JOYDEV_MINOR_BASE, | 965 | .minor = JOYDEV_MINOR_BASE, |
943 | .name = "joydev", | 966 | .name = "joydev", |
944 | .id_table = joydev_ids, | 967 | .id_table = joydev_ids, |
945 | .blacklist = joydev_blacklist, | ||
946 | }; | 968 | }; |
947 | 969 | ||
948 | static int __init joydev_init(void) | 970 | static int __init joydev_init(void) |
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index b11419590cfe..5b596165b571 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig | |||
@@ -221,6 +221,7 @@ config JOYSTICK_DB9 | |||
221 | config JOYSTICK_GAMECON | 221 | config JOYSTICK_GAMECON |
222 | tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads" | 222 | tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads" |
223 | depends on PARPORT | 223 | depends on PARPORT |
224 | select INPUT_FF_MEMLESS | ||
224 | ---help--- | 225 | ---help--- |
225 | Say Y here if you have a Nintendo Entertainment System gamepad, | 226 | Say Y here if you have a Nintendo Entertainment System gamepad, |
226 | Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad, | 227 | Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad, |
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..0bc86204213e 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 | input_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/analog.c b/drivers/input/joystick/analog.c index 1c0b529c06aa..4afe0a3b4884 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c | |||
@@ -146,11 +146,11 @@ static unsigned int get_time_pit(void) | |||
146 | unsigned long flags; | 146 | unsigned long flags; |
147 | unsigned int count; | 147 | unsigned int count; |
148 | 148 | ||
149 | spin_lock_irqsave(&i8253_lock, flags); | 149 | raw_spin_lock_irqsave(&i8253_lock, flags); |
150 | outb_p(0x00, 0x43); | 150 | outb_p(0x00, 0x43); |
151 | count = inb_p(0x40); | 151 | count = inb_p(0x40); |
152 | count |= inb_p(0x40) << 8; | 152 | count |= inb_p(0x40) << 8; |
153 | spin_unlock_irqrestore(&i8253_lock, flags); | 153 | raw_spin_unlock_irqrestore(&i8253_lock, flags); |
154 | 154 | ||
155 | return count; | 155 | return count; |
156 | } | 156 | } |
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 523959484753..8e7de5c7754f 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/parport.h> | 36 | #include <linux/parport.h> |
37 | #include <linux/input.h> | 37 | #include <linux/input.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/slab.h> | ||
39 | 40 | ||
40 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 41 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
41 | MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver"); | 42 | MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver"); |
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 07a32aff5a31..e68e49786483 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c | |||
@@ -30,6 +30,8 @@ | |||
30 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 30 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
34 | |||
33 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
34 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
35 | #include <linux/module.h> | 37 | #include <linux/module.h> |
@@ -37,6 +39,7 @@ | |||
37 | #include <linux/parport.h> | 39 | #include <linux/parport.h> |
38 | #include <linux/input.h> | 40 | #include <linux/input.h> |
39 | #include <linux/mutex.h> | 41 | #include <linux/mutex.h> |
42 | #include <linux/slab.h> | ||
40 | 43 | ||
41 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 44 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
42 | MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); | 45 | MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); |
@@ -61,48 +64,72 @@ MODULE_PARM_DESC(map3, "Describes third set of devices"); | |||
61 | 64 | ||
62 | /* see also gs_psx_delay parameter in PSX support section */ | 65 | /* see also gs_psx_delay parameter in PSX support section */ |
63 | 66 | ||
64 | #define GC_SNES 1 | 67 | enum gc_type { |
65 | #define GC_NES 2 | 68 | GC_NONE = 0, |
66 | #define GC_NES4 3 | 69 | GC_SNES, |
67 | #define GC_MULTI 4 | 70 | GC_NES, |
68 | #define GC_MULTI2 5 | 71 | GC_NES4, |
69 | #define GC_N64 6 | 72 | GC_MULTI, |
70 | #define GC_PSX 7 | 73 | GC_MULTI2, |
71 | #define GC_DDR 8 | 74 | GC_N64, |
72 | #define GC_SNESMOUSE 9 | 75 | GC_PSX, |
73 | 76 | GC_DDR, | |
74 | #define GC_MAX 9 | 77 | GC_SNESMOUSE, |
78 | GC_MAX | ||
79 | }; | ||
75 | 80 | ||
76 | #define GC_REFRESH_TIME HZ/100 | 81 | #define GC_REFRESH_TIME HZ/100 |
77 | 82 | ||
83 | struct gc_pad { | ||
84 | struct input_dev *dev; | ||
85 | enum gc_type type; | ||
86 | char phys[32]; | ||
87 | }; | ||
88 | |||
78 | struct gc { | 89 | struct gc { |
79 | struct pardevice *pd; | 90 | struct pardevice *pd; |
80 | struct input_dev *dev[GC_MAX_DEVICES]; | 91 | struct gc_pad pads[GC_MAX_DEVICES]; |
81 | struct timer_list timer; | 92 | struct timer_list timer; |
82 | unsigned char pads[GC_MAX + 1]; | 93 | int pad_count[GC_MAX]; |
83 | int used; | 94 | int used; |
84 | struct mutex mutex; | 95 | struct mutex mutex; |
85 | char phys[GC_MAX_DEVICES][32]; | 96 | }; |
97 | |||
98 | struct gc_subdev { | ||
99 | unsigned int idx; | ||
86 | }; | 100 | }; |
87 | 101 | ||
88 | static struct gc *gc_base[3]; | 102 | static struct gc *gc_base[3]; |
89 | 103 | ||
90 | static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; | 104 | static const int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; |
105 | |||
106 | static const char *gc_names[] = { | ||
107 | NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", | ||
108 | "Multisystem 2-button joystick", "N64 controller", "PSX controller", | ||
109 | "PSX DDR controller", "SNES mouse" | ||
110 | }; | ||
91 | 111 | ||
92 | static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", | ||
93 | "Multisystem 2-button joystick", "N64 controller", "PSX controller", | ||
94 | "PSX DDR controller", "SNES mouse" }; | ||
95 | /* | 112 | /* |
96 | * N64 support. | 113 | * N64 support. |
97 | */ | 114 | */ |
98 | 115 | ||
99 | static unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 }; | 116 | static const unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 }; |
100 | static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START }; | 117 | static const short gc_n64_btn[] = { |
118 | BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, | ||
119 | BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START | ||
120 | }; | ||
101 | 121 | ||
102 | #define GC_N64_LENGTH 32 /* N64 bit length, not including stop bit */ | 122 | #define GC_N64_LENGTH 32 /* N64 bit length, not including stop bit */ |
103 | #define GC_N64_REQUEST_LENGTH 37 /* transmit request sequence is 9 bits long */ | 123 | #define GC_N64_STOP_LENGTH 5 /* Length of encoded stop bit */ |
124 | #define GC_N64_CMD_00 0x11111111UL | ||
125 | #define GC_N64_CMD_01 0xd1111111UL | ||
126 | #define GC_N64_CMD_03 0xdd111111UL | ||
127 | #define GC_N64_CMD_1b 0xdd1dd111UL | ||
128 | #define GC_N64_CMD_c0 0x111111ddUL | ||
129 | #define GC_N64_CMD_80 0x1111111dUL | ||
130 | #define GC_N64_STOP_BIT 0x1d /* Encoded stop bit */ | ||
131 | #define GC_N64_REQUEST_DATA GC_N64_CMD_01 /* the request data command */ | ||
104 | #define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */ | 132 | #define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */ |
105 | #define GC_N64_REQUEST 0x1dd1111111ULL /* the request data command (encoded for 000000011) */ | ||
106 | #define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */ | 133 | #define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */ |
107 | /* GC_N64_DWS > 24 is known to fail */ | 134 | /* GC_N64_DWS > 24 is known to fail */ |
108 | #define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */ | 135 | #define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */ |
@@ -114,8 +141,40 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, | |||
114 | #define GC_N64_CLOCK 0x02 /* clock bits for read */ | 141 | #define GC_N64_CLOCK 0x02 /* clock bits for read */ |
115 | 142 | ||
116 | /* | 143 | /* |
144 | * Used for rumble code. | ||
145 | */ | ||
146 | |||
147 | /* Send encoded command */ | ||
148 | static void gc_n64_send_command(struct gc *gc, unsigned long cmd, | ||
149 | unsigned char target) | ||
150 | { | ||
151 | struct parport *port = gc->pd->port; | ||
152 | int i; | ||
153 | |||
154 | for (i = 0; i < GC_N64_LENGTH; i++) { | ||
155 | unsigned char data = (cmd >> i) & 1 ? target : 0; | ||
156 | parport_write_data(port, GC_N64_POWER_W | data); | ||
157 | udelay(GC_N64_DWS); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* Send stop bit */ | ||
162 | static void gc_n64_send_stop_bit(struct gc *gc, unsigned char target) | ||
163 | { | ||
164 | struct parport *port = gc->pd->port; | ||
165 | int i; | ||
166 | |||
167 | for (i = 0; i < GC_N64_STOP_LENGTH; i++) { | ||
168 | unsigned char data = (GC_N64_STOP_BIT >> i) & 1 ? target : 0; | ||
169 | parport_write_data(port, GC_N64_POWER_W | data); | ||
170 | udelay(GC_N64_DWS); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /* | ||
117 | * gc_n64_read_packet() reads an N64 packet. | 175 | * gc_n64_read_packet() reads an N64 packet. |
118 | * Each pad uses one bit per byte. So all pads connected to this port are read in parallel. | 176 | * Each pad uses one bit per byte. So all pads connected to this port |
177 | * are read in parallel. | ||
119 | */ | 178 | */ |
120 | 179 | ||
121 | static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | 180 | static void gc_n64_read_packet(struct gc *gc, unsigned char *data) |
@@ -128,14 +187,13 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | |||
128 | */ | 187 | */ |
129 | 188 | ||
130 | local_irq_save(flags); | 189 | local_irq_save(flags); |
131 | for (i = 0; i < GC_N64_REQUEST_LENGTH; i++) { | 190 | gc_n64_send_command(gc, GC_N64_REQUEST_DATA, GC_N64_OUT); |
132 | parport_write_data(gc->pd->port, GC_N64_POWER_W | ((GC_N64_REQUEST >> i) & 1 ? GC_N64_OUT : 0)); | 191 | gc_n64_send_stop_bit(gc, GC_N64_OUT); |
133 | udelay(GC_N64_DWS); | ||
134 | } | ||
135 | local_irq_restore(flags); | 192 | local_irq_restore(flags); |
136 | 193 | ||
137 | /* | 194 | /* |
138 | * Wait for the pad response to be loaded into the 33-bit register of the adapter | 195 | * Wait for the pad response to be loaded into the 33-bit register |
196 | * of the adapter. | ||
139 | */ | 197 | */ |
140 | 198 | ||
141 | udelay(GC_N64_DELAY); | 199 | udelay(GC_N64_DELAY); |
@@ -146,13 +204,15 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | |||
146 | 204 | ||
147 | for (i = 0; i < GC_N64_LENGTH; i++) { | 205 | for (i = 0; i < GC_N64_LENGTH; i++) { |
148 | parport_write_data(gc->pd->port, GC_N64_POWER_R); | 206 | parport_write_data(gc->pd->port, GC_N64_POWER_R); |
207 | udelay(2); | ||
149 | data[i] = parport_read_status(gc->pd->port); | 208 | data[i] = parport_read_status(gc->pd->port); |
150 | parport_write_data(gc->pd->port, GC_N64_POWER_R | GC_N64_CLOCK); | 209 | parport_write_data(gc->pd->port, GC_N64_POWER_R | GC_N64_CLOCK); |
151 | } | 210 | } |
152 | 211 | ||
153 | /* | 212 | /* |
154 | * We must wait 200 ms here for the controller to reinitialize before the next read request. | 213 | * We must wait 200 ms here for the controller to reinitialize before |
155 | * No worries as long as gc_read is polled less frequently than this. | 214 | * the next read request. No worries as long as gc_read is polled less |
215 | * frequently than this. | ||
156 | */ | 216 | */ |
157 | 217 | ||
158 | } | 218 | } |
@@ -160,45 +220,112 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | |||
160 | static void gc_n64_process_packet(struct gc *gc) | 220 | static void gc_n64_process_packet(struct gc *gc) |
161 | { | 221 | { |
162 | unsigned char data[GC_N64_LENGTH]; | 222 | unsigned char data[GC_N64_LENGTH]; |
163 | signed char axes[2]; | ||
164 | struct input_dev *dev; | 223 | struct input_dev *dev; |
165 | int i, j, s; | 224 | int i, j, s; |
225 | signed char x, y; | ||
166 | 226 | ||
167 | gc_n64_read_packet(gc, data); | 227 | gc_n64_read_packet(gc, data); |
168 | 228 | ||
169 | for (i = 0; i < GC_MAX_DEVICES; i++) { | 229 | for (i = 0; i < GC_MAX_DEVICES; i++) { |
170 | 230 | ||
171 | dev = gc->dev[i]; | 231 | if (gc->pads[i].type != GC_N64) |
172 | if (!dev) | ||
173 | continue; | 232 | continue; |
174 | 233 | ||
234 | dev = gc->pads[i].dev; | ||
175 | s = gc_status_bit[i]; | 235 | s = gc_status_bit[i]; |
176 | 236 | ||
177 | if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) { | 237 | if (s & ~(data[8] | data[9])) { |
178 | 238 | ||
179 | axes[0] = axes[1] = 0; | 239 | x = y = 0; |
180 | 240 | ||
181 | for (j = 0; j < 8; j++) { | 241 | for (j = 0; j < 8; j++) { |
182 | if (data[23 - j] & s) | 242 | if (data[23 - j] & s) |
183 | axes[0] |= 1 << j; | 243 | x |= 1 << j; |
184 | if (data[31 - j] & s) | 244 | if (data[31 - j] & s) |
185 | axes[1] |= 1 << j; | 245 | y |= 1 << j; |
186 | } | 246 | } |
187 | 247 | ||
188 | input_report_abs(dev, ABS_X, axes[0]); | 248 | input_report_abs(dev, ABS_X, x); |
189 | input_report_abs(dev, ABS_Y, -axes[1]); | 249 | input_report_abs(dev, ABS_Y, -y); |
190 | 250 | ||
191 | input_report_abs(dev, ABS_HAT0X, !(s & data[6]) - !(s & data[7])); | 251 | input_report_abs(dev, ABS_HAT0X, |
192 | input_report_abs(dev, ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); | 252 | !(s & data[6]) - !(s & data[7])); |
253 | input_report_abs(dev, ABS_HAT0Y, | ||
254 | !(s & data[4]) - !(s & data[5])); | ||
193 | 255 | ||
194 | for (j = 0; j < 10; j++) | 256 | for (j = 0; j < 10; j++) |
195 | input_report_key(dev, gc_n64_btn[j], s & data[gc_n64_bytes[j]]); | 257 | input_report_key(dev, gc_n64_btn[j], |
258 | s & data[gc_n64_bytes[j]]); | ||
196 | 259 | ||
197 | input_sync(dev); | 260 | input_sync(dev); |
198 | } | 261 | } |
199 | } | 262 | } |
200 | } | 263 | } |
201 | 264 | ||
265 | static int gc_n64_play_effect(struct input_dev *dev, void *data, | ||
266 | struct ff_effect *effect) | ||
267 | { | ||
268 | int i; | ||
269 | unsigned long flags; | ||
270 | struct gc *gc = input_get_drvdata(dev); | ||
271 | struct gc_subdev *sdev = data; | ||
272 | unsigned char target = 1 << sdev->idx; /* select desired pin */ | ||
273 | |||
274 | if (effect->type == FF_RUMBLE) { | ||
275 | struct ff_rumble_effect *rumble = &effect->u.rumble; | ||
276 | unsigned int cmd = | ||
277 | rumble->strong_magnitude || rumble->weak_magnitude ? | ||
278 | GC_N64_CMD_01 : GC_N64_CMD_00; | ||
279 | |||
280 | local_irq_save(flags); | ||
281 | |||
282 | /* Init Rumble - 0x03, 0x80, 0x01, (34)0x80 */ | ||
283 | gc_n64_send_command(gc, GC_N64_CMD_03, target); | ||
284 | gc_n64_send_command(gc, GC_N64_CMD_80, target); | ||
285 | gc_n64_send_command(gc, GC_N64_CMD_01, target); | ||
286 | for (i = 0; i < 32; i++) | ||
287 | gc_n64_send_command(gc, GC_N64_CMD_80, target); | ||
288 | gc_n64_send_stop_bit(gc, target); | ||
289 | |||
290 | udelay(GC_N64_DELAY); | ||
291 | |||
292 | /* Now start or stop it - 0x03, 0xc0, 0zx1b, (32)0x01/0x00 */ | ||
293 | gc_n64_send_command(gc, GC_N64_CMD_03, target); | ||
294 | gc_n64_send_command(gc, GC_N64_CMD_c0, target); | ||
295 | gc_n64_send_command(gc, GC_N64_CMD_1b, target); | ||
296 | for (i = 0; i < 32; i++) | ||
297 | gc_n64_send_command(gc, cmd, target); | ||
298 | gc_n64_send_stop_bit(gc, target); | ||
299 | |||
300 | local_irq_restore(flags); | ||
301 | |||
302 | } | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static int __init gc_n64_init_ff(struct input_dev *dev, int i) | ||
308 | { | ||
309 | struct gc_subdev *sdev; | ||
310 | int err; | ||
311 | |||
312 | sdev = kmalloc(sizeof(*sdev), GFP_KERNEL); | ||
313 | if (!sdev) | ||
314 | return -ENOMEM; | ||
315 | |||
316 | sdev->idx = i; | ||
317 | |||
318 | input_set_capability(dev, EV_FF, FF_RUMBLE); | ||
319 | |||
320 | err = input_ff_create_memless(dev, sdev, gc_n64_play_effect); | ||
321 | if (err) { | ||
322 | kfree(sdev); | ||
323 | return err; | ||
324 | } | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
202 | /* | 329 | /* |
203 | * NES/SNES support. | 330 | * NES/SNES support. |
204 | */ | 331 | */ |
@@ -214,9 +341,11 @@ static void gc_n64_process_packet(struct gc *gc) | |||
214 | #define GC_NES_CLOCK 0x01 | 341 | #define GC_NES_CLOCK 0x01 |
215 | #define GC_NES_LATCH 0x02 | 342 | #define GC_NES_LATCH 0x02 |
216 | 343 | ||
217 | static unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 }; | 344 | static const unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 }; |
218 | static unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 }; | 345 | static const unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 }; |
219 | static short gc_snes_btn[] = { BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR }; | 346 | static const short gc_snes_btn[] = { |
347 | BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR | ||
348 | }; | ||
220 | 349 | ||
221 | /* | 350 | /* |
222 | * gc_nes_read_packet() reads a NES/SNES packet. | 351 | * gc_nes_read_packet() reads a NES/SNES packet. |
@@ -244,40 +373,51 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data) | |||
244 | static void gc_nes_process_packet(struct gc *gc) | 373 | static void gc_nes_process_packet(struct gc *gc) |
245 | { | 374 | { |
246 | unsigned char data[GC_SNESMOUSE_LENGTH]; | 375 | unsigned char data[GC_SNESMOUSE_LENGTH]; |
376 | struct gc_pad *pad; | ||
247 | struct input_dev *dev; | 377 | struct input_dev *dev; |
248 | int i, j, s, len; | 378 | int i, j, s, len; |
249 | char x_rel, y_rel; | 379 | char x_rel, y_rel; |
250 | 380 | ||
251 | len = gc->pads[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH : | 381 | len = gc->pad_count[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH : |
252 | (gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH); | 382 | (gc->pad_count[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH); |
253 | 383 | ||
254 | gc_nes_read_packet(gc, len, data); | 384 | gc_nes_read_packet(gc, len, data); |
255 | 385 | ||
256 | for (i = 0; i < GC_MAX_DEVICES; i++) { | 386 | for (i = 0; i < GC_MAX_DEVICES; i++) { |
257 | 387 | ||
258 | dev = gc->dev[i]; | 388 | pad = &gc->pads[i]; |
259 | if (!dev) | 389 | dev = pad->dev; |
260 | continue; | ||
261 | |||
262 | s = gc_status_bit[i]; | 390 | s = gc_status_bit[i]; |
263 | 391 | ||
264 | if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) { | 392 | switch (pad->type) { |
393 | |||
394 | case GC_NES: | ||
395 | |||
265 | input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); | 396 | input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); |
266 | input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); | 397 | input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); |
267 | } | ||
268 | 398 | ||
269 | if (s & gc->pads[GC_NES]) | ||
270 | for (j = 0; j < 4; j++) | 399 | for (j = 0; j < 4; j++) |
271 | input_report_key(dev, gc_snes_btn[j], s & data[gc_nes_bytes[j]]); | 400 | input_report_key(dev, gc_snes_btn[j], |
401 | s & data[gc_nes_bytes[j]]); | ||
402 | input_sync(dev); | ||
403 | break; | ||
404 | |||
405 | case GC_SNES: | ||
406 | |||
407 | input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); | ||
408 | input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); | ||
272 | 409 | ||
273 | if (s & gc->pads[GC_SNES]) | ||
274 | for (j = 0; j < 8; j++) | 410 | for (j = 0; j < 8; j++) |
275 | input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); | 411 | input_report_key(dev, gc_snes_btn[j], |
412 | s & data[gc_snes_bytes[j]]); | ||
413 | input_sync(dev); | ||
414 | break; | ||
276 | 415 | ||
277 | if (s & gc->pads[GC_SNESMOUSE]) { | 416 | case GC_SNESMOUSE: |
278 | /* | 417 | /* |
279 | * The 4 unused bits from SNES controllers appear to be ID bits | 418 | * The 4 unused bits from SNES controllers appear |
280 | * so use them to make sure iwe are dealing with a mouse. | 419 | * to be ID bits so use them to make sure we are |
420 | * dealing with a mouse. | ||
281 | * gamepad is connected. This is important since | 421 | * gamepad is connected. This is important since |
282 | * my SNES gamepad sends 1's for bits 16-31, which | 422 | * my SNES gamepad sends 1's for bits 16-31, which |
283 | * cause the mouse pointer to quickly move to the | 423 | * cause the mouse pointer to quickly move to the |
@@ -310,9 +450,14 @@ static void gc_nes_process_packet(struct gc *gc) | |||
310 | y_rel = -y_rel; | 450 | y_rel = -y_rel; |
311 | input_report_rel(dev, REL_Y, y_rel); | 451 | input_report_rel(dev, REL_Y, y_rel); |
312 | } | 452 | } |
453 | |||
454 | input_sync(dev); | ||
313 | } | 455 | } |
456 | break; | ||
457 | |||
458 | default: | ||
459 | break; | ||
314 | } | 460 | } |
315 | input_sync(dev); | ||
316 | } | 461 | } |
317 | } | 462 | } |
318 | 463 | ||
@@ -340,29 +485,35 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data) | |||
340 | static void gc_multi_process_packet(struct gc *gc) | 485 | static void gc_multi_process_packet(struct gc *gc) |
341 | { | 486 | { |
342 | unsigned char data[GC_MULTI2_LENGTH]; | 487 | unsigned char data[GC_MULTI2_LENGTH]; |
488 | int data_len = gc->pad_count[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH; | ||
489 | struct gc_pad *pad; | ||
343 | struct input_dev *dev; | 490 | struct input_dev *dev; |
344 | int i, s; | 491 | int i, s; |
345 | 492 | ||
346 | gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data); | 493 | gc_multi_read_packet(gc, data_len, data); |
347 | 494 | ||
348 | for (i = 0; i < GC_MAX_DEVICES; i++) { | 495 | for (i = 0; i < GC_MAX_DEVICES; i++) { |
349 | 496 | pad = &gc->pads[i]; | |
350 | dev = gc->dev[i]; | 497 | dev = pad->dev; |
351 | if (!dev) | ||
352 | continue; | ||
353 | |||
354 | s = gc_status_bit[i]; | 498 | s = gc_status_bit[i]; |
355 | 499 | ||
356 | if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { | 500 | switch (pad->type) { |
357 | input_report_abs(dev, ABS_X, !(s & data[2]) - !(s & data[3])); | 501 | case GC_MULTI2: |
358 | input_report_abs(dev, ABS_Y, !(s & data[0]) - !(s & data[1])); | ||
359 | input_report_key(dev, BTN_TRIGGER, s & data[4]); | ||
360 | } | ||
361 | |||
362 | if (s & gc->pads[GC_MULTI2]) | ||
363 | input_report_key(dev, BTN_THUMB, s & data[5]); | 502 | input_report_key(dev, BTN_THUMB, s & data[5]); |
503 | /* fall through */ | ||
364 | 504 | ||
365 | input_sync(dev); | 505 | case GC_MULTI: |
506 | input_report_abs(dev, ABS_X, | ||
507 | !(s & data[2]) - !(s & data[3])); | ||
508 | input_report_abs(dev, ABS_Y, | ||
509 | !(s & data[0]) - !(s & data[1])); | ||
510 | input_report_key(dev, BTN_TRIGGER, s & data[4]); | ||
511 | input_sync(dev); | ||
512 | break; | ||
513 | |||
514 | default: | ||
515 | break; | ||
516 | } | ||
366 | } | 517 | } |
367 | } | 518 | } |
368 | 519 | ||
@@ -370,9 +521,8 @@ static void gc_multi_process_packet(struct gc *gc) | |||
370 | * PSX support | 521 | * PSX support |
371 | * | 522 | * |
372 | * See documentation at: | 523 | * See documentation at: |
373 | * http://www.dim.com/~mackys/psxmemcard/ps-eng2.txt | 524 | * http://www.geocities.co.jp/Playtown/2004/psx/ps_eng.txt |
374 | * http://www.gamesx.com/controldata/psxcont/psxcont.htm | 525 | * http://www.gamesx.com/controldata/psxcont/psxcont.htm |
375 | * ftp://milano.usal.es/pablo/ | ||
376 | * | 526 | * |
377 | */ | 527 | */ |
378 | 528 | ||
@@ -398,30 +548,41 @@ static int gc_psx_delay = GC_PSX_DELAY; | |||
398 | module_param_named(psx_delay, gc_psx_delay, uint, 0); | 548 | module_param_named(psx_delay, gc_psx_delay, uint, 0); |
399 | MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)"); | 549 | MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)"); |
400 | 550 | ||
401 | static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y }; | 551 | static const short gc_psx_abs[] = { |
402 | static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, | 552 | ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y |
403 | BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR }; | 553 | }; |
404 | static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; | 554 | static const short gc_psx_btn[] = { |
555 | BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, | ||
556 | BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR | ||
557 | }; | ||
558 | static const short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; | ||
405 | 559 | ||
406 | /* | 560 | /* |
407 | * gc_psx_command() writes 8bit command and reads 8bit data from | 561 | * gc_psx_command() writes 8bit command and reads 8bit data from |
408 | * the psx pad. | 562 | * the psx pad. |
409 | */ | 563 | */ |
410 | 564 | ||
411 | static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_MAX_DEVICES]) | 565 | static void gc_psx_command(struct gc *gc, int b, unsigned char *data) |
412 | { | 566 | { |
567 | struct parport *port = gc->pd->port; | ||
413 | int i, j, cmd, read; | 568 | int i, j, cmd, read; |
414 | 569 | ||
415 | for (i = 0; i < GC_MAX_DEVICES; i++) | 570 | memset(data, 0, GC_MAX_DEVICES); |
416 | data[i] = 0; | ||
417 | 571 | ||
418 | for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) { | 572 | for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) { |
419 | cmd = (b & 1) ? GC_PSX_COMMAND : 0; | 573 | cmd = (b & 1) ? GC_PSX_COMMAND : 0; |
420 | parport_write_data(gc->pd->port, cmd | GC_PSX_POWER); | 574 | parport_write_data(port, cmd | GC_PSX_POWER); |
421 | udelay(gc_psx_delay); | 575 | udelay(gc_psx_delay); |
422 | read = parport_read_status(gc->pd->port) ^ 0x80; | 576 | |
423 | for (j = 0; j < GC_MAX_DEVICES; j++) | 577 | read = parport_read_status(port) ^ 0x80; |
424 | data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0; | 578 | |
579 | for (j = 0; j < GC_MAX_DEVICES; j++) { | ||
580 | struct gc_pad *pad = &gc->pads[j]; | ||
581 | |||
582 | if (pad->type == GC_PSX || pad->type == GC_DDR) | ||
583 | data[j] |= (read & gc_status_bit[j]) ? (1 << i) : 0; | ||
584 | } | ||
585 | |||
425 | parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); | 586 | parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); |
426 | udelay(gc_psx_delay); | 587 | udelay(gc_psx_delay); |
427 | } | 588 | } |
@@ -432,31 +593,40 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_MAX_DEVIC | |||
432 | * device identifier code. | 593 | * device identifier code. |
433 | */ | 594 | */ |
434 | 595 | ||
435 | static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES], | 596 | static void gc_psx_read_packet(struct gc *gc, |
597 | unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES], | ||
436 | unsigned char id[GC_MAX_DEVICES]) | 598 | unsigned char id[GC_MAX_DEVICES]) |
437 | { | 599 | { |
438 | int i, j, max_len = 0; | 600 | int i, j, max_len = 0; |
439 | unsigned long flags; | 601 | unsigned long flags; |
440 | unsigned char data2[GC_MAX_DEVICES]; | 602 | unsigned char data2[GC_MAX_DEVICES]; |
441 | 603 | ||
442 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ | 604 | /* Select pad */ |
605 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); | ||
443 | udelay(gc_psx_delay); | 606 | udelay(gc_psx_delay); |
444 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); /* Deselect, begin command */ | 607 | /* Deselect, begin command */ |
608 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); | ||
445 | udelay(gc_psx_delay); | 609 | udelay(gc_psx_delay); |
446 | 610 | ||
447 | local_irq_save(flags); | 611 | local_irq_save(flags); |
448 | 612 | ||
449 | gc_psx_command(gc, 0x01, data2); /* Access pad */ | 613 | gc_psx_command(gc, 0x01, data2); /* Access pad */ |
450 | gc_psx_command(gc, 0x42, id); /* Get device ids */ | 614 | gc_psx_command(gc, 0x42, id); /* Get device ids */ |
451 | gc_psx_command(gc, 0, data2); /* Dump status */ | 615 | gc_psx_command(gc, 0, data2); /* Dump status */ |
452 | 616 | ||
453 | for (i =0; i < GC_MAX_DEVICES; i++) /* Find the longest pad */ | 617 | /* Find the longest pad */ |
454 | if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) | 618 | for (i = 0; i < GC_MAX_DEVICES; i++) { |
455 | && (GC_PSX_LEN(id[i]) > max_len) | 619 | struct gc_pad *pad = &gc->pads[i]; |
456 | && (GC_PSX_LEN(id[i]) <= GC_PSX_BYTES)) | 620 | |
621 | if ((pad->type == GC_PSX || pad->type == GC_DDR) && | ||
622 | GC_PSX_LEN(id[i]) > max_len && | ||
623 | GC_PSX_LEN(id[i]) <= GC_PSX_BYTES) { | ||
457 | max_len = GC_PSX_LEN(id[i]); | 624 | max_len = GC_PSX_LEN(id[i]); |
625 | } | ||
626 | } | ||
458 | 627 | ||
459 | for (i = 0; i < max_len; i++) { /* Read in all the data */ | 628 | /* Read in all the data */ |
629 | for (i = 0; i < max_len; i++) { | ||
460 | gc_psx_command(gc, 0, data2); | 630 | gc_psx_command(gc, 0, data2); |
461 | for (j = 0; j < GC_MAX_DEVICES; j++) | 631 | for (j = 0; j < GC_MAX_DEVICES; j++) |
462 | data[j][i] = data2[j]; | 632 | data[j][i] = data2[j]; |
@@ -466,86 +636,104 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES] | |||
466 | 636 | ||
467 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); | 637 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); |
468 | 638 | ||
469 | for(i = 0; i < GC_MAX_DEVICES; i++) /* Set id's to the real value */ | 639 | /* Set id's to the real value */ |
640 | for (i = 0; i < GC_MAX_DEVICES; i++) | ||
470 | id[i] = GC_PSX_ID(id[i]); | 641 | id[i] = GC_PSX_ID(id[i]); |
471 | } | 642 | } |
472 | 643 | ||
473 | static void gc_psx_process_packet(struct gc *gc) | 644 | static void gc_psx_report_one(struct gc_pad *pad, unsigned char psx_type, |
645 | unsigned char *data) | ||
474 | { | 646 | { |
475 | unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES]; | 647 | struct input_dev *dev = pad->dev; |
476 | unsigned char id[GC_MAX_DEVICES]; | 648 | int i; |
477 | struct input_dev *dev; | ||
478 | int i, j; | ||
479 | 649 | ||
480 | gc_psx_read_packet(gc, data, id); | 650 | switch (psx_type) { |
481 | 651 | ||
482 | for (i = 0; i < GC_MAX_DEVICES; i++) { | 652 | case GC_PSX_RUMBLE: |
483 | 653 | ||
484 | dev = gc->dev[i]; | 654 | input_report_key(dev, BTN_THUMBL, ~data[0] & 0x04); |
485 | if (!dev) | 655 | input_report_key(dev, BTN_THUMBR, ~data[0] & 0x02); |
486 | continue; | ||
487 | 656 | ||
488 | switch (id[i]) { | 657 | case GC_PSX_NEGCON: |
658 | case GC_PSX_ANALOG: | ||
489 | 659 | ||
490 | case GC_PSX_RUMBLE: | 660 | if (pad->type == GC_DDR) { |
661 | for (i = 0; i < 4; i++) | ||
662 | input_report_key(dev, gc_psx_ddr_btn[i], | ||
663 | ~data[0] & (0x10 << i)); | ||
664 | } else { | ||
665 | for (i = 0; i < 4; i++) | ||
666 | input_report_abs(dev, gc_psx_abs[i + 2], | ||
667 | data[i + 2]); | ||
491 | 668 | ||
492 | input_report_key(dev, BTN_THUMBL, ~data[i][0] & 0x04); | 669 | input_report_abs(dev, ABS_X, |
493 | input_report_key(dev, BTN_THUMBR, ~data[i][0] & 0x02); | 670 | !!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127); |
671 | input_report_abs(dev, ABS_Y, | ||
672 | !!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127); | ||
673 | } | ||
494 | 674 | ||
495 | case GC_PSX_NEGCON: | 675 | for (i = 0; i < 8; i++) |
496 | case GC_PSX_ANALOG: | 676 | input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i)); |
497 | 677 | ||
498 | if (gc->pads[GC_DDR] & gc_status_bit[i]) { | 678 | input_report_key(dev, BTN_START, ~data[0] & 0x08); |
499 | for(j = 0; j < 4; j++) | 679 | input_report_key(dev, BTN_SELECT, ~data[0] & 0x01); |
500 | input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); | ||
501 | } else { | ||
502 | for (j = 0; j < 4; j++) | ||
503 | input_report_abs(dev, gc_psx_abs[j + 2], data[i][j + 2]); | ||
504 | 680 | ||
505 | input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); | 681 | input_sync(dev); |
506 | input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); | ||
507 | } | ||
508 | 682 | ||
509 | for (j = 0; j < 8; j++) | 683 | break; |
510 | input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); | ||
511 | 684 | ||
512 | input_report_key(dev, BTN_START, ~data[i][0] & 0x08); | 685 | case GC_PSX_NORMAL: |
513 | input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); | ||
514 | 686 | ||
515 | input_sync(dev); | 687 | if (pad->type == GC_DDR) { |
688 | for (i = 0; i < 4; i++) | ||
689 | input_report_key(dev, gc_psx_ddr_btn[i], | ||
690 | ~data[0] & (0x10 << i)); | ||
691 | } else { | ||
692 | input_report_abs(dev, ABS_X, | ||
693 | !!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127); | ||
694 | input_report_abs(dev, ABS_Y, | ||
695 | !!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127); | ||
516 | 696 | ||
517 | break; | 697 | /* |
518 | 698 | * For some reason if the extra axes are left unset | |
519 | case GC_PSX_NORMAL: | 699 | * they drift. |
520 | if (gc->pads[GC_DDR] & gc_status_bit[i]) { | 700 | * for (i = 0; i < 4; i++) |
521 | for(j = 0; j < 4; j++) | 701 | input_report_abs(dev, gc_psx_abs[i + 2], 128); |
522 | input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); | 702 | * This needs to be debugged properly, |
523 | } else { | 703 | * maybe fuzz processing needs to be done |
524 | input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); | 704 | * in input_sync() |
525 | input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); | 705 | * --vojtech |
526 | 706 | */ | |
527 | /* for some reason if the extra axes are left unset they drift */ | 707 | } |
528 | /* for (j = 0; j < 4; j++) | ||
529 | input_report_abs(dev, gc_psx_abs[j + 2], 128); | ||
530 | * This needs to be debugged properly, | ||
531 | * maybe fuzz processing needs to be done in input_sync() | ||
532 | * --vojtech | ||
533 | */ | ||
534 | } | ||
535 | 708 | ||
536 | for (j = 0; j < 8; j++) | 709 | for (i = 0; i < 8; i++) |
537 | input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); | 710 | input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i)); |
538 | 711 | ||
539 | input_report_key(dev, BTN_START, ~data[i][0] & 0x08); | 712 | input_report_key(dev, BTN_START, ~data[0] & 0x08); |
540 | input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); | 713 | input_report_key(dev, BTN_SELECT, ~data[0] & 0x01); |
541 | 714 | ||
542 | input_sync(dev); | 715 | input_sync(dev); |
543 | 716 | ||
544 | break; | 717 | break; |
545 | 718 | ||
546 | case 0: /* not a pad, ignore */ | 719 | default: /* not a pad, ignore */ |
547 | break; | 720 | break; |
548 | } | 721 | } |
722 | } | ||
723 | |||
724 | static void gc_psx_process_packet(struct gc *gc) | ||
725 | { | ||
726 | unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES]; | ||
727 | unsigned char id[GC_MAX_DEVICES]; | ||
728 | struct gc_pad *pad; | ||
729 | int i; | ||
730 | |||
731 | gc_psx_read_packet(gc, data, id); | ||
732 | |||
733 | for (i = 0; i < GC_MAX_DEVICES; i++) { | ||
734 | pad = &gc->pads[i]; | ||
735 | if (pad->type == GC_PSX || pad->type == GC_DDR) | ||
736 | gc_psx_report_one(pad, id[i], data[i]); | ||
549 | } | 737 | } |
550 | } | 738 | } |
551 | 739 | ||
@@ -561,28 +749,31 @@ static void gc_timer(unsigned long private) | |||
561 | * N64 pads - must be read first, any read confuses them for 200 us | 749 | * N64 pads - must be read first, any read confuses them for 200 us |
562 | */ | 750 | */ |
563 | 751 | ||
564 | if (gc->pads[GC_N64]) | 752 | if (gc->pad_count[GC_N64]) |
565 | gc_n64_process_packet(gc); | 753 | gc_n64_process_packet(gc); |
566 | 754 | ||
567 | /* | 755 | /* |
568 | * NES and SNES pads or mouse | 756 | * NES and SNES pads or mouse |
569 | */ | 757 | */ |
570 | 758 | ||
571 | if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE]) | 759 | if (gc->pad_count[GC_NES] || |
760 | gc->pad_count[GC_SNES] || | ||
761 | gc->pad_count[GC_SNESMOUSE]) { | ||
572 | gc_nes_process_packet(gc); | 762 | gc_nes_process_packet(gc); |
763 | } | ||
573 | 764 | ||
574 | /* | 765 | /* |
575 | * Multi and Multi2 joysticks | 766 | * Multi and Multi2 joysticks |
576 | */ | 767 | */ |
577 | 768 | ||
578 | if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2]) | 769 | if (gc->pad_count[GC_MULTI] || gc->pad_count[GC_MULTI2]) |
579 | gc_multi_process_packet(gc); | 770 | gc_multi_process_packet(gc); |
580 | 771 | ||
581 | /* | 772 | /* |
582 | * PSX controllers | 773 | * PSX controllers |
583 | */ | 774 | */ |
584 | 775 | ||
585 | if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) | 776 | if (gc->pad_count[GC_PSX] || gc->pad_count[GC_DDR]) |
586 | gc_psx_process_packet(gc); | 777 | gc_psx_process_packet(gc); |
587 | 778 | ||
588 | mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); | 779 | mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); |
@@ -622,25 +813,29 @@ static void gc_close(struct input_dev *dev) | |||
622 | 813 | ||
623 | static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) | 814 | static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) |
624 | { | 815 | { |
816 | struct gc_pad *pad = &gc->pads[idx]; | ||
625 | struct input_dev *input_dev; | 817 | struct input_dev *input_dev; |
626 | int i; | 818 | int i; |
819 | int err; | ||
627 | 820 | ||
628 | if (!pad_type) | 821 | if (pad_type < 1 || pad_type >= GC_MAX) { |
629 | return 0; | 822 | pr_err("Pad type %d unknown\n", pad_type); |
630 | |||
631 | if (pad_type < 1 || pad_type > GC_MAX) { | ||
632 | printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type); | ||
633 | return -EINVAL; | 823 | return -EINVAL; |
634 | } | 824 | } |
635 | 825 | ||
636 | gc->dev[idx] = input_dev = input_allocate_device(); | 826 | pad->dev = input_dev = input_allocate_device(); |
637 | if (!input_dev) { | 827 | if (!input_dev) { |
638 | printk(KERN_ERR "gamecon.c: Not enough memory for input device\n"); | 828 | pr_err("Not enough memory for input device\n"); |
639 | return -ENOMEM; | 829 | return -ENOMEM; |
640 | } | 830 | } |
641 | 831 | ||
832 | pad->type = pad_type; | ||
833 | |||
834 | snprintf(pad->phys, sizeof(pad->phys), | ||
835 | "%s/input%d", gc->pd->port->name, idx); | ||
836 | |||
642 | input_dev->name = gc_names[pad_type]; | 837 | input_dev->name = gc_names[pad_type]; |
643 | input_dev->phys = gc->phys[idx]; | 838 | input_dev->phys = pad->phys; |
644 | input_dev->id.bustype = BUS_PARPORT; | 839 | input_dev->id.bustype = BUS_PARPORT; |
645 | input_dev->id.vendor = 0x0001; | 840 | input_dev->id.vendor = 0x0001; |
646 | input_dev->id.product = pad_type; | 841 | input_dev->id.product = pad_type; |
@@ -659,61 +854,76 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) | |||
659 | } else | 854 | } else |
660 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 855 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
661 | 856 | ||
662 | gc->pads[0] |= gc_status_bit[idx]; | 857 | gc->pad_count[pad_type]++; |
663 | gc->pads[pad_type] |= gc_status_bit[idx]; | ||
664 | 858 | ||
665 | switch (pad_type) { | 859 | switch (pad_type) { |
666 | 860 | ||
667 | case GC_N64: | 861 | case GC_N64: |
668 | for (i = 0; i < 10; i++) | 862 | for (i = 0; i < 10; i++) |
669 | set_bit(gc_n64_btn[i], input_dev->keybit); | 863 | __set_bit(gc_n64_btn[i], input_dev->keybit); |
670 | 864 | ||
671 | for (i = 0; i < 2; i++) { | 865 | for (i = 0; i < 2; i++) { |
672 | input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2); | 866 | input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2); |
673 | input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); | 867 | input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); |
674 | } | 868 | } |
675 | |||
676 | break; | ||
677 | |||
678 | case GC_SNESMOUSE: | ||
679 | set_bit(BTN_LEFT, input_dev->keybit); | ||
680 | set_bit(BTN_RIGHT, input_dev->keybit); | ||
681 | set_bit(REL_X, input_dev->relbit); | ||
682 | set_bit(REL_Y, input_dev->relbit); | ||
683 | break; | ||
684 | |||
685 | case GC_SNES: | ||
686 | for (i = 4; i < 8; i++) | ||
687 | set_bit(gc_snes_btn[i], input_dev->keybit); | ||
688 | case GC_NES: | ||
689 | for (i = 0; i < 4; i++) | ||
690 | set_bit(gc_snes_btn[i], input_dev->keybit); | ||
691 | break; | ||
692 | |||
693 | case GC_MULTI2: | ||
694 | set_bit(BTN_THUMB, input_dev->keybit); | ||
695 | case GC_MULTI: | ||
696 | set_bit(BTN_TRIGGER, input_dev->keybit); | ||
697 | break; | ||
698 | |||
699 | case GC_PSX: | ||
700 | for (i = 0; i < 6; i++) | ||
701 | input_set_abs_params(input_dev, gc_psx_abs[i], 4, 252, 0, 2); | ||
702 | for (i = 0; i < 12; i++) | ||
703 | set_bit(gc_psx_btn[i], input_dev->keybit); | ||
704 | |||
705 | break; | ||
706 | 869 | ||
707 | case GC_DDR: | 870 | err = gc_n64_init_ff(input_dev, idx); |
708 | for (i = 0; i < 4; i++) | 871 | if (err) { |
709 | set_bit(gc_psx_ddr_btn[i], input_dev->keybit); | 872 | pr_warning("Failed to initiate rumble for N64 device %d\n", idx); |
710 | for (i = 0; i < 12; i++) | 873 | goto err_free_dev; |
711 | set_bit(gc_psx_btn[i], input_dev->keybit); | 874 | } |
712 | 875 | ||
713 | break; | 876 | break; |
877 | |||
878 | case GC_SNESMOUSE: | ||
879 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
880 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
881 | __set_bit(REL_X, input_dev->relbit); | ||
882 | __set_bit(REL_Y, input_dev->relbit); | ||
883 | break; | ||
884 | |||
885 | case GC_SNES: | ||
886 | for (i = 4; i < 8; i++) | ||
887 | __set_bit(gc_snes_btn[i], input_dev->keybit); | ||
888 | case GC_NES: | ||
889 | for (i = 0; i < 4; i++) | ||
890 | __set_bit(gc_snes_btn[i], input_dev->keybit); | ||
891 | break; | ||
892 | |||
893 | case GC_MULTI2: | ||
894 | __set_bit(BTN_THUMB, input_dev->keybit); | ||
895 | case GC_MULTI: | ||
896 | __set_bit(BTN_TRIGGER, input_dev->keybit); | ||
897 | break; | ||
898 | |||
899 | case GC_PSX: | ||
900 | for (i = 0; i < 6; i++) | ||
901 | input_set_abs_params(input_dev, | ||
902 | gc_psx_abs[i], 4, 252, 0, 2); | ||
903 | for (i = 0; i < 12; i++) | ||
904 | __set_bit(gc_psx_btn[i], input_dev->keybit); | ||
905 | |||
906 | break; | ||
907 | |||
908 | case GC_DDR: | ||
909 | for (i = 0; i < 4; i++) | ||
910 | __set_bit(gc_psx_ddr_btn[i], input_dev->keybit); | ||
911 | for (i = 0; i < 12; i++) | ||
912 | __set_bit(gc_psx_btn[i], input_dev->keybit); | ||
913 | |||
914 | break; | ||
714 | } | 915 | } |
715 | 916 | ||
917 | err = input_register_device(pad->dev); | ||
918 | if (err) | ||
919 | goto err_free_dev; | ||
920 | |||
716 | return 0; | 921 | return 0; |
922 | |||
923 | err_free_dev: | ||
924 | input_free_device(pad->dev); | ||
925 | pad->dev = NULL; | ||
926 | return err; | ||
717 | } | 927 | } |
718 | 928 | ||
719 | static struct gc __init *gc_probe(int parport, int *pads, int n_pads) | 929 | static struct gc __init *gc_probe(int parport, int *pads, int n_pads) |
@@ -722,52 +932,47 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) | |||
722 | struct parport *pp; | 932 | struct parport *pp; |
723 | struct pardevice *pd; | 933 | struct pardevice *pd; |
724 | int i; | 934 | int i; |
935 | int count = 0; | ||
725 | int err; | 936 | int err; |
726 | 937 | ||
727 | pp = parport_find_number(parport); | 938 | pp = parport_find_number(parport); |
728 | if (!pp) { | 939 | if (!pp) { |
729 | printk(KERN_ERR "gamecon.c: no such parport\n"); | 940 | pr_err("no such parport %d\n", parport); |
730 | err = -EINVAL; | 941 | err = -EINVAL; |
731 | goto err_out; | 942 | goto err_out; |
732 | } | 943 | } |
733 | 944 | ||
734 | pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); | 945 | pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); |
735 | if (!pd) { | 946 | if (!pd) { |
736 | printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n"); | 947 | pr_err("parport busy already - lp.o loaded?\n"); |
737 | err = -EBUSY; | 948 | err = -EBUSY; |
738 | goto err_put_pp; | 949 | goto err_put_pp; |
739 | } | 950 | } |
740 | 951 | ||
741 | gc = kzalloc(sizeof(struct gc), GFP_KERNEL); | 952 | gc = kzalloc(sizeof(struct gc), GFP_KERNEL); |
742 | if (!gc) { | 953 | if (!gc) { |
743 | printk(KERN_ERR "gamecon.c: Not enough memory\n"); | 954 | pr_err("Not enough memory\n"); |
744 | err = -ENOMEM; | 955 | err = -ENOMEM; |
745 | goto err_unreg_pardev; | 956 | goto err_unreg_pardev; |
746 | } | 957 | } |
747 | 958 | ||
748 | mutex_init(&gc->mutex); | 959 | mutex_init(&gc->mutex); |
749 | gc->pd = pd; | 960 | gc->pd = pd; |
750 | init_timer(&gc->timer); | 961 | setup_timer(&gc->timer, gc_timer, (long) gc); |
751 | gc->timer.data = (long) gc; | ||
752 | gc->timer.function = gc_timer; | ||
753 | 962 | ||
754 | for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) { | 963 | for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) { |
755 | if (!pads[i]) | 964 | if (!pads[i]) |
756 | continue; | 965 | continue; |
757 | 966 | ||
758 | snprintf(gc->phys[i], sizeof(gc->phys[i]), | ||
759 | "%s/input%d", gc->pd->port->name, i); | ||
760 | err = gc_setup_pad(gc, i, pads[i]); | 967 | err = gc_setup_pad(gc, i, pads[i]); |
761 | if (err) | 968 | if (err) |
762 | goto err_unreg_devs; | 969 | goto err_unreg_devs; |
763 | 970 | ||
764 | err = input_register_device(gc->dev[i]); | 971 | count++; |
765 | if (err) | ||
766 | goto err_free_dev; | ||
767 | } | 972 | } |
768 | 973 | ||
769 | if (!gc->pads[0]) { | 974 | if (count == 0) { |
770 | printk(KERN_ERR "gamecon.c: No valid devices specified\n"); | 975 | pr_err("No valid devices specified\n"); |
771 | err = -EINVAL; | 976 | err = -EINVAL; |
772 | goto err_free_gc; | 977 | goto err_free_gc; |
773 | } | 978 | } |
@@ -775,12 +980,10 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) | |||
775 | parport_put_port(pp); | 980 | parport_put_port(pp); |
776 | return gc; | 981 | return gc; |
777 | 982 | ||
778 | err_free_dev: | ||
779 | input_free_device(gc->dev[i]); | ||
780 | err_unreg_devs: | 983 | err_unreg_devs: |
781 | while (--i >= 0) | 984 | while (--i >= 0) |
782 | if (gc->dev[i]) | 985 | if (gc->pads[i].dev) |
783 | input_unregister_device(gc->dev[i]); | 986 | input_unregister_device(gc->pads[i].dev); |
784 | err_free_gc: | 987 | err_free_gc: |
785 | kfree(gc); | 988 | kfree(gc); |
786 | err_unreg_pardev: | 989 | err_unreg_pardev: |
@@ -796,8 +999,8 @@ static void gc_remove(struct gc *gc) | |||
796 | int i; | 999 | int i; |
797 | 1000 | ||
798 | for (i = 0; i < GC_MAX_DEVICES; i++) | 1001 | for (i = 0; i < GC_MAX_DEVICES; i++) |
799 | if (gc->dev[i]) | 1002 | if (gc->pads[i].dev) |
800 | input_unregister_device(gc->dev[i]); | 1003 | input_unregister_device(gc->pads[i].dev); |
801 | parport_unregister_device(gc->pd); | 1004 | parport_unregister_device(gc->pd); |
802 | kfree(gc); | 1005 | kfree(gc); |
803 | } | 1006 | } |
@@ -813,7 +1016,7 @@ static int __init gc_init(void) | |||
813 | continue; | 1016 | continue; |
814 | 1017 | ||
815 | if (gc_cfg[i].nargs < 2) { | 1018 | if (gc_cfg[i].nargs < 2) { |
816 | printk(KERN_ERR "gamecon.c: at least one device must be specified\n"); | 1019 | pr_err("at least one device must be specified\n"); |
817 | err = -EINVAL; | 1020 | err = -EINVAL; |
818 | break; | 1021 | break; |
819 | } | 1022 | } |
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/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index b1edd778639c..405febd94f24 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
@@ -54,6 +54,9 @@ static signed short btn_avb_wheel[] = | |||
54 | static signed short abs_joystick[] = | 54 | static signed short abs_joystick[] = |
55 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 }; | 55 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 }; |
56 | 56 | ||
57 | static signed short abs_joystick_rudder[] = | ||
58 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 }; | ||
59 | |||
57 | static signed short abs_avb_pegasus[] = | 60 | static signed short abs_avb_pegasus[] = |
58 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, | 61 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, |
59 | ABS_HAT1X, ABS_HAT1Y, -1 }; | 62 | ABS_HAT1X, ABS_HAT1Y, -1 }; |
@@ -76,8 +79,9 @@ static struct iforce_device iforce_device[] = { | |||
76 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? | 79 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? |
77 | { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, | 80 | { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, |
78 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? | 81 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? |
82 | { 0x06f8, 0x0001, "Guillemot Jet Leader Force Feedback", btn_joystick, abs_joystick_rudder, ff_iforce }, | ||
79 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? | 83 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? |
80 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? | 84 | { 0x06f8, 0xa302, "Guillemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? |
81 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, | 85 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, |
82 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } | 86 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } |
83 | }; | 87 | }; |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index b41303d3ec54..6c96631ae5d9 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
@@ -212,6 +212,7 @@ static struct usb_device_id iforce_usb_ids [] = { | |||
212 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ | 212 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ |
213 | { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ | 213 | { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ |
214 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ | 214 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ |
215 | { USB_DEVICE(0x06f8, 0x0003) }, /* Guillemot Jet Leader Force Feedback */ | ||
215 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ | 216 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ |
216 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ | 217 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ |
217 | { } /* Terminating entry */ | 218 | { } /* Terminating entry */ |
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/turbografx.c b/drivers/input/joystick/turbografx.c index b6f859869540..d53b9e900234 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
38 | #include <linux/slab.h> | ||
38 | 39 | ||
39 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 40 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
40 | MODULE_DESCRIPTION("TurboGraFX parallel port interface driver"); | 41 | MODULE_DESCRIPTION("TurboGraFX parallel port interface driver"); |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 8a28fb7846dc..f9fb7fa10af3 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * 2005 Dominic Cerquetti <binary1230@yahoo.com> | 9 | * 2005 Dominic Cerquetti <binary1230@yahoo.com> |
10 | * 2006 Adam Buchbinder <adam.buchbinder@gmail.com> | 10 | * 2006 Adam Buchbinder <adam.buchbinder@gmail.com> |
11 | * 2007 Jan Kratochvil <honza@jikos.cz> | 11 | * 2007 Jan Kratochvil <honza@jikos.cz> |
12 | * 2010 Christoph Fritz <chf.fritz@googlemail.com> | ||
12 | * | 13 | * |
13 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or |
14 | * modify it under the terms of the GNU General Public License as | 15 | * modify it under the terms of the GNU General Public License as |
@@ -86,9 +87,11 @@ | |||
86 | 87 | ||
87 | /* xbox d-pads should map to buttons, as is required for DDR pads | 88 | /* xbox d-pads should map to buttons, as is required for DDR pads |
88 | but we map them to axes when possible to simplify things */ | 89 | but we map them to axes when possible to simplify things */ |
89 | #define MAP_DPAD_TO_BUTTONS 0 | 90 | #define MAP_DPAD_TO_BUTTONS (1 << 0) |
90 | #define MAP_DPAD_TO_AXES 1 | 91 | #define MAP_TRIGGERS_TO_BUTTONS (1 << 1) |
91 | #define MAP_DPAD_UNKNOWN 2 | 92 | #define MAP_STICKS_TO_NULL (1 << 2) |
93 | #define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \ | ||
94 | MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) | ||
92 | 95 | ||
93 | #define XTYPE_XBOX 0 | 96 | #define XTYPE_XBOX 0 |
94 | #define XTYPE_XBOX360 1 | 97 | #define XTYPE_XBOX360 1 |
@@ -99,63 +102,73 @@ static int dpad_to_buttons; | |||
99 | module_param(dpad_to_buttons, bool, S_IRUGO); | 102 | module_param(dpad_to_buttons, bool, S_IRUGO); |
100 | MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); | 103 | MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); |
101 | 104 | ||
105 | static int triggers_to_buttons; | ||
106 | module_param(triggers_to_buttons, bool, S_IRUGO); | ||
107 | MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads"); | ||
108 | |||
109 | static int sticks_to_null; | ||
110 | module_param(sticks_to_null, bool, S_IRUGO); | ||
111 | MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads"); | ||
112 | |||
102 | static const struct xpad_device { | 113 | static const struct xpad_device { |
103 | u16 idVendor; | 114 | u16 idVendor; |
104 | u16 idProduct; | 115 | u16 idProduct; |
105 | char *name; | 116 | char *name; |
106 | u8 dpad_mapping; | 117 | u8 mapping; |
107 | u8 xtype; | 118 | u8 xtype; |
108 | } xpad_device[] = { | 119 | } xpad_device[] = { |
109 | { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 120 | { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX }, |
110 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 121 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, |
111 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 122 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX }, |
112 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 123 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, |
113 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, | 124 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, |
114 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 125 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", DANCEPAD_MAP_CONFIG, XTYPE_XBOX }, |
115 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 126 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, |
116 | { 0x046d, 0xc242, "Logitech Chillstream Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 127 | { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, |
117 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 128 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, |
118 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 129 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, |
119 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 130 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, |
120 | { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 131 | { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX }, |
121 | { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 132 | { 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX }, |
122 | { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 133 | { 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX }, |
123 | { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 134 | { 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX }, |
124 | { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 135 | { 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX }, |
125 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 136 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
126 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 137 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX }, |
127 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 138 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
128 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 139 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
129 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 140 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
130 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 141 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
131 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 142 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX }, |
132 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 143 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
133 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 144 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, |
134 | { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 145 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, |
135 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 146 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, |
136 | { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 147 | { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX }, |
137 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 148 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX }, |
138 | { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 149 | { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX }, |
139 | { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 150 | { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
140 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 151 | { 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
141 | { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 152 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX }, |
142 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 153 | { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, |
143 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 154 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, |
155 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX }, | ||
144 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 156 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
145 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 157 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 }, |
146 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 158 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
147 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 159 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, |
148 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 160 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, |
149 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | 161 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, |
150 | { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 162 | { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
151 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 163 | { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
152 | { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } | 164 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, |
165 | { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } | ||
153 | }; | 166 | }; |
154 | 167 | ||
155 | /* buttons shared with xbox and xbox360 */ | 168 | /* buttons shared with xbox and xbox360 */ |
156 | static const signed short xpad_common_btn[] = { | 169 | static const signed short xpad_common_btn[] = { |
157 | BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */ | 170 | BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */ |
158 | BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ | 171 | BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ |
159 | -1 /* terminating entry */ | 172 | -1 /* terminating entry */ |
160 | }; | 173 | }; |
161 | 174 | ||
@@ -165,13 +178,20 @@ static const signed short xpad_btn[] = { | |||
165 | -1 /* terminating entry */ | 178 | -1 /* terminating entry */ |
166 | }; | 179 | }; |
167 | 180 | ||
168 | /* only used if MAP_DPAD_TO_BUTTONS */ | 181 | /* used when dpad is mapped to buttons */ |
169 | static const signed short xpad_btn_pad[] = { | 182 | static const signed short xpad_btn_pad[] = { |
170 | BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ | 183 | BTN_TRIGGER_HAPPY1, BTN_TRIGGER_HAPPY2, /* d-pad left, right */ |
171 | BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ | 184 | BTN_TRIGGER_HAPPY3, BTN_TRIGGER_HAPPY4, /* d-pad up, down */ |
172 | -1 /* terminating entry */ | 185 | -1 /* terminating entry */ |
173 | }; | 186 | }; |
174 | 187 | ||
188 | /* used when triggers are mapped to buttons */ | ||
189 | static const signed short xpad_btn_triggers[] = { | ||
190 | BTN_TL2, BTN_TR2, /* triggers left/right */ | ||
191 | -1 | ||
192 | }; | ||
193 | |||
194 | |||
175 | static const signed short xpad360_btn[] = { /* buttons for x360 controller */ | 195 | static const signed short xpad360_btn[] = { /* buttons for x360 controller */ |
176 | BTN_TL, BTN_TR, /* Button LB/RB */ | 196 | BTN_TL, BTN_TR, /* Button LB/RB */ |
177 | BTN_MODE, /* The big X button */ | 197 | BTN_MODE, /* The big X button */ |
@@ -181,16 +201,21 @@ static const signed short xpad360_btn[] = { /* buttons for x360 controller */ | |||
181 | static const signed short xpad_abs[] = { | 201 | static const signed short xpad_abs[] = { |
182 | ABS_X, ABS_Y, /* left stick */ | 202 | ABS_X, ABS_Y, /* left stick */ |
183 | ABS_RX, ABS_RY, /* right stick */ | 203 | ABS_RX, ABS_RY, /* right stick */ |
184 | ABS_Z, ABS_RZ, /* triggers left/right */ | ||
185 | -1 /* terminating entry */ | 204 | -1 /* terminating entry */ |
186 | }; | 205 | }; |
187 | 206 | ||
188 | /* only used if MAP_DPAD_TO_AXES */ | 207 | /* used when dpad is mapped to axes */ |
189 | static const signed short xpad_abs_pad[] = { | 208 | static const signed short xpad_abs_pad[] = { |
190 | ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ | 209 | ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ |
191 | -1 /* terminating entry */ | 210 | -1 /* terminating entry */ |
192 | }; | 211 | }; |
193 | 212 | ||
213 | /* used when triggers are mapped to axes */ | ||
214 | static const signed short xpad_abs_triggers[] = { | ||
215 | ABS_Z, ABS_RZ, /* triggers left/right */ | ||
216 | -1 | ||
217 | }; | ||
218 | |||
194 | /* Xbox 360 has a vendor-specific class, so we cannot match it with only | 219 | /* Xbox 360 has a vendor-specific class, so we cannot match it with only |
195 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we | 220 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we |
196 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, | 221 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, |
@@ -246,7 +271,7 @@ struct usb_xpad { | |||
246 | 271 | ||
247 | char phys[64]; /* physical device path */ | 272 | char phys[64]; /* physical device path */ |
248 | 273 | ||
249 | int dpad_mapping; /* map d-pad to buttons or to axes */ | 274 | int mapping; /* map d-pad to buttons or to axes */ |
250 | int xtype; /* type of xbox device */ | 275 | int xtype; /* type of xbox device */ |
251 | }; | 276 | }; |
252 | 277 | ||
@@ -264,38 +289,46 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d | |||
264 | { | 289 | { |
265 | struct input_dev *dev = xpad->dev; | 290 | struct input_dev *dev = xpad->dev; |
266 | 291 | ||
267 | /* left stick */ | 292 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { |
268 | input_report_abs(dev, ABS_X, | 293 | /* left stick */ |
269 | (__s16) le16_to_cpup((__le16 *)(data + 12))); | 294 | input_report_abs(dev, ABS_X, |
270 | input_report_abs(dev, ABS_Y, | 295 | (__s16) le16_to_cpup((__le16 *)(data + 12))); |
271 | ~(__s16) le16_to_cpup((__le16 *)(data + 14))); | 296 | input_report_abs(dev, ABS_Y, |
272 | 297 | ~(__s16) le16_to_cpup((__le16 *)(data + 14))); | |
273 | /* right stick */ | 298 | |
274 | input_report_abs(dev, ABS_RX, | 299 | /* right stick */ |
275 | (__s16) le16_to_cpup((__le16 *)(data + 16))); | 300 | input_report_abs(dev, ABS_RX, |
276 | input_report_abs(dev, ABS_RY, | 301 | (__s16) le16_to_cpup((__le16 *)(data + 16))); |
277 | ~(__s16) le16_to_cpup((__le16 *)(data + 18))); | 302 | input_report_abs(dev, ABS_RY, |
303 | ~(__s16) le16_to_cpup((__le16 *)(data + 18))); | ||
304 | } | ||
278 | 305 | ||
279 | /* triggers left/right */ | 306 | /* triggers left/right */ |
280 | input_report_abs(dev, ABS_Z, data[10]); | 307 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { |
281 | input_report_abs(dev, ABS_RZ, data[11]); | 308 | input_report_key(dev, BTN_TL2, data[10]); |
309 | input_report_key(dev, BTN_TR2, data[11]); | ||
310 | } else { | ||
311 | input_report_abs(dev, ABS_Z, data[10]); | ||
312 | input_report_abs(dev, ABS_RZ, data[11]); | ||
313 | } | ||
282 | 314 | ||
283 | /* digital pad */ | 315 | /* digital pad */ |
284 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { | 316 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { |
317 | /* dpad as buttons (left, right, up, down) */ | ||
318 | input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04); | ||
319 | input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08); | ||
320 | input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01); | ||
321 | input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02); | ||
322 | } else { | ||
285 | input_report_abs(dev, ABS_HAT0X, | 323 | input_report_abs(dev, ABS_HAT0X, |
286 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | 324 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); |
287 | input_report_abs(dev, ABS_HAT0Y, | 325 | input_report_abs(dev, ABS_HAT0Y, |
288 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | 326 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); |
289 | } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { | ||
290 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); | ||
291 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); | ||
292 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ | ||
293 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ | ||
294 | } | 327 | } |
295 | 328 | ||
296 | /* start/back buttons and stick press left/right */ | 329 | /* start/back buttons and stick press left/right */ |
297 | input_report_key(dev, BTN_START, data[2] & 0x10); | 330 | input_report_key(dev, BTN_START, data[2] & 0x10); |
298 | input_report_key(dev, BTN_BACK, data[2] & 0x20); | 331 | input_report_key(dev, BTN_SELECT, data[2] & 0x20); |
299 | input_report_key(dev, BTN_THUMBL, data[2] & 0x40); | 332 | input_report_key(dev, BTN_THUMBL, data[2] & 0x40); |
300 | input_report_key(dev, BTN_THUMBR, data[2] & 0x80); | 333 | input_report_key(dev, BTN_THUMBR, data[2] & 0x80); |
301 | 334 | ||
@@ -328,22 +361,22 @@ static void xpad360_process_packet(struct usb_xpad *xpad, | |||
328 | struct input_dev *dev = xpad->dev; | 361 | struct input_dev *dev = xpad->dev; |
329 | 362 | ||
330 | /* digital pad */ | 363 | /* digital pad */ |
331 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { | 364 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { |
365 | /* dpad as buttons (left, right, up, down) */ | ||
366 | input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04); | ||
367 | input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08); | ||
368 | input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01); | ||
369 | input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02); | ||
370 | } else { | ||
332 | input_report_abs(dev, ABS_HAT0X, | 371 | input_report_abs(dev, ABS_HAT0X, |
333 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | 372 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); |
334 | input_report_abs(dev, ABS_HAT0Y, | 373 | input_report_abs(dev, ABS_HAT0Y, |
335 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | 374 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); |
336 | } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) { | ||
337 | /* dpad as buttons (right, left, down, up) */ | ||
338 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); | ||
339 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); | ||
340 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ | ||
341 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ | ||
342 | } | 375 | } |
343 | 376 | ||
344 | /* start/back buttons */ | 377 | /* start/back buttons */ |
345 | input_report_key(dev, BTN_START, data[2] & 0x10); | 378 | input_report_key(dev, BTN_START, data[2] & 0x10); |
346 | input_report_key(dev, BTN_BACK, data[2] & 0x20); | 379 | input_report_key(dev, BTN_SELECT, data[2] & 0x20); |
347 | 380 | ||
348 | /* stick press left/right */ | 381 | /* stick press left/right */ |
349 | input_report_key(dev, BTN_THUMBL, data[2] & 0x40); | 382 | input_report_key(dev, BTN_THUMBL, data[2] & 0x40); |
@@ -358,21 +391,28 @@ static void xpad360_process_packet(struct usb_xpad *xpad, | |||
358 | input_report_key(dev, BTN_TR, data[3] & 0x02); | 391 | input_report_key(dev, BTN_TR, data[3] & 0x02); |
359 | input_report_key(dev, BTN_MODE, data[3] & 0x04); | 392 | input_report_key(dev, BTN_MODE, data[3] & 0x04); |
360 | 393 | ||
361 | /* left stick */ | 394 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { |
362 | input_report_abs(dev, ABS_X, | 395 | /* left stick */ |
363 | (__s16) le16_to_cpup((__le16 *)(data + 6))); | 396 | input_report_abs(dev, ABS_X, |
364 | input_report_abs(dev, ABS_Y, | 397 | (__s16) le16_to_cpup((__le16 *)(data + 6))); |
365 | ~(__s16) le16_to_cpup((__le16 *)(data + 8))); | 398 | input_report_abs(dev, ABS_Y, |
366 | 399 | ~(__s16) le16_to_cpup((__le16 *)(data + 8))); | |
367 | /* right stick */ | 400 | |
368 | input_report_abs(dev, ABS_RX, | 401 | /* right stick */ |
369 | (__s16) le16_to_cpup((__le16 *)(data + 10))); | 402 | input_report_abs(dev, ABS_RX, |
370 | input_report_abs(dev, ABS_RY, | 403 | (__s16) le16_to_cpup((__le16 *)(data + 10))); |
371 | ~(__s16) le16_to_cpup((__le16 *)(data + 12))); | 404 | input_report_abs(dev, ABS_RY, |
405 | ~(__s16) le16_to_cpup((__le16 *)(data + 12))); | ||
406 | } | ||
372 | 407 | ||
373 | /* triggers left/right */ | 408 | /* triggers left/right */ |
374 | input_report_abs(dev, ABS_Z, data[4]); | 409 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { |
375 | input_report_abs(dev, ABS_RZ, data[5]); | 410 | input_report_key(dev, BTN_TL2, data[4]); |
411 | input_report_key(dev, BTN_TR2, data[5]); | ||
412 | } else { | ||
413 | input_report_abs(dev, ABS_Z, data[4]); | ||
414 | input_report_abs(dev, ABS_RZ, data[5]); | ||
415 | } | ||
376 | 416 | ||
377 | input_sync(dev); | 417 | input_sync(dev); |
378 | } | 418 | } |
@@ -505,11 +545,11 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
505 | struct usb_endpoint_descriptor *ep_irq_out; | 545 | struct usb_endpoint_descriptor *ep_irq_out; |
506 | int error = -ENOMEM; | 546 | int error = -ENOMEM; |
507 | 547 | ||
508 | if (xpad->xtype != XTYPE_XBOX360) | 548 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) |
509 | return 0; | 549 | return 0; |
510 | 550 | ||
511 | xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, | 551 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, |
512 | GFP_KERNEL, &xpad->odata_dma); | 552 | GFP_KERNEL, &xpad->odata_dma); |
513 | if (!xpad->odata) | 553 | if (!xpad->odata) |
514 | goto fail1; | 554 | goto fail1; |
515 | 555 | ||
@@ -529,21 +569,21 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
529 | 569 | ||
530 | return 0; | 570 | return 0; |
531 | 571 | ||
532 | fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); | 572 | fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); |
533 | fail1: return error; | 573 | fail1: return error; |
534 | } | 574 | } |
535 | 575 | ||
536 | static void xpad_stop_output(struct usb_xpad *xpad) | 576 | static void xpad_stop_output(struct usb_xpad *xpad) |
537 | { | 577 | { |
538 | if (xpad->xtype == XTYPE_XBOX360) | 578 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) |
539 | usb_kill_urb(xpad->irq_out); | 579 | usb_kill_urb(xpad->irq_out); |
540 | } | 580 | } |
541 | 581 | ||
542 | static void xpad_deinit_output(struct usb_xpad *xpad) | 582 | static void xpad_deinit_output(struct usb_xpad *xpad) |
543 | { | 583 | { |
544 | if (xpad->xtype == XTYPE_XBOX360) { | 584 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) { |
545 | usb_free_urb(xpad->irq_out); | 585 | usb_free_urb(xpad->irq_out); |
546 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, | 586 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, |
547 | xpad->odata, xpad->odata_dma); | 587 | xpad->odata, xpad->odata_dma); |
548 | } | 588 | } |
549 | } | 589 | } |
@@ -554,24 +594,45 @@ static void xpad_stop_output(struct usb_xpad *xpad) {} | |||
554 | #endif | 594 | #endif |
555 | 595 | ||
556 | #ifdef CONFIG_JOYSTICK_XPAD_FF | 596 | #ifdef CONFIG_JOYSTICK_XPAD_FF |
557 | static int xpad_play_effect(struct input_dev *dev, void *data, | 597 | static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) |
558 | struct ff_effect *effect) | ||
559 | { | 598 | { |
560 | struct usb_xpad *xpad = input_get_drvdata(dev); | 599 | struct usb_xpad *xpad = input_get_drvdata(dev); |
561 | 600 | ||
562 | if (effect->type == FF_RUMBLE) { | 601 | if (effect->type == FF_RUMBLE) { |
563 | __u16 strong = effect->u.rumble.strong_magnitude; | 602 | __u16 strong = effect->u.rumble.strong_magnitude; |
564 | __u16 weak = effect->u.rumble.weak_magnitude; | 603 | __u16 weak = effect->u.rumble.weak_magnitude; |
565 | xpad->odata[0] = 0x00; | 604 | |
566 | xpad->odata[1] = 0x08; | 605 | switch (xpad->xtype) { |
567 | xpad->odata[2] = 0x00; | 606 | |
568 | xpad->odata[3] = strong / 256; | 607 | case XTYPE_XBOX: |
569 | xpad->odata[4] = weak / 256; | 608 | xpad->odata[0] = 0x00; |
570 | xpad->odata[5] = 0x00; | 609 | xpad->odata[1] = 0x06; |
571 | xpad->odata[6] = 0x00; | 610 | xpad->odata[2] = 0x00; |
572 | xpad->odata[7] = 0x00; | 611 | xpad->odata[3] = strong / 256; /* left actuator */ |
573 | xpad->irq_out->transfer_buffer_length = 8; | 612 | xpad->odata[4] = 0x00; |
574 | usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | 613 | xpad->odata[5] = weak / 256; /* right actuator */ |
614 | xpad->irq_out->transfer_buffer_length = 6; | ||
615 | |||
616 | return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | ||
617 | |||
618 | case XTYPE_XBOX360: | ||
619 | xpad->odata[0] = 0x00; | ||
620 | xpad->odata[1] = 0x08; | ||
621 | xpad->odata[2] = 0x00; | ||
622 | xpad->odata[3] = strong / 256; /* left actuator? */ | ||
623 | xpad->odata[4] = weak / 256; /* right actuator? */ | ||
624 | xpad->odata[5] = 0x00; | ||
625 | xpad->odata[6] = 0x00; | ||
626 | xpad->odata[7] = 0x00; | ||
627 | xpad->irq_out->transfer_buffer_length = 8; | ||
628 | |||
629 | return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | ||
630 | |||
631 | default: | ||
632 | dbg("%s - rumble command sent to unsupported xpad type: %d", | ||
633 | __func__, xpad->xtype); | ||
634 | return -1; | ||
635 | } | ||
575 | } | 636 | } |
576 | 637 | ||
577 | return 0; | 638 | return 0; |
@@ -579,7 +640,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, | |||
579 | 640 | ||
580 | static int xpad_init_ff(struct usb_xpad *xpad) | 641 | static int xpad_init_ff(struct usb_xpad *xpad) |
581 | { | 642 | { |
582 | if (xpad->xtype != XTYPE_XBOX360) | 643 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) |
583 | return 0; | 644 | return 0; |
584 | 645 | ||
585 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); | 646 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); |
@@ -712,11 +773,11 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | |||
712 | input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); | 773 | input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); |
713 | break; | 774 | break; |
714 | case ABS_Z: | 775 | case ABS_Z: |
715 | case ABS_RZ: /* the triggers */ | 776 | case ABS_RZ: /* the triggers (if mapped to axes) */ |
716 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); | 777 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); |
717 | break; | 778 | break; |
718 | case ABS_HAT0X: | 779 | case ABS_HAT0X: |
719 | case ABS_HAT0Y: /* the d-pad (only if MAP_DPAD_TO_AXES) */ | 780 | case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ |
720 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0); | 781 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0); |
721 | break; | 782 | break; |
722 | } | 783 | } |
@@ -742,8 +803,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
742 | if (!xpad || !input_dev) | 803 | if (!xpad || !input_dev) |
743 | goto fail1; | 804 | goto fail1; |
744 | 805 | ||
745 | xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, | 806 | xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, |
746 | GFP_KERNEL, &xpad->idata_dma); | 807 | GFP_KERNEL, &xpad->idata_dma); |
747 | if (!xpad->idata) | 808 | if (!xpad->idata) |
748 | goto fail1; | 809 | goto fail1; |
749 | 810 | ||
@@ -752,10 +813,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
752 | goto fail2; | 813 | goto fail2; |
753 | 814 | ||
754 | xpad->udev = udev; | 815 | xpad->udev = udev; |
755 | xpad->dpad_mapping = xpad_device[i].dpad_mapping; | 816 | xpad->mapping = xpad_device[i].mapping; |
756 | xpad->xtype = xpad_device[i].xtype; | 817 | xpad->xtype = xpad_device[i].xtype; |
757 | if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) | 818 | |
758 | xpad->dpad_mapping = !dpad_to_buttons; | ||
759 | if (xpad->xtype == XTYPE_UNKNOWN) { | 819 | if (xpad->xtype == XTYPE_UNKNOWN) { |
760 | if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { | 820 | if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { |
761 | if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) | 821 | if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) |
@@ -764,7 +824,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
764 | xpad->xtype = XTYPE_XBOX360; | 824 | xpad->xtype = XTYPE_XBOX360; |
765 | } else | 825 | } else |
766 | xpad->xtype = XTYPE_XBOX; | 826 | xpad->xtype = XTYPE_XBOX; |
827 | |||
828 | if (dpad_to_buttons) | ||
829 | xpad->mapping |= MAP_DPAD_TO_BUTTONS; | ||
830 | if (triggers_to_buttons) | ||
831 | xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; | ||
832 | if (sticks_to_null) | ||
833 | xpad->mapping |= MAP_STICKS_TO_NULL; | ||
767 | } | 834 | } |
835 | |||
768 | xpad->dev = input_dev; | 836 | xpad->dev = input_dev; |
769 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); | 837 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); |
770 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); | 838 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); |
@@ -779,27 +847,43 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
779 | input_dev->open = xpad_open; | 847 | input_dev->open = xpad_open; |
780 | input_dev->close = xpad_close; | 848 | input_dev->close = xpad_close; |
781 | 849 | ||
782 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 850 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
851 | |||
852 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { | ||
853 | input_dev->evbit[0] |= BIT_MASK(EV_ABS); | ||
854 | /* set up axes */ | ||
855 | for (i = 0; xpad_abs[i] >= 0; i++) | ||
856 | xpad_set_up_abs(input_dev, xpad_abs[i]); | ||
857 | } | ||
783 | 858 | ||
784 | /* set up buttons */ | 859 | /* set up standard buttons */ |
785 | for (i = 0; xpad_common_btn[i] >= 0; i++) | 860 | for (i = 0; xpad_common_btn[i] >= 0; i++) |
786 | set_bit(xpad_common_btn[i], input_dev->keybit); | 861 | __set_bit(xpad_common_btn[i], input_dev->keybit); |
787 | if ((xpad->xtype == XTYPE_XBOX360) || (xpad->xtype == XTYPE_XBOX360W)) | 862 | |
863 | /* set up model-specific ones */ | ||
864 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { | ||
788 | for (i = 0; xpad360_btn[i] >= 0; i++) | 865 | for (i = 0; xpad360_btn[i] >= 0; i++) |
789 | set_bit(xpad360_btn[i], input_dev->keybit); | 866 | __set_bit(xpad360_btn[i], input_dev->keybit); |
790 | else | 867 | } else { |
791 | for (i = 0; xpad_btn[i] >= 0; i++) | 868 | for (i = 0; xpad_btn[i] >= 0; i++) |
792 | set_bit(xpad_btn[i], input_dev->keybit); | 869 | __set_bit(xpad_btn[i], input_dev->keybit); |
793 | if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) | 870 | } |
794 | for (i = 0; xpad_btn_pad[i] >= 0; i++) | ||
795 | set_bit(xpad_btn_pad[i], input_dev->keybit); | ||
796 | 871 | ||
797 | /* set up axes */ | 872 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { |
798 | for (i = 0; xpad_abs[i] >= 0; i++) | 873 | for (i = 0; xpad_btn_pad[i] >= 0; i++) |
799 | xpad_set_up_abs(input_dev, xpad_abs[i]); | 874 | __set_bit(xpad_btn_pad[i], input_dev->keybit); |
800 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) | 875 | } else { |
801 | for (i = 0; xpad_abs_pad[i] >= 0; i++) | 876 | for (i = 0; xpad_abs_pad[i] >= 0; i++) |
802 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); | 877 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); |
878 | } | ||
879 | |||
880 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { | ||
881 | for (i = 0; xpad_btn_triggers[i] >= 0; i++) | ||
882 | __set_bit(xpad_btn_triggers[i], input_dev->keybit); | ||
883 | } else { | ||
884 | for (i = 0; xpad_abs_triggers[i] >= 0; i++) | ||
885 | xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); | ||
886 | } | ||
803 | 887 | ||
804 | error = xpad_init_output(intf, xpad); | 888 | error = xpad_init_output(intf, xpad); |
805 | if (error) | 889 | if (error) |
@@ -879,7 +963,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
879 | fail5: usb_kill_urb(xpad->irq_in); | 963 | fail5: usb_kill_urb(xpad->irq_in); |
880 | fail4: usb_free_urb(xpad->irq_in); | 964 | fail4: usb_free_urb(xpad->irq_in); |
881 | fail3: xpad_deinit_output(xpad); | 965 | fail3: xpad_deinit_output(xpad); |
882 | fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | 966 | fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); |
883 | fail1: input_free_device(input_dev); | 967 | fail1: input_free_device(input_dev); |
884 | kfree(xpad); | 968 | kfree(xpad); |
885 | return error; | 969 | return error; |
@@ -901,7 +985,7 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
901 | usb_kill_urb(xpad->irq_in); | 985 | usb_kill_urb(xpad->irq_in); |
902 | } | 986 | } |
903 | usb_free_urb(xpad->irq_in); | 987 | usb_free_urb(xpad->irq_in); |
904 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, | 988 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, |
905 | xpad->idata, xpad->idata_dma); | 989 | xpad->idata, xpad->idata_dma); |
906 | kfree(xpad); | 990 | kfree(xpad); |
907 | } | 991 | } |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 02c836e11813..b8c51b9781db 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -35,10 +35,10 @@ config KEYBOARD_ADP5520 | |||
35 | be called adp5520-keys. | 35 | be called adp5520-keys. |
36 | 36 | ||
37 | config KEYBOARD_ADP5588 | 37 | config KEYBOARD_ADP5588 |
38 | tristate "ADP5588 I2C QWERTY Keypad and IO Expander" | 38 | tristate "ADP5588/87 I2C QWERTY Keypad and IO Expander" |
39 | depends on I2C | 39 | depends on I2C |
40 | help | 40 | help |
41 | Say Y here if you want to use a ADP5588 attached to your | 41 | Say Y here if you want to use a ADP5588/87 attached to your |
42 | system I2C bus. | 42 | system I2C bus. |
43 | 43 | ||
44 | To compile this driver as a module, choose M here: the | 44 | To compile this driver as a module, choose M here: the |
@@ -124,7 +124,7 @@ config KEYBOARD_ATKBD_RDI_KEYCODES | |||
124 | right-hand column will be interpreted as the key shown in the | 124 | right-hand column will be interpreted as the key shown in the |
125 | left-hand column. | 125 | left-hand column. |
126 | 126 | ||
127 | config QT2160 | 127 | config KEYBOARD_QT2160 |
128 | tristate "Atmel AT42QT2160 Touch Sensor Chip" | 128 | tristate "Atmel AT42QT2160 Touch Sensor Chip" |
129 | depends on I2C && EXPERIMENTAL | 129 | depends on I2C && EXPERIMENTAL |
130 | help | 130 | help |
@@ -143,17 +143,6 @@ config KEYBOARD_BFIN | |||
143 | To compile this driver as a module, choose M here: the | 143 | To compile this driver as a module, choose M here: the |
144 | module will be called bf54x-keys. | 144 | module will be called bf54x-keys. |
145 | 145 | ||
146 | config KEYBOARD_CORGI | ||
147 | tristate "Corgi keyboard" | ||
148 | depends on PXA_SHARPSL | ||
149 | default y | ||
150 | help | ||
151 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx | ||
152 | series of PDAs. | ||
153 | |||
154 | To compile this driver as a module, choose M here: the | ||
155 | module will be called corgikbd. | ||
156 | |||
157 | config KEYBOARD_LKKBD | 146 | config KEYBOARD_LKKBD |
158 | tristate "DECstation/VAXstation LK201/LK401 keyboard" | 147 | tristate "DECstation/VAXstation LK201/LK401 keyboard" |
159 | select SERIO | 148 | select SERIO |
@@ -190,6 +179,22 @@ config KEYBOARD_GPIO | |||
190 | To compile this driver as a module, choose M here: the | 179 | To compile this driver as a module, choose M here: the |
191 | module will be called gpio_keys. | 180 | module will be called gpio_keys. |
192 | 181 | ||
182 | config KEYBOARD_TCA6416 | ||
183 | tristate "TCA6416 Keypad Support" | ||
184 | depends on I2C | ||
185 | help | ||
186 | This driver implements basic keypad functionality | ||
187 | for keys connected through TCA6416 IO expander | ||
188 | |||
189 | Say Y here if your device has keys connected to | ||
190 | TCA6416 IO expander. Your board-specific setup logic | ||
191 | must also provide pin-mask details(of which TCA6416 pins | ||
192 | are used for keypad). | ||
193 | |||
194 | If enabled the complete TCA6416 device will be managed through | ||
195 | this driver. | ||
196 | |||
197 | |||
193 | config KEYBOARD_MATRIX | 198 | config KEYBOARD_MATRIX |
194 | tristate "GPIO driven matrix keypad support" | 199 | tristate "GPIO driven matrix keypad support" |
195 | depends on GENERIC_GPIO | 200 | depends on GENERIC_GPIO |
@@ -292,6 +297,27 @@ config KEYBOARD_MAX7359 | |||
292 | To compile this driver as a module, choose M here: the | 297 | To compile this driver as a module, choose M here: the |
293 | module will be called max7359_keypad. | 298 | module will be called max7359_keypad. |
294 | 299 | ||
300 | config KEYBOARD_MCS | ||
301 | tristate "MELFAS MCS Touchkey" | ||
302 | depends on I2C | ||
303 | help | ||
304 | Say Y here if you have the MELFAS MCS5000/5080 touchkey controller | ||
305 | chip in your system. | ||
306 | |||
307 | If unsure, say N. | ||
308 | |||
309 | To compile this driver as a module, choose M here: the | ||
310 | module will be called mcs_touchkey. | ||
311 | |||
312 | config KEYBOARD_IMX | ||
313 | tristate "IMX keypad support" | ||
314 | depends on ARCH_MXC | ||
315 | help | ||
316 | Enable support for IMX keypad port. | ||
317 | |||
318 | To compile this driver as a module, choose M here: the | ||
319 | module will be called imx_keypad. | ||
320 | |||
295 | config KEYBOARD_NEWTON | 321 | config KEYBOARD_NEWTON |
296 | tristate "Newton keyboard" | 322 | tristate "Newton keyboard" |
297 | select SERIO | 323 | select SERIO |
@@ -301,6 +327,16 @@ config KEYBOARD_NEWTON | |||
301 | To compile this driver as a module, choose M here: the | 327 | To compile this driver as a module, choose M here: the |
302 | module will be called newtonkbd. | 328 | module will be called newtonkbd. |
303 | 329 | ||
330 | config KEYBOARD_NOMADIK | ||
331 | tristate "ST-Ericsson Nomadik SKE keyboard" | ||
332 | depends on PLAT_NOMADIK | ||
333 | help | ||
334 | Say Y here if you want to use a keypad provided on the SKE controller | ||
335 | used on the Ux500 and Nomadik platforms | ||
336 | |||
337 | To compile this driver as a module, choose M here: the | ||
338 | module will be called nmk-ske-keypad. | ||
339 | |||
304 | config KEYBOARD_OPENCORES | 340 | config KEYBOARD_OPENCORES |
305 | tristate "OpenCores Keyboard Controller" | 341 | tristate "OpenCores Keyboard Controller" |
306 | help | 342 | help |
@@ -312,7 +348,7 @@ config KEYBOARD_OPENCORES | |||
312 | 348 | ||
313 | config KEYBOARD_PXA27x | 349 | config KEYBOARD_PXA27x |
314 | tristate "PXA27x/PXA3xx keypad support" | 350 | tristate "PXA27x/PXA3xx keypad support" |
315 | depends on PXA27x || PXA3xx | 351 | depends on PXA27x || PXA3xx || ARCH_MMP |
316 | help | 352 | help |
317 | Enable support for PXA27x/PXA3xx keypad controller. | 353 | Enable support for PXA27x/PXA3xx keypad controller. |
318 | 354 | ||
@@ -328,16 +364,14 @@ config KEYBOARD_PXA930_ROTARY | |||
328 | To compile this driver as a module, choose M here: the | 364 | To compile this driver as a module, choose M here: the |
329 | module will be called pxa930_rotary. | 365 | module will be called pxa930_rotary. |
330 | 366 | ||
331 | config KEYBOARD_SPITZ | 367 | config KEYBOARD_SAMSUNG |
332 | tristate "Spitz keyboard" | 368 | tristate "Samsung keypad support" |
333 | depends on PXA_SHARPSL | 369 | depends on SAMSUNG_DEV_KEYPAD |
334 | default y | ||
335 | help | 370 | help |
336 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, | 371 | Say Y here if you want to use the Samsung keypad. |
337 | SL-C3000 and Sl-C3100 series of PDAs. | ||
338 | 372 | ||
339 | To compile this driver as a module, choose M here: the | 373 | To compile this driver as a module, choose M here: the |
340 | module will be called spitzkbd. | 374 | module will be called samsung-keypad. |
341 | 375 | ||
342 | config KEYBOARD_STOWAWAY | 376 | config KEYBOARD_STOWAWAY |
343 | tristate "Stowaway keyboard" | 377 | tristate "Stowaway keyboard" |
@@ -363,7 +397,7 @@ config KEYBOARD_SUNKBD | |||
363 | 397 | ||
364 | config KEYBOARD_SH_KEYSC | 398 | config KEYBOARD_SH_KEYSC |
365 | tristate "SuperH KEYSC keypad support" | 399 | tristate "SuperH KEYSC keypad support" |
366 | depends on SUPERH | 400 | depends on SUPERH || ARCH_SHMOBILE |
367 | help | 401 | help |
368 | Say Y here if you want to use a keypad attached to the KEYSC block | 402 | Say Y here if you want to use a keypad attached to the KEYSC block |
369 | on SuperH processors such as sh7722 and sh7343. | 403 | on SuperH processors such as sh7722 and sh7343. |
@@ -371,6 +405,16 @@ config KEYBOARD_SH_KEYSC | |||
371 | To compile this driver as a module, choose M here: the | 405 | To compile this driver as a module, choose M here: the |
372 | module will be called sh_keysc. | 406 | module will be called sh_keysc. |
373 | 407 | ||
408 | config KEYBOARD_STMPE | ||
409 | tristate "STMPE keypad support" | ||
410 | depends on MFD_STMPE | ||
411 | help | ||
412 | Say Y here if you want to use the keypad controller on STMPE I/O | ||
413 | expanders. | ||
414 | |||
415 | To compile this driver as a module, choose M here: the module will be | ||
416 | called stmpe-keypad. | ||
417 | |||
374 | config KEYBOARD_DAVINCI | 418 | config KEYBOARD_DAVINCI |
375 | tristate "TI DaVinci Key Scan" | 419 | tristate "TI DaVinci Key Scan" |
376 | depends on ARCH_DAVINCI_DM365 | 420 | depends on ARCH_DAVINCI_DM365 |
@@ -390,36 +434,34 @@ config KEYBOARD_OMAP | |||
390 | To compile this driver as a module, choose M here: the | 434 | To compile this driver as a module, choose M here: the |
391 | module will be called omap-keypad. | 435 | module will be called omap-keypad. |
392 | 436 | ||
393 | config KEYBOARD_TWL4030 | 437 | config KEYBOARD_OMAP4 |
394 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" | 438 | tristate "TI OMAP4 keypad support" |
395 | depends on TWL4030_CORE | 439 | depends on ARCH_OMAP4 |
396 | help | 440 | help |
397 | Say Y here if your board use the keypad controller on | 441 | Say Y here if you want to use the OMAP4 keypad. |
398 | TWL4030 family chips. It's safe to say enable this | ||
399 | even on boards that don't use the keypad controller. | ||
400 | 442 | ||
401 | To compile this driver as a module, choose M here: the | 443 | To compile this driver as a module, choose M here: the |
402 | module will be called twl4030_keypad. | 444 | module will be called omap4-keypad. |
403 | 445 | ||
404 | config KEYBOARD_TOSA | 446 | config KEYBOARD_TNETV107X |
405 | tristate "Tosa keyboard" | 447 | tristate "TI TNETV107X keypad support" |
406 | depends on MACH_TOSA | 448 | depends on ARCH_DAVINCI_TNETV107X |
407 | default y | ||
408 | help | 449 | help |
409 | Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) | 450 | Say Y here if you want to use the TNETV107X keypad. |
410 | 451 | ||
411 | To compile this driver as a module, choose M here: the | 452 | To compile this driver as a module, choose M here: the |
412 | module will be called tosakbd. | 453 | module will be called tnetv107x-keypad. |
413 | 454 | ||
414 | config KEYBOARD_TOSA_USE_EXT_KEYCODES | 455 | config KEYBOARD_TWL4030 |
415 | bool "Tosa keyboard: use extended keycodes" | 456 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" |
416 | depends on KEYBOARD_TOSA | 457 | depends on TWL4030_CORE |
417 | help | 458 | help |
418 | Say Y here to enable the tosa keyboard driver to generate extended | 459 | Say Y here if your board use the keypad controller on |
419 | (>= 127) keycodes. Be aware, that they can't be correctly interpreted | 460 | TWL4030 family chips. It's safe to say enable this |
420 | by either console keyboard driver or by Kdrive keybd driver. | 461 | even on boards that don't use the keypad controller. |
421 | 462 | ||
422 | Say Y only if you know, what you are doing! | 463 | To compile this driver as a module, choose M here: the |
464 | module will be called twl4030_keypad. | ||
423 | 465 | ||
424 | config KEYBOARD_XTKBD | 466 | config KEYBOARD_XTKBD |
425 | tristate "XT keyboard" | 467 | tristate "XT keyboard" |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 78654ef65206..a34452e8ebe2 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -11,12 +11,13 @@ obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | |||
11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | 11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o |
12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
14 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o | ||
15 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | 14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o |
16 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
17 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
17 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o | ||
18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
20 | obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o | ||
20 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | 21 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o |
21 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | 22 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o |
22 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o | 23 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o |
@@ -25,17 +26,21 @@ obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o | |||
25 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | 26 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o |
26 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o | 27 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o |
27 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o | 28 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o |
29 | obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o | ||
28 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o | 30 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o |
31 | obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o | ||
29 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o | 32 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o |
33 | obj-$(CONFIG_KEYBOARD_OMAP4) += omap4-keypad.o | ||
30 | obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o | 34 | obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o |
31 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o | 35 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o |
32 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o | 36 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o |
33 | obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o | 37 | obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o |
38 | obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o | ||
34 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | 39 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o |
35 | obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o | 40 | obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o |
36 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | 41 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o |
37 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | 42 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o |
38 | obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o | 43 | obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o |
39 | obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o | 44 | obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o |
40 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o | 45 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o |
41 | obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o | 46 | obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o |
diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c index a7ba27fb4109..3db8006dac3a 100644 --- a/drivers/input/keyboard/adp5520-keys.c +++ b/drivers/input/keyboard/adp5520-keys.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/input.h> | 13 | #include <linux/input.h> |
14 | #include <linux/mfd/adp5520.h> | 14 | #include <linux/mfd/adp5520.h> |
15 | #include <linux/slab.h> | ||
15 | 16 | ||
16 | struct adp5520_keys { | 17 | struct adp5520_keys { |
17 | struct input_dev *input; | 18 | struct input_dev *input; |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 1edb596d927b..b92d1cd5cba1 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File: drivers/input/keyboard/adp5588_keys.c | 2 | * File: drivers/input/keyboard/adp5588_keys.c |
3 | * Description: keypad driver for ADP5588 I2C QWERTY Keypad and IO Expander | 3 | * Description: keypad driver for ADP5588 and ADP5587 |
4 | * I2C QWERTY Keypad and IO Expander | ||
4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 5 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
5 | * | 6 | * |
6 | * Copyright (C) 2008-2009 Analog Devices Inc. | 7 | * Copyright (C) 2008-2009 Analog Devices Inc. |
@@ -18,6 +19,8 @@ | |||
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/input.h> | 20 | #include <linux/input.h> |
20 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/gpio.h> | ||
23 | #include <linux/slab.h> | ||
21 | 24 | ||
22 | #include <linux/i2c/adp5588.h> | 25 | #include <linux/i2c/adp5588.h> |
23 | 26 | ||
@@ -52,6 +55,10 @@ | |||
52 | 55 | ||
53 | #define KEYP_MAX_EVENT 10 | 56 | #define KEYP_MAX_EVENT 10 |
54 | 57 | ||
58 | #define MAXGPIO 18 | ||
59 | #define ADP_BANK(offs) ((offs) >> 3) | ||
60 | #define ADP_BIT(offs) (1u << ((offs) & 0x7)) | ||
61 | |||
55 | /* | 62 | /* |
56 | * Early pre 4.0 Silicon required to delay readout by at least 25ms, | 63 | * Early pre 4.0 Silicon required to delay readout by at least 25ms, |
57 | * since the Event Counter Register updated 25ms after the interrupt | 64 | * since the Event Counter Register updated 25ms after the interrupt |
@@ -65,6 +72,16 @@ struct adp5588_kpad { | |||
65 | struct delayed_work work; | 72 | struct delayed_work work; |
66 | unsigned long delay; | 73 | unsigned long delay; |
67 | unsigned short keycode[ADP5588_KEYMAPSIZE]; | 74 | unsigned short keycode[ADP5588_KEYMAPSIZE]; |
75 | const struct adp5588_gpi_map *gpimap; | ||
76 | unsigned short gpimapsize; | ||
77 | #ifdef CONFIG_GPIOLIB | ||
78 | unsigned char gpiomap[MAXGPIO]; | ||
79 | bool export_gpio; | ||
80 | struct gpio_chip gc; | ||
81 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ | ||
82 | u8 dat_out[3]; | ||
83 | u8 dir[3]; | ||
84 | #endif | ||
68 | }; | 85 | }; |
69 | 86 | ||
70 | static int adp5588_read(struct i2c_client *client, u8 reg) | 87 | static int adp5588_read(struct i2c_client *client, u8 reg) |
@@ -82,12 +99,222 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) | |||
82 | return i2c_smbus_write_byte_data(client, reg, val); | 99 | return i2c_smbus_write_byte_data(client, reg, val); |
83 | } | 100 | } |
84 | 101 | ||
102 | #ifdef CONFIG_GPIOLIB | ||
103 | static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) | ||
104 | { | ||
105 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | ||
106 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | ||
107 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | ||
108 | |||
109 | return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); | ||
110 | } | ||
111 | |||
112 | static void adp5588_gpio_set_value(struct gpio_chip *chip, | ||
113 | unsigned off, int val) | ||
114 | { | ||
115 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | ||
116 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | ||
117 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | ||
118 | |||
119 | mutex_lock(&kpad->gpio_lock); | ||
120 | |||
121 | if (val) | ||
122 | kpad->dat_out[bank] |= bit; | ||
123 | else | ||
124 | kpad->dat_out[bank] &= ~bit; | ||
125 | |||
126 | adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, | ||
127 | kpad->dat_out[bank]); | ||
128 | |||
129 | mutex_unlock(&kpad->gpio_lock); | ||
130 | } | ||
131 | |||
132 | static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) | ||
133 | { | ||
134 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | ||
135 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | ||
136 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | ||
137 | int ret; | ||
138 | |||
139 | mutex_lock(&kpad->gpio_lock); | ||
140 | |||
141 | kpad->dir[bank] &= ~bit; | ||
142 | ret = adp5588_write(kpad->client, GPIO_DIR1 + bank, kpad->dir[bank]); | ||
143 | |||
144 | mutex_unlock(&kpad->gpio_lock); | ||
145 | |||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | static int adp5588_gpio_direction_output(struct gpio_chip *chip, | ||
150 | unsigned off, int val) | ||
151 | { | ||
152 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | ||
153 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | ||
154 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | ||
155 | int ret; | ||
156 | |||
157 | mutex_lock(&kpad->gpio_lock); | ||
158 | |||
159 | kpad->dir[bank] |= bit; | ||
160 | |||
161 | if (val) | ||
162 | kpad->dat_out[bank] |= bit; | ||
163 | else | ||
164 | kpad->dat_out[bank] &= ~bit; | ||
165 | |||
166 | ret = adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, | ||
167 | kpad->dat_out[bank]); | ||
168 | ret |= adp5588_write(kpad->client, GPIO_DIR1 + bank, | ||
169 | kpad->dir[bank]); | ||
170 | |||
171 | mutex_unlock(&kpad->gpio_lock); | ||
172 | |||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, | ||
177 | const struct adp5588_kpad_platform_data *pdata) | ||
178 | { | ||
179 | bool pin_used[MAXGPIO]; | ||
180 | int n_unused = 0; | ||
181 | int i; | ||
182 | |||
183 | memset(pin_used, 0, sizeof(pin_used)); | ||
184 | |||
185 | for (i = 0; i < pdata->rows; i++) | ||
186 | pin_used[i] = true; | ||
187 | |||
188 | for (i = 0; i < pdata->cols; i++) | ||
189 | pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true; | ||
190 | |||
191 | for (i = 0; i < kpad->gpimapsize; i++) | ||
192 | pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; | ||
193 | |||
194 | for (i = 0; i < MAXGPIO; i++) | ||
195 | if (!pin_used[i]) | ||
196 | kpad->gpiomap[n_unused++] = i; | ||
197 | |||
198 | return n_unused; | ||
199 | } | ||
200 | |||
201 | static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad) | ||
202 | { | ||
203 | struct device *dev = &kpad->client->dev; | ||
204 | const struct adp5588_kpad_platform_data *pdata = dev->platform_data; | ||
205 | const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; | ||
206 | int i, error; | ||
207 | |||
208 | if (!gpio_data) | ||
209 | return 0; | ||
210 | |||
211 | kpad->gc.ngpio = adp5588_build_gpiomap(kpad, pdata); | ||
212 | if (kpad->gc.ngpio == 0) { | ||
213 | dev_info(dev, "No unused gpios left to export\n"); | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | kpad->export_gpio = true; | ||
218 | |||
219 | kpad->gc.direction_input = adp5588_gpio_direction_input; | ||
220 | kpad->gc.direction_output = adp5588_gpio_direction_output; | ||
221 | kpad->gc.get = adp5588_gpio_get_value; | ||
222 | kpad->gc.set = adp5588_gpio_set_value; | ||
223 | kpad->gc.can_sleep = 1; | ||
224 | |||
225 | kpad->gc.base = gpio_data->gpio_start; | ||
226 | kpad->gc.label = kpad->client->name; | ||
227 | kpad->gc.owner = THIS_MODULE; | ||
228 | |||
229 | mutex_init(&kpad->gpio_lock); | ||
230 | |||
231 | error = gpiochip_add(&kpad->gc); | ||
232 | if (error) { | ||
233 | dev_err(dev, "gpiochip_add failed, err: %d\n", error); | ||
234 | return error; | ||
235 | } | ||
236 | |||
237 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { | ||
238 | kpad->dat_out[i] = adp5588_read(kpad->client, | ||
239 | GPIO_DAT_OUT1 + i); | ||
240 | kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i); | ||
241 | } | ||
242 | |||
243 | if (gpio_data->setup) { | ||
244 | error = gpio_data->setup(kpad->client, | ||
245 | kpad->gc.base, kpad->gc.ngpio, | ||
246 | gpio_data->context); | ||
247 | if (error) | ||
248 | dev_warn(dev, "setup failed, %d\n", error); | ||
249 | } | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static void __devexit adp5588_gpio_remove(struct adp5588_kpad *kpad) | ||
255 | { | ||
256 | struct device *dev = &kpad->client->dev; | ||
257 | const struct adp5588_kpad_platform_data *pdata = dev->platform_data; | ||
258 | const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; | ||
259 | int error; | ||
260 | |||
261 | if (!kpad->export_gpio) | ||
262 | return; | ||
263 | |||
264 | if (gpio_data->teardown) { | ||
265 | error = gpio_data->teardown(kpad->client, | ||
266 | kpad->gc.base, kpad->gc.ngpio, | ||
267 | gpio_data->context); | ||
268 | if (error) | ||
269 | dev_warn(dev, "teardown failed %d\n", error); | ||
270 | } | ||
271 | |||
272 | error = gpiochip_remove(&kpad->gc); | ||
273 | if (error) | ||
274 | dev_warn(dev, "gpiochip_remove failed %d\n", error); | ||
275 | } | ||
276 | #else | ||
277 | static inline int adp5588_gpio_add(struct adp5588_kpad *kpad) | ||
278 | { | ||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | static inline void adp5588_gpio_remove(struct adp5588_kpad *kpad) | ||
283 | { | ||
284 | } | ||
285 | #endif | ||
286 | |||
287 | static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt) | ||
288 | { | ||
289 | int i, j; | ||
290 | |||
291 | for (i = 0; i < ev_cnt; i++) { | ||
292 | int key = adp5588_read(kpad->client, Key_EVENTA + i); | ||
293 | int key_val = key & KEY_EV_MASK; | ||
294 | |||
295 | if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) { | ||
296 | for (j = 0; j < kpad->gpimapsize; j++) { | ||
297 | if (key_val == kpad->gpimap[j].pin) { | ||
298 | input_report_switch(kpad->input, | ||
299 | kpad->gpimap[j].sw_evt, | ||
300 | key & KEY_EV_PRESSED); | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | } else { | ||
305 | input_report_key(kpad->input, | ||
306 | kpad->keycode[key_val - 1], | ||
307 | key & KEY_EV_PRESSED); | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | |||
85 | static void adp5588_work(struct work_struct *work) | 312 | static void adp5588_work(struct work_struct *work) |
86 | { | 313 | { |
87 | struct adp5588_kpad *kpad = container_of(work, | 314 | struct adp5588_kpad *kpad = container_of(work, |
88 | struct adp5588_kpad, work.work); | 315 | struct adp5588_kpad, work.work); |
89 | struct i2c_client *client = kpad->client; | 316 | struct i2c_client *client = kpad->client; |
90 | int i, key, status, ev_cnt; | 317 | int status, ev_cnt; |
91 | 318 | ||
92 | status = adp5588_read(client, INT_STAT); | 319 | status = adp5588_read(client, INT_STAT); |
93 | 320 | ||
@@ -97,12 +324,7 @@ static void adp5588_work(struct work_struct *work) | |||
97 | if (status & KE_INT) { | 324 | if (status & KE_INT) { |
98 | ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC; | 325 | ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC; |
99 | if (ev_cnt) { | 326 | if (ev_cnt) { |
100 | for (i = 0; i < ev_cnt; i++) { | 327 | adp5588_report_events(kpad, ev_cnt); |
101 | key = adp5588_read(client, Key_EVENTA + i); | ||
102 | input_report_key(kpad->input, | ||
103 | kpad->keycode[(key & KEY_EV_MASK) - 1], | ||
104 | key & KEY_EV_PRESSED); | ||
105 | } | ||
106 | input_sync(kpad->input); | 328 | input_sync(kpad->input); |
107 | } | 329 | } |
108 | } | 330 | } |
@@ -126,8 +348,10 @@ static irqreturn_t adp5588_irq(int irq, void *handle) | |||
126 | 348 | ||
127 | static int __devinit adp5588_setup(struct i2c_client *client) | 349 | static int __devinit adp5588_setup(struct i2c_client *client) |
128 | { | 350 | { |
129 | struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; | 351 | const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; |
352 | const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; | ||
130 | int i, ret; | 353 | int i, ret; |
354 | unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; | ||
131 | 355 | ||
132 | ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows)); | 356 | ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows)); |
133 | ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); | 357 | ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); |
@@ -142,6 +366,32 @@ static int __devinit adp5588_setup(struct i2c_client *client) | |||
142 | for (i = 0; i < KEYP_MAX_EVENT; i++) | 366 | for (i = 0; i < KEYP_MAX_EVENT; i++) |
143 | ret |= adp5588_read(client, Key_EVENTA); | 367 | ret |= adp5588_read(client, Key_EVENTA); |
144 | 368 | ||
369 | for (i = 0; i < pdata->gpimapsize; i++) { | ||
370 | unsigned short pin = pdata->gpimap[i].pin; | ||
371 | |||
372 | if (pin <= GPI_PIN_ROW_END) { | ||
373 | evt_mode1 |= (1 << (pin - GPI_PIN_ROW_BASE)); | ||
374 | } else { | ||
375 | evt_mode2 |= ((1 << (pin - GPI_PIN_COL_BASE)) & 0xFF); | ||
376 | evt_mode3 |= ((1 << (pin - GPI_PIN_COL_BASE)) >> 8); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | if (pdata->gpimapsize) { | ||
381 | ret |= adp5588_write(client, GPI_EM1, evt_mode1); | ||
382 | ret |= adp5588_write(client, GPI_EM2, evt_mode2); | ||
383 | ret |= adp5588_write(client, GPI_EM3, evt_mode3); | ||
384 | } | ||
385 | |||
386 | if (gpio_data) { | ||
387 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { | ||
388 | int pull_mask = gpio_data->pullup_dis_mask; | ||
389 | |||
390 | ret |= adp5588_write(client, GPIO_PULL1 + i, | ||
391 | (pull_mask >> (8 * i)) & 0xFF); | ||
392 | } | ||
393 | } | ||
394 | |||
145 | ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | | 395 | ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | |
146 | OVR_FLOW_INT | K_LCK_INT | | 396 | OVR_FLOW_INT | K_LCK_INT | |
147 | GPI_INT | KE_INT); /* Status is W1C */ | 397 | GPI_INT | KE_INT); /* Status is W1C */ |
@@ -156,11 +406,49 @@ static int __devinit adp5588_setup(struct i2c_client *client) | |||
156 | return 0; | 406 | return 0; |
157 | } | 407 | } |
158 | 408 | ||
409 | static void __devinit adp5588_report_switch_state(struct adp5588_kpad *kpad) | ||
410 | { | ||
411 | int gpi_stat1 = adp5588_read(kpad->client, GPIO_DAT_STAT1); | ||
412 | int gpi_stat2 = adp5588_read(kpad->client, GPIO_DAT_STAT2); | ||
413 | int gpi_stat3 = adp5588_read(kpad->client, GPIO_DAT_STAT3); | ||
414 | int gpi_stat_tmp, pin_loc; | ||
415 | int i; | ||
416 | |||
417 | for (i = 0; i < kpad->gpimapsize; i++) { | ||
418 | unsigned short pin = kpad->gpimap[i].pin; | ||
419 | |||
420 | if (pin <= GPI_PIN_ROW_END) { | ||
421 | gpi_stat_tmp = gpi_stat1; | ||
422 | pin_loc = pin - GPI_PIN_ROW_BASE; | ||
423 | } else if ((pin - GPI_PIN_COL_BASE) < 8) { | ||
424 | gpi_stat_tmp = gpi_stat2; | ||
425 | pin_loc = pin - GPI_PIN_COL_BASE; | ||
426 | } else { | ||
427 | gpi_stat_tmp = gpi_stat3; | ||
428 | pin_loc = pin - GPI_PIN_COL_BASE - 8; | ||
429 | } | ||
430 | |||
431 | if (gpi_stat_tmp < 0) { | ||
432 | dev_err(&kpad->client->dev, | ||
433 | "Can't read GPIO_DAT_STAT switch %d default to OFF\n", | ||
434 | pin); | ||
435 | gpi_stat_tmp = 0; | ||
436 | } | ||
437 | |||
438 | input_report_switch(kpad->input, | ||
439 | kpad->gpimap[i].sw_evt, | ||
440 | !(gpi_stat_tmp & (1 << pin_loc))); | ||
441 | } | ||
442 | |||
443 | input_sync(kpad->input); | ||
444 | } | ||
445 | |||
446 | |||
159 | static int __devinit adp5588_probe(struct i2c_client *client, | 447 | static int __devinit adp5588_probe(struct i2c_client *client, |
160 | const struct i2c_device_id *id) | 448 | const struct i2c_device_id *id) |
161 | { | 449 | { |
162 | struct adp5588_kpad *kpad; | 450 | struct adp5588_kpad *kpad; |
163 | struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; | 451 | const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; |
164 | struct input_dev *input; | 452 | struct input_dev *input; |
165 | unsigned int revid; | 453 | unsigned int revid; |
166 | int ret, i; | 454 | int ret, i; |
@@ -187,6 +475,37 @@ static int __devinit adp5588_probe(struct i2c_client *client, | |||
187 | return -EINVAL; | 475 | return -EINVAL; |
188 | } | 476 | } |
189 | 477 | ||
478 | if (!pdata->gpimap && pdata->gpimapsize) { | ||
479 | dev_err(&client->dev, "invalid gpimap from pdata\n"); | ||
480 | return -EINVAL; | ||
481 | } | ||
482 | |||
483 | if (pdata->gpimapsize > ADP5588_GPIMAPSIZE_MAX) { | ||
484 | dev_err(&client->dev, "invalid gpimapsize\n"); | ||
485 | return -EINVAL; | ||
486 | } | ||
487 | |||
488 | for (i = 0; i < pdata->gpimapsize; i++) { | ||
489 | unsigned short pin = pdata->gpimap[i].pin; | ||
490 | |||
491 | if (pin < GPI_PIN_BASE || pin > GPI_PIN_END) { | ||
492 | dev_err(&client->dev, "invalid gpi pin data\n"); | ||
493 | return -EINVAL; | ||
494 | } | ||
495 | |||
496 | if (pin <= GPI_PIN_ROW_END) { | ||
497 | if (pin - GPI_PIN_ROW_BASE + 1 <= pdata->rows) { | ||
498 | dev_err(&client->dev, "invalid gpi row data\n"); | ||
499 | return -EINVAL; | ||
500 | } | ||
501 | } else { | ||
502 | if (pin - GPI_PIN_COL_BASE + 1 <= pdata->cols) { | ||
503 | dev_err(&client->dev, "invalid gpi col data\n"); | ||
504 | return -EINVAL; | ||
505 | } | ||
506 | } | ||
507 | } | ||
508 | |||
190 | if (!client->irq) { | 509 | if (!client->irq) { |
191 | dev_err(&client->dev, "no IRQ?\n"); | 510 | dev_err(&client->dev, "no IRQ?\n"); |
192 | return -EINVAL; | 511 | return -EINVAL; |
@@ -231,6 +550,9 @@ static int __devinit adp5588_probe(struct i2c_client *client, | |||
231 | memcpy(kpad->keycode, pdata->keymap, | 550 | memcpy(kpad->keycode, pdata->keymap, |
232 | pdata->keymapsize * input->keycodesize); | 551 | pdata->keymapsize * input->keycodesize); |
233 | 552 | ||
553 | kpad->gpimap = pdata->gpimap; | ||
554 | kpad->gpimapsize = pdata->gpimapsize; | ||
555 | |||
234 | /* setup input device */ | 556 | /* setup input device */ |
235 | __set_bit(EV_KEY, input->evbit); | 557 | __set_bit(EV_KEY, input->evbit); |
236 | 558 | ||
@@ -241,6 +563,11 @@ static int __devinit adp5588_probe(struct i2c_client *client, | |||
241 | __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit); | 563 | __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit); |
242 | __clear_bit(KEY_RESERVED, input->keybit); | 564 | __clear_bit(KEY_RESERVED, input->keybit); |
243 | 565 | ||
566 | if (kpad->gpimapsize) | ||
567 | __set_bit(EV_SW, input->evbit); | ||
568 | for (i = 0; i < kpad->gpimapsize; i++) | ||
569 | __set_bit(kpad->gpimap[i].sw_evt, input->swbit); | ||
570 | |||
244 | error = input_register_device(input); | 571 | error = input_register_device(input); |
245 | if (error) { | 572 | if (error) { |
246 | dev_err(&client->dev, "unable to register input device\n"); | 573 | dev_err(&client->dev, "unable to register input device\n"); |
@@ -259,6 +586,13 @@ static int __devinit adp5588_probe(struct i2c_client *client, | |||
259 | if (error) | 586 | if (error) |
260 | goto err_free_irq; | 587 | goto err_free_irq; |
261 | 588 | ||
589 | if (kpad->gpimapsize) | ||
590 | adp5588_report_switch_state(kpad); | ||
591 | |||
592 | error = adp5588_gpio_add(kpad); | ||
593 | if (error) | ||
594 | goto err_free_irq; | ||
595 | |||
262 | device_init_wakeup(&client->dev, 1); | 596 | device_init_wakeup(&client->dev, 1); |
263 | i2c_set_clientdata(client, kpad); | 597 | i2c_set_clientdata(client, kpad); |
264 | 598 | ||
@@ -285,7 +619,7 @@ static int __devexit adp5588_remove(struct i2c_client *client) | |||
285 | free_irq(client->irq, kpad); | 619 | free_irq(client->irq, kpad); |
286 | cancel_delayed_work_sync(&kpad->work); | 620 | cancel_delayed_work_sync(&kpad->work); |
287 | input_unregister_device(kpad->input); | 621 | input_unregister_device(kpad->input); |
288 | i2c_set_clientdata(client, NULL); | 622 | adp5588_gpio_remove(kpad); |
289 | kfree(kpad); | 623 | kfree(kpad); |
290 | 624 | ||
291 | return 0; | 625 | return 0; |
@@ -326,7 +660,8 @@ static const struct dev_pm_ops adp5588_dev_pm_ops = { | |||
326 | #endif | 660 | #endif |
327 | 661 | ||
328 | static const struct i2c_device_id adp5588_id[] = { | 662 | static const struct i2c_device_id adp5588_id[] = { |
329 | { KBUILD_MODNAME, 0 }, | 663 | { "adp5588-keys", 0 }, |
664 | { "adp5587-keys", 0 }, | ||
330 | { } | 665 | { } |
331 | }; | 666 | }; |
332 | MODULE_DEVICE_TABLE(i2c, adp5588_id); | 667 | MODULE_DEVICE_TABLE(i2c, adp5588_id); |
@@ -357,5 +692,5 @@ module_exit(adp5588_exit); | |||
357 | 692 | ||
358 | MODULE_LICENSE("GPL"); | 693 | MODULE_LICENSE("GPL"); |
359 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 694 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
360 | MODULE_DESCRIPTION("ADP5588 Keypad driver"); | 695 | MODULE_DESCRIPTION("ADP5588/87 Keypad driver"); |
361 | MODULE_ALIAS("platform:adp5588-keys"); | 696 | MODULE_ALIAS("platform:adp5588-keys"); |
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 35149ec455a9..79172af164f2 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/keyboard.h> | 37 | #include <linux/keyboard.h> |
38 | #include <linux/platform_device.h> | ||
38 | 39 | ||
39 | #include <asm/amigaints.h> | 40 | #include <asm/amigaints.h> |
40 | #include <asm/amigahw.h> | 41 | #include <asm/amigahw.h> |
@@ -154,10 +155,9 @@ static const char *amikbd_messages[8] = { | |||
154 | [7] = KERN_WARNING "amikbd: keyboard interrupt\n" | 155 | [7] = KERN_WARNING "amikbd: keyboard interrupt\n" |
155 | }; | 156 | }; |
156 | 157 | ||
157 | static struct input_dev *amikbd_dev; | 158 | static irqreturn_t amikbd_interrupt(int irq, void *data) |
158 | |||
159 | static irqreturn_t amikbd_interrupt(int irq, void *dummy) | ||
160 | { | 159 | { |
160 | struct input_dev *dev = data; | ||
161 | unsigned char scancode, down; | 161 | unsigned char scancode, down; |
162 | 162 | ||
163 | scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */ | 163 | scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */ |
@@ -170,47 +170,42 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy) | |||
170 | 170 | ||
171 | if (scancode < 0x78) { /* scancodes < 0x78 are keys */ | 171 | if (scancode < 0x78) { /* scancodes < 0x78 are keys */ |
172 | if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ | 172 | if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ |
173 | input_report_key(amikbd_dev, scancode, 1); | 173 | input_report_key(dev, scancode, 1); |
174 | input_report_key(amikbd_dev, scancode, 0); | 174 | input_report_key(dev, scancode, 0); |
175 | } else { | 175 | } else { |
176 | input_report_key(amikbd_dev, scancode, down); | 176 | input_report_key(dev, scancode, down); |
177 | } | 177 | } |
178 | 178 | ||
179 | input_sync(amikbd_dev); | 179 | input_sync(dev); |
180 | } else /* scancodes >= 0x78 are error codes */ | 180 | } else /* scancodes >= 0x78 are error codes */ |
181 | printk(amikbd_messages[scancode - 0x78]); | 181 | printk(amikbd_messages[scancode - 0x78]); |
182 | 182 | ||
183 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
184 | } | 184 | } |
185 | 185 | ||
186 | static int __init amikbd_init(void) | 186 | static int __init amikbd_probe(struct platform_device *pdev) |
187 | { | 187 | { |
188 | struct input_dev *dev; | ||
188 | int i, j, err; | 189 | int i, j, err; |
189 | 190 | ||
190 | if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) | 191 | dev = input_allocate_device(); |
191 | return -ENODEV; | 192 | if (!dev) { |
192 | 193 | dev_err(&pdev->dev, "Not enough memory for input device\n"); | |
193 | if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) | 194 | return -ENOMEM; |
194 | return -EBUSY; | ||
195 | |||
196 | amikbd_dev = input_allocate_device(); | ||
197 | if (!amikbd_dev) { | ||
198 | printk(KERN_ERR "amikbd: not enough memory for input device\n"); | ||
199 | err = -ENOMEM; | ||
200 | goto fail1; | ||
201 | } | 195 | } |
202 | 196 | ||
203 | amikbd_dev->name = "Amiga Keyboard"; | 197 | dev->name = pdev->name; |
204 | amikbd_dev->phys = "amikbd/input0"; | 198 | dev->phys = "amikbd/input0"; |
205 | amikbd_dev->id.bustype = BUS_AMIGA; | 199 | dev->id.bustype = BUS_AMIGA; |
206 | amikbd_dev->id.vendor = 0x0001; | 200 | dev->id.vendor = 0x0001; |
207 | amikbd_dev->id.product = 0x0001; | 201 | dev->id.product = 0x0001; |
208 | amikbd_dev->id.version = 0x0100; | 202 | dev->id.version = 0x0100; |
203 | dev->dev.parent = &pdev->dev; | ||
209 | 204 | ||
210 | amikbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 205 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
211 | 206 | ||
212 | for (i = 0; i < 0x78; i++) | 207 | for (i = 0; i < 0x78; i++) |
213 | set_bit(i, amikbd_dev->keybit); | 208 | set_bit(i, dev->keybit); |
214 | 209 | ||
215 | for (i = 0; i < MAX_NR_KEYMAPS; i++) { | 210 | for (i = 0; i < MAX_NR_KEYMAPS; i++) { |
216 | static u_short temp_map[NR_KEYS] __initdata; | 211 | static u_short temp_map[NR_KEYS] __initdata; |
@@ -229,30 +224,54 @@ static int __init amikbd_init(void) | |||
229 | memcpy(key_maps[i], temp_map, sizeof(temp_map)); | 224 | memcpy(key_maps[i], temp_map, sizeof(temp_map)); |
230 | } | 225 | } |
231 | ciaa.cra &= ~0x41; /* serial data in, turn off TA */ | 226 | ciaa.cra &= ~0x41; /* serial data in, turn off TA */ |
232 | if (request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", | 227 | err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", |
233 | amikbd_interrupt)) { | 228 | dev); |
234 | err = -EBUSY; | 229 | if (err) |
235 | goto fail2; | 230 | goto fail2; |
236 | } | ||
237 | 231 | ||
238 | err = input_register_device(amikbd_dev); | 232 | err = input_register_device(dev); |
239 | if (err) | 233 | if (err) |
240 | goto fail3; | 234 | goto fail3; |
241 | 235 | ||
236 | platform_set_drvdata(pdev, dev); | ||
237 | |||
242 | return 0; | 238 | return 0; |
243 | 239 | ||
244 | fail3: free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); | 240 | fail3: free_irq(IRQ_AMIGA_CIAA_SP, dev); |
245 | fail2: input_free_device(amikbd_dev); | 241 | fail2: input_free_device(dev); |
246 | fail1: release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); | ||
247 | return err; | 242 | return err; |
248 | } | 243 | } |
249 | 244 | ||
250 | static void __exit amikbd_exit(void) | 245 | static int __exit amikbd_remove(struct platform_device *pdev) |
246 | { | ||
247 | struct input_dev *dev = platform_get_drvdata(pdev); | ||
248 | |||
249 | platform_set_drvdata(pdev, NULL); | ||
250 | free_irq(IRQ_AMIGA_CIAA_SP, dev); | ||
251 | input_unregister_device(dev); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static struct platform_driver amikbd_driver = { | ||
256 | .remove = __exit_p(amikbd_remove), | ||
257 | .driver = { | ||
258 | .name = "amiga-keyboard", | ||
259 | .owner = THIS_MODULE, | ||
260 | }, | ||
261 | }; | ||
262 | |||
263 | static int __init amikbd_init(void) | ||
251 | { | 264 | { |
252 | free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); | 265 | return platform_driver_probe(&amikbd_driver, amikbd_probe); |
253 | input_unregister_device(amikbd_dev); | ||
254 | release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); | ||
255 | } | 266 | } |
256 | 267 | ||
257 | module_init(amikbd_init); | 268 | module_init(amikbd_init); |
269 | |||
270 | static void __exit amikbd_exit(void) | ||
271 | { | ||
272 | platform_driver_unregister(&amikbd_driver); | ||
273 | } | ||
274 | |||
258 | module_exit(amikbd_exit); | 275 | module_exit(amikbd_exit); |
276 | |||
277 | MODULE_ALIAS("platform:amiga-keyboard"); | ||
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 7b4056292eaf..d358ef8623f4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -40,26 +40,26 @@ module_param_named(set, atkbd_set, int, 0); | |||
40 | MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); | 40 | MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); |
41 | 41 | ||
42 | #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) | 42 | #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) |
43 | static int atkbd_reset; | 43 | static bool atkbd_reset; |
44 | #else | 44 | #else |
45 | static int atkbd_reset = 1; | 45 | static bool atkbd_reset = true; |
46 | #endif | 46 | #endif |
47 | module_param_named(reset, atkbd_reset, bool, 0); | 47 | module_param_named(reset, atkbd_reset, bool, 0); |
48 | MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); | 48 | MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); |
49 | 49 | ||
50 | static int atkbd_softrepeat; | 50 | static bool atkbd_softrepeat; |
51 | module_param_named(softrepeat, atkbd_softrepeat, bool, 0); | 51 | module_param_named(softrepeat, atkbd_softrepeat, bool, 0); |
52 | MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); | 52 | MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); |
53 | 53 | ||
54 | static int atkbd_softraw = 1; | 54 | static bool atkbd_softraw = true; |
55 | module_param_named(softraw, atkbd_softraw, bool, 0); | 55 | module_param_named(softraw, atkbd_softraw, bool, 0); |
56 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); | 56 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); |
57 | 57 | ||
58 | static int atkbd_scroll; | 58 | static bool atkbd_scroll; |
59 | module_param_named(scroll, atkbd_scroll, bool, 0); | 59 | module_param_named(scroll, atkbd_scroll, bool, 0); |
60 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); | 60 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); |
61 | 61 | ||
62 | static int atkbd_extra; | 62 | static bool atkbd_extra; |
63 | module_param_named(extra, atkbd_extra, bool, 0); | 63 | module_param_named(extra, atkbd_extra, bool, 0); |
64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); | 64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); |
65 | 65 | ||
@@ -153,16 +153,16 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
153 | #define ATKBD_RET_HANGEUL 0xf2 | 153 | #define ATKBD_RET_HANGEUL 0xf2 |
154 | #define ATKBD_RET_ERR 0xff | 154 | #define ATKBD_RET_ERR 0xff |
155 | 155 | ||
156 | #define ATKBD_KEY_UNKNOWN 0 | 156 | #define ATKBD_KEY_UNKNOWN 0 |
157 | #define ATKBD_KEY_NULL 255 | 157 | #define ATKBD_KEY_NULL 255 |
158 | 158 | ||
159 | #define ATKBD_SCR_1 254 | 159 | #define ATKBD_SCR_1 0xfffe |
160 | #define ATKBD_SCR_2 253 | 160 | #define ATKBD_SCR_2 0xfffd |
161 | #define ATKBD_SCR_4 252 | 161 | #define ATKBD_SCR_4 0xfffc |
162 | #define ATKBD_SCR_8 251 | 162 | #define ATKBD_SCR_8 0xfffb |
163 | #define ATKBD_SCR_CLICK 250 | 163 | #define ATKBD_SCR_CLICK 0xfffa |
164 | #define ATKBD_SCR_LEFT 249 | 164 | #define ATKBD_SCR_LEFT 0xfff9 |
165 | #define ATKBD_SCR_RIGHT 248 | 165 | #define ATKBD_SCR_RIGHT 0xfff8 |
166 | 166 | ||
167 | #define ATKBD_SPECIAL ATKBD_SCR_RIGHT | 167 | #define ATKBD_SPECIAL ATKBD_SCR_RIGHT |
168 | 168 | ||
@@ -177,7 +177,7 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
177 | #define ATKBD_XL_HANJA 0x20 | 177 | #define ATKBD_XL_HANJA 0x20 |
178 | 178 | ||
179 | static const struct { | 179 | static const struct { |
180 | unsigned char keycode; | 180 | unsigned short keycode; |
181 | unsigned char set2; | 181 | unsigned char set2; |
182 | } atkbd_scroll_keys[] = { | 182 | } atkbd_scroll_keys[] = { |
183 | { ATKBD_SCR_1, 0xc5 }, | 183 | { ATKBD_SCR_1, 0xc5 }, |
@@ -206,18 +206,18 @@ struct atkbd { | |||
206 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; | 206 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; |
207 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); | 207 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); |
208 | unsigned char set; | 208 | unsigned char set; |
209 | unsigned char translated; | 209 | bool translated; |
210 | unsigned char extra; | 210 | bool extra; |
211 | unsigned char write; | 211 | bool write; |
212 | unsigned char softrepeat; | 212 | bool softrepeat; |
213 | unsigned char softraw; | 213 | bool softraw; |
214 | unsigned char scroll; | 214 | bool scroll; |
215 | unsigned char enabled; | 215 | bool enabled; |
216 | 216 | ||
217 | /* Accessed only from interrupt */ | 217 | /* Accessed only from interrupt */ |
218 | unsigned char emul; | 218 | unsigned char emul; |
219 | unsigned char resend; | 219 | bool resend; |
220 | unsigned char release; | 220 | bool release; |
221 | unsigned long xl_bit; | 221 | unsigned long xl_bit; |
222 | unsigned int last; | 222 | unsigned int last; |
223 | unsigned long time; | 223 | unsigned long time; |
@@ -301,18 +301,18 @@ static const unsigned int xl_table[] = { | |||
301 | * Checks if we should mangle the scancode to extract 'release' bit | 301 | * Checks if we should mangle the scancode to extract 'release' bit |
302 | * in translated mode. | 302 | * in translated mode. |
303 | */ | 303 | */ |
304 | static int atkbd_need_xlate(unsigned long xl_bit, unsigned char code) | 304 | static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code) |
305 | { | 305 | { |
306 | int i; | 306 | int i; |
307 | 307 | ||
308 | if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) | 308 | if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) |
309 | return 0; | 309 | return false; |
310 | 310 | ||
311 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) | 311 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) |
312 | if (code == xl_table[i]) | 312 | if (code == xl_table[i]) |
313 | return test_bit(i, &xl_bit); | 313 | return test_bit(i, &xl_bit); |
314 | 314 | ||
315 | return 1; | 315 | return true; |
316 | } | 316 | } |
317 | 317 | ||
318 | /* | 318 | /* |
@@ -359,7 +359,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code | |||
359 | */ | 359 | */ |
360 | 360 | ||
361 | static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | 361 | static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, |
362 | unsigned int flags) | 362 | unsigned int flags) |
363 | { | 363 | { |
364 | struct atkbd *atkbd = serio_get_drvdata(serio); | 364 | struct atkbd *atkbd = serio_get_drvdata(serio); |
365 | struct input_dev *dev = atkbd->dev; | 365 | struct input_dev *dev = atkbd->dev; |
@@ -368,20 +368,18 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
368 | int value; | 368 | int value; |
369 | unsigned short keycode; | 369 | unsigned short keycode; |
370 | 370 | ||
371 | #ifdef ATKBD_DEBUG | 371 | dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); |
372 | printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); | ||
373 | #endif | ||
374 | 372 | ||
375 | #if !defined(__i386__) && !defined (__x86_64__) | 373 | #if !defined(__i386__) && !defined (__x86_64__) |
376 | if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { | 374 | if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { |
377 | printk(KERN_WARNING "atkbd.c: frame/parity error: %02x\n", flags); | 375 | dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags); |
378 | serio_write(serio, ATKBD_CMD_RESEND); | 376 | serio_write(serio, ATKBD_CMD_RESEND); |
379 | atkbd->resend = 1; | 377 | atkbd->resend = true; |
380 | goto out; | 378 | goto out; |
381 | } | 379 | } |
382 | 380 | ||
383 | if (!flags && data == ATKBD_RET_ACK) | 381 | if (!flags && data == ATKBD_RET_ACK) |
384 | atkbd->resend = 0; | 382 | atkbd->resend = false; |
385 | #endif | 383 | #endif |
386 | 384 | ||
387 | if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) | 385 | if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) |
@@ -412,32 +410,32 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
412 | } | 410 | } |
413 | 411 | ||
414 | switch (code) { | 412 | switch (code) { |
415 | case ATKBD_RET_BAT: | 413 | case ATKBD_RET_BAT: |
416 | atkbd->enabled = 0; | 414 | atkbd->enabled = false; |
417 | serio_reconnect(atkbd->ps2dev.serio); | 415 | serio_reconnect(atkbd->ps2dev.serio); |
418 | goto out; | 416 | goto out; |
419 | case ATKBD_RET_EMUL0: | 417 | case ATKBD_RET_EMUL0: |
420 | atkbd->emul = 1; | 418 | atkbd->emul = 1; |
421 | goto out; | 419 | goto out; |
422 | case ATKBD_RET_EMUL1: | 420 | case ATKBD_RET_EMUL1: |
423 | atkbd->emul = 2; | 421 | atkbd->emul = 2; |
424 | goto out; | 422 | goto out; |
425 | case ATKBD_RET_RELEASE: | 423 | case ATKBD_RET_RELEASE: |
426 | atkbd->release = 1; | 424 | atkbd->release = true; |
427 | goto out; | 425 | goto out; |
428 | case ATKBD_RET_ACK: | 426 | case ATKBD_RET_ACK: |
429 | case ATKBD_RET_NAK: | 427 | case ATKBD_RET_NAK: |
430 | if (printk_ratelimit()) | 428 | if (printk_ratelimit()) |
431 | printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " | 429 | dev_warn(&serio->dev, |
432 | "Some program might be trying access hardware directly.\n", | 430 | "Spurious %s on %s. " |
433 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); | 431 | "Some program might be trying access hardware directly.\n", |
434 | goto out; | 432 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); |
435 | case ATKBD_RET_ERR: | 433 | goto out; |
436 | atkbd->err_count++; | 434 | case ATKBD_RET_ERR: |
437 | #ifdef ATKBD_DEBUG | 435 | atkbd->err_count++; |
438 | printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); | 436 | dev_dbg(&serio->dev, "Keyboard on %s reports too many keys pressed.\n", |
439 | #endif | 437 | serio->phys); |
440 | goto out; | 438 | goto out; |
441 | } | 439 | } |
442 | 440 | ||
443 | code = atkbd_compat_scancode(atkbd, code); | 441 | code = atkbd_compat_scancode(atkbd, code); |
@@ -451,71 +449,72 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
451 | input_event(dev, EV_MSC, MSC_SCAN, code); | 449 | input_event(dev, EV_MSC, MSC_SCAN, code); |
452 | 450 | ||
453 | switch (keycode) { | 451 | switch (keycode) { |
454 | case ATKBD_KEY_NULL: | 452 | case ATKBD_KEY_NULL: |
455 | break; | 453 | break; |
456 | case ATKBD_KEY_UNKNOWN: | 454 | case ATKBD_KEY_UNKNOWN: |
457 | printk(KERN_WARNING | 455 | dev_warn(&serio->dev, |
458 | "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", | 456 | "Unknown key %s (%s set %d, code %#x on %s).\n", |
459 | atkbd->release ? "released" : "pressed", | 457 | atkbd->release ? "released" : "pressed", |
460 | atkbd->translated ? "translated" : "raw", | 458 | atkbd->translated ? "translated" : "raw", |
461 | atkbd->set, code, serio->phys); | 459 | atkbd->set, code, serio->phys); |
462 | printk(KERN_WARNING | 460 | dev_warn(&serio->dev, |
463 | "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n", | 461 | "Use 'setkeycodes %s%02x <keycode>' to make it known.\n", |
464 | code & 0x80 ? "e0" : "", code & 0x7f); | 462 | code & 0x80 ? "e0" : "", code & 0x7f); |
465 | input_sync(dev); | 463 | input_sync(dev); |
466 | break; | 464 | break; |
467 | case ATKBD_SCR_1: | 465 | case ATKBD_SCR_1: |
468 | scroll = 1 - atkbd->release * 2; | 466 | scroll = 1; |
469 | break; | 467 | break; |
470 | case ATKBD_SCR_2: | 468 | case ATKBD_SCR_2: |
471 | scroll = 2 - atkbd->release * 4; | 469 | scroll = 2; |
472 | break; | 470 | break; |
473 | case ATKBD_SCR_4: | 471 | case ATKBD_SCR_4: |
474 | scroll = 4 - atkbd->release * 8; | 472 | scroll = 4; |
475 | break; | 473 | break; |
476 | case ATKBD_SCR_8: | 474 | case ATKBD_SCR_8: |
477 | scroll = 8 - atkbd->release * 16; | 475 | scroll = 8; |
478 | break; | 476 | break; |
479 | case ATKBD_SCR_CLICK: | 477 | case ATKBD_SCR_CLICK: |
480 | click = !atkbd->release; | 478 | click = !atkbd->release; |
481 | break; | 479 | break; |
482 | case ATKBD_SCR_LEFT: | 480 | case ATKBD_SCR_LEFT: |
483 | hscroll = -1; | 481 | hscroll = -1; |
484 | break; | 482 | break; |
485 | case ATKBD_SCR_RIGHT: | 483 | case ATKBD_SCR_RIGHT: |
486 | hscroll = 1; | 484 | hscroll = 1; |
487 | break; | 485 | break; |
488 | default: | 486 | default: |
489 | if (atkbd->release) { | 487 | if (atkbd->release) { |
490 | value = 0; | 488 | value = 0; |
491 | atkbd->last = 0; | 489 | atkbd->last = 0; |
492 | } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { | 490 | } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { |
493 | /* Workaround Toshiba laptop multiple keypress */ | 491 | /* Workaround Toshiba laptop multiple keypress */ |
494 | value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; | 492 | value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; |
495 | } else { | 493 | } else { |
496 | value = 1; | 494 | value = 1; |
497 | atkbd->last = code; | 495 | atkbd->last = code; |
498 | atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; | 496 | atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; |
499 | } | 497 | } |
500 | 498 | ||
501 | input_event(dev, EV_KEY, keycode, value); | 499 | input_event(dev, EV_KEY, keycode, value); |
502 | input_sync(dev); | 500 | input_sync(dev); |
503 | 501 | ||
504 | if (value && test_bit(code, atkbd->force_release_mask)) { | 502 | if (value && test_bit(code, atkbd->force_release_mask)) { |
505 | input_report_key(dev, keycode, 0); | 503 | input_report_key(dev, keycode, 0); |
506 | input_sync(dev); | 504 | input_sync(dev); |
507 | } | 505 | } |
508 | } | 506 | } |
509 | 507 | ||
510 | if (atkbd->scroll) { | 508 | if (atkbd->scroll) { |
511 | if (click != -1) | 509 | if (click != -1) |
512 | input_report_key(dev, BTN_MIDDLE, click); | 510 | input_report_key(dev, BTN_MIDDLE, click); |
513 | input_report_rel(dev, REL_WHEEL, scroll); | 511 | input_report_rel(dev, REL_WHEEL, |
512 | atkbd->release ? -scroll : scroll); | ||
514 | input_report_rel(dev, REL_HWHEEL, hscroll); | 513 | input_report_rel(dev, REL_HWHEEL, hscroll); |
515 | input_sync(dev); | 514 | input_sync(dev); |
516 | } | 515 | } |
517 | 516 | ||
518 | atkbd->release = 0; | 517 | atkbd->release = false; |
519 | out: | 518 | out: |
520 | return IRQ_HANDLED; | 519 | return IRQ_HANDLED; |
521 | } | 520 | } |
@@ -634,17 +633,18 @@ static int atkbd_event(struct input_dev *dev, | |||
634 | 633 | ||
635 | switch (type) { | 634 | switch (type) { |
636 | 635 | ||
637 | case EV_LED: | 636 | case EV_LED: |
638 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); | 637 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); |
639 | return 0; | 638 | return 0; |
640 | 639 | ||
641 | case EV_REP: | 640 | case EV_REP: |
642 | if (!atkbd->softrepeat) | 641 | if (!atkbd->softrepeat) |
643 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); | 642 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); |
644 | return 0; | 643 | return 0; |
645 | } | ||
646 | 644 | ||
647 | return -1; | 645 | default: |
646 | return -1; | ||
647 | } | ||
648 | } | 648 | } |
649 | 649 | ||
650 | /* | 650 | /* |
@@ -655,7 +655,7 @@ static int atkbd_event(struct input_dev *dev, | |||
655 | static inline void atkbd_enable(struct atkbd *atkbd) | 655 | static inline void atkbd_enable(struct atkbd *atkbd) |
656 | { | 656 | { |
657 | serio_pause_rx(atkbd->ps2dev.serio); | 657 | serio_pause_rx(atkbd->ps2dev.serio); |
658 | atkbd->enabled = 1; | 658 | atkbd->enabled = true; |
659 | serio_continue_rx(atkbd->ps2dev.serio); | 659 | serio_continue_rx(atkbd->ps2dev.serio); |
660 | } | 660 | } |
661 | 661 | ||
@@ -667,7 +667,7 @@ static inline void atkbd_enable(struct atkbd *atkbd) | |||
667 | static inline void atkbd_disable(struct atkbd *atkbd) | 667 | static inline void atkbd_disable(struct atkbd *atkbd) |
668 | { | 668 | { |
669 | serio_pause_rx(atkbd->ps2dev.serio); | 669 | serio_pause_rx(atkbd->ps2dev.serio); |
670 | atkbd->enabled = 0; | 670 | atkbd->enabled = false; |
671 | serio_continue_rx(atkbd->ps2dev.serio); | 671 | serio_continue_rx(atkbd->ps2dev.serio); |
672 | } | 672 | } |
673 | 673 | ||
@@ -688,7 +688,9 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
688 | 688 | ||
689 | if (atkbd_reset) | 689 | if (atkbd_reset) |
690 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) | 690 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) |
691 | printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", ps2dev->serio->phys); | 691 | dev_warn(&ps2dev->serio->dev, |
692 | "keyboard reset failed on %s\n", | ||
693 | ps2dev->serio->phys); | ||
692 | 694 | ||
693 | /* | 695 | /* |
694 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. | 696 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. |
@@ -718,8 +720,9 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
718 | atkbd->id = (param[0] << 8) | param[1]; | 720 | atkbd->id = (param[0] << 8) | param[1]; |
719 | 721 | ||
720 | if (atkbd->id == 0xaca1 && atkbd->translated) { | 722 | if (atkbd->id == 0xaca1 && atkbd->translated) { |
721 | printk(KERN_ERR "atkbd.c: NCD terminal keyboards are only supported on non-translating\n"); | 723 | dev_err(&ps2dev->serio->dev, |
722 | printk(KERN_ERR "atkbd.c: controllers. Use i8042.direct=1 to disable translation.\n"); | 724 | "NCD terminal keyboards are only supported on non-translating controlelrs. " |
725 | "Use i8042.direct=1 to disable translation.\n"); | ||
723 | return -1; | 726 | return -1; |
724 | } | 727 | } |
725 | 728 | ||
@@ -737,7 +740,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
737 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 740 | struct ps2dev *ps2dev = &atkbd->ps2dev; |
738 | unsigned char param[2]; | 741 | unsigned char param[2]; |
739 | 742 | ||
740 | atkbd->extra = 0; | 743 | atkbd->extra = false; |
741 | /* | 744 | /* |
742 | * For known special keyboards we can go ahead and set the correct set. | 745 | * For known special keyboards we can go ahead and set the correct set. |
743 | * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and | 746 | * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and |
@@ -756,7 +759,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
756 | if (allow_extra) { | 759 | if (allow_extra) { |
757 | param[0] = 0x71; | 760 | param[0] = 0x71; |
758 | if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { | 761 | if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { |
759 | atkbd->extra = 1; | 762 | atkbd->extra = true; |
760 | return 2; | 763 | return 2; |
761 | } | 764 | } |
762 | } | 765 | } |
@@ -821,7 +824,8 @@ static int atkbd_activate(struct atkbd *atkbd) | |||
821 | */ | 824 | */ |
822 | 825 | ||
823 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { | 826 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { |
824 | printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n", | 827 | dev_err(&ps2dev->serio->dev, |
828 | "Failed to enable keyboard on %s\n", | ||
825 | ps2dev->serio->phys); | 829 | ps2dev->serio->phys); |
826 | return -1; | 830 | return -1; |
827 | } | 831 | } |
@@ -1070,9 +1074,13 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) | |||
1070 | input_dev->keycodesize = sizeof(unsigned short); | 1074 | input_dev->keycodesize = sizeof(unsigned short); |
1071 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); | 1075 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); |
1072 | 1076 | ||
1073 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) | 1077 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) { |
1074 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) | 1078 | if (atkbd->keycode[i] != KEY_RESERVED && |
1079 | atkbd->keycode[i] != ATKBD_KEY_NULL && | ||
1080 | atkbd->keycode[i] < ATKBD_SPECIAL) { | ||
1075 | __set_bit(atkbd->keycode[i], input_dev->keybit); | 1081 | __set_bit(atkbd->keycode[i], input_dev->keybit); |
1082 | } | ||
1083 | } | ||
1076 | } | 1084 | } |
1077 | 1085 | ||
1078 | /* | 1086 | /* |
@@ -1100,12 +1108,14 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1100 | 1108 | ||
1101 | switch (serio->id.type) { | 1109 | switch (serio->id.type) { |
1102 | 1110 | ||
1103 | case SERIO_8042_XL: | 1111 | case SERIO_8042_XL: |
1104 | atkbd->translated = 1; | 1112 | atkbd->translated = true; |
1105 | case SERIO_8042: | 1113 | /* Fall through */ |
1106 | if (serio->write) | 1114 | |
1107 | atkbd->write = 1; | 1115 | case SERIO_8042: |
1108 | break; | 1116 | if (serio->write) |
1117 | atkbd->write = true; | ||
1118 | break; | ||
1109 | } | 1119 | } |
1110 | 1120 | ||
1111 | atkbd->softraw = atkbd_softraw; | 1121 | atkbd->softraw = atkbd_softraw; |
@@ -1113,7 +1123,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1113 | atkbd->scroll = atkbd_scroll; | 1123 | atkbd->scroll = atkbd_scroll; |
1114 | 1124 | ||
1115 | if (atkbd->softrepeat) | 1125 | if (atkbd->softrepeat) |
1116 | atkbd->softraw = 1; | 1126 | atkbd->softraw = true; |
1117 | 1127 | ||
1118 | serio_set_drvdata(serio, atkbd); | 1128 | serio_set_drvdata(serio, atkbd); |
1119 | 1129 | ||
@@ -1172,7 +1182,8 @@ static int atkbd_reconnect(struct serio *serio) | |||
1172 | int retval = -1; | 1182 | int retval = -1; |
1173 | 1183 | ||
1174 | if (!atkbd || !drv) { | 1184 | if (!atkbd || !drv) { |
1175 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); | 1185 | dev_dbg(&serio->dev, |
1186 | "reconnect request, but serio is disconnected, ignoring...\n"); | ||
1176 | return -1; | 1187 | return -1; |
1177 | } | 1188 | } |
1178 | 1189 | ||
@@ -1286,7 +1297,8 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun | |||
1286 | struct input_dev *old_dev, *new_dev; | 1297 | struct input_dev *old_dev, *new_dev; |
1287 | unsigned long value; | 1298 | unsigned long value; |
1288 | int err; | 1299 | int err; |
1289 | unsigned char old_extra, old_set; | 1300 | bool old_extra; |
1301 | unsigned char old_set; | ||
1290 | 1302 | ||
1291 | if (!atkbd->write) | 1303 | if (!atkbd->write) |
1292 | return -EIO; | 1304 | return -EIO; |
@@ -1369,7 +1381,7 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou | |||
1369 | struct input_dev *old_dev, *new_dev; | 1381 | struct input_dev *old_dev, *new_dev; |
1370 | unsigned long value; | 1382 | unsigned long value; |
1371 | int err; | 1383 | int err; |
1372 | unsigned char old_scroll; | 1384 | bool old_scroll; |
1373 | 1385 | ||
1374 | if (strict_strtoul(buf, 10, &value) || value > 1) | 1386 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1375 | return -EINVAL; | 1387 | return -EINVAL; |
@@ -1413,7 +1425,8 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | |||
1413 | struct input_dev *old_dev, *new_dev; | 1425 | struct input_dev *old_dev, *new_dev; |
1414 | unsigned long value; | 1426 | unsigned long value; |
1415 | int err; | 1427 | int err; |
1416 | unsigned char old_set, old_extra; | 1428 | unsigned char old_set; |
1429 | bool old_extra; | ||
1417 | 1430 | ||
1418 | if (!atkbd->write) | 1431 | if (!atkbd->write) |
1419 | return -EIO; | 1432 | return -EIO; |
@@ -1463,7 +1476,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t | |||
1463 | struct input_dev *old_dev, *new_dev; | 1476 | struct input_dev *old_dev, *new_dev; |
1464 | unsigned long value; | 1477 | unsigned long value; |
1465 | int err; | 1478 | int err; |
1466 | unsigned char old_softrepeat, old_softraw; | 1479 | bool old_softrepeat, old_softraw; |
1467 | 1480 | ||
1468 | if (!atkbd->write) | 1481 | if (!atkbd->write) |
1469 | return -EIO; | 1482 | return -EIO; |
@@ -1483,7 +1496,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t | |||
1483 | atkbd->dev = new_dev; | 1496 | atkbd->dev = new_dev; |
1484 | atkbd->softrepeat = value; | 1497 | atkbd->softrepeat = value; |
1485 | if (atkbd->softrepeat) | 1498 | if (atkbd->softrepeat) |
1486 | atkbd->softraw = 1; | 1499 | atkbd->softraw = true; |
1487 | atkbd_set_device_attrs(atkbd); | 1500 | atkbd_set_device_attrs(atkbd); |
1488 | 1501 | ||
1489 | err = input_register_device(atkbd->dev); | 1502 | err = input_register_device(atkbd->dev); |
@@ -1513,7 +1526,7 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co | |||
1513 | struct input_dev *old_dev, *new_dev; | 1526 | struct input_dev *old_dev, *new_dev; |
1514 | unsigned long value; | 1527 | unsigned long value; |
1515 | int err; | 1528 | int err; |
1516 | unsigned char old_softraw; | 1529 | bool old_softraw; |
1517 | 1530 | ||
1518 | if (strict_strtoul(buf, 10, &value) || value > 1) | 1531 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1519 | return -EINVAL; | 1532 | return -EINVAL; |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index fe376a27fe57..7d989603f875 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/fs.h> | 34 | #include <linux/fs.h> |
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
37 | #include <linux/slab.h> | ||
37 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
38 | #include <linux/pm.h> | 39 | #include <linux/pm.h> |
39 | #include <linux/sysctl.h> | 40 | #include <linux/sysctl.h> |
@@ -162,7 +163,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) | |||
162 | input_sync(input); | 163 | input_sync(input); |
163 | 164 | ||
164 | if (bfin_kpad_get_keypressed(bf54x_kpad)) { | 165 | if (bfin_kpad_get_keypressed(bf54x_kpad)) { |
165 | disable_irq(bf54x_kpad->irq); | 166 | disable_irq_nosync(bf54x_kpad->irq); |
166 | bf54x_kpad->lastkey = key; | 167 | bf54x_kpad->lastkey = key; |
167 | mod_timer(&bf54x_kpad->timer, | 168 | mod_timer(&bf54x_kpad->timer, |
168 | jiffies + bf54x_kpad->keyup_test_jiffies); | 169 | jiffies + bf54x_kpad->keyup_test_jiffies); |
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c deleted file mode 100644 index 634af6a8e6b3..000000000000 --- a/drivers/input/keyboard/corgikbd.c +++ /dev/null | |||
@@ -1,414 +0,0 @@ | |||
1 | /* | ||
2 | * Keyboard driver for Sharp Corgi models (SL-C7xx) | ||
3 | * | ||
4 | * Copyright (c) 2004-2005 Richard Purdie | ||
5 | * | ||
6 | * Based on xtkbd.c/locomkbd.c | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/jiffies.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #include <mach/corgi.h> | ||
24 | #include <mach/pxa2xx-gpio.h> | ||
25 | #include <asm/hardware/scoop.h> | ||
26 | |||
27 | #define KB_ROWS 8 | ||
28 | #define KB_COLS 12 | ||
29 | #define KB_ROWMASK(r) (1 << (r)) | ||
30 | #define SCANCODE(r,c) ( ((r)<<4) + (c) + 1 ) | ||
31 | /* zero code, 124 scancodes */ | ||
32 | #define NR_SCANCODES ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 ) | ||
33 | |||
34 | #define SCAN_INTERVAL (50) /* ms */ | ||
35 | #define HINGE_SCAN_INTERVAL (250) /* ms */ | ||
36 | |||
37 | #define CORGI_KEY_CALENDER KEY_F1 | ||
38 | #define CORGI_KEY_ADDRESS KEY_F2 | ||
39 | #define CORGI_KEY_FN KEY_F3 | ||
40 | #define CORGI_KEY_CANCEL KEY_F4 | ||
41 | #define CORGI_KEY_OFF KEY_SUSPEND | ||
42 | #define CORGI_KEY_EXOK KEY_F5 | ||
43 | #define CORGI_KEY_EXCANCEL KEY_F6 | ||
44 | #define CORGI_KEY_EXJOGDOWN KEY_F7 | ||
45 | #define CORGI_KEY_EXJOGUP KEY_F8 | ||
46 | #define CORGI_KEY_JAP1 KEY_LEFTCTRL | ||
47 | #define CORGI_KEY_JAP2 KEY_LEFTALT | ||
48 | #define CORGI_KEY_MAIL KEY_F10 | ||
49 | #define CORGI_KEY_OK KEY_F11 | ||
50 | #define CORGI_KEY_MENU KEY_F12 | ||
51 | |||
52 | static unsigned char corgikbd_keycode[NR_SCANCODES] = { | ||
53 | 0, /* 0 */ | ||
54 | 0, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, 0, 0, 0, 0, 0, 0, 0, /* 1-16 */ | ||
55 | 0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, 0, 0, 0, 0, 0, 0, 0, /* 17-32 */ | ||
56 | KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */ | ||
57 | CORGI_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */ | ||
58 | CORGI_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, 0, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, /* 65-80 */ | ||
59 | CORGI_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, 0, CORGI_KEY_FN, 0, 0, 0, 0, /* 81-96 */ | ||
60 | KEY_SYSRQ, CORGI_KEY_JAP1, CORGI_KEY_JAP2, CORGI_KEY_CANCEL, CORGI_KEY_OK, CORGI_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0, /* 97-112 */ | ||
61 | CORGI_KEY_OFF, CORGI_KEY_EXOK, CORGI_KEY_EXCANCEL, CORGI_KEY_EXJOGDOWN, CORGI_KEY_EXJOGUP, 0, 0, 0, 0, 0, 0, 0, /* 113-124 */ | ||
62 | }; | ||
63 | |||
64 | |||
65 | struct corgikbd { | ||
66 | unsigned char keycode[ARRAY_SIZE(corgikbd_keycode)]; | ||
67 | struct input_dev *input; | ||
68 | |||
69 | spinlock_t lock; | ||
70 | struct timer_list timer; | ||
71 | struct timer_list htimer; | ||
72 | |||
73 | unsigned int suspended; | ||
74 | unsigned long suspend_jiffies; | ||
75 | }; | ||
76 | |||
77 | #define KB_DISCHARGE_DELAY 10 | ||
78 | #define KB_ACTIVATE_DELAY 10 | ||
79 | |||
80 | /* Helper functions for reading the keyboard matrix | ||
81 | * Note: We should really be using the generic gpio functions to alter | ||
82 | * GPDR but it requires a function call per GPIO bit which is | ||
83 | * excessive when we need to access 12 bits at once, multiple times. | ||
84 | * These functions must be called within local_irq_save()/local_irq_restore() | ||
85 | * or similar. | ||
86 | */ | ||
87 | static inline void corgikbd_discharge_all(void) | ||
88 | { | ||
89 | /* STROBE All HiZ */ | ||
90 | GPCR2 = CORGI_GPIO_ALL_STROBE_BIT; | ||
91 | GPDR2 &= ~CORGI_GPIO_ALL_STROBE_BIT; | ||
92 | } | ||
93 | |||
94 | static inline void corgikbd_activate_all(void) | ||
95 | { | ||
96 | /* STROBE ALL -> High */ | ||
97 | GPSR2 = CORGI_GPIO_ALL_STROBE_BIT; | ||
98 | GPDR2 |= CORGI_GPIO_ALL_STROBE_BIT; | ||
99 | |||
100 | udelay(KB_DISCHARGE_DELAY); | ||
101 | |||
102 | /* Clear any interrupts we may have triggered when altering the GPIO lines */ | ||
103 | GEDR1 = CORGI_GPIO_HIGH_SENSE_BIT; | ||
104 | GEDR2 = CORGI_GPIO_LOW_SENSE_BIT; | ||
105 | } | ||
106 | |||
107 | static inline void corgikbd_activate_col(int col) | ||
108 | { | ||
109 | /* STROBE col -> High, not col -> HiZ */ | ||
110 | GPSR2 = CORGI_GPIO_STROBE_BIT(col); | ||
111 | GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col); | ||
112 | } | ||
113 | |||
114 | static inline void corgikbd_reset_col(int col) | ||
115 | { | ||
116 | /* STROBE col -> Low */ | ||
117 | GPCR2 = CORGI_GPIO_STROBE_BIT(col); | ||
118 | /* STROBE col -> out, not col -> HiZ */ | ||
119 | GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col); | ||
120 | } | ||
121 | |||
122 | #define GET_ROWS_STATUS(c) (((GPLR1 & CORGI_GPIO_HIGH_SENSE_BIT) >> CORGI_GPIO_HIGH_SENSE_RSHIFT) | ((GPLR2 & CORGI_GPIO_LOW_SENSE_BIT) << CORGI_GPIO_LOW_SENSE_LSHIFT)) | ||
123 | |||
124 | /* | ||
125 | * The corgi keyboard only generates interrupts when a key is pressed. | ||
126 | * When a key is pressed, we enable a timer which then scans the | ||
127 | * keyboard to detect when the key is released. | ||
128 | */ | ||
129 | |||
130 | /* Scan the hardware keyboard and push any changes up through the input layer */ | ||
131 | static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data) | ||
132 | { | ||
133 | unsigned int row, col, rowd; | ||
134 | unsigned long flags; | ||
135 | unsigned int num_pressed; | ||
136 | |||
137 | if (corgikbd_data->suspended) | ||
138 | return; | ||
139 | |||
140 | spin_lock_irqsave(&corgikbd_data->lock, flags); | ||
141 | |||
142 | num_pressed = 0; | ||
143 | for (col = 0; col < KB_COLS; col++) { | ||
144 | /* | ||
145 | * Discharge the output driver capacitatance | ||
146 | * in the keyboard matrix. (Yes it is significant..) | ||
147 | */ | ||
148 | |||
149 | corgikbd_discharge_all(); | ||
150 | udelay(KB_DISCHARGE_DELAY); | ||
151 | |||
152 | corgikbd_activate_col(col); | ||
153 | udelay(KB_ACTIVATE_DELAY); | ||
154 | |||
155 | rowd = GET_ROWS_STATUS(col); | ||
156 | for (row = 0; row < KB_ROWS; row++) { | ||
157 | unsigned int scancode, pressed; | ||
158 | |||
159 | scancode = SCANCODE(row, col); | ||
160 | pressed = rowd & KB_ROWMASK(row); | ||
161 | |||
162 | input_report_key(corgikbd_data->input, corgikbd_data->keycode[scancode], pressed); | ||
163 | |||
164 | if (pressed) | ||
165 | num_pressed++; | ||
166 | |||
167 | if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF) | ||
168 | && time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) { | ||
169 | input_event(corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1); | ||
170 | corgikbd_data->suspend_jiffies=jiffies; | ||
171 | } | ||
172 | } | ||
173 | corgikbd_reset_col(col); | ||
174 | } | ||
175 | |||
176 | corgikbd_activate_all(); | ||
177 | |||
178 | input_sync(corgikbd_data->input); | ||
179 | |||
180 | /* if any keys are pressed, enable the timer */ | ||
181 | if (num_pressed) | ||
182 | mod_timer(&corgikbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL)); | ||
183 | |||
184 | spin_unlock_irqrestore(&corgikbd_data->lock, flags); | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * corgi keyboard interrupt handler. | ||
189 | */ | ||
190 | static irqreturn_t corgikbd_interrupt(int irq, void *dev_id) | ||
191 | { | ||
192 | struct corgikbd *corgikbd_data = dev_id; | ||
193 | |||
194 | if (!timer_pending(&corgikbd_data->timer)) { | ||
195 | /** wait chattering delay **/ | ||
196 | udelay(20); | ||
197 | corgikbd_scankeyboard(corgikbd_data); | ||
198 | } | ||
199 | |||
200 | return IRQ_HANDLED; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * corgi timer checking for released keys | ||
205 | */ | ||
206 | static void corgikbd_timer_callback(unsigned long data) | ||
207 | { | ||
208 | struct corgikbd *corgikbd_data = (struct corgikbd *) data; | ||
209 | corgikbd_scankeyboard(corgikbd_data); | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * The hinge switches generate no interrupt so they need to be | ||
214 | * monitored by a timer. | ||
215 | * | ||
216 | * We debounce the switches and pass them to the input system. | ||
217 | * | ||
218 | * gprr == 0x00 - Keyboard with Landscape Screen | ||
219 | * 0x08 - No Keyboard with Portrait Screen | ||
220 | * 0x0c - Keyboard and Screen Closed | ||
221 | */ | ||
222 | |||
223 | #define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) | ||
224 | #define HINGE_STABLE_COUNT 2 | ||
225 | static int sharpsl_hinge_state; | ||
226 | static int hinge_count; | ||
227 | |||
228 | static void corgikbd_hinge_timer(unsigned long data) | ||
229 | { | ||
230 | struct corgikbd *corgikbd_data = (struct corgikbd *) data; | ||
231 | unsigned long gprr; | ||
232 | unsigned long flags; | ||
233 | |||
234 | gprr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_GPRR) & (CORGI_SCP_SWA | CORGI_SCP_SWB); | ||
235 | gprr |= (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0); | ||
236 | if (gprr != sharpsl_hinge_state) { | ||
237 | hinge_count = 0; | ||
238 | sharpsl_hinge_state = gprr; | ||
239 | } else if (hinge_count < HINGE_STABLE_COUNT) { | ||
240 | hinge_count++; | ||
241 | if (hinge_count >= HINGE_STABLE_COUNT) { | ||
242 | spin_lock_irqsave(&corgikbd_data->lock, flags); | ||
243 | |||
244 | input_report_switch(corgikbd_data->input, SW_LID, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0)); | ||
245 | input_report_switch(corgikbd_data->input, SW_TABLET_MODE, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0)); | ||
246 | input_report_switch(corgikbd_data->input, SW_HEADPHONE_INSERT, (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0)); | ||
247 | input_sync(corgikbd_data->input); | ||
248 | |||
249 | spin_unlock_irqrestore(&corgikbd_data->lock, flags); | ||
250 | } | ||
251 | } | ||
252 | mod_timer(&corgikbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); | ||
253 | } | ||
254 | |||
255 | #ifdef CONFIG_PM | ||
256 | static int corgikbd_suspend(struct platform_device *dev, pm_message_t state) | ||
257 | { | ||
258 | int i; | ||
259 | struct corgikbd *corgikbd = platform_get_drvdata(dev); | ||
260 | |||
261 | corgikbd->suspended = 1; | ||
262 | /* strobe 0 is the power key so this can't be made an input for | ||
263 | powersaving therefore i = 1 */ | ||
264 | for (i = 1; i < CORGI_KEY_STROBE_NUM; i++) | ||
265 | pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_IN); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int corgikbd_resume(struct platform_device *dev) | ||
271 | { | ||
272 | int i; | ||
273 | struct corgikbd *corgikbd = platform_get_drvdata(dev); | ||
274 | |||
275 | for (i = 1; i < CORGI_KEY_STROBE_NUM; i++) | ||
276 | pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH); | ||
277 | |||
278 | /* Upon resume, ignore the suspend key for a short while */ | ||
279 | corgikbd->suspend_jiffies=jiffies; | ||
280 | corgikbd->suspended = 0; | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | #else | ||
285 | #define corgikbd_suspend NULL | ||
286 | #define corgikbd_resume NULL | ||
287 | #endif | ||
288 | |||
289 | static int __devinit corgikbd_probe(struct platform_device *pdev) | ||
290 | { | ||
291 | struct corgikbd *corgikbd; | ||
292 | struct input_dev *input_dev; | ||
293 | int i, err = -ENOMEM; | ||
294 | |||
295 | corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL); | ||
296 | input_dev = input_allocate_device(); | ||
297 | if (!corgikbd || !input_dev) | ||
298 | goto fail; | ||
299 | |||
300 | platform_set_drvdata(pdev, corgikbd); | ||
301 | |||
302 | corgikbd->input = input_dev; | ||
303 | spin_lock_init(&corgikbd->lock); | ||
304 | |||
305 | /* Init Keyboard rescan timer */ | ||
306 | init_timer(&corgikbd->timer); | ||
307 | corgikbd->timer.function = corgikbd_timer_callback; | ||
308 | corgikbd->timer.data = (unsigned long) corgikbd; | ||
309 | |||
310 | /* Init Hinge Timer */ | ||
311 | init_timer(&corgikbd->htimer); | ||
312 | corgikbd->htimer.function = corgikbd_hinge_timer; | ||
313 | corgikbd->htimer.data = (unsigned long) corgikbd; | ||
314 | |||
315 | corgikbd->suspend_jiffies=jiffies; | ||
316 | |||
317 | memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode)); | ||
318 | |||
319 | input_dev->name = "Corgi Keyboard"; | ||
320 | input_dev->phys = "corgikbd/input0"; | ||
321 | input_dev->id.bustype = BUS_HOST; | ||
322 | input_dev->id.vendor = 0x0001; | ||
323 | input_dev->id.product = 0x0001; | ||
324 | input_dev->id.version = 0x0100; | ||
325 | input_dev->dev.parent = &pdev->dev; | ||
326 | |||
327 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | | ||
328 | BIT_MASK(EV_PWR) | BIT_MASK(EV_SW); | ||
329 | input_dev->keycode = corgikbd->keycode; | ||
330 | input_dev->keycodesize = sizeof(unsigned char); | ||
331 | input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode); | ||
332 | |||
333 | for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++) | ||
334 | set_bit(corgikbd->keycode[i], input_dev->keybit); | ||
335 | clear_bit(0, input_dev->keybit); | ||
336 | set_bit(SW_LID, input_dev->swbit); | ||
337 | set_bit(SW_TABLET_MODE, input_dev->swbit); | ||
338 | set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); | ||
339 | |||
340 | err = input_register_device(corgikbd->input); | ||
341 | if (err) | ||
342 | goto fail; | ||
343 | |||
344 | mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); | ||
345 | |||
346 | /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ | ||
347 | for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) { | ||
348 | pxa_gpio_mode(CORGI_GPIO_KEY_SENSE(i) | GPIO_IN); | ||
349 | if (request_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd_interrupt, | ||
350 | IRQF_DISABLED | IRQF_TRIGGER_RISING, | ||
351 | "corgikbd", corgikbd)) | ||
352 | printk(KERN_WARNING "corgikbd: Can't get IRQ: %d!\n", i); | ||
353 | } | ||
354 | |||
355 | /* Set Strobe lines as outputs - set high */ | ||
356 | for (i = 0; i < CORGI_KEY_STROBE_NUM; i++) | ||
357 | pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH); | ||
358 | |||
359 | /* Setup the headphone jack as an input */ | ||
360 | pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN); | ||
361 | |||
362 | return 0; | ||
363 | |||
364 | fail: input_free_device(input_dev); | ||
365 | kfree(corgikbd); | ||
366 | return err; | ||
367 | } | ||
368 | |||
369 | static int __devexit corgikbd_remove(struct platform_device *pdev) | ||
370 | { | ||
371 | int i; | ||
372 | struct corgikbd *corgikbd = platform_get_drvdata(pdev); | ||
373 | |||
374 | for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) | ||
375 | free_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd); | ||
376 | |||
377 | del_timer_sync(&corgikbd->htimer); | ||
378 | del_timer_sync(&corgikbd->timer); | ||
379 | |||
380 | input_unregister_device(corgikbd->input); | ||
381 | |||
382 | kfree(corgikbd); | ||
383 | |||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static struct platform_driver corgikbd_driver = { | ||
388 | .probe = corgikbd_probe, | ||
389 | .remove = __devexit_p(corgikbd_remove), | ||
390 | .suspend = corgikbd_suspend, | ||
391 | .resume = corgikbd_resume, | ||
392 | .driver = { | ||
393 | .name = "corgi-keyboard", | ||
394 | .owner = THIS_MODULE, | ||
395 | }, | ||
396 | }; | ||
397 | |||
398 | static int __init corgikbd_init(void) | ||
399 | { | ||
400 | return platform_driver_register(&corgikbd_driver); | ||
401 | } | ||
402 | |||
403 | static void __exit corgikbd_exit(void) | ||
404 | { | ||
405 | platform_driver_unregister(&corgikbd_driver); | ||
406 | } | ||
407 | |||
408 | module_init(corgikbd_init); | ||
409 | module_exit(corgikbd_exit); | ||
410 | |||
411 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | ||
412 | MODULE_DESCRIPTION("Corgi Keyboard Driver"); | ||
413 | MODULE_LICENSE("GPL v2"); | ||
414 | MODULE_ALIAS("platform:corgi-keyboard"); | ||
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index d410d7a52f1d..a91ee941b5c1 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/errno.h> | 32 | #include <linux/errno.h> |
33 | #include <linux/slab.h> | ||
33 | 34 | ||
34 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
35 | 36 | ||
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index e45740429f7e..c8242dd190d0 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/input/matrix_keypad.h> | 27 | #include <linux/input/matrix_keypad.h> |
28 | #include <linux/slab.h> | ||
28 | 29 | ||
29 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
30 | #include <mach/ep93xx_keypad.h> | 31 | #include <mach/ep93xx_keypad.h> |
@@ -69,7 +70,7 @@ struct ep93xx_keypad { | |||
69 | 70 | ||
70 | void __iomem *mmio_base; | 71 | void __iomem *mmio_base; |
71 | 72 | ||
72 | unsigned int matrix_keycodes[EP93XX_MATRIX_SIZE]; | 73 | unsigned short keycodes[EP93XX_MATRIX_SIZE]; |
73 | 74 | ||
74 | int key1; | 75 | int key1; |
75 | int key2; | 76 | int key2; |
@@ -79,24 +80,6 @@ struct ep93xx_keypad { | |||
79 | bool enabled; | 80 | bool enabled; |
80 | }; | 81 | }; |
81 | 82 | ||
82 | static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad) | ||
83 | { | ||
84 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; | ||
85 | struct input_dev *input_dev = keypad->input_dev; | ||
86 | unsigned int *key; | ||
87 | int i; | ||
88 | |||
89 | key = &pdata->matrix_key_map[0]; | ||
90 | for (i = 0; i < pdata->matrix_key_map_size; i++, key++) { | ||
91 | int row = KEY_ROW(*key); | ||
92 | int col = KEY_COL(*key); | ||
93 | int code = KEY_VAL(*key); | ||
94 | |||
95 | keypad->matrix_keycodes[(row << 3) + col] = code; | ||
96 | __set_bit(code, input_dev->keybit); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) | 83 | static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) |
101 | { | 84 | { |
102 | struct ep93xx_keypad *keypad = dev_id; | 85 | struct ep93xx_keypad *keypad = dev_id; |
@@ -107,10 +90,10 @@ static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) | |||
107 | status = __raw_readl(keypad->mmio_base + KEY_REG); | 90 | status = __raw_readl(keypad->mmio_base + KEY_REG); |
108 | 91 | ||
109 | keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; | 92 | keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; |
110 | key1 = keypad->matrix_keycodes[keycode]; | 93 | key1 = keypad->keycodes[keycode]; |
111 | 94 | ||
112 | keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; | 95 | keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; |
113 | key2 = keypad->matrix_keycodes[keycode]; | 96 | key2 = keypad->keycodes[keycode]; |
114 | 97 | ||
115 | if (status & KEY_REG_2KEYS) { | 98 | if (status & KEY_REG_2KEYS) { |
116 | if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) | 99 | if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) |
@@ -256,6 +239,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) | |||
256 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | 239 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) |
257 | { | 240 | { |
258 | struct ep93xx_keypad *keypad; | 241 | struct ep93xx_keypad *keypad; |
242 | const struct matrix_keymap_data *keymap_data; | ||
259 | struct input_dev *input_dev; | 243 | struct input_dev *input_dev; |
260 | struct resource *res; | 244 | struct resource *res; |
261 | int err; | 245 | int err; |
@@ -270,6 +254,12 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
270 | goto failed_free; | 254 | goto failed_free; |
271 | } | 255 | } |
272 | 256 | ||
257 | keymap_data = keypad->pdata->keymap_data; | ||
258 | if (!keymap_data) { | ||
259 | err = -EINVAL; | ||
260 | goto failed_free; | ||
261 | } | ||
262 | |||
273 | keypad->irq = platform_get_irq(pdev, 0); | 263 | keypad->irq = platform_get_irq(pdev, 0); |
274 | if (!keypad->irq) { | 264 | if (!keypad->irq) { |
275 | err = -ENXIO; | 265 | err = -ENXIO; |
@@ -317,9 +307,9 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
317 | input_dev->open = ep93xx_keypad_open; | 307 | input_dev->open = ep93xx_keypad_open; |
318 | input_dev->close = ep93xx_keypad_close; | 308 | input_dev->close = ep93xx_keypad_close; |
319 | input_dev->dev.parent = &pdev->dev; | 309 | input_dev->dev.parent = &pdev->dev; |
320 | input_dev->keycode = keypad->matrix_keycodes; | 310 | input_dev->keycode = keypad->keycodes; |
321 | input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]); | 311 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); |
322 | input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes); | 312 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); |
323 | 313 | ||
324 | input_set_drvdata(input_dev, keypad); | 314 | input_set_drvdata(input_dev, keypad); |
325 | 315 | ||
@@ -327,7 +317,8 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
327 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) | 317 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) |
328 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | 318 | input_dev->evbit[0] |= BIT_MASK(EV_REP); |
329 | 319 | ||
330 | ep93xx_keypad_build_keycode(keypad); | 320 | matrix_keypad_build_keymap(keymap_data, 3, |
321 | input_dev->keycode, input_dev->keybit); | ||
331 | platform_set_drvdata(pdev, keypad); | 322 | platform_set_drvdata(pdev, keypad); |
332 | 323 | ||
333 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, | 324 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 1aff3b76effd..6069abe31e42 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
19 | #include <linux/slab.h> | ||
19 | #include <linux/sysctl.h> | 20 | #include <linux/sysctl.h> |
20 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
21 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
@@ -30,13 +31,292 @@ struct gpio_button_data { | |||
30 | struct input_dev *input; | 31 | struct input_dev *input; |
31 | struct timer_list timer; | 32 | struct timer_list timer; |
32 | struct work_struct work; | 33 | struct work_struct work; |
34 | int timer_debounce; /* in msecs */ | ||
35 | bool disabled; | ||
33 | }; | 36 | }; |
34 | 37 | ||
35 | struct gpio_keys_drvdata { | 38 | struct gpio_keys_drvdata { |
36 | struct input_dev *input; | 39 | struct input_dev *input; |
40 | struct mutex disable_lock; | ||
41 | unsigned int n_buttons; | ||
42 | int (*enable)(struct device *dev); | ||
43 | void (*disable)(struct device *dev); | ||
37 | struct gpio_button_data data[0]; | 44 | struct gpio_button_data data[0]; |
38 | }; | 45 | }; |
39 | 46 | ||
47 | /* | ||
48 | * SYSFS interface for enabling/disabling keys and switches: | ||
49 | * | ||
50 | * There are 4 attributes under /sys/devices/platform/gpio-keys/ | ||
51 | * keys [ro] - bitmap of keys (EV_KEY) which can be | ||
52 | * disabled | ||
53 | * switches [ro] - bitmap of switches (EV_SW) which can be | ||
54 | * disabled | ||
55 | * disabled_keys [rw] - bitmap of keys currently disabled | ||
56 | * disabled_switches [rw] - bitmap of switches currently disabled | ||
57 | * | ||
58 | * Userland can change these values and hence disable event generation | ||
59 | * for each key (or switch). Disabling a key means its interrupt line | ||
60 | * is disabled. | ||
61 | * | ||
62 | * For example, if we have following switches set up as gpio-keys: | ||
63 | * SW_DOCK = 5 | ||
64 | * SW_CAMERA_LENS_COVER = 9 | ||
65 | * SW_KEYPAD_SLIDE = 10 | ||
66 | * SW_FRONT_PROXIMITY = 11 | ||
67 | * This is read from switches: | ||
68 | * 11-9,5 | ||
69 | * Next we want to disable proximity (11) and dock (5), we write: | ||
70 | * 11,5 | ||
71 | * to file disabled_switches. Now proximity and dock IRQs are disabled. | ||
72 | * This can be verified by reading the file disabled_switches: | ||
73 | * 11,5 | ||
74 | * If we now want to enable proximity (11) switch we write: | ||
75 | * 5 | ||
76 | * to disabled_switches. | ||
77 | * | ||
78 | * We can disable only those keys which don't allow sharing the irq. | ||
79 | */ | ||
80 | |||
81 | /** | ||
82 | * get_n_events_by_type() - returns maximum number of events per @type | ||
83 | * @type: type of button (%EV_KEY, %EV_SW) | ||
84 | * | ||
85 | * Return value of this function can be used to allocate bitmap | ||
86 | * large enough to hold all bits for given type. | ||
87 | */ | ||
88 | static inline int get_n_events_by_type(int type) | ||
89 | { | ||
90 | BUG_ON(type != EV_SW && type != EV_KEY); | ||
91 | |||
92 | return (type == EV_KEY) ? KEY_CNT : SW_CNT; | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * gpio_keys_disable_button() - disables given GPIO button | ||
97 | * @bdata: button data for button to be disabled | ||
98 | * | ||
99 | * Disables button pointed by @bdata. This is done by masking | ||
100 | * IRQ line. After this function is called, button won't generate | ||
101 | * input events anymore. Note that one can only disable buttons | ||
102 | * that don't share IRQs. | ||
103 | * | ||
104 | * Make sure that @bdata->disable_lock is locked when entering | ||
105 | * this function to avoid races when concurrent threads are | ||
106 | * disabling buttons at the same time. | ||
107 | */ | ||
108 | static void gpio_keys_disable_button(struct gpio_button_data *bdata) | ||
109 | { | ||
110 | if (!bdata->disabled) { | ||
111 | /* | ||
112 | * Disable IRQ and possible debouncing timer. | ||
113 | */ | ||
114 | disable_irq(gpio_to_irq(bdata->button->gpio)); | ||
115 | if (bdata->timer_debounce) | ||
116 | del_timer_sync(&bdata->timer); | ||
117 | |||
118 | bdata->disabled = true; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * gpio_keys_enable_button() - enables given GPIO button | ||
124 | * @bdata: button data for button to be disabled | ||
125 | * | ||
126 | * Enables given button pointed by @bdata. | ||
127 | * | ||
128 | * Make sure that @bdata->disable_lock is locked when entering | ||
129 | * this function to avoid races with concurrent threads trying | ||
130 | * to enable the same button at the same time. | ||
131 | */ | ||
132 | static void gpio_keys_enable_button(struct gpio_button_data *bdata) | ||
133 | { | ||
134 | if (bdata->disabled) { | ||
135 | enable_irq(gpio_to_irq(bdata->button->gpio)); | ||
136 | bdata->disabled = false; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * gpio_keys_attr_show_helper() - fill in stringified bitmap of buttons | ||
142 | * @ddata: pointer to drvdata | ||
143 | * @buf: buffer where stringified bitmap is written | ||
144 | * @type: button type (%EV_KEY, %EV_SW) | ||
145 | * @only_disabled: does caller want only those buttons that are | ||
146 | * currently disabled or all buttons that can be | ||
147 | * disabled | ||
148 | * | ||
149 | * This function writes buttons that can be disabled to @buf. If | ||
150 | * @only_disabled is true, then @buf contains only those buttons | ||
151 | * that are currently disabled. Returns 0 on success or negative | ||
152 | * errno on failure. | ||
153 | */ | ||
154 | static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, | ||
155 | char *buf, unsigned int type, | ||
156 | bool only_disabled) | ||
157 | { | ||
158 | int n_events = get_n_events_by_type(type); | ||
159 | unsigned long *bits; | ||
160 | ssize_t ret; | ||
161 | int i; | ||
162 | |||
163 | bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); | ||
164 | if (!bits) | ||
165 | return -ENOMEM; | ||
166 | |||
167 | for (i = 0; i < ddata->n_buttons; i++) { | ||
168 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
169 | |||
170 | if (bdata->button->type != type) | ||
171 | continue; | ||
172 | |||
173 | if (only_disabled && !bdata->disabled) | ||
174 | continue; | ||
175 | |||
176 | __set_bit(bdata->button->code, bits); | ||
177 | } | ||
178 | |||
179 | ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events); | ||
180 | buf[ret++] = '\n'; | ||
181 | buf[ret] = '\0'; | ||
182 | |||
183 | kfree(bits); | ||
184 | |||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * gpio_keys_attr_store_helper() - enable/disable buttons based on given bitmap | ||
190 | * @ddata: pointer to drvdata | ||
191 | * @buf: buffer from userspace that contains stringified bitmap | ||
192 | * @type: button type (%EV_KEY, %EV_SW) | ||
193 | * | ||
194 | * This function parses stringified bitmap from @buf and disables/enables | ||
195 | * GPIO buttons accordinly. Returns 0 on success and negative error | ||
196 | * on failure. | ||
197 | */ | ||
198 | static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, | ||
199 | const char *buf, unsigned int type) | ||
200 | { | ||
201 | int n_events = get_n_events_by_type(type); | ||
202 | unsigned long *bits; | ||
203 | ssize_t error; | ||
204 | int i; | ||
205 | |||
206 | bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); | ||
207 | if (!bits) | ||
208 | return -ENOMEM; | ||
209 | |||
210 | error = bitmap_parselist(buf, bits, n_events); | ||
211 | if (error) | ||
212 | goto out; | ||
213 | |||
214 | /* First validate */ | ||
215 | for (i = 0; i < ddata->n_buttons; i++) { | ||
216 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
217 | |||
218 | if (bdata->button->type != type) | ||
219 | continue; | ||
220 | |||
221 | if (test_bit(bdata->button->code, bits) && | ||
222 | !bdata->button->can_disable) { | ||
223 | error = -EINVAL; | ||
224 | goto out; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | mutex_lock(&ddata->disable_lock); | ||
229 | |||
230 | for (i = 0; i < ddata->n_buttons; i++) { | ||
231 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
232 | |||
233 | if (bdata->button->type != type) | ||
234 | continue; | ||
235 | |||
236 | if (test_bit(bdata->button->code, bits)) | ||
237 | gpio_keys_disable_button(bdata); | ||
238 | else | ||
239 | gpio_keys_enable_button(bdata); | ||
240 | } | ||
241 | |||
242 | mutex_unlock(&ddata->disable_lock); | ||
243 | |||
244 | out: | ||
245 | kfree(bits); | ||
246 | return error; | ||
247 | } | ||
248 | |||
249 | #define ATTR_SHOW_FN(name, type, only_disabled) \ | ||
250 | static ssize_t gpio_keys_show_##name(struct device *dev, \ | ||
251 | struct device_attribute *attr, \ | ||
252 | char *buf) \ | ||
253 | { \ | ||
254 | struct platform_device *pdev = to_platform_device(dev); \ | ||
255 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ | ||
256 | \ | ||
257 | return gpio_keys_attr_show_helper(ddata, buf, \ | ||
258 | type, only_disabled); \ | ||
259 | } | ||
260 | |||
261 | ATTR_SHOW_FN(keys, EV_KEY, false); | ||
262 | ATTR_SHOW_FN(switches, EV_SW, false); | ||
263 | ATTR_SHOW_FN(disabled_keys, EV_KEY, true); | ||
264 | ATTR_SHOW_FN(disabled_switches, EV_SW, true); | ||
265 | |||
266 | /* | ||
267 | * ATTRIBUTES: | ||
268 | * | ||
269 | * /sys/devices/platform/gpio-keys/keys [ro] | ||
270 | * /sys/devices/platform/gpio-keys/switches [ro] | ||
271 | */ | ||
272 | static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL); | ||
273 | static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL); | ||
274 | |||
275 | #define ATTR_STORE_FN(name, type) \ | ||
276 | static ssize_t gpio_keys_store_##name(struct device *dev, \ | ||
277 | struct device_attribute *attr, \ | ||
278 | const char *buf, \ | ||
279 | size_t count) \ | ||
280 | { \ | ||
281 | struct platform_device *pdev = to_platform_device(dev); \ | ||
282 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ | ||
283 | ssize_t error; \ | ||
284 | \ | ||
285 | error = gpio_keys_attr_store_helper(ddata, buf, type); \ | ||
286 | if (error) \ | ||
287 | return error; \ | ||
288 | \ | ||
289 | return count; \ | ||
290 | } | ||
291 | |||
292 | ATTR_STORE_FN(disabled_keys, EV_KEY); | ||
293 | ATTR_STORE_FN(disabled_switches, EV_SW); | ||
294 | |||
295 | /* | ||
296 | * ATTRIBUTES: | ||
297 | * | ||
298 | * /sys/devices/platform/gpio-keys/disabled_keys [rw] | ||
299 | * /sys/devices/platform/gpio-keys/disables_switches [rw] | ||
300 | */ | ||
301 | static DEVICE_ATTR(disabled_keys, S_IWUSR | S_IRUGO, | ||
302 | gpio_keys_show_disabled_keys, | ||
303 | gpio_keys_store_disabled_keys); | ||
304 | static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO, | ||
305 | gpio_keys_show_disabled_switches, | ||
306 | gpio_keys_store_disabled_switches); | ||
307 | |||
308 | static struct attribute *gpio_keys_attrs[] = { | ||
309 | &dev_attr_keys.attr, | ||
310 | &dev_attr_switches.attr, | ||
311 | &dev_attr_disabled_keys.attr, | ||
312 | &dev_attr_disabled_switches.attr, | ||
313 | NULL, | ||
314 | }; | ||
315 | |||
316 | static struct attribute_group gpio_keys_attr_group = { | ||
317 | .attrs = gpio_keys_attrs, | ||
318 | }; | ||
319 | |||
40 | static void gpio_keys_report_event(struct gpio_button_data *bdata) | 320 | static void gpio_keys_report_event(struct gpio_button_data *bdata) |
41 | { | 321 | { |
42 | struct gpio_keys_button *button = bdata->button; | 322 | struct gpio_keys_button *button = bdata->button; |
@@ -70,20 +350,22 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
70 | 350 | ||
71 | BUG_ON(irq != gpio_to_irq(button->gpio)); | 351 | BUG_ON(irq != gpio_to_irq(button->gpio)); |
72 | 352 | ||
73 | if (button->debounce_interval) | 353 | if (bdata->timer_debounce) |
74 | mod_timer(&bdata->timer, | 354 | mod_timer(&bdata->timer, |
75 | jiffies + msecs_to_jiffies(button->debounce_interval)); | 355 | jiffies + msecs_to_jiffies(bdata->timer_debounce)); |
76 | else | 356 | else |
77 | schedule_work(&bdata->work); | 357 | schedule_work(&bdata->work); |
78 | 358 | ||
79 | return IRQ_HANDLED; | 359 | return IRQ_HANDLED; |
80 | } | 360 | } |
81 | 361 | ||
82 | static int __devinit gpio_keys_setup_key(struct device *dev, | 362 | static int __devinit gpio_keys_setup_key(struct platform_device *pdev, |
83 | struct gpio_button_data *bdata, | 363 | struct gpio_button_data *bdata, |
84 | struct gpio_keys_button *button) | 364 | struct gpio_keys_button *button) |
85 | { | 365 | { |
86 | char *desc = button->desc ? button->desc : "gpio_keys"; | 366 | char *desc = button->desc ? button->desc : "gpio_keys"; |
367 | struct device *dev = &pdev->dev; | ||
368 | unsigned long irqflags; | ||
87 | int irq, error; | 369 | int irq, error; |
88 | 370 | ||
89 | setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); | 371 | setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); |
@@ -104,6 +386,14 @@ static int __devinit gpio_keys_setup_key(struct device *dev, | |||
104 | goto fail3; | 386 | goto fail3; |
105 | } | 387 | } |
106 | 388 | ||
389 | if (button->debounce_interval) { | ||
390 | error = gpio_set_debounce(button->gpio, | ||
391 | button->debounce_interval * 1000); | ||
392 | /* use timer if gpiolib doesn't provide debounce */ | ||
393 | if (error < 0) | ||
394 | bdata->timer_debounce = button->debounce_interval; | ||
395 | } | ||
396 | |||
107 | irq = gpio_to_irq(button->gpio); | 397 | irq = gpio_to_irq(button->gpio); |
108 | if (irq < 0) { | 398 | if (irq < 0) { |
109 | error = irq; | 399 | error = irq; |
@@ -112,10 +402,15 @@ static int __devinit gpio_keys_setup_key(struct device *dev, | |||
112 | goto fail3; | 402 | goto fail3; |
113 | } | 403 | } |
114 | 404 | ||
115 | error = request_irq(irq, gpio_keys_isr, | 405 | irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; |
116 | IRQF_SHARED | | 406 | /* |
117 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 407 | * If platform has specified that the button can be disabled, |
118 | desc, bdata); | 408 | * we don't want it to share the interrupt line. |
409 | */ | ||
410 | if (!button->can_disable) | ||
411 | irqflags |= IRQF_SHARED; | ||
412 | |||
413 | error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata); | ||
119 | if (error) { | 414 | if (error) { |
120 | dev_err(dev, "Unable to claim irq %d; error %d\n", | 415 | dev_err(dev, "Unable to claim irq %d; error %d\n", |
121 | irq, error); | 416 | irq, error); |
@@ -130,6 +425,21 @@ fail2: | |||
130 | return error; | 425 | return error; |
131 | } | 426 | } |
132 | 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 | |||
133 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 443 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
134 | { | 444 | { |
135 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 445 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
@@ -149,11 +459,20 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
149 | goto fail1; | 459 | goto fail1; |
150 | } | 460 | } |
151 | 461 | ||
462 | ddata->input = input; | ||
463 | ddata->n_buttons = pdata->nbuttons; | ||
464 | ddata->enable = pdata->enable; | ||
465 | ddata->disable = pdata->disable; | ||
466 | mutex_init(&ddata->disable_lock); | ||
467 | |||
152 | platform_set_drvdata(pdev, ddata); | 468 | platform_set_drvdata(pdev, ddata); |
469 | input_set_drvdata(input, ddata); | ||
153 | 470 | ||
154 | input->name = pdev->name; | 471 | input->name = pdev->name; |
155 | input->phys = "gpio-keys/input0"; | 472 | input->phys = "gpio-keys/input0"; |
156 | input->dev.parent = &pdev->dev; | 473 | input->dev.parent = &pdev->dev; |
474 | input->open = gpio_keys_open; | ||
475 | input->close = gpio_keys_close; | ||
157 | 476 | ||
158 | input->id.bustype = BUS_HOST; | 477 | input->id.bustype = BUS_HOST; |
159 | input->id.vendor = 0x0001; | 478 | input->id.vendor = 0x0001; |
@@ -164,8 +483,6 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
164 | if (pdata->rep) | 483 | if (pdata->rep) |
165 | __set_bit(EV_REP, input->evbit); | 484 | __set_bit(EV_REP, input->evbit); |
166 | 485 | ||
167 | ddata->input = input; | ||
168 | |||
169 | for (i = 0; i < pdata->nbuttons; i++) { | 486 | for (i = 0; i < pdata->nbuttons; i++) { |
170 | struct gpio_keys_button *button = &pdata->buttons[i]; | 487 | struct gpio_keys_button *button = &pdata->buttons[i]; |
171 | struct gpio_button_data *bdata = &ddata->data[i]; | 488 | struct gpio_button_data *bdata = &ddata->data[i]; |
@@ -174,7 +491,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
174 | bdata->input = input; | 491 | bdata->input = input; |
175 | bdata->button = button; | 492 | bdata->button = button; |
176 | 493 | ||
177 | error = gpio_keys_setup_key(dev, bdata, button); | 494 | error = gpio_keys_setup_key(pdev, bdata, button); |
178 | if (error) | 495 | if (error) |
179 | goto fail2; | 496 | goto fail2; |
180 | 497 | ||
@@ -184,13 +501,20 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
184 | input_set_capability(input, type, button->code); | 501 | input_set_capability(input, type, button->code); |
185 | } | 502 | } |
186 | 503 | ||
187 | error = input_register_device(input); | 504 | error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); |
188 | if (error) { | 505 | if (error) { |
189 | dev_err(dev, "Unable to register input device, " | 506 | dev_err(dev, "Unable to export keys/switches, error: %d\n", |
190 | "error: %d\n", error); | 507 | error); |
191 | goto fail2; | 508 | goto fail2; |
192 | } | 509 | } |
193 | 510 | ||
511 | error = input_register_device(input); | ||
512 | if (error) { | ||
513 | dev_err(dev, "Unable to register input device, error: %d\n", | ||
514 | error); | ||
515 | goto fail3; | ||
516 | } | ||
517 | |||
194 | /* get current state of buttons */ | 518 | /* get current state of buttons */ |
195 | for (i = 0; i < pdata->nbuttons; i++) | 519 | for (i = 0; i < pdata->nbuttons; i++) |
196 | gpio_keys_report_event(&ddata->data[i]); | 520 | gpio_keys_report_event(&ddata->data[i]); |
@@ -200,10 +524,12 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
200 | 524 | ||
201 | return 0; | 525 | return 0; |
202 | 526 | ||
527 | fail3: | ||
528 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | ||
203 | fail2: | 529 | fail2: |
204 | while (--i >= 0) { | 530 | while (--i >= 0) { |
205 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); | 531 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); |
206 | if (pdata->buttons[i].debounce_interval) | 532 | if (ddata->data[i].timer_debounce) |
207 | del_timer_sync(&ddata->data[i].timer); | 533 | del_timer_sync(&ddata->data[i].timer); |
208 | cancel_work_sync(&ddata->data[i].work); | 534 | cancel_work_sync(&ddata->data[i].work); |
209 | gpio_free(pdata->buttons[i].gpio); | 535 | gpio_free(pdata->buttons[i].gpio); |
@@ -224,12 +550,14 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
224 | struct input_dev *input = ddata->input; | 550 | struct input_dev *input = ddata->input; |
225 | int i; | 551 | int i; |
226 | 552 | ||
553 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | ||
554 | |||
227 | device_init_wakeup(&pdev->dev, 0); | 555 | device_init_wakeup(&pdev->dev, 0); |
228 | 556 | ||
229 | for (i = 0; i < pdata->nbuttons; i++) { | 557 | for (i = 0; i < pdata->nbuttons; i++) { |
230 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | 558 | int irq = gpio_to_irq(pdata->buttons[i].gpio); |
231 | free_irq(irq, &ddata->data[i]); | 559 | free_irq(irq, &ddata->data[i]); |
232 | if (pdata->buttons[i].debounce_interval) | 560 | if (ddata->data[i].timer_debounce) |
233 | del_timer_sync(&ddata->data[i].timer); | 561 | del_timer_sync(&ddata->data[i].timer); |
234 | cancel_work_sync(&ddata->data[i].work); | 562 | cancel_work_sync(&ddata->data[i].work); |
235 | gpio_free(pdata->buttons[i].gpio); | 563 | gpio_free(pdata->buttons[i].gpio); |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index c83f4b2ec7d3..fed31e0947a1 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_get_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_get_max(dev, ABS_X + i)) |
238 | dev->absmax[ABS_X + i] = val; | 238 | input_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_get_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_get_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_get_min(input_dev, ABS_X + i) + diff); |
394 | input_abs_set_max(input_dev, ABS_X + i, | ||
395 | input_abs_get_max(input_dev, ABS_X + i) - diff); | ||
393 | } | 396 | } |
394 | #endif | 397 | #endif |
395 | 398 | ||
@@ -567,6 +570,8 @@ static struct serio_device_id hil_dev_ids[] = { | |||
567 | { 0 } | 570 | { 0 } |
568 | }; | 571 | }; |
569 | 572 | ||
573 | MODULE_DEVICE_TABLE(serio, hil_dev_ids); | ||
574 | |||
570 | static struct serio_driver hil_serio_drv = { | 575 | static struct serio_driver hil_serio_drv = { |
571 | .driver = { | 576 | .driver = { |
572 | .name = "hil_dev", | 577 | .name = "hil_dev", |
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c new file mode 100644 index 000000000000..d92c15c39e68 --- /dev/null +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -0,0 +1,595 @@ | |||
1 | /* | ||
2 | * Driver for the IMX keypad port. | ||
3 | * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * <<Power management needs to be implemented>>. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input/matrix_keypad.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/jiffies.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/timer.h> | ||
26 | |||
27 | /* | ||
28 | * Keypad Controller registers (halfword) | ||
29 | */ | ||
30 | #define KPCR 0x00 /* Keypad Control Register */ | ||
31 | |||
32 | #define KPSR 0x02 /* Keypad Status Register */ | ||
33 | #define KBD_STAT_KPKD (0x1 << 0) /* Key Press Interrupt Status bit (w1c) */ | ||
34 | #define KBD_STAT_KPKR (0x1 << 1) /* Key Release Interrupt Status bit (w1c) */ | ||
35 | #define KBD_STAT_KDSC (0x1 << 2) /* Key Depress Synch Chain Status bit (w1c)*/ | ||
36 | #define KBD_STAT_KRSS (0x1 << 3) /* Key Release Synch Status bit (w1c)*/ | ||
37 | #define KBD_STAT_KDIE (0x1 << 8) /* Key Depress Interrupt Enable Status bit */ | ||
38 | #define KBD_STAT_KRIE (0x1 << 9) /* Key Release Interrupt Enable */ | ||
39 | #define KBD_STAT_KPPEN (0x1 << 10) /* Keypad Clock Enable */ | ||
40 | |||
41 | #define KDDR 0x04 /* Keypad Data Direction Register */ | ||
42 | #define KPDR 0x06 /* Keypad Data Register */ | ||
43 | |||
44 | #define MAX_MATRIX_KEY_ROWS 8 | ||
45 | #define MAX_MATRIX_KEY_COLS 8 | ||
46 | #define MATRIX_ROW_SHIFT 3 | ||
47 | |||
48 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) | ||
49 | |||
50 | struct imx_keypad { | ||
51 | |||
52 | struct clk *clk; | ||
53 | struct input_dev *input_dev; | ||
54 | void __iomem *mmio_base; | ||
55 | |||
56 | int irq; | ||
57 | struct timer_list check_matrix_timer; | ||
58 | |||
59 | /* | ||
60 | * The matrix is stable only if no changes are detected after | ||
61 | * IMX_KEYPAD_SCANS_FOR_STABILITY scans | ||
62 | */ | ||
63 | #define IMX_KEYPAD_SCANS_FOR_STABILITY 3 | ||
64 | int stable_count; | ||
65 | |||
66 | bool enabled; | ||
67 | |||
68 | /* Masks for enabled rows/cols */ | ||
69 | unsigned short rows_en_mask; | ||
70 | unsigned short cols_en_mask; | ||
71 | |||
72 | unsigned short keycodes[MAX_MATRIX_KEY_NUM]; | ||
73 | |||
74 | /* | ||
75 | * Matrix states: | ||
76 | * -stable: achieved after a complete debounce process. | ||
77 | * -unstable: used in the debouncing process. | ||
78 | */ | ||
79 | unsigned short matrix_stable_state[MAX_MATRIX_KEY_COLS]; | ||
80 | unsigned short matrix_unstable_state[MAX_MATRIX_KEY_COLS]; | ||
81 | }; | ||
82 | |||
83 | /* Scan the matrix and return the new state in *matrix_volatile_state. */ | ||
84 | static void imx_keypad_scan_matrix(struct imx_keypad *keypad, | ||
85 | unsigned short *matrix_volatile_state) | ||
86 | { | ||
87 | int col; | ||
88 | unsigned short reg_val; | ||
89 | |||
90 | for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { | ||
91 | if ((keypad->cols_en_mask & (1 << col)) == 0) | ||
92 | continue; | ||
93 | /* | ||
94 | * Discharge keypad capacitance: | ||
95 | * 2. write 1s on column data. | ||
96 | * 3. configure columns as totem-pole to discharge capacitance. | ||
97 | * 4. configure columns as open-drain. | ||
98 | */ | ||
99 | reg_val = readw(keypad->mmio_base + KPDR); | ||
100 | reg_val |= 0xff00; | ||
101 | writew(reg_val, keypad->mmio_base + KPDR); | ||
102 | |||
103 | reg_val = readw(keypad->mmio_base + KPCR); | ||
104 | reg_val &= ~((keypad->cols_en_mask & 0xff) << 8); | ||
105 | writew(reg_val, keypad->mmio_base + KPCR); | ||
106 | |||
107 | udelay(2); | ||
108 | |||
109 | reg_val = readw(keypad->mmio_base + KPCR); | ||
110 | reg_val |= (keypad->cols_en_mask & 0xff) << 8; | ||
111 | writew(reg_val, keypad->mmio_base + KPCR); | ||
112 | |||
113 | /* | ||
114 | * 5. Write a single column to 0, others to 1. | ||
115 | * 6. Sample row inputs and save data. | ||
116 | * 7. Repeat steps 2 - 6 for remaining columns. | ||
117 | */ | ||
118 | reg_val = readw(keypad->mmio_base + KPDR); | ||
119 | reg_val &= ~(1 << (8 + col)); | ||
120 | writew(reg_val, keypad->mmio_base + KPDR); | ||
121 | |||
122 | /* | ||
123 | * Delay added to avoid propagating the 0 from column to row | ||
124 | * when scanning. | ||
125 | */ | ||
126 | udelay(5); | ||
127 | |||
128 | /* | ||
129 | * 1s in matrix_volatile_state[col] means key pressures | ||
130 | * throw data from non enabled rows. | ||
131 | */ | ||
132 | reg_val = readw(keypad->mmio_base + KPDR); | ||
133 | matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Return in standby mode: | ||
138 | * 9. write 0s to columns | ||
139 | */ | ||
140 | reg_val = readw(keypad->mmio_base + KPDR); | ||
141 | reg_val &= 0x00ff; | ||
142 | writew(reg_val, keypad->mmio_base + KPDR); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Compare the new matrix state (volatile) with the stable one stored in | ||
147 | * keypad->matrix_stable_state and fire events if changes are detected. | ||
148 | */ | ||
149 | static void imx_keypad_fire_events(struct imx_keypad *keypad, | ||
150 | unsigned short *matrix_volatile_state) | ||
151 | { | ||
152 | struct input_dev *input_dev = keypad->input_dev; | ||
153 | int row, col; | ||
154 | |||
155 | for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { | ||
156 | unsigned short bits_changed; | ||
157 | int code; | ||
158 | |||
159 | if ((keypad->cols_en_mask & (1 << col)) == 0) | ||
160 | continue; /* Column is not enabled */ | ||
161 | |||
162 | bits_changed = keypad->matrix_stable_state[col] ^ | ||
163 | matrix_volatile_state[col]; | ||
164 | |||
165 | if (bits_changed == 0) | ||
166 | continue; /* Column does not contain changes */ | ||
167 | |||
168 | for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) { | ||
169 | if ((keypad->rows_en_mask & (1 << row)) == 0) | ||
170 | continue; /* Row is not enabled */ | ||
171 | if ((bits_changed & (1 << row)) == 0) | ||
172 | continue; /* Row does not contain changes */ | ||
173 | |||
174 | code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); | ||
175 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
176 | input_report_key(input_dev, keypad->keycodes[code], | ||
177 | matrix_volatile_state[col] & (1 << row)); | ||
178 | dev_dbg(&input_dev->dev, "Event code: %d, val: %d", | ||
179 | keypad->keycodes[code], | ||
180 | matrix_volatile_state[col] & (1 << row)); | ||
181 | } | ||
182 | } | ||
183 | input_sync(input_dev); | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * imx_keypad_check_for_events is the timer handler. | ||
188 | */ | ||
189 | static void imx_keypad_check_for_events(unsigned long data) | ||
190 | { | ||
191 | struct imx_keypad *keypad = (struct imx_keypad *) data; | ||
192 | unsigned short matrix_volatile_state[MAX_MATRIX_KEY_COLS]; | ||
193 | unsigned short reg_val; | ||
194 | bool state_changed, is_zero_matrix; | ||
195 | int i; | ||
196 | |||
197 | memset(matrix_volatile_state, 0, sizeof(matrix_volatile_state)); | ||
198 | |||
199 | imx_keypad_scan_matrix(keypad, matrix_volatile_state); | ||
200 | |||
201 | state_changed = false; | ||
202 | for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { | ||
203 | if ((keypad->cols_en_mask & (1 << i)) == 0) | ||
204 | continue; | ||
205 | |||
206 | if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) { | ||
207 | state_changed = true; | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * If the matrix state is changed from the previous scan | ||
214 | * (Re)Begin the debouncing process, saving the new state in | ||
215 | * keypad->matrix_unstable_state. | ||
216 | * else | ||
217 | * Increase the count of number of scans with a stable state. | ||
218 | */ | ||
219 | if (state_changed) { | ||
220 | memcpy(keypad->matrix_unstable_state, matrix_volatile_state, | ||
221 | sizeof(matrix_volatile_state)); | ||
222 | keypad->stable_count = 0; | ||
223 | } else | ||
224 | keypad->stable_count++; | ||
225 | |||
226 | /* | ||
227 | * If the matrix is not as stable as we want reschedule scan | ||
228 | * in the near future. | ||
229 | */ | ||
230 | if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) { | ||
231 | mod_timer(&keypad->check_matrix_timer, | ||
232 | jiffies + msecs_to_jiffies(10)); | ||
233 | return; | ||
234 | } | ||
235 | |||
236 | /* | ||
237 | * If the matrix state is stable, fire the events and save the new | ||
238 | * stable state. Note, if the matrix is kept stable for longer | ||
239 | * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all | ||
240 | * events have already been generated. | ||
241 | */ | ||
242 | if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) { | ||
243 | imx_keypad_fire_events(keypad, matrix_volatile_state); | ||
244 | |||
245 | memcpy(keypad->matrix_stable_state, matrix_volatile_state, | ||
246 | sizeof(matrix_volatile_state)); | ||
247 | } | ||
248 | |||
249 | is_zero_matrix = true; | ||
250 | for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { | ||
251 | if (matrix_volatile_state[i] != 0) { | ||
252 | is_zero_matrix = false; | ||
253 | break; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | |||
258 | if (is_zero_matrix) { | ||
259 | /* | ||
260 | * All keys have been released. Enable only the KDI | ||
261 | * interrupt for future key presses (clear the KDI | ||
262 | * status bit and its sync chain before that). | ||
263 | */ | ||
264 | reg_val = readw(keypad->mmio_base + KPSR); | ||
265 | reg_val |= KBD_STAT_KPKD | KBD_STAT_KDSC; | ||
266 | writew(reg_val, keypad->mmio_base + KPSR); | ||
267 | |||
268 | reg_val = readw(keypad->mmio_base + KPSR); | ||
269 | reg_val |= KBD_STAT_KDIE; | ||
270 | reg_val &= ~KBD_STAT_KRIE; | ||
271 | writew(reg_val, keypad->mmio_base + KPSR); | ||
272 | } else { | ||
273 | /* | ||
274 | * Some keys are still pressed. Schedule a rescan in | ||
275 | * attempt to detect multiple key presses and enable | ||
276 | * the KRI interrupt to react quickly to key release | ||
277 | * event. | ||
278 | */ | ||
279 | mod_timer(&keypad->check_matrix_timer, | ||
280 | jiffies + msecs_to_jiffies(60)); | ||
281 | |||
282 | reg_val = readw(keypad->mmio_base + KPSR); | ||
283 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KRSS; | ||
284 | writew(reg_val, keypad->mmio_base + KPSR); | ||
285 | |||
286 | reg_val = readw(keypad->mmio_base + KPSR); | ||
287 | reg_val |= KBD_STAT_KRIE; | ||
288 | reg_val &= ~KBD_STAT_KDIE; | ||
289 | writew(reg_val, keypad->mmio_base + KPSR); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | static irqreturn_t imx_keypad_irq_handler(int irq, void *dev_id) | ||
294 | { | ||
295 | struct imx_keypad *keypad = dev_id; | ||
296 | unsigned short reg_val; | ||
297 | |||
298 | reg_val = readw(keypad->mmio_base + KPSR); | ||
299 | |||
300 | /* Disable both interrupt types */ | ||
301 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | ||
302 | /* Clear interrupts status bits */ | ||
303 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; | ||
304 | writew(reg_val, keypad->mmio_base + KPSR); | ||
305 | |||
306 | if (keypad->enabled) { | ||
307 | /* The matrix is supposed to be changed */ | ||
308 | keypad->stable_count = 0; | ||
309 | |||
310 | /* Schedule the scanning procedure near in the future */ | ||
311 | mod_timer(&keypad->check_matrix_timer, | ||
312 | jiffies + msecs_to_jiffies(2)); | ||
313 | } | ||
314 | |||
315 | return IRQ_HANDLED; | ||
316 | } | ||
317 | |||
318 | static void imx_keypad_config(struct imx_keypad *keypad) | ||
319 | { | ||
320 | unsigned short reg_val; | ||
321 | |||
322 | /* | ||
323 | * Include enabled rows in interrupt generation (KPCR[7:0]) | ||
324 | * Configure keypad columns as open-drain (KPCR[15:8]) | ||
325 | */ | ||
326 | reg_val = readw(keypad->mmio_base + KPCR); | ||
327 | reg_val |= keypad->rows_en_mask & 0xff; /* rows */ | ||
328 | reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */ | ||
329 | writew(reg_val, keypad->mmio_base + KPCR); | ||
330 | |||
331 | /* Write 0's to KPDR[15:8] (Colums) */ | ||
332 | reg_val = readw(keypad->mmio_base + KPDR); | ||
333 | reg_val &= 0x00ff; | ||
334 | writew(reg_val, keypad->mmio_base + KPDR); | ||
335 | |||
336 | /* Configure columns as output, rows as input (KDDR[15:0]) */ | ||
337 | writew(0xff00, keypad->mmio_base + KDDR); | ||
338 | |||
339 | /* | ||
340 | * Clear Key Depress and Key Release status bit. | ||
341 | * Clear both synchronizer chain. | ||
342 | */ | ||
343 | reg_val = readw(keypad->mmio_base + KPSR); | ||
344 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD | | ||
345 | KBD_STAT_KDSC | KBD_STAT_KRSS; | ||
346 | writew(reg_val, keypad->mmio_base + KPSR); | ||
347 | |||
348 | /* Enable KDI and disable KRI (avoid false release events). */ | ||
349 | reg_val |= KBD_STAT_KDIE; | ||
350 | reg_val &= ~KBD_STAT_KRIE; | ||
351 | writew(reg_val, keypad->mmio_base + KPSR); | ||
352 | } | ||
353 | |||
354 | static void imx_keypad_inhibit(struct imx_keypad *keypad) | ||
355 | { | ||
356 | unsigned short reg_val; | ||
357 | |||
358 | /* Inhibit KDI and KRI interrupts. */ | ||
359 | reg_val = readw(keypad->mmio_base + KPSR); | ||
360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | ||
361 | writew(reg_val, keypad->mmio_base + KPSR); | ||
362 | |||
363 | /* Colums as open drain and disable all rows */ | ||
364 | writew(0xff00, keypad->mmio_base + KPCR); | ||
365 | } | ||
366 | |||
367 | static void imx_keypad_close(struct input_dev *dev) | ||
368 | { | ||
369 | struct imx_keypad *keypad = input_get_drvdata(dev); | ||
370 | |||
371 | dev_dbg(&dev->dev, ">%s\n", __func__); | ||
372 | |||
373 | /* Mark keypad as being inactive */ | ||
374 | keypad->enabled = false; | ||
375 | synchronize_irq(keypad->irq); | ||
376 | del_timer_sync(&keypad->check_matrix_timer); | ||
377 | |||
378 | imx_keypad_inhibit(keypad); | ||
379 | |||
380 | /* Disable clock unit */ | ||
381 | clk_disable(keypad->clk); | ||
382 | } | ||
383 | |||
384 | static int imx_keypad_open(struct input_dev *dev) | ||
385 | { | ||
386 | struct imx_keypad *keypad = input_get_drvdata(dev); | ||
387 | |||
388 | dev_dbg(&dev->dev, ">%s\n", __func__); | ||
389 | |||
390 | /* We became active from now */ | ||
391 | keypad->enabled = true; | ||
392 | |||
393 | /* Enable the kpp clock */ | ||
394 | clk_enable(keypad->clk); | ||
395 | imx_keypad_config(keypad); | ||
396 | |||
397 | /* Sanity control, not all the rows must be actived now. */ | ||
398 | if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) { | ||
399 | dev_err(&dev->dev, | ||
400 | "too many keys pressed, control pins initialisation\n"); | ||
401 | goto open_err; | ||
402 | } | ||
403 | |||
404 | return 0; | ||
405 | |||
406 | open_err: | ||
407 | imx_keypad_close(dev); | ||
408 | return -EIO; | ||
409 | } | ||
410 | |||
411 | static int __devinit imx_keypad_probe(struct platform_device *pdev) | ||
412 | { | ||
413 | const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; | ||
414 | struct imx_keypad *keypad; | ||
415 | struct input_dev *input_dev; | ||
416 | struct resource *res; | ||
417 | int irq, error, i; | ||
418 | |||
419 | if (keymap_data == NULL) { | ||
420 | dev_err(&pdev->dev, "no keymap defined\n"); | ||
421 | return -EINVAL; | ||
422 | } | ||
423 | |||
424 | irq = platform_get_irq(pdev, 0); | ||
425 | if (irq < 0) { | ||
426 | dev_err(&pdev->dev, "no irq defined in platform data\n"); | ||
427 | return -EINVAL; | ||
428 | } | ||
429 | |||
430 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
431 | if (res == NULL) { | ||
432 | dev_err(&pdev->dev, "no I/O memory defined in platform data\n"); | ||
433 | return -EINVAL; | ||
434 | } | ||
435 | |||
436 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
437 | if (res == NULL) { | ||
438 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
439 | return -EBUSY; | ||
440 | } | ||
441 | |||
442 | input_dev = input_allocate_device(); | ||
443 | if (!input_dev) { | ||
444 | dev_err(&pdev->dev, "failed to allocate the input device\n"); | ||
445 | error = -ENOMEM; | ||
446 | goto failed_rel_mem; | ||
447 | } | ||
448 | |||
449 | keypad = kzalloc(sizeof(struct imx_keypad), GFP_KERNEL); | ||
450 | if (!keypad) { | ||
451 | dev_err(&pdev->dev, "not enough memory for driver data\n"); | ||
452 | error = -ENOMEM; | ||
453 | goto failed_free_input; | ||
454 | } | ||
455 | |||
456 | keypad->input_dev = input_dev; | ||
457 | keypad->irq = irq; | ||
458 | keypad->stable_count = 0; | ||
459 | |||
460 | setup_timer(&keypad->check_matrix_timer, | ||
461 | imx_keypad_check_for_events, (unsigned long) keypad); | ||
462 | |||
463 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | ||
464 | if (keypad->mmio_base == NULL) { | ||
465 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
466 | error = -ENOMEM; | ||
467 | goto failed_free_priv; | ||
468 | } | ||
469 | |||
470 | keypad->clk = clk_get(&pdev->dev, "kpp"); | ||
471 | if (IS_ERR(keypad->clk)) { | ||
472 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | ||
473 | error = PTR_ERR(keypad->clk); | ||
474 | goto failed_unmap; | ||
475 | } | ||
476 | |||
477 | /* Search for rows and cols enabled */ | ||
478 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
479 | keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]); | ||
480 | keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]); | ||
481 | } | ||
482 | |||
483 | if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || | ||
484 | keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { | ||
485 | dev_err(&pdev->dev, | ||
486 | "invalid key data (too many rows or colums)\n"); | ||
487 | error = -EINVAL; | ||
488 | goto failed_clock_put; | ||
489 | } | ||
490 | dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); | ||
491 | dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); | ||
492 | |||
493 | /* Init the Input device */ | ||
494 | input_dev->name = pdev->name; | ||
495 | input_dev->id.bustype = BUS_HOST; | ||
496 | input_dev->dev.parent = &pdev->dev; | ||
497 | input_dev->open = imx_keypad_open; | ||
498 | input_dev->close = imx_keypad_close; | ||
499 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
500 | input_dev->keycode = keypad->keycodes; | ||
501 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
502 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
503 | |||
504 | matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, | ||
505 | keypad->keycodes, input_dev->keybit); | ||
506 | |||
507 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
508 | input_set_drvdata(input_dev, keypad); | ||
509 | |||
510 | /* Ensure that the keypad will stay dormant until opened */ | ||
511 | imx_keypad_inhibit(keypad); | ||
512 | |||
513 | error = request_irq(irq, imx_keypad_irq_handler, IRQF_DISABLED, | ||
514 | pdev->name, keypad); | ||
515 | if (error) { | ||
516 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
517 | goto failed_clock_put; | ||
518 | } | ||
519 | |||
520 | /* Register the input device */ | ||
521 | error = input_register_device(input_dev); | ||
522 | if (error) { | ||
523 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
524 | goto failed_free_irq; | ||
525 | } | ||
526 | |||
527 | platform_set_drvdata(pdev, keypad); | ||
528 | device_init_wakeup(&pdev->dev, 1); | ||
529 | |||
530 | return 0; | ||
531 | |||
532 | failed_free_irq: | ||
533 | free_irq(irq, pdev); | ||
534 | failed_clock_put: | ||
535 | clk_put(keypad->clk); | ||
536 | failed_unmap: | ||
537 | iounmap(keypad->mmio_base); | ||
538 | failed_free_priv: | ||
539 | kfree(keypad); | ||
540 | failed_free_input: | ||
541 | input_free_device(input_dev); | ||
542 | failed_rel_mem: | ||
543 | release_mem_region(res->start, resource_size(res)); | ||
544 | return error; | ||
545 | } | ||
546 | |||
547 | static int __devexit imx_keypad_remove(struct platform_device *pdev) | ||
548 | { | ||
549 | struct imx_keypad *keypad = platform_get_drvdata(pdev); | ||
550 | struct resource *res; | ||
551 | |||
552 | dev_dbg(&pdev->dev, ">%s\n", __func__); | ||
553 | |||
554 | platform_set_drvdata(pdev, NULL); | ||
555 | |||
556 | input_unregister_device(keypad->input_dev); | ||
557 | |||
558 | free_irq(keypad->irq, keypad); | ||
559 | clk_put(keypad->clk); | ||
560 | |||
561 | iounmap(keypad->mmio_base); | ||
562 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
563 | release_mem_region(res->start, resource_size(res)); | ||
564 | |||
565 | kfree(keypad); | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | static struct platform_driver imx_keypad_driver = { | ||
571 | .driver = { | ||
572 | .name = "imx-keypad", | ||
573 | .owner = THIS_MODULE, | ||
574 | }, | ||
575 | .probe = imx_keypad_probe, | ||
576 | .remove = __devexit_p(imx_keypad_remove), | ||
577 | }; | ||
578 | |||
579 | static int __init imx_keypad_init(void) | ||
580 | { | ||
581 | return platform_driver_register(&imx_keypad_driver); | ||
582 | } | ||
583 | |||
584 | static void __exit imx_keypad_exit(void) | ||
585 | { | ||
586 | platform_driver_unregister(&imx_keypad_driver); | ||
587 | } | ||
588 | |||
589 | module_init(imx_keypad_init); | ||
590 | module_exit(imx_keypad_exit); | ||
591 | |||
592 | MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>"); | ||
593 | MODULE_DESCRIPTION("IMX Keypad Port Driver"); | ||
594 | MODULE_LICENSE("GPL v2"); | ||
595 | MODULE_ALIAS("platform:imx-keypad"); | ||
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 781fc6102860..7197c5698747 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | ||
27 | 28 | ||
28 | #include <asm/delay.h> | 29 | #include <asm/delay.h> |
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
@@ -138,35 +139,35 @@ static void jornada_scan_keyb(unsigned char *s) | |||
138 | }, *y = matrix_PDE; | 139 | }, *y = matrix_PDE; |
139 | 140 | ||
140 | /* Save these control reg bits */ | 141 | /* Save these control reg bits */ |
141 | dc_static = (ctrl_inw(PDCR) & (~0xcc0c)); | 142 | dc_static = (__raw_readw(PDCR) & (~0xcc0c)); |
142 | ec_static = (ctrl_inw(PECR) & (~0xf0cf)); | 143 | ec_static = (__raw_readw(PECR) & (~0xf0cf)); |
143 | 144 | ||
144 | for (i = 0; i < 8; i++) { | 145 | for (i = 0; i < 8; i++) { |
145 | /* disable output for all but the one we want to scan */ | 146 | /* disable output for all but the one we want to scan */ |
146 | ctrl_outw((dc_static | *y++), PDCR); | 147 | __raw_writew((dc_static | *y++), PDCR); |
147 | ctrl_outw((ec_static | *y++), PECR); | 148 | __raw_writew((ec_static | *y++), PECR); |
148 | udelay(5); | 149 | udelay(5); |
149 | 150 | ||
150 | /* Get scanline row */ | 151 | /* Get scanline row */ |
151 | ctrl_outb(*t++, PDDR); | 152 | __raw_writeb(*t++, PDDR); |
152 | ctrl_outb(*t++, PEDR); | 153 | __raw_writeb(*t++, PEDR); |
153 | udelay(50); | 154 | udelay(50); |
154 | 155 | ||
155 | /* Read data */ | 156 | /* Read data */ |
156 | *s++ = ctrl_inb(PCDR); | 157 | *s++ = __raw_readb(PCDR); |
157 | *s++ = ctrl_inb(PFDR); | 158 | *s++ = __raw_readb(PFDR); |
158 | } | 159 | } |
159 | /* Scan no lines */ | 160 | /* Scan no lines */ |
160 | ctrl_outb(0xff, PDDR); | 161 | __raw_writeb(0xff, PDDR); |
161 | ctrl_outb(0xff, PEDR); | 162 | __raw_writeb(0xff, PEDR); |
162 | 163 | ||
163 | /* Enable all scanlines */ | 164 | /* Enable all scanlines */ |
164 | ctrl_outw((dc_static | (0x5555 & 0xcc0c)),PDCR); | 165 | __raw_writew((dc_static | (0x5555 & 0xcc0c)),PDCR); |
165 | ctrl_outw((ec_static | (0x5555 & 0xf0cf)),PECR); | 166 | __raw_writew((ec_static | (0x5555 & 0xf0cf)),PECR); |
166 | 167 | ||
167 | /* Ignore extra keys and events */ | 168 | /* Ignore extra keys and events */ |
168 | *s++ = ctrl_inb(PGDR); | 169 | *s++ = __raw_readb(PGDR); |
169 | *s++ = ctrl_inb(PHDR); | 170 | *s++ = __raw_readb(PHDR); |
170 | } | 171 | } |
171 | 172 | ||
172 | static void jornadakbd680_poll(struct input_polled_dev *dev) | 173 | static void jornadakbd680_poll(struct input_polled_dev *dev) |
diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index 4e016d823069..2cd3e1d56ea4 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/slab.h> | ||
26 | 27 | ||
27 | #include <mach/jornada720.h> | 28 | #include <mach/jornada720.h> |
28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 574eda2a4957..f7c2a166576b 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/leds.h> | 32 | #include <linux/leds.h> |
33 | #include <linux/i2c/lm8323.h> | 33 | #include <linux/i2c/lm8323.h> |
34 | #include <linux/slab.h> | ||
34 | 35 | ||
35 | /* Commands to send to the chip. */ | 36 | /* Commands to send to the chip. */ |
36 | #define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */ | 37 | #define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */ |
@@ -641,6 +642,7 @@ static int __devinit lm8323_probe(struct i2c_client *client, | |||
641 | struct lm8323_platform_data *pdata = client->dev.platform_data; | 642 | struct lm8323_platform_data *pdata = client->dev.platform_data; |
642 | struct input_dev *idev; | 643 | struct input_dev *idev; |
643 | struct lm8323_chip *lm; | 644 | struct lm8323_chip *lm; |
645 | int pwm; | ||
644 | int i, err; | 646 | int i, err; |
645 | unsigned long tmo; | 647 | unsigned long tmo; |
646 | u8 data[2]; | 648 | u8 data[2]; |
@@ -669,8 +671,6 @@ static int __devinit lm8323_probe(struct i2c_client *client, | |||
669 | goto fail1; | 671 | goto fail1; |
670 | } | 672 | } |
671 | 673 | ||
672 | i2c_set_clientdata(client, lm); | ||
673 | |||
674 | lm->client = client; | 674 | lm->client = client; |
675 | lm->idev = idev; | 675 | lm->idev = idev; |
676 | mutex_init(&lm->lock); | 676 | mutex_init(&lm->lock); |
@@ -711,8 +711,9 @@ static int __devinit lm8323_probe(struct i2c_client *client, | |||
711 | goto fail1; | 711 | goto fail1; |
712 | } | 712 | } |
713 | 713 | ||
714 | for (i = 0; i < LM8323_NUM_PWMS; i++) { | 714 | for (pwm = 0; pwm < LM8323_NUM_PWMS; pwm++) { |
715 | err = init_pwm(lm, i + 1, &client->dev, pdata->pwm_names[i]); | 715 | err = init_pwm(lm, pwm + 1, &client->dev, |
716 | pdata->pwm_names[pwm]); | ||
716 | if (err < 0) | 717 | if (err < 0) |
717 | goto fail2; | 718 | goto fail2; |
718 | } | 719 | } |
@@ -752,6 +753,8 @@ static int __devinit lm8323_probe(struct i2c_client *client, | |||
752 | goto fail4; | 753 | goto fail4; |
753 | } | 754 | } |
754 | 755 | ||
756 | i2c_set_clientdata(client, lm); | ||
757 | |||
755 | device_init_wakeup(&client->dev, 1); | 758 | device_init_wakeup(&client->dev, 1); |
756 | enable_irq_wake(client->irq); | 759 | enable_irq_wake(client->irq); |
757 | 760 | ||
@@ -763,9 +766,9 @@ fail4: | |||
763 | fail3: | 766 | fail3: |
764 | device_remove_file(&client->dev, &dev_attr_disable_kp); | 767 | device_remove_file(&client->dev, &dev_attr_disable_kp); |
765 | fail2: | 768 | fail2: |
766 | while (--i >= 0) | 769 | while (--pwm >= 0) |
767 | if (lm->pwm[i].enabled) | 770 | if (lm->pwm[pwm].enabled) |
768 | led_classdev_unregister(&lm->pwm[i].cdev); | 771 | led_classdev_unregister(&lm->pwm[pwm].cdev); |
769 | fail1: | 772 | fail1: |
770 | input_free_device(idev); | 773 | input_free_device(idev); |
771 | kfree(lm); | 774 | kfree(lm); |
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 9caed30f3bbb..b1ab29861e1c 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c | |||
@@ -192,11 +192,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) | |||
192 | static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) | 192 | static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) |
193 | { | 193 | { |
194 | struct locomokbd *locomokbd = dev_id; | 194 | struct locomokbd *locomokbd = dev_id; |
195 | u16 r; | ||
196 | |||
197 | r = locomo_readl(locomokbd->base + LOCOMO_KIC); | ||
198 | if ((r & 0x0001) == 0) | ||
199 | return IRQ_HANDLED; | ||
200 | |||
201 | locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */ | ||
202 | |||
195 | /** wait chattering delay **/ | 203 | /** wait chattering delay **/ |
196 | udelay(100); | 204 | udelay(100); |
197 | 205 | ||
198 | locomokbd_scankeyboard(locomokbd); | 206 | locomokbd_scankeyboard(locomokbd); |
199 | |||
200 | return IRQ_HANDLED; | 207 | return IRQ_HANDLED; |
201 | } | 208 | } |
202 | 209 | ||
@@ -210,6 +217,25 @@ static void locomokbd_timer_callback(unsigned long data) | |||
210 | locomokbd_scankeyboard(locomokbd); | 217 | locomokbd_scankeyboard(locomokbd); |
211 | } | 218 | } |
212 | 219 | ||
220 | static int locomokbd_open(struct input_dev *dev) | ||
221 | { | ||
222 | struct locomokbd *locomokbd = input_get_drvdata(dev); | ||
223 | u16 r; | ||
224 | |||
225 | r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010; | ||
226 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static void locomokbd_close(struct input_dev *dev) | ||
231 | { | ||
232 | struct locomokbd *locomokbd = input_get_drvdata(dev); | ||
233 | u16 r; | ||
234 | |||
235 | r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010; | ||
236 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); | ||
237 | } | ||
238 | |||
213 | static int __devinit locomokbd_probe(struct locomo_dev *dev) | 239 | static int __devinit locomokbd_probe(struct locomo_dev *dev) |
214 | { | 240 | { |
215 | struct locomokbd *locomokbd; | 241 | struct locomokbd *locomokbd; |
@@ -253,6 +279,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) | |||
253 | input_dev->id.vendor = 0x0001; | 279 | input_dev->id.vendor = 0x0001; |
254 | input_dev->id.product = 0x0001; | 280 | input_dev->id.product = 0x0001; |
255 | input_dev->id.version = 0x0100; | 281 | input_dev->id.version = 0x0100; |
282 | input_dev->open = locomokbd_open; | ||
283 | input_dev->close = locomokbd_close; | ||
256 | input_dev->dev.parent = &dev->dev; | 284 | input_dev->dev.parent = &dev->dev; |
257 | 285 | ||
258 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | | 286 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | |
@@ -261,6 +289,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) | |||
261 | input_dev->keycodesize = sizeof(locomokbd_keycode[0]); | 289 | input_dev->keycodesize = sizeof(locomokbd_keycode[0]); |
262 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); | 290 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); |
263 | 291 | ||
292 | input_set_drvdata(input_dev, locomokbd); | ||
293 | |||
264 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); | 294 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); |
265 | for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) | 295 | for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) |
266 | set_bit(locomokbd->keycode[i], input_dev->keybit); | 296 | set_bit(locomokbd->keycode[i], input_dev->keybit); |
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index d3c8b61a941d..b02e4268e18f 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/input/matrix_keypad.h> | 24 | #include <linux/input/matrix_keypad.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | struct matrix_keypad { | 27 | struct matrix_keypad { |
27 | const struct matrix_keypad_platform_data *pdata; | 28 | const struct matrix_keypad_platform_data *pdata; |
@@ -36,6 +37,7 @@ struct matrix_keypad { | |||
36 | spinlock_t lock; | 37 | spinlock_t lock; |
37 | bool scan_pending; | 38 | bool scan_pending; |
38 | bool stopped; | 39 | bool stopped; |
40 | bool gpio_all_disabled; | ||
39 | }; | 41 | }; |
40 | 42 | ||
41 | /* | 43 | /* |
@@ -86,8 +88,12 @@ static void enable_row_irqs(struct matrix_keypad *keypad) | |||
86 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 88 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
87 | int i; | 89 | int i; |
88 | 90 | ||
89 | for (i = 0; i < pdata->num_row_gpios; i++) | 91 | if (pdata->clustered_irq > 0) |
90 | enable_irq(gpio_to_irq(pdata->row_gpios[i])); | 92 | enable_irq(pdata->clustered_irq); |
93 | else { | ||
94 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
95 | enable_irq(gpio_to_irq(pdata->row_gpios[i])); | ||
96 | } | ||
91 | } | 97 | } |
92 | 98 | ||
93 | static void disable_row_irqs(struct matrix_keypad *keypad) | 99 | static void disable_row_irqs(struct matrix_keypad *keypad) |
@@ -95,8 +101,12 @@ static void disable_row_irqs(struct matrix_keypad *keypad) | |||
95 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 101 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
96 | int i; | 102 | int i; |
97 | 103 | ||
98 | for (i = 0; i < pdata->num_row_gpios; i++) | 104 | if (pdata->clustered_irq > 0) |
99 | disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i])); | 105 | disable_irq_nosync(pdata->clustered_irq); |
106 | else { | ||
107 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
108 | disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i])); | ||
109 | } | ||
100 | } | 110 | } |
101 | 111 | ||
102 | /* | 112 | /* |
@@ -215,45 +225,69 @@ static void matrix_keypad_stop(struct input_dev *dev) | |||
215 | } | 225 | } |
216 | 226 | ||
217 | #ifdef CONFIG_PM | 227 | #ifdef CONFIG_PM |
218 | static int matrix_keypad_suspend(struct device *dev) | 228 | static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) |
219 | { | 229 | { |
220 | struct platform_device *pdev = to_platform_device(dev); | ||
221 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | ||
222 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 230 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
231 | unsigned int gpio; | ||
223 | int i; | 232 | int i; |
224 | 233 | ||
225 | matrix_keypad_stop(keypad->input_dev); | 234 | if (pdata->clustered_irq > 0) { |
235 | if (enable_irq_wake(pdata->clustered_irq) == 0) | ||
236 | keypad->gpio_all_disabled = true; | ||
237 | } else { | ||
226 | 238 | ||
227 | if (device_may_wakeup(&pdev->dev)) { | ||
228 | for (i = 0; i < pdata->num_row_gpios; i++) { | 239 | for (i = 0; i < pdata->num_row_gpios; i++) { |
229 | if (!test_bit(i, keypad->disabled_gpios)) { | 240 | if (!test_bit(i, keypad->disabled_gpios)) { |
230 | unsigned int gpio = pdata->row_gpios[i]; | 241 | gpio = pdata->row_gpios[i]; |
231 | 242 | ||
232 | if (enable_irq_wake(gpio_to_irq(gpio)) == 0) | 243 | if (enable_irq_wake(gpio_to_irq(gpio)) == 0) |
233 | __set_bit(i, keypad->disabled_gpios); | 244 | __set_bit(i, keypad->disabled_gpios); |
234 | } | 245 | } |
235 | } | 246 | } |
236 | } | 247 | } |
237 | |||
238 | return 0; | ||
239 | } | 248 | } |
240 | 249 | ||
241 | static int matrix_keypad_resume(struct device *dev) | 250 | static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad) |
242 | { | 251 | { |
243 | struct platform_device *pdev = to_platform_device(dev); | ||
244 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | ||
245 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 252 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
253 | unsigned int gpio; | ||
246 | int i; | 254 | int i; |
247 | 255 | ||
248 | if (device_may_wakeup(&pdev->dev)) { | 256 | if (pdata->clustered_irq > 0) { |
257 | if (keypad->gpio_all_disabled) { | ||
258 | disable_irq_wake(pdata->clustered_irq); | ||
259 | keypad->gpio_all_disabled = false; | ||
260 | } | ||
261 | } else { | ||
249 | for (i = 0; i < pdata->num_row_gpios; i++) { | 262 | for (i = 0; i < pdata->num_row_gpios; i++) { |
250 | if (test_and_clear_bit(i, keypad->disabled_gpios)) { | 263 | if (test_and_clear_bit(i, keypad->disabled_gpios)) { |
251 | unsigned int gpio = pdata->row_gpios[i]; | 264 | gpio = pdata->row_gpios[i]; |
252 | |||
253 | disable_irq_wake(gpio_to_irq(gpio)); | 265 | disable_irq_wake(gpio_to_irq(gpio)); |
254 | } | 266 | } |
255 | } | 267 | } |
256 | } | 268 | } |
269 | } | ||
270 | |||
271 | static int matrix_keypad_suspend(struct device *dev) | ||
272 | { | ||
273 | struct platform_device *pdev = to_platform_device(dev); | ||
274 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | ||
275 | |||
276 | matrix_keypad_stop(keypad->input_dev); | ||
277 | |||
278 | if (device_may_wakeup(&pdev->dev)) | ||
279 | matrix_keypad_enable_wakeup(keypad); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static int matrix_keypad_resume(struct device *dev) | ||
285 | { | ||
286 | struct platform_device *pdev = to_platform_device(dev); | ||
287 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | ||
288 | |||
289 | if (device_may_wakeup(&pdev->dev)) | ||
290 | matrix_keypad_disable_wakeup(keypad); | ||
257 | 291 | ||
258 | matrix_keypad_start(keypad->input_dev); | 292 | matrix_keypad_start(keypad->input_dev); |
259 | 293 | ||
@@ -295,17 +329,31 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev, | |||
295 | gpio_direction_input(pdata->row_gpios[i]); | 329 | gpio_direction_input(pdata->row_gpios[i]); |
296 | } | 330 | } |
297 | 331 | ||
298 | for (i = 0; i < pdata->num_row_gpios; i++) { | 332 | if (pdata->clustered_irq > 0) { |
299 | err = request_irq(gpio_to_irq(pdata->row_gpios[i]), | 333 | err = request_irq(pdata->clustered_irq, |
300 | matrix_keypad_interrupt, | 334 | matrix_keypad_interrupt, |
301 | IRQF_DISABLED | | 335 | pdata->clustered_irq_flags, |
302 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
303 | "matrix-keypad", keypad); | 336 | "matrix-keypad", keypad); |
304 | if (err) { | 337 | if (err) { |
305 | dev_err(&pdev->dev, | 338 | dev_err(&pdev->dev, |
306 | "Unable to acquire interrupt for GPIO line %i\n", | 339 | "Unable to acquire clustered interrupt\n"); |
307 | pdata->row_gpios[i]); | 340 | goto err_free_rows; |
308 | goto err_free_irqs; | 341 | } |
342 | } else { | ||
343 | for (i = 0; i < pdata->num_row_gpios; i++) { | ||
344 | err = request_irq(gpio_to_irq(pdata->row_gpios[i]), | ||
345 | matrix_keypad_interrupt, | ||
346 | IRQF_DISABLED | | ||
347 | IRQF_TRIGGER_RISING | | ||
348 | IRQF_TRIGGER_FALLING, | ||
349 | "matrix-keypad", keypad); | ||
350 | if (err) { | ||
351 | dev_err(&pdev->dev, | ||
352 | "Unable to acquire interrupt " | ||
353 | "for GPIO line %i\n", | ||
354 | pdata->row_gpios[i]); | ||
355 | goto err_free_irqs; | ||
356 | } | ||
309 | } | 357 | } |
310 | } | 358 | } |
311 | 359 | ||
@@ -373,7 +421,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) | |||
373 | input_dev->name = pdev->name; | 421 | input_dev->name = pdev->name; |
374 | input_dev->id.bustype = BUS_HOST; | 422 | input_dev->id.bustype = BUS_HOST; |
375 | input_dev->dev.parent = &pdev->dev; | 423 | input_dev->dev.parent = &pdev->dev; |
376 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 424 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
425 | if (!pdata->no_autorepeat) | ||
426 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
377 | input_dev->open = matrix_keypad_start; | 427 | input_dev->open = matrix_keypad_start; |
378 | input_dev->close = matrix_keypad_stop; | 428 | input_dev->close = matrix_keypad_stop; |
379 | 429 | ||
@@ -415,11 +465,16 @@ static int __devexit matrix_keypad_remove(struct platform_device *pdev) | |||
415 | 465 | ||
416 | device_init_wakeup(&pdev->dev, 0); | 466 | device_init_wakeup(&pdev->dev, 0); |
417 | 467 | ||
418 | for (i = 0; i < pdata->num_row_gpios; i++) { | 468 | if (pdata->clustered_irq > 0) { |
419 | free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); | 469 | free_irq(pdata->clustered_irq, keypad); |
420 | gpio_free(pdata->row_gpios[i]); | 470 | } else { |
471 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
472 | free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); | ||
421 | } | 473 | } |
422 | 474 | ||
475 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
476 | gpio_free(pdata->row_gpios[i]); | ||
477 | |||
423 | for (i = 0; i < pdata->num_col_gpios; i++) | 478 | for (i = 0; i < pdata->num_col_gpios; i++) |
424 | gpio_free(pdata->col_gpios[i]); | 479 | gpio_free(pdata->col_gpios[i]); |
425 | 480 | ||
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 3b5b948eba39..9091ff5ea808 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
19 | #include <linux/input.h> | 20 | #include <linux/input.h> |
20 | #include <linux/input/matrix_keypad.h> | 21 | #include <linux/input/matrix_keypad.h> |
@@ -264,7 +265,6 @@ static int __devexit max7359_remove(struct i2c_client *client) | |||
264 | 265 | ||
265 | free_irq(client->irq, keypad); | 266 | free_irq(client->irq, keypad); |
266 | input_unregister_device(keypad->input_dev); | 267 | input_unregister_device(keypad->input_dev); |
267 | i2c_set_clientdata(client, NULL); | ||
268 | kfree(keypad); | 268 | kfree(keypad); |
269 | 269 | ||
270 | return 0; | 270 | return 0; |
diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c new file mode 100644 index 000000000000..63b849d7e90b --- /dev/null +++ b/drivers/input/keyboard/mcs_touchkey.c | |||
@@ -0,0 +1,239 @@ | |||
1 | /* | ||
2 | * mcs_touchkey.c - Touchkey driver for MELFAS MCS5000/5080 controller | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: HeungJun Kim <riverful.kim@samsung.com> | ||
6 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/i2c/mcs.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/irq.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | /* MCS5000 Touchkey */ | ||
24 | #define MCS5000_TOUCHKEY_STATUS 0x04 | ||
25 | #define MCS5000_TOUCHKEY_STATUS_PRESS 7 | ||
26 | #define MCS5000_TOUCHKEY_FW 0x0a | ||
27 | #define MCS5000_TOUCHKEY_BASE_VAL 0x61 | ||
28 | |||
29 | /* MCS5080 Touchkey */ | ||
30 | #define MCS5080_TOUCHKEY_STATUS 0x00 | ||
31 | #define MCS5080_TOUCHKEY_STATUS_PRESS 3 | ||
32 | #define MCS5080_TOUCHKEY_FW 0x01 | ||
33 | #define MCS5080_TOUCHKEY_BASE_VAL 0x1 | ||
34 | |||
35 | enum mcs_touchkey_type { | ||
36 | MCS5000_TOUCHKEY, | ||
37 | MCS5080_TOUCHKEY, | ||
38 | }; | ||
39 | |||
40 | struct mcs_touchkey_chip { | ||
41 | unsigned int status_reg; | ||
42 | unsigned int pressbit; | ||
43 | unsigned int press_invert; | ||
44 | unsigned int baseval; | ||
45 | }; | ||
46 | |||
47 | struct mcs_touchkey_data { | ||
48 | struct i2c_client *client; | ||
49 | struct input_dev *input_dev; | ||
50 | struct mcs_touchkey_chip chip; | ||
51 | unsigned int key_code; | ||
52 | unsigned int key_val; | ||
53 | unsigned short keycodes[]; | ||
54 | }; | ||
55 | |||
56 | static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id) | ||
57 | { | ||
58 | struct mcs_touchkey_data *data = dev_id; | ||
59 | struct mcs_touchkey_chip *chip = &data->chip; | ||
60 | struct i2c_client *client = data->client; | ||
61 | struct input_dev *input = data->input_dev; | ||
62 | unsigned int key_val; | ||
63 | unsigned int pressed; | ||
64 | int val; | ||
65 | |||
66 | val = i2c_smbus_read_byte_data(client, chip->status_reg); | ||
67 | if (val < 0) { | ||
68 | dev_err(&client->dev, "i2c read error [%d]\n", val); | ||
69 | goto out; | ||
70 | } | ||
71 | |||
72 | pressed = (val & (1 << chip->pressbit)) >> chip->pressbit; | ||
73 | if (chip->press_invert) | ||
74 | pressed ^= chip->press_invert; | ||
75 | |||
76 | /* key_val is 0 when released, so we should use key_val of press. */ | ||
77 | if (pressed) { | ||
78 | key_val = val & (0xff >> (8 - chip->pressbit)); | ||
79 | if (!key_val) | ||
80 | goto out; | ||
81 | key_val -= chip->baseval; | ||
82 | data->key_code = data->keycodes[key_val]; | ||
83 | data->key_val = key_val; | ||
84 | } | ||
85 | |||
86 | input_event(input, EV_MSC, MSC_SCAN, data->key_val); | ||
87 | input_report_key(input, data->key_code, pressed); | ||
88 | input_sync(input); | ||
89 | |||
90 | dev_dbg(&client->dev, "key %d %d %s\n", data->key_val, data->key_code, | ||
91 | pressed ? "pressed" : "released"); | ||
92 | |||
93 | out: | ||
94 | return IRQ_HANDLED; | ||
95 | } | ||
96 | |||
97 | static int __devinit mcs_touchkey_probe(struct i2c_client *client, | ||
98 | const struct i2c_device_id *id) | ||
99 | { | ||
100 | const struct mcs_platform_data *pdata; | ||
101 | struct mcs_touchkey_data *data; | ||
102 | struct input_dev *input_dev; | ||
103 | unsigned int fw_reg; | ||
104 | int fw_ver; | ||
105 | int error; | ||
106 | int i; | ||
107 | |||
108 | pdata = client->dev.platform_data; | ||
109 | if (!pdata) { | ||
110 | dev_err(&client->dev, "no platform data defined\n"); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | |||
114 | data = kzalloc(sizeof(struct mcs_touchkey_data) + | ||
115 | sizeof(data->keycodes[0]) * (pdata->key_maxval + 1), | ||
116 | GFP_KERNEL); | ||
117 | input_dev = input_allocate_device(); | ||
118 | if (!data || !input_dev) { | ||
119 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
120 | error = -ENOMEM; | ||
121 | goto err_free_mem; | ||
122 | } | ||
123 | |||
124 | data->client = client; | ||
125 | data->input_dev = input_dev; | ||
126 | |||
127 | if (id->driver_data == MCS5000_TOUCHKEY) { | ||
128 | data->chip.status_reg = MCS5000_TOUCHKEY_STATUS; | ||
129 | data->chip.pressbit = MCS5000_TOUCHKEY_STATUS_PRESS; | ||
130 | data->chip.baseval = MCS5000_TOUCHKEY_BASE_VAL; | ||
131 | fw_reg = MCS5000_TOUCHKEY_FW; | ||
132 | } else { | ||
133 | data->chip.status_reg = MCS5080_TOUCHKEY_STATUS; | ||
134 | data->chip.pressbit = MCS5080_TOUCHKEY_STATUS_PRESS; | ||
135 | data->chip.press_invert = 1; | ||
136 | data->chip.baseval = MCS5080_TOUCHKEY_BASE_VAL; | ||
137 | fw_reg = MCS5080_TOUCHKEY_FW; | ||
138 | } | ||
139 | |||
140 | fw_ver = i2c_smbus_read_byte_data(client, fw_reg); | ||
141 | if (fw_ver < 0) { | ||
142 | error = fw_ver; | ||
143 | dev_err(&client->dev, "i2c read error[%d]\n", error); | ||
144 | goto err_free_mem; | ||
145 | } | ||
146 | dev_info(&client->dev, "Firmware version: %d\n", fw_ver); | ||
147 | |||
148 | input_dev->name = "MELPAS MCS Touchkey"; | ||
149 | input_dev->id.bustype = BUS_I2C; | ||
150 | input_dev->dev.parent = &client->dev; | ||
151 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
152 | if (!pdata->no_autorepeat) | ||
153 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
154 | input_dev->keycode = data->keycodes; | ||
155 | input_dev->keycodesize = sizeof(data->keycodes[0]); | ||
156 | input_dev->keycodemax = pdata->key_maxval + 1; | ||
157 | |||
158 | for (i = 0; i < pdata->keymap_size; i++) { | ||
159 | unsigned int val = MCS_KEY_VAL(pdata->keymap[i]); | ||
160 | unsigned int code = MCS_KEY_CODE(pdata->keymap[i]); | ||
161 | |||
162 | data->keycodes[val] = code; | ||
163 | __set_bit(code, input_dev->keybit); | ||
164 | } | ||
165 | |||
166 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
167 | input_set_drvdata(input_dev, data); | ||
168 | |||
169 | if (pdata->cfg_pin) | ||
170 | pdata->cfg_pin(); | ||
171 | |||
172 | error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt, | ||
173 | IRQF_TRIGGER_FALLING, client->dev.driver->name, data); | ||
174 | if (error) { | ||
175 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
176 | goto err_free_mem; | ||
177 | } | ||
178 | |||
179 | error = input_register_device(input_dev); | ||
180 | if (error) | ||
181 | goto err_free_irq; | ||
182 | |||
183 | i2c_set_clientdata(client, data); | ||
184 | return 0; | ||
185 | |||
186 | err_free_irq: | ||
187 | free_irq(client->irq, data); | ||
188 | err_free_mem: | ||
189 | input_free_device(input_dev); | ||
190 | kfree(data); | ||
191 | return error; | ||
192 | } | ||
193 | |||
194 | static int __devexit mcs_touchkey_remove(struct i2c_client *client) | ||
195 | { | ||
196 | struct mcs_touchkey_data *data = i2c_get_clientdata(client); | ||
197 | |||
198 | free_irq(client->irq, data); | ||
199 | input_unregister_device(data->input_dev); | ||
200 | kfree(data); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static const struct i2c_device_id mcs_touchkey_id[] = { | ||
206 | { "mcs5000_touchkey", MCS5000_TOUCHKEY }, | ||
207 | { "mcs5080_touchkey", MCS5080_TOUCHKEY }, | ||
208 | { } | ||
209 | }; | ||
210 | MODULE_DEVICE_TABLE(i2c, mcs_touchkey_id); | ||
211 | |||
212 | static struct i2c_driver mcs_touchkey_driver = { | ||
213 | .driver = { | ||
214 | .name = "mcs_touchkey", | ||
215 | .owner = THIS_MODULE, | ||
216 | }, | ||
217 | .probe = mcs_touchkey_probe, | ||
218 | .remove = __devexit_p(mcs_touchkey_remove), | ||
219 | .id_table = mcs_touchkey_id, | ||
220 | }; | ||
221 | |||
222 | static int __init mcs_touchkey_init(void) | ||
223 | { | ||
224 | return i2c_add_driver(&mcs_touchkey_driver); | ||
225 | } | ||
226 | |||
227 | static void __exit mcs_touchkey_exit(void) | ||
228 | { | ||
229 | i2c_del_driver(&mcs_touchkey_driver); | ||
230 | } | ||
231 | |||
232 | module_init(mcs_touchkey_init); | ||
233 | module_exit(mcs_touchkey_exit); | ||
234 | |||
235 | /* Module information */ | ||
236 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
237 | MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>"); | ||
238 | MODULE_DESCRIPTION("Touchkey driver for MELFAS MCS5000/5080 controller"); | ||
239 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c new file mode 100644 index 000000000000..6e0f23091360 --- /dev/null +++ b/drivers/input/keyboard/nomadik-ske-keypad.c | |||
@@ -0,0 +1,408 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | ||
6 | * | ||
7 | * License terms:GNU General Public License (GPL) version 2 | ||
8 | * | ||
9 | * Keypad controller driver for the SKE (Scroll Key Encoder) module used in | ||
10 | * the Nomadik 8815 and Ux500 platforms. | ||
11 | */ | ||
12 | |||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/clk.h> | ||
21 | |||
22 | #include <plat/ske.h> | ||
23 | |||
24 | /* SKE_CR bits */ | ||
25 | #define SKE_KPMLT (0x1 << 6) | ||
26 | #define SKE_KPCN (0x7 << 3) | ||
27 | #define SKE_KPASEN (0x1 << 2) | ||
28 | #define SKE_KPASON (0x1 << 7) | ||
29 | |||
30 | /* SKE_IMSC bits */ | ||
31 | #define SKE_KPIMA (0x1 << 2) | ||
32 | |||
33 | /* SKE_ICR bits */ | ||
34 | #define SKE_KPICS (0x1 << 3) | ||
35 | #define SKE_KPICA (0x1 << 2) | ||
36 | |||
37 | /* SKE_RIS bits */ | ||
38 | #define SKE_KPRISA (0x1 << 2) | ||
39 | |||
40 | #define SKE_KEYPAD_ROW_SHIFT 3 | ||
41 | #define SKE_KPD_KEYMAP_SIZE (8 * 8) | ||
42 | |||
43 | /* keypad auto scan registers */ | ||
44 | #define SKE_ASR0 0x20 | ||
45 | #define SKE_ASR1 0x24 | ||
46 | #define SKE_ASR2 0x28 | ||
47 | #define SKE_ASR3 0x2C | ||
48 | |||
49 | #define SKE_NUM_ASRX_REGISTERS (4) | ||
50 | |||
51 | /** | ||
52 | * struct ske_keypad - data structure used by keypad driver | ||
53 | * @irq: irq no | ||
54 | * @reg_base: ske regsiters base address | ||
55 | * @input: pointer to input device object | ||
56 | * @board: keypad platform device | ||
57 | * @keymap: matrix scan code table for keycodes | ||
58 | * @clk: clock structure pointer | ||
59 | */ | ||
60 | struct ske_keypad { | ||
61 | int irq; | ||
62 | void __iomem *reg_base; | ||
63 | struct input_dev *input; | ||
64 | const struct ske_keypad_platform_data *board; | ||
65 | unsigned short keymap[SKE_KPD_KEYMAP_SIZE]; | ||
66 | struct clk *clk; | ||
67 | spinlock_t ske_keypad_lock; | ||
68 | }; | ||
69 | |||
70 | static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr, | ||
71 | u8 mask, u8 data) | ||
72 | { | ||
73 | u32 ret; | ||
74 | |||
75 | spin_lock(&keypad->ske_keypad_lock); | ||
76 | |||
77 | ret = readl(keypad->reg_base + addr); | ||
78 | ret &= ~mask; | ||
79 | ret |= data; | ||
80 | writel(ret, keypad->reg_base + addr); | ||
81 | |||
82 | spin_unlock(&keypad->ske_keypad_lock); | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * ske_keypad_chip_init: init keypad controller configuration | ||
87 | * | ||
88 | * Enable Multi key press detection, auto scan mode | ||
89 | */ | ||
90 | static int __devinit ske_keypad_chip_init(struct ske_keypad *keypad) | ||
91 | { | ||
92 | u32 value; | ||
93 | int timeout = 50; | ||
94 | |||
95 | /* check SKE_RIS to be 0 */ | ||
96 | while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--) | ||
97 | cpu_relax(); | ||
98 | |||
99 | if (!timeout) | ||
100 | return -EINVAL; | ||
101 | |||
102 | /* | ||
103 | * set debounce value | ||
104 | * keypad dbounce is configured in DBCR[15:8] | ||
105 | * dbounce value in steps of 32/32.768 ms | ||
106 | */ | ||
107 | spin_lock(&keypad->ske_keypad_lock); | ||
108 | value = readl(keypad->reg_base + SKE_DBCR); | ||
109 | value = value & 0xff; | ||
110 | value |= ((keypad->board->debounce_ms * 32000)/32768) << 8; | ||
111 | writel(value, keypad->reg_base + SKE_DBCR); | ||
112 | spin_unlock(&keypad->ske_keypad_lock); | ||
113 | |||
114 | /* enable multi key detection */ | ||
115 | ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPMLT); | ||
116 | |||
117 | /* | ||
118 | * set up the number of columns | ||
119 | * KPCN[5:3] defines no. of keypad columns to be auto scanned | ||
120 | */ | ||
121 | value = (keypad->board->kcol - 1) << 3; | ||
122 | ske_keypad_set_bits(keypad, SKE_CR, SKE_KPCN, value); | ||
123 | |||
124 | /* clear keypad interrupt for auto(and pending SW) scans */ | ||
125 | ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA | SKE_KPICS); | ||
126 | |||
127 | /* un-mask keypad interrupts */ | ||
128 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | ||
129 | |||
130 | /* enable automatic scan */ | ||
131 | ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPASEN); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static void ske_keypad_read_data(struct ske_keypad *keypad) | ||
137 | { | ||
138 | struct input_dev *input = keypad->input; | ||
139 | u16 status; | ||
140 | int col = 0, row = 0, code; | ||
141 | int ske_asr, ske_ris, key_pressed, i; | ||
142 | |||
143 | /* | ||
144 | * Read the auto scan registers | ||
145 | * | ||
146 | * Each SKE_ASRx (x=0 to x=3) contains two row values. | ||
147 | * lower byte contains row value for column 2*x, | ||
148 | * upper byte contains row value for column 2*x + 1 | ||
149 | */ | ||
150 | for (i = 0; i < SKE_NUM_ASRX_REGISTERS; i++) { | ||
151 | ske_asr = readl(keypad->reg_base + SKE_ASR0 + (4 * i)); | ||
152 | if (!ske_asr) | ||
153 | continue; | ||
154 | |||
155 | /* now that ASRx is zero, find out the column x and row y*/ | ||
156 | if (ske_asr & 0xff) { | ||
157 | col = i * 2; | ||
158 | status = ske_asr & 0xff; | ||
159 | } else { | ||
160 | col = (i * 2) + 1; | ||
161 | status = (ske_asr & 0xff00) >> 8; | ||
162 | } | ||
163 | |||
164 | /* find out the row */ | ||
165 | row = __ffs(status); | ||
166 | |||
167 | code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); | ||
168 | ske_ris = readl(keypad->reg_base + SKE_RIS); | ||
169 | key_pressed = ske_ris & SKE_KPRISA; | ||
170 | |||
171 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
172 | input_report_key(input, keypad->keymap[code], key_pressed); | ||
173 | input_sync(input); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | static irqreturn_t ske_keypad_irq(int irq, void *dev_id) | ||
178 | { | ||
179 | struct ske_keypad *keypad = dev_id; | ||
180 | int retries = 20; | ||
181 | |||
182 | /* disable auto scan interrupt; mask the interrupt generated */ | ||
183 | ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); | ||
184 | ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA); | ||
185 | |||
186 | while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries) | ||
187 | msleep(5); | ||
188 | |||
189 | if (retries) { | ||
190 | /* SKEx registers are stable and can be read */ | ||
191 | ske_keypad_read_data(keypad); | ||
192 | } | ||
193 | |||
194 | /* enable auto scan interrupts */ | ||
195 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | ||
196 | |||
197 | return IRQ_HANDLED; | ||
198 | } | ||
199 | |||
200 | static int __devinit ske_keypad_probe(struct platform_device *pdev) | ||
201 | { | ||
202 | const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; | ||
203 | struct ske_keypad *keypad; | ||
204 | struct input_dev *input; | ||
205 | struct resource *res; | ||
206 | int irq; | ||
207 | int error; | ||
208 | |||
209 | if (!plat) { | ||
210 | dev_err(&pdev->dev, "invalid keypad platform data\n"); | ||
211 | return -EINVAL; | ||
212 | } | ||
213 | |||
214 | irq = platform_get_irq(pdev, 0); | ||
215 | if (irq < 0) { | ||
216 | dev_err(&pdev->dev, "failed to get keypad irq\n"); | ||
217 | return -EINVAL; | ||
218 | } | ||
219 | |||
220 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
221 | if (!res) { | ||
222 | dev_err(&pdev->dev, "missing platform resources\n"); | ||
223 | return -EINVAL; | ||
224 | } | ||
225 | |||
226 | keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL); | ||
227 | input = input_allocate_device(); | ||
228 | if (!keypad || !input) { | ||
229 | dev_err(&pdev->dev, "failed to allocate keypad memory\n"); | ||
230 | error = -ENOMEM; | ||
231 | goto err_free_mem; | ||
232 | } | ||
233 | |||
234 | keypad->irq = irq; | ||
235 | keypad->board = plat; | ||
236 | keypad->input = input; | ||
237 | spin_lock_init(&keypad->ske_keypad_lock); | ||
238 | |||
239 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { | ||
240 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
241 | error = -EBUSY; | ||
242 | goto err_free_mem; | ||
243 | } | ||
244 | |||
245 | keypad->reg_base = ioremap(res->start, resource_size(res)); | ||
246 | if (!keypad->reg_base) { | ||
247 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
248 | error = -ENXIO; | ||
249 | goto err_free_mem_region; | ||
250 | } | ||
251 | |||
252 | keypad->clk = clk_get(&pdev->dev, NULL); | ||
253 | if (IS_ERR(keypad->clk)) { | ||
254 | dev_err(&pdev->dev, "failed to get clk\n"); | ||
255 | error = PTR_ERR(keypad->clk); | ||
256 | goto err_iounmap; | ||
257 | } | ||
258 | |||
259 | input->id.bustype = BUS_HOST; | ||
260 | input->name = "ux500-ske-keypad"; | ||
261 | input->dev.parent = &pdev->dev; | ||
262 | |||
263 | input->keycode = keypad->keymap; | ||
264 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
265 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
266 | |||
267 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
268 | |||
269 | __set_bit(EV_KEY, input->evbit); | ||
270 | if (!plat->no_autorepeat) | ||
271 | __set_bit(EV_REP, input->evbit); | ||
272 | |||
273 | matrix_keypad_build_keymap(plat->keymap_data, SKE_KEYPAD_ROW_SHIFT, | ||
274 | input->keycode, input->keybit); | ||
275 | |||
276 | clk_enable(keypad->clk); | ||
277 | |||
278 | /* go through board initialization helpers */ | ||
279 | if (keypad->board->init) | ||
280 | keypad->board->init(); | ||
281 | |||
282 | error = ske_keypad_chip_init(keypad); | ||
283 | if (error) { | ||
284 | dev_err(&pdev->dev, "unable to init keypad hardware\n"); | ||
285 | goto err_clk_disable; | ||
286 | } | ||
287 | |||
288 | error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq, | ||
289 | IRQF_ONESHOT, "ske-keypad", keypad); | ||
290 | if (error) { | ||
291 | dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq); | ||
292 | goto err_clk_disable; | ||
293 | } | ||
294 | |||
295 | error = input_register_device(input); | ||
296 | if (error) { | ||
297 | dev_err(&pdev->dev, | ||
298 | "unable to register input device: %d\n", error); | ||
299 | goto err_free_irq; | ||
300 | } | ||
301 | |||
302 | if (plat->wakeup_enable) | ||
303 | device_init_wakeup(&pdev->dev, true); | ||
304 | |||
305 | platform_set_drvdata(pdev, keypad); | ||
306 | |||
307 | return 0; | ||
308 | |||
309 | err_free_irq: | ||
310 | free_irq(keypad->irq, keypad); | ||
311 | err_clk_disable: | ||
312 | clk_disable(keypad->clk); | ||
313 | clk_put(keypad->clk); | ||
314 | err_iounmap: | ||
315 | iounmap(keypad->reg_base); | ||
316 | err_free_mem_region: | ||
317 | release_mem_region(res->start, resource_size(res)); | ||
318 | err_free_mem: | ||
319 | input_free_device(input); | ||
320 | kfree(keypad); | ||
321 | return error; | ||
322 | } | ||
323 | |||
324 | static int __devexit ske_keypad_remove(struct platform_device *pdev) | ||
325 | { | ||
326 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | ||
327 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
328 | |||
329 | free_irq(keypad->irq, keypad); | ||
330 | |||
331 | input_unregister_device(keypad->input); | ||
332 | |||
333 | clk_disable(keypad->clk); | ||
334 | clk_put(keypad->clk); | ||
335 | |||
336 | if (keypad->board->exit) | ||
337 | keypad->board->exit(); | ||
338 | |||
339 | iounmap(keypad->reg_base); | ||
340 | release_mem_region(res->start, resource_size(res)); | ||
341 | kfree(keypad); | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | #ifdef CONFIG_PM | ||
347 | static int ske_keypad_suspend(struct device *dev) | ||
348 | { | ||
349 | struct platform_device *pdev = to_platform_device(dev); | ||
350 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | ||
351 | int irq = platform_get_irq(pdev, 0); | ||
352 | |||
353 | if (device_may_wakeup(dev)) | ||
354 | enable_irq_wake(irq); | ||
355 | else | ||
356 | ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static int ske_keypad_resume(struct device *dev) | ||
362 | { | ||
363 | struct platform_device *pdev = to_platform_device(dev); | ||
364 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | ||
365 | int irq = platform_get_irq(pdev, 0); | ||
366 | |||
367 | if (device_may_wakeup(dev)) | ||
368 | disable_irq_wake(irq); | ||
369 | else | ||
370 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | ||
371 | |||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static const struct dev_pm_ops ske_keypad_dev_pm_ops = { | ||
376 | .suspend = ske_keypad_suspend, | ||
377 | .resume = ske_keypad_resume, | ||
378 | }; | ||
379 | #endif | ||
380 | |||
381 | struct platform_driver ske_keypad_driver = { | ||
382 | .driver = { | ||
383 | .name = "nmk-ske-keypad", | ||
384 | .owner = THIS_MODULE, | ||
385 | #ifdef CONFIG_PM | ||
386 | .pm = &ske_keypad_dev_pm_ops, | ||
387 | #endif | ||
388 | }, | ||
389 | .probe = ske_keypad_probe, | ||
390 | .remove = __devexit_p(ske_keypad_remove), | ||
391 | }; | ||
392 | |||
393 | static int __init ske_keypad_init(void) | ||
394 | { | ||
395 | return platform_driver_probe(&ske_keypad_driver, ske_keypad_probe); | ||
396 | } | ||
397 | module_init(ske_keypad_init); | ||
398 | |||
399 | static void __exit ske_keypad_exit(void) | ||
400 | { | ||
401 | platform_driver_unregister(&ske_keypad_driver); | ||
402 | } | ||
403 | module_exit(ske_keypad_exit); | ||
404 | |||
405 | MODULE_LICENSE("GPL v2"); | ||
406 | MODULE_AUTHOR("Naveen Kumar <naveen.gaddipati@stericsson.com> / Sundar Iyer <sundar.iyer@stericsson.com>"); | ||
407 | MODULE_DESCRIPTION("Nomadik Scroll-Key-Encoder Keypad Driver"); | ||
408 | MODULE_ALIAS("platform:nomadik-ske-keypad"); | ||
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 1a494d505431..a72e61ddca91 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
37 | #include <linux/slab.h> | ||
37 | #include <mach/gpio.h> | 38 | #include <mach/gpio.h> |
38 | #include <plat/keypad.h> | 39 | #include <plat/keypad.h> |
39 | #include <plat/menelaus.h> | 40 | #include <plat/menelaus.h> |
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c new file mode 100644 index 000000000000..45bd0977d006 --- /dev/null +++ b/drivers/input/keyboard/omap4-keypad.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* | ||
2 | * OMAP4 Keypad Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * Author: Abraham Arce <x0066660@ti.com> | ||
7 | * Initial Code: Syed Rafiuddin <rafiuddin.syed@ti.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/input.h> | ||
31 | #include <linux/slab.h> | ||
32 | |||
33 | #include <plat/omap4-keypad.h> | ||
34 | |||
35 | /* OMAP4 registers */ | ||
36 | #define OMAP4_KBD_REVISION 0x00 | ||
37 | #define OMAP4_KBD_SYSCONFIG 0x10 | ||
38 | #define OMAP4_KBD_SYSSTATUS 0x14 | ||
39 | #define OMAP4_KBD_IRQSTATUS 0x18 | ||
40 | #define OMAP4_KBD_IRQENABLE 0x1C | ||
41 | #define OMAP4_KBD_WAKEUPENABLE 0x20 | ||
42 | #define OMAP4_KBD_PENDING 0x24 | ||
43 | #define OMAP4_KBD_CTRL 0x28 | ||
44 | #define OMAP4_KBD_DEBOUNCINGTIME 0x2C | ||
45 | #define OMAP4_KBD_LONGKEYTIME 0x30 | ||
46 | #define OMAP4_KBD_TIMEOUT 0x34 | ||
47 | #define OMAP4_KBD_STATEMACHINE 0x38 | ||
48 | #define OMAP4_KBD_ROWINPUTS 0x3C | ||
49 | #define OMAP4_KBD_COLUMNOUTPUTS 0x40 | ||
50 | #define OMAP4_KBD_FULLCODE31_0 0x44 | ||
51 | #define OMAP4_KBD_FULLCODE63_32 0x48 | ||
52 | |||
53 | /* OMAP4 bit definitions */ | ||
54 | #define OMAP4_DEF_IRQENABLE_EVENTEN (1 << 0) | ||
55 | #define OMAP4_DEF_IRQENABLE_LONGKEY (1 << 1) | ||
56 | #define OMAP4_DEF_IRQENABLE_TIMEOUTEN (1 << 2) | ||
57 | #define OMAP4_DEF_WUP_EVENT_ENA (1 << 0) | ||
58 | #define OMAP4_DEF_WUP_LONG_KEY_ENA (1 << 1) | ||
59 | #define OMAP4_DEF_CTRL_NOSOFTMODE (1 << 1) | ||
60 | #define OMAP4_DEF_CTRLPTVVALUE (1 << 2) | ||
61 | #define OMAP4_DEF_CTRLPTV (1 << 1) | ||
62 | |||
63 | /* OMAP4 values */ | ||
64 | #define OMAP4_VAL_IRQDISABLE 0x00 | ||
65 | #define OMAP4_VAL_DEBOUNCINGTIME 0x07 | ||
66 | #define OMAP4_VAL_FUNCTIONALCFG 0x1E | ||
67 | |||
68 | #define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF | ||
69 | |||
70 | struct omap4_keypad { | ||
71 | struct input_dev *input; | ||
72 | |||
73 | void __iomem *base; | ||
74 | int irq; | ||
75 | |||
76 | unsigned int rows; | ||
77 | unsigned int cols; | ||
78 | unsigned int row_shift; | ||
79 | unsigned char key_state[8]; | ||
80 | unsigned short keymap[]; | ||
81 | }; | ||
82 | |||
83 | static void __devinit omap4_keypad_config(struct omap4_keypad *keypad_data) | ||
84 | { | ||
85 | __raw_writel(OMAP4_VAL_FUNCTIONALCFG, | ||
86 | keypad_data->base + OMAP4_KBD_CTRL); | ||
87 | __raw_writel(OMAP4_VAL_DEBOUNCINGTIME, | ||
88 | keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME); | ||
89 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
90 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
91 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | ||
92 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
93 | __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA, | ||
94 | keypad_data->base + OMAP4_KBD_WAKEUPENABLE); | ||
95 | } | ||
96 | |||
97 | /* Interrupt handler */ | ||
98 | static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | ||
99 | { | ||
100 | struct omap4_keypad *keypad_data = dev_id; | ||
101 | struct input_dev *input_dev = keypad_data->input; | ||
102 | unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)]; | ||
103 | unsigned int col, row, code, changed; | ||
104 | u32 *new_state = (u32 *) key_state; | ||
105 | |||
106 | /* Disable interrupts */ | ||
107 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
108 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
109 | |||
110 | *new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0); | ||
111 | *(new_state + 1) = __raw_readl(keypad_data->base | ||
112 | + OMAP4_KBD_FULLCODE63_32); | ||
113 | |||
114 | for (row = 0; row < keypad_data->rows; row++) { | ||
115 | changed = key_state[row] ^ keypad_data->key_state[row]; | ||
116 | if (!changed) | ||
117 | continue; | ||
118 | |||
119 | for (col = 0; col < keypad_data->cols; col++) { | ||
120 | if (changed & (1 << col)) { | ||
121 | code = MATRIX_SCAN_CODE(row, col, | ||
122 | keypad_data->row_shift); | ||
123 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
124 | input_report_key(input_dev, | ||
125 | keypad_data->keymap[code], | ||
126 | key_state[row] & (1 << col)); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | input_sync(input_dev); | ||
132 | |||
133 | memcpy(keypad_data->key_state, key_state, | ||
134 | sizeof(keypad_data->key_state)); | ||
135 | |||
136 | /* clear pending interrupts */ | ||
137 | __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), | ||
138 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
139 | |||
140 | /* enable interrupts */ | ||
141 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | ||
142 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
143 | |||
144 | return IRQ_HANDLED; | ||
145 | } | ||
146 | |||
147 | static int __devinit omap4_keypad_probe(struct platform_device *pdev) | ||
148 | { | ||
149 | const struct omap4_keypad_platform_data *pdata; | ||
150 | struct omap4_keypad *keypad_data; | ||
151 | struct input_dev *input_dev; | ||
152 | struct resource *res; | ||
153 | resource_size_t size; | ||
154 | unsigned int row_shift, max_keys; | ||
155 | int irq; | ||
156 | int error; | ||
157 | |||
158 | /* platform data */ | ||
159 | pdata = pdev->dev.platform_data; | ||
160 | if (!pdata) { | ||
161 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
166 | if (!res) { | ||
167 | dev_err(&pdev->dev, "no base address specified\n"); | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | irq = platform_get_irq(pdev, 0); | ||
172 | if (!irq) { | ||
173 | dev_err(&pdev->dev, "no keyboard irq assigned\n"); | ||
174 | return -EINVAL; | ||
175 | } | ||
176 | |||
177 | if (!pdata->keymap_data) { | ||
178 | dev_err(&pdev->dev, "no keymap data defined\n"); | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | row_shift = get_count_order(pdata->cols); | ||
183 | max_keys = pdata->rows << row_shift; | ||
184 | |||
185 | keypad_data = kzalloc(sizeof(struct omap4_keypad) + | ||
186 | max_keys * sizeof(keypad_data->keymap[0]), | ||
187 | GFP_KERNEL); | ||
188 | if (!keypad_data) { | ||
189 | dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); | ||
190 | return -ENOMEM; | ||
191 | } | ||
192 | |||
193 | size = resource_size(res); | ||
194 | |||
195 | res = request_mem_region(res->start, size, pdev->name); | ||
196 | if (!res) { | ||
197 | dev_err(&pdev->dev, "can't request mem region\n"); | ||
198 | error = -EBUSY; | ||
199 | goto err_free_keypad; | ||
200 | } | ||
201 | |||
202 | keypad_data->base = ioremap(res->start, resource_size(res)); | ||
203 | if (!keypad_data->base) { | ||
204 | dev_err(&pdev->dev, "can't ioremap mem resource\n"); | ||
205 | error = -ENOMEM; | ||
206 | goto err_release_mem; | ||
207 | } | ||
208 | |||
209 | keypad_data->irq = irq; | ||
210 | keypad_data->row_shift = row_shift; | ||
211 | keypad_data->rows = pdata->rows; | ||
212 | keypad_data->cols = pdata->cols; | ||
213 | |||
214 | /* input device allocation */ | ||
215 | keypad_data->input = input_dev = input_allocate_device(); | ||
216 | if (!input_dev) { | ||
217 | error = -ENOMEM; | ||
218 | goto err_unmap; | ||
219 | } | ||
220 | |||
221 | input_dev->name = pdev->name; | ||
222 | input_dev->dev.parent = &pdev->dev; | ||
223 | input_dev->id.bustype = BUS_HOST; | ||
224 | input_dev->id.vendor = 0x0001; | ||
225 | input_dev->id.product = 0x0001; | ||
226 | input_dev->id.version = 0x0001; | ||
227 | |||
228 | input_dev->keycode = keypad_data->keymap; | ||
229 | input_dev->keycodesize = sizeof(keypad_data->keymap[0]); | ||
230 | input_dev->keycodemax = max_keys; | ||
231 | |||
232 | __set_bit(EV_KEY, input_dev->evbit); | ||
233 | __set_bit(EV_REP, input_dev->evbit); | ||
234 | |||
235 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
236 | |||
237 | input_set_drvdata(input_dev, keypad_data); | ||
238 | |||
239 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, | ||
240 | input_dev->keycode, input_dev->keybit); | ||
241 | |||
242 | omap4_keypad_config(keypad_data); | ||
243 | |||
244 | error = request_irq(keypad_data->irq, omap4_keypad_interrupt, | ||
245 | IRQF_TRIGGER_RISING, | ||
246 | "omap4-keypad", keypad_data); | ||
247 | if (error) { | ||
248 | dev_err(&pdev->dev, "failed to register interrupt\n"); | ||
249 | goto err_free_input; | ||
250 | } | ||
251 | |||
252 | error = input_register_device(keypad_data->input); | ||
253 | if (error < 0) { | ||
254 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
255 | goto err_free_irq; | ||
256 | } | ||
257 | |||
258 | |||
259 | platform_set_drvdata(pdev, keypad_data); | ||
260 | return 0; | ||
261 | |||
262 | err_free_irq: | ||
263 | free_irq(keypad_data->irq, keypad_data); | ||
264 | err_free_input: | ||
265 | input_free_device(input_dev); | ||
266 | err_unmap: | ||
267 | iounmap(keypad_data->base); | ||
268 | err_release_mem: | ||
269 | release_mem_region(res->start, size); | ||
270 | err_free_keypad: | ||
271 | kfree(keypad_data); | ||
272 | return error; | ||
273 | } | ||
274 | |||
275 | static int __devexit omap4_keypad_remove(struct platform_device *pdev) | ||
276 | { | ||
277 | struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); | ||
278 | struct resource *res; | ||
279 | |||
280 | free_irq(keypad_data->irq, keypad_data); | ||
281 | input_unregister_device(keypad_data->input); | ||
282 | |||
283 | iounmap(keypad_data->base); | ||
284 | |||
285 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
286 | release_mem_region(res->start, resource_size(res)); | ||
287 | |||
288 | kfree(keypad_data); | ||
289 | platform_set_drvdata(pdev, NULL); | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static struct platform_driver omap4_keypad_driver = { | ||
295 | .probe = omap4_keypad_probe, | ||
296 | .remove = __devexit_p(omap4_keypad_remove), | ||
297 | .driver = { | ||
298 | .name = "omap4-keypad", | ||
299 | .owner = THIS_MODULE, | ||
300 | }, | ||
301 | }; | ||
302 | |||
303 | static int __init omap4_keypad_init(void) | ||
304 | { | ||
305 | return platform_driver_register(&omap4_keypad_driver); | ||
306 | } | ||
307 | module_init(omap4_keypad_init); | ||
308 | |||
309 | static void __exit omap4_keypad_exit(void) | ||
310 | { | ||
311 | platform_driver_unregister(&omap4_keypad_driver); | ||
312 | } | ||
313 | module_exit(omap4_keypad_exit); | ||
314 | |||
315 | MODULE_AUTHOR("Texas Instruments"); | ||
316 | MODULE_DESCRIPTION("OMAP4 Keypad Driver"); | ||
317 | MODULE_LICENSE("GPL"); | ||
318 | MODULE_ALIAS("platform:omap4-keypad"); | ||
diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index 78cccddbf551..1f1a5563f60a 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/slab.h> | ||
17 | 18 | ||
18 | struct opencores_kbd { | 19 | struct opencores_kbd { |
19 | struct input_dev *input; | 20 | struct input_dev *input; |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 79cd3e9fdf2e..4b0ec35259a1 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -26,12 +26,13 @@ | |||
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/input/matrix_keypad.h> | 28 | #include <linux/input/matrix_keypad.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include <asm/mach/arch.h> | 31 | #include <asm/mach/arch.h> |
31 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
32 | 33 | ||
33 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
34 | #include <mach/pxa27x_keypad.h> | 35 | #include <plat/pxa27x_keypad.h> |
35 | /* | 36 | /* |
36 | * Keypad Controller registers | 37 | * Keypad Controller registers |
37 | */ | 38 | */ |
@@ -329,11 +330,21 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) | |||
329 | keypad->direct_key_state = new_state; | 330 | keypad->direct_key_state = new_state; |
330 | } | 331 | } |
331 | 332 | ||
333 | static void clear_wakeup_event(struct pxa27x_keypad *keypad) | ||
334 | { | ||
335 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | ||
336 | |||
337 | if (pdata->clear_wakeup_event) | ||
338 | (pdata->clear_wakeup_event)(); | ||
339 | } | ||
340 | |||
332 | static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) | 341 | static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) |
333 | { | 342 | { |
334 | struct pxa27x_keypad *keypad = dev_id; | 343 | struct pxa27x_keypad *keypad = dev_id; |
335 | unsigned long kpc = keypad_readl(KPC); | 344 | unsigned long kpc = keypad_readl(KPC); |
336 | 345 | ||
346 | clear_wakeup_event(keypad); | ||
347 | |||
337 | if (kpc & KPC_DI) | 348 | if (kpc & KPC_DI) |
338 | pxa27x_keypad_scan_direct(keypad); | 349 | pxa27x_keypad_scan_direct(keypad); |
339 | 350 | ||
@@ -566,8 +577,6 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) | |||
566 | clk_put(keypad->clk); | 577 | clk_put(keypad->clk); |
567 | 578 | ||
568 | input_unregister_device(keypad->input_dev); | 579 | input_unregister_device(keypad->input_dev); |
569 | input_free_device(keypad->input_dev); | ||
570 | |||
571 | iounmap(keypad->mmio_base); | 580 | iounmap(keypad->mmio_base); |
572 | 581 | ||
573 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 582 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index 95fbba470e65..b7123a44b6ec 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/input.h> | 13 | #include <linux/input.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | #include <mach/pxa930_rotary.h> | 18 | #include <mach/pxa930_rotary.h> |
18 | 19 | ||
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 191cc51d6cf8..fac695157e8a 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c | |||
@@ -358,11 +358,10 @@ static int __devexit qt2160_remove(struct i2c_client *client) | |||
358 | input_unregister_device(qt2160->input); | 358 | input_unregister_device(qt2160->input); |
359 | kfree(qt2160); | 359 | kfree(qt2160); |
360 | 360 | ||
361 | i2c_set_clientdata(client, NULL); | ||
362 | return 0; | 361 | return 0; |
363 | } | 362 | } |
364 | 363 | ||
365 | static struct i2c_device_id qt2160_idtable[] = { | 364 | static const struct i2c_device_id qt2160_idtable[] = { |
366 | { "qt2160", 0, }, | 365 | { "qt2160", 0, }, |
367 | { } | 366 | { } |
368 | }; | 367 | }; |
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c new file mode 100644 index 000000000000..f689f49e3109 --- /dev/null +++ b/drivers/input/keyboard/samsung-keypad.c | |||
@@ -0,0 +1,491 @@ | |||
1 | /* | ||
2 | * Samsung keypad driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
6 | * Author: Donghwa Lee <dh09.lee@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <plat/keypad.h> | ||
26 | |||
27 | #define SAMSUNG_KEYIFCON 0x00 | ||
28 | #define SAMSUNG_KEYIFSTSCLR 0x04 | ||
29 | #define SAMSUNG_KEYIFCOL 0x08 | ||
30 | #define SAMSUNG_KEYIFROW 0x0c | ||
31 | #define SAMSUNG_KEYIFFC 0x10 | ||
32 | |||
33 | /* SAMSUNG_KEYIFCON */ | ||
34 | #define SAMSUNG_KEYIFCON_INT_F_EN (1 << 0) | ||
35 | #define SAMSUNG_KEYIFCON_INT_R_EN (1 << 1) | ||
36 | #define SAMSUNG_KEYIFCON_DF_EN (1 << 2) | ||
37 | #define SAMSUNG_KEYIFCON_FC_EN (1 << 3) | ||
38 | #define SAMSUNG_KEYIFCON_WAKEUPEN (1 << 4) | ||
39 | |||
40 | /* SAMSUNG_KEYIFSTSCLR */ | ||
41 | #define SAMSUNG_KEYIFSTSCLR_P_INT_MASK (0xff << 0) | ||
42 | #define SAMSUNG_KEYIFSTSCLR_R_INT_MASK (0xff << 8) | ||
43 | #define SAMSUNG_KEYIFSTSCLR_R_INT_OFFSET 8 | ||
44 | #define S5PV210_KEYIFSTSCLR_P_INT_MASK (0x3fff << 0) | ||
45 | #define S5PV210_KEYIFSTSCLR_R_INT_MASK (0x3fff << 16) | ||
46 | #define S5PV210_KEYIFSTSCLR_R_INT_OFFSET 16 | ||
47 | |||
48 | /* SAMSUNG_KEYIFCOL */ | ||
49 | #define SAMSUNG_KEYIFCOL_MASK (0xff << 0) | ||
50 | #define S5PV210_KEYIFCOLEN_MASK (0xff << 8) | ||
51 | |||
52 | /* SAMSUNG_KEYIFROW */ | ||
53 | #define SAMSUNG_KEYIFROW_MASK (0xff << 0) | ||
54 | #define S5PV210_KEYIFROW_MASK (0x3fff << 0) | ||
55 | |||
56 | /* SAMSUNG_KEYIFFC */ | ||
57 | #define SAMSUNG_KEYIFFC_MASK (0x3ff << 0) | ||
58 | |||
59 | enum samsung_keypad_type { | ||
60 | KEYPAD_TYPE_SAMSUNG, | ||
61 | KEYPAD_TYPE_S5PV210, | ||
62 | }; | ||
63 | |||
64 | struct samsung_keypad { | ||
65 | struct input_dev *input_dev; | ||
66 | struct clk *clk; | ||
67 | void __iomem *base; | ||
68 | wait_queue_head_t wait; | ||
69 | bool stopped; | ||
70 | int irq; | ||
71 | unsigned int row_shift; | ||
72 | unsigned int rows; | ||
73 | unsigned int cols; | ||
74 | unsigned int row_state[SAMSUNG_MAX_COLS]; | ||
75 | unsigned short keycodes[]; | ||
76 | }; | ||
77 | |||
78 | static int samsung_keypad_is_s5pv210(struct device *dev) | ||
79 | { | ||
80 | struct platform_device *pdev = to_platform_device(dev); | ||
81 | enum samsung_keypad_type type = | ||
82 | platform_get_device_id(pdev)->driver_data; | ||
83 | |||
84 | return type == KEYPAD_TYPE_S5PV210; | ||
85 | } | ||
86 | |||
87 | static void samsung_keypad_scan(struct samsung_keypad *keypad, | ||
88 | unsigned int *row_state) | ||
89 | { | ||
90 | struct device *dev = keypad->input_dev->dev.parent; | ||
91 | unsigned int col; | ||
92 | unsigned int val; | ||
93 | |||
94 | for (col = 0; col < keypad->cols; col++) { | ||
95 | if (samsung_keypad_is_s5pv210(dev)) { | ||
96 | val = S5PV210_KEYIFCOLEN_MASK; | ||
97 | val &= ~(1 << col) << 8; | ||
98 | } else { | ||
99 | val = SAMSUNG_KEYIFCOL_MASK; | ||
100 | val &= ~(1 << col); | ||
101 | } | ||
102 | |||
103 | writel(val, keypad->base + SAMSUNG_KEYIFCOL); | ||
104 | mdelay(1); | ||
105 | |||
106 | val = readl(keypad->base + SAMSUNG_KEYIFROW); | ||
107 | row_state[col] = ~val & ((1 << keypad->rows) - 1); | ||
108 | } | ||
109 | |||
110 | /* KEYIFCOL reg clear */ | ||
111 | writel(0, keypad->base + SAMSUNG_KEYIFCOL); | ||
112 | } | ||
113 | |||
114 | static bool samsung_keypad_report(struct samsung_keypad *keypad, | ||
115 | unsigned int *row_state) | ||
116 | { | ||
117 | struct input_dev *input_dev = keypad->input_dev; | ||
118 | unsigned int changed; | ||
119 | unsigned int pressed; | ||
120 | unsigned int key_down = 0; | ||
121 | unsigned int val; | ||
122 | unsigned int col, row; | ||
123 | |||
124 | for (col = 0; col < keypad->cols; col++) { | ||
125 | changed = row_state[col] ^ keypad->row_state[col]; | ||
126 | key_down |= row_state[col]; | ||
127 | if (!changed) | ||
128 | continue; | ||
129 | |||
130 | for (row = 0; row < keypad->rows; row++) { | ||
131 | if (!(changed & (1 << row))) | ||
132 | continue; | ||
133 | |||
134 | pressed = row_state[col] & (1 << row); | ||
135 | |||
136 | dev_dbg(&keypad->input_dev->dev, | ||
137 | "key %s, row: %d, col: %d\n", | ||
138 | pressed ? "pressed" : "released", row, col); | ||
139 | |||
140 | val = MATRIX_SCAN_CODE(row, col, keypad->row_shift); | ||
141 | |||
142 | input_event(input_dev, EV_MSC, MSC_SCAN, val); | ||
143 | input_report_key(input_dev, | ||
144 | keypad->keycodes[val], pressed); | ||
145 | } | ||
146 | input_sync(keypad->input_dev); | ||
147 | } | ||
148 | |||
149 | memcpy(keypad->row_state, row_state, sizeof(keypad->row_state)); | ||
150 | |||
151 | return key_down; | ||
152 | } | ||
153 | |||
154 | static irqreturn_t samsung_keypad_irq(int irq, void *dev_id) | ||
155 | { | ||
156 | struct samsung_keypad *keypad = dev_id; | ||
157 | unsigned int row_state[SAMSUNG_MAX_COLS]; | ||
158 | unsigned int val; | ||
159 | bool key_down; | ||
160 | |||
161 | do { | ||
162 | val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR); | ||
163 | /* Clear interrupt. */ | ||
164 | writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR); | ||
165 | |||
166 | samsung_keypad_scan(keypad, row_state); | ||
167 | |||
168 | key_down = samsung_keypad_report(keypad, row_state); | ||
169 | if (key_down) | ||
170 | wait_event_timeout(keypad->wait, keypad->stopped, | ||
171 | msecs_to_jiffies(50)); | ||
172 | |||
173 | } while (key_down && !keypad->stopped); | ||
174 | |||
175 | return IRQ_HANDLED; | ||
176 | } | ||
177 | |||
178 | static void samsung_keypad_start(struct samsung_keypad *keypad) | ||
179 | { | ||
180 | unsigned int val; | ||
181 | |||
182 | /* Tell IRQ thread that it may poll the device. */ | ||
183 | keypad->stopped = false; | ||
184 | |||
185 | clk_enable(keypad->clk); | ||
186 | |||
187 | /* Enable interrupt bits. */ | ||
188 | val = readl(keypad->base + SAMSUNG_KEYIFCON); | ||
189 | val |= SAMSUNG_KEYIFCON_INT_F_EN | SAMSUNG_KEYIFCON_INT_R_EN; | ||
190 | writel(val, keypad->base + SAMSUNG_KEYIFCON); | ||
191 | |||
192 | /* KEYIFCOL reg clear. */ | ||
193 | writel(0, keypad->base + SAMSUNG_KEYIFCOL); | ||
194 | } | ||
195 | |||
196 | static void samsung_keypad_stop(struct samsung_keypad *keypad) | ||
197 | { | ||
198 | unsigned int val; | ||
199 | |||
200 | /* Signal IRQ thread to stop polling and disable the handler. */ | ||
201 | keypad->stopped = true; | ||
202 | wake_up(&keypad->wait); | ||
203 | disable_irq(keypad->irq); | ||
204 | |||
205 | /* Clear interrupt. */ | ||
206 | writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR); | ||
207 | |||
208 | /* Disable interrupt bits. */ | ||
209 | val = readl(keypad->base + SAMSUNG_KEYIFCON); | ||
210 | val &= ~(SAMSUNG_KEYIFCON_INT_F_EN | SAMSUNG_KEYIFCON_INT_R_EN); | ||
211 | writel(val, keypad->base + SAMSUNG_KEYIFCON); | ||
212 | |||
213 | clk_disable(keypad->clk); | ||
214 | |||
215 | /* | ||
216 | * Now that chip should not generate interrupts we can safely | ||
217 | * re-enable the handler. | ||
218 | */ | ||
219 | enable_irq(keypad->irq); | ||
220 | } | ||
221 | |||
222 | static int samsung_keypad_open(struct input_dev *input_dev) | ||
223 | { | ||
224 | struct samsung_keypad *keypad = input_get_drvdata(input_dev); | ||
225 | |||
226 | samsung_keypad_start(keypad); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static void samsung_keypad_close(struct input_dev *input_dev) | ||
232 | { | ||
233 | struct samsung_keypad *keypad = input_get_drvdata(input_dev); | ||
234 | |||
235 | samsung_keypad_stop(keypad); | ||
236 | } | ||
237 | |||
238 | static int __devinit samsung_keypad_probe(struct platform_device *pdev) | ||
239 | { | ||
240 | const struct samsung_keypad_platdata *pdata; | ||
241 | const struct matrix_keymap_data *keymap_data; | ||
242 | struct samsung_keypad *keypad; | ||
243 | struct resource *res; | ||
244 | struct input_dev *input_dev; | ||
245 | unsigned int row_shift; | ||
246 | unsigned int keymap_size; | ||
247 | int error; | ||
248 | |||
249 | pdata = pdev->dev.platform_data; | ||
250 | if (!pdata) { | ||
251 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | |||
255 | keymap_data = pdata->keymap_data; | ||
256 | if (!keymap_data) { | ||
257 | dev_err(&pdev->dev, "no keymap data defined\n"); | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | |||
261 | if (!pdata->rows || pdata->rows > SAMSUNG_MAX_ROWS) | ||
262 | return -EINVAL; | ||
263 | |||
264 | if (!pdata->cols || pdata->cols > SAMSUNG_MAX_COLS) | ||
265 | return -EINVAL; | ||
266 | |||
267 | /* initialize the gpio */ | ||
268 | if (pdata->cfg_gpio) | ||
269 | pdata->cfg_gpio(pdata->rows, pdata->cols); | ||
270 | |||
271 | row_shift = get_count_order(pdata->cols); | ||
272 | keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]); | ||
273 | |||
274 | keypad = kzalloc(sizeof(*keypad) + keymap_size, GFP_KERNEL); | ||
275 | input_dev = input_allocate_device(); | ||
276 | if (!keypad || !input_dev) { | ||
277 | error = -ENOMEM; | ||
278 | goto err_free_mem; | ||
279 | } | ||
280 | |||
281 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
282 | if (!res) { | ||
283 | error = -ENODEV; | ||
284 | goto err_free_mem; | ||
285 | } | ||
286 | |||
287 | keypad->base = ioremap(res->start, resource_size(res)); | ||
288 | if (!keypad->base) { | ||
289 | error = -EBUSY; | ||
290 | goto err_free_mem; | ||
291 | } | ||
292 | |||
293 | keypad->clk = clk_get(&pdev->dev, "keypad"); | ||
294 | if (IS_ERR(keypad->clk)) { | ||
295 | dev_err(&pdev->dev, "failed to get keypad clk\n"); | ||
296 | error = PTR_ERR(keypad->clk); | ||
297 | goto err_unmap_base; | ||
298 | } | ||
299 | |||
300 | keypad->input_dev = input_dev; | ||
301 | keypad->row_shift = row_shift; | ||
302 | keypad->rows = pdata->rows; | ||
303 | keypad->cols = pdata->cols; | ||
304 | init_waitqueue_head(&keypad->wait); | ||
305 | |||
306 | input_dev->name = pdev->name; | ||
307 | input_dev->id.bustype = BUS_HOST; | ||
308 | input_dev->dev.parent = &pdev->dev; | ||
309 | input_set_drvdata(input_dev, keypad); | ||
310 | |||
311 | input_dev->open = samsung_keypad_open; | ||
312 | input_dev->close = samsung_keypad_close; | ||
313 | |||
314 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
315 | if (!pdata->no_autorepeat) | ||
316 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
317 | |||
318 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
319 | |||
320 | input_dev->keycode = keypad->keycodes; | ||
321 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
322 | input_dev->keycodemax = pdata->rows << row_shift; | ||
323 | |||
324 | matrix_keypad_build_keymap(keymap_data, row_shift, | ||
325 | input_dev->keycode, input_dev->keybit); | ||
326 | |||
327 | keypad->irq = platform_get_irq(pdev, 0); | ||
328 | if (keypad->irq < 0) { | ||
329 | error = keypad->irq; | ||
330 | goto err_put_clk; | ||
331 | } | ||
332 | |||
333 | error = request_threaded_irq(keypad->irq, NULL, samsung_keypad_irq, | ||
334 | IRQF_ONESHOT, dev_name(&pdev->dev), keypad); | ||
335 | if (error) { | ||
336 | dev_err(&pdev->dev, "failed to register keypad interrupt\n"); | ||
337 | goto err_put_clk; | ||
338 | } | ||
339 | |||
340 | error = input_register_device(keypad->input_dev); | ||
341 | if (error) | ||
342 | goto err_free_irq; | ||
343 | |||
344 | device_init_wakeup(&pdev->dev, pdata->wakeup); | ||
345 | platform_set_drvdata(pdev, keypad); | ||
346 | return 0; | ||
347 | |||
348 | err_free_irq: | ||
349 | free_irq(keypad->irq, keypad); | ||
350 | err_put_clk: | ||
351 | clk_put(keypad->clk); | ||
352 | err_unmap_base: | ||
353 | iounmap(keypad->base); | ||
354 | err_free_mem: | ||
355 | input_free_device(input_dev); | ||
356 | kfree(keypad); | ||
357 | |||
358 | return error; | ||
359 | } | ||
360 | |||
361 | static int __devexit samsung_keypad_remove(struct platform_device *pdev) | ||
362 | { | ||
363 | struct samsung_keypad *keypad = platform_get_drvdata(pdev); | ||
364 | |||
365 | device_init_wakeup(&pdev->dev, 0); | ||
366 | platform_set_drvdata(pdev, NULL); | ||
367 | |||
368 | input_unregister_device(keypad->input_dev); | ||
369 | |||
370 | /* | ||
371 | * It is safe to free IRQ after unregistering device because | ||
372 | * samsung_keypad_close will shut off interrupts. | ||
373 | */ | ||
374 | free_irq(keypad->irq, keypad); | ||
375 | |||
376 | clk_put(keypad->clk); | ||
377 | |||
378 | iounmap(keypad->base); | ||
379 | kfree(keypad); | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | #ifdef CONFIG_PM | ||
385 | static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad, | ||
386 | bool enable) | ||
387 | { | ||
388 | struct device *dev = keypad->input_dev->dev.parent; | ||
389 | unsigned int val; | ||
390 | |||
391 | clk_enable(keypad->clk); | ||
392 | |||
393 | val = readl(keypad->base + SAMSUNG_KEYIFCON); | ||
394 | if (enable) { | ||
395 | val |= SAMSUNG_KEYIFCON_WAKEUPEN; | ||
396 | if (device_may_wakeup(dev)) | ||
397 | enable_irq_wake(keypad->irq); | ||
398 | } else { | ||
399 | val &= ~SAMSUNG_KEYIFCON_WAKEUPEN; | ||
400 | if (device_may_wakeup(dev)) | ||
401 | disable_irq_wake(keypad->irq); | ||
402 | } | ||
403 | writel(val, keypad->base + SAMSUNG_KEYIFCON); | ||
404 | |||
405 | clk_disable(keypad->clk); | ||
406 | } | ||
407 | |||
408 | static int samsung_keypad_suspend(struct device *dev) | ||
409 | { | ||
410 | struct platform_device *pdev = to_platform_device(dev); | ||
411 | struct samsung_keypad *keypad = platform_get_drvdata(pdev); | ||
412 | struct input_dev *input_dev = keypad->input_dev; | ||
413 | |||
414 | mutex_lock(&input_dev->mutex); | ||
415 | |||
416 | if (input_dev->users) | ||
417 | samsung_keypad_stop(keypad); | ||
418 | |||
419 | samsung_keypad_toggle_wakeup(keypad, true); | ||
420 | |||
421 | mutex_unlock(&input_dev->mutex); | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static int samsung_keypad_resume(struct device *dev) | ||
427 | { | ||
428 | struct platform_device *pdev = to_platform_device(dev); | ||
429 | struct samsung_keypad *keypad = platform_get_drvdata(pdev); | ||
430 | struct input_dev *input_dev = keypad->input_dev; | ||
431 | |||
432 | mutex_lock(&input_dev->mutex); | ||
433 | |||
434 | samsung_keypad_toggle_wakeup(keypad, false); | ||
435 | |||
436 | if (input_dev->users) | ||
437 | samsung_keypad_start(keypad); | ||
438 | |||
439 | mutex_unlock(&input_dev->mutex); | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static const struct dev_pm_ops samsung_keypad_pm_ops = { | ||
445 | .suspend = samsung_keypad_suspend, | ||
446 | .resume = samsung_keypad_resume, | ||
447 | }; | ||
448 | #endif | ||
449 | |||
450 | static struct platform_device_id samsung_keypad_driver_ids[] = { | ||
451 | { | ||
452 | .name = "samsung-keypad", | ||
453 | .driver_data = KEYPAD_TYPE_SAMSUNG, | ||
454 | }, { | ||
455 | .name = "s5pv210-keypad", | ||
456 | .driver_data = KEYPAD_TYPE_S5PV210, | ||
457 | }, | ||
458 | { }, | ||
459 | }; | ||
460 | MODULE_DEVICE_TABLE(platform, samsung_keypad_driver_ids); | ||
461 | |||
462 | static struct platform_driver samsung_keypad_driver = { | ||
463 | .probe = samsung_keypad_probe, | ||
464 | .remove = __devexit_p(samsung_keypad_remove), | ||
465 | .driver = { | ||
466 | .name = "samsung-keypad", | ||
467 | .owner = THIS_MODULE, | ||
468 | #ifdef CONFIG_PM | ||
469 | .pm = &samsung_keypad_pm_ops, | ||
470 | #endif | ||
471 | }, | ||
472 | .id_table = samsung_keypad_driver_ids, | ||
473 | }; | ||
474 | |||
475 | static int __init samsung_keypad_init(void) | ||
476 | { | ||
477 | return platform_driver_register(&samsung_keypad_driver); | ||
478 | } | ||
479 | module_init(samsung_keypad_init); | ||
480 | |||
481 | static void __exit samsung_keypad_exit(void) | ||
482 | { | ||
483 | platform_driver_unregister(&samsung_keypad_driver); | ||
484 | } | ||
485 | module_exit(samsung_keypad_exit); | ||
486 | |||
487 | MODULE_DESCRIPTION("Samsung keypad driver"); | ||
488 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
489 | MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>"); | ||
490 | MODULE_LICENSE("GPL"); | ||
491 | MODULE_ALIAS("platform:samsung-keypad"); | ||
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 8e9380bfed40..d7dafd9425b6 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -19,16 +19,10 @@ | |||
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/input/sh_keysc.h> | 21 | #include <linux/input/sh_keysc.h> |
22 | #include <linux/bitmap.h> | ||
22 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
23 | #include <linux/io.h> | 24 | #include <linux/io.h> |
24 | 25 | #include <linux/slab.h> | |
25 | #define KYCR1_OFFS 0x00 | ||
26 | #define KYCR2_OFFS 0x04 | ||
27 | #define KYINDR_OFFS 0x08 | ||
28 | #define KYOUTDR_OFFS 0x0c | ||
29 | |||
30 | #define KYCR2_IRQ_LEVEL 0x10 | ||
31 | #define KYCR2_IRQ_DISABLED 0x00 | ||
32 | 26 | ||
33 | static const struct { | 27 | static const struct { |
34 | unsigned char kymd, keyout, keyin; | 28 | unsigned char kymd, keyout, keyin; |
@@ -36,84 +30,131 @@ static const struct { | |||
36 | [SH_KEYSC_MODE_1] = { 0, 6, 5 }, | 30 | [SH_KEYSC_MODE_1] = { 0, 6, 5 }, |
37 | [SH_KEYSC_MODE_2] = { 1, 5, 6 }, | 31 | [SH_KEYSC_MODE_2] = { 1, 5, 6 }, |
38 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, | 32 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, |
33 | [SH_KEYSC_MODE_4] = { 3, 6, 6 }, | ||
34 | [SH_KEYSC_MODE_5] = { 4, 6, 7 }, | ||
35 | [SH_KEYSC_MODE_6] = { 5, 7, 7 }, | ||
39 | }; | 36 | }; |
40 | 37 | ||
41 | struct sh_keysc_priv { | 38 | struct sh_keysc_priv { |
42 | void __iomem *iomem_base; | 39 | void __iomem *iomem_base; |
43 | struct clk *clk; | 40 | struct clk *clk; |
44 | unsigned long last_keys; | 41 | DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); |
45 | struct input_dev *input; | 42 | struct input_dev *input; |
46 | struct sh_keysc_info pdata; | 43 | struct sh_keysc_info pdata; |
47 | }; | 44 | }; |
48 | 45 | ||
46 | #define KYCR1 0 | ||
47 | #define KYCR2 1 | ||
48 | #define KYINDR 2 | ||
49 | #define KYOUTDR 3 | ||
50 | |||
51 | #define KYCR2_IRQ_LEVEL 0x10 | ||
52 | #define KYCR2_IRQ_DISABLED 0x00 | ||
53 | |||
54 | static unsigned long sh_keysc_read(struct sh_keysc_priv *p, int reg_nr) | ||
55 | { | ||
56 | return ioread16(p->iomem_base + (reg_nr << 2)); | ||
57 | } | ||
58 | |||
59 | static void sh_keysc_write(struct sh_keysc_priv *p, int reg_nr, | ||
60 | unsigned long value) | ||
61 | { | ||
62 | iowrite16(value, p->iomem_base + (reg_nr << 2)); | ||
63 | } | ||
64 | |||
65 | static void sh_keysc_level_mode(struct sh_keysc_priv *p, | ||
66 | unsigned long keys_set) | ||
67 | { | ||
68 | struct sh_keysc_info *pdata = &p->pdata; | ||
69 | |||
70 | sh_keysc_write(p, KYOUTDR, 0); | ||
71 | sh_keysc_write(p, KYCR2, KYCR2_IRQ_LEVEL | (keys_set << 8)); | ||
72 | |||
73 | if (pdata->kycr2_delay) | ||
74 | udelay(pdata->kycr2_delay); | ||
75 | } | ||
76 | |||
77 | static void sh_keysc_map_dbg(struct device *dev, unsigned long *map, | ||
78 | const char *str) | ||
79 | { | ||
80 | int k; | ||
81 | |||
82 | for (k = 0; k < BITS_TO_LONGS(SH_KEYSC_MAXKEYS); k++) | ||
83 | dev_dbg(dev, "%s[%d] 0x%lx\n", str, k, map[k]); | ||
84 | } | ||
85 | |||
49 | static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | 86 | static irqreturn_t sh_keysc_isr(int irq, void *dev_id) |
50 | { | 87 | { |
51 | struct platform_device *pdev = dev_id; | 88 | struct platform_device *pdev = dev_id; |
52 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | 89 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); |
53 | struct sh_keysc_info *pdata = &priv->pdata; | 90 | struct sh_keysc_info *pdata = &priv->pdata; |
54 | unsigned long keys, keys1, keys0, mask; | 91 | int keyout_nr = sh_keysc_mode[pdata->mode].keyout; |
92 | int keyin_nr = sh_keysc_mode[pdata->mode].keyin; | ||
93 | DECLARE_BITMAP(keys, SH_KEYSC_MAXKEYS); | ||
94 | DECLARE_BITMAP(keys0, SH_KEYSC_MAXKEYS); | ||
95 | DECLARE_BITMAP(keys1, SH_KEYSC_MAXKEYS); | ||
55 | unsigned char keyin_set, tmp; | 96 | unsigned char keyin_set, tmp; |
56 | int i, k; | 97 | int i, k, n; |
57 | 98 | ||
58 | dev_dbg(&pdev->dev, "isr!\n"); | 99 | dev_dbg(&pdev->dev, "isr!\n"); |
59 | 100 | ||
60 | keys1 = ~0; | 101 | bitmap_fill(keys1, SH_KEYSC_MAXKEYS); |
61 | keys0 = 0; | 102 | bitmap_zero(keys0, SH_KEYSC_MAXKEYS); |
62 | 103 | ||
63 | do { | 104 | do { |
64 | keys = 0; | 105 | bitmap_zero(keys, SH_KEYSC_MAXKEYS); |
65 | keyin_set = 0; | 106 | keyin_set = 0; |
66 | 107 | ||
67 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | 108 | sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); |
109 | |||
110 | for (i = 0; i < keyout_nr; i++) { | ||
111 | n = keyin_nr * i; | ||
68 | 112 | ||
69 | for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) { | 113 | /* drive one KEYOUT pin low, read KEYIN pins */ |
70 | iowrite16(0xfff ^ (3 << (i * 2)), | 114 | sh_keysc_write(priv, KYOUTDR, 0xffff ^ (3 << (i * 2))); |
71 | priv->iomem_base + KYOUTDR_OFFS); | ||
72 | udelay(pdata->delay); | 115 | udelay(pdata->delay); |
73 | tmp = ioread16(priv->iomem_base + KYINDR_OFFS); | 116 | tmp = sh_keysc_read(priv, KYINDR); |
74 | keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i); | ||
75 | tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1; | ||
76 | keyin_set |= tmp; | ||
77 | } | ||
78 | 117 | ||
79 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 118 | /* set bit if key press has been detected */ |
80 | iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8), | 119 | for (k = 0; k < keyin_nr; k++) { |
81 | priv->iomem_base + KYCR2_OFFS); | 120 | if (tmp & (1 << k)) |
121 | __set_bit(n + k, keys); | ||
122 | } | ||
82 | 123 | ||
83 | if (pdata->kycr2_delay) | 124 | /* keep track of which KEYIN bits that have been set */ |
84 | udelay(pdata->kycr2_delay); | 125 | keyin_set |= tmp ^ ((1 << keyin_nr) - 1); |
126 | } | ||
85 | 127 | ||
86 | keys ^= ~0; | 128 | sh_keysc_level_mode(priv, keyin_set); |
87 | keys &= (1 << (sh_keysc_mode[pdata->mode].keyin * | ||
88 | sh_keysc_mode[pdata->mode].keyout)) - 1; | ||
89 | keys1 &= keys; | ||
90 | keys0 |= keys; | ||
91 | 129 | ||
92 | dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys); | 130 | bitmap_complement(keys, keys, SH_KEYSC_MAXKEYS); |
131 | bitmap_and(keys1, keys1, keys, SH_KEYSC_MAXKEYS); | ||
132 | bitmap_or(keys0, keys0, keys, SH_KEYSC_MAXKEYS); | ||
93 | 133 | ||
94 | } while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01); | 134 | sh_keysc_map_dbg(&pdev->dev, keys, "keys"); |
95 | 135 | ||
96 | dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n", | 136 | } while (sh_keysc_read(priv, KYCR2) & 0x01); |
97 | priv->last_keys, keys0, keys1); | 137 | |
138 | sh_keysc_map_dbg(&pdev->dev, priv->last_keys, "last_keys"); | ||
139 | sh_keysc_map_dbg(&pdev->dev, keys0, "keys0"); | ||
140 | sh_keysc_map_dbg(&pdev->dev, keys1, "keys1"); | ||
98 | 141 | ||
99 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { | 142 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { |
100 | k = pdata->keycodes[i]; | 143 | k = pdata->keycodes[i]; |
101 | if (!k) | 144 | if (!k) |
102 | continue; | 145 | continue; |
103 | 146 | ||
104 | mask = 1 << i; | 147 | if (test_bit(i, keys0) == test_bit(i, priv->last_keys)) |
105 | |||
106 | if (!((priv->last_keys ^ keys0) & mask)) | ||
107 | continue; | 148 | continue; |
108 | 149 | ||
109 | if ((keys1 | keys0) & mask) { | 150 | if (test_bit(i, keys1) || test_bit(i, keys0)) { |
110 | input_event(priv->input, EV_KEY, k, 1); | 151 | input_event(priv->input, EV_KEY, k, 1); |
111 | priv->last_keys |= mask; | 152 | __set_bit(i, priv->last_keys); |
112 | } | 153 | } |
113 | 154 | ||
114 | if (!(keys1 & mask)) { | 155 | if (!test_bit(i, keys1)) { |
115 | input_event(priv->input, EV_KEY, k, 0); | 156 | input_event(priv->input, EV_KEY, k, 0); |
116 | priv->last_keys &= ~mask; | 157 | __clear_bit(i, priv->last_keys); |
117 | } | 158 | } |
118 | 159 | ||
119 | } | 160 | } |
@@ -122,8 +163,6 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | |||
122 | return IRQ_HANDLED; | 163 | return IRQ_HANDLED; |
123 | } | 164 | } |
124 | 165 | ||
125 | #define res_size(res) ((res)->end - (res)->start + 1) | ||
126 | |||
127 | static int __devinit sh_keysc_probe(struct platform_device *pdev) | 166 | static int __devinit sh_keysc_probe(struct platform_device *pdev) |
128 | { | 167 | { |
129 | struct sh_keysc_priv *priv; | 168 | struct sh_keysc_priv *priv; |
@@ -164,7 +203,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
164 | memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); | 203 | memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); |
165 | pdata = &priv->pdata; | 204 | pdata = &priv->pdata; |
166 | 205 | ||
167 | priv->iomem_base = ioremap_nocache(res->start, res_size(res)); | 206 | priv->iomem_base = ioremap_nocache(res->start, resource_size(res)); |
168 | if (priv->iomem_base == NULL) { | 207 | if (priv->iomem_base == NULL) { |
169 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | 208 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); |
170 | error = -ENXIO; | 209 | error = -ENXIO; |
@@ -220,10 +259,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
220 | 259 | ||
221 | clk_enable(priv->clk); | 260 | clk_enable(priv->clk); |
222 | 261 | ||
223 | iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | | 262 | sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | |
224 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); | 263 | pdata->scan_timing); |
225 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 264 | sh_keysc_level_mode(priv, 0); |
226 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); | ||
227 | 265 | ||
228 | device_init_wakeup(&pdev->dev, 1); | 266 | device_init_wakeup(&pdev->dev, 1); |
229 | 267 | ||
@@ -248,7 +286,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
248 | { | 286 | { |
249 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | 287 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); |
250 | 288 | ||
251 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | 289 | sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); |
252 | 290 | ||
253 | input_unregister_device(priv->input); | 291 | input_unregister_device(priv->input); |
254 | free_irq(platform_get_irq(pdev, 0), pdev); | 292 | free_irq(platform_get_irq(pdev, 0), pdev); |
@@ -270,7 +308,7 @@ static int sh_keysc_suspend(struct device *dev) | |||
270 | int irq = platform_get_irq(pdev, 0); | 308 | int irq = platform_get_irq(pdev, 0); |
271 | unsigned short value; | 309 | unsigned short value; |
272 | 310 | ||
273 | value = ioread16(priv->iomem_base + KYCR1_OFFS); | 311 | value = sh_keysc_read(priv, KYCR1); |
274 | 312 | ||
275 | if (device_may_wakeup(dev)) { | 313 | if (device_may_wakeup(dev)) { |
276 | value |= 0x80; | 314 | value |= 0x80; |
@@ -279,7 +317,7 @@ static int sh_keysc_suspend(struct device *dev) | |||
279 | value &= ~0x80; | 317 | value &= ~0x80; |
280 | } | 318 | } |
281 | 319 | ||
282 | iowrite16(value, priv->iomem_base + KYCR1_OFFS); | 320 | sh_keysc_write(priv, KYCR1, value); |
283 | 321 | ||
284 | return 0; | 322 | return 0; |
285 | } | 323 | } |
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c deleted file mode 100644 index 13967422658c..000000000000 --- a/drivers/input/keyboard/spitzkbd.c +++ /dev/null | |||
@@ -1,496 +0,0 @@ | |||
1 | /* | ||
2 | * Keyboard driver for Sharp Spitz, Borzoi and Akita (SL-Cxx00 series) | ||
3 | * | ||
4 | * Copyright (c) 2005 Richard Purdie | ||
5 | * | ||
6 | * Based on corgikbd.c | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/jiffies.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #include <mach/spitz.h> | ||
24 | #include <mach/pxa2xx-gpio.h> | ||
25 | |||
26 | #define KB_ROWS 7 | ||
27 | #define KB_COLS 11 | ||
28 | #define KB_ROWMASK(r) (1 << (r)) | ||
29 | #define SCANCODE(r,c) (((r)<<4) + (c) + 1) | ||
30 | #define NR_SCANCODES ((KB_ROWS<<4) + 1) | ||
31 | |||
32 | #define SCAN_INTERVAL (50) /* ms */ | ||
33 | #define HINGE_SCAN_INTERVAL (150) /* ms */ | ||
34 | |||
35 | #define SPITZ_KEY_CALENDER KEY_F1 | ||
36 | #define SPITZ_KEY_ADDRESS KEY_F2 | ||
37 | #define SPITZ_KEY_FN KEY_F3 | ||
38 | #define SPITZ_KEY_CANCEL KEY_F4 | ||
39 | #define SPITZ_KEY_EXOK KEY_F5 | ||
40 | #define SPITZ_KEY_EXCANCEL KEY_F6 | ||
41 | #define SPITZ_KEY_EXJOGDOWN KEY_F7 | ||
42 | #define SPITZ_KEY_EXJOGUP KEY_F8 | ||
43 | #define SPITZ_KEY_JAP1 KEY_LEFTALT | ||
44 | #define SPITZ_KEY_JAP2 KEY_RIGHTCTRL | ||
45 | #define SPITZ_KEY_SYNC KEY_F9 | ||
46 | #define SPITZ_KEY_MAIL KEY_F10 | ||
47 | #define SPITZ_KEY_OK KEY_F11 | ||
48 | #define SPITZ_KEY_MENU KEY_F12 | ||
49 | |||
50 | static unsigned char spitzkbd_keycode[NR_SCANCODES] = { | ||
51 | 0, /* 0 */ | ||
52 | KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0, /* 1-16 */ | ||
53 | 0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */ | ||
54 | KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */ | ||
55 | SPITZ_KEY_ADDRESS, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */ | ||
56 | SPITZ_KEY_CALENDER, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */ | ||
57 | SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0, /* 81-96 */ | ||
58 | KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0 /* 97-112 */ | ||
59 | }; | ||
60 | |||
61 | static int spitz_strobes[] = { | ||
62 | SPITZ_GPIO_KEY_STROBE0, | ||
63 | SPITZ_GPIO_KEY_STROBE1, | ||
64 | SPITZ_GPIO_KEY_STROBE2, | ||
65 | SPITZ_GPIO_KEY_STROBE3, | ||
66 | SPITZ_GPIO_KEY_STROBE4, | ||
67 | SPITZ_GPIO_KEY_STROBE5, | ||
68 | SPITZ_GPIO_KEY_STROBE6, | ||
69 | SPITZ_GPIO_KEY_STROBE7, | ||
70 | SPITZ_GPIO_KEY_STROBE8, | ||
71 | SPITZ_GPIO_KEY_STROBE9, | ||
72 | SPITZ_GPIO_KEY_STROBE10, | ||
73 | }; | ||
74 | |||
75 | static int spitz_senses[] = { | ||
76 | SPITZ_GPIO_KEY_SENSE0, | ||
77 | SPITZ_GPIO_KEY_SENSE1, | ||
78 | SPITZ_GPIO_KEY_SENSE2, | ||
79 | SPITZ_GPIO_KEY_SENSE3, | ||
80 | SPITZ_GPIO_KEY_SENSE4, | ||
81 | SPITZ_GPIO_KEY_SENSE5, | ||
82 | SPITZ_GPIO_KEY_SENSE6, | ||
83 | }; | ||
84 | |||
85 | struct spitzkbd { | ||
86 | unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)]; | ||
87 | struct input_dev *input; | ||
88 | char phys[32]; | ||
89 | |||
90 | spinlock_t lock; | ||
91 | struct timer_list timer; | ||
92 | struct timer_list htimer; | ||
93 | |||
94 | unsigned int suspended; | ||
95 | unsigned long suspend_jiffies; | ||
96 | }; | ||
97 | |||
98 | #define KB_DISCHARGE_DELAY 10 | ||
99 | #define KB_ACTIVATE_DELAY 10 | ||
100 | |||
101 | /* Helper functions for reading the keyboard matrix | ||
102 | * Note: We should really be using the generic gpio functions to alter | ||
103 | * GPDR but it requires a function call per GPIO bit which is | ||
104 | * excessive when we need to access 11 bits at once, multiple times. | ||
105 | * These functions must be called within local_irq_save()/local_irq_restore() | ||
106 | * or similar. | ||
107 | */ | ||
108 | static inline void spitzkbd_discharge_all(void) | ||
109 | { | ||
110 | /* STROBE All HiZ */ | ||
111 | GPCR0 = SPITZ_GPIO_G0_STROBE_BIT; | ||
112 | GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT; | ||
113 | GPCR1 = SPITZ_GPIO_G1_STROBE_BIT; | ||
114 | GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT; | ||
115 | GPCR2 = SPITZ_GPIO_G2_STROBE_BIT; | ||
116 | GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT; | ||
117 | GPCR3 = SPITZ_GPIO_G3_STROBE_BIT; | ||
118 | GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; | ||
119 | } | ||
120 | |||
121 | static inline void spitzkbd_activate_all(void) | ||
122 | { | ||
123 | /* STROBE ALL -> High */ | ||
124 | GPSR0 = SPITZ_GPIO_G0_STROBE_BIT; | ||
125 | GPDR0 |= SPITZ_GPIO_G0_STROBE_BIT; | ||
126 | GPSR1 = SPITZ_GPIO_G1_STROBE_BIT; | ||
127 | GPDR1 |= SPITZ_GPIO_G1_STROBE_BIT; | ||
128 | GPSR2 = SPITZ_GPIO_G2_STROBE_BIT; | ||
129 | GPDR2 |= SPITZ_GPIO_G2_STROBE_BIT; | ||
130 | GPSR3 = SPITZ_GPIO_G3_STROBE_BIT; | ||
131 | GPDR3 |= SPITZ_GPIO_G3_STROBE_BIT; | ||
132 | |||
133 | udelay(KB_DISCHARGE_DELAY); | ||
134 | |||
135 | /* Clear any interrupts we may have triggered when altering the GPIO lines */ | ||
136 | GEDR0 = SPITZ_GPIO_G0_SENSE_BIT; | ||
137 | GEDR1 = SPITZ_GPIO_G1_SENSE_BIT; | ||
138 | GEDR2 = SPITZ_GPIO_G2_SENSE_BIT; | ||
139 | GEDR3 = SPITZ_GPIO_G3_SENSE_BIT; | ||
140 | } | ||
141 | |||
142 | static inline void spitzkbd_activate_col(int col) | ||
143 | { | ||
144 | int gpio = spitz_strobes[col]; | ||
145 | GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT; | ||
146 | GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT; | ||
147 | GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT; | ||
148 | GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; | ||
149 | GPSR(gpio) = GPIO_bit(gpio); | ||
150 | GPDR(gpio) |= GPIO_bit(gpio); | ||
151 | } | ||
152 | |||
153 | static inline void spitzkbd_reset_col(int col) | ||
154 | { | ||
155 | int gpio = spitz_strobes[col]; | ||
156 | GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT; | ||
157 | GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT; | ||
158 | GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT; | ||
159 | GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; | ||
160 | GPCR(gpio) = GPIO_bit(gpio); | ||
161 | GPDR(gpio) |= GPIO_bit(gpio); | ||
162 | } | ||
163 | |||
164 | static inline int spitzkbd_get_row_status(int col) | ||
165 | { | ||
166 | return ((GPLR0 >> 12) & 0x01) | ((GPLR0 >> 16) & 0x02) | ||
167 | | ((GPLR2 >> 25) & 0x04) | ((GPLR1 << 1) & 0x08) | ||
168 | | ((GPLR1 >> 0) & 0x10) | ((GPLR1 >> 1) & 0x60); | ||
169 | } | ||
170 | |||
171 | /* | ||
172 | * The spitz keyboard only generates interrupts when a key is pressed. | ||
173 | * When a key is pressed, we enable a timer which then scans the | ||
174 | * keyboard to detect when the key is released. | ||
175 | */ | ||
176 | |||
177 | /* Scan the hardware keyboard and push any changes up through the input layer */ | ||
178 | static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data) | ||
179 | { | ||
180 | unsigned int row, col, rowd; | ||
181 | unsigned long flags; | ||
182 | unsigned int num_pressed, pwrkey = ((GPLR(SPITZ_GPIO_ON_KEY) & GPIO_bit(SPITZ_GPIO_ON_KEY)) != 0); | ||
183 | |||
184 | if (spitzkbd_data->suspended) | ||
185 | return; | ||
186 | |||
187 | spin_lock_irqsave(&spitzkbd_data->lock, flags); | ||
188 | |||
189 | num_pressed = 0; | ||
190 | for (col = 0; col < KB_COLS; col++) { | ||
191 | /* | ||
192 | * Discharge the output driver capacitatance | ||
193 | * in the keyboard matrix. (Yes it is significant..) | ||
194 | */ | ||
195 | |||
196 | spitzkbd_discharge_all(); | ||
197 | udelay(KB_DISCHARGE_DELAY); | ||
198 | |||
199 | spitzkbd_activate_col(col); | ||
200 | udelay(KB_ACTIVATE_DELAY); | ||
201 | |||
202 | rowd = spitzkbd_get_row_status(col); | ||
203 | for (row = 0; row < KB_ROWS; row++) { | ||
204 | unsigned int scancode, pressed; | ||
205 | |||
206 | scancode = SCANCODE(row, col); | ||
207 | pressed = rowd & KB_ROWMASK(row); | ||
208 | |||
209 | input_report_key(spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed); | ||
210 | |||
211 | if (pressed) | ||
212 | num_pressed++; | ||
213 | } | ||
214 | spitzkbd_reset_col(col); | ||
215 | } | ||
216 | |||
217 | spitzkbd_activate_all(); | ||
218 | |||
219 | input_report_key(spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 ); | ||
220 | input_report_key(spitzkbd_data->input, KEY_SUSPEND, pwrkey); | ||
221 | |||
222 | if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) { | ||
223 | input_event(spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1); | ||
224 | spitzkbd_data->suspend_jiffies = jiffies; | ||
225 | } | ||
226 | |||
227 | input_sync(spitzkbd_data->input); | ||
228 | |||
229 | /* if any keys are pressed, enable the timer */ | ||
230 | if (num_pressed) | ||
231 | mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL)); | ||
232 | |||
233 | spin_unlock_irqrestore(&spitzkbd_data->lock, flags); | ||
234 | } | ||
235 | |||
236 | /* | ||
237 | * spitz keyboard interrupt handler. | ||
238 | */ | ||
239 | static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id) | ||
240 | { | ||
241 | struct spitzkbd *spitzkbd_data = dev_id; | ||
242 | |||
243 | if (!timer_pending(&spitzkbd_data->timer)) { | ||
244 | /** wait chattering delay **/ | ||
245 | udelay(20); | ||
246 | spitzkbd_scankeyboard(spitzkbd_data); | ||
247 | } | ||
248 | |||
249 | return IRQ_HANDLED; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * spitz timer checking for released keys | ||
254 | */ | ||
255 | static void spitzkbd_timer_callback(unsigned long data) | ||
256 | { | ||
257 | struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data; | ||
258 | |||
259 | spitzkbd_scankeyboard(spitzkbd_data); | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * The hinge switches generate an interrupt. | ||
264 | * We debounce the switches and pass them to the input system. | ||
265 | */ | ||
266 | |||
267 | static irqreturn_t spitzkbd_hinge_isr(int irq, void *dev_id) | ||
268 | { | ||
269 | struct spitzkbd *spitzkbd_data = dev_id; | ||
270 | |||
271 | if (!timer_pending(&spitzkbd_data->htimer)) | ||
272 | mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); | ||
273 | |||
274 | return IRQ_HANDLED; | ||
275 | } | ||
276 | |||
277 | #define HINGE_STABLE_COUNT 2 | ||
278 | static int sharpsl_hinge_state; | ||
279 | static int hinge_count; | ||
280 | |||
281 | static void spitzkbd_hinge_timer(unsigned long data) | ||
282 | { | ||
283 | struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data; | ||
284 | unsigned long state; | ||
285 | unsigned long flags; | ||
286 | |||
287 | state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB)); | ||
288 | state |= (GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)); | ||
289 | if (state != sharpsl_hinge_state) { | ||
290 | hinge_count = 0; | ||
291 | sharpsl_hinge_state = state; | ||
292 | } else if (hinge_count < HINGE_STABLE_COUNT) { | ||
293 | hinge_count++; | ||
294 | } | ||
295 | |||
296 | if (hinge_count >= HINGE_STABLE_COUNT) { | ||
297 | spin_lock_irqsave(&spitzkbd_data->lock, flags); | ||
298 | |||
299 | input_report_switch(spitzkbd_data->input, SW_LID, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0)); | ||
300 | input_report_switch(spitzkbd_data->input, SW_TABLET_MODE, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0)); | ||
301 | input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0)); | ||
302 | input_sync(spitzkbd_data->input); | ||
303 | |||
304 | spin_unlock_irqrestore(&spitzkbd_data->lock, flags); | ||
305 | } else { | ||
306 | mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | #ifdef CONFIG_PM | ||
311 | static int spitzkbd_suspend(struct platform_device *dev, pm_message_t state) | ||
312 | { | ||
313 | int i; | ||
314 | struct spitzkbd *spitzkbd = platform_get_drvdata(dev); | ||
315 | spitzkbd->suspended = 1; | ||
316 | |||
317 | /* Set Strobe lines as inputs - *except* strobe line 0 leave this | ||
318 | enabled so we can detect a power button press for resume */ | ||
319 | for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++) | ||
320 | pxa_gpio_mode(spitz_strobes[i] | GPIO_IN); | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int spitzkbd_resume(struct platform_device *dev) | ||
326 | { | ||
327 | int i; | ||
328 | struct spitzkbd *spitzkbd = platform_get_drvdata(dev); | ||
329 | |||
330 | for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++) | ||
331 | pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH); | ||
332 | |||
333 | /* Upon resume, ignore the suspend key for a short while */ | ||
334 | spitzkbd->suspend_jiffies = jiffies; | ||
335 | spitzkbd->suspended = 0; | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | #else | ||
340 | #define spitzkbd_suspend NULL | ||
341 | #define spitzkbd_resume NULL | ||
342 | #endif | ||
343 | |||
344 | static int __devinit spitzkbd_probe(struct platform_device *dev) | ||
345 | { | ||
346 | struct spitzkbd *spitzkbd; | ||
347 | struct input_dev *input_dev; | ||
348 | int i, err = -ENOMEM; | ||
349 | |||
350 | spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL); | ||
351 | input_dev = input_allocate_device(); | ||
352 | if (!spitzkbd || !input_dev) | ||
353 | goto fail; | ||
354 | |||
355 | platform_set_drvdata(dev, spitzkbd); | ||
356 | strcpy(spitzkbd->phys, "spitzkbd/input0"); | ||
357 | |||
358 | spin_lock_init(&spitzkbd->lock); | ||
359 | |||
360 | /* Init Keyboard rescan timer */ | ||
361 | init_timer(&spitzkbd->timer); | ||
362 | spitzkbd->timer.function = spitzkbd_timer_callback; | ||
363 | spitzkbd->timer.data = (unsigned long) spitzkbd; | ||
364 | |||
365 | /* Init Hinge Timer */ | ||
366 | init_timer(&spitzkbd->htimer); | ||
367 | spitzkbd->htimer.function = spitzkbd_hinge_timer; | ||
368 | spitzkbd->htimer.data = (unsigned long) spitzkbd; | ||
369 | |||
370 | spitzkbd->suspend_jiffies = jiffies; | ||
371 | |||
372 | spitzkbd->input = input_dev; | ||
373 | |||
374 | input_dev->name = "Spitz Keyboard"; | ||
375 | input_dev->phys = spitzkbd->phys; | ||
376 | input_dev->dev.parent = &dev->dev; | ||
377 | |||
378 | input_dev->id.bustype = BUS_HOST; | ||
379 | input_dev->id.vendor = 0x0001; | ||
380 | input_dev->id.product = 0x0001; | ||
381 | input_dev->id.version = 0x0100; | ||
382 | |||
383 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | | ||
384 | BIT_MASK(EV_PWR) | BIT_MASK(EV_SW); | ||
385 | input_dev->keycode = spitzkbd->keycode; | ||
386 | input_dev->keycodesize = sizeof(unsigned char); | ||
387 | input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode); | ||
388 | |||
389 | memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode)); | ||
390 | for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++) | ||
391 | set_bit(spitzkbd->keycode[i], input_dev->keybit); | ||
392 | clear_bit(0, input_dev->keybit); | ||
393 | set_bit(KEY_SUSPEND, input_dev->keybit); | ||
394 | set_bit(SW_LID, input_dev->swbit); | ||
395 | set_bit(SW_TABLET_MODE, input_dev->swbit); | ||
396 | set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); | ||
397 | |||
398 | err = input_register_device(input_dev); | ||
399 | if (err) | ||
400 | goto fail; | ||
401 | |||
402 | mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); | ||
403 | |||
404 | /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ | ||
405 | for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) { | ||
406 | pxa_gpio_mode(spitz_senses[i] | GPIO_IN); | ||
407 | if (request_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd_interrupt, | ||
408 | IRQF_DISABLED|IRQF_TRIGGER_RISING, | ||
409 | "Spitzkbd Sense", spitzkbd)) | ||
410 | printk(KERN_WARNING "spitzkbd: Can't get Sense IRQ: %d!\n", i); | ||
411 | } | ||
412 | |||
413 | /* Set Strobe lines as outputs - set high */ | ||
414 | for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++) | ||
415 | pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH); | ||
416 | |||
417 | pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN); | ||
418 | pxa_gpio_mode(SPITZ_GPIO_ON_KEY | GPIO_IN); | ||
419 | pxa_gpio_mode(SPITZ_GPIO_SWA | GPIO_IN); | ||
420 | pxa_gpio_mode(SPITZ_GPIO_SWB | GPIO_IN); | ||
421 | |||
422 | request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt, | ||
423 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
424 | "Spitzkbd Sync", spitzkbd); | ||
425 | request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt, | ||
426 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
427 | "Spitzkbd PwrOn", spitzkbd); | ||
428 | request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr, | ||
429 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
430 | "Spitzkbd SWA", spitzkbd); | ||
431 | request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, | ||
432 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
433 | "Spitzkbd SWB", spitzkbd); | ||
434 | request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, | ||
435 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
436 | "Spitzkbd HP", spitzkbd); | ||
437 | |||
438 | return 0; | ||
439 | |||
440 | fail: input_free_device(input_dev); | ||
441 | kfree(spitzkbd); | ||
442 | return err; | ||
443 | } | ||
444 | |||
445 | static int __devexit spitzkbd_remove(struct platform_device *dev) | ||
446 | { | ||
447 | int i; | ||
448 | struct spitzkbd *spitzkbd = platform_get_drvdata(dev); | ||
449 | |||
450 | for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) | ||
451 | free_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd); | ||
452 | |||
453 | free_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd); | ||
454 | free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd); | ||
455 | free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd); | ||
456 | free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd); | ||
457 | free_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd); | ||
458 | |||
459 | del_timer_sync(&spitzkbd->htimer); | ||
460 | del_timer_sync(&spitzkbd->timer); | ||
461 | |||
462 | input_unregister_device(spitzkbd->input); | ||
463 | |||
464 | kfree(spitzkbd); | ||
465 | |||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | static struct platform_driver spitzkbd_driver = { | ||
470 | .probe = spitzkbd_probe, | ||
471 | .remove = __devexit_p(spitzkbd_remove), | ||
472 | .suspend = spitzkbd_suspend, | ||
473 | .resume = spitzkbd_resume, | ||
474 | .driver = { | ||
475 | .name = "spitz-keyboard", | ||
476 | .owner = THIS_MODULE, | ||
477 | }, | ||
478 | }; | ||
479 | |||
480 | static int __init spitzkbd_init(void) | ||
481 | { | ||
482 | return platform_driver_register(&spitzkbd_driver); | ||
483 | } | ||
484 | |||
485 | static void __exit spitzkbd_exit(void) | ||
486 | { | ||
487 | platform_driver_unregister(&spitzkbd_driver); | ||
488 | } | ||
489 | |||
490 | module_init(spitzkbd_init); | ||
491 | module_exit(spitzkbd_exit); | ||
492 | |||
493 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | ||
494 | MODULE_DESCRIPTION("Spitz Keyboard Driver"); | ||
495 | MODULE_LICENSE("GPL v2"); | ||
496 | MODULE_ALIAS("platform:spitz-keyboard"); | ||
diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c new file mode 100644 index 000000000000..ab7610ca10eb --- /dev/null +++ b/drivers/input/keyboard/stmpe-keypad.c | |||
@@ -0,0 +1,386 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License, version 2 | ||
5 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
6 | */ | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/slab.h> | ||
11 | #include <linux/input.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/input/matrix_keypad.h> | ||
15 | #include <linux/mfd/stmpe.h> | ||
16 | |||
17 | /* These are at the same addresses in all STMPE variants */ | ||
18 | #define STMPE_KPC_COL 0x60 | ||
19 | #define STMPE_KPC_ROW_MSB 0x61 | ||
20 | #define STMPE_KPC_ROW_LSB 0x62 | ||
21 | #define STMPE_KPC_CTRL_MSB 0x63 | ||
22 | #define STMPE_KPC_CTRL_LSB 0x64 | ||
23 | #define STMPE_KPC_COMBI_KEY_0 0x65 | ||
24 | #define STMPE_KPC_COMBI_KEY_1 0x66 | ||
25 | #define STMPE_KPC_COMBI_KEY_2 0x67 | ||
26 | #define STMPE_KPC_DATA_BYTE0 0x68 | ||
27 | #define STMPE_KPC_DATA_BYTE1 0x69 | ||
28 | #define STMPE_KPC_DATA_BYTE2 0x6a | ||
29 | #define STMPE_KPC_DATA_BYTE3 0x6b | ||
30 | #define STMPE_KPC_DATA_BYTE4 0x6c | ||
31 | |||
32 | #define STMPE_KPC_CTRL_LSB_SCAN (0x1 << 0) | ||
33 | #define STMPE_KPC_CTRL_LSB_DEBOUNCE (0x7f << 1) | ||
34 | #define STMPE_KPC_CTRL_MSB_SCAN_COUNT (0xf << 4) | ||
35 | |||
36 | #define STMPE_KPC_ROW_MSB_ROWS 0xff | ||
37 | |||
38 | #define STMPE_KPC_DATA_UP (0x1 << 7) | ||
39 | #define STMPE_KPC_DATA_ROW (0xf << 3) | ||
40 | #define STMPE_KPC_DATA_COL (0x7 << 0) | ||
41 | #define STMPE_KPC_DATA_NOKEY_MASK 0x78 | ||
42 | |||
43 | #define STMPE_KEYPAD_MAX_DEBOUNCE 127 | ||
44 | #define STMPE_KEYPAD_MAX_SCAN_COUNT 15 | ||
45 | |||
46 | #define STMPE_KEYPAD_MAX_ROWS 8 | ||
47 | #define STMPE_KEYPAD_MAX_COLS 8 | ||
48 | #define STMPE_KEYPAD_ROW_SHIFT 3 | ||
49 | #define STMPE_KEYPAD_KEYMAP_SIZE \ | ||
50 | (STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS) | ||
51 | |||
52 | /** | ||
53 | * struct stmpe_keypad_variant - model-specific attributes | ||
54 | * @auto_increment: whether the KPC_DATA_BYTE register address | ||
55 | * auto-increments on multiple read | ||
56 | * @num_data: number of data bytes | ||
57 | * @num_normal_data: number of normal keys' data bytes | ||
58 | * @max_cols: maximum number of columns supported | ||
59 | * @max_rows: maximum number of rows supported | ||
60 | * @col_gpios: bitmask of gpios which can be used for columns | ||
61 | * @row_gpios: bitmask of gpios which can be used for rows | ||
62 | */ | ||
63 | struct stmpe_keypad_variant { | ||
64 | bool auto_increment; | ||
65 | int num_data; | ||
66 | int num_normal_data; | ||
67 | int max_cols; | ||
68 | int max_rows; | ||
69 | unsigned int col_gpios; | ||
70 | unsigned int row_gpios; | ||
71 | }; | ||
72 | |||
73 | static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { | ||
74 | [STMPE1601] = { | ||
75 | .auto_increment = true, | ||
76 | .num_data = 5, | ||
77 | .num_normal_data = 3, | ||
78 | .max_cols = 8, | ||
79 | .max_rows = 8, | ||
80 | .col_gpios = 0x000ff, /* GPIO 0 - 7 */ | ||
81 | .row_gpios = 0x0ff00, /* GPIO 8 - 15 */ | ||
82 | }, | ||
83 | [STMPE2401] = { | ||
84 | .auto_increment = false, | ||
85 | .num_data = 3, | ||
86 | .num_normal_data = 2, | ||
87 | .max_cols = 8, | ||
88 | .max_rows = 12, | ||
89 | .col_gpios = 0x0000ff, /* GPIO 0 - 7*/ | ||
90 | .row_gpios = 0x1fef00, /* GPIO 8-14, 16-20 */ | ||
91 | }, | ||
92 | [STMPE2403] = { | ||
93 | .auto_increment = true, | ||
94 | .num_data = 5, | ||
95 | .num_normal_data = 3, | ||
96 | .max_cols = 8, | ||
97 | .max_rows = 12, | ||
98 | .col_gpios = 0x0000ff, /* GPIO 0 - 7*/ | ||
99 | .row_gpios = 0x1fef00, /* GPIO 8-14, 16-20 */ | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | struct stmpe_keypad { | ||
104 | struct stmpe *stmpe; | ||
105 | struct input_dev *input; | ||
106 | const struct stmpe_keypad_variant *variant; | ||
107 | const struct stmpe_keypad_platform_data *plat; | ||
108 | |||
109 | unsigned int rows; | ||
110 | unsigned int cols; | ||
111 | |||
112 | unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE]; | ||
113 | }; | ||
114 | |||
115 | static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data) | ||
116 | { | ||
117 | const struct stmpe_keypad_variant *variant = keypad->variant; | ||
118 | struct stmpe *stmpe = keypad->stmpe; | ||
119 | int ret; | ||
120 | int i; | ||
121 | |||
122 | if (variant->auto_increment) | ||
123 | return stmpe_block_read(stmpe, STMPE_KPC_DATA_BYTE0, | ||
124 | variant->num_data, data); | ||
125 | |||
126 | for (i = 0; i < variant->num_data; i++) { | ||
127 | ret = stmpe_reg_read(stmpe, STMPE_KPC_DATA_BYTE0 + i); | ||
128 | if (ret < 0) | ||
129 | return ret; | ||
130 | |||
131 | data[i] = ret; | ||
132 | } | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static irqreturn_t stmpe_keypad_irq(int irq, void *dev) | ||
138 | { | ||
139 | struct stmpe_keypad *keypad = dev; | ||
140 | struct input_dev *input = keypad->input; | ||
141 | const struct stmpe_keypad_variant *variant = keypad->variant; | ||
142 | u8 fifo[variant->num_data]; | ||
143 | int ret; | ||
144 | int i; | ||
145 | |||
146 | ret = stmpe_keypad_read_data(keypad, fifo); | ||
147 | if (ret < 0) | ||
148 | return IRQ_NONE; | ||
149 | |||
150 | for (i = 0; i < variant->num_normal_data; i++) { | ||
151 | u8 data = fifo[i]; | ||
152 | int row = (data & STMPE_KPC_DATA_ROW) >> 3; | ||
153 | int col = data & STMPE_KPC_DATA_COL; | ||
154 | int code = MATRIX_SCAN_CODE(row, col, STMPE_KEYPAD_ROW_SHIFT); | ||
155 | bool up = data & STMPE_KPC_DATA_UP; | ||
156 | |||
157 | if ((data & STMPE_KPC_DATA_NOKEY_MASK) | ||
158 | == STMPE_KPC_DATA_NOKEY_MASK) | ||
159 | continue; | ||
160 | |||
161 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
162 | input_report_key(input, keypad->keymap[code], !up); | ||
163 | input_sync(input); | ||
164 | } | ||
165 | |||
166 | return IRQ_HANDLED; | ||
167 | } | ||
168 | |||
169 | static int __devinit stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | ||
170 | { | ||
171 | const struct stmpe_keypad_variant *variant = keypad->variant; | ||
172 | unsigned int col_gpios = variant->col_gpios; | ||
173 | unsigned int row_gpios = variant->row_gpios; | ||
174 | struct stmpe *stmpe = keypad->stmpe; | ||
175 | unsigned int pins = 0; | ||
176 | int i; | ||
177 | |||
178 | /* | ||
179 | * Figure out which pins need to be set to the keypad alternate | ||
180 | * function. | ||
181 | * | ||
182 | * {cols,rows}_gpios are bitmasks of which pins on the chip can be used | ||
183 | * for the keypad. | ||
184 | * | ||
185 | * keypad->{cols,rows} are a bitmask of which pins (of the ones useable | ||
186 | * for the keypad) are used on the board. | ||
187 | */ | ||
188 | |||
189 | for (i = 0; i < variant->max_cols; i++) { | ||
190 | int num = __ffs(col_gpios); | ||
191 | |||
192 | if (keypad->cols & (1 << i)) | ||
193 | pins |= 1 << num; | ||
194 | |||
195 | col_gpios &= ~(1 << num); | ||
196 | } | ||
197 | |||
198 | for (i = 0; i < variant->max_rows; i++) { | ||
199 | int num = __ffs(row_gpios); | ||
200 | |||
201 | if (keypad->rows & (1 << i)) | ||
202 | pins |= 1 << num; | ||
203 | |||
204 | row_gpios &= ~(1 << num); | ||
205 | } | ||
206 | |||
207 | return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); | ||
208 | } | ||
209 | |||
210 | static int __devinit stmpe_keypad_chip_init(struct stmpe_keypad *keypad) | ||
211 | { | ||
212 | const struct stmpe_keypad_platform_data *plat = keypad->plat; | ||
213 | const struct stmpe_keypad_variant *variant = keypad->variant; | ||
214 | struct stmpe *stmpe = keypad->stmpe; | ||
215 | int ret; | ||
216 | |||
217 | if (plat->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE) | ||
218 | return -EINVAL; | ||
219 | |||
220 | if (plat->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT) | ||
221 | return -EINVAL; | ||
222 | |||
223 | ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD); | ||
224 | if (ret < 0) | ||
225 | return ret; | ||
226 | |||
227 | ret = stmpe_keypad_altfunc_init(keypad); | ||
228 | if (ret < 0) | ||
229 | return ret; | ||
230 | |||
231 | ret = stmpe_reg_write(stmpe, STMPE_KPC_COL, keypad->cols); | ||
232 | if (ret < 0) | ||
233 | return ret; | ||
234 | |||
235 | ret = stmpe_reg_write(stmpe, STMPE_KPC_ROW_LSB, keypad->rows); | ||
236 | if (ret < 0) | ||
237 | return ret; | ||
238 | |||
239 | if (variant->max_rows > 8) { | ||
240 | ret = stmpe_set_bits(stmpe, STMPE_KPC_ROW_MSB, | ||
241 | STMPE_KPC_ROW_MSB_ROWS, | ||
242 | keypad->rows >> 8); | ||
243 | if (ret < 0) | ||
244 | return ret; | ||
245 | } | ||
246 | |||
247 | ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB, | ||
248 | STMPE_KPC_CTRL_MSB_SCAN_COUNT, | ||
249 | plat->scan_count << 4); | ||
250 | if (ret < 0) | ||
251 | return ret; | ||
252 | |||
253 | return stmpe_set_bits(stmpe, STMPE_KPC_CTRL_LSB, | ||
254 | STMPE_KPC_CTRL_LSB_SCAN | | ||
255 | STMPE_KPC_CTRL_LSB_DEBOUNCE, | ||
256 | STMPE_KPC_CTRL_LSB_SCAN | | ||
257 | (plat->debounce_ms << 1)); | ||
258 | } | ||
259 | |||
260 | static int __devinit stmpe_keypad_probe(struct platform_device *pdev) | ||
261 | { | ||
262 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | ||
263 | struct stmpe_keypad_platform_data *plat; | ||
264 | struct stmpe_keypad *keypad; | ||
265 | struct input_dev *input; | ||
266 | int ret; | ||
267 | int irq; | ||
268 | int i; | ||
269 | |||
270 | plat = stmpe->pdata->keypad; | ||
271 | if (!plat) | ||
272 | return -ENODEV; | ||
273 | |||
274 | irq = platform_get_irq(pdev, 0); | ||
275 | if (irq < 0) | ||
276 | return irq; | ||
277 | |||
278 | keypad = kzalloc(sizeof(struct stmpe_keypad), GFP_KERNEL); | ||
279 | if (!keypad) | ||
280 | return -ENOMEM; | ||
281 | |||
282 | input = input_allocate_device(); | ||
283 | if (!input) { | ||
284 | ret = -ENOMEM; | ||
285 | goto out_freekeypad; | ||
286 | } | ||
287 | |||
288 | input->name = "STMPE keypad"; | ||
289 | input->id.bustype = BUS_I2C; | ||
290 | input->dev.parent = &pdev->dev; | ||
291 | |||
292 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
293 | |||
294 | __set_bit(EV_KEY, input->evbit); | ||
295 | if (!plat->no_autorepeat) | ||
296 | __set_bit(EV_REP, input->evbit); | ||
297 | |||
298 | input->keycode = keypad->keymap; | ||
299 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
300 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
301 | |||
302 | matrix_keypad_build_keymap(plat->keymap_data, STMPE_KEYPAD_ROW_SHIFT, | ||
303 | input->keycode, input->keybit); | ||
304 | |||
305 | for (i = 0; i < plat->keymap_data->keymap_size; i++) { | ||
306 | unsigned int key = plat->keymap_data->keymap[i]; | ||
307 | |||
308 | keypad->cols |= 1 << KEY_COL(key); | ||
309 | keypad->rows |= 1 << KEY_ROW(key); | ||
310 | } | ||
311 | |||
312 | keypad->stmpe = stmpe; | ||
313 | keypad->plat = plat; | ||
314 | keypad->input = input; | ||
315 | keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; | ||
316 | |||
317 | ret = stmpe_keypad_chip_init(keypad); | ||
318 | if (ret < 0) | ||
319 | goto out_freeinput; | ||
320 | |||
321 | ret = input_register_device(input); | ||
322 | if (ret) { | ||
323 | dev_err(&pdev->dev, | ||
324 | "unable to register input device: %d\n", ret); | ||
325 | goto out_freeinput; | ||
326 | } | ||
327 | |||
328 | ret = request_threaded_irq(irq, NULL, stmpe_keypad_irq, IRQF_ONESHOT, | ||
329 | "stmpe-keypad", keypad); | ||
330 | if (ret) { | ||
331 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); | ||
332 | goto out_unregisterinput; | ||
333 | } | ||
334 | |||
335 | platform_set_drvdata(pdev, keypad); | ||
336 | |||
337 | return 0; | ||
338 | |||
339 | out_unregisterinput: | ||
340 | input_unregister_device(input); | ||
341 | input = NULL; | ||
342 | out_freeinput: | ||
343 | input_free_device(input); | ||
344 | out_freekeypad: | ||
345 | kfree(keypad); | ||
346 | return ret; | ||
347 | } | ||
348 | |||
349 | static int __devexit stmpe_keypad_remove(struct platform_device *pdev) | ||
350 | { | ||
351 | struct stmpe_keypad *keypad = platform_get_drvdata(pdev); | ||
352 | struct stmpe *stmpe = keypad->stmpe; | ||
353 | int irq = platform_get_irq(pdev, 0); | ||
354 | |||
355 | stmpe_disable(stmpe, STMPE_BLOCK_KEYPAD); | ||
356 | |||
357 | free_irq(irq, keypad); | ||
358 | input_unregister_device(keypad->input); | ||
359 | platform_set_drvdata(pdev, NULL); | ||
360 | kfree(keypad); | ||
361 | |||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | static struct platform_driver stmpe_keypad_driver = { | ||
366 | .driver.name = "stmpe-keypad", | ||
367 | .driver.owner = THIS_MODULE, | ||
368 | .probe = stmpe_keypad_probe, | ||
369 | .remove = __devexit_p(stmpe_keypad_remove), | ||
370 | }; | ||
371 | |||
372 | static int __init stmpe_keypad_init(void) | ||
373 | { | ||
374 | return platform_driver_register(&stmpe_keypad_driver); | ||
375 | } | ||
376 | module_init(stmpe_keypad_init); | ||
377 | |||
378 | static void __exit stmpe_keypad_exit(void) | ||
379 | { | ||
380 | platform_driver_unregister(&stmpe_keypad_driver); | ||
381 | } | ||
382 | module_exit(stmpe_keypad_exit); | ||
383 | |||
384 | MODULE_LICENSE("GPL v2"); | ||
385 | MODULE_DESCRIPTION("STMPExxxx keypad driver"); | ||
386 | MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>"); | ||
diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c new file mode 100644 index 000000000000..00137bebcf97 --- /dev/null +++ b/drivers/input/keyboard/tca6416-keypad.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* | ||
2 | * Driver for keys on TCA6416 I2C IO expander | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * Author : Sriramakrishnan.A.G. <srk@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/types.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/workqueue.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/tca6416_keypad.h> | ||
24 | |||
25 | #define TCA6416_INPUT 0 | ||
26 | #define TCA6416_OUTPUT 1 | ||
27 | #define TCA6416_INVERT 2 | ||
28 | #define TCA6416_DIRECTION 3 | ||
29 | |||
30 | static const struct i2c_device_id tca6416_id[] = { | ||
31 | { "tca6416-keys", 16, }, | ||
32 | { } | ||
33 | }; | ||
34 | MODULE_DEVICE_TABLE(i2c, tca6416_id); | ||
35 | |||
36 | struct tca6416_drv_data { | ||
37 | struct input_dev *input; | ||
38 | struct tca6416_button data[0]; | ||
39 | }; | ||
40 | |||
41 | struct tca6416_keypad_chip { | ||
42 | uint16_t reg_output; | ||
43 | uint16_t reg_direction; | ||
44 | uint16_t reg_input; | ||
45 | |||
46 | struct i2c_client *client; | ||
47 | struct input_dev *input; | ||
48 | struct delayed_work dwork; | ||
49 | u16 pinmask; | ||
50 | int irqnum; | ||
51 | bool use_polling; | ||
52 | struct tca6416_button buttons[0]; | ||
53 | }; | ||
54 | |||
55 | static int tca6416_write_reg(struct tca6416_keypad_chip *chip, int reg, u16 val) | ||
56 | { | ||
57 | int error; | ||
58 | |||
59 | error = i2c_smbus_write_word_data(chip->client, reg << 1, val); | ||
60 | if (error < 0) { | ||
61 | dev_err(&chip->client->dev, | ||
62 | "%s failed, reg: %d, val: %d, error: %d\n", | ||
63 | __func__, reg, val, error); | ||
64 | return error; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int tca6416_read_reg(struct tca6416_keypad_chip *chip, int reg, u16 *val) | ||
71 | { | ||
72 | int retval; | ||
73 | |||
74 | retval = i2c_smbus_read_word_data(chip->client, reg << 1); | ||
75 | if (retval < 0) { | ||
76 | dev_err(&chip->client->dev, "%s failed, reg: %d, error: %d\n", | ||
77 | __func__, reg, retval); | ||
78 | return retval; | ||
79 | } | ||
80 | |||
81 | *val = (u16)retval; | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static void tca6416_keys_scan(struct tca6416_keypad_chip *chip) | ||
86 | { | ||
87 | struct input_dev *input = chip->input; | ||
88 | u16 reg_val, val; | ||
89 | int error, i, pin_index; | ||
90 | |||
91 | error = tca6416_read_reg(chip, TCA6416_INPUT, ®_val); | ||
92 | if (error) | ||
93 | return; | ||
94 | |||
95 | reg_val &= chip->pinmask; | ||
96 | |||
97 | /* Figure out which lines have changed */ | ||
98 | val = reg_val ^ chip->reg_input; | ||
99 | chip->reg_input = reg_val; | ||
100 | |||
101 | for (i = 0, pin_index = 0; i < 16; i++) { | ||
102 | if (val & (1 << i)) { | ||
103 | struct tca6416_button *button = &chip->buttons[pin_index]; | ||
104 | unsigned int type = button->type ?: EV_KEY; | ||
105 | int state = ((reg_val & (1 << i)) ? 1 : 0) | ||
106 | ^ button->active_low; | ||
107 | |||
108 | input_event(input, type, button->code, !!state); | ||
109 | input_sync(input); | ||
110 | } | ||
111 | |||
112 | if (chip->pinmask & (1 << i)) | ||
113 | pin_index++; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * This is threaded IRQ handler and this can (and will) sleep. | ||
119 | */ | ||
120 | static irqreturn_t tca6416_keys_isr(int irq, void *dev_id) | ||
121 | { | ||
122 | struct tca6416_keypad_chip *chip = dev_id; | ||
123 | |||
124 | tca6416_keys_scan(chip); | ||
125 | |||
126 | return IRQ_HANDLED; | ||
127 | } | ||
128 | |||
129 | static void tca6416_keys_work_func(struct work_struct *work) | ||
130 | { | ||
131 | struct tca6416_keypad_chip *chip = | ||
132 | container_of(work, struct tca6416_keypad_chip, dwork.work); | ||
133 | |||
134 | tca6416_keys_scan(chip); | ||
135 | schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100)); | ||
136 | } | ||
137 | |||
138 | static int tca6416_keys_open(struct input_dev *dev) | ||
139 | { | ||
140 | struct tca6416_keypad_chip *chip = input_get_drvdata(dev); | ||
141 | |||
142 | /* Get initial device state in case it has switches */ | ||
143 | tca6416_keys_scan(chip); | ||
144 | |||
145 | if (chip->use_polling) | ||
146 | schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100)); | ||
147 | else | ||
148 | enable_irq(chip->irqnum); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static void tca6416_keys_close(struct input_dev *dev) | ||
154 | { | ||
155 | struct tca6416_keypad_chip *chip = input_get_drvdata(dev); | ||
156 | |||
157 | if (chip->use_polling) | ||
158 | cancel_delayed_work_sync(&chip->dwork); | ||
159 | else | ||
160 | disable_irq(chip->irqnum); | ||
161 | } | ||
162 | |||
163 | static int __devinit tca6416_setup_registers(struct tca6416_keypad_chip *chip) | ||
164 | { | ||
165 | int error; | ||
166 | |||
167 | error = tca6416_read_reg(chip, TCA6416_OUTPUT, &chip->reg_output); | ||
168 | if (error) | ||
169 | return error; | ||
170 | |||
171 | error = tca6416_read_reg(chip, TCA6416_DIRECTION, &chip->reg_direction); | ||
172 | if (error) | ||
173 | return error; | ||
174 | |||
175 | /* ensure that keypad pins are set to input */ | ||
176 | error = tca6416_write_reg(chip, TCA6416_DIRECTION, | ||
177 | chip->reg_direction | chip->pinmask); | ||
178 | if (error) | ||
179 | return error; | ||
180 | |||
181 | error = tca6416_read_reg(chip, TCA6416_DIRECTION, &chip->reg_direction); | ||
182 | if (error) | ||
183 | return error; | ||
184 | |||
185 | error = tca6416_read_reg(chip, TCA6416_INPUT, &chip->reg_input); | ||
186 | if (error) | ||
187 | return error; | ||
188 | |||
189 | chip->reg_input &= chip->pinmask; | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static int __devinit tca6416_keypad_probe(struct i2c_client *client, | ||
195 | const struct i2c_device_id *id) | ||
196 | { | ||
197 | struct tca6416_keys_platform_data *pdata; | ||
198 | struct tca6416_keypad_chip *chip; | ||
199 | struct input_dev *input; | ||
200 | int error; | ||
201 | int i; | ||
202 | |||
203 | /* Check functionality */ | ||
204 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { | ||
205 | dev_err(&client->dev, "%s adapter not supported\n", | ||
206 | dev_driver_string(&client->adapter->dev)); | ||
207 | return -ENODEV; | ||
208 | } | ||
209 | |||
210 | pdata = client->dev.platform_data; | ||
211 | if (!pdata) { | ||
212 | dev_dbg(&client->dev, "no platform data\n"); | ||
213 | return -EINVAL; | ||
214 | } | ||
215 | |||
216 | chip = kzalloc(sizeof(struct tca6416_keypad_chip) + | ||
217 | pdata->nbuttons * sizeof(struct tca6416_button), | ||
218 | GFP_KERNEL); | ||
219 | input = input_allocate_device(); | ||
220 | if (!chip || !input) { | ||
221 | error = -ENOMEM; | ||
222 | goto fail1; | ||
223 | } | ||
224 | |||
225 | chip->client = client; | ||
226 | chip->input = input; | ||
227 | chip->pinmask = pdata->pinmask; | ||
228 | chip->use_polling = pdata->use_polling; | ||
229 | |||
230 | INIT_DELAYED_WORK(&chip->dwork, tca6416_keys_work_func); | ||
231 | |||
232 | input->phys = "tca6416-keys/input0"; | ||
233 | input->name = client->name; | ||
234 | input->dev.parent = &client->dev; | ||
235 | |||
236 | input->open = tca6416_keys_open; | ||
237 | input->close = tca6416_keys_close; | ||
238 | |||
239 | input->id.bustype = BUS_HOST; | ||
240 | input->id.vendor = 0x0001; | ||
241 | input->id.product = 0x0001; | ||
242 | input->id.version = 0x0100; | ||
243 | |||
244 | /* Enable auto repeat feature of Linux input subsystem */ | ||
245 | if (pdata->rep) | ||
246 | __set_bit(EV_REP, input->evbit); | ||
247 | |||
248 | for (i = 0; i < pdata->nbuttons; i++) { | ||
249 | unsigned int type; | ||
250 | |||
251 | chip->buttons[i] = pdata->buttons[i]; | ||
252 | type = (pdata->buttons[i].type) ?: EV_KEY; | ||
253 | input_set_capability(input, type, pdata->buttons[i].code); | ||
254 | } | ||
255 | |||
256 | input_set_drvdata(input, chip); | ||
257 | |||
258 | /* | ||
259 | * Initialize cached registers from their original values. | ||
260 | * we can't share this chip with another i2c master. | ||
261 | */ | ||
262 | error = tca6416_setup_registers(chip); | ||
263 | if (error) | ||
264 | goto fail1; | ||
265 | |||
266 | if (!chip->use_polling) { | ||
267 | if (pdata->irq_is_gpio) | ||
268 | chip->irqnum = gpio_to_irq(client->irq); | ||
269 | else | ||
270 | chip->irqnum = client->irq; | ||
271 | |||
272 | error = request_threaded_irq(chip->irqnum, NULL, | ||
273 | tca6416_keys_isr, | ||
274 | IRQF_TRIGGER_FALLING, | ||
275 | "tca6416-keypad", chip); | ||
276 | if (error) { | ||
277 | dev_dbg(&client->dev, | ||
278 | "Unable to claim irq %d; error %d\n", | ||
279 | chip->irqnum, error); | ||
280 | goto fail1; | ||
281 | } | ||
282 | disable_irq(chip->irqnum); | ||
283 | } | ||
284 | |||
285 | error = input_register_device(input); | ||
286 | if (error) { | ||
287 | dev_dbg(&client->dev, | ||
288 | "Unable to register input device, error: %d\n", error); | ||
289 | goto fail2; | ||
290 | } | ||
291 | |||
292 | i2c_set_clientdata(client, chip); | ||
293 | |||
294 | return 0; | ||
295 | |||
296 | fail2: | ||
297 | if (!chip->use_polling) { | ||
298 | free_irq(chip->irqnum, chip); | ||
299 | enable_irq(chip->irqnum); | ||
300 | } | ||
301 | fail1: | ||
302 | input_free_device(input); | ||
303 | kfree(chip); | ||
304 | return error; | ||
305 | } | ||
306 | |||
307 | static int __devexit tca6416_keypad_remove(struct i2c_client *client) | ||
308 | { | ||
309 | struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); | ||
310 | |||
311 | if (!chip->use_polling) { | ||
312 | free_irq(chip->irqnum, chip); | ||
313 | enable_irq(chip->irqnum); | ||
314 | } | ||
315 | |||
316 | input_unregister_device(chip->input); | ||
317 | kfree(chip); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | |||
323 | static struct i2c_driver tca6416_keypad_driver = { | ||
324 | .driver = { | ||
325 | .name = "tca6416-keypad", | ||
326 | }, | ||
327 | .probe = tca6416_keypad_probe, | ||
328 | .remove = __devexit_p(tca6416_keypad_remove), | ||
329 | .id_table = tca6416_id, | ||
330 | }; | ||
331 | |||
332 | static int __init tca6416_keypad_init(void) | ||
333 | { | ||
334 | return i2c_add_driver(&tca6416_keypad_driver); | ||
335 | } | ||
336 | |||
337 | subsys_initcall(tca6416_keypad_init); | ||
338 | |||
339 | static void __exit tca6416_keypad_exit(void) | ||
340 | { | ||
341 | i2c_del_driver(&tca6416_keypad_driver); | ||
342 | } | ||
343 | module_exit(tca6416_keypad_exit); | ||
344 | |||
345 | MODULE_AUTHOR("Sriramakrishnan <srk@ti.com>"); | ||
346 | MODULE_DESCRIPTION("Keypad driver over tca6146 IO expander"); | ||
347 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c new file mode 100644 index 000000000000..b4a81ebfab92 --- /dev/null +++ b/drivers/input/keyboard/tnetv107x-keypad.c | |||
@@ -0,0 +1,340 @@ | |||
1 | /* | ||
2 | * Texas Instruments TNETV107X Keypad Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/clk.h> | ||
25 | #include <linux/input/matrix_keypad.h> | ||
26 | |||
27 | #define BITS(x) (BIT(x) - 1) | ||
28 | |||
29 | #define KEYPAD_ROWS 9 | ||
30 | #define KEYPAD_COLS 9 | ||
31 | |||
32 | #define DEBOUNCE_MIN 0x400ul | ||
33 | #define DEBOUNCE_MAX 0x3ffffffful | ||
34 | |||
35 | struct keypad_regs { | ||
36 | u32 rev; | ||
37 | u32 mode; | ||
38 | u32 mask; | ||
39 | u32 pol; | ||
40 | u32 dclock; | ||
41 | u32 rclock; | ||
42 | u32 stable_cnt; | ||
43 | u32 in_en; | ||
44 | u32 out; | ||
45 | u32 out_en; | ||
46 | u32 in; | ||
47 | u32 lock; | ||
48 | u32 pres[3]; | ||
49 | }; | ||
50 | |||
51 | #define keypad_read(kp, reg) __raw_readl(&(kp)->regs->reg) | ||
52 | #define keypad_write(kp, reg, val) __raw_writel(val, &(kp)->regs->reg) | ||
53 | |||
54 | struct keypad_data { | ||
55 | struct input_dev *input_dev; | ||
56 | struct resource *res; | ||
57 | struct keypad_regs __iomem *regs; | ||
58 | struct clk *clk; | ||
59 | struct device *dev; | ||
60 | spinlock_t lock; | ||
61 | u32 irq_press; | ||
62 | u32 irq_release; | ||
63 | int rows, cols, row_shift; | ||
64 | int debounce_ms, active_low; | ||
65 | u32 prev_keys[3]; | ||
66 | unsigned short keycodes[]; | ||
67 | }; | ||
68 | |||
69 | static irqreturn_t keypad_irq(int irq, void *data) | ||
70 | { | ||
71 | struct keypad_data *kp = data; | ||
72 | int i, bit, val, row, col, code; | ||
73 | unsigned long flags; | ||
74 | u32 curr_keys[3]; | ||
75 | u32 change; | ||
76 | |||
77 | spin_lock_irqsave(&kp->lock, flags); | ||
78 | |||
79 | memset(curr_keys, 0, sizeof(curr_keys)); | ||
80 | if (irq == kp->irq_press) | ||
81 | for (i = 0; i < 3; i++) | ||
82 | curr_keys[i] = keypad_read(kp, pres[i]); | ||
83 | |||
84 | for (i = 0; i < 3; i++) { | ||
85 | change = curr_keys[i] ^ kp->prev_keys[i]; | ||
86 | |||
87 | while (change) { | ||
88 | bit = fls(change) - 1; | ||
89 | change ^= BIT(bit); | ||
90 | val = curr_keys[i] & BIT(bit); | ||
91 | bit += i * 32; | ||
92 | row = bit / KEYPAD_COLS; | ||
93 | col = bit % KEYPAD_COLS; | ||
94 | |||
95 | code = MATRIX_SCAN_CODE(row, col, kp->row_shift); | ||
96 | input_event(kp->input_dev, EV_MSC, MSC_SCAN, code); | ||
97 | input_report_key(kp->input_dev, kp->keycodes[code], | ||
98 | val); | ||
99 | } | ||
100 | } | ||
101 | input_sync(kp->input_dev); | ||
102 | memcpy(kp->prev_keys, curr_keys, sizeof(curr_keys)); | ||
103 | |||
104 | if (irq == kp->irq_press) | ||
105 | keypad_write(kp, lock, 0); /* Allow hardware updates */ | ||
106 | |||
107 | spin_unlock_irqrestore(&kp->lock, flags); | ||
108 | |||
109 | return IRQ_HANDLED; | ||
110 | } | ||
111 | |||
112 | static int keypad_start(struct input_dev *dev) | ||
113 | { | ||
114 | struct keypad_data *kp = input_get_drvdata(dev); | ||
115 | unsigned long mask, debounce, clk_rate_khz; | ||
116 | unsigned long flags; | ||
117 | |||
118 | clk_enable(kp->clk); | ||
119 | clk_rate_khz = clk_get_rate(kp->clk) / 1000; | ||
120 | |||
121 | spin_lock_irqsave(&kp->lock, flags); | ||
122 | |||
123 | /* Initialize device registers */ | ||
124 | keypad_write(kp, mode, 0); | ||
125 | |||
126 | mask = BITS(kp->rows) << KEYPAD_COLS; | ||
127 | mask |= BITS(kp->cols); | ||
128 | keypad_write(kp, mask, ~mask); | ||
129 | |||
130 | keypad_write(kp, pol, kp->active_low ? 0 : 0x3ffff); | ||
131 | keypad_write(kp, stable_cnt, 3); | ||
132 | |||
133 | debounce = kp->debounce_ms * clk_rate_khz; | ||
134 | debounce = clamp(debounce, DEBOUNCE_MIN, DEBOUNCE_MAX); | ||
135 | keypad_write(kp, dclock, debounce); | ||
136 | keypad_write(kp, rclock, 4 * debounce); | ||
137 | |||
138 | keypad_write(kp, in_en, 1); | ||
139 | |||
140 | spin_unlock_irqrestore(&kp->lock, flags); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static void keypad_stop(struct input_dev *dev) | ||
146 | { | ||
147 | struct keypad_data *kp = input_get_drvdata(dev); | ||
148 | |||
149 | synchronize_irq(kp->irq_press); | ||
150 | synchronize_irq(kp->irq_release); | ||
151 | clk_disable(kp->clk); | ||
152 | } | ||
153 | |||
154 | static int __devinit keypad_probe(struct platform_device *pdev) | ||
155 | { | ||
156 | const struct matrix_keypad_platform_data *pdata; | ||
157 | const struct matrix_keymap_data *keymap_data; | ||
158 | struct device *dev = &pdev->dev; | ||
159 | struct keypad_data *kp; | ||
160 | int error = 0, sz, row_shift; | ||
161 | u32 rev = 0; | ||
162 | |||
163 | pdata = pdev->dev.platform_data; | ||
164 | if (!pdata) { | ||
165 | dev_err(dev, "cannot find device data\n"); | ||
166 | return -EINVAL; | ||
167 | } | ||
168 | |||
169 | keymap_data = pdata->keymap_data; | ||
170 | if (!keymap_data) { | ||
171 | dev_err(dev, "cannot find keymap data\n"); | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | |||
175 | row_shift = get_count_order(pdata->num_col_gpios); | ||
176 | sz = offsetof(struct keypad_data, keycodes); | ||
177 | sz += (pdata->num_row_gpios << row_shift) * sizeof(kp->keycodes[0]); | ||
178 | kp = kzalloc(sz, GFP_KERNEL); | ||
179 | if (!kp) { | ||
180 | dev_err(dev, "cannot allocate device info\n"); | ||
181 | return -ENOMEM; | ||
182 | } | ||
183 | |||
184 | kp->dev = dev; | ||
185 | kp->rows = pdata->num_row_gpios; | ||
186 | kp->cols = pdata->num_col_gpios; | ||
187 | kp->row_shift = row_shift; | ||
188 | platform_set_drvdata(pdev, kp); | ||
189 | spin_lock_init(&kp->lock); | ||
190 | |||
191 | kp->irq_press = platform_get_irq_byname(pdev, "press"); | ||
192 | kp->irq_release = platform_get_irq_byname(pdev, "release"); | ||
193 | if (kp->irq_press < 0 || kp->irq_release < 0) { | ||
194 | dev_err(dev, "cannot determine device interrupts\n"); | ||
195 | error = -ENODEV; | ||
196 | goto error_res; | ||
197 | } | ||
198 | |||
199 | kp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
200 | if (!kp->res) { | ||
201 | dev_err(dev, "cannot determine register area\n"); | ||
202 | error = -ENODEV; | ||
203 | goto error_res; | ||
204 | } | ||
205 | |||
206 | if (!request_mem_region(kp->res->start, resource_size(kp->res), | ||
207 | pdev->name)) { | ||
208 | dev_err(dev, "cannot claim register memory\n"); | ||
209 | kp->res = NULL; | ||
210 | error = -EINVAL; | ||
211 | goto error_res; | ||
212 | } | ||
213 | |||
214 | kp->regs = ioremap(kp->res->start, resource_size(kp->res)); | ||
215 | if (!kp->regs) { | ||
216 | dev_err(dev, "cannot map register memory\n"); | ||
217 | error = -ENOMEM; | ||
218 | goto error_map; | ||
219 | } | ||
220 | |||
221 | kp->clk = clk_get(dev, NULL); | ||
222 | if (!kp->clk) { | ||
223 | dev_err(dev, "cannot claim device clock\n"); | ||
224 | error = -EINVAL; | ||
225 | goto error_clk; | ||
226 | } | ||
227 | |||
228 | error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, 0, | ||
229 | dev_name(dev), kp); | ||
230 | if (error < 0) { | ||
231 | dev_err(kp->dev, "Could not allocate keypad press key irq\n"); | ||
232 | goto error_irq_press; | ||
233 | } | ||
234 | |||
235 | error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, 0, | ||
236 | dev_name(dev), kp); | ||
237 | if (error < 0) { | ||
238 | dev_err(kp->dev, "Could not allocate keypad release key irq\n"); | ||
239 | goto error_irq_release; | ||
240 | } | ||
241 | |||
242 | kp->input_dev = input_allocate_device(); | ||
243 | if (!kp->input_dev) { | ||
244 | dev_err(dev, "cannot allocate input device\n"); | ||
245 | error = -ENOMEM; | ||
246 | goto error_input; | ||
247 | } | ||
248 | input_set_drvdata(kp->input_dev, kp); | ||
249 | |||
250 | kp->input_dev->name = pdev->name; | ||
251 | kp->input_dev->dev.parent = &pdev->dev; | ||
252 | kp->input_dev->open = keypad_start; | ||
253 | kp->input_dev->close = keypad_stop; | ||
254 | kp->input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
255 | if (!pdata->no_autorepeat) | ||
256 | kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
257 | |||
258 | clk_enable(kp->clk); | ||
259 | rev = keypad_read(kp, rev); | ||
260 | kp->input_dev->id.bustype = BUS_HOST; | ||
261 | kp->input_dev->id.product = ((rev >> 8) & 0x07); | ||
262 | kp->input_dev->id.version = ((rev >> 16) & 0xfff); | ||
263 | clk_disable(kp->clk); | ||
264 | |||
265 | kp->input_dev->keycode = kp->keycodes; | ||
266 | kp->input_dev->keycodesize = sizeof(kp->keycodes[0]); | ||
267 | kp->input_dev->keycodemax = kp->rows << kp->row_shift; | ||
268 | |||
269 | matrix_keypad_build_keymap(keymap_data, kp->row_shift, kp->keycodes, | ||
270 | kp->input_dev->keybit); | ||
271 | |||
272 | input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); | ||
273 | |||
274 | error = input_register_device(kp->input_dev); | ||
275 | if (error < 0) { | ||
276 | dev_err(dev, "Could not register input device\n"); | ||
277 | goto error_reg; | ||
278 | } | ||
279 | |||
280 | return 0; | ||
281 | |||
282 | |||
283 | error_reg: | ||
284 | input_free_device(kp->input_dev); | ||
285 | error_input: | ||
286 | free_irq(kp->irq_release, kp); | ||
287 | error_irq_release: | ||
288 | free_irq(kp->irq_press, kp); | ||
289 | error_irq_press: | ||
290 | clk_put(kp->clk); | ||
291 | error_clk: | ||
292 | iounmap(kp->regs); | ||
293 | error_map: | ||
294 | release_mem_region(kp->res->start, resource_size(kp->res)); | ||
295 | error_res: | ||
296 | platform_set_drvdata(pdev, NULL); | ||
297 | kfree(kp); | ||
298 | return error; | ||
299 | } | ||
300 | |||
301 | static int __devexit keypad_remove(struct platform_device *pdev) | ||
302 | { | ||
303 | struct keypad_data *kp = platform_get_drvdata(pdev); | ||
304 | |||
305 | free_irq(kp->irq_press, kp); | ||
306 | free_irq(kp->irq_release, kp); | ||
307 | input_unregister_device(kp->input_dev); | ||
308 | clk_put(kp->clk); | ||
309 | iounmap(kp->regs); | ||
310 | release_mem_region(kp->res->start, resource_size(kp->res)); | ||
311 | platform_set_drvdata(pdev, NULL); | ||
312 | kfree(kp); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static struct platform_driver keypad_driver = { | ||
318 | .probe = keypad_probe, | ||
319 | .remove = __devexit_p(keypad_remove), | ||
320 | .driver.name = "tnetv107x-keypad", | ||
321 | .driver.owner = THIS_MODULE, | ||
322 | }; | ||
323 | |||
324 | static int __init keypad_init(void) | ||
325 | { | ||
326 | return platform_driver_register(&keypad_driver); | ||
327 | } | ||
328 | |||
329 | static void __exit keypad_exit(void) | ||
330 | { | ||
331 | platform_driver_unregister(&keypad_driver); | ||
332 | } | ||
333 | |||
334 | module_init(keypad_init); | ||
335 | module_exit(keypad_exit); | ||
336 | |||
337 | MODULE_AUTHOR("Cyril Chemparathy"); | ||
338 | MODULE_DESCRIPTION("TNETV107X Keypad Driver"); | ||
339 | MODULE_ALIAS("platform: tnetv107x-keypad"); | ||
340 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c deleted file mode 100644 index 42cb3faf7336..000000000000 --- a/drivers/input/keyboard/tosakbd.c +++ /dev/null | |||
@@ -1,430 +0,0 @@ | |||
1 | /* | ||
2 | * Keyboard driver for Sharp Tosa models (SL-6000x) | ||
3 | * | ||
4 | * Copyright (c) 2005 Dirk Opfer | ||
5 | * Copyright (c) 2007 Dmitry Baryshkov | ||
6 | * | ||
7 | * Based on xtkbd.c/locomkbd.c/corgikbd.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | |||
22 | #include <mach/gpio.h> | ||
23 | #include <mach/tosa.h> | ||
24 | |||
25 | #define KB_ROWMASK(r) (1 << (r)) | ||
26 | #define SCANCODE(r, c) (((r)<<4) + (c) + 1) | ||
27 | #define NR_SCANCODES SCANCODE(TOSA_KEY_SENSE_NUM - 1, TOSA_KEY_STROBE_NUM - 1) + 1 | ||
28 | |||
29 | #define SCAN_INTERVAL (HZ/10) | ||
30 | |||
31 | #define KB_DISCHARGE_DELAY 10 | ||
32 | #define KB_ACTIVATE_DELAY 10 | ||
33 | |||
34 | static unsigned short tosakbd_keycode[NR_SCANCODES] = { | ||
35 | 0, | ||
36 | 0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P, | ||
37 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
38 | KEY_Q, KEY_E, KEY_T, KEY_Y, 0, KEY_O, KEY_I, KEY_COMMA, | ||
39 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
40 | KEY_A, KEY_D, KEY_G, KEY_U, 0, KEY_L, KEY_ENTER, KEY_DOT, | ||
41 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
42 | KEY_Z, KEY_C, KEY_V, KEY_J, TOSA_KEY_ADDRESSBOOK, TOSA_KEY_CANCEL, TOSA_KEY_CENTER, TOSA_KEY_OK, | ||
43 | KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, 0, | ||
44 | KEY_S, KEY_R, KEY_B, KEY_N, TOSA_KEY_CALENDAR, TOSA_KEY_HOMEPAGE, KEY_LEFTCTRL, TOSA_KEY_LIGHT, | ||
45 | 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, | ||
46 | KEY_TAB, KEY_SLASH, KEY_H, KEY_M, TOSA_KEY_MENU, 0, KEY_UP, 0, | ||
47 | 0, 0, TOSA_KEY_FN, 0, 0, 0, 0, 0, | ||
48 | KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_RIGHT, | ||
49 | 0, 0, 0, | ||
50 | }; | ||
51 | |||
52 | struct tosakbd { | ||
53 | unsigned short keycode[ARRAY_SIZE(tosakbd_keycode)]; | ||
54 | struct input_dev *input; | ||
55 | bool suspended; | ||
56 | spinlock_t lock; /* protect kbd scanning */ | ||
57 | struct timer_list timer; | ||
58 | }; | ||
59 | |||
60 | |||
61 | /* Helper functions for reading the keyboard matrix | ||
62 | * Note: We should really be using the generic gpio functions to alter | ||
63 | * GPDR but it requires a function call per GPIO bit which is | ||
64 | * excessive when we need to access 12 bits at once, multiple times. | ||
65 | * These functions must be called within local_irq_save()/local_irq_restore() | ||
66 | * or similar. | ||
67 | */ | ||
68 | #define GET_ROWS_STATUS(c) ((GPLR2 & TOSA_GPIO_ALL_SENSE_BIT) >> TOSA_GPIO_ALL_SENSE_RSHIFT) | ||
69 | |||
70 | static inline void tosakbd_discharge_all(void) | ||
71 | { | ||
72 | /* STROBE All HiZ */ | ||
73 | GPCR1 = TOSA_GPIO_HIGH_STROBE_BIT; | ||
74 | GPDR1 &= ~TOSA_GPIO_HIGH_STROBE_BIT; | ||
75 | GPCR2 = TOSA_GPIO_LOW_STROBE_BIT; | ||
76 | GPDR2 &= ~TOSA_GPIO_LOW_STROBE_BIT; | ||
77 | } | ||
78 | |||
79 | static inline void tosakbd_activate_all(void) | ||
80 | { | ||
81 | /* STROBE ALL -> High */ | ||
82 | GPSR1 = TOSA_GPIO_HIGH_STROBE_BIT; | ||
83 | GPDR1 |= TOSA_GPIO_HIGH_STROBE_BIT; | ||
84 | GPSR2 = TOSA_GPIO_LOW_STROBE_BIT; | ||
85 | GPDR2 |= TOSA_GPIO_LOW_STROBE_BIT; | ||
86 | |||
87 | udelay(KB_DISCHARGE_DELAY); | ||
88 | |||
89 | /* STATE CLEAR */ | ||
90 | GEDR2 |= TOSA_GPIO_ALL_SENSE_BIT; | ||
91 | } | ||
92 | |||
93 | static inline void tosakbd_activate_col(int col) | ||
94 | { | ||
95 | if (col <= 5) { | ||
96 | /* STROBE col -> High, not col -> HiZ */ | ||
97 | GPSR1 = TOSA_GPIO_STROBE_BIT(col); | ||
98 | GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col); | ||
99 | } else { | ||
100 | /* STROBE col -> High, not col -> HiZ */ | ||
101 | GPSR2 = TOSA_GPIO_STROBE_BIT(col); | ||
102 | GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | static inline void tosakbd_reset_col(int col) | ||
107 | { | ||
108 | if (col <= 5) { | ||
109 | /* STROBE col -> Low */ | ||
110 | GPCR1 = TOSA_GPIO_STROBE_BIT(col); | ||
111 | /* STROBE col -> out, not col -> HiZ */ | ||
112 | GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col); | ||
113 | } else { | ||
114 | /* STROBE col -> Low */ | ||
115 | GPCR2 = TOSA_GPIO_STROBE_BIT(col); | ||
116 | /* STROBE col -> out, not col -> HiZ */ | ||
117 | GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col); | ||
118 | } | ||
119 | } | ||
120 | /* | ||
121 | * The tosa keyboard only generates interrupts when a key is pressed. | ||
122 | * So when a key is pressed, we enable a timer. This timer scans the | ||
123 | * keyboard, and this is how we detect when the key is released. | ||
124 | */ | ||
125 | |||
126 | /* Scan the hardware keyboard and push any changes up through the input layer */ | ||
127 | static void tosakbd_scankeyboard(struct platform_device *dev) | ||
128 | { | ||
129 | struct tosakbd *tosakbd = platform_get_drvdata(dev); | ||
130 | unsigned int row, col, rowd; | ||
131 | unsigned long flags; | ||
132 | unsigned int num_pressed = 0; | ||
133 | |||
134 | spin_lock_irqsave(&tosakbd->lock, flags); | ||
135 | |||
136 | if (tosakbd->suspended) | ||
137 | goto out; | ||
138 | |||
139 | for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) { | ||
140 | /* | ||
141 | * Discharge the output driver capacitatance | ||
142 | * in the keyboard matrix. (Yes it is significant..) | ||
143 | */ | ||
144 | tosakbd_discharge_all(); | ||
145 | udelay(KB_DISCHARGE_DELAY); | ||
146 | |||
147 | tosakbd_activate_col(col); | ||
148 | udelay(KB_ACTIVATE_DELAY); | ||
149 | |||
150 | rowd = GET_ROWS_STATUS(col); | ||
151 | |||
152 | for (row = 0; row < TOSA_KEY_SENSE_NUM; row++) { | ||
153 | unsigned int scancode, pressed; | ||
154 | scancode = SCANCODE(row, col); | ||
155 | pressed = rowd & KB_ROWMASK(row); | ||
156 | |||
157 | if (pressed && !tosakbd->keycode[scancode]) | ||
158 | dev_warn(&dev->dev, | ||
159 | "unhandled scancode: 0x%02x\n", | ||
160 | scancode); | ||
161 | |||
162 | input_report_key(tosakbd->input, | ||
163 | tosakbd->keycode[scancode], | ||
164 | pressed); | ||
165 | if (pressed) | ||
166 | num_pressed++; | ||
167 | } | ||
168 | |||
169 | tosakbd_reset_col(col); | ||
170 | } | ||
171 | |||
172 | tosakbd_activate_all(); | ||
173 | |||
174 | input_sync(tosakbd->input); | ||
175 | |||
176 | /* if any keys are pressed, enable the timer */ | ||
177 | if (num_pressed) | ||
178 | mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL); | ||
179 | |||
180 | out: | ||
181 | spin_unlock_irqrestore(&tosakbd->lock, flags); | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * tosa keyboard interrupt handler. | ||
186 | */ | ||
187 | static irqreturn_t tosakbd_interrupt(int irq, void *__dev) | ||
188 | { | ||
189 | struct platform_device *dev = __dev; | ||
190 | struct tosakbd *tosakbd = platform_get_drvdata(dev); | ||
191 | |||
192 | if (!timer_pending(&tosakbd->timer)) { | ||
193 | /** wait chattering delay **/ | ||
194 | udelay(20); | ||
195 | tosakbd_scankeyboard(dev); | ||
196 | } | ||
197 | |||
198 | return IRQ_HANDLED; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * tosa timer checking for released keys | ||
203 | */ | ||
204 | static void tosakbd_timer_callback(unsigned long __dev) | ||
205 | { | ||
206 | struct platform_device *dev = (struct platform_device *)__dev; | ||
207 | |||
208 | tosakbd_scankeyboard(dev); | ||
209 | } | ||
210 | |||
211 | #ifdef CONFIG_PM | ||
212 | static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) | ||
213 | { | ||
214 | struct tosakbd *tosakbd = platform_get_drvdata(dev); | ||
215 | unsigned long flags; | ||
216 | |||
217 | spin_lock_irqsave(&tosakbd->lock, flags); | ||
218 | tosakbd->suspended = true; | ||
219 | spin_unlock_irqrestore(&tosakbd->lock, flags); | ||
220 | |||
221 | del_timer_sync(&tosakbd->timer); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int tosakbd_resume(struct platform_device *dev) | ||
227 | { | ||
228 | struct tosakbd *tosakbd = platform_get_drvdata(dev); | ||
229 | |||
230 | tosakbd->suspended = false; | ||
231 | tosakbd_scankeyboard(dev); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | #else | ||
236 | #define tosakbd_suspend NULL | ||
237 | #define tosakbd_resume NULL | ||
238 | #endif | ||
239 | |||
240 | static int __devinit tosakbd_probe(struct platform_device *pdev) { | ||
241 | |||
242 | int i; | ||
243 | struct tosakbd *tosakbd; | ||
244 | struct input_dev *input_dev; | ||
245 | int error; | ||
246 | |||
247 | tosakbd = kzalloc(sizeof(struct tosakbd), GFP_KERNEL); | ||
248 | if (!tosakbd) | ||
249 | return -ENOMEM; | ||
250 | |||
251 | input_dev = input_allocate_device(); | ||
252 | if (!input_dev) { | ||
253 | kfree(tosakbd); | ||
254 | return -ENOMEM; | ||
255 | } | ||
256 | |||
257 | platform_set_drvdata(pdev, tosakbd); | ||
258 | |||
259 | spin_lock_init(&tosakbd->lock); | ||
260 | |||
261 | /* Init Keyboard rescan timer */ | ||
262 | init_timer(&tosakbd->timer); | ||
263 | tosakbd->timer.function = tosakbd_timer_callback; | ||
264 | tosakbd->timer.data = (unsigned long) pdev; | ||
265 | |||
266 | tosakbd->input = input_dev; | ||
267 | |||
268 | input_set_drvdata(input_dev, tosakbd); | ||
269 | input_dev->name = "Tosa Keyboard"; | ||
270 | input_dev->phys = "tosakbd/input0"; | ||
271 | input_dev->dev.parent = &pdev->dev; | ||
272 | |||
273 | input_dev->id.bustype = BUS_HOST; | ||
274 | input_dev->id.vendor = 0x0001; | ||
275 | input_dev->id.product = 0x0001; | ||
276 | input_dev->id.version = 0x0100; | ||
277 | |||
278 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | ||
279 | input_dev->keycode = tosakbd->keycode; | ||
280 | input_dev->keycodesize = sizeof(tosakbd->keycode[0]); | ||
281 | input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode); | ||
282 | |||
283 | memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode)); | ||
284 | |||
285 | for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++) | ||
286 | __set_bit(tosakbd->keycode[i], input_dev->keybit); | ||
287 | __clear_bit(KEY_RESERVED, input_dev->keybit); | ||
288 | |||
289 | /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ | ||
290 | for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) { | ||
291 | int gpio = TOSA_GPIO_KEY_SENSE(i); | ||
292 | int irq; | ||
293 | error = gpio_request(gpio, "tosakbd"); | ||
294 | if (error < 0) { | ||
295 | printk(KERN_ERR "tosakbd: failed to request GPIO %d, " | ||
296 | " error %d\n", gpio, error); | ||
297 | goto fail; | ||
298 | } | ||
299 | |||
300 | error = gpio_direction_input(TOSA_GPIO_KEY_SENSE(i)); | ||
301 | if (error < 0) { | ||
302 | printk(KERN_ERR "tosakbd: failed to configure input" | ||
303 | " direction for GPIO %d, error %d\n", | ||
304 | gpio, error); | ||
305 | gpio_free(gpio); | ||
306 | goto fail; | ||
307 | } | ||
308 | |||
309 | irq = gpio_to_irq(gpio); | ||
310 | if (irq < 0) { | ||
311 | error = irq; | ||
312 | printk(KERN_ERR "gpio-keys: Unable to get irq number" | ||
313 | " for GPIO %d, error %d\n", | ||
314 | gpio, error); | ||
315 | gpio_free(gpio); | ||
316 | goto fail; | ||
317 | } | ||
318 | |||
319 | error = request_irq(irq, tosakbd_interrupt, | ||
320 | IRQF_DISABLED | IRQF_TRIGGER_RISING, | ||
321 | "tosakbd", pdev); | ||
322 | |||
323 | if (error) { | ||
324 | printk("tosakbd: Can't get IRQ: %d: error %d!\n", | ||
325 | irq, error); | ||
326 | gpio_free(gpio); | ||
327 | goto fail; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | /* Set Strobe lines as outputs - set high */ | ||
332 | for (i = 0; i < TOSA_KEY_STROBE_NUM; i++) { | ||
333 | int gpio = TOSA_GPIO_KEY_STROBE(i); | ||
334 | error = gpio_request(gpio, "tosakbd"); | ||
335 | if (error < 0) { | ||
336 | printk(KERN_ERR "tosakbd: failed to request GPIO %d, " | ||
337 | " error %d\n", gpio, error); | ||
338 | goto fail2; | ||
339 | } | ||
340 | |||
341 | error = gpio_direction_output(gpio, 1); | ||
342 | if (error < 0) { | ||
343 | printk(KERN_ERR "tosakbd: failed to configure input" | ||
344 | " direction for GPIO %d, error %d\n", | ||
345 | gpio, error); | ||
346 | gpio_free(gpio); | ||
347 | goto fail2; | ||
348 | } | ||
349 | |||
350 | } | ||
351 | |||
352 | error = input_register_device(input_dev); | ||
353 | if (error) { | ||
354 | printk(KERN_ERR "tosakbd: Unable to register input device, " | ||
355 | "error: %d\n", error); | ||
356 | goto fail2; | ||
357 | } | ||
358 | |||
359 | printk(KERN_INFO "input: Tosa Keyboard Registered\n"); | ||
360 | |||
361 | return 0; | ||
362 | |||
363 | fail2: | ||
364 | while (--i >= 0) | ||
365 | gpio_free(TOSA_GPIO_KEY_STROBE(i)); | ||
366 | |||
367 | i = TOSA_KEY_SENSE_NUM; | ||
368 | fail: | ||
369 | while (--i >= 0) { | ||
370 | free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), pdev); | ||
371 | gpio_free(TOSA_GPIO_KEY_SENSE(i)); | ||
372 | } | ||
373 | |||
374 | platform_set_drvdata(pdev, NULL); | ||
375 | input_free_device(input_dev); | ||
376 | kfree(tosakbd); | ||
377 | |||
378 | return error; | ||
379 | } | ||
380 | |||
381 | static int __devexit tosakbd_remove(struct platform_device *dev) | ||
382 | { | ||
383 | int i; | ||
384 | struct tosakbd *tosakbd = platform_get_drvdata(dev); | ||
385 | |||
386 | for (i = 0; i < TOSA_KEY_STROBE_NUM; i++) | ||
387 | gpio_free(TOSA_GPIO_KEY_STROBE(i)); | ||
388 | |||
389 | for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) { | ||
390 | free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), dev); | ||
391 | gpio_free(TOSA_GPIO_KEY_SENSE(i)); | ||
392 | } | ||
393 | |||
394 | del_timer_sync(&tosakbd->timer); | ||
395 | |||
396 | input_unregister_device(tosakbd->input); | ||
397 | |||
398 | kfree(tosakbd); | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static struct platform_driver tosakbd_driver = { | ||
404 | .probe = tosakbd_probe, | ||
405 | .remove = __devexit_p(tosakbd_remove), | ||
406 | .suspend = tosakbd_suspend, | ||
407 | .resume = tosakbd_resume, | ||
408 | .driver = { | ||
409 | .name = "tosa-keyboard", | ||
410 | .owner = THIS_MODULE, | ||
411 | }, | ||
412 | }; | ||
413 | |||
414 | static int __devinit tosakbd_init(void) | ||
415 | { | ||
416 | return platform_driver_register(&tosakbd_driver); | ||
417 | } | ||
418 | |||
419 | static void __exit tosakbd_exit(void) | ||
420 | { | ||
421 | platform_driver_unregister(&tosakbd_driver); | ||
422 | } | ||
423 | |||
424 | module_init(tosakbd_init); | ||
425 | module_exit(tosakbd_exit); | ||
426 | |||
427 | MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>"); | ||
428 | MODULE_DESCRIPTION("Tosa Keyboard Driver"); | ||
429 | MODULE_LICENSE("GPL v2"); | ||
430 | MODULE_ALIAS("platform:tosa-keyboard"); | ||
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 21d6184efa96..09bef79d9da1 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/input.h> | 32 | #include <linux/input.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/i2c/twl.h> | 34 | #include <linux/i2c/twl.h> |
35 | #include <linux/slab.h> | ||
35 | 36 | ||
36 | 37 | ||
37 | /* | 38 | /* |
@@ -50,8 +51,12 @@ | |||
50 | */ | 51 | */ |
51 | #define TWL4030_MAX_ROWS 8 /* TWL4030 hard limit */ | 52 | #define TWL4030_MAX_ROWS 8 /* TWL4030 hard limit */ |
52 | #define TWL4030_MAX_COLS 8 | 53 | #define TWL4030_MAX_COLS 8 |
53 | #define TWL4030_ROW_SHIFT 3 | 54 | /* |
54 | #define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS * TWL4030_MAX_COLS) | 55 | * Note that we add space for an extra column so that we can handle |
56 | * row lines connected to the gnd (see twl4030_col_xlate()). | ||
57 | */ | ||
58 | #define TWL4030_ROW_SHIFT 4 | ||
59 | #define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS << TWL4030_ROW_SHIFT) | ||
55 | 60 | ||
56 | struct twl4030_keypad { | 61 | struct twl4030_keypad { |
57 | unsigned short keymap[TWL4030_KEYMAP_SIZE]; | 62 | unsigned short keymap[TWL4030_KEYMAP_SIZE]; |
@@ -181,7 +186,7 @@ static int twl4030_read_kp_matrix_state(struct twl4030_keypad *kp, u16 *state) | |||
181 | return ret; | 186 | return ret; |
182 | } | 187 | } |
183 | 188 | ||
184 | static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) | 189 | static bool twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) |
185 | { | 190 | { |
186 | int i; | 191 | int i; |
187 | u16 check = 0; | 192 | u16 check = 0; |
@@ -190,12 +195,12 @@ static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) | |||
190 | u16 col = key_state[i]; | 195 | u16 col = key_state[i]; |
191 | 196 | ||
192 | if ((col & check) && hweight16(col) > 1) | 197 | if ((col & check) && hweight16(col) > 1) |
193 | return 1; | 198 | return true; |
194 | 199 | ||
195 | check |= col; | 200 | check |= col; |
196 | } | 201 | } |
197 | 202 | ||
198 | return 0; | 203 | return false; |
199 | } | 204 | } |
200 | 205 | ||
201 | static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) | 206 | static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) |
@@ -224,7 +229,8 @@ static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) | |||
224 | if (!changed) | 229 | if (!changed) |
225 | continue; | 230 | continue; |
226 | 231 | ||
227 | for (col = 0; col < kp->n_cols; col++) { | 232 | /* Extra column handles "all gnd" rows */ |
233 | for (col = 0; col < kp->n_cols + 1; col++) { | ||
228 | int code; | 234 | int code; |
229 | 235 | ||
230 | if (!(changed & (1 << col))) | 236 | if (!(changed & (1 << col))) |
@@ -400,23 +406,22 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev) | |||
400 | if (error) { | 406 | if (error) { |
401 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", | 407 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", |
402 | kp->irq); | 408 | kp->irq); |
403 | goto err3; | 409 | goto err2; |
404 | } | 410 | } |
405 | 411 | ||
406 | /* Enable KP and TO interrupts now. */ | 412 | /* Enable KP and TO interrupts now. */ |
407 | reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); | 413 | reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); |
408 | if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { | 414 | if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { |
409 | error = -EIO; | 415 | error = -EIO; |
410 | goto err4; | 416 | goto err3; |
411 | } | 417 | } |
412 | 418 | ||
413 | platform_set_drvdata(pdev, kp); | 419 | platform_set_drvdata(pdev, kp); |
414 | return 0; | 420 | return 0; |
415 | 421 | ||
416 | err4: | 422 | err3: |
417 | /* mask all events - we don't care about the result */ | 423 | /* mask all events - we don't care about the result */ |
418 | (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); | 424 | (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); |
419 | err3: | ||
420 | free_irq(kp->irq, NULL); | 425 | free_irq(kp->irq, NULL); |
421 | err2: | 426 | err2: |
422 | input_unregister_device(input); | 427 | input_unregister_device(input); |
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index 6032def03707..ee2bf6bcf291 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | #include <mach/w90p910_keypad.h> | 24 | #include <mach/w90p910_keypad.h> |
24 | 25 | ||
@@ -257,7 +258,7 @@ static struct platform_driver w90p910_keypad_driver = { | |||
257 | .probe = w90p910_keypad_probe, | 258 | .probe = w90p910_keypad_probe, |
258 | .remove = __devexit_p(w90p910_keypad_remove), | 259 | .remove = __devexit_p(w90p910_keypad_remove), |
259 | .driver = { | 260 | .driver = { |
260 | .name = "nuc900-keypad", | 261 | .name = "nuc900-kpi", |
261 | .owner = THIS_MODULE, | 262 | .owner = THIS_MODULE, |
262 | }, | 263 | }, |
263 | }; | 264 | }; |
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c new file mode 100644 index 000000000000..4cc82826ea6b --- /dev/null +++ b/drivers/input/misc/88pm860x_onkey.c | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | * 88pm860x_onkey.c - Marvell 88PM860x ONKEY driver | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Marvell International Ltd. | ||
5 | * Haojian Zhuang <haojian.zhuang@marvell.com> | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General | ||
8 | * Public License. See the file "COPYING" in the main directory of this | ||
9 | * archive for more details. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/input.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/mfd/88pm860x.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #define PM8607_WAKEUP 0x0b | ||
31 | |||
32 | #define LONG_ONKEY_EN (1 << 1) | ||
33 | #define ONKEY_STATUS (1 << 0) | ||
34 | |||
35 | struct pm860x_onkey_info { | ||
36 | struct input_dev *idev; | ||
37 | struct pm860x_chip *chip; | ||
38 | struct i2c_client *i2c; | ||
39 | struct device *dev; | ||
40 | int irq; | ||
41 | }; | ||
42 | |||
43 | /* 88PM860x gives us an interrupt when ONKEY is held */ | ||
44 | static irqreturn_t pm860x_onkey_handler(int irq, void *data) | ||
45 | { | ||
46 | struct pm860x_onkey_info *info = data; | ||
47 | int ret; | ||
48 | |||
49 | ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); | ||
50 | ret &= ONKEY_STATUS; | ||
51 | input_report_key(info->idev, KEY_POWER, ret); | ||
52 | input_sync(info->idev); | ||
53 | |||
54 | /* Enable 8-second long onkey detection */ | ||
55 | pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN); | ||
56 | return IRQ_HANDLED; | ||
57 | } | ||
58 | |||
59 | static int __devinit pm860x_onkey_probe(struct platform_device *pdev) | ||
60 | { | ||
61 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
62 | struct pm860x_onkey_info *info; | ||
63 | int irq, ret; | ||
64 | |||
65 | irq = platform_get_irq(pdev, 0); | ||
66 | if (irq < 0) { | ||
67 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
68 | return -EINVAL; | ||
69 | } | ||
70 | |||
71 | info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL); | ||
72 | if (!info) | ||
73 | return -ENOMEM; | ||
74 | info->chip = chip; | ||
75 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | ||
76 | info->dev = &pdev->dev; | ||
77 | info->irq = irq + chip->irq_base; | ||
78 | |||
79 | info->idev = input_allocate_device(); | ||
80 | if (!info->idev) { | ||
81 | dev_err(chip->dev, "Failed to allocate input dev\n"); | ||
82 | ret = -ENOMEM; | ||
83 | goto out; | ||
84 | } | ||
85 | |||
86 | info->idev->name = "88pm860x_on"; | ||
87 | info->idev->phys = "88pm860x_on/input0"; | ||
88 | info->idev->id.bustype = BUS_I2C; | ||
89 | info->idev->dev.parent = &pdev->dev; | ||
90 | info->idev->evbit[0] = BIT_MASK(EV_KEY); | ||
91 | info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); | ||
92 | |||
93 | ret = input_register_device(info->idev); | ||
94 | if (ret) { | ||
95 | dev_err(chip->dev, "Can't register input device: %d\n", ret); | ||
96 | goto out_reg; | ||
97 | } | ||
98 | |||
99 | ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler, | ||
100 | IRQF_ONESHOT, "onkey", info); | ||
101 | if (ret < 0) { | ||
102 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
103 | info->irq, ret); | ||
104 | goto out_irq; | ||
105 | } | ||
106 | |||
107 | platform_set_drvdata(pdev, info); | ||
108 | return 0; | ||
109 | |||
110 | out_irq: | ||
111 | input_unregister_device(info->idev); | ||
112 | kfree(info); | ||
113 | return ret; | ||
114 | |||
115 | out_reg: | ||
116 | input_free_device(info->idev); | ||
117 | out: | ||
118 | kfree(info); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | static int __devexit pm860x_onkey_remove(struct platform_device *pdev) | ||
123 | { | ||
124 | struct pm860x_onkey_info *info = platform_get_drvdata(pdev); | ||
125 | |||
126 | free_irq(info->irq, info); | ||
127 | input_unregister_device(info->idev); | ||
128 | kfree(info); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static struct platform_driver pm860x_onkey_driver = { | ||
133 | .driver = { | ||
134 | .name = "88pm860x-onkey", | ||
135 | .owner = THIS_MODULE, | ||
136 | }, | ||
137 | .probe = pm860x_onkey_probe, | ||
138 | .remove = __devexit_p(pm860x_onkey_remove), | ||
139 | }; | ||
140 | |||
141 | static int __init pm860x_onkey_init(void) | ||
142 | { | ||
143 | return platform_driver_register(&pm860x_onkey_driver); | ||
144 | } | ||
145 | module_init(pm860x_onkey_init); | ||
146 | |||
147 | static void __exit pm860x_onkey_exit(void) | ||
148 | { | ||
149 | platform_driver_unregister(&pm860x_onkey_driver); | ||
150 | } | ||
151 | module_exit(pm860x_onkey_exit); | ||
152 | |||
153 | MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver"); | ||
154 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); | ||
155 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 16ec5233441c..b99b8cbde02f 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -12,6 +12,56 @@ menuconfig INPUT_MISC | |||
12 | 12 | ||
13 | if INPUT_MISC | 13 | if INPUT_MISC |
14 | 14 | ||
15 | config INPUT_88PM860X_ONKEY | ||
16 | tristate "88PM860x ONKEY support" | ||
17 | depends on MFD_88PM860X | ||
18 | help | ||
19 | Support the ONKEY of Marvell 88PM860x PMICs as an input device | ||
20 | reporting power button status. | ||
21 | |||
22 | To compile this driver as a module, choose M here: the module | ||
23 | will be called 88pm860x_onkey. | ||
24 | |||
25 | config INPUT_AB8500_PONKEY | ||
26 | tristate "AB8500 Pon (PowerOn) Key" | ||
27 | depends on AB8500_CORE | ||
28 | help | ||
29 | Say Y here to use the PowerOn Key for ST-Ericsson's AB8500 | ||
30 | Mix-Sig PMIC. | ||
31 | |||
32 | To compile this driver as a module, choose M here: the module | ||
33 | will be called ab8500-ponkey. | ||
34 | |||
35 | config INPUT_AD714X | ||
36 | tristate "Analog Devices AD714x Capacitance Touch Sensor" | ||
37 | help | ||
38 | Say Y here if you want to support an AD7142/3/7/8/7A touch sensor. | ||
39 | |||
40 | You should select a bus connection too. | ||
41 | |||
42 | To compile this driver as a module, choose M here: the | ||
43 | module will be called ad714x. | ||
44 | |||
45 | config INPUT_AD714X_I2C | ||
46 | tristate "support I2C bus connection" | ||
47 | depends on INPUT_AD714X && I2C | ||
48 | default y | ||
49 | help | ||
50 | Say Y here if you have AD7142/AD7147 hooked to an I2C bus. | ||
51 | |||
52 | To compile this driver as a module, choose M here: the | ||
53 | module will be called ad714x-i2c. | ||
54 | |||
55 | config INPUT_AD714X_SPI | ||
56 | tristate "support SPI bus connection" | ||
57 | depends on INPUT_AD714X && SPI | ||
58 | default y | ||
59 | help | ||
60 | Say Y here if you have AD7142/AD7147 hooked to a SPI bus. | ||
61 | |||
62 | To compile this driver as a module, choose M here: the | ||
63 | module will be called ad714x-spi. | ||
64 | |||
15 | config INPUT_PCSPKR | 65 | config INPUT_PCSPKR |
16 | tristate "PC Speaker support" | 66 | tristate "PC Speaker support" |
17 | depends on PCSPKR_PLATFORM | 67 | depends on PCSPKR_PLATFORM |
@@ -40,6 +90,16 @@ config INPUT_M68K_BEEP | |||
40 | tristate "M68k Beeper support" | 90 | tristate "M68k Beeper support" |
41 | depends on M68K | 91 | depends on M68K |
42 | 92 | ||
93 | config INPUT_MAX8925_ONKEY | ||
94 | tristate "MAX8925 ONKEY support" | ||
95 | depends on MFD_MAX8925 | ||
96 | help | ||
97 | Support the ONKEY of MAX8925 PMICs as an input device | ||
98 | reporting power button status. | ||
99 | |||
100 | To compile this driver as a module, choose M here: the module | ||
101 | will be called max8925_onkey. | ||
102 | |||
43 | config INPUT_APANEL | 103 | config INPUT_APANEL |
44 | tristate "Fujitsu Lifebook Application Panel buttons" | 104 | tristate "Fujitsu Lifebook Application Panel buttons" |
45 | depends on X86 && I2C && LEDS_CLASS | 105 | depends on X86 && I2C && LEDS_CLASS |
@@ -204,6 +264,17 @@ config INPUT_TWL4030_PWRBUTTON | |||
204 | To compile this driver as a module, choose M here. The module will | 264 | To compile this driver as a module, choose M here. The module will |
205 | be called twl4030_pwrbutton. | 265 | be called twl4030_pwrbutton. |
206 | 266 | ||
267 | config INPUT_TWL4030_VIBRA | ||
268 | tristate "Support for TWL4030 Vibrator" | ||
269 | depends on TWL4030_CORE | ||
270 | select TWL4030_CODEC | ||
271 | select INPUT_FF_MEMLESS | ||
272 | help | ||
273 | This option enables support for TWL4030 Vibrator Driver. | ||
274 | |||
275 | To compile this driver as a module, choose M here. The module will | ||
276 | be called twl4030_vibra. | ||
277 | |||
207 | config INPUT_UINPUT | 278 | config INPUT_UINPUT |
208 | tristate "User level driver support" | 279 | tristate "User level driver support" |
209 | help | 280 | help |
@@ -256,6 +327,27 @@ config INPUT_PCF50633_PMU | |||
256 | Say Y to include support for delivering PMU events via input | 327 | Say Y to include support for delivering PMU events via input |
257 | layer on NXP PCF50633. | 328 | layer on NXP PCF50633. |
258 | 329 | ||
330 | config INPUT_PCF8574 | ||
331 | tristate "PCF8574 Keypad input device" | ||
332 | depends on I2C && EXPERIMENTAL | ||
333 | help | ||
334 | Say Y here if you want to support a keypad connetced via I2C | ||
335 | with a PCF8574. | ||
336 | |||
337 | To compile this driver as a module, choose M here: the | ||
338 | module will be called pcf8574_keypad. | ||
339 | |||
340 | config INPUT_PWM_BEEPER | ||
341 | tristate "PWM beeper support" | ||
342 | depends on HAVE_PWM | ||
343 | help | ||
344 | Say Y here to get support for PWM based beeper devices. | ||
345 | |||
346 | If unsure, say N. | ||
347 | |||
348 | To compile this driver as a module, choose M here: the module will be | ||
349 | called pwm-beeper. | ||
350 | |||
259 | config INPUT_GPIO_ROTARY_ENCODER | 351 | config INPUT_GPIO_ROTARY_ENCODER |
260 | tristate "Rotary encoders connected to GPIO pins" | 352 | tristate "Rotary encoders connected to GPIO pins" |
261 | depends on GPIOLIB && GENERIC_GPIO | 353 | depends on GPIOLIB && GENERIC_GPIO |
@@ -319,4 +411,41 @@ config INPUT_PCAP | |||
319 | To compile this driver as a module, choose M here: the | 411 | To compile this driver as a module, choose M here: the |
320 | module will be called pcap_keys. | 412 | module will be called pcap_keys. |
321 | 413 | ||
414 | config INPUT_ADXL34X | ||
415 | tristate "Analog Devices ADXL34x Three-Axis Digital Accelerometer" | ||
416 | default n | ||
417 | help | ||
418 | Say Y here if you have a Accelerometer interface using the | ||
419 | ADXL345/6 controller, and your board-specific initialization | ||
420 | code includes that in its table of devices. | ||
421 | |||
422 | This driver can use either I2C or SPI communication to the | ||
423 | ADXL345/6 controller. Select the appropriate method for | ||
424 | your system. | ||
425 | |||
426 | If unsure, say N (but it's safe to say "Y"). | ||
427 | |||
428 | To compile this driver as a module, choose M here: the | ||
429 | module will be called adxl34x. | ||
430 | |||
431 | config INPUT_ADXL34X_I2C | ||
432 | tristate "support I2C bus connection" | ||
433 | depends on INPUT_ADXL34X && I2C | ||
434 | default y | ||
435 | help | ||
436 | Say Y here if you have ADXL345/6 hooked to an I2C bus. | ||
437 | |||
438 | To compile this driver as a module, choose M here: the | ||
439 | module will be called adxl34x-i2c. | ||
440 | |||
441 | config INPUT_ADXL34X_SPI | ||
442 | tristate "support SPI bus connection" | ||
443 | depends on INPUT_ADXL34X && SPI | ||
444 | default y | ||
445 | help | ||
446 | Say Y here if you have ADXL345/6 hooked to a SPI bus. | ||
447 | |||
448 | To compile this driver as a module, choose M here: the | ||
449 | module will be called adxl34x-spi. | ||
450 | |||
322 | endif | 451 | endif |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index a8b84854fb7b..1fe1f6c8b737 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -4,6 +4,14 @@ | |||
4 | 4 | ||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o | ||
8 | obj-$(CONFIG_INPUT_AB8500_PONKEY) += ab8500-ponkey.o | ||
9 | obj-$(CONFIG_INPUT_AD714X) += ad714x.o | ||
10 | obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o | ||
11 | obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o | ||
12 | obj-$(CONFIG_INPUT_ADXL34X) += adxl34x.o | ||
13 | obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o | ||
14 | obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o | ||
7 | obj-$(CONFIG_INPUT_APANEL) += apanel.o | 15 | obj-$(CONFIG_INPUT_APANEL) += apanel.o |
8 | obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o | 16 | obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o |
9 | obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o | 17 | obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o |
@@ -16,15 +24,19 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | |||
16 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o | 24 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o |
17 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o | 25 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o |
18 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o | 26 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o |
27 | obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o | ||
19 | obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o | 28 | obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o |
20 | obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o | 29 | obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o |
30 | obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o | ||
21 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o | 31 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o |
22 | obj-$(CONFIG_INPUT_POWERMATE) += powermate.o | 32 | obj-$(CONFIG_INPUT_POWERMATE) += powermate.o |
33 | obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o | ||
23 | obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o | 34 | obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o |
24 | obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o | 35 | obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o |
25 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o | 36 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o |
26 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | 37 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o |
27 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o | 38 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o |
39 | obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o | ||
28 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 40 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
29 | obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o | 41 | obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o |
30 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | 42 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o |
diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c new file mode 100644 index 000000000000..3d3288a78fdc --- /dev/null +++ b/drivers/input/misc/ab8500-ponkey.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | ||
6 | * | ||
7 | * AB8500 Power-On Key handler | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/input.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/mfd/ab8500.h> | ||
16 | #include <linux/slab.h> | ||
17 | |||
18 | /** | ||
19 | * struct ab8500_ponkey - ab8500 ponkey information | ||
20 | * @input_dev: pointer to input device | ||
21 | * @ab8500: ab8500 parent | ||
22 | * @irq_dbf: irq number for falling transition | ||
23 | * @irq_dbr: irq number for rising transition | ||
24 | */ | ||
25 | struct ab8500_ponkey { | ||
26 | struct input_dev *idev; | ||
27 | struct ab8500 *ab8500; | ||
28 | int irq_dbf; | ||
29 | int irq_dbr; | ||
30 | }; | ||
31 | |||
32 | /* AB8500 gives us an interrupt when ONKEY is held */ | ||
33 | static irqreturn_t ab8500_ponkey_handler(int irq, void *data) | ||
34 | { | ||
35 | struct ab8500_ponkey *ponkey = data; | ||
36 | |||
37 | if (irq == ponkey->irq_dbf) | ||
38 | input_report_key(ponkey->idev, KEY_POWER, true); | ||
39 | else if (irq == ponkey->irq_dbr) | ||
40 | input_report_key(ponkey->idev, KEY_POWER, false); | ||
41 | |||
42 | input_sync(ponkey->idev); | ||
43 | |||
44 | return IRQ_HANDLED; | ||
45 | } | ||
46 | |||
47 | static int __devinit ab8500_ponkey_probe(struct platform_device *pdev) | ||
48 | { | ||
49 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | ||
50 | struct ab8500_ponkey *ponkey; | ||
51 | struct input_dev *input; | ||
52 | int irq_dbf, irq_dbr; | ||
53 | int error; | ||
54 | |||
55 | irq_dbf = platform_get_irq_byname(pdev, "ONKEY_DBF"); | ||
56 | if (irq_dbf < 0) { | ||
57 | dev_err(&pdev->dev, "No IRQ for ONKEY_DBF, error=%d\n", irq_dbf); | ||
58 | return irq_dbf; | ||
59 | } | ||
60 | |||
61 | irq_dbr = platform_get_irq_byname(pdev, "ONKEY_DBR"); | ||
62 | if (irq_dbr < 0) { | ||
63 | dev_err(&pdev->dev, "No IRQ for ONKEY_DBR, error=%d\n", irq_dbr); | ||
64 | return irq_dbr; | ||
65 | } | ||
66 | |||
67 | ponkey = kzalloc(sizeof(struct ab8500_ponkey), GFP_KERNEL); | ||
68 | input = input_allocate_device(); | ||
69 | if (!ponkey || !input) { | ||
70 | error = -ENOMEM; | ||
71 | goto err_free_mem; | ||
72 | } | ||
73 | |||
74 | ponkey->idev = input; | ||
75 | ponkey->ab8500 = ab8500; | ||
76 | ponkey->irq_dbf = irq_dbf; | ||
77 | ponkey->irq_dbr = irq_dbr; | ||
78 | |||
79 | input->name = "AB8500 POn(PowerOn) Key"; | ||
80 | input->dev.parent = &pdev->dev; | ||
81 | |||
82 | input_set_capability(input, EV_KEY, KEY_POWER); | ||
83 | |||
84 | error = request_any_context_irq(ponkey->irq_dbf, ab8500_ponkey_handler, | ||
85 | 0, "ab8500-ponkey-dbf", ponkey); | ||
86 | if (error < 0) { | ||
87 | dev_err(ab8500->dev, "Failed to request dbf IRQ#%d: %d\n", | ||
88 | ponkey->irq_dbf, error); | ||
89 | goto err_free_mem; | ||
90 | } | ||
91 | |||
92 | error = request_any_context_irq(ponkey->irq_dbr, ab8500_ponkey_handler, | ||
93 | 0, "ab8500-ponkey-dbr", ponkey); | ||
94 | if (error < 0) { | ||
95 | dev_err(ab8500->dev, "Failed to request dbr IRQ#%d: %d\n", | ||
96 | ponkey->irq_dbr, error); | ||
97 | goto err_free_dbf_irq; | ||
98 | } | ||
99 | |||
100 | error = input_register_device(ponkey->idev); | ||
101 | if (error) { | ||
102 | dev_err(ab8500->dev, "Can't register input device: %d\n", error); | ||
103 | goto err_free_dbr_irq; | ||
104 | } | ||
105 | |||
106 | platform_set_drvdata(pdev, ponkey); | ||
107 | return 0; | ||
108 | |||
109 | err_free_dbr_irq: | ||
110 | free_irq(ponkey->irq_dbr, ponkey); | ||
111 | err_free_dbf_irq: | ||
112 | free_irq(ponkey->irq_dbf, ponkey); | ||
113 | err_free_mem: | ||
114 | input_free_device(input); | ||
115 | kfree(ponkey); | ||
116 | |||
117 | return error; | ||
118 | } | ||
119 | |||
120 | static int __devexit ab8500_ponkey_remove(struct platform_device *pdev) | ||
121 | { | ||
122 | struct ab8500_ponkey *ponkey = platform_get_drvdata(pdev); | ||
123 | |||
124 | free_irq(ponkey->irq_dbf, ponkey); | ||
125 | free_irq(ponkey->irq_dbr, ponkey); | ||
126 | input_unregister_device(ponkey->idev); | ||
127 | kfree(ponkey); | ||
128 | |||
129 | platform_set_drvdata(pdev, NULL); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static struct platform_driver ab8500_ponkey_driver = { | ||
135 | .driver = { | ||
136 | .name = "ab8500-poweron-key", | ||
137 | .owner = THIS_MODULE, | ||
138 | }, | ||
139 | .probe = ab8500_ponkey_probe, | ||
140 | .remove = __devexit_p(ab8500_ponkey_remove), | ||
141 | }; | ||
142 | |||
143 | static int __init ab8500_ponkey_init(void) | ||
144 | { | ||
145 | return platform_driver_register(&ab8500_ponkey_driver); | ||
146 | } | ||
147 | module_init(ab8500_ponkey_init); | ||
148 | |||
149 | static void __exit ab8500_ponkey_exit(void) | ||
150 | { | ||
151 | platform_driver_unregister(&ab8500_ponkey_driver); | ||
152 | } | ||
153 | module_exit(ab8500_ponkey_exit); | ||
154 | |||
155 | MODULE_LICENSE("GPL v2"); | ||
156 | MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>"); | ||
157 | MODULE_DESCRIPTION("ST-Ericsson AB8500 Power-ON(Pon) Key driver"); | ||
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c new file mode 100644 index 000000000000..2bef8fa56c94 --- /dev/null +++ b/drivers/input/misc/ad714x-i2c.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * AD714X CapTouch Programmable Controller driver (I2C bus) | ||
3 | * | ||
4 | * Copyright 2009 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/input.h> /* BUS_I2C */ | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/types.h> | ||
13 | #include "ad714x.h" | ||
14 | |||
15 | #ifdef CONFIG_PM | ||
16 | static int ad714x_i2c_suspend(struct i2c_client *client, pm_message_t message) | ||
17 | { | ||
18 | return ad714x_disable(i2c_get_clientdata(client)); | ||
19 | } | ||
20 | |||
21 | static int ad714x_i2c_resume(struct i2c_client *client) | ||
22 | { | ||
23 | return ad714x_enable(i2c_get_clientdata(client)); | ||
24 | } | ||
25 | #else | ||
26 | # define ad714x_i2c_suspend NULL | ||
27 | # define ad714x_i2c_resume NULL | ||
28 | #endif | ||
29 | |||
30 | static int ad714x_i2c_write(struct device *dev, unsigned short reg, | ||
31 | unsigned short data) | ||
32 | { | ||
33 | struct i2c_client *client = to_i2c_client(dev); | ||
34 | int ret = 0; | ||
35 | u8 *_reg = (u8 *)® | ||
36 | u8 *_data = (u8 *)&data; | ||
37 | |||
38 | u8 tx[4] = { | ||
39 | _reg[1], | ||
40 | _reg[0], | ||
41 | _data[1], | ||
42 | _data[0] | ||
43 | }; | ||
44 | |||
45 | ret = i2c_master_send(client, tx, 4); | ||
46 | if (ret < 0) | ||
47 | dev_err(&client->dev, "I2C write error\n"); | ||
48 | |||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | static int ad714x_i2c_read(struct device *dev, unsigned short reg, | ||
53 | unsigned short *data) | ||
54 | { | ||
55 | struct i2c_client *client = to_i2c_client(dev); | ||
56 | int ret = 0; | ||
57 | u8 *_reg = (u8 *)® | ||
58 | u8 *_data = (u8 *)data; | ||
59 | |||
60 | u8 tx[2] = { | ||
61 | _reg[1], | ||
62 | _reg[0] | ||
63 | }; | ||
64 | u8 rx[2]; | ||
65 | |||
66 | ret = i2c_master_send(client, tx, 2); | ||
67 | if (ret >= 0) | ||
68 | ret = i2c_master_recv(client, rx, 2); | ||
69 | |||
70 | if (unlikely(ret < 0)) { | ||
71 | dev_err(&client->dev, "I2C read error\n"); | ||
72 | } else { | ||
73 | _data[0] = rx[1]; | ||
74 | _data[1] = rx[0]; | ||
75 | } | ||
76 | |||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | static int __devinit ad714x_i2c_probe(struct i2c_client *client, | ||
81 | const struct i2c_device_id *id) | ||
82 | { | ||
83 | struct ad714x_chip *chip; | ||
84 | |||
85 | chip = ad714x_probe(&client->dev, BUS_I2C, client->irq, | ||
86 | ad714x_i2c_read, ad714x_i2c_write); | ||
87 | if (IS_ERR(chip)) | ||
88 | return PTR_ERR(chip); | ||
89 | |||
90 | i2c_set_clientdata(client, chip); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static int __devexit ad714x_i2c_remove(struct i2c_client *client) | ||
96 | { | ||
97 | struct ad714x_chip *chip = i2c_get_clientdata(client); | ||
98 | |||
99 | ad714x_remove(chip); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static const struct i2c_device_id ad714x_id[] = { | ||
105 | { "ad7142_captouch", 0 }, | ||
106 | { "ad7143_captouch", 0 }, | ||
107 | { "ad7147_captouch", 0 }, | ||
108 | { "ad7147a_captouch", 0 }, | ||
109 | { "ad7148_captouch", 0 }, | ||
110 | { } | ||
111 | }; | ||
112 | MODULE_DEVICE_TABLE(i2c, ad714x_id); | ||
113 | |||
114 | static struct i2c_driver ad714x_i2c_driver = { | ||
115 | .driver = { | ||
116 | .name = "ad714x_captouch", | ||
117 | }, | ||
118 | .probe = ad714x_i2c_probe, | ||
119 | .remove = __devexit_p(ad714x_i2c_remove), | ||
120 | .suspend = ad714x_i2c_suspend, | ||
121 | .resume = ad714x_i2c_resume, | ||
122 | .id_table = ad714x_id, | ||
123 | }; | ||
124 | |||
125 | static __init int ad714x_i2c_init(void) | ||
126 | { | ||
127 | return i2c_add_driver(&ad714x_i2c_driver); | ||
128 | } | ||
129 | module_init(ad714x_i2c_init); | ||
130 | |||
131 | static __exit void ad714x_i2c_exit(void) | ||
132 | { | ||
133 | i2c_del_driver(&ad714x_i2c_driver); | ||
134 | } | ||
135 | module_exit(ad714x_i2c_exit); | ||
136 | |||
137 | MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor I2C Bus Driver"); | ||
138 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
139 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c new file mode 100644 index 000000000000..7f8dedfd1bfe --- /dev/null +++ b/drivers/input/misc/ad714x-spi.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * AD714X CapTouch Programmable Controller driver (SPI bus) | ||
3 | * | ||
4 | * Copyright 2009 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/input.h> /* BUS_I2C */ | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/spi/spi.h> | ||
12 | #include <linux/types.h> | ||
13 | #include "ad714x.h" | ||
14 | |||
15 | #define AD714x_SPI_CMD_PREFIX 0xE000 /* bits 15:11 */ | ||
16 | #define AD714x_SPI_READ BIT(10) | ||
17 | |||
18 | #ifdef CONFIG_PM | ||
19 | static int ad714x_spi_suspend(struct spi_device *spi, pm_message_t message) | ||
20 | { | ||
21 | return ad714x_disable(spi_get_drvdata(spi)); | ||
22 | } | ||
23 | |||
24 | static int ad714x_spi_resume(struct spi_device *spi) | ||
25 | { | ||
26 | return ad714x_enable(spi_get_drvdata(spi)); | ||
27 | } | ||
28 | #else | ||
29 | # define ad714x_spi_suspend NULL | ||
30 | # define ad714x_spi_resume NULL | ||
31 | #endif | ||
32 | |||
33 | static int ad714x_spi_read(struct device *dev, unsigned short reg, | ||
34 | unsigned short *data) | ||
35 | { | ||
36 | struct spi_device *spi = to_spi_device(dev); | ||
37 | unsigned short tx = AD714x_SPI_CMD_PREFIX | AD714x_SPI_READ | reg; | ||
38 | |||
39 | return spi_write_then_read(spi, (u8 *)&tx, 2, (u8 *)data, 2); | ||
40 | } | ||
41 | |||
42 | static int ad714x_spi_write(struct device *dev, unsigned short reg, | ||
43 | unsigned short data) | ||
44 | { | ||
45 | struct spi_device *spi = to_spi_device(dev); | ||
46 | unsigned short tx[2] = { | ||
47 | AD714x_SPI_CMD_PREFIX | reg, | ||
48 | data | ||
49 | }; | ||
50 | |||
51 | return spi_write(spi, (u8 *)tx, 4); | ||
52 | } | ||
53 | |||
54 | static int __devinit ad714x_spi_probe(struct spi_device *spi) | ||
55 | { | ||
56 | struct ad714x_chip *chip; | ||
57 | |||
58 | chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq, | ||
59 | ad714x_spi_read, ad714x_spi_write); | ||
60 | if (IS_ERR(chip)) | ||
61 | return PTR_ERR(chip); | ||
62 | |||
63 | spi_set_drvdata(spi, chip); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static int __devexit ad714x_spi_remove(struct spi_device *spi) | ||
69 | { | ||
70 | struct ad714x_chip *chip = spi_get_drvdata(spi); | ||
71 | |||
72 | ad714x_remove(chip); | ||
73 | spi_set_drvdata(spi, NULL); | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static struct spi_driver ad714x_spi_driver = { | ||
79 | .driver = { | ||
80 | .name = "ad714x_captouch", | ||
81 | .owner = THIS_MODULE, | ||
82 | }, | ||
83 | .probe = ad714x_spi_probe, | ||
84 | .remove = __devexit_p(ad714x_spi_remove), | ||
85 | .suspend = ad714x_spi_suspend, | ||
86 | .resume = ad714x_spi_resume, | ||
87 | }; | ||
88 | |||
89 | static __init int ad714x_spi_init(void) | ||
90 | { | ||
91 | return spi_register_driver(&ad714x_spi_driver); | ||
92 | } | ||
93 | module_init(ad714x_spi_init); | ||
94 | |||
95 | static __exit void ad714x_spi_exit(void) | ||
96 | { | ||
97 | spi_unregister_driver(&ad714x_spi_driver); | ||
98 | } | ||
99 | module_exit(ad714x_spi_exit); | ||
100 | |||
101 | MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor SPI Bus Driver"); | ||
102 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
103 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c new file mode 100644 index 000000000000..c431d09e401a --- /dev/null +++ b/drivers/input/misc/ad714x.c | |||
@@ -0,0 +1,1347 @@ | |||
1 | /* | ||
2 | * AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A | ||
3 | * | ||
4 | * Copyright 2009 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/device.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/input.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/input/ad714x.h> | ||
15 | #include "ad714x.h" | ||
16 | |||
17 | #define AD714X_PWR_CTRL 0x0 | ||
18 | #define AD714X_STG_CAL_EN_REG 0x1 | ||
19 | #define AD714X_AMB_COMP_CTRL0_REG 0x2 | ||
20 | #define AD714X_PARTID_REG 0x17 | ||
21 | #define AD7142_PARTID 0xE620 | ||
22 | #define AD7143_PARTID 0xE630 | ||
23 | #define AD7147_PARTID 0x1470 | ||
24 | #define AD7148_PARTID 0x1480 | ||
25 | #define AD714X_STAGECFG_REG 0x80 | ||
26 | #define AD714X_SYSCFG_REG 0x0 | ||
27 | |||
28 | #define STG_LOW_INT_EN_REG 0x5 | ||
29 | #define STG_HIGH_INT_EN_REG 0x6 | ||
30 | #define STG_COM_INT_EN_REG 0x7 | ||
31 | #define STG_LOW_INT_STA_REG 0x8 | ||
32 | #define STG_HIGH_INT_STA_REG 0x9 | ||
33 | #define STG_COM_INT_STA_REG 0xA | ||
34 | |||
35 | #define CDC_RESULT_S0 0xB | ||
36 | #define CDC_RESULT_S1 0xC | ||
37 | #define CDC_RESULT_S2 0xD | ||
38 | #define CDC_RESULT_S3 0xE | ||
39 | #define CDC_RESULT_S4 0xF | ||
40 | #define CDC_RESULT_S5 0x10 | ||
41 | #define CDC_RESULT_S6 0x11 | ||
42 | #define CDC_RESULT_S7 0x12 | ||
43 | #define CDC_RESULT_S8 0x13 | ||
44 | #define CDC_RESULT_S9 0x14 | ||
45 | #define CDC_RESULT_S10 0x15 | ||
46 | #define CDC_RESULT_S11 0x16 | ||
47 | |||
48 | #define STAGE0_AMBIENT 0xF1 | ||
49 | #define STAGE1_AMBIENT 0x115 | ||
50 | #define STAGE2_AMBIENT 0x139 | ||
51 | #define STAGE3_AMBIENT 0x15D | ||
52 | #define STAGE4_AMBIENT 0x181 | ||
53 | #define STAGE5_AMBIENT 0x1A5 | ||
54 | #define STAGE6_AMBIENT 0x1C9 | ||
55 | #define STAGE7_AMBIENT 0x1ED | ||
56 | #define STAGE8_AMBIENT 0x211 | ||
57 | #define STAGE9_AMBIENT 0x234 | ||
58 | #define STAGE10_AMBIENT 0x259 | ||
59 | #define STAGE11_AMBIENT 0x27D | ||
60 | |||
61 | #define PER_STAGE_REG_NUM 36 | ||
62 | #define STAGE_NUM 12 | ||
63 | #define STAGE_CFGREG_NUM 8 | ||
64 | #define SYS_CFGREG_NUM 8 | ||
65 | |||
66 | /* | ||
67 | * driver information which will be used to maintain the software flow | ||
68 | */ | ||
69 | enum ad714x_device_state { IDLE, JITTER, ACTIVE, SPACE }; | ||
70 | |||
71 | struct ad714x_slider_drv { | ||
72 | int highest_stage; | ||
73 | int abs_pos; | ||
74 | int flt_pos; | ||
75 | enum ad714x_device_state state; | ||
76 | struct input_dev *input; | ||
77 | }; | ||
78 | |||
79 | struct ad714x_wheel_drv { | ||
80 | int abs_pos; | ||
81 | int flt_pos; | ||
82 | int pre_mean_value; | ||
83 | int pre_highest_stage; | ||
84 | int pre_mean_value_no_offset; | ||
85 | int mean_value; | ||
86 | int mean_value_no_offset; | ||
87 | int pos_offset; | ||
88 | int pos_ratio; | ||
89 | int highest_stage; | ||
90 | enum ad714x_device_state state; | ||
91 | struct input_dev *input; | ||
92 | }; | ||
93 | |||
94 | struct ad714x_touchpad_drv { | ||
95 | int x_highest_stage; | ||
96 | int x_flt_pos; | ||
97 | int x_abs_pos; | ||
98 | int y_highest_stage; | ||
99 | int y_flt_pos; | ||
100 | int y_abs_pos; | ||
101 | int left_ep; | ||
102 | int left_ep_val; | ||
103 | int right_ep; | ||
104 | int right_ep_val; | ||
105 | int top_ep; | ||
106 | int top_ep_val; | ||
107 | int bottom_ep; | ||
108 | int bottom_ep_val; | ||
109 | enum ad714x_device_state state; | ||
110 | struct input_dev *input; | ||
111 | }; | ||
112 | |||
113 | struct ad714x_button_drv { | ||
114 | enum ad714x_device_state state; | ||
115 | /* | ||
116 | * Unlike slider/wheel/touchpad, all buttons point to | ||
117 | * same input_dev instance | ||
118 | */ | ||
119 | struct input_dev *input; | ||
120 | }; | ||
121 | |||
122 | struct ad714x_driver_data { | ||
123 | struct ad714x_slider_drv *slider; | ||
124 | struct ad714x_wheel_drv *wheel; | ||
125 | struct ad714x_touchpad_drv *touchpad; | ||
126 | struct ad714x_button_drv *button; | ||
127 | }; | ||
128 | |||
129 | /* | ||
130 | * information to integrate all things which will be private data | ||
131 | * of spi/i2c device | ||
132 | */ | ||
133 | struct ad714x_chip { | ||
134 | unsigned short h_state; | ||
135 | unsigned short l_state; | ||
136 | unsigned short c_state; | ||
137 | unsigned short adc_reg[STAGE_NUM]; | ||
138 | unsigned short amb_reg[STAGE_NUM]; | ||
139 | unsigned short sensor_val[STAGE_NUM]; | ||
140 | |||
141 | struct ad714x_platform_data *hw; | ||
142 | struct ad714x_driver_data *sw; | ||
143 | |||
144 | int irq; | ||
145 | struct device *dev; | ||
146 | ad714x_read_t read; | ||
147 | ad714x_write_t write; | ||
148 | |||
149 | struct mutex mutex; | ||
150 | |||
151 | unsigned product; | ||
152 | unsigned version; | ||
153 | }; | ||
154 | |||
155 | static void ad714x_use_com_int(struct ad714x_chip *ad714x, | ||
156 | int start_stage, int end_stage) | ||
157 | { | ||
158 | unsigned short data; | ||
159 | unsigned short mask; | ||
160 | |||
161 | mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage); | ||
162 | |||
163 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); | ||
164 | data |= 1 << start_stage; | ||
165 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); | ||
166 | |||
167 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); | ||
168 | data &= ~mask; | ||
169 | ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data); | ||
170 | } | ||
171 | |||
172 | static void ad714x_use_thr_int(struct ad714x_chip *ad714x, | ||
173 | int start_stage, int end_stage) | ||
174 | { | ||
175 | unsigned short data; | ||
176 | unsigned short mask; | ||
177 | |||
178 | mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage); | ||
179 | |||
180 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); | ||
181 | data &= ~(1 << start_stage); | ||
182 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); | ||
183 | |||
184 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); | ||
185 | data |= mask; | ||
186 | ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data); | ||
187 | } | ||
188 | |||
189 | static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x, | ||
190 | int start_stage, int end_stage) | ||
191 | { | ||
192 | int max_res = 0; | ||
193 | int max_idx = 0; | ||
194 | int i; | ||
195 | |||
196 | for (i = start_stage; i <= end_stage; i++) { | ||
197 | if (ad714x->sensor_val[i] > max_res) { | ||
198 | max_res = ad714x->sensor_val[i]; | ||
199 | max_idx = i; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | return max_idx; | ||
204 | } | ||
205 | |||
206 | static int ad714x_cal_abs_pos(struct ad714x_chip *ad714x, | ||
207 | int start_stage, int end_stage, | ||
208 | int highest_stage, int max_coord) | ||
209 | { | ||
210 | int a_param, b_param; | ||
211 | |||
212 | if (highest_stage == start_stage) { | ||
213 | a_param = ad714x->sensor_val[start_stage + 1]; | ||
214 | b_param = ad714x->sensor_val[start_stage] + | ||
215 | ad714x->sensor_val[start_stage + 1]; | ||
216 | } else if (highest_stage == end_stage) { | ||
217 | a_param = ad714x->sensor_val[end_stage] * | ||
218 | (end_stage - start_stage) + | ||
219 | ad714x->sensor_val[end_stage - 1] * | ||
220 | (end_stage - start_stage - 1); | ||
221 | b_param = ad714x->sensor_val[end_stage] + | ||
222 | ad714x->sensor_val[end_stage - 1]; | ||
223 | } else { | ||
224 | a_param = ad714x->sensor_val[highest_stage] * | ||
225 | (highest_stage - start_stage) + | ||
226 | ad714x->sensor_val[highest_stage - 1] * | ||
227 | (highest_stage - start_stage - 1) + | ||
228 | ad714x->sensor_val[highest_stage + 1] * | ||
229 | (highest_stage - start_stage + 1); | ||
230 | b_param = ad714x->sensor_val[highest_stage] + | ||
231 | ad714x->sensor_val[highest_stage - 1] + | ||
232 | ad714x->sensor_val[highest_stage + 1]; | ||
233 | } | ||
234 | |||
235 | return (max_coord / (end_stage - start_stage)) * a_param / b_param; | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * One button can connect to multi positive and negative of CDCs | ||
240 | * Multi-buttons can connect to same positive/negative of one CDC | ||
241 | */ | ||
242 | static void ad714x_button_state_machine(struct ad714x_chip *ad714x, int idx) | ||
243 | { | ||
244 | struct ad714x_button_plat *hw = &ad714x->hw->button[idx]; | ||
245 | struct ad714x_button_drv *sw = &ad714x->sw->button[idx]; | ||
246 | |||
247 | switch (sw->state) { | ||
248 | case IDLE: | ||
249 | if (((ad714x->h_state & hw->h_mask) == hw->h_mask) && | ||
250 | ((ad714x->l_state & hw->l_mask) == hw->l_mask)) { | ||
251 | dev_dbg(ad714x->dev, "button %d touched\n", idx); | ||
252 | input_report_key(sw->input, hw->keycode, 1); | ||
253 | input_sync(sw->input); | ||
254 | sw->state = ACTIVE; | ||
255 | } | ||
256 | break; | ||
257 | |||
258 | case ACTIVE: | ||
259 | if (((ad714x->h_state & hw->h_mask) != hw->h_mask) || | ||
260 | ((ad714x->l_state & hw->l_mask) != hw->l_mask)) { | ||
261 | dev_dbg(ad714x->dev, "button %d released\n", idx); | ||
262 | input_report_key(sw->input, hw->keycode, 0); | ||
263 | input_sync(sw->input); | ||
264 | sw->state = IDLE; | ||
265 | } | ||
266 | break; | ||
267 | |||
268 | default: | ||
269 | break; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * The response of a sensor is defined by the absolute number of codes | ||
275 | * between the current CDC value and the ambient value. | ||
276 | */ | ||
277 | static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx) | ||
278 | { | ||
279 | struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx]; | ||
280 | int i; | ||
281 | |||
282 | for (i = hw->start_stage; i <= hw->end_stage; i++) { | ||
283 | ad714x->read(ad714x->dev, CDC_RESULT_S0 + i, | ||
284 | &ad714x->adc_reg[i]); | ||
285 | ad714x->read(ad714x->dev, | ||
286 | STAGE0_AMBIENT + i * PER_STAGE_REG_NUM, | ||
287 | &ad714x->amb_reg[i]); | ||
288 | |||
289 | ad714x->sensor_val[i] = abs(ad714x->adc_reg[i] - | ||
290 | ad714x->amb_reg[i]); | ||
291 | } | ||
292 | } | ||
293 | |||
294 | static void ad714x_slider_cal_highest_stage(struct ad714x_chip *ad714x, int idx) | ||
295 | { | ||
296 | struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx]; | ||
297 | struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx]; | ||
298 | |||
299 | sw->highest_stage = ad714x_cal_highest_stage(ad714x, hw->start_stage, | ||
300 | hw->end_stage); | ||
301 | |||
302 | dev_dbg(ad714x->dev, "slider %d highest_stage:%d\n", idx, | ||
303 | sw->highest_stage); | ||
304 | } | ||
305 | |||
306 | /* | ||
307 | * The formulae are very straight forward. It uses the sensor with the | ||
308 | * highest response and the 2 adjacent ones. | ||
309 | * When Sensor 0 has the highest response, only sensor 0 and sensor 1 | ||
310 | * are used in the calculations. Similarly when the last sensor has the | ||
311 | * highest response, only the last sensor and the second last sensors | ||
312 | * are used in the calculations. | ||
313 | * | ||
314 | * For i= idx_of_peak_Sensor-1 to i= idx_of_peak_Sensor+1 | ||
315 | * v += Sensor response(i)*i | ||
316 | * w += Sensor response(i) | ||
317 | * POS=(Number_of_Positions_Wanted/(Number_of_Sensors_Used-1)) *(v/w) | ||
318 | */ | ||
319 | static void ad714x_slider_cal_abs_pos(struct ad714x_chip *ad714x, int idx) | ||
320 | { | ||
321 | struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx]; | ||
322 | struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx]; | ||
323 | |||
324 | sw->abs_pos = ad714x_cal_abs_pos(ad714x, hw->start_stage, hw->end_stage, | ||
325 | sw->highest_stage, hw->max_coord); | ||
326 | |||
327 | dev_dbg(ad714x->dev, "slider %d absolute position:%d\n", idx, | ||
328 | sw->abs_pos); | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * To minimise the Impact of the noise on the algorithm, ADI developed a | ||
333 | * routine that filters the CDC results after they have been read by the | ||
334 | * host processor. | ||
335 | * The filter used is an Infinite Input Response(IIR) filter implemented | ||
336 | * in firmware and attenuates the noise on the CDC results after they've | ||
337 | * been read by the host processor. | ||
338 | * Filtered_CDC_result = (Filtered_CDC_result * (10 - Coefficient) + | ||
339 | * Latest_CDC_result * Coefficient)/10 | ||
340 | */ | ||
341 | static void ad714x_slider_cal_flt_pos(struct ad714x_chip *ad714x, int idx) | ||
342 | { | ||
343 | struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx]; | ||
344 | |||
345 | sw->flt_pos = (sw->flt_pos * (10 - 4) + | ||
346 | sw->abs_pos * 4)/10; | ||
347 | |||
348 | dev_dbg(ad714x->dev, "slider %d filter position:%d\n", idx, | ||
349 | sw->flt_pos); | ||
350 | } | ||
351 | |||
352 | static void ad714x_slider_use_com_int(struct ad714x_chip *ad714x, int idx) | ||
353 | { | ||
354 | struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx]; | ||
355 | |||
356 | ad714x_use_com_int(ad714x, hw->start_stage, hw->end_stage); | ||
357 | } | ||
358 | |||
359 | static void ad714x_slider_use_thr_int(struct ad714x_chip *ad714x, int idx) | ||
360 | { | ||
361 | struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx]; | ||
362 | |||
363 | ad714x_use_thr_int(ad714x, hw->start_stage, hw->end_stage); | ||
364 | } | ||
365 | |||
366 | static void ad714x_slider_state_machine(struct ad714x_chip *ad714x, int idx) | ||
367 | { | ||
368 | struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx]; | ||
369 | struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx]; | ||
370 | unsigned short h_state, c_state; | ||
371 | unsigned short mask; | ||
372 | |||
373 | mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1); | ||
374 | |||
375 | h_state = ad714x->h_state & mask; | ||
376 | c_state = ad714x->c_state & mask; | ||
377 | |||
378 | switch (sw->state) { | ||
379 | case IDLE: | ||
380 | if (h_state) { | ||
381 | sw->state = JITTER; | ||
382 | /* In End of Conversion interrupt mode, the AD714X | ||
383 | * continuously generates hardware interrupts. | ||
384 | */ | ||
385 | ad714x_slider_use_com_int(ad714x, idx); | ||
386 | dev_dbg(ad714x->dev, "slider %d touched\n", idx); | ||
387 | } | ||
388 | break; | ||
389 | |||
390 | case JITTER: | ||
391 | if (c_state == mask) { | ||
392 | ad714x_slider_cal_sensor_val(ad714x, idx); | ||
393 | ad714x_slider_cal_highest_stage(ad714x, idx); | ||
394 | ad714x_slider_cal_abs_pos(ad714x, idx); | ||
395 | sw->flt_pos = sw->abs_pos; | ||
396 | sw->state = ACTIVE; | ||
397 | } | ||
398 | break; | ||
399 | |||
400 | case ACTIVE: | ||
401 | if (c_state == mask) { | ||
402 | if (h_state) { | ||
403 | ad714x_slider_cal_sensor_val(ad714x, idx); | ||
404 | ad714x_slider_cal_highest_stage(ad714x, idx); | ||
405 | ad714x_slider_cal_abs_pos(ad714x, idx); | ||
406 | ad714x_slider_cal_flt_pos(ad714x, idx); | ||
407 | |||
408 | input_report_abs(sw->input, ABS_X, sw->flt_pos); | ||
409 | input_report_key(sw->input, BTN_TOUCH, 1); | ||
410 | } else { | ||
411 | /* When the user lifts off the sensor, configure | ||
412 | * the AD714X back to threshold interrupt mode. | ||
413 | */ | ||
414 | ad714x_slider_use_thr_int(ad714x, idx); | ||
415 | sw->state = IDLE; | ||
416 | input_report_key(sw->input, BTN_TOUCH, 0); | ||
417 | dev_dbg(ad714x->dev, "slider %d released\n", | ||
418 | idx); | ||
419 | } | ||
420 | input_sync(sw->input); | ||
421 | } | ||
422 | break; | ||
423 | |||
424 | default: | ||
425 | break; | ||
426 | } | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * When the scroll wheel is activated, we compute the absolute position based | ||
431 | * on the sensor values. To calculate the position, we first determine the | ||
432 | * sensor that has the greatest response among the 8 sensors that constitutes | ||
433 | * the scrollwheel. Then we determined the 2 sensors on either sides of the | ||
434 | * sensor with the highest response and we apply weights to these sensors. | ||
435 | */ | ||
436 | static void ad714x_wheel_cal_highest_stage(struct ad714x_chip *ad714x, int idx) | ||
437 | { | ||
438 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; | ||
439 | struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx]; | ||
440 | |||
441 | sw->pre_highest_stage = sw->highest_stage; | ||
442 | sw->highest_stage = ad714x_cal_highest_stage(ad714x, hw->start_stage, | ||
443 | hw->end_stage); | ||
444 | |||
445 | dev_dbg(ad714x->dev, "wheel %d highest_stage:%d\n", idx, | ||
446 | sw->highest_stage); | ||
447 | } | ||
448 | |||
449 | static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx) | ||
450 | { | ||
451 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; | ||
452 | int i; | ||
453 | |||
454 | for (i = hw->start_stage; i <= hw->end_stage; i++) { | ||
455 | ad714x->read(ad714x->dev, CDC_RESULT_S0 + i, | ||
456 | &ad714x->adc_reg[i]); | ||
457 | ad714x->read(ad714x->dev, | ||
458 | STAGE0_AMBIENT + i * PER_STAGE_REG_NUM, | ||
459 | &ad714x->amb_reg[i]); | ||
460 | if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) | ||
461 | ad714x->sensor_val[i] = ad714x->adc_reg[i] - | ||
462 | ad714x->amb_reg[i]; | ||
463 | else | ||
464 | ad714x->sensor_val[i] = 0; | ||
465 | } | ||
466 | } | ||
467 | |||
468 | /* | ||
469 | * When the scroll wheel is activated, we compute the absolute position based | ||
470 | * on the sensor values. To calculate the position, we first determine the | ||
471 | * sensor that has the greatest response among the 8 sensors that constitutes | ||
472 | * the scrollwheel. Then we determined the 2 sensors on either sides of the | ||
473 | * sensor with the highest response and we apply weights to these sensors. The | ||
474 | * result of this computation gives us the mean value which defined by the | ||
475 | * following formula: | ||
476 | * For i= second_before_highest_stage to i= second_after_highest_stage | ||
477 | * v += Sensor response(i)*WEIGHT*(i+3) | ||
478 | * w += Sensor response(i) | ||
479 | * Mean_Value=v/w | ||
480 | * pos_on_scrollwheel = (Mean_Value - position_offset) / position_ratio | ||
481 | */ | ||
482 | |||
483 | #define WEIGHT_FACTOR 30 | ||
484 | /* This constant prevents the "PositionOffset" from reaching a big value */ | ||
485 | #define OFFSET_POSITION_CLAMP 120 | ||
486 | static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx) | ||
487 | { | ||
488 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; | ||
489 | struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx]; | ||
490 | int stage_num = hw->end_stage - hw->start_stage + 1; | ||
491 | int second_before, first_before, highest, first_after, second_after; | ||
492 | int a_param, b_param; | ||
493 | |||
494 | /* Calculate Mean value */ | ||
495 | |||
496 | second_before = (sw->highest_stage + stage_num - 2) % stage_num; | ||
497 | first_before = (sw->highest_stage + stage_num - 1) % stage_num; | ||
498 | highest = sw->highest_stage; | ||
499 | first_after = (sw->highest_stage + stage_num + 1) % stage_num; | ||
500 | second_after = (sw->highest_stage + stage_num + 2) % stage_num; | ||
501 | |||
502 | if (((sw->highest_stage - hw->start_stage) > 1) && | ||
503 | ((hw->end_stage - sw->highest_stage) > 1)) { | ||
504 | a_param = ad714x->sensor_val[second_before] * | ||
505 | (second_before - hw->start_stage + 3) + | ||
506 | ad714x->sensor_val[first_before] * | ||
507 | (second_before - hw->start_stage + 3) + | ||
508 | ad714x->sensor_val[highest] * | ||
509 | (second_before - hw->start_stage + 3) + | ||
510 | ad714x->sensor_val[first_after] * | ||
511 | (first_after - hw->start_stage + 3) + | ||
512 | ad714x->sensor_val[second_after] * | ||
513 | (second_after - hw->start_stage + 3); | ||
514 | } else { | ||
515 | a_param = ad714x->sensor_val[second_before] * | ||
516 | (second_before - hw->start_stage + 1) + | ||
517 | ad714x->sensor_val[first_before] * | ||
518 | (second_before - hw->start_stage + 2) + | ||
519 | ad714x->sensor_val[highest] * | ||
520 | (second_before - hw->start_stage + 3) + | ||
521 | ad714x->sensor_val[first_after] * | ||
522 | (first_after - hw->start_stage + 4) + | ||
523 | ad714x->sensor_val[second_after] * | ||
524 | (second_after - hw->start_stage + 5); | ||
525 | } | ||
526 | a_param *= WEIGHT_FACTOR; | ||
527 | |||
528 | b_param = ad714x->sensor_val[second_before] + | ||
529 | ad714x->sensor_val[first_before] + | ||
530 | ad714x->sensor_val[highest] + | ||
531 | ad714x->sensor_val[first_after] + | ||
532 | ad714x->sensor_val[second_after]; | ||
533 | |||
534 | sw->pre_mean_value = sw->mean_value; | ||
535 | sw->mean_value = a_param / b_param; | ||
536 | |||
537 | /* Calculate the offset */ | ||
538 | |||
539 | if ((sw->pre_highest_stage == hw->end_stage) && | ||
540 | (sw->highest_stage == hw->start_stage)) | ||
541 | sw->pos_offset = sw->mean_value; | ||
542 | else if ((sw->pre_highest_stage == hw->start_stage) && | ||
543 | (sw->highest_stage == hw->end_stage)) | ||
544 | sw->pos_offset = sw->pre_mean_value; | ||
545 | |||
546 | if (sw->pos_offset > OFFSET_POSITION_CLAMP) | ||
547 | sw->pos_offset = OFFSET_POSITION_CLAMP; | ||
548 | |||
549 | /* Calculate the mean value without the offset */ | ||
550 | |||
551 | sw->pre_mean_value_no_offset = sw->mean_value_no_offset; | ||
552 | sw->mean_value_no_offset = sw->mean_value - sw->pos_offset; | ||
553 | if (sw->mean_value_no_offset < 0) | ||
554 | sw->mean_value_no_offset = 0; | ||
555 | |||
556 | /* Calculate ratio to scale down to NUMBER_OF_WANTED_POSITIONS */ | ||
557 | |||
558 | if ((sw->pre_highest_stage == hw->end_stage) && | ||
559 | (sw->highest_stage == hw->start_stage)) | ||
560 | sw->pos_ratio = (sw->pre_mean_value_no_offset * 100) / | ||
561 | hw->max_coord; | ||
562 | else if ((sw->pre_highest_stage == hw->start_stage) && | ||
563 | (sw->highest_stage == hw->end_stage)) | ||
564 | sw->pos_ratio = (sw->mean_value_no_offset * 100) / | ||
565 | hw->max_coord; | ||
566 | sw->abs_pos = (sw->mean_value_no_offset * 100) / sw->pos_ratio; | ||
567 | if (sw->abs_pos > hw->max_coord) | ||
568 | sw->abs_pos = hw->max_coord; | ||
569 | } | ||
570 | |||
571 | static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx) | ||
572 | { | ||
573 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; | ||
574 | struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx]; | ||
575 | if (((sw->pre_highest_stage == hw->end_stage) && | ||
576 | (sw->highest_stage == hw->start_stage)) || | ||
577 | ((sw->pre_highest_stage == hw->start_stage) && | ||
578 | (sw->highest_stage == hw->end_stage))) | ||
579 | sw->flt_pos = sw->abs_pos; | ||
580 | else | ||
581 | sw->flt_pos = ((sw->flt_pos * 30) + (sw->abs_pos * 71)) / 100; | ||
582 | |||
583 | if (sw->flt_pos > hw->max_coord) | ||
584 | sw->flt_pos = hw->max_coord; | ||
585 | } | ||
586 | |||
587 | static void ad714x_wheel_use_com_int(struct ad714x_chip *ad714x, int idx) | ||
588 | { | ||
589 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; | ||
590 | |||
591 | ad714x_use_com_int(ad714x, hw->start_stage, hw->end_stage); | ||
592 | } | ||
593 | |||
594 | static void ad714x_wheel_use_thr_int(struct ad714x_chip *ad714x, int idx) | ||
595 | { | ||
596 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; | ||
597 | |||
598 | ad714x_use_thr_int(ad714x, hw->start_stage, hw->end_stage); | ||
599 | } | ||
600 | |||
601 | static void ad714x_wheel_state_machine(struct ad714x_chip *ad714x, int idx) | ||
602 | { | ||
603 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; | ||
604 | struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx]; | ||
605 | unsigned short h_state, c_state; | ||
606 | unsigned short mask; | ||
607 | |||
608 | mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1); | ||
609 | |||
610 | h_state = ad714x->h_state & mask; | ||
611 | c_state = ad714x->c_state & mask; | ||
612 | |||
613 | switch (sw->state) { | ||
614 | case IDLE: | ||
615 | if (h_state) { | ||
616 | sw->state = JITTER; | ||
617 | /* In End of Conversion interrupt mode, the AD714X | ||
618 | * continuously generates hardware interrupts. | ||
619 | */ | ||
620 | ad714x_wheel_use_com_int(ad714x, idx); | ||
621 | dev_dbg(ad714x->dev, "wheel %d touched\n", idx); | ||
622 | } | ||
623 | break; | ||
624 | |||
625 | case JITTER: | ||
626 | if (c_state == mask) { | ||
627 | ad714x_wheel_cal_sensor_val(ad714x, idx); | ||
628 | ad714x_wheel_cal_highest_stage(ad714x, idx); | ||
629 | ad714x_wheel_cal_abs_pos(ad714x, idx); | ||
630 | sw->flt_pos = sw->abs_pos; | ||
631 | sw->state = ACTIVE; | ||
632 | } | ||
633 | break; | ||
634 | |||
635 | case ACTIVE: | ||
636 | if (c_state == mask) { | ||
637 | if (h_state) { | ||
638 | ad714x_wheel_cal_sensor_val(ad714x, idx); | ||
639 | ad714x_wheel_cal_highest_stage(ad714x, idx); | ||
640 | ad714x_wheel_cal_abs_pos(ad714x, idx); | ||
641 | ad714x_wheel_cal_flt_pos(ad714x, idx); | ||
642 | |||
643 | input_report_abs(sw->input, ABS_WHEEL, | ||
644 | sw->abs_pos); | ||
645 | input_report_key(sw->input, BTN_TOUCH, 1); | ||
646 | } else { | ||
647 | /* When the user lifts off the sensor, configure | ||
648 | * the AD714X back to threshold interrupt mode. | ||
649 | */ | ||
650 | ad714x_wheel_use_thr_int(ad714x, idx); | ||
651 | sw->state = IDLE; | ||
652 | input_report_key(sw->input, BTN_TOUCH, 0); | ||
653 | |||
654 | dev_dbg(ad714x->dev, "wheel %d released\n", | ||
655 | idx); | ||
656 | } | ||
657 | input_sync(sw->input); | ||
658 | } | ||
659 | break; | ||
660 | |||
661 | default: | ||
662 | break; | ||
663 | } | ||
664 | } | ||
665 | |||
666 | static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx) | ||
667 | { | ||
668 | struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; | ||
669 | int i; | ||
670 | |||
671 | for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) { | ||
672 | ad714x->read(ad714x->dev, CDC_RESULT_S0 + i, | ||
673 | &ad714x->adc_reg[i]); | ||
674 | ad714x->read(ad714x->dev, | ||
675 | STAGE0_AMBIENT + i * PER_STAGE_REG_NUM, | ||
676 | &ad714x->amb_reg[i]); | ||
677 | if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) | ||
678 | ad714x->sensor_val[i] = ad714x->adc_reg[i] - | ||
679 | ad714x->amb_reg[i]; | ||
680 | else | ||
681 | ad714x->sensor_val[i] = 0; | ||
682 | } | ||
683 | } | ||
684 | |||
685 | static void touchpad_cal_highest_stage(struct ad714x_chip *ad714x, int idx) | ||
686 | { | ||
687 | struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; | ||
688 | struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx]; | ||
689 | |||
690 | sw->x_highest_stage = ad714x_cal_highest_stage(ad714x, | ||
691 | hw->x_start_stage, hw->x_end_stage); | ||
692 | sw->y_highest_stage = ad714x_cal_highest_stage(ad714x, | ||
693 | hw->y_start_stage, hw->y_end_stage); | ||
694 | |||
695 | dev_dbg(ad714x->dev, | ||
696 | "touchpad %d x_highest_stage:%d, y_highest_stage:%d\n", | ||
697 | idx, sw->x_highest_stage, sw->y_highest_stage); | ||
698 | } | ||
699 | |||
700 | /* | ||
701 | * If 2 fingers are touching the sensor then 2 peaks can be observed in the | ||
702 | * distribution. | ||
703 | * The arithmetic doesn't support to get absolute coordinates for multi-touch | ||
704 | * yet. | ||
705 | */ | ||
706 | static int touchpad_check_second_peak(struct ad714x_chip *ad714x, int idx) | ||
707 | { | ||
708 | struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; | ||
709 | struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx]; | ||
710 | int i; | ||
711 | |||
712 | for (i = hw->x_start_stage; i < sw->x_highest_stage; i++) { | ||
713 | if ((ad714x->sensor_val[i] - ad714x->sensor_val[i + 1]) | ||
714 | > (ad714x->sensor_val[i + 1] / 10)) | ||
715 | return 1; | ||
716 | } | ||
717 | |||
718 | for (i = sw->x_highest_stage; i < hw->x_end_stage; i++) { | ||
719 | if ((ad714x->sensor_val[i + 1] - ad714x->sensor_val[i]) | ||
720 | > (ad714x->sensor_val[i] / 10)) | ||
721 | return 1; | ||
722 | } | ||
723 | |||
724 | for (i = hw->y_start_stage; i < sw->y_highest_stage; i++) { | ||
725 | if ((ad714x->sensor_val[i] - ad714x->sensor_val[i + 1]) | ||
726 | > (ad714x->sensor_val[i + 1] / 10)) | ||
727 | return 1; | ||
728 | } | ||
729 | |||
730 | for (i = sw->y_highest_stage; i < hw->y_end_stage; i++) { | ||
731 | if ((ad714x->sensor_val[i + 1] - ad714x->sensor_val[i]) | ||
732 | > (ad714x->sensor_val[i] / 10)) | ||
733 | return 1; | ||
734 | } | ||
735 | |||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | /* | ||
740 | * If only one finger is used to activate the touch pad then only 1 peak will be | ||
741 | * registered in the distribution. This peak and the 2 adjacent sensors will be | ||
742 | * used in the calculation of the absolute position. This will prevent hand | ||
743 | * shadows to affect the absolute position calculation. | ||
744 | */ | ||
745 | static void touchpad_cal_abs_pos(struct ad714x_chip *ad714x, int idx) | ||
746 | { | ||
747 | struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; | ||
748 | struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx]; | ||
749 | |||
750 | sw->x_abs_pos = ad714x_cal_abs_pos(ad714x, hw->x_start_stage, | ||
751 | hw->x_end_stage, sw->x_highest_stage, hw->x_max_coord); | ||
752 | sw->y_abs_pos = ad714x_cal_abs_pos(ad714x, hw->y_start_stage, | ||
753 | hw->y_end_stage, sw->y_highest_stage, hw->y_max_coord); | ||
754 | |||
755 | dev_dbg(ad714x->dev, "touchpad %d absolute position:(%d, %d)\n", idx, | ||
756 | sw->x_abs_pos, sw->y_abs_pos); | ||
757 | } | ||
758 | |||
759 | static void touchpad_cal_flt_pos(struct ad714x_chip *ad714x, int idx) | ||
760 | { | ||
761 | struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx]; | ||
762 | |||
763 | sw->x_flt_pos = (sw->x_flt_pos * (10 - 4) + | ||
764 | sw->x_abs_pos * 4)/10; | ||
765 | sw->y_flt_pos = (sw->y_flt_pos * (10 - 4) + | ||
766 | sw->y_abs_pos * 4)/10; | ||
767 | |||
768 | dev_dbg(ad714x->dev, "touchpad %d filter position:(%d, %d)\n", | ||
769 | idx, sw->x_flt_pos, sw->y_flt_pos); | ||
770 | } | ||
771 | |||
772 | /* | ||
773 | * To prevent distortion from showing in the absolute position, it is | ||
774 | * necessary to detect the end points. When endpoints are detected, the | ||
775 | * driver stops updating the status variables with absolute positions. | ||
776 | * End points are detected on the 4 edges of the touchpad sensor. The | ||
777 | * method to detect them is the same for all 4. | ||
778 | * To detect the end points, the firmware computes the difference in | ||
779 | * percent between the sensor on the edge and the adjacent one. The | ||
780 | * difference is calculated in percent in order to make the end point | ||
781 | * detection independent of the pressure. | ||
782 | */ | ||
783 | |||
784 | #define LEFT_END_POINT_DETECTION_LEVEL 550 | ||
785 | #define RIGHT_END_POINT_DETECTION_LEVEL 750 | ||
786 | #define LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL 850 | ||
787 | #define TOP_END_POINT_DETECTION_LEVEL 550 | ||
788 | #define BOTTOM_END_POINT_DETECTION_LEVEL 950 | ||
789 | #define TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL 700 | ||
790 | static int touchpad_check_endpoint(struct ad714x_chip *ad714x, int idx) | ||
791 | { | ||
792 | struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; | ||
793 | struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx]; | ||
794 | int percent_sensor_diff; | ||
795 | |||
796 | /* left endpoint detect */ | ||
797 | percent_sensor_diff = (ad714x->sensor_val[hw->x_start_stage] - | ||
798 | ad714x->sensor_val[hw->x_start_stage + 1]) * 100 / | ||
799 | ad714x->sensor_val[hw->x_start_stage + 1]; | ||
800 | if (!sw->left_ep) { | ||
801 | if (percent_sensor_diff >= LEFT_END_POINT_DETECTION_LEVEL) { | ||
802 | sw->left_ep = 1; | ||
803 | sw->left_ep_val = | ||
804 | ad714x->sensor_val[hw->x_start_stage + 1]; | ||
805 | } | ||
806 | } else { | ||
807 | if ((percent_sensor_diff < LEFT_END_POINT_DETECTION_LEVEL) && | ||
808 | (ad714x->sensor_val[hw->x_start_stage + 1] > | ||
809 | LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL + sw->left_ep_val)) | ||
810 | sw->left_ep = 0; | ||
811 | } | ||
812 | |||
813 | /* right endpoint detect */ | ||
814 | percent_sensor_diff = (ad714x->sensor_val[hw->x_end_stage] - | ||
815 | ad714x->sensor_val[hw->x_end_stage - 1]) * 100 / | ||
816 | ad714x->sensor_val[hw->x_end_stage - 1]; | ||
817 | if (!sw->right_ep) { | ||
818 | if (percent_sensor_diff >= RIGHT_END_POINT_DETECTION_LEVEL) { | ||
819 | sw->right_ep = 1; | ||
820 | sw->right_ep_val = | ||
821 | ad714x->sensor_val[hw->x_end_stage - 1]; | ||
822 | } | ||
823 | } else { | ||
824 | if ((percent_sensor_diff < RIGHT_END_POINT_DETECTION_LEVEL) && | ||
825 | (ad714x->sensor_val[hw->x_end_stage - 1] > | ||
826 | LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL + sw->right_ep_val)) | ||
827 | sw->right_ep = 0; | ||
828 | } | ||
829 | |||
830 | /* top endpoint detect */ | ||
831 | percent_sensor_diff = (ad714x->sensor_val[hw->y_start_stage] - | ||
832 | ad714x->sensor_val[hw->y_start_stage + 1]) * 100 / | ||
833 | ad714x->sensor_val[hw->y_start_stage + 1]; | ||
834 | if (!sw->top_ep) { | ||
835 | if (percent_sensor_diff >= TOP_END_POINT_DETECTION_LEVEL) { | ||
836 | sw->top_ep = 1; | ||
837 | sw->top_ep_val = | ||
838 | ad714x->sensor_val[hw->y_start_stage + 1]; | ||
839 | } | ||
840 | } else { | ||
841 | if ((percent_sensor_diff < TOP_END_POINT_DETECTION_LEVEL) && | ||
842 | (ad714x->sensor_val[hw->y_start_stage + 1] > | ||
843 | TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL + sw->top_ep_val)) | ||
844 | sw->top_ep = 0; | ||
845 | } | ||
846 | |||
847 | /* bottom endpoint detect */ | ||
848 | percent_sensor_diff = (ad714x->sensor_val[hw->y_end_stage] - | ||
849 | ad714x->sensor_val[hw->y_end_stage - 1]) * 100 / | ||
850 | ad714x->sensor_val[hw->y_end_stage - 1]; | ||
851 | if (!sw->bottom_ep) { | ||
852 | if (percent_sensor_diff >= BOTTOM_END_POINT_DETECTION_LEVEL) { | ||
853 | sw->bottom_ep = 1; | ||
854 | sw->bottom_ep_val = | ||
855 | ad714x->sensor_val[hw->y_end_stage - 1]; | ||
856 | } | ||
857 | } else { | ||
858 | if ((percent_sensor_diff < BOTTOM_END_POINT_DETECTION_LEVEL) && | ||
859 | (ad714x->sensor_val[hw->y_end_stage - 1] > | ||
860 | TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL + sw->bottom_ep_val)) | ||
861 | sw->bottom_ep = 0; | ||
862 | } | ||
863 | |||
864 | return sw->left_ep || sw->right_ep || sw->top_ep || sw->bottom_ep; | ||
865 | } | ||
866 | |||
867 | static void touchpad_use_com_int(struct ad714x_chip *ad714x, int idx) | ||
868 | { | ||
869 | struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; | ||
870 | |||
871 | ad714x_use_com_int(ad714x, hw->x_start_stage, hw->x_end_stage); | ||
872 | } | ||
873 | |||
874 | static void touchpad_use_thr_int(struct ad714x_chip *ad714x, int idx) | ||
875 | { | ||
876 | struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; | ||
877 | |||
878 | ad714x_use_thr_int(ad714x, hw->x_start_stage, hw->x_end_stage); | ||
879 | ad714x_use_thr_int(ad714x, hw->y_start_stage, hw->y_end_stage); | ||
880 | } | ||
881 | |||
882 | static void ad714x_touchpad_state_machine(struct ad714x_chip *ad714x, int idx) | ||
883 | { | ||
884 | struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; | ||
885 | struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx]; | ||
886 | unsigned short h_state, c_state; | ||
887 | unsigned short mask; | ||
888 | |||
889 | mask = (((1 << (hw->x_end_stage + 1)) - 1) - | ||
890 | ((1 << hw->x_start_stage) - 1)) + | ||
891 | (((1 << (hw->y_end_stage + 1)) - 1) - | ||
892 | ((1 << hw->y_start_stage) - 1)); | ||
893 | |||
894 | h_state = ad714x->h_state & mask; | ||
895 | c_state = ad714x->c_state & mask; | ||
896 | |||
897 | switch (sw->state) { | ||
898 | case IDLE: | ||
899 | if (h_state) { | ||
900 | sw->state = JITTER; | ||
901 | /* In End of Conversion interrupt mode, the AD714X | ||
902 | * continuously generates hardware interrupts. | ||
903 | */ | ||
904 | touchpad_use_com_int(ad714x, idx); | ||
905 | dev_dbg(ad714x->dev, "touchpad %d touched\n", idx); | ||
906 | } | ||
907 | break; | ||
908 | |||
909 | case JITTER: | ||
910 | if (c_state == mask) { | ||
911 | touchpad_cal_sensor_val(ad714x, idx); | ||
912 | touchpad_cal_highest_stage(ad714x, idx); | ||
913 | if ((!touchpad_check_second_peak(ad714x, idx)) && | ||
914 | (!touchpad_check_endpoint(ad714x, idx))) { | ||
915 | dev_dbg(ad714x->dev, | ||
916 | "touchpad%d, 2 fingers or endpoint\n", | ||
917 | idx); | ||
918 | touchpad_cal_abs_pos(ad714x, idx); | ||
919 | sw->x_flt_pos = sw->x_abs_pos; | ||
920 | sw->y_flt_pos = sw->y_abs_pos; | ||
921 | sw->state = ACTIVE; | ||
922 | } | ||
923 | } | ||
924 | break; | ||
925 | |||
926 | case ACTIVE: | ||
927 | if (c_state == mask) { | ||
928 | if (h_state) { | ||
929 | touchpad_cal_sensor_val(ad714x, idx); | ||
930 | touchpad_cal_highest_stage(ad714x, idx); | ||
931 | if ((!touchpad_check_second_peak(ad714x, idx)) | ||
932 | && (!touchpad_check_endpoint(ad714x, idx))) { | ||
933 | touchpad_cal_abs_pos(ad714x, idx); | ||
934 | touchpad_cal_flt_pos(ad714x, idx); | ||
935 | input_report_abs(sw->input, ABS_X, | ||
936 | sw->x_flt_pos); | ||
937 | input_report_abs(sw->input, ABS_Y, | ||
938 | sw->y_flt_pos); | ||
939 | input_report_key(sw->input, BTN_TOUCH, | ||
940 | 1); | ||
941 | } | ||
942 | } else { | ||
943 | /* When the user lifts off the sensor, configure | ||
944 | * the AD714X back to threshold interrupt mode. | ||
945 | */ | ||
946 | touchpad_use_thr_int(ad714x, idx); | ||
947 | sw->state = IDLE; | ||
948 | input_report_key(sw->input, BTN_TOUCH, 0); | ||
949 | dev_dbg(ad714x->dev, "touchpad %d released\n", | ||
950 | idx); | ||
951 | } | ||
952 | input_sync(sw->input); | ||
953 | } | ||
954 | break; | ||
955 | |||
956 | default: | ||
957 | break; | ||
958 | } | ||
959 | } | ||
960 | |||
961 | static int ad714x_hw_detect(struct ad714x_chip *ad714x) | ||
962 | { | ||
963 | unsigned short data; | ||
964 | |||
965 | ad714x->read(ad714x->dev, AD714X_PARTID_REG, &data); | ||
966 | switch (data & 0xFFF0) { | ||
967 | case AD7142_PARTID: | ||
968 | ad714x->product = 0x7142; | ||
969 | ad714x->version = data & 0xF; | ||
970 | dev_info(ad714x->dev, "found AD7142 captouch, rev:%d\n", | ||
971 | ad714x->version); | ||
972 | return 0; | ||
973 | |||
974 | case AD7143_PARTID: | ||
975 | ad714x->product = 0x7143; | ||
976 | ad714x->version = data & 0xF; | ||
977 | dev_info(ad714x->dev, "found AD7143 captouch, rev:%d\n", | ||
978 | ad714x->version); | ||
979 | return 0; | ||
980 | |||
981 | case AD7147_PARTID: | ||
982 | ad714x->product = 0x7147; | ||
983 | ad714x->version = data & 0xF; | ||
984 | dev_info(ad714x->dev, "found AD7147(A) captouch, rev:%d\n", | ||
985 | ad714x->version); | ||
986 | return 0; | ||
987 | |||
988 | case AD7148_PARTID: | ||
989 | ad714x->product = 0x7148; | ||
990 | ad714x->version = data & 0xF; | ||
991 | dev_info(ad714x->dev, "found AD7148 captouch, rev:%d\n", | ||
992 | ad714x->version); | ||
993 | return 0; | ||
994 | |||
995 | default: | ||
996 | dev_err(ad714x->dev, | ||
997 | "fail to detect AD714X captouch, read ID is %04x\n", | ||
998 | data); | ||
999 | return -ENODEV; | ||
1000 | } | ||
1001 | } | ||
1002 | |||
1003 | static void ad714x_hw_init(struct ad714x_chip *ad714x) | ||
1004 | { | ||
1005 | int i, j; | ||
1006 | unsigned short reg_base; | ||
1007 | unsigned short data; | ||
1008 | |||
1009 | /* configuration CDC and interrupts */ | ||
1010 | |||
1011 | for (i = 0; i < STAGE_NUM; i++) { | ||
1012 | reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM; | ||
1013 | for (j = 0; j < STAGE_CFGREG_NUM; j++) | ||
1014 | ad714x->write(ad714x->dev, reg_base + j, | ||
1015 | ad714x->hw->stage_cfg_reg[i][j]); | ||
1016 | } | ||
1017 | |||
1018 | for (i = 0; i < SYS_CFGREG_NUM; i++) | ||
1019 | ad714x->write(ad714x->dev, AD714X_SYSCFG_REG + i, | ||
1020 | ad714x->hw->sys_cfg_reg[i]); | ||
1021 | for (i = 0; i < SYS_CFGREG_NUM; i++) | ||
1022 | ad714x->read(ad714x->dev, AD714X_SYSCFG_REG + i, | ||
1023 | &data); | ||
1024 | |||
1025 | ad714x->write(ad714x->dev, AD714X_STG_CAL_EN_REG, 0xFFF); | ||
1026 | |||
1027 | /* clear all interrupts */ | ||
1028 | ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data); | ||
1029 | ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data); | ||
1030 | ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data); | ||
1031 | } | ||
1032 | |||
1033 | static irqreturn_t ad714x_interrupt_thread(int irq, void *data) | ||
1034 | { | ||
1035 | struct ad714x_chip *ad714x = data; | ||
1036 | int i; | ||
1037 | |||
1038 | mutex_lock(&ad714x->mutex); | ||
1039 | |||
1040 | ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state); | ||
1041 | ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state); | ||
1042 | ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state); | ||
1043 | |||
1044 | for (i = 0; i < ad714x->hw->button_num; i++) | ||
1045 | ad714x_button_state_machine(ad714x, i); | ||
1046 | for (i = 0; i < ad714x->hw->slider_num; i++) | ||
1047 | ad714x_slider_state_machine(ad714x, i); | ||
1048 | for (i = 0; i < ad714x->hw->wheel_num; i++) | ||
1049 | ad714x_wheel_state_machine(ad714x, i); | ||
1050 | for (i = 0; i < ad714x->hw->touchpad_num; i++) | ||
1051 | ad714x_touchpad_state_machine(ad714x, i); | ||
1052 | |||
1053 | mutex_unlock(&ad714x->mutex); | ||
1054 | |||
1055 | return IRQ_HANDLED; | ||
1056 | } | ||
1057 | |||
1058 | #define MAX_DEVICE_NUM 8 | ||
1059 | struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | ||
1060 | ad714x_read_t read, ad714x_write_t write) | ||
1061 | { | ||
1062 | int i, alloc_idx; | ||
1063 | int error; | ||
1064 | struct input_dev *input[MAX_DEVICE_NUM]; | ||
1065 | |||
1066 | struct ad714x_platform_data *plat_data = dev->platform_data; | ||
1067 | struct ad714x_chip *ad714x; | ||
1068 | void *drv_mem; | ||
1069 | |||
1070 | struct ad714x_button_drv *bt_drv; | ||
1071 | struct ad714x_slider_drv *sd_drv; | ||
1072 | struct ad714x_wheel_drv *wl_drv; | ||
1073 | struct ad714x_touchpad_drv *tp_drv; | ||
1074 | |||
1075 | |||
1076 | if (irq <= 0) { | ||
1077 | dev_err(dev, "IRQ not configured!\n"); | ||
1078 | error = -EINVAL; | ||
1079 | goto err_out; | ||
1080 | } | ||
1081 | |||
1082 | if (dev->platform_data == NULL) { | ||
1083 | dev_err(dev, "platform data for ad714x doesn't exist\n"); | ||
1084 | error = -EINVAL; | ||
1085 | goto err_out; | ||
1086 | } | ||
1087 | |||
1088 | ad714x = kzalloc(sizeof(*ad714x) + sizeof(*ad714x->sw) + | ||
1089 | sizeof(*sd_drv) * plat_data->slider_num + | ||
1090 | sizeof(*wl_drv) * plat_data->wheel_num + | ||
1091 | sizeof(*tp_drv) * plat_data->touchpad_num + | ||
1092 | sizeof(*bt_drv) * plat_data->button_num, GFP_KERNEL); | ||
1093 | if (!ad714x) { | ||
1094 | error = -ENOMEM; | ||
1095 | goto err_out; | ||
1096 | } | ||
1097 | |||
1098 | ad714x->hw = plat_data; | ||
1099 | |||
1100 | drv_mem = ad714x + 1; | ||
1101 | ad714x->sw = drv_mem; | ||
1102 | drv_mem += sizeof(*ad714x->sw); | ||
1103 | ad714x->sw->slider = sd_drv = drv_mem; | ||
1104 | drv_mem += sizeof(*sd_drv) * ad714x->hw->slider_num; | ||
1105 | ad714x->sw->wheel = wl_drv = drv_mem; | ||
1106 | drv_mem += sizeof(*wl_drv) * ad714x->hw->wheel_num; | ||
1107 | ad714x->sw->touchpad = tp_drv = drv_mem; | ||
1108 | drv_mem += sizeof(*tp_drv) * ad714x->hw->touchpad_num; | ||
1109 | ad714x->sw->button = bt_drv = drv_mem; | ||
1110 | drv_mem += sizeof(*bt_drv) * ad714x->hw->button_num; | ||
1111 | |||
1112 | ad714x->read = read; | ||
1113 | ad714x->write = write; | ||
1114 | ad714x->irq = irq; | ||
1115 | ad714x->dev = dev; | ||
1116 | |||
1117 | error = ad714x_hw_detect(ad714x); | ||
1118 | if (error) | ||
1119 | goto err_free_mem; | ||
1120 | |||
1121 | /* initialize and request sw/hw resources */ | ||
1122 | |||
1123 | ad714x_hw_init(ad714x); | ||
1124 | mutex_init(&ad714x->mutex); | ||
1125 | |||
1126 | /* | ||
1127 | * Allocate and register AD714X input device | ||
1128 | */ | ||
1129 | alloc_idx = 0; | ||
1130 | |||
1131 | /* a slider uses one input_dev instance */ | ||
1132 | if (ad714x->hw->slider_num > 0) { | ||
1133 | struct ad714x_slider_plat *sd_plat = ad714x->hw->slider; | ||
1134 | |||
1135 | for (i = 0; i < ad714x->hw->slider_num; i++) { | ||
1136 | sd_drv[i].input = input[alloc_idx] = input_allocate_device(); | ||
1137 | if (!input[alloc_idx]) { | ||
1138 | error = -ENOMEM; | ||
1139 | goto err_free_dev; | ||
1140 | } | ||
1141 | |||
1142 | __set_bit(EV_ABS, input[alloc_idx]->evbit); | ||
1143 | __set_bit(EV_KEY, input[alloc_idx]->evbit); | ||
1144 | __set_bit(ABS_X, input[alloc_idx]->absbit); | ||
1145 | __set_bit(BTN_TOUCH, input[alloc_idx]->keybit); | ||
1146 | input_set_abs_params(input[alloc_idx], | ||
1147 | ABS_X, 0, sd_plat->max_coord, 0, 0); | ||
1148 | |||
1149 | input[alloc_idx]->id.bustype = bus_type; | ||
1150 | input[alloc_idx]->id.product = ad714x->product; | ||
1151 | input[alloc_idx]->id.version = ad714x->version; | ||
1152 | |||
1153 | error = input_register_device(input[alloc_idx]); | ||
1154 | if (error) | ||
1155 | goto err_free_dev; | ||
1156 | |||
1157 | alloc_idx++; | ||
1158 | } | ||
1159 | } | ||
1160 | |||
1161 | /* a wheel uses one input_dev instance */ | ||
1162 | if (ad714x->hw->wheel_num > 0) { | ||
1163 | struct ad714x_wheel_plat *wl_plat = ad714x->hw->wheel; | ||
1164 | |||
1165 | for (i = 0; i < ad714x->hw->wheel_num; i++) { | ||
1166 | wl_drv[i].input = input[alloc_idx] = input_allocate_device(); | ||
1167 | if (!input[alloc_idx]) { | ||
1168 | error = -ENOMEM; | ||
1169 | goto err_free_dev; | ||
1170 | } | ||
1171 | |||
1172 | __set_bit(EV_KEY, input[alloc_idx]->evbit); | ||
1173 | __set_bit(EV_ABS, input[alloc_idx]->evbit); | ||
1174 | __set_bit(ABS_WHEEL, input[alloc_idx]->absbit); | ||
1175 | __set_bit(BTN_TOUCH, input[alloc_idx]->keybit); | ||
1176 | input_set_abs_params(input[alloc_idx], | ||
1177 | ABS_WHEEL, 0, wl_plat->max_coord, 0, 0); | ||
1178 | |||
1179 | input[alloc_idx]->id.bustype = bus_type; | ||
1180 | input[alloc_idx]->id.product = ad714x->product; | ||
1181 | input[alloc_idx]->id.version = ad714x->version; | ||
1182 | |||
1183 | error = input_register_device(input[alloc_idx]); | ||
1184 | if (error) | ||
1185 | goto err_free_dev; | ||
1186 | |||
1187 | alloc_idx++; | ||
1188 | } | ||
1189 | } | ||
1190 | |||
1191 | /* a touchpad uses one input_dev instance */ | ||
1192 | if (ad714x->hw->touchpad_num > 0) { | ||
1193 | struct ad714x_touchpad_plat *tp_plat = ad714x->hw->touchpad; | ||
1194 | |||
1195 | for (i = 0; i < ad714x->hw->touchpad_num; i++) { | ||
1196 | tp_drv[i].input = input[alloc_idx] = input_allocate_device(); | ||
1197 | if (!input[alloc_idx]) { | ||
1198 | error = -ENOMEM; | ||
1199 | goto err_free_dev; | ||
1200 | } | ||
1201 | |||
1202 | __set_bit(EV_ABS, input[alloc_idx]->evbit); | ||
1203 | __set_bit(EV_KEY, input[alloc_idx]->evbit); | ||
1204 | __set_bit(ABS_X, input[alloc_idx]->absbit); | ||
1205 | __set_bit(ABS_Y, input[alloc_idx]->absbit); | ||
1206 | __set_bit(BTN_TOUCH, input[alloc_idx]->keybit); | ||
1207 | input_set_abs_params(input[alloc_idx], | ||
1208 | ABS_X, 0, tp_plat->x_max_coord, 0, 0); | ||
1209 | input_set_abs_params(input[alloc_idx], | ||
1210 | ABS_Y, 0, tp_plat->y_max_coord, 0, 0); | ||
1211 | |||
1212 | input[alloc_idx]->id.bustype = bus_type; | ||
1213 | input[alloc_idx]->id.product = ad714x->product; | ||
1214 | input[alloc_idx]->id.version = ad714x->version; | ||
1215 | |||
1216 | error = input_register_device(input[alloc_idx]); | ||
1217 | if (error) | ||
1218 | goto err_free_dev; | ||
1219 | |||
1220 | alloc_idx++; | ||
1221 | } | ||
1222 | } | ||
1223 | |||
1224 | /* all buttons use one input node */ | ||
1225 | if (ad714x->hw->button_num > 0) { | ||
1226 | struct ad714x_button_plat *bt_plat = ad714x->hw->button; | ||
1227 | |||
1228 | input[alloc_idx] = input_allocate_device(); | ||
1229 | if (!input[alloc_idx]) { | ||
1230 | error = -ENOMEM; | ||
1231 | goto err_free_dev; | ||
1232 | } | ||
1233 | |||
1234 | __set_bit(EV_KEY, input[alloc_idx]->evbit); | ||
1235 | for (i = 0; i < ad714x->hw->button_num; i++) { | ||
1236 | bt_drv[i].input = input[alloc_idx]; | ||
1237 | __set_bit(bt_plat[i].keycode, input[alloc_idx]->keybit); | ||
1238 | } | ||
1239 | |||
1240 | input[alloc_idx]->id.bustype = bus_type; | ||
1241 | input[alloc_idx]->id.product = ad714x->product; | ||
1242 | input[alloc_idx]->id.version = ad714x->version; | ||
1243 | |||
1244 | error = input_register_device(input[alloc_idx]); | ||
1245 | if (error) | ||
1246 | goto err_free_dev; | ||
1247 | |||
1248 | alloc_idx++; | ||
1249 | } | ||
1250 | |||
1251 | error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread, | ||
1252 | IRQF_TRIGGER_FALLING, "ad714x_captouch", ad714x); | ||
1253 | if (error) { | ||
1254 | dev_err(dev, "can't allocate irq %d\n", ad714x->irq); | ||
1255 | goto err_unreg_dev; | ||
1256 | } | ||
1257 | |||
1258 | return ad714x; | ||
1259 | |||
1260 | err_free_dev: | ||
1261 | dev_err(dev, "failed to setup AD714x input device %i\n", alloc_idx); | ||
1262 | input_free_device(input[alloc_idx]); | ||
1263 | err_unreg_dev: | ||
1264 | while (--alloc_idx >= 0) | ||
1265 | input_unregister_device(input[alloc_idx]); | ||
1266 | err_free_mem: | ||
1267 | kfree(ad714x); | ||
1268 | err_out: | ||
1269 | return ERR_PTR(error); | ||
1270 | } | ||
1271 | EXPORT_SYMBOL(ad714x_probe); | ||
1272 | |||
1273 | void ad714x_remove(struct ad714x_chip *ad714x) | ||
1274 | { | ||
1275 | struct ad714x_platform_data *hw = ad714x->hw; | ||
1276 | struct ad714x_driver_data *sw = ad714x->sw; | ||
1277 | int i; | ||
1278 | |||
1279 | free_irq(ad714x->irq, ad714x); | ||
1280 | |||
1281 | /* unregister and free all input devices */ | ||
1282 | |||
1283 | for (i = 0; i < hw->slider_num; i++) | ||
1284 | input_unregister_device(sw->slider[i].input); | ||
1285 | |||
1286 | for (i = 0; i < hw->wheel_num; i++) | ||
1287 | input_unregister_device(sw->wheel[i].input); | ||
1288 | |||
1289 | for (i = 0; i < hw->touchpad_num; i++) | ||
1290 | input_unregister_device(sw->touchpad[i].input); | ||
1291 | |||
1292 | if (hw->button_num) | ||
1293 | input_unregister_device(sw->button[0].input); | ||
1294 | |||
1295 | kfree(ad714x); | ||
1296 | } | ||
1297 | EXPORT_SYMBOL(ad714x_remove); | ||
1298 | |||
1299 | #ifdef CONFIG_PM | ||
1300 | int ad714x_disable(struct ad714x_chip *ad714x) | ||
1301 | { | ||
1302 | unsigned short data; | ||
1303 | |||
1304 | dev_dbg(ad714x->dev, "%s enter\n", __func__); | ||
1305 | |||
1306 | mutex_lock(&ad714x->mutex); | ||
1307 | |||
1308 | data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3; | ||
1309 | ad714x->write(ad714x->dev, AD714X_PWR_CTRL, data); | ||
1310 | |||
1311 | mutex_unlock(&ad714x->mutex); | ||
1312 | |||
1313 | return 0; | ||
1314 | } | ||
1315 | EXPORT_SYMBOL(ad714x_disable); | ||
1316 | |||
1317 | int ad714x_enable(struct ad714x_chip *ad714x) | ||
1318 | { | ||
1319 | unsigned short data; | ||
1320 | |||
1321 | dev_dbg(ad714x->dev, "%s enter\n", __func__); | ||
1322 | |||
1323 | mutex_lock(&ad714x->mutex); | ||
1324 | |||
1325 | /* resume to non-shutdown mode */ | ||
1326 | |||
1327 | ad714x->write(ad714x->dev, AD714X_PWR_CTRL, | ||
1328 | ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]); | ||
1329 | |||
1330 | /* make sure the interrupt output line is not low level after resume, | ||
1331 | * otherwise we will get no chance to enter falling-edge irq again | ||
1332 | */ | ||
1333 | |||
1334 | ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data); | ||
1335 | ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data); | ||
1336 | ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data); | ||
1337 | |||
1338 | mutex_unlock(&ad714x->mutex); | ||
1339 | |||
1340 | return 0; | ||
1341 | } | ||
1342 | EXPORT_SYMBOL(ad714x_enable); | ||
1343 | #endif | ||
1344 | |||
1345 | MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor Driver"); | ||
1346 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
1347 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/ad714x.h b/drivers/input/misc/ad714x.h new file mode 100644 index 000000000000..45c54fb13f07 --- /dev/null +++ b/drivers/input/misc/ad714x.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * AD714X CapTouch Programmable Controller driver (bus interfaces) | ||
3 | * | ||
4 | * Copyright 2009 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #ifndef _AD714X_H_ | ||
10 | #define _AD714X_H_ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | |||
14 | struct device; | ||
15 | struct ad714x_chip; | ||
16 | |||
17 | typedef int (*ad714x_read_t)(struct device *, unsigned short, unsigned short *); | ||
18 | typedef int (*ad714x_write_t)(struct device *, unsigned short, unsigned short); | ||
19 | |||
20 | int ad714x_disable(struct ad714x_chip *ad714x); | ||
21 | int ad714x_enable(struct ad714x_chip *ad714x); | ||
22 | struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | ||
23 | ad714x_read_t read, ad714x_write_t write); | ||
24 | void ad714x_remove(struct ad714x_chip *ad714x); | ||
25 | |||
26 | #endif | ||
diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c new file mode 100644 index 000000000000..0779724af7e7 --- /dev/null +++ b/drivers/input/misc/adxl34x-i2c.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * ADLX345/346 Three-Axis Digital Accelerometers (I2C Interface) | ||
3 | * | ||
4 | * Enter bugs at http://blackfin.uclinux.org/ | ||
5 | * | ||
6 | * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc. | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/input.h> /* BUS_I2C */ | ||
11 | #include <linux/i2c.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/types.h> | ||
14 | #include "adxl34x.h" | ||
15 | |||
16 | static int adxl34x_smbus_read(struct device *dev, unsigned char reg) | ||
17 | { | ||
18 | struct i2c_client *client = to_i2c_client(dev); | ||
19 | |||
20 | return i2c_smbus_read_byte_data(client, reg); | ||
21 | } | ||
22 | |||
23 | static int adxl34x_smbus_write(struct device *dev, | ||
24 | unsigned char reg, unsigned char val) | ||
25 | { | ||
26 | struct i2c_client *client = to_i2c_client(dev); | ||
27 | |||
28 | return i2c_smbus_write_byte_data(client, reg, val); | ||
29 | } | ||
30 | |||
31 | static int adxl34x_smbus_read_block(struct device *dev, | ||
32 | unsigned char reg, int count, | ||
33 | void *buf) | ||
34 | { | ||
35 | struct i2c_client *client = to_i2c_client(dev); | ||
36 | |||
37 | return i2c_smbus_read_i2c_block_data(client, reg, count, buf); | ||
38 | } | ||
39 | |||
40 | static int adxl34x_i2c_read_block(struct device *dev, | ||
41 | unsigned char reg, int count, | ||
42 | void *buf) | ||
43 | { | ||
44 | struct i2c_client *client = to_i2c_client(dev); | ||
45 | int ret; | ||
46 | |||
47 | ret = i2c_master_send(client, ®, 1); | ||
48 | if (ret < 0) | ||
49 | return ret; | ||
50 | |||
51 | ret = i2c_master_recv(client, buf, count); | ||
52 | if (ret < 0) | ||
53 | return ret; | ||
54 | |||
55 | if (ret != count) | ||
56 | return -EIO; | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static const struct adxl34x_bus_ops adxl34x_smbus_bops = { | ||
62 | .bustype = BUS_I2C, | ||
63 | .write = adxl34x_smbus_write, | ||
64 | .read = adxl34x_smbus_read, | ||
65 | .read_block = adxl34x_smbus_read_block, | ||
66 | }; | ||
67 | |||
68 | static const struct adxl34x_bus_ops adxl34x_i2c_bops = { | ||
69 | .bustype = BUS_I2C, | ||
70 | .write = adxl34x_smbus_write, | ||
71 | .read = adxl34x_smbus_read, | ||
72 | .read_block = adxl34x_i2c_read_block, | ||
73 | }; | ||
74 | |||
75 | static int __devinit adxl34x_i2c_probe(struct i2c_client *client, | ||
76 | const struct i2c_device_id *id) | ||
77 | { | ||
78 | struct adxl34x *ac; | ||
79 | int error; | ||
80 | |||
81 | error = i2c_check_functionality(client->adapter, | ||
82 | I2C_FUNC_SMBUS_BYTE_DATA); | ||
83 | if (!error) { | ||
84 | dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); | ||
85 | return -EIO; | ||
86 | } | ||
87 | |||
88 | ac = adxl34x_probe(&client->dev, client->irq, false, | ||
89 | i2c_check_functionality(client->adapter, | ||
90 | I2C_FUNC_SMBUS_READ_I2C_BLOCK) ? | ||
91 | &adxl34x_smbus_bops : &adxl34x_i2c_bops); | ||
92 | if (IS_ERR(ac)) | ||
93 | return PTR_ERR(ac); | ||
94 | |||
95 | i2c_set_clientdata(client, ac); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int __devexit adxl34x_i2c_remove(struct i2c_client *client) | ||
101 | { | ||
102 | struct adxl34x *ac = i2c_get_clientdata(client); | ||
103 | |||
104 | return adxl34x_remove(ac); | ||
105 | } | ||
106 | |||
107 | #ifdef CONFIG_PM | ||
108 | static int adxl34x_i2c_suspend(struct i2c_client *client, pm_message_t message) | ||
109 | { | ||
110 | struct adxl34x *ac = i2c_get_clientdata(client); | ||
111 | |||
112 | adxl34x_suspend(ac); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static int adxl34x_i2c_resume(struct i2c_client *client) | ||
118 | { | ||
119 | struct adxl34x *ac = i2c_get_clientdata(client); | ||
120 | |||
121 | adxl34x_resume(ac); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | #else | ||
126 | # define adxl34x_i2c_suspend NULL | ||
127 | # define adxl34x_i2c_resume NULL | ||
128 | #endif | ||
129 | |||
130 | static const struct i2c_device_id adxl34x_id[] = { | ||
131 | { "adxl34x", 0 }, | ||
132 | { } | ||
133 | }; | ||
134 | |||
135 | MODULE_DEVICE_TABLE(i2c, adxl34x_id); | ||
136 | |||
137 | static struct i2c_driver adxl34x_driver = { | ||
138 | .driver = { | ||
139 | .name = "adxl34x", | ||
140 | .owner = THIS_MODULE, | ||
141 | }, | ||
142 | .probe = adxl34x_i2c_probe, | ||
143 | .remove = __devexit_p(adxl34x_i2c_remove), | ||
144 | .suspend = adxl34x_i2c_suspend, | ||
145 | .resume = adxl34x_i2c_resume, | ||
146 | .id_table = adxl34x_id, | ||
147 | }; | ||
148 | |||
149 | static int __init adxl34x_i2c_init(void) | ||
150 | { | ||
151 | return i2c_add_driver(&adxl34x_driver); | ||
152 | } | ||
153 | module_init(adxl34x_i2c_init); | ||
154 | |||
155 | static void __exit adxl34x_i2c_exit(void) | ||
156 | { | ||
157 | i2c_del_driver(&adxl34x_driver); | ||
158 | } | ||
159 | module_exit(adxl34x_i2c_exit); | ||
160 | |||
161 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
162 | MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer I2C Bus Driver"); | ||
163 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c new file mode 100644 index 000000000000..782de9e89828 --- /dev/null +++ b/drivers/input/misc/adxl34x-spi.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * ADLX345/346 Three-Axis Digital Accelerometers (SPI Interface) | ||
3 | * | ||
4 | * Enter bugs at http://blackfin.uclinux.org/ | ||
5 | * | ||
6 | * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc. | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/input.h> /* BUS_SPI */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/spi/spi.h> | ||
13 | #include <linux/types.h> | ||
14 | #include "adxl34x.h" | ||
15 | |||
16 | #define MAX_SPI_FREQ_HZ 5000000 | ||
17 | #define MAX_FREQ_NO_FIFODELAY 1500000 | ||
18 | #define ADXL34X_CMD_MULTB (1 << 6) | ||
19 | #define ADXL34X_CMD_READ (1 << 7) | ||
20 | #define ADXL34X_WRITECMD(reg) (reg & 0x3F) | ||
21 | #define ADXL34X_READCMD(reg) (ADXL34X_CMD_READ | (reg & 0x3F)) | ||
22 | #define ADXL34X_READMB_CMD(reg) (ADXL34X_CMD_READ | ADXL34X_CMD_MULTB \ | ||
23 | | (reg & 0x3F)) | ||
24 | |||
25 | static int adxl34x_spi_read(struct device *dev, unsigned char reg) | ||
26 | { | ||
27 | struct spi_device *spi = to_spi_device(dev); | ||
28 | unsigned char cmd; | ||
29 | |||
30 | cmd = ADXL34X_READCMD(reg); | ||
31 | |||
32 | return spi_w8r8(spi, cmd); | ||
33 | } | ||
34 | |||
35 | static int adxl34x_spi_write(struct device *dev, | ||
36 | unsigned char reg, unsigned char val) | ||
37 | { | ||
38 | struct spi_device *spi = to_spi_device(dev); | ||
39 | unsigned char buf[2]; | ||
40 | |||
41 | buf[0] = ADXL34X_WRITECMD(reg); | ||
42 | buf[1] = val; | ||
43 | |||
44 | return spi_write(spi, buf, sizeof(buf)); | ||
45 | } | ||
46 | |||
47 | static int adxl34x_spi_read_block(struct device *dev, | ||
48 | unsigned char reg, int count, | ||
49 | void *buf) | ||
50 | { | ||
51 | struct spi_device *spi = to_spi_device(dev); | ||
52 | ssize_t status; | ||
53 | |||
54 | reg = ADXL34X_READMB_CMD(reg); | ||
55 | status = spi_write_then_read(spi, ®, 1, buf, count); | ||
56 | |||
57 | return (status < 0) ? status : 0; | ||
58 | } | ||
59 | |||
60 | static const struct adxl34x_bus_ops adx134x_spi_bops = { | ||
61 | .bustype = BUS_SPI, | ||
62 | .write = adxl34x_spi_write, | ||
63 | .read = adxl34x_spi_read, | ||
64 | .read_block = adxl34x_spi_read_block, | ||
65 | }; | ||
66 | |||
67 | static int __devinit adxl34x_spi_probe(struct spi_device *spi) | ||
68 | { | ||
69 | struct adxl34x *ac; | ||
70 | |||
71 | /* don't exceed max specified SPI CLK frequency */ | ||
72 | if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) { | ||
73 | dev_err(&spi->dev, "SPI CLK %d Hz too fast\n", spi->max_speed_hz); | ||
74 | return -EINVAL; | ||
75 | } | ||
76 | |||
77 | ac = adxl34x_probe(&spi->dev, spi->irq, | ||
78 | spi->max_speed_hz > MAX_FREQ_NO_FIFODELAY, | ||
79 | &adx134x_spi_bops); | ||
80 | |||
81 | if (IS_ERR(ac)) | ||
82 | return PTR_ERR(ac); | ||
83 | |||
84 | spi_set_drvdata(spi, ac); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int __devexit adxl34x_spi_remove(struct spi_device *spi) | ||
90 | { | ||
91 | struct adxl34x *ac = dev_get_drvdata(&spi->dev); | ||
92 | |||
93 | return adxl34x_remove(ac); | ||
94 | } | ||
95 | |||
96 | #ifdef CONFIG_PM | ||
97 | static int adxl34x_spi_suspend(struct spi_device *spi, pm_message_t message) | ||
98 | { | ||
99 | struct adxl34x *ac = dev_get_drvdata(&spi->dev); | ||
100 | |||
101 | adxl34x_suspend(ac); | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int adxl34x_spi_resume(struct spi_device *spi) | ||
107 | { | ||
108 | struct adxl34x *ac = dev_get_drvdata(&spi->dev); | ||
109 | |||
110 | adxl34x_resume(ac); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | #else | ||
115 | # define adxl34x_spi_suspend NULL | ||
116 | # define adxl34x_spi_resume NULL | ||
117 | #endif | ||
118 | |||
119 | static struct spi_driver adxl34x_driver = { | ||
120 | .driver = { | ||
121 | .name = "adxl34x", | ||
122 | .bus = &spi_bus_type, | ||
123 | .owner = THIS_MODULE, | ||
124 | }, | ||
125 | .probe = adxl34x_spi_probe, | ||
126 | .remove = __devexit_p(adxl34x_spi_remove), | ||
127 | .suspend = adxl34x_spi_suspend, | ||
128 | .resume = adxl34x_spi_resume, | ||
129 | }; | ||
130 | |||
131 | static int __init adxl34x_spi_init(void) | ||
132 | { | ||
133 | return spi_register_driver(&adxl34x_driver); | ||
134 | } | ||
135 | module_init(adxl34x_spi_init); | ||
136 | |||
137 | static void __exit adxl34x_spi_exit(void) | ||
138 | { | ||
139 | spi_unregister_driver(&adxl34x_driver); | ||
140 | } | ||
141 | module_exit(adxl34x_spi_exit); | ||
142 | |||
143 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
144 | MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer SPI Bus Driver"); | ||
145 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c new file mode 100644 index 000000000000..de5900d50788 --- /dev/null +++ b/drivers/input/misc/adxl34x.c | |||
@@ -0,0 +1,914 @@ | |||
1 | /* | ||
2 | * ADXL345/346 Three-Axis Digital Accelerometers | ||
3 | * | ||
4 | * Enter bugs at http://blackfin.uclinux.org/ | ||
5 | * | ||
6 | * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc. | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/device.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/input.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/workqueue.h> | ||
18 | #include <linux/input/adxl34x.h> | ||
19 | |||
20 | #include "adxl34x.h" | ||
21 | |||
22 | /* ADXL345/6 Register Map */ | ||
23 | #define DEVID 0x00 /* R Device ID */ | ||
24 | #define THRESH_TAP 0x1D /* R/W Tap threshold */ | ||
25 | #define OFSX 0x1E /* R/W X-axis offset */ | ||
26 | #define OFSY 0x1F /* R/W Y-axis offset */ | ||
27 | #define OFSZ 0x20 /* R/W Z-axis offset */ | ||
28 | #define DUR 0x21 /* R/W Tap duration */ | ||
29 | #define LATENT 0x22 /* R/W Tap latency */ | ||
30 | #define WINDOW 0x23 /* R/W Tap window */ | ||
31 | #define THRESH_ACT 0x24 /* R/W Activity threshold */ | ||
32 | #define THRESH_INACT 0x25 /* R/W Inactivity threshold */ | ||
33 | #define TIME_INACT 0x26 /* R/W Inactivity time */ | ||
34 | #define ACT_INACT_CTL 0x27 /* R/W Axis enable control for activity and */ | ||
35 | /* inactivity detection */ | ||
36 | #define THRESH_FF 0x28 /* R/W Free-fall threshold */ | ||
37 | #define TIME_FF 0x29 /* R/W Free-fall time */ | ||
38 | #define TAP_AXES 0x2A /* R/W Axis control for tap/double tap */ | ||
39 | #define ACT_TAP_STATUS 0x2B /* R Source of tap/double tap */ | ||
40 | #define BW_RATE 0x2C /* R/W Data rate and power mode control */ | ||
41 | #define POWER_CTL 0x2D /* R/W Power saving features control */ | ||
42 | #define INT_ENABLE 0x2E /* R/W Interrupt enable control */ | ||
43 | #define INT_MAP 0x2F /* R/W Interrupt mapping control */ | ||
44 | #define INT_SOURCE 0x30 /* R Source of interrupts */ | ||
45 | #define DATA_FORMAT 0x31 /* R/W Data format control */ | ||
46 | #define DATAX0 0x32 /* R X-Axis Data 0 */ | ||
47 | #define DATAX1 0x33 /* R X-Axis Data 1 */ | ||
48 | #define DATAY0 0x34 /* R Y-Axis Data 0 */ | ||
49 | #define DATAY1 0x35 /* R Y-Axis Data 1 */ | ||
50 | #define DATAZ0 0x36 /* R Z-Axis Data 0 */ | ||
51 | #define DATAZ1 0x37 /* R Z-Axis Data 1 */ | ||
52 | #define FIFO_CTL 0x38 /* R/W FIFO control */ | ||
53 | #define FIFO_STATUS 0x39 /* R FIFO status */ | ||
54 | #define TAP_SIGN 0x3A /* R Sign and source for tap/double tap */ | ||
55 | /* Orientation ADXL346 only */ | ||
56 | #define ORIENT_CONF 0x3B /* R/W Orientation configuration */ | ||
57 | #define ORIENT 0x3C /* R Orientation status */ | ||
58 | |||
59 | /* DEVIDs */ | ||
60 | #define ID_ADXL345 0xE5 | ||
61 | #define ID_ADXL346 0xE6 | ||
62 | |||
63 | /* INT_ENABLE/INT_MAP/INT_SOURCE Bits */ | ||
64 | #define DATA_READY (1 << 7) | ||
65 | #define SINGLE_TAP (1 << 6) | ||
66 | #define DOUBLE_TAP (1 << 5) | ||
67 | #define ACTIVITY (1 << 4) | ||
68 | #define INACTIVITY (1 << 3) | ||
69 | #define FREE_FALL (1 << 2) | ||
70 | #define WATERMARK (1 << 1) | ||
71 | #define OVERRUN (1 << 0) | ||
72 | |||
73 | /* ACT_INACT_CONTROL Bits */ | ||
74 | #define ACT_ACDC (1 << 7) | ||
75 | #define ACT_X_EN (1 << 6) | ||
76 | #define ACT_Y_EN (1 << 5) | ||
77 | #define ACT_Z_EN (1 << 4) | ||
78 | #define INACT_ACDC (1 << 3) | ||
79 | #define INACT_X_EN (1 << 2) | ||
80 | #define INACT_Y_EN (1 << 1) | ||
81 | #define INACT_Z_EN (1 << 0) | ||
82 | |||
83 | /* TAP_AXES Bits */ | ||
84 | #define SUPPRESS (1 << 3) | ||
85 | #define TAP_X_EN (1 << 2) | ||
86 | #define TAP_Y_EN (1 << 1) | ||
87 | #define TAP_Z_EN (1 << 0) | ||
88 | |||
89 | /* ACT_TAP_STATUS Bits */ | ||
90 | #define ACT_X_SRC (1 << 6) | ||
91 | #define ACT_Y_SRC (1 << 5) | ||
92 | #define ACT_Z_SRC (1 << 4) | ||
93 | #define ASLEEP (1 << 3) | ||
94 | #define TAP_X_SRC (1 << 2) | ||
95 | #define TAP_Y_SRC (1 << 1) | ||
96 | #define TAP_Z_SRC (1 << 0) | ||
97 | |||
98 | /* BW_RATE Bits */ | ||
99 | #define LOW_POWER (1 << 4) | ||
100 | #define RATE(x) ((x) & 0xF) | ||
101 | |||
102 | /* POWER_CTL Bits */ | ||
103 | #define PCTL_LINK (1 << 5) | ||
104 | #define PCTL_AUTO_SLEEP (1 << 4) | ||
105 | #define PCTL_MEASURE (1 << 3) | ||
106 | #define PCTL_SLEEP (1 << 2) | ||
107 | #define PCTL_WAKEUP(x) ((x) & 0x3) | ||
108 | |||
109 | /* DATA_FORMAT Bits */ | ||
110 | #define SELF_TEST (1 << 7) | ||
111 | #define SPI (1 << 6) | ||
112 | #define INT_INVERT (1 << 5) | ||
113 | #define FULL_RES (1 << 3) | ||
114 | #define JUSTIFY (1 << 2) | ||
115 | #define RANGE(x) ((x) & 0x3) | ||
116 | #define RANGE_PM_2g 0 | ||
117 | #define RANGE_PM_4g 1 | ||
118 | #define RANGE_PM_8g 2 | ||
119 | #define RANGE_PM_16g 3 | ||
120 | |||
121 | /* | ||
122 | * Maximum value our axis may get in full res mode for the input device | ||
123 | * (signed 13 bits) | ||
124 | */ | ||
125 | #define ADXL_FULLRES_MAX_VAL 4096 | ||
126 | |||
127 | /* | ||
128 | * Maximum value our axis may get in fixed res mode for the input device | ||
129 | * (signed 10 bits) | ||
130 | */ | ||
131 | #define ADXL_FIXEDRES_MAX_VAL 512 | ||
132 | |||
133 | /* FIFO_CTL Bits */ | ||
134 | #define FIFO_MODE(x) (((x) & 0x3) << 6) | ||
135 | #define FIFO_BYPASS 0 | ||
136 | #define FIFO_FIFO 1 | ||
137 | #define FIFO_STREAM 2 | ||
138 | #define FIFO_TRIGGER 3 | ||
139 | #define TRIGGER (1 << 5) | ||
140 | #define SAMPLES(x) ((x) & 0x1F) | ||
141 | |||
142 | /* FIFO_STATUS Bits */ | ||
143 | #define FIFO_TRIG (1 << 7) | ||
144 | #define ENTRIES(x) ((x) & 0x3F) | ||
145 | |||
146 | /* TAP_SIGN Bits ADXL346 only */ | ||
147 | #define XSIGN (1 << 6) | ||
148 | #define YSIGN (1 << 5) | ||
149 | #define ZSIGN (1 << 4) | ||
150 | #define XTAP (1 << 3) | ||
151 | #define YTAP (1 << 2) | ||
152 | #define ZTAP (1 << 1) | ||
153 | |||
154 | /* ORIENT_CONF ADXL346 only */ | ||
155 | #define ORIENT_DEADZONE(x) (((x) & 0x7) << 4) | ||
156 | #define ORIENT_DIVISOR(x) ((x) & 0x7) | ||
157 | |||
158 | /* ORIENT ADXL346 only */ | ||
159 | #define ADXL346_2D_VALID (1 << 6) | ||
160 | #define ADXL346_2D_ORIENT(x) (((x) & 0x3) >> 4) | ||
161 | #define ADXL346_3D_VALID (1 << 3) | ||
162 | #define ADXL346_3D_ORIENT(x) ((x) & 0x7) | ||
163 | #define ADXL346_2D_PORTRAIT_POS 0 /* +X */ | ||
164 | #define ADXL346_2D_PORTRAIT_NEG 1 /* -X */ | ||
165 | #define ADXL346_2D_LANDSCAPE_POS 2 /* +Y */ | ||
166 | #define ADXL346_2D_LANDSCAPE_NEG 3 /* -Y */ | ||
167 | |||
168 | #define ADXL346_3D_FRONT 3 /* +X */ | ||
169 | #define ADXL346_3D_BACK 4 /* -X */ | ||
170 | #define ADXL346_3D_RIGHT 2 /* +Y */ | ||
171 | #define ADXL346_3D_LEFT 5 /* -Y */ | ||
172 | #define ADXL346_3D_TOP 1 /* +Z */ | ||
173 | #define ADXL346_3D_BOTTOM 6 /* -Z */ | ||
174 | |||
175 | #undef ADXL_DEBUG | ||
176 | |||
177 | #define ADXL_X_AXIS 0 | ||
178 | #define ADXL_Y_AXIS 1 | ||
179 | #define ADXL_Z_AXIS 2 | ||
180 | |||
181 | #define AC_READ(ac, reg) ((ac)->bops->read((ac)->dev, reg)) | ||
182 | #define AC_WRITE(ac, reg, val) ((ac)->bops->write((ac)->dev, reg, val)) | ||
183 | |||
184 | struct axis_triple { | ||
185 | int x; | ||
186 | int y; | ||
187 | int z; | ||
188 | }; | ||
189 | |||
190 | struct adxl34x { | ||
191 | struct device *dev; | ||
192 | struct input_dev *input; | ||
193 | struct mutex mutex; /* reentrant protection for struct */ | ||
194 | struct adxl34x_platform_data pdata; | ||
195 | struct axis_triple swcal; | ||
196 | struct axis_triple hwcal; | ||
197 | struct axis_triple saved; | ||
198 | char phys[32]; | ||
199 | unsigned orient2d_saved; | ||
200 | unsigned orient3d_saved; | ||
201 | bool disabled; /* P: mutex */ | ||
202 | bool opened; /* P: mutex */ | ||
203 | bool suspended; /* P: mutex */ | ||
204 | bool fifo_delay; | ||
205 | int irq; | ||
206 | unsigned model; | ||
207 | unsigned int_mask; | ||
208 | |||
209 | const struct adxl34x_bus_ops *bops; | ||
210 | }; | ||
211 | |||
212 | static const struct adxl34x_platform_data adxl34x_default_init = { | ||
213 | .tap_threshold = 35, | ||
214 | .tap_duration = 3, | ||
215 | .tap_latency = 20, | ||
216 | .tap_window = 20, | ||
217 | .tap_axis_control = ADXL_TAP_X_EN | ADXL_TAP_Y_EN | ADXL_TAP_Z_EN, | ||
218 | .act_axis_control = 0xFF, | ||
219 | .activity_threshold = 6, | ||
220 | .inactivity_threshold = 4, | ||
221 | .inactivity_time = 3, | ||
222 | .free_fall_threshold = 8, | ||
223 | .free_fall_time = 0x20, | ||
224 | .data_rate = 8, | ||
225 | .data_range = ADXL_FULL_RES, | ||
226 | |||
227 | .ev_type = EV_ABS, | ||
228 | .ev_code_x = ABS_X, /* EV_REL */ | ||
229 | .ev_code_y = ABS_Y, /* EV_REL */ | ||
230 | .ev_code_z = ABS_Z, /* EV_REL */ | ||
231 | |||
232 | .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY {x,y,z} */ | ||
233 | .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK, | ||
234 | .fifo_mode = FIFO_STREAM, | ||
235 | .watermark = 0, | ||
236 | }; | ||
237 | |||
238 | static void adxl34x_get_triple(struct adxl34x *ac, struct axis_triple *axis) | ||
239 | { | ||
240 | short buf[3]; | ||
241 | |||
242 | ac->bops->read_block(ac->dev, DATAX0, DATAZ1 - DATAX0 + 1, buf); | ||
243 | |||
244 | mutex_lock(&ac->mutex); | ||
245 | ac->saved.x = (s16) le16_to_cpu(buf[0]); | ||
246 | axis->x = ac->saved.x; | ||
247 | |||
248 | ac->saved.y = (s16) le16_to_cpu(buf[1]); | ||
249 | axis->y = ac->saved.y; | ||
250 | |||
251 | ac->saved.z = (s16) le16_to_cpu(buf[2]); | ||
252 | axis->z = ac->saved.z; | ||
253 | mutex_unlock(&ac->mutex); | ||
254 | } | ||
255 | |||
256 | static void adxl34x_service_ev_fifo(struct adxl34x *ac) | ||
257 | { | ||
258 | struct adxl34x_platform_data *pdata = &ac->pdata; | ||
259 | struct axis_triple axis; | ||
260 | |||
261 | adxl34x_get_triple(ac, &axis); | ||
262 | |||
263 | input_event(ac->input, pdata->ev_type, pdata->ev_code_x, | ||
264 | axis.x - ac->swcal.x); | ||
265 | input_event(ac->input, pdata->ev_type, pdata->ev_code_y, | ||
266 | axis.y - ac->swcal.y); | ||
267 | input_event(ac->input, pdata->ev_type, pdata->ev_code_z, | ||
268 | axis.z - ac->swcal.z); | ||
269 | } | ||
270 | |||
271 | static void adxl34x_report_key_single(struct input_dev *input, int key) | ||
272 | { | ||
273 | input_report_key(input, key, true); | ||
274 | input_sync(input); | ||
275 | input_report_key(input, key, false); | ||
276 | } | ||
277 | |||
278 | static void adxl34x_send_key_events(struct adxl34x *ac, | ||
279 | struct adxl34x_platform_data *pdata, int status, int press) | ||
280 | { | ||
281 | int i; | ||
282 | |||
283 | for (i = ADXL_X_AXIS; i <= ADXL_Z_AXIS; i++) { | ||
284 | if (status & (1 << (ADXL_Z_AXIS - i))) | ||
285 | input_report_key(ac->input, | ||
286 | pdata->ev_code_tap[i], press); | ||
287 | } | ||
288 | } | ||
289 | |||
290 | static void adxl34x_do_tap(struct adxl34x *ac, | ||
291 | struct adxl34x_platform_data *pdata, int status) | ||
292 | { | ||
293 | adxl34x_send_key_events(ac, pdata, status, true); | ||
294 | input_sync(ac->input); | ||
295 | adxl34x_send_key_events(ac, pdata, status, false); | ||
296 | } | ||
297 | |||
298 | static irqreturn_t adxl34x_irq(int irq, void *handle) | ||
299 | { | ||
300 | struct adxl34x *ac = handle; | ||
301 | struct adxl34x_platform_data *pdata = &ac->pdata; | ||
302 | int int_stat, tap_stat, samples, orient, orient_code; | ||
303 | |||
304 | /* | ||
305 | * ACT_TAP_STATUS should be read before clearing the interrupt | ||
306 | * Avoid reading ACT_TAP_STATUS in case TAP detection is disabled | ||
307 | */ | ||
308 | |||
309 | if (pdata->tap_axis_control & (TAP_X_EN | TAP_Y_EN | TAP_Z_EN)) | ||
310 | tap_stat = AC_READ(ac, ACT_TAP_STATUS); | ||
311 | else | ||
312 | tap_stat = 0; | ||
313 | |||
314 | int_stat = AC_READ(ac, INT_SOURCE); | ||
315 | |||
316 | if (int_stat & FREE_FALL) | ||
317 | adxl34x_report_key_single(ac->input, pdata->ev_code_ff); | ||
318 | |||
319 | if (int_stat & OVERRUN) | ||
320 | dev_dbg(ac->dev, "OVERRUN\n"); | ||
321 | |||
322 | if (int_stat & (SINGLE_TAP | DOUBLE_TAP)) { | ||
323 | adxl34x_do_tap(ac, pdata, tap_stat); | ||
324 | |||
325 | if (int_stat & DOUBLE_TAP) | ||
326 | adxl34x_do_tap(ac, pdata, tap_stat); | ||
327 | } | ||
328 | |||
329 | if (pdata->ev_code_act_inactivity) { | ||
330 | if (int_stat & ACTIVITY) | ||
331 | input_report_key(ac->input, | ||
332 | pdata->ev_code_act_inactivity, 1); | ||
333 | if (int_stat & INACTIVITY) | ||
334 | input_report_key(ac->input, | ||
335 | pdata->ev_code_act_inactivity, 0); | ||
336 | } | ||
337 | |||
338 | /* | ||
339 | * ORIENTATION SENSING ADXL346 only | ||
340 | */ | ||
341 | if (pdata->orientation_enable) { | ||
342 | orient = AC_READ(ac, ORIENT); | ||
343 | if ((pdata->orientation_enable & ADXL_EN_ORIENTATION_2D) && | ||
344 | (orient & ADXL346_2D_VALID)) { | ||
345 | |||
346 | orient_code = ADXL346_2D_ORIENT(orient); | ||
347 | /* Report orientation only when it changes */ | ||
348 | if (ac->orient2d_saved != orient_code) { | ||
349 | ac->orient2d_saved = orient_code; | ||
350 | adxl34x_report_key_single(ac->input, | ||
351 | pdata->ev_codes_orient_2d[orient_code]); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | if ((pdata->orientation_enable & ADXL_EN_ORIENTATION_3D) && | ||
356 | (orient & ADXL346_3D_VALID)) { | ||
357 | |||
358 | orient_code = ADXL346_3D_ORIENT(orient) - 1; | ||
359 | /* Report orientation only when it changes */ | ||
360 | if (ac->orient3d_saved != orient_code) { | ||
361 | ac->orient3d_saved = orient_code; | ||
362 | adxl34x_report_key_single(ac->input, | ||
363 | pdata->ev_codes_orient_3d[orient_code]); | ||
364 | } | ||
365 | } | ||
366 | } | ||
367 | |||
368 | if (int_stat & (DATA_READY | WATERMARK)) { | ||
369 | |||
370 | if (pdata->fifo_mode) | ||
371 | samples = ENTRIES(AC_READ(ac, FIFO_STATUS)) + 1; | ||
372 | else | ||
373 | samples = 1; | ||
374 | |||
375 | for (; samples > 0; samples--) { | ||
376 | adxl34x_service_ev_fifo(ac); | ||
377 | /* | ||
378 | * To ensure that the FIFO has | ||
379 | * completely popped, there must be at least 5 us between | ||
380 | * the end of reading the data registers, signified by the | ||
381 | * transition to register 0x38 from 0x37 or the CS pin | ||
382 | * going high, and the start of new reads of the FIFO or | ||
383 | * reading the FIFO_STATUS register. For SPI operation at | ||
384 | * 1.5 MHz or lower, the register addressing portion of the | ||
385 | * transmission is sufficient delay to ensure the FIFO has | ||
386 | * completely popped. It is necessary for SPI operation | ||
387 | * greater than 1.5 MHz to de-assert the CS pin to ensure a | ||
388 | * total of 5 us, which is at most 3.4 us at 5 MHz | ||
389 | * operation. | ||
390 | */ | ||
391 | if (ac->fifo_delay && (samples > 1)) | ||
392 | udelay(3); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | input_sync(ac->input); | ||
397 | |||
398 | return IRQ_HANDLED; | ||
399 | } | ||
400 | |||
401 | static void __adxl34x_disable(struct adxl34x *ac) | ||
402 | { | ||
403 | /* | ||
404 | * A '0' places the ADXL34x into standby mode | ||
405 | * with minimum power consumption. | ||
406 | */ | ||
407 | AC_WRITE(ac, POWER_CTL, 0); | ||
408 | } | ||
409 | |||
410 | static void __adxl34x_enable(struct adxl34x *ac) | ||
411 | { | ||
412 | AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE); | ||
413 | } | ||
414 | |||
415 | void adxl34x_suspend(struct adxl34x *ac) | ||
416 | { | ||
417 | mutex_lock(&ac->mutex); | ||
418 | |||
419 | if (!ac->suspended && !ac->disabled && ac->opened) | ||
420 | __adxl34x_disable(ac); | ||
421 | |||
422 | ac->suspended = true; | ||
423 | |||
424 | mutex_unlock(&ac->mutex); | ||
425 | } | ||
426 | EXPORT_SYMBOL_GPL(adxl34x_suspend); | ||
427 | |||
428 | void adxl34x_resume(struct adxl34x *ac) | ||
429 | { | ||
430 | mutex_lock(&ac->mutex); | ||
431 | |||
432 | if (ac->suspended && !ac->disabled && ac->opened) | ||
433 | __adxl34x_enable(ac); | ||
434 | |||
435 | ac->suspended = false; | ||
436 | |||
437 | mutex_unlock(&ac->mutex); | ||
438 | } | ||
439 | EXPORT_SYMBOL_GPL(adxl34x_resume); | ||
440 | |||
441 | static ssize_t adxl34x_disable_show(struct device *dev, | ||
442 | struct device_attribute *attr, char *buf) | ||
443 | { | ||
444 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
445 | |||
446 | return sprintf(buf, "%u\n", ac->disabled); | ||
447 | } | ||
448 | |||
449 | static ssize_t adxl34x_disable_store(struct device *dev, | ||
450 | struct device_attribute *attr, | ||
451 | const char *buf, size_t count) | ||
452 | { | ||
453 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
454 | unsigned long val; | ||
455 | int error; | ||
456 | |||
457 | error = strict_strtoul(buf, 10, &val); | ||
458 | if (error) | ||
459 | return error; | ||
460 | |||
461 | mutex_lock(&ac->mutex); | ||
462 | |||
463 | if (!ac->suspended && ac->opened) { | ||
464 | if (val) { | ||
465 | if (!ac->disabled) | ||
466 | __adxl34x_disable(ac); | ||
467 | } else { | ||
468 | if (ac->disabled) | ||
469 | __adxl34x_enable(ac); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | ac->disabled = !!val; | ||
474 | |||
475 | mutex_unlock(&ac->mutex); | ||
476 | |||
477 | return count; | ||
478 | } | ||
479 | |||
480 | static DEVICE_ATTR(disable, 0664, adxl34x_disable_show, adxl34x_disable_store); | ||
481 | |||
482 | static ssize_t adxl34x_calibrate_show(struct device *dev, | ||
483 | struct device_attribute *attr, char *buf) | ||
484 | { | ||
485 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
486 | ssize_t count; | ||
487 | |||
488 | mutex_lock(&ac->mutex); | ||
489 | count = sprintf(buf, "%d,%d,%d\n", | ||
490 | ac->hwcal.x * 4 + ac->swcal.x, | ||
491 | ac->hwcal.y * 4 + ac->swcal.y, | ||
492 | ac->hwcal.z * 4 + ac->swcal.z); | ||
493 | mutex_unlock(&ac->mutex); | ||
494 | |||
495 | return count; | ||
496 | } | ||
497 | |||
498 | static ssize_t adxl34x_calibrate_store(struct device *dev, | ||
499 | struct device_attribute *attr, | ||
500 | const char *buf, size_t count) | ||
501 | { | ||
502 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
503 | |||
504 | /* | ||
505 | * Hardware offset calibration has a resolution of 15.6 mg/LSB. | ||
506 | * We use HW calibration and handle the remaining bits in SW. (4mg/LSB) | ||
507 | */ | ||
508 | |||
509 | mutex_lock(&ac->mutex); | ||
510 | ac->hwcal.x -= (ac->saved.x / 4); | ||
511 | ac->swcal.x = ac->saved.x % 4; | ||
512 | |||
513 | ac->hwcal.y -= (ac->saved.y / 4); | ||
514 | ac->swcal.y = ac->saved.y % 4; | ||
515 | |||
516 | ac->hwcal.z -= (ac->saved.z / 4); | ||
517 | ac->swcal.z = ac->saved.z % 4; | ||
518 | |||
519 | AC_WRITE(ac, OFSX, (s8) ac->hwcal.x); | ||
520 | AC_WRITE(ac, OFSY, (s8) ac->hwcal.y); | ||
521 | AC_WRITE(ac, OFSZ, (s8) ac->hwcal.z); | ||
522 | mutex_unlock(&ac->mutex); | ||
523 | |||
524 | return count; | ||
525 | } | ||
526 | |||
527 | static DEVICE_ATTR(calibrate, 0664, | ||
528 | adxl34x_calibrate_show, adxl34x_calibrate_store); | ||
529 | |||
530 | static ssize_t adxl34x_rate_show(struct device *dev, | ||
531 | struct device_attribute *attr, char *buf) | ||
532 | { | ||
533 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
534 | |||
535 | return sprintf(buf, "%u\n", RATE(ac->pdata.data_rate)); | ||
536 | } | ||
537 | |||
538 | static ssize_t adxl34x_rate_store(struct device *dev, | ||
539 | struct device_attribute *attr, | ||
540 | const char *buf, size_t count) | ||
541 | { | ||
542 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
543 | unsigned long val; | ||
544 | int error; | ||
545 | |||
546 | error = strict_strtoul(buf, 10, &val); | ||
547 | if (error) | ||
548 | return error; | ||
549 | |||
550 | mutex_lock(&ac->mutex); | ||
551 | |||
552 | ac->pdata.data_rate = RATE(val); | ||
553 | AC_WRITE(ac, BW_RATE, | ||
554 | ac->pdata.data_rate | | ||
555 | (ac->pdata.low_power_mode ? LOW_POWER : 0)); | ||
556 | |||
557 | mutex_unlock(&ac->mutex); | ||
558 | |||
559 | return count; | ||
560 | } | ||
561 | |||
562 | static DEVICE_ATTR(rate, 0664, adxl34x_rate_show, adxl34x_rate_store); | ||
563 | |||
564 | static ssize_t adxl34x_autosleep_show(struct device *dev, | ||
565 | struct device_attribute *attr, char *buf) | ||
566 | { | ||
567 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
568 | |||
569 | return sprintf(buf, "%u\n", | ||
570 | ac->pdata.power_mode & (PCTL_AUTO_SLEEP | PCTL_LINK) ? 1 : 0); | ||
571 | } | ||
572 | |||
573 | static ssize_t adxl34x_autosleep_store(struct device *dev, | ||
574 | struct device_attribute *attr, | ||
575 | const char *buf, size_t count) | ||
576 | { | ||
577 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
578 | unsigned long val; | ||
579 | int error; | ||
580 | |||
581 | error = strict_strtoul(buf, 10, &val); | ||
582 | if (error) | ||
583 | return error; | ||
584 | |||
585 | mutex_lock(&ac->mutex); | ||
586 | |||
587 | if (val) | ||
588 | ac->pdata.power_mode |= (PCTL_AUTO_SLEEP | PCTL_LINK); | ||
589 | else | ||
590 | ac->pdata.power_mode &= ~(PCTL_AUTO_SLEEP | PCTL_LINK); | ||
591 | |||
592 | if (!ac->disabled && !ac->suspended && ac->opened) | ||
593 | AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE); | ||
594 | |||
595 | mutex_unlock(&ac->mutex); | ||
596 | |||
597 | return count; | ||
598 | } | ||
599 | |||
600 | static DEVICE_ATTR(autosleep, 0664, | ||
601 | adxl34x_autosleep_show, adxl34x_autosleep_store); | ||
602 | |||
603 | static ssize_t adxl34x_position_show(struct device *dev, | ||
604 | struct device_attribute *attr, char *buf) | ||
605 | { | ||
606 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
607 | ssize_t count; | ||
608 | |||
609 | mutex_lock(&ac->mutex); | ||
610 | count = sprintf(buf, "(%d, %d, %d)\n", | ||
611 | ac->saved.x, ac->saved.y, ac->saved.z); | ||
612 | mutex_unlock(&ac->mutex); | ||
613 | |||
614 | return count; | ||
615 | } | ||
616 | |||
617 | static DEVICE_ATTR(position, S_IRUGO, adxl34x_position_show, NULL); | ||
618 | |||
619 | #ifdef ADXL_DEBUG | ||
620 | static ssize_t adxl34x_write_store(struct device *dev, | ||
621 | struct device_attribute *attr, | ||
622 | const char *buf, size_t count) | ||
623 | { | ||
624 | struct adxl34x *ac = dev_get_drvdata(dev); | ||
625 | unsigned long val; | ||
626 | int error; | ||
627 | |||
628 | /* | ||
629 | * This allows basic ADXL register write access for debug purposes. | ||
630 | */ | ||
631 | error = strict_strtoul(buf, 16, &val); | ||
632 | if (error) | ||
633 | return error; | ||
634 | |||
635 | mutex_lock(&ac->mutex); | ||
636 | AC_WRITE(ac, val >> 8, val & 0xFF); | ||
637 | mutex_unlock(&ac->mutex); | ||
638 | |||
639 | return count; | ||
640 | } | ||
641 | |||
642 | static DEVICE_ATTR(write, 0664, NULL, adxl34x_write_store); | ||
643 | #endif | ||
644 | |||
645 | static struct attribute *adxl34x_attributes[] = { | ||
646 | &dev_attr_disable.attr, | ||
647 | &dev_attr_calibrate.attr, | ||
648 | &dev_attr_rate.attr, | ||
649 | &dev_attr_autosleep.attr, | ||
650 | &dev_attr_position.attr, | ||
651 | #ifdef ADXL_DEBUG | ||
652 | &dev_attr_write.attr, | ||
653 | #endif | ||
654 | NULL | ||
655 | }; | ||
656 | |||
657 | static const struct attribute_group adxl34x_attr_group = { | ||
658 | .attrs = adxl34x_attributes, | ||
659 | }; | ||
660 | |||
661 | static int adxl34x_input_open(struct input_dev *input) | ||
662 | { | ||
663 | struct adxl34x *ac = input_get_drvdata(input); | ||
664 | |||
665 | mutex_lock(&ac->mutex); | ||
666 | |||
667 | if (!ac->suspended && !ac->disabled) | ||
668 | __adxl34x_enable(ac); | ||
669 | |||
670 | ac->opened = true; | ||
671 | |||
672 | mutex_unlock(&ac->mutex); | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | static void adxl34x_input_close(struct input_dev *input) | ||
678 | { | ||
679 | struct adxl34x *ac = input_get_drvdata(input); | ||
680 | |||
681 | mutex_lock(&ac->mutex); | ||
682 | |||
683 | if (!ac->suspended && !ac->disabled) | ||
684 | __adxl34x_disable(ac); | ||
685 | |||
686 | ac->opened = false; | ||
687 | |||
688 | mutex_unlock(&ac->mutex); | ||
689 | } | ||
690 | |||
691 | struct adxl34x *adxl34x_probe(struct device *dev, int irq, | ||
692 | bool fifo_delay_default, | ||
693 | const struct adxl34x_bus_ops *bops) | ||
694 | { | ||
695 | struct adxl34x *ac; | ||
696 | struct input_dev *input_dev; | ||
697 | const struct adxl34x_platform_data *pdata; | ||
698 | int err, range, i; | ||
699 | unsigned char revid; | ||
700 | |||
701 | if (!irq) { | ||
702 | dev_err(dev, "no IRQ?\n"); | ||
703 | err = -ENODEV; | ||
704 | goto err_out; | ||
705 | } | ||
706 | |||
707 | ac = kzalloc(sizeof(*ac), GFP_KERNEL); | ||
708 | input_dev = input_allocate_device(); | ||
709 | if (!ac || !input_dev) { | ||
710 | err = -ENOMEM; | ||
711 | goto err_free_mem; | ||
712 | } | ||
713 | |||
714 | ac->fifo_delay = fifo_delay_default; | ||
715 | |||
716 | pdata = dev->platform_data; | ||
717 | if (!pdata) { | ||
718 | dev_dbg(dev, | ||
719 | "No platfrom data: Using default initialization\n"); | ||
720 | pdata = &adxl34x_default_init; | ||
721 | } | ||
722 | |||
723 | ac->pdata = *pdata; | ||
724 | pdata = &ac->pdata; | ||
725 | |||
726 | ac->input = input_dev; | ||
727 | ac->dev = dev; | ||
728 | ac->irq = irq; | ||
729 | ac->bops = bops; | ||
730 | |||
731 | mutex_init(&ac->mutex); | ||
732 | |||
733 | input_dev->name = "ADXL34x accelerometer"; | ||
734 | revid = ac->bops->read(dev, DEVID); | ||
735 | |||
736 | switch (revid) { | ||
737 | case ID_ADXL345: | ||
738 | ac->model = 345; | ||
739 | break; | ||
740 | case ID_ADXL346: | ||
741 | ac->model = 346; | ||
742 | break; | ||
743 | default: | ||
744 | dev_err(dev, "Failed to probe %s\n", input_dev->name); | ||
745 | err = -ENODEV; | ||
746 | goto err_free_mem; | ||
747 | } | ||
748 | |||
749 | snprintf(ac->phys, sizeof(ac->phys), "%s/input0", dev_name(dev)); | ||
750 | |||
751 | input_dev->phys = ac->phys; | ||
752 | input_dev->dev.parent = dev; | ||
753 | input_dev->id.product = ac->model; | ||
754 | input_dev->id.bustype = bops->bustype; | ||
755 | input_dev->open = adxl34x_input_open; | ||
756 | input_dev->close = adxl34x_input_close; | ||
757 | |||
758 | input_set_drvdata(input_dev, ac); | ||
759 | |||
760 | __set_bit(ac->pdata.ev_type, input_dev->evbit); | ||
761 | |||
762 | if (ac->pdata.ev_type == EV_REL) { | ||
763 | __set_bit(REL_X, input_dev->relbit); | ||
764 | __set_bit(REL_Y, input_dev->relbit); | ||
765 | __set_bit(REL_Z, input_dev->relbit); | ||
766 | } else { | ||
767 | /* EV_ABS */ | ||
768 | __set_bit(ABS_X, input_dev->absbit); | ||
769 | __set_bit(ABS_Y, input_dev->absbit); | ||
770 | __set_bit(ABS_Z, input_dev->absbit); | ||
771 | |||
772 | if (pdata->data_range & FULL_RES) | ||
773 | range = ADXL_FULLRES_MAX_VAL; /* Signed 13-bit */ | ||
774 | else | ||
775 | range = ADXL_FIXEDRES_MAX_VAL; /* Signed 10-bit */ | ||
776 | |||
777 | input_set_abs_params(input_dev, ABS_X, -range, range, 3, 3); | ||
778 | input_set_abs_params(input_dev, ABS_Y, -range, range, 3, 3); | ||
779 | input_set_abs_params(input_dev, ABS_Z, -range, range, 3, 3); | ||
780 | } | ||
781 | |||
782 | __set_bit(EV_KEY, input_dev->evbit); | ||
783 | __set_bit(pdata->ev_code_tap[ADXL_X_AXIS], input_dev->keybit); | ||
784 | __set_bit(pdata->ev_code_tap[ADXL_Y_AXIS], input_dev->keybit); | ||
785 | __set_bit(pdata->ev_code_tap[ADXL_Z_AXIS], input_dev->keybit); | ||
786 | |||
787 | if (pdata->ev_code_ff) { | ||
788 | ac->int_mask = FREE_FALL; | ||
789 | __set_bit(pdata->ev_code_ff, input_dev->keybit); | ||
790 | } | ||
791 | |||
792 | if (pdata->ev_code_act_inactivity) | ||
793 | __set_bit(pdata->ev_code_act_inactivity, input_dev->keybit); | ||
794 | |||
795 | ac->int_mask |= ACTIVITY | INACTIVITY; | ||
796 | |||
797 | if (pdata->watermark) { | ||
798 | ac->int_mask |= WATERMARK; | ||
799 | if (!FIFO_MODE(pdata->fifo_mode)) | ||
800 | ac->pdata.fifo_mode |= FIFO_STREAM; | ||
801 | } else { | ||
802 | ac->int_mask |= DATA_READY; | ||
803 | } | ||
804 | |||
805 | if (pdata->tap_axis_control & (TAP_X_EN | TAP_Y_EN | TAP_Z_EN)) | ||
806 | ac->int_mask |= SINGLE_TAP | DOUBLE_TAP; | ||
807 | |||
808 | if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS) | ||
809 | ac->fifo_delay = false; | ||
810 | |||
811 | ac->bops->write(dev, POWER_CTL, 0); | ||
812 | |||
813 | err = request_threaded_irq(ac->irq, NULL, adxl34x_irq, | ||
814 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
815 | dev_name(dev), ac); | ||
816 | if (err) { | ||
817 | dev_err(dev, "irq %d busy?\n", ac->irq); | ||
818 | goto err_free_mem; | ||
819 | } | ||
820 | |||
821 | err = sysfs_create_group(&dev->kobj, &adxl34x_attr_group); | ||
822 | if (err) | ||
823 | goto err_free_irq; | ||
824 | |||
825 | err = input_register_device(input_dev); | ||
826 | if (err) | ||
827 | goto err_remove_attr; | ||
828 | |||
829 | AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold); | ||
830 | AC_WRITE(ac, OFSX, pdata->x_axis_offset); | ||
831 | ac->hwcal.x = pdata->x_axis_offset; | ||
832 | AC_WRITE(ac, OFSY, pdata->y_axis_offset); | ||
833 | ac->hwcal.y = pdata->y_axis_offset; | ||
834 | AC_WRITE(ac, OFSZ, pdata->z_axis_offset); | ||
835 | ac->hwcal.z = pdata->z_axis_offset; | ||
836 | AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold); | ||
837 | AC_WRITE(ac, DUR, pdata->tap_duration); | ||
838 | AC_WRITE(ac, LATENT, pdata->tap_latency); | ||
839 | AC_WRITE(ac, WINDOW, pdata->tap_window); | ||
840 | AC_WRITE(ac, THRESH_ACT, pdata->activity_threshold); | ||
841 | AC_WRITE(ac, THRESH_INACT, pdata->inactivity_threshold); | ||
842 | AC_WRITE(ac, TIME_INACT, pdata->inactivity_time); | ||
843 | AC_WRITE(ac, THRESH_FF, pdata->free_fall_threshold); | ||
844 | AC_WRITE(ac, TIME_FF, pdata->free_fall_time); | ||
845 | AC_WRITE(ac, TAP_AXES, pdata->tap_axis_control); | ||
846 | AC_WRITE(ac, ACT_INACT_CTL, pdata->act_axis_control); | ||
847 | AC_WRITE(ac, BW_RATE, RATE(ac->pdata.data_rate) | | ||
848 | (pdata->low_power_mode ? LOW_POWER : 0)); | ||
849 | AC_WRITE(ac, DATA_FORMAT, pdata->data_range); | ||
850 | AC_WRITE(ac, FIFO_CTL, FIFO_MODE(pdata->fifo_mode) | | ||
851 | SAMPLES(pdata->watermark)); | ||
852 | |||
853 | if (pdata->use_int2) { | ||
854 | /* Map all INTs to INT2 */ | ||
855 | AC_WRITE(ac, INT_MAP, ac->int_mask | OVERRUN); | ||
856 | } else { | ||
857 | /* Map all INTs to INT1 */ | ||
858 | AC_WRITE(ac, INT_MAP, 0); | ||
859 | } | ||
860 | |||
861 | if (ac->model == 346 && ac->pdata.orientation_enable) { | ||
862 | AC_WRITE(ac, ORIENT_CONF, | ||
863 | ORIENT_DEADZONE(ac->pdata.deadzone_angle) | | ||
864 | ORIENT_DIVISOR(ac->pdata.divisor_length)); | ||
865 | |||
866 | ac->orient2d_saved = 1234; | ||
867 | ac->orient3d_saved = 1234; | ||
868 | |||
869 | if (pdata->orientation_enable & ADXL_EN_ORIENTATION_3D) | ||
870 | for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_3d); i++) | ||
871 | __set_bit(pdata->ev_codes_orient_3d[i], | ||
872 | input_dev->keybit); | ||
873 | |||
874 | if (pdata->orientation_enable & ADXL_EN_ORIENTATION_2D) | ||
875 | for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_2d); i++) | ||
876 | __set_bit(pdata->ev_codes_orient_2d[i], | ||
877 | input_dev->keybit); | ||
878 | } else { | ||
879 | ac->pdata.orientation_enable = 0; | ||
880 | } | ||
881 | |||
882 | AC_WRITE(ac, INT_ENABLE, ac->int_mask | OVERRUN); | ||
883 | |||
884 | ac->pdata.power_mode &= (PCTL_AUTO_SLEEP | PCTL_LINK); | ||
885 | |||
886 | return ac; | ||
887 | |||
888 | err_remove_attr: | ||
889 | sysfs_remove_group(&dev->kobj, &adxl34x_attr_group); | ||
890 | err_free_irq: | ||
891 | free_irq(ac->irq, ac); | ||
892 | err_free_mem: | ||
893 | input_free_device(input_dev); | ||
894 | kfree(ac); | ||
895 | err_out: | ||
896 | return ERR_PTR(err); | ||
897 | } | ||
898 | EXPORT_SYMBOL_GPL(adxl34x_probe); | ||
899 | |||
900 | int adxl34x_remove(struct adxl34x *ac) | ||
901 | { | ||
902 | sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group); | ||
903 | free_irq(ac->irq, ac); | ||
904 | input_unregister_device(ac->input); | ||
905 | dev_dbg(ac->dev, "unregistered accelerometer\n"); | ||
906 | kfree(ac); | ||
907 | |||
908 | return 0; | ||
909 | } | ||
910 | EXPORT_SYMBOL_GPL(adxl34x_remove); | ||
911 | |||
912 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
913 | MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer Driver"); | ||
914 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/adxl34x.h b/drivers/input/misc/adxl34x.h new file mode 100644 index 000000000000..bbbc80fda164 --- /dev/null +++ b/drivers/input/misc/adxl34x.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * ADXL345/346 Three-Axis Digital Accelerometers (I2C/SPI Interface) | ||
3 | * | ||
4 | * Enter bugs at http://blackfin.uclinux.org/ | ||
5 | * | ||
6 | * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc. | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #ifndef _ADXL34X_H_ | ||
11 | #define _ADXL34X_H_ | ||
12 | |||
13 | struct device; | ||
14 | struct adxl34x; | ||
15 | |||
16 | struct adxl34x_bus_ops { | ||
17 | u16 bustype; | ||
18 | int (*read)(struct device *, unsigned char); | ||
19 | int (*read_block)(struct device *, unsigned char, int, void *); | ||
20 | int (*write)(struct device *, unsigned char, unsigned char); | ||
21 | }; | ||
22 | |||
23 | void adxl34x_suspend(struct adxl34x *ac); | ||
24 | void adxl34x_resume(struct adxl34x *ac); | ||
25 | struct adxl34x *adxl34x_probe(struct device *dev, int irq, | ||
26 | bool fifo_delay_default, | ||
27 | const struct adxl34x_bus_ops *bops); | ||
28 | int adxl34x_remove(struct adxl34x *ac); | ||
29 | |||
30 | #endif | ||
diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c index 71b82434264d..a8d2b8db4e35 100644 --- a/drivers/input/misc/apanel.c +++ b/drivers/input/misc/apanel.c | |||
@@ -149,7 +149,7 @@ static void apanel_shutdown(struct i2c_client *client) | |||
149 | apanel_remove(client); | 149 | apanel_remove(client); |
150 | } | 150 | } |
151 | 151 | ||
152 | static struct i2c_device_id apanel_id[] = { | 152 | static const struct i2c_device_id apanel_id[] = { |
153 | { "fujitsu_apanel", 0 }, | 153 | { "fujitsu_apanel", 0 }, |
154 | { } | 154 | { } |
155 | }; | 155 | }; |
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c index 614b65d78fe9..bce57129afba 100644 --- a/drivers/input/misc/ati_remote.c +++ b/drivers/input/misc/ati_remote.c | |||
@@ -98,10 +98,12 @@ | |||
98 | * Module and Version Information, Module Parameters | 98 | * Module and Version Information, Module Parameters |
99 | */ | 99 | */ |
100 | 100 | ||
101 | #define ATI_REMOTE_VENDOR_ID 0x0bc7 | 101 | #define ATI_REMOTE_VENDOR_ID 0x0bc7 |
102 | #define ATI_REMOTE_PRODUCT_ID 0x004 | 102 | #define LOLA_REMOTE_PRODUCT_ID 0x0002 |
103 | #define LOLA_REMOTE_PRODUCT_ID 0x002 | 103 | #define LOLA2_REMOTE_PRODUCT_ID 0x0003 |
104 | #define MEDION_REMOTE_PRODUCT_ID 0x006 | 104 | #define ATI_REMOTE_PRODUCT_ID 0x0004 |
105 | #define NVIDIA_REMOTE_PRODUCT_ID 0x0005 | ||
106 | #define MEDION_REMOTE_PRODUCT_ID 0x0006 | ||
105 | 107 | ||
106 | #define DRIVER_VERSION "2.2.1" | 108 | #define DRIVER_VERSION "2.2.1" |
107 | #define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>" | 109 | #define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>" |
@@ -142,8 +144,10 @@ MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec | |||
142 | #define err(format, arg...) printk(KERN_ERR format , ## arg) | 144 | #define err(format, arg...) printk(KERN_ERR format , ## arg) |
143 | 145 | ||
144 | static struct usb_device_id ati_remote_table[] = { | 146 | static struct usb_device_id ati_remote_table[] = { |
145 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) }, | ||
146 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) }, | 147 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) }, |
148 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID) }, | ||
149 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) }, | ||
150 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID) }, | ||
147 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) }, | 151 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) }, |
148 | {} /* Terminating entry */ | 152 | {} /* Terminating entry */ |
149 | }; | 153 | }; |
@@ -620,13 +624,13 @@ static void ati_remote_irq_in(struct urb *urb) | |||
620 | static int ati_remote_alloc_buffers(struct usb_device *udev, | 624 | static int ati_remote_alloc_buffers(struct usb_device *udev, |
621 | struct ati_remote *ati_remote) | 625 | struct ati_remote *ati_remote) |
622 | { | 626 | { |
623 | ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC, | 627 | ati_remote->inbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC, |
624 | &ati_remote->inbuf_dma); | 628 | &ati_remote->inbuf_dma); |
625 | if (!ati_remote->inbuf) | 629 | if (!ati_remote->inbuf) |
626 | return -1; | 630 | return -1; |
627 | 631 | ||
628 | ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC, | 632 | ati_remote->outbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC, |
629 | &ati_remote->outbuf_dma); | 633 | &ati_remote->outbuf_dma); |
630 | if (!ati_remote->outbuf) | 634 | if (!ati_remote->outbuf) |
631 | return -1; | 635 | return -1; |
632 | 636 | ||
@@ -649,10 +653,10 @@ static void ati_remote_free_buffers(struct ati_remote *ati_remote) | |||
649 | usb_free_urb(ati_remote->irq_urb); | 653 | usb_free_urb(ati_remote->irq_urb); |
650 | usb_free_urb(ati_remote->out_urb); | 654 | usb_free_urb(ati_remote->out_urb); |
651 | 655 | ||
652 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, | 656 | usb_free_coherent(ati_remote->udev, DATA_BUFSIZE, |
653 | ati_remote->inbuf, ati_remote->inbuf_dma); | 657 | ati_remote->inbuf, ati_remote->inbuf_dma); |
654 | 658 | ||
655 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, | 659 | usb_free_coherent(ati_remote->udev, DATA_BUFSIZE, |
656 | ati_remote->outbuf, ati_remote->outbuf_dma); | 660 | ati_remote->outbuf, ati_remote->outbuf_dma); |
657 | } | 661 | } |
658 | 662 | ||
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 0501f0e65157..0b0e9be63542 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/usb/input.h> | 12 | #include <linux/usb/input.h> |
13 | #include <linux/slab.h> | ||
13 | 14 | ||
14 | #define DRIVER_DESC "ATI/Philips USB RF remote driver" | 15 | #define DRIVER_DESC "ATI/Philips USB RF remote driver" |
15 | #define DRIVER_VERSION "0.3" | 16 | #define DRIVER_VERSION "0.3" |
@@ -37,7 +38,8 @@ enum { | |||
37 | }; | 38 | }; |
38 | 39 | ||
39 | static int ati_remote2_set_mask(const char *val, | 40 | static int ati_remote2_set_mask(const char *val, |
40 | struct kernel_param *kp, unsigned int max) | 41 | const struct kernel_param *kp, |
42 | unsigned int max) | ||
41 | { | 43 | { |
42 | unsigned long mask; | 44 | unsigned long mask; |
43 | int ret; | 45 | int ret; |
@@ -58,28 +60,31 @@ static int ati_remote2_set_mask(const char *val, | |||
58 | } | 60 | } |
59 | 61 | ||
60 | static int ati_remote2_set_channel_mask(const char *val, | 62 | static int ati_remote2_set_channel_mask(const char *val, |
61 | struct kernel_param *kp) | 63 | const struct kernel_param *kp) |
62 | { | 64 | { |
63 | pr_debug("%s()\n", __func__); | 65 | pr_debug("%s()\n", __func__); |
64 | 66 | ||
65 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK); | 67 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK); |
66 | } | 68 | } |
67 | 69 | ||
68 | static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp) | 70 | static int ati_remote2_get_channel_mask(char *buffer, |
71 | const struct kernel_param *kp) | ||
69 | { | 72 | { |
70 | pr_debug("%s()\n", __func__); | 73 | pr_debug("%s()\n", __func__); |
71 | 74 | ||
72 | return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); | 75 | return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); |
73 | } | 76 | } |
74 | 77 | ||
75 | static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp) | 78 | static int ati_remote2_set_mode_mask(const char *val, |
79 | const struct kernel_param *kp) | ||
76 | { | 80 | { |
77 | pr_debug("%s()\n", __func__); | 81 | pr_debug("%s()\n", __func__); |
78 | 82 | ||
79 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK); | 83 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK); |
80 | } | 84 | } |
81 | 85 | ||
82 | static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) | 86 | static int ati_remote2_get_mode_mask(char *buffer, |
87 | const struct kernel_param *kp) | ||
83 | { | 88 | { |
84 | pr_debug("%s()\n", __func__); | 89 | pr_debug("%s()\n", __func__); |
85 | 90 | ||
@@ -88,15 +93,19 @@ static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) | |||
88 | 93 | ||
89 | static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; | 94 | static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; |
90 | #define param_check_channel_mask(name, p) __param_check(name, p, unsigned int) | 95 | #define param_check_channel_mask(name, p) __param_check(name, p, unsigned int) |
91 | #define param_set_channel_mask ati_remote2_set_channel_mask | 96 | static struct kernel_param_ops param_ops_channel_mask = { |
92 | #define param_get_channel_mask ati_remote2_get_channel_mask | 97 | .set = ati_remote2_set_channel_mask, |
98 | .get = ati_remote2_get_channel_mask, | ||
99 | }; | ||
93 | module_param(channel_mask, channel_mask, 0644); | 100 | module_param(channel_mask, channel_mask, 0644); |
94 | MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); | 101 | MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); |
95 | 102 | ||
96 | static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK; | 103 | static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK; |
97 | #define param_check_mode_mask(name, p) __param_check(name, p, unsigned int) | 104 | #define param_check_mode_mask(name, p) __param_check(name, p, unsigned int) |
98 | #define param_set_mode_mask ati_remote2_set_mode_mask | 105 | static struct kernel_param_ops param_ops_mode_mask = { |
99 | #define param_get_mode_mask ati_remote2_get_mode_mask | 106 | .set = ati_remote2_set_mode_mask, |
107 | .get = ati_remote2_get_mode_mask, | ||
108 | }; | ||
100 | module_param(mode_mask, mode_mask, 0644); | 109 | module_param(mode_mask, mode_mask, 0644); |
101 | MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); | 110 | MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); |
102 | 111 | ||
@@ -474,51 +483,88 @@ static void ati_remote2_complete_key(struct urb *urb) | |||
474 | } | 483 | } |
475 | 484 | ||
476 | static int ati_remote2_getkeycode(struct input_dev *idev, | 485 | static int ati_remote2_getkeycode(struct input_dev *idev, |
477 | int scancode, int *keycode) | 486 | struct input_keymap_entry *ke) |
478 | { | 487 | { |
479 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 488 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
480 | int index, mode; | 489 | unsigned int mode; |
481 | 490 | int offset; | |
482 | mode = scancode >> 8; | 491 | unsigned int index; |
483 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 492 | unsigned int scancode; |
484 | return -EINVAL; | 493 | |
494 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { | ||
495 | index = ke->index; | ||
496 | if (index >= ATI_REMOTE2_MODES * | ||
497 | ARRAY_SIZE(ati_remote2_key_table)) | ||
498 | return -EINVAL; | ||
499 | |||
500 | mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); | ||
501 | offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); | ||
502 | scancode = (mode << 8) + ati_remote2_key_table[offset].hw_code; | ||
503 | } else { | ||
504 | if (input_scancode_to_scalar(ke, &scancode)) | ||
505 | return -EINVAL; | ||
506 | |||
507 | mode = scancode >> 8; | ||
508 | if (mode > ATI_REMOTE2_PC) | ||
509 | return -EINVAL; | ||
510 | |||
511 | offset = ati_remote2_lookup(scancode & 0xff); | ||
512 | if (offset < 0) | ||
513 | return -EINVAL; | ||
514 | |||
515 | index = mode * ARRAY_SIZE(ati_remote2_key_table) + offset; | ||
516 | } | ||
485 | 517 | ||
486 | index = ati_remote2_lookup(scancode & 0xFF); | 518 | ke->keycode = ar2->keycode[mode][offset]; |
487 | if (index < 0) | 519 | ke->len = sizeof(scancode); |
488 | return -EINVAL; | 520 | memcpy(&ke->scancode, &scancode, sizeof(scancode)); |
521 | ke->index = index; | ||
489 | 522 | ||
490 | *keycode = ar2->keycode[mode][index]; | ||
491 | return 0; | 523 | return 0; |
492 | } | 524 | } |
493 | 525 | ||
494 | static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode) | 526 | static int ati_remote2_setkeycode(struct input_dev *idev, |
527 | const struct input_keymap_entry *ke, | ||
528 | unsigned int *old_keycode) | ||
495 | { | 529 | { |
496 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 530 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
497 | int index, mode, old_keycode; | 531 | unsigned int mode; |
498 | 532 | int offset; | |
499 | mode = scancode >> 8; | 533 | unsigned int index; |
500 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 534 | unsigned int scancode; |
501 | return -EINVAL; | 535 | |
502 | 536 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { | |
503 | index = ati_remote2_lookup(scancode & 0xFF); | 537 | if (ke->index >= ATI_REMOTE2_MODES * |
504 | if (index < 0) | 538 | ARRAY_SIZE(ati_remote2_key_table)) |
505 | return -EINVAL; | 539 | return -EINVAL; |
506 | 540 | ||
507 | if (keycode < KEY_RESERVED || keycode > KEY_MAX) | 541 | mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); |
508 | return -EINVAL; | 542 | offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); |
543 | } else { | ||
544 | if (input_scancode_to_scalar(ke, &scancode)) | ||
545 | return -EINVAL; | ||
546 | |||
547 | mode = scancode >> 8; | ||
548 | if (mode > ATI_REMOTE2_PC) | ||
549 | return -EINVAL; | ||
550 | |||
551 | offset = ati_remote2_lookup(scancode & 0xff); | ||
552 | if (offset < 0) | ||
553 | return -EINVAL; | ||
554 | } | ||
509 | 555 | ||
510 | old_keycode = ar2->keycode[mode][index]; | 556 | *old_keycode = ar2->keycode[mode][offset]; |
511 | ar2->keycode[mode][index] = keycode; | 557 | ar2->keycode[mode][offset] = ke->keycode; |
512 | __set_bit(keycode, idev->keybit); | 558 | __set_bit(ke->keycode, idev->keybit); |
513 | 559 | ||
514 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { | 560 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { |
515 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { | 561 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { |
516 | if (ar2->keycode[mode][index] == old_keycode) | 562 | if (ar2->keycode[mode][index] == *old_keycode) |
517 | return 0; | 563 | return 0; |
518 | } | 564 | } |
519 | } | 565 | } |
520 | 566 | ||
521 | __clear_bit(old_keycode, idev->keybit); | 567 | __clear_bit(*old_keycode, idev->keybit); |
522 | 568 | ||
523 | return 0; | 569 | return 0; |
524 | } | 570 | } |
@@ -566,8 +612,8 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) | |||
566 | idev->open = ati_remote2_open; | 612 | idev->open = ati_remote2_open; |
567 | idev->close = ati_remote2_close; | 613 | idev->close = ati_remote2_close; |
568 | 614 | ||
569 | idev->getkeycode = ati_remote2_getkeycode; | 615 | idev->getkeycode_new = ati_remote2_getkeycode; |
570 | idev->setkeycode = ati_remote2_setkeycode; | 616 | idev->setkeycode_new = ati_remote2_setkeycode; |
571 | 617 | ||
572 | idev->name = ar2->name; | 618 | idev->name = ar2->name; |
573 | idev->phys = ar2->phys; | 619 | idev->phys = ar2->phys; |
@@ -588,7 +634,7 @@ static int ati_remote2_urb_init(struct ati_remote2 *ar2) | |||
588 | int i, pipe, maxp; | 634 | int i, pipe, maxp; |
589 | 635 | ||
590 | for (i = 0; i < 2; i++) { | 636 | for (i = 0; i < 2; i++) { |
591 | ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]); | 637 | ar2->buf[i] = usb_alloc_coherent(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]); |
592 | if (!ar2->buf[i]) | 638 | if (!ar2->buf[i]) |
593 | return -ENOMEM; | 639 | return -ENOMEM; |
594 | 640 | ||
@@ -616,7 +662,7 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2) | |||
616 | 662 | ||
617 | for (i = 0; i < 2; i++) { | 663 | for (i = 0; i < 2; i++) { |
618 | usb_free_urb(ar2->urb[i]); | 664 | usb_free_urb(ar2->urb[i]); |
619 | usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]); | 665 | usb_free_coherent(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]); |
620 | } | 666 | } |
621 | } | 667 | } |
622 | 668 | ||
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 1b871917340a..601f7372f9c4 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
25 | |||
24 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 27 | #include <linux/module.h> |
26 | #include <linux/init.h> | 28 | #include <linux/init.h> |
@@ -47,7 +49,7 @@ static acpi_status acpi_atlas_button_setup(acpi_handle region_handle, | |||
47 | 49 | ||
48 | static acpi_status acpi_atlas_button_handler(u32 function, | 50 | static acpi_status acpi_atlas_button_handler(u32 function, |
49 | acpi_physical_address address, | 51 | acpi_physical_address address, |
50 | u32 bit_width, acpi_integer *value, | 52 | u32 bit_width, u64 *value, |
51 | void *handler_context, void *region_context) | 53 | void *handler_context, void *region_context) |
52 | { | 54 | { |
53 | acpi_status status; | 55 | acpi_status status; |
@@ -60,12 +62,11 @@ static acpi_status acpi_atlas_button_handler(u32 function, | |||
60 | input_report_key(input_dev, atlas_keymap[code], key_down); | 62 | input_report_key(input_dev, atlas_keymap[code], key_down); |
61 | input_sync(input_dev); | 63 | input_sync(input_dev); |
62 | 64 | ||
63 | status = 0; | 65 | status = AE_OK; |
64 | } else { | 66 | } else { |
65 | printk(KERN_WARNING "atlas: shrugged on unexpected function" | 67 | pr_warn("shrugged on unexpected function: function=%x,address=%lx,value=%x\n", |
66 | ":function=%x,address=%lx,value=%x\n", | ||
67 | function, (unsigned long)address, (u32)*value); | 68 | function, (unsigned long)address, (u32)*value); |
68 | status = -EINVAL; | 69 | status = AE_BAD_PARAMETER; |
69 | } | 70 | } |
70 | 71 | ||
71 | return status; | 72 | return status; |
@@ -79,7 +80,7 @@ static int atlas_acpi_button_add(struct acpi_device *device) | |||
79 | 80 | ||
80 | input_dev = input_allocate_device(); | 81 | input_dev = input_allocate_device(); |
81 | if (!input_dev) { | 82 | if (!input_dev) { |
82 | printk(KERN_ERR "atlas: unable to allocate input device\n"); | 83 | pr_err("unable to allocate input device\n"); |
83 | return -ENOMEM; | 84 | return -ENOMEM; |
84 | } | 85 | } |
85 | 86 | ||
@@ -102,7 +103,7 @@ static int atlas_acpi_button_add(struct acpi_device *device) | |||
102 | 103 | ||
103 | err = input_register_device(input_dev); | 104 | err = input_register_device(input_dev); |
104 | if (err) { | 105 | if (err) { |
105 | printk(KERN_ERR "atlas: couldn't register input device\n"); | 106 | pr_err("couldn't register input device\n"); |
106 | input_free_device(input_dev); | 107 | input_free_device(input_dev); |
107 | return err; | 108 | return err; |
108 | } | 109 | } |
@@ -112,12 +113,12 @@ static int atlas_acpi_button_add(struct acpi_device *device) | |||
112 | 0x81, &acpi_atlas_button_handler, | 113 | 0x81, &acpi_atlas_button_handler, |
113 | &acpi_atlas_button_setup, device); | 114 | &acpi_atlas_button_setup, device); |
114 | if (ACPI_FAILURE(status)) { | 115 | if (ACPI_FAILURE(status)) { |
115 | printk(KERN_ERR "Atlas: Error installing addr spc handler\n"); | 116 | pr_err("error installing addr spc handler\n"); |
116 | input_unregister_device(input_dev); | 117 | input_unregister_device(input_dev); |
117 | status = -EINVAL; | 118 | err = -EINVAL; |
118 | } | 119 | } |
119 | 120 | ||
120 | return status; | 121 | return err; |
121 | } | 122 | } |
122 | 123 | ||
123 | static int atlas_acpi_button_remove(struct acpi_device *device, int type) | 124 | static int atlas_acpi_button_remove(struct acpi_device *device, int type) |
@@ -126,14 +127,12 @@ static int atlas_acpi_button_remove(struct acpi_device *device, int type) | |||
126 | 127 | ||
127 | status = acpi_remove_address_space_handler(device->handle, | 128 | status = acpi_remove_address_space_handler(device->handle, |
128 | 0x81, &acpi_atlas_button_handler); | 129 | 0x81, &acpi_atlas_button_handler); |
129 | if (ACPI_FAILURE(status)) { | 130 | if (ACPI_FAILURE(status)) |
130 | printk(KERN_ERR "Atlas: Error removing addr spc handler\n"); | 131 | pr_err("error removing addr spc handler\n"); |
131 | status = -EINVAL; | ||
132 | } | ||
133 | 132 | ||
134 | input_unregister_device(input_dev); | 133 | input_unregister_device(input_dev); |
135 | 134 | ||
136 | return status; | 135 | return 0; |
137 | } | 136 | } |
138 | 137 | ||
139 | static const struct acpi_device_id atlas_device_ids[] = { | 138 | static const struct acpi_device_id atlas_device_ids[] = { |
@@ -145,6 +144,7 @@ MODULE_DEVICE_TABLE(acpi, atlas_device_ids); | |||
145 | static struct acpi_driver atlas_acpi_driver = { | 144 | static struct acpi_driver atlas_acpi_driver = { |
146 | .name = ACPI_ATLAS_NAME, | 145 | .name = ACPI_ATLAS_NAME, |
147 | .class = ACPI_ATLAS_CLASS, | 146 | .class = ACPI_ATLAS_CLASS, |
147 | .owner = THIS_MODULE, | ||
148 | .ids = atlas_device_ids, | 148 | .ids = atlas_device_ids, |
149 | .ops = { | 149 | .ops = { |
150 | .add = atlas_acpi_button_add, | 150 | .add = atlas_acpi_button_add, |
@@ -154,18 +154,10 @@ static struct acpi_driver atlas_acpi_driver = { | |||
154 | 154 | ||
155 | static int __init atlas_acpi_init(void) | 155 | static int __init atlas_acpi_init(void) |
156 | { | 156 | { |
157 | int result; | ||
158 | |||
159 | if (acpi_disabled) | 157 | if (acpi_disabled) |
160 | return -ENODEV; | 158 | return -ENODEV; |
161 | 159 | ||
162 | result = acpi_bus_register_driver(&atlas_acpi_driver); | 160 | return acpi_bus_register_driver(&atlas_acpi_driver); |
163 | if (result < 0) { | ||
164 | printk(KERN_ERR "Atlas ACPI: Unable to register driver\n"); | ||
165 | return -ENODEV; | ||
166 | } | ||
167 | |||
168 | return 0; | ||
169 | } | 161 | } |
170 | 162 | ||
171 | static void __exit atlas_acpi_exit(void) | 163 | static void __exit atlas_acpi_exit(void) |
diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index 61d10177fa83..4f72bdd69410 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/pm.h> | 13 | #include <linux/pm.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/input.h> | 15 | #include <linux/input.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | #include <asm/portmux.h> | 18 | #include <asm/portmux.h> |
18 | #include <asm/bfin_rotary.h> | 19 | #include <asm/bfin_rotary.h> |
diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c index 86457feccfc4..b09c7d127219 100644 --- a/drivers/input/misc/cm109.c +++ b/drivers/input/misc/cm109.c | |||
@@ -102,7 +102,6 @@ struct cm109_dev { | |||
102 | struct cm109_ctl_packet *ctl_data; | 102 | struct cm109_ctl_packet *ctl_data; |
103 | dma_addr_t ctl_dma; | 103 | dma_addr_t ctl_dma; |
104 | struct usb_ctrlrequest *ctl_req; | 104 | struct usb_ctrlrequest *ctl_req; |
105 | dma_addr_t ctl_req_dma; | ||
106 | struct urb *urb_ctl; | 105 | struct urb *urb_ctl; |
107 | /* | 106 | /* |
108 | * The 3 bitfields below are protected by ctl_submit_lock. | 107 | * The 3 bitfields below are protected by ctl_submit_lock. |
@@ -260,7 +259,7 @@ static unsigned short keymap_usbph01(int scancode) | |||
260 | 259 | ||
261 | /* | 260 | /* |
262 | * Keymap for ATCom AU-100 | 261 | * Keymap for ATCom AU-100 |
263 | * http://www.atcom.cn/En_products_AU100.html | 262 | * http://www.atcom.cn/products.html |
264 | * http://www.packetizer.com/products/au100/ | 263 | * http://www.packetizer.com/products/au100/ |
265 | * http://www.voip-info.org/wiki/view/AU-100 | 264 | * http://www.voip-info.org/wiki/view/AU-100 |
266 | * | 265 | * |
@@ -629,15 +628,13 @@ static const struct usb_device_id cm109_usb_table[] = { | |||
629 | 628 | ||
630 | static void cm109_usb_cleanup(struct cm109_dev *dev) | 629 | static void cm109_usb_cleanup(struct cm109_dev *dev) |
631 | { | 630 | { |
632 | if (dev->ctl_req) | 631 | kfree(dev->ctl_req); |
633 | usb_buffer_free(dev->udev, sizeof(*(dev->ctl_req)), | ||
634 | dev->ctl_req, dev->ctl_req_dma); | ||
635 | if (dev->ctl_data) | 632 | if (dev->ctl_data) |
636 | usb_buffer_free(dev->udev, USB_PKT_LEN, | 633 | usb_free_coherent(dev->udev, USB_PKT_LEN, |
637 | dev->ctl_data, dev->ctl_dma); | 634 | dev->ctl_data, dev->ctl_dma); |
638 | if (dev->irq_data) | 635 | if (dev->irq_data) |
639 | usb_buffer_free(dev->udev, USB_PKT_LEN, | 636 | usb_free_coherent(dev->udev, USB_PKT_LEN, |
640 | dev->irq_data, dev->irq_dma); | 637 | dev->irq_data, dev->irq_dma); |
641 | 638 | ||
642 | usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */ | 639 | usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */ |
643 | usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */ | 640 | usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */ |
@@ -686,18 +683,17 @@ static int cm109_usb_probe(struct usb_interface *intf, | |||
686 | goto err_out; | 683 | goto err_out; |
687 | 684 | ||
688 | /* allocate usb buffers */ | 685 | /* allocate usb buffers */ |
689 | dev->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN, | 686 | dev->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN, |
690 | GFP_KERNEL, &dev->irq_dma); | 687 | GFP_KERNEL, &dev->irq_dma); |
691 | if (!dev->irq_data) | 688 | if (!dev->irq_data) |
692 | goto err_out; | 689 | goto err_out; |
693 | 690 | ||
694 | dev->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN, | 691 | dev->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN, |
695 | GFP_KERNEL, &dev->ctl_dma); | 692 | GFP_KERNEL, &dev->ctl_dma); |
696 | if (!dev->ctl_data) | 693 | if (!dev->ctl_data) |
697 | goto err_out; | 694 | goto err_out; |
698 | 695 | ||
699 | dev->ctl_req = usb_buffer_alloc(udev, sizeof(*(dev->ctl_req)), | 696 | dev->ctl_req = kmalloc(sizeof(*(dev->ctl_req)), GFP_KERNEL); |
700 | GFP_KERNEL, &dev->ctl_req_dma); | ||
701 | if (!dev->ctl_req) | 697 | if (!dev->ctl_req) |
702 | goto err_out; | 698 | goto err_out; |
703 | 699 | ||
@@ -735,10 +731,8 @@ static int cm109_usb_probe(struct usb_interface *intf, | |||
735 | usb_fill_control_urb(dev->urb_ctl, udev, usb_sndctrlpipe(udev, 0), | 731 | usb_fill_control_urb(dev->urb_ctl, udev, usb_sndctrlpipe(udev, 0), |
736 | (void *)dev->ctl_req, dev->ctl_data, USB_PKT_LEN, | 732 | (void *)dev->ctl_req, dev->ctl_data, USB_PKT_LEN, |
737 | cm109_urb_ctl_callback, dev); | 733 | cm109_urb_ctl_callback, dev); |
738 | dev->urb_ctl->setup_dma = dev->ctl_req_dma; | ||
739 | dev->urb_ctl->transfer_dma = dev->ctl_dma; | 734 | dev->urb_ctl->transfer_dma = dev->ctl_dma; |
740 | dev->urb_ctl->transfer_flags |= URB_NO_SETUP_DMA_MAP | | 735 | dev->urb_ctl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
741 | URB_NO_TRANSFER_DMA_MAP; | ||
742 | dev->urb_ctl->dev = udev; | 736 | dev->urb_ctl->dev = udev; |
743 | 737 | ||
744 | /* find out the physical bus location */ | 738 | /* find out the physical bus location */ |
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index ee73d7219c92..fd8407a29631 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | #define BUTTONS_POLL_INTERVAL 30 /* msec */ | 27 | #define BUTTONS_POLL_INTERVAL 30 /* msec */ |
27 | #define BUTTONS_COUNT_THRESHOLD 3 | 28 | #define BUTTONS_COUNT_THRESHOLD 3 |
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index 766c06911f41..19af682c24fb 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/slab.h> | ||
13 | #include <linux/input.h> | 14 | #include <linux/input.h> |
14 | #include <linux/input/sparse-keymap.h> | 15 | #include <linux/input/sparse-keymap.h> |
15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index ad730e15afc0..0b4f54265f62 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/proc_fs.h> | 43 | #include <linux/proc_fs.h> |
44 | #include <linux/poll.h> | 44 | #include <linux/poll.h> |
45 | #include <linux/rtc.h> | 45 | #include <linux/rtc.h> |
46 | #include <linux/mutex.h> | ||
46 | #include <linux/semaphore.h> | 47 | #include <linux/semaphore.h> |
47 | 48 | ||
48 | MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); | 49 | MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); |
@@ -51,6 +52,7 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
51 | 52 | ||
52 | #define RTC_VERSION "1.10d" | 53 | #define RTC_VERSION "1.10d" |
53 | 54 | ||
55 | static DEFINE_MUTEX(hp_sdc_rtc_mutex); | ||
54 | static unsigned long epoch = 2000; | 56 | static unsigned long epoch = 2000; |
55 | 57 | ||
56 | static struct semaphore i8042tregs; | 58 | static struct semaphore i8042tregs; |
@@ -64,8 +66,8 @@ static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait); | |||
64 | static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf, | 66 | static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf, |
65 | size_t count, loff_t *ppos); | 67 | size_t count, loff_t *ppos); |
66 | 68 | ||
67 | static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, | 69 | static long hp_sdc_rtc_unlocked_ioctl(struct file *file, |
68 | unsigned int cmd, unsigned long arg); | 70 | unsigned int cmd, unsigned long arg); |
69 | 71 | ||
70 | static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait); | 72 | static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait); |
71 | 73 | ||
@@ -103,7 +105,7 @@ static int hp_sdc_rtc_do_read_bbrtc (struct rtc_time *rtctm) | |||
103 | t.endidx = 91; | 105 | t.endidx = 91; |
104 | t.seq = tseq; | 106 | t.seq = tseq; |
105 | t.act.semaphore = &tsem; | 107 | t.act.semaphore = &tsem; |
106 | init_MUTEX_LOCKED(&tsem); | 108 | sema_init(&tsem, 0); |
107 | 109 | ||
108 | if (hp_sdc_enqueue_transaction(&t)) return -1; | 110 | if (hp_sdc_enqueue_transaction(&t)) return -1; |
109 | 111 | ||
@@ -512,7 +514,7 @@ static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off, | |||
512 | return len; | 514 | return len; |
513 | } | 515 | } |
514 | 516 | ||
515 | static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, | 517 | static int hp_sdc_rtc_ioctl(struct file *file, |
516 | unsigned int cmd, unsigned long arg) | 518 | unsigned int cmd, unsigned long arg) |
517 | { | 519 | { |
518 | #if 1 | 520 | #if 1 |
@@ -659,14 +661,27 @@ static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, | |||
659 | #endif | 661 | #endif |
660 | } | 662 | } |
661 | 663 | ||
664 | static long hp_sdc_rtc_unlocked_ioctl(struct file *file, | ||
665 | unsigned int cmd, unsigned long arg) | ||
666 | { | ||
667 | int ret; | ||
668 | |||
669 | mutex_lock(&hp_sdc_rtc_mutex); | ||
670 | ret = hp_sdc_rtc_ioctl(file, cmd, arg); | ||
671 | mutex_unlock(&hp_sdc_rtc_mutex); | ||
672 | |||
673 | return ret; | ||
674 | } | ||
675 | |||
676 | |||
662 | static const struct file_operations hp_sdc_rtc_fops = { | 677 | static const struct file_operations hp_sdc_rtc_fops = { |
663 | .owner = THIS_MODULE, | 678 | .owner = THIS_MODULE, |
664 | .llseek = no_llseek, | 679 | .llseek = no_llseek, |
665 | .read = hp_sdc_rtc_read, | 680 | .read = hp_sdc_rtc_read, |
666 | .poll = hp_sdc_rtc_poll, | 681 | .poll = hp_sdc_rtc_poll, |
667 | .ioctl = hp_sdc_rtc_ioctl, | 682 | .unlocked_ioctl = hp_sdc_rtc_unlocked_ioctl, |
668 | .open = hp_sdc_rtc_open, | 683 | .open = hp_sdc_rtc_open, |
669 | .fasync = hp_sdc_rtc_fasync, | 684 | .fasync = hp_sdc_rtc_fasync, |
670 | }; | 685 | }; |
671 | 686 | ||
672 | static struct miscdevice hp_sdc_rtc_dev = { | 687 | static struct miscdevice hp_sdc_rtc_dev = { |
@@ -684,7 +699,7 @@ static int __init hp_sdc_rtc_init(void) | |||
684 | return -ENODEV; | 699 | return -ENODEV; |
685 | #endif | 700 | #endif |
686 | 701 | ||
687 | init_MUTEX(&i8042tregs); | 702 | sema_init(&i8042tregs, 1); |
688 | 703 | ||
689 | if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr))) | 704 | if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr))) |
690 | return ret; | 705 | return ret; |
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index 9946d73624b9..9dfd6e5f786f 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c | |||
@@ -115,7 +115,8 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) | |||
115 | input_dev->event = ixp4xx_spkr_event; | 115 | input_dev->event = ixp4xx_spkr_event; |
116 | 116 | ||
117 | err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt, | 117 | err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt, |
118 | IRQF_DISABLED | IRQF_TIMER, "ixp4xx-beeper", (void *) dev->id); | 118 | IRQF_DISABLED | IRQF_NO_SUSPEND, "ixp4xx-beeper", |
119 | (void *) dev->id); | ||
119 | if (err) | 120 | if (err) |
120 | goto err_free_device; | 121 | goto err_free_device; |
121 | 122 | ||
diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index 86afdd1fdf9d..a93c525475c6 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c | |||
@@ -464,7 +464,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic | |||
464 | remote->in_endpoint = endpoint; | 464 | remote->in_endpoint = endpoint; |
465 | remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */ | 465 | remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */ |
466 | 466 | ||
467 | remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma); | 467 | remote->in_buffer = usb_alloc_coherent(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma); |
468 | if (!remote->in_buffer) { | 468 | if (!remote->in_buffer) { |
469 | error = -ENOMEM; | 469 | error = -ENOMEM; |
470 | goto fail1; | 470 | goto fail1; |
@@ -543,7 +543,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic | |||
543 | return 0; | 543 | return 0; |
544 | 544 | ||
545 | fail3: usb_free_urb(remote->irq_urb); | 545 | fail3: usb_free_urb(remote->irq_urb); |
546 | fail2: usb_buffer_free(udev, RECV_SIZE, remote->in_buffer, remote->in_dma); | 546 | fail2: usb_free_coherent(udev, RECV_SIZE, remote->in_buffer, remote->in_dma); |
547 | fail1: kfree(remote); | 547 | fail1: kfree(remote); |
548 | input_free_device(input_dev); | 548 | input_free_device(input_dev); |
549 | 549 | ||
@@ -564,7 +564,7 @@ static void keyspan_disconnect(struct usb_interface *interface) | |||
564 | input_unregister_device(remote->input); | 564 | input_unregister_device(remote->input); |
565 | usb_kill_urb(remote->irq_urb); | 565 | usb_kill_urb(remote->irq_urb); |
566 | usb_free_urb(remote->irq_urb); | 566 | usb_free_urb(remote->irq_urb); |
567 | usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma); | 567 | usb_free_coherent(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma); |
568 | kfree(remote); | 568 | kfree(remote); |
569 | } | 569 | } |
570 | } | 570 | } |
diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c new file mode 100644 index 000000000000..7de0ded4ccc3 --- /dev/null +++ b/drivers/input/misc/max8925_onkey.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /** | ||
2 | * max8925_onkey.c - MAX8925 ONKEY driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Marvell International Ltd. | ||
5 | * Haojian Zhuang <haojian.zhuang@marvell.com> | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General | ||
8 | * Public License. See the file "COPYING" in the main directory of this | ||
9 | * archive for more details. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/input.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/mfd/max8925.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #define SW_INPUT (1 << 7) /* 0/1 -- up/down */ | ||
31 | #define HARDRESET_EN (1 << 7) | ||
32 | #define PWREN_EN (1 << 7) | ||
33 | |||
34 | struct max8925_onkey_info { | ||
35 | struct input_dev *idev; | ||
36 | struct i2c_client *i2c; | ||
37 | struct device *dev; | ||
38 | int irq[2]; | ||
39 | }; | ||
40 | |||
41 | /* | ||
42 | * MAX8925 gives us an interrupt when ONKEY is pressed or released. | ||
43 | * max8925_set_bits() operates I2C bus and may sleep. So implement | ||
44 | * it in thread IRQ handler. | ||
45 | */ | ||
46 | static irqreturn_t max8925_onkey_handler(int irq, void *data) | ||
47 | { | ||
48 | struct max8925_onkey_info *info = data; | ||
49 | int ret, event; | ||
50 | |||
51 | ret = max8925_reg_read(info->i2c, MAX8925_ON_OFF_STATUS); | ||
52 | if (ret & SW_INPUT) | ||
53 | event = 1; | ||
54 | else | ||
55 | event = 0; | ||
56 | input_report_key(info->idev, KEY_POWER, event); | ||
57 | input_sync(info->idev); | ||
58 | |||
59 | dev_dbg(info->dev, "onkey event:%d\n", event); | ||
60 | |||
61 | /* Enable hardreset to halt if system isn't shutdown on time */ | ||
62 | max8925_set_bits(info->i2c, MAX8925_SYSENSEL, | ||
63 | HARDRESET_EN, HARDRESET_EN); | ||
64 | |||
65 | return IRQ_HANDLED; | ||
66 | } | ||
67 | |||
68 | static int __devinit max8925_onkey_probe(struct platform_device *pdev) | ||
69 | { | ||
70 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
71 | struct max8925_onkey_info *info; | ||
72 | int irq[2], error; | ||
73 | |||
74 | irq[0] = platform_get_irq(pdev, 0); | ||
75 | if (irq[0] < 0) { | ||
76 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | irq[1] = platform_get_irq(pdev, 1); | ||
80 | if (irq[1] < 0) { | ||
81 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | |||
85 | info = kzalloc(sizeof(struct max8925_onkey_info), GFP_KERNEL); | ||
86 | if (!info) | ||
87 | return -ENOMEM; | ||
88 | |||
89 | info->i2c = chip->i2c; | ||
90 | info->dev = &pdev->dev; | ||
91 | irq[0] += chip->irq_base; | ||
92 | irq[1] += chip->irq_base; | ||
93 | |||
94 | error = request_threaded_irq(irq[0], NULL, max8925_onkey_handler, | ||
95 | IRQF_ONESHOT, "onkey-down", info); | ||
96 | if (error < 0) { | ||
97 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
98 | irq[0], error); | ||
99 | goto out; | ||
100 | } | ||
101 | error = request_threaded_irq(irq[1], NULL, max8925_onkey_handler, | ||
102 | IRQF_ONESHOT, "onkey-up", info); | ||
103 | if (error < 0) { | ||
104 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
105 | irq[1], error); | ||
106 | goto out_irq; | ||
107 | } | ||
108 | |||
109 | info->idev = input_allocate_device(); | ||
110 | if (!info->idev) { | ||
111 | dev_err(chip->dev, "Failed to allocate input dev\n"); | ||
112 | error = -ENOMEM; | ||
113 | goto out_input; | ||
114 | } | ||
115 | |||
116 | info->idev->name = "max8925_on"; | ||
117 | info->idev->phys = "max8925_on/input0"; | ||
118 | info->idev->id.bustype = BUS_I2C; | ||
119 | info->idev->dev.parent = &pdev->dev; | ||
120 | info->irq[0] = irq[0]; | ||
121 | info->irq[1] = irq[1]; | ||
122 | info->idev->evbit[0] = BIT_MASK(EV_KEY); | ||
123 | info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); | ||
124 | |||
125 | |||
126 | error = input_register_device(info->idev); | ||
127 | if (error) { | ||
128 | dev_err(chip->dev, "Can't register input device: %d\n", error); | ||
129 | goto out_reg; | ||
130 | } | ||
131 | |||
132 | platform_set_drvdata(pdev, info); | ||
133 | |||
134 | return 0; | ||
135 | |||
136 | out_reg: | ||
137 | input_free_device(info->idev); | ||
138 | out_input: | ||
139 | free_irq(info->irq[1], info); | ||
140 | out_irq: | ||
141 | free_irq(info->irq[0], info); | ||
142 | out: | ||
143 | kfree(info); | ||
144 | return error; | ||
145 | } | ||
146 | |||
147 | static int __devexit max8925_onkey_remove(struct platform_device *pdev) | ||
148 | { | ||
149 | struct max8925_onkey_info *info = platform_get_drvdata(pdev); | ||
150 | |||
151 | free_irq(info->irq[0], info); | ||
152 | free_irq(info->irq[1], info); | ||
153 | input_unregister_device(info->idev); | ||
154 | kfree(info); | ||
155 | |||
156 | platform_set_drvdata(pdev, NULL); | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static struct platform_driver max8925_onkey_driver = { | ||
162 | .driver = { | ||
163 | .name = "max8925-onkey", | ||
164 | .owner = THIS_MODULE, | ||
165 | }, | ||
166 | .probe = max8925_onkey_probe, | ||
167 | .remove = __devexit_p(max8925_onkey_remove), | ||
168 | }; | ||
169 | |||
170 | static int __init max8925_onkey_init(void) | ||
171 | { | ||
172 | return platform_driver_register(&max8925_onkey_driver); | ||
173 | } | ||
174 | module_init(max8925_onkey_init); | ||
175 | |||
176 | static void __exit max8925_onkey_exit(void) | ||
177 | { | ||
178 | platform_driver_unregister(&max8925_onkey_driver); | ||
179 | } | ||
180 | module_exit(max8925_onkey_exit); | ||
181 | |||
182 | MODULE_DESCRIPTION("Maxim MAX8925 ONKEY driver"); | ||
183 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); | ||
184 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c index 7ea969347ca9..99335c286250 100644 --- a/drivers/input/misc/pcap_keys.c +++ b/drivers/input/misc/pcap_keys.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/mfd/ezx-pcap.h> | 19 | #include <linux/mfd/ezx-pcap.h> |
20 | #include <linux/slab.h> | ||
20 | 21 | ||
21 | struct pcap_keys { | 22 | struct pcap_keys { |
22 | struct pcap_chip *pcap; | 23 | struct pcap_chip *pcap; |
diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c index 008de0c5834b..95562735728d 100644 --- a/drivers/input/misc/pcf50633-input.c +++ b/drivers/input/misc/pcf50633-input.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/input.h> | 22 | #include <linux/input.h> |
23 | #include <linux/slab.h> | ||
23 | 24 | ||
24 | #include <linux/mfd/pcf50633/core.h> | 25 | #include <linux/mfd/pcf50633/core.h> |
25 | 26 | ||
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c new file mode 100644 index 000000000000..4b42ffc0532a --- /dev/null +++ b/drivers/input/misc/pcf8574_keypad.c | |||
@@ -0,0 +1,225 @@ | |||
1 | /* | ||
2 | * Driver for a keypad w/16 buttons connected to a PCF8574 I2C I/O expander | ||
3 | * | ||
4 | * Copyright 2005-2008 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/input.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/workqueue.h> | ||
16 | |||
17 | #define DRV_NAME "pcf8574_keypad" | ||
18 | |||
19 | static const unsigned char pcf8574_kp_btncode[] = { | ||
20 | [0] = KEY_RESERVED, | ||
21 | [1] = KEY_ENTER, | ||
22 | [2] = KEY_BACKSLASH, | ||
23 | [3] = KEY_0, | ||
24 | [4] = KEY_RIGHTBRACE, | ||
25 | [5] = KEY_C, | ||
26 | [6] = KEY_9, | ||
27 | [7] = KEY_8, | ||
28 | [8] = KEY_7, | ||
29 | [9] = KEY_B, | ||
30 | [10] = KEY_6, | ||
31 | [11] = KEY_5, | ||
32 | [12] = KEY_4, | ||
33 | [13] = KEY_A, | ||
34 | [14] = KEY_3, | ||
35 | [15] = KEY_2, | ||
36 | [16] = KEY_1 | ||
37 | }; | ||
38 | |||
39 | struct kp_data { | ||
40 | unsigned short btncode[ARRAY_SIZE(pcf8574_kp_btncode)]; | ||
41 | struct input_dev *idev; | ||
42 | struct i2c_client *client; | ||
43 | char name[64]; | ||
44 | char phys[32]; | ||
45 | unsigned char laststate; | ||
46 | }; | ||
47 | |||
48 | static short read_state(struct kp_data *lp) | ||
49 | { | ||
50 | unsigned char x, y, a, b; | ||
51 | |||
52 | i2c_smbus_write_byte(lp->client, 240); | ||
53 | x = 0xF & (~(i2c_smbus_read_byte(lp->client) >> 4)); | ||
54 | |||
55 | i2c_smbus_write_byte(lp->client, 15); | ||
56 | y = 0xF & (~i2c_smbus_read_byte(lp->client)); | ||
57 | |||
58 | for (a = 0; x > 0; a++) | ||
59 | x = x >> 1; | ||
60 | for (b = 0; y > 0; b++) | ||
61 | y = y >> 1; | ||
62 | |||
63 | return ((a - 1) * 4) + b; | ||
64 | } | ||
65 | |||
66 | static irqreturn_t pcf8574_kp_irq_handler(int irq, void *dev_id) | ||
67 | { | ||
68 | struct kp_data *lp = dev_id; | ||
69 | unsigned char nextstate = read_state(lp); | ||
70 | |||
71 | if (lp->laststate != nextstate) { | ||
72 | int key_down = nextstate < ARRAY_SIZE(lp->btncode); | ||
73 | unsigned short keycode = key_down ? | ||
74 | lp->btncode[nextstate] : lp->btncode[lp->laststate]; | ||
75 | |||
76 | input_report_key(lp->idev, keycode, key_down); | ||
77 | input_sync(lp->idev); | ||
78 | |||
79 | lp->laststate = nextstate; | ||
80 | } | ||
81 | |||
82 | return IRQ_HANDLED; | ||
83 | } | ||
84 | |||
85 | static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
86 | { | ||
87 | int i, ret; | ||
88 | struct input_dev *idev; | ||
89 | struct kp_data *lp; | ||
90 | |||
91 | if (i2c_smbus_write_byte(client, 240) < 0) { | ||
92 | dev_err(&client->dev, "probe: write fail\n"); | ||
93 | return -ENODEV; | ||
94 | } | ||
95 | |||
96 | lp = kzalloc(sizeof(*lp), GFP_KERNEL); | ||
97 | if (!lp) | ||
98 | return -ENOMEM; | ||
99 | |||
100 | idev = input_allocate_device(); | ||
101 | if (!idev) { | ||
102 | dev_err(&client->dev, "Can't allocate input device\n"); | ||
103 | ret = -ENOMEM; | ||
104 | goto fail_allocate; | ||
105 | } | ||
106 | |||
107 | lp->idev = idev; | ||
108 | lp->client = client; | ||
109 | |||
110 | idev->evbit[0] = BIT_MASK(EV_KEY); | ||
111 | idev->keycode = lp->btncode; | ||
112 | idev->keycodesize = sizeof(lp->btncode[0]); | ||
113 | idev->keycodemax = ARRAY_SIZE(lp->btncode); | ||
114 | |||
115 | for (i = 0; i < ARRAY_SIZE(pcf8574_kp_btncode); i++) { | ||
116 | lp->btncode[i] = pcf8574_kp_btncode[i]; | ||
117 | __set_bit(lp->btncode[i] & KEY_MAX, idev->keybit); | ||
118 | } | ||
119 | |||
120 | sprintf(lp->name, DRV_NAME); | ||
121 | sprintf(lp->phys, "kp_data/input0"); | ||
122 | |||
123 | idev->name = lp->name; | ||
124 | idev->phys = lp->phys; | ||
125 | idev->id.bustype = BUS_I2C; | ||
126 | idev->id.vendor = 0x0001; | ||
127 | idev->id.product = 0x0001; | ||
128 | idev->id.version = 0x0100; | ||
129 | |||
130 | input_set_drvdata(idev, lp); | ||
131 | |||
132 | ret = input_register_device(idev); | ||
133 | if (ret) { | ||
134 | dev_err(&client->dev, "input_register_device() failed\n"); | ||
135 | goto fail_register; | ||
136 | } | ||
137 | |||
138 | lp->laststate = read_state(lp); | ||
139 | |||
140 | ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler, | ||
141 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
142 | DRV_NAME, lp); | ||
143 | if (ret) { | ||
144 | dev_err(&client->dev, "IRQ %d is not free\n", client->irq); | ||
145 | goto fail_irq; | ||
146 | } | ||
147 | |||
148 | i2c_set_clientdata(client, lp); | ||
149 | return 0; | ||
150 | |||
151 | fail_irq: | ||
152 | input_unregister_device(idev); | ||
153 | fail_register: | ||
154 | input_set_drvdata(idev, NULL); | ||
155 | input_free_device(idev); | ||
156 | fail_allocate: | ||
157 | kfree(lp); | ||
158 | |||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | static int __devexit pcf8574_kp_remove(struct i2c_client *client) | ||
163 | { | ||
164 | struct kp_data *lp = i2c_get_clientdata(client); | ||
165 | |||
166 | free_irq(client->irq, lp); | ||
167 | |||
168 | input_unregister_device(lp->idev); | ||
169 | kfree(lp); | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | #ifdef CONFIG_PM | ||
175 | static int pcf8574_kp_resume(struct i2c_client *client) | ||
176 | { | ||
177 | enable_irq(client->irq); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int pcf8574_kp_suspend(struct i2c_client *client, pm_message_t mesg) | ||
183 | { | ||
184 | disable_irq(client->irq); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | #else | ||
189 | # define pcf8574_kp_resume NULL | ||
190 | # define pcf8574_kp_suspend NULL | ||
191 | #endif | ||
192 | |||
193 | static const struct i2c_device_id pcf8574_kp_id[] = { | ||
194 | { DRV_NAME, 0 }, | ||
195 | { } | ||
196 | }; | ||
197 | MODULE_DEVICE_TABLE(i2c, pcf8574_kp_id); | ||
198 | |||
199 | static struct i2c_driver pcf8574_kp_driver = { | ||
200 | .driver = { | ||
201 | .name = DRV_NAME, | ||
202 | .owner = THIS_MODULE, | ||
203 | }, | ||
204 | .probe = pcf8574_kp_probe, | ||
205 | .remove = __devexit_p(pcf8574_kp_remove), | ||
206 | .suspend = pcf8574_kp_suspend, | ||
207 | .resume = pcf8574_kp_resume, | ||
208 | .id_table = pcf8574_kp_id, | ||
209 | }; | ||
210 | |||
211 | static int __init pcf8574_kp_init(void) | ||
212 | { | ||
213 | return i2c_add_driver(&pcf8574_kp_driver); | ||
214 | } | ||
215 | module_init(pcf8574_kp_init); | ||
216 | |||
217 | static void __exit pcf8574_kp_exit(void) | ||
218 | { | ||
219 | i2c_del_driver(&pcf8574_kp_driver); | ||
220 | } | ||
221 | module_exit(pcf8574_kp_exit); | ||
222 | |||
223 | MODULE_AUTHOR("Michael Hennerich"); | ||
224 | MODULE_DESCRIPTION("Keypad input driver for 16 keys connected to PCF8574"); | ||
225 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index ea4e1fd12651..f080dd31499b 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c | |||
@@ -30,7 +30,7 @@ MODULE_ALIAS("platform:pcspkr"); | |||
30 | #include <asm/i8253.h> | 30 | #include <asm/i8253.h> |
31 | #else | 31 | #else |
32 | #include <asm/8253pit.h> | 32 | #include <asm/8253pit.h> |
33 | static DEFINE_SPINLOCK(i8253_lock); | 33 | static DEFINE_RAW_SPINLOCK(i8253_lock); |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 36 | static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
@@ -50,7 +50,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c | |||
50 | if (value > 20 && value < 32767) | 50 | if (value > 20 && value < 32767) |
51 | count = PIT_TICK_RATE / value; | 51 | count = PIT_TICK_RATE / value; |
52 | 52 | ||
53 | spin_lock_irqsave(&i8253_lock, flags); | 53 | raw_spin_lock_irqsave(&i8253_lock, flags); |
54 | 54 | ||
55 | if (count) { | 55 | if (count) { |
56 | /* set command for counter 2, 2 byte write */ | 56 | /* set command for counter 2, 2 byte write */ |
@@ -65,7 +65,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c | |||
65 | outb(inb_p(0x61) & 0xFC, 0x61); | 65 | outb(inb_p(0x61) & 0xFC, 0x61); |
66 | } | 66 | } |
67 | 67 | ||
68 | spin_unlock_irqrestore(&i8253_lock, flags); | 68 | raw_spin_unlock_irqrestore(&i8253_lock, flags); |
69 | 69 | ||
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index 668913d12044..f45947190e4f 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c | |||
@@ -64,7 +64,6 @@ struct powermate_device { | |||
64 | dma_addr_t data_dma; | 64 | dma_addr_t data_dma; |
65 | struct urb *irq, *config; | 65 | struct urb *irq, *config; |
66 | struct usb_ctrlrequest *configcr; | 66 | struct usb_ctrlrequest *configcr; |
67 | dma_addr_t configcr_dma; | ||
68 | struct usb_device *udev; | 67 | struct usb_device *udev; |
69 | struct input_dev *input; | 68 | struct input_dev *input; |
70 | spinlock_t lock; | 69 | spinlock_t lock; |
@@ -182,8 +181,6 @@ static void powermate_sync_state(struct powermate_device *pm) | |||
182 | usb_fill_control_urb(pm->config, pm->udev, usb_sndctrlpipe(pm->udev, 0), | 181 | usb_fill_control_urb(pm->config, pm->udev, usb_sndctrlpipe(pm->udev, 0), |
183 | (void *) pm->configcr, NULL, 0, | 182 | (void *) pm->configcr, NULL, 0, |
184 | powermate_config_complete, pm); | 183 | powermate_config_complete, pm); |
185 | pm->config->setup_dma = pm->configcr_dma; | ||
186 | pm->config->transfer_flags |= URB_NO_SETUP_DMA_MAP; | ||
187 | 184 | ||
188 | if (usb_submit_urb(pm->config, GFP_ATOMIC)) | 185 | if (usb_submit_urb(pm->config, GFP_ATOMIC)) |
189 | printk(KERN_ERR "powermate: usb_submit_urb(config) failed"); | 186 | printk(KERN_ERR "powermate: usb_submit_urb(config) failed"); |
@@ -276,25 +273,23 @@ static int powermate_input_event(struct input_dev *dev, unsigned int type, unsig | |||
276 | 273 | ||
277 | static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm) | 274 | static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm) |
278 | { | 275 | { |
279 | pm->data = usb_buffer_alloc(udev, POWERMATE_PAYLOAD_SIZE_MAX, | 276 | pm->data = usb_alloc_coherent(udev, POWERMATE_PAYLOAD_SIZE_MAX, |
280 | GFP_ATOMIC, &pm->data_dma); | 277 | GFP_ATOMIC, &pm->data_dma); |
281 | if (!pm->data) | 278 | if (!pm->data) |
282 | return -1; | 279 | return -1; |
283 | 280 | ||
284 | pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)), | 281 | pm->configcr = kmalloc(sizeof(*(pm->configcr)), GFP_KERNEL); |
285 | GFP_ATOMIC, &pm->configcr_dma); | ||
286 | if (!pm->configcr) | 282 | if (!pm->configcr) |
287 | return -1; | 283 | return -ENOMEM; |
288 | 284 | ||
289 | return 0; | 285 | return 0; |
290 | } | 286 | } |
291 | 287 | ||
292 | static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm) | 288 | static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm) |
293 | { | 289 | { |
294 | usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX, | 290 | usb_free_coherent(udev, POWERMATE_PAYLOAD_SIZE_MAX, |
295 | pm->data, pm->data_dma); | 291 | pm->data, pm->data_dma); |
296 | usb_buffer_free(udev, sizeof(*(pm->configcr)), | 292 | kfree(pm->configcr); |
297 | pm->configcr, pm->configcr_dma); | ||
298 | } | 293 | } |
299 | 294 | ||
300 | /* Called whenever a USB device matching one in our supported devices table is connected */ | 295 | /* Called whenever a USB device matching one in our supported devices table is connected */ |
diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c new file mode 100644 index 000000000000..57c294f07198 --- /dev/null +++ b/drivers/input/misc/pwm-beeper.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> | ||
3 | * PWM beeper driver | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * You should have received a copy of the GNU General Public License along | ||
11 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
12 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/input.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/pwm.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | struct pwm_beeper { | ||
24 | struct input_dev *input; | ||
25 | struct pwm_device *pwm; | ||
26 | unsigned long period; | ||
27 | }; | ||
28 | |||
29 | #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x)) | ||
30 | |||
31 | static int pwm_beeper_event(struct input_dev *input, | ||
32 | unsigned int type, unsigned int code, int value) | ||
33 | { | ||
34 | int ret = 0; | ||
35 | struct pwm_beeper *beeper = input_get_drvdata(input); | ||
36 | unsigned long period; | ||
37 | |||
38 | if (type != EV_SND || value < 0) | ||
39 | return -EINVAL; | ||
40 | |||
41 | switch (code) { | ||
42 | case SND_BELL: | ||
43 | value = value ? 1000 : 0; | ||
44 | break; | ||
45 | case SND_TONE: | ||
46 | break; | ||
47 | default: | ||
48 | return -EINVAL; | ||
49 | } | ||
50 | |||
51 | if (value == 0) { | ||
52 | pwm_config(beeper->pwm, 0, 0); | ||
53 | pwm_disable(beeper->pwm); | ||
54 | } else { | ||
55 | period = HZ_TO_NANOSECONDS(value); | ||
56 | ret = pwm_config(beeper->pwm, period / 2, period); | ||
57 | if (ret) | ||
58 | return ret; | ||
59 | ret = pwm_enable(beeper->pwm); | ||
60 | if (ret) | ||
61 | return ret; | ||
62 | beeper->period = period; | ||
63 | } | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static int __devinit pwm_beeper_probe(struct platform_device *pdev) | ||
69 | { | ||
70 | unsigned long pwm_id = (unsigned long)pdev->dev.platform_data; | ||
71 | struct pwm_beeper *beeper; | ||
72 | int error; | ||
73 | |||
74 | beeper = kzalloc(sizeof(*beeper), GFP_KERNEL); | ||
75 | if (!beeper) | ||
76 | return -ENOMEM; | ||
77 | |||
78 | beeper->pwm = pwm_request(pwm_id, "pwm beeper"); | ||
79 | |||
80 | if (IS_ERR(beeper->pwm)) { | ||
81 | error = PTR_ERR(beeper->pwm); | ||
82 | dev_err(&pdev->dev, "Failed to request pwm device: %d\n", error); | ||
83 | goto err_free; | ||
84 | } | ||
85 | |||
86 | beeper->input = input_allocate_device(); | ||
87 | if (!beeper->input) { | ||
88 | dev_err(&pdev->dev, "Failed to allocate input device\n"); | ||
89 | error = -ENOMEM; | ||
90 | goto err_pwm_free; | ||
91 | } | ||
92 | beeper->input->dev.parent = &pdev->dev; | ||
93 | |||
94 | beeper->input->name = "pwm-beeper"; | ||
95 | beeper->input->phys = "pwm/input0"; | ||
96 | beeper->input->id.bustype = BUS_HOST; | ||
97 | beeper->input->id.vendor = 0x001f; | ||
98 | beeper->input->id.product = 0x0001; | ||
99 | beeper->input->id.version = 0x0100; | ||
100 | |||
101 | beeper->input->evbit[0] = BIT(EV_SND); | ||
102 | beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL); | ||
103 | |||
104 | beeper->input->event = pwm_beeper_event; | ||
105 | |||
106 | input_set_drvdata(beeper->input, beeper); | ||
107 | |||
108 | error = input_register_device(beeper->input); | ||
109 | if (error) { | ||
110 | dev_err(&pdev->dev, "Failed to register input device: %d\n", error); | ||
111 | goto err_input_free; | ||
112 | } | ||
113 | |||
114 | platform_set_drvdata(pdev, beeper); | ||
115 | |||
116 | return 0; | ||
117 | |||
118 | err_input_free: | ||
119 | input_free_device(beeper->input); | ||
120 | err_pwm_free: | ||
121 | pwm_free(beeper->pwm); | ||
122 | err_free: | ||
123 | kfree(beeper); | ||
124 | |||
125 | return error; | ||
126 | } | ||
127 | |||
128 | static int __devexit pwm_beeper_remove(struct platform_device *pdev) | ||
129 | { | ||
130 | struct pwm_beeper *beeper = platform_get_drvdata(pdev); | ||
131 | |||
132 | platform_set_drvdata(pdev, NULL); | ||
133 | input_unregister_device(beeper->input); | ||
134 | |||
135 | pwm_disable(beeper->pwm); | ||
136 | pwm_free(beeper->pwm); | ||
137 | |||
138 | kfree(beeper); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | #ifdef CONFIG_PM | ||
144 | static int pwm_beeper_suspend(struct device *dev) | ||
145 | { | ||
146 | struct pwm_beeper *beeper = dev_get_drvdata(dev); | ||
147 | |||
148 | if (beeper->period) | ||
149 | pwm_disable(beeper->pwm); | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int pwm_beeper_resume(struct device *dev) | ||
155 | { | ||
156 | struct pwm_beeper *beeper = dev_get_drvdata(dev); | ||
157 | |||
158 | if (beeper->period) { | ||
159 | pwm_config(beeper->pwm, beeper->period / 2, beeper->period); | ||
160 | pwm_enable(beeper->pwm); | ||
161 | } | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops, | ||
167 | pwm_beeper_suspend, pwm_beeper_resume); | ||
168 | |||
169 | #define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops) | ||
170 | #else | ||
171 | #define PWM_BEEPER_PM_OPS NULL | ||
172 | #endif | ||
173 | |||
174 | static struct platform_driver pwm_beeper_driver = { | ||
175 | .probe = pwm_beeper_probe, | ||
176 | .remove = __devexit_p(pwm_beeper_remove), | ||
177 | .driver = { | ||
178 | .name = "pwm-beeper", | ||
179 | .owner = THIS_MODULE, | ||
180 | .pm = PWM_BEEPER_PM_OPS, | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | static int __init pwm_beeper_init(void) | ||
185 | { | ||
186 | return platform_driver_register(&pwm_beeper_driver); | ||
187 | } | ||
188 | module_init(pwm_beeper_init); | ||
189 | |||
190 | static void __exit pwm_beeper_exit(void) | ||
191 | { | ||
192 | platform_driver_unregister(&pwm_beeper_driver); | ||
193 | } | ||
194 | module_exit(pwm_beeper_exit); | ||
195 | |||
196 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
197 | MODULE_DESCRIPTION("PWM beeper driver"); | ||
198 | MODULE_LICENSE("GPL"); | ||
199 | MODULE_ALIAS("platform:pwm-beeper"); | ||
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 3b9f588fc747..1f8e0108962e 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/rotary_encoder.h> | 24 | #include <linux/rotary_encoder.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | #define DRV_NAME "rotary-encoder" | 27 | #define DRV_NAME "rotary-encoder" |
27 | 28 | ||
@@ -152,6 +153,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
152 | goto exit_unregister_input; | 153 | goto exit_unregister_input; |
153 | } | 154 | } |
154 | 155 | ||
156 | err = gpio_direction_input(pdata->gpio_a); | ||
157 | if (err) { | ||
158 | dev_err(&pdev->dev, "unable to set GPIO %d for input\n", | ||
159 | pdata->gpio_a); | ||
160 | goto exit_unregister_input; | ||
161 | } | ||
162 | |||
155 | err = gpio_request(pdata->gpio_b, DRV_NAME); | 163 | err = gpio_request(pdata->gpio_b, DRV_NAME); |
156 | if (err) { | 164 | if (err) { |
157 | dev_err(&pdev->dev, "unable to request GPIO %d\n", | 165 | dev_err(&pdev->dev, "unable to request GPIO %d\n", |
@@ -159,6 +167,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
159 | goto exit_free_gpio_a; | 167 | goto exit_free_gpio_a; |
160 | } | 168 | } |
161 | 169 | ||
170 | err = gpio_direction_input(pdata->gpio_b); | ||
171 | if (err) { | ||
172 | dev_err(&pdev->dev, "unable to set GPIO %d for input\n", | ||
173 | pdata->gpio_b); | ||
174 | goto exit_free_gpio_a; | ||
175 | } | ||
176 | |||
162 | /* request the IRQs */ | 177 | /* request the IRQs */ |
163 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, | 178 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, |
164 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | 179 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, |
diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c index be3a15f5b25d..1a80c0dab83b 100644 --- a/drivers/input/misc/sgi_btns.c +++ b/drivers/input/misc/sgi_btns.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | #ifdef CONFIG_SGI_IP22 | 27 | #ifdef CONFIG_SGI_IP22 |
27 | #include <asm/sgi/ioc.h> | 28 | #include <asm/sgi/ioc.h> |
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index b064419b90a2..8e130bf7d32b 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/input.h> | 10 | #include <linux/input.h> |
11 | #include <linux/of_device.h> | 11 | #include <linux/of_device.h> |
12 | #include <linux/slab.h> | ||
12 | 13 | ||
13 | #include <asm/io.h> | 14 | #include <asm/io.h> |
14 | 15 | ||
@@ -172,7 +173,7 @@ static int __devinit sparcspkr_probe(struct device *dev) | |||
172 | return 0; | 173 | return 0; |
173 | } | 174 | } |
174 | 175 | ||
175 | static int sparcspkr_shutdown(struct of_device *dev) | 176 | static int sparcspkr_shutdown(struct platform_device *dev) |
176 | { | 177 | { |
177 | struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); | 178 | struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); |
178 | struct input_dev *input_dev = state->input_dev; | 179 | struct input_dev *input_dev = state->input_dev; |
@@ -183,7 +184,7 @@ static int sparcspkr_shutdown(struct of_device *dev) | |||
183 | return 0; | 184 | return 0; |
184 | } | 185 | } |
185 | 186 | ||
186 | static int __devinit bbc_beep_probe(struct of_device *op, const struct of_device_id *match) | 187 | static int __devinit bbc_beep_probe(struct platform_device *op, const struct of_device_id *match) |
187 | { | 188 | { |
188 | struct sparcspkr_state *state; | 189 | struct sparcspkr_state *state; |
189 | struct bbc_beep_info *info; | 190 | struct bbc_beep_info *info; |
@@ -230,7 +231,7 @@ out_err: | |||
230 | return err; | 231 | return err; |
231 | } | 232 | } |
232 | 233 | ||
233 | static int __devexit bbc_remove(struct of_device *op) | 234 | static int __devexit bbc_remove(struct platform_device *op) |
234 | { | 235 | { |
235 | struct sparcspkr_state *state = dev_get_drvdata(&op->dev); | 236 | struct sparcspkr_state *state = dev_get_drvdata(&op->dev); |
236 | struct input_dev *input_dev = state->input_dev; | 237 | struct input_dev *input_dev = state->input_dev; |
@@ -258,14 +259,17 @@ static const struct of_device_id bbc_beep_match[] = { | |||
258 | }; | 259 | }; |
259 | 260 | ||
260 | static struct of_platform_driver bbc_beep_driver = { | 261 | static struct of_platform_driver bbc_beep_driver = { |
261 | .name = "bbcbeep", | 262 | .driver = { |
262 | .match_table = bbc_beep_match, | 263 | .name = "bbcbeep", |
264 | .owner = THIS_MODULE, | ||
265 | .of_match_table = bbc_beep_match, | ||
266 | }, | ||
263 | .probe = bbc_beep_probe, | 267 | .probe = bbc_beep_probe, |
264 | .remove = __devexit_p(bbc_remove), | 268 | .remove = __devexit_p(bbc_remove), |
265 | .shutdown = sparcspkr_shutdown, | 269 | .shutdown = sparcspkr_shutdown, |
266 | }; | 270 | }; |
267 | 271 | ||
268 | static int __devinit grover_beep_probe(struct of_device *op, const struct of_device_id *match) | 272 | static int __devinit grover_beep_probe(struct platform_device *op, const struct of_device_id *match) |
269 | { | 273 | { |
270 | struct sparcspkr_state *state; | 274 | struct sparcspkr_state *state; |
271 | struct grover_beep_info *info; | 275 | struct grover_beep_info *info; |
@@ -308,7 +312,7 @@ out_err: | |||
308 | return err; | 312 | return err; |
309 | } | 313 | } |
310 | 314 | ||
311 | static int __devexit grover_remove(struct of_device *op) | 315 | static int __devexit grover_remove(struct platform_device *op) |
312 | { | 316 | { |
313 | struct sparcspkr_state *state = dev_get_drvdata(&op->dev); | 317 | struct sparcspkr_state *state = dev_get_drvdata(&op->dev); |
314 | struct grover_beep_info *info = &state->u.grover; | 318 | struct grover_beep_info *info = &state->u.grover; |
@@ -337,8 +341,11 @@ static const struct of_device_id grover_beep_match[] = { | |||
337 | }; | 341 | }; |
338 | 342 | ||
339 | static struct of_platform_driver grover_beep_driver = { | 343 | static struct of_platform_driver grover_beep_driver = { |
340 | .name = "groverbeep", | 344 | .driver = { |
341 | .match_table = grover_beep_match, | 345 | .name = "groverbeep", |
346 | .owner = THIS_MODULE, | ||
347 | .of_match_table = grover_beep_match, | ||
348 | }, | ||
342 | .probe = grover_beep_probe, | 349 | .probe = grover_beep_probe, |
343 | .remove = __devexit_p(grover_remove), | 350 | .remove = __devexit_p(grover_remove), |
344 | .shutdown = sparcspkr_shutdown, | 351 | .shutdown = sparcspkr_shutdown, |
@@ -346,14 +353,12 @@ static struct of_platform_driver grover_beep_driver = { | |||
346 | 353 | ||
347 | static int __init sparcspkr_init(void) | 354 | static int __init sparcspkr_init(void) |
348 | { | 355 | { |
349 | int err = of_register_driver(&bbc_beep_driver, | 356 | int err = of_register_platform_driver(&bbc_beep_driver); |
350 | &of_platform_bus_type); | ||
351 | 357 | ||
352 | if (!err) { | 358 | if (!err) { |
353 | err = of_register_driver(&grover_beep_driver, | 359 | err = of_register_platform_driver(&grover_beep_driver); |
354 | &of_platform_bus_type); | ||
355 | if (err) | 360 | if (err) |
356 | of_unregister_driver(&bbc_beep_driver); | 361 | of_unregister_platform_driver(&bbc_beep_driver); |
357 | } | 362 | } |
358 | 363 | ||
359 | return err; | 364 | return err; |
@@ -361,8 +366,8 @@ static int __init sparcspkr_init(void) | |||
361 | 366 | ||
362 | static void __exit sparcspkr_exit(void) | 367 | static void __exit sparcspkr_exit(void) |
363 | { | 368 | { |
364 | of_unregister_driver(&bbc_beep_driver); | 369 | of_unregister_platform_driver(&bbc_beep_driver); |
365 | of_unregister_driver(&grover_beep_driver); | 370 | of_unregister_platform_driver(&grover_beep_driver); |
366 | } | 371 | } |
367 | 372 | ||
368 | module_init(sparcspkr_init); | 373 | module_init(sparcspkr_init); |
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index e9069b87fde2..f16972bddca4 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c | |||
@@ -52,7 +52,7 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr) | |||
52 | return IRQ_HANDLED; | 52 | return IRQ_HANDLED; |
53 | } | 53 | } |
54 | 54 | ||
55 | static int __devinit twl4030_pwrbutton_probe(struct platform_device *pdev) | 55 | static int __init twl4030_pwrbutton_probe(struct platform_device *pdev) |
56 | { | 56 | { |
57 | struct input_dev *pwr; | 57 | struct input_dev *pwr; |
58 | int irq = platform_get_irq(pdev, 0); | 58 | int irq = platform_get_irq(pdev, 0); |
@@ -95,7 +95,7 @@ free_input_dev: | |||
95 | return err; | 95 | return err; |
96 | } | 96 | } |
97 | 97 | ||
98 | static int __devexit twl4030_pwrbutton_remove(struct platform_device *pdev) | 98 | static int __exit twl4030_pwrbutton_remove(struct platform_device *pdev) |
99 | { | 99 | { |
100 | struct input_dev *pwr = platform_get_drvdata(pdev); | 100 | struct input_dev *pwr = platform_get_drvdata(pdev); |
101 | int irq = platform_get_irq(pdev, 0); | 101 | int irq = platform_get_irq(pdev, 0); |
@@ -106,9 +106,8 @@ static int __devexit twl4030_pwrbutton_remove(struct platform_device *pdev) | |||
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | 108 | ||
109 | struct platform_driver twl4030_pwrbutton_driver = { | 109 | static struct platform_driver twl4030_pwrbutton_driver = { |
110 | .probe = twl4030_pwrbutton_probe, | 110 | .remove = __exit_p(twl4030_pwrbutton_remove), |
111 | .remove = __devexit_p(twl4030_pwrbutton_remove), | ||
112 | .driver = { | 111 | .driver = { |
113 | .name = "twl4030_pwrbutton", | 112 | .name = "twl4030_pwrbutton", |
114 | .owner = THIS_MODULE, | 113 | .owner = THIS_MODULE, |
@@ -117,7 +116,8 @@ struct platform_driver twl4030_pwrbutton_driver = { | |||
117 | 116 | ||
118 | static int __init twl4030_pwrbutton_init(void) | 117 | static int __init twl4030_pwrbutton_init(void) |
119 | { | 118 | { |
120 | return platform_driver_register(&twl4030_pwrbutton_driver); | 119 | return platform_driver_probe(&twl4030_pwrbutton_driver, |
120 | twl4030_pwrbutton_probe); | ||
121 | } | 121 | } |
122 | module_init(twl4030_pwrbutton_init); | 122 | module_init(twl4030_pwrbutton_init); |
123 | 123 | ||
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c new file mode 100644 index 000000000000..014dd4ad0d4f --- /dev/null +++ b/drivers/input/misc/twl4030-vibra.c | |||
@@ -0,0 +1,298 @@ | |||
1 | /* | ||
2 | * twl4030-vibra.c - TWL4030 Vibrator driver | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Nokia Corporation | ||
5 | * | ||
6 | * Written by Henrik Saari <henrik.saari@nokia.com> | ||
7 | * Updates by Felipe Balbi <felipe.balbi@nokia.com> | ||
8 | * Input by Jari Vanhala <ext-jari.vanhala@nokia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
22 | * 02110-1301 USA | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/jiffies.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/workqueue.h> | ||
30 | #include <linux/i2c/twl.h> | ||
31 | #include <linux/mfd/twl4030-codec.h> | ||
32 | #include <linux/input.h> | ||
33 | #include <linux/slab.h> | ||
34 | |||
35 | /* MODULE ID2 */ | ||
36 | #define LEDEN 0x00 | ||
37 | |||
38 | /* ForceFeedback */ | ||
39 | #define EFFECT_DIR_180_DEG 0x8000 /* range is 0 - 0xFFFF */ | ||
40 | |||
41 | struct vibra_info { | ||
42 | struct device *dev; | ||
43 | struct input_dev *input_dev; | ||
44 | |||
45 | struct workqueue_struct *workqueue; | ||
46 | struct work_struct play_work; | ||
47 | |||
48 | bool enabled; | ||
49 | int speed; | ||
50 | int direction; | ||
51 | |||
52 | bool coexist; | ||
53 | }; | ||
54 | |||
55 | static void vibra_disable_leds(void) | ||
56 | { | ||
57 | u8 reg; | ||
58 | |||
59 | /* Disable LEDA & LEDB, cannot be used with vibra (PWM) */ | ||
60 | twl_i2c_read_u8(TWL4030_MODULE_LED, ®, LEDEN); | ||
61 | reg &= ~0x03; | ||
62 | twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg); | ||
63 | } | ||
64 | |||
65 | /* Powers H-Bridge and enables audio clk */ | ||
66 | static void vibra_enable(struct vibra_info *info) | ||
67 | { | ||
68 | u8 reg; | ||
69 | |||
70 | twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER); | ||
71 | |||
72 | /* turn H-Bridge on */ | ||
73 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
74 | ®, TWL4030_REG_VIBRA_CTL); | ||
75 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
76 | (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); | ||
77 | |||
78 | twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); | ||
79 | |||
80 | info->enabled = true; | ||
81 | } | ||
82 | |||
83 | static void vibra_disable(struct vibra_info *info) | ||
84 | { | ||
85 | u8 reg; | ||
86 | |||
87 | /* Power down H-Bridge */ | ||
88 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
89 | ®, TWL4030_REG_VIBRA_CTL); | ||
90 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
91 | (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); | ||
92 | |||
93 | twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); | ||
94 | twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); | ||
95 | |||
96 | info->enabled = false; | ||
97 | } | ||
98 | |||
99 | static void vibra_play_work(struct work_struct *work) | ||
100 | { | ||
101 | struct vibra_info *info = container_of(work, | ||
102 | struct vibra_info, play_work); | ||
103 | int dir; | ||
104 | int pwm; | ||
105 | u8 reg; | ||
106 | |||
107 | dir = info->direction; | ||
108 | pwm = info->speed; | ||
109 | |||
110 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
111 | ®, TWL4030_REG_VIBRA_CTL); | ||
112 | if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) { | ||
113 | |||
114 | if (!info->enabled) | ||
115 | vibra_enable(info); | ||
116 | |||
117 | /* set vibra rotation direction */ | ||
118 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
119 | ®, TWL4030_REG_VIBRA_CTL); | ||
120 | reg = (dir) ? (reg | TWL4030_VIBRA_DIR) : | ||
121 | (reg & ~TWL4030_VIBRA_DIR); | ||
122 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
123 | reg, TWL4030_REG_VIBRA_CTL); | ||
124 | |||
125 | /* set PWM, 1 = max, 255 = min */ | ||
126 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
127 | 256 - pwm, TWL4030_REG_VIBRA_SET); | ||
128 | } else { | ||
129 | if (info->enabled) | ||
130 | vibra_disable(info); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | /*** Input/ForceFeedback ***/ | ||
135 | |||
136 | static int vibra_play(struct input_dev *input, void *data, | ||
137 | struct ff_effect *effect) | ||
138 | { | ||
139 | struct vibra_info *info = input_get_drvdata(input); | ||
140 | |||
141 | info->speed = effect->u.rumble.strong_magnitude >> 8; | ||
142 | if (!info->speed) | ||
143 | info->speed = effect->u.rumble.weak_magnitude >> 9; | ||
144 | info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1; | ||
145 | queue_work(info->workqueue, &info->play_work); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int twl4030_vibra_open(struct input_dev *input) | ||
150 | { | ||
151 | struct vibra_info *info = input_get_drvdata(input); | ||
152 | |||
153 | info->workqueue = create_singlethread_workqueue("vibra"); | ||
154 | if (info->workqueue == NULL) { | ||
155 | dev_err(&input->dev, "couldn't create workqueue\n"); | ||
156 | return -ENOMEM; | ||
157 | } | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static void twl4030_vibra_close(struct input_dev *input) | ||
162 | { | ||
163 | struct vibra_info *info = input_get_drvdata(input); | ||
164 | |||
165 | cancel_work_sync(&info->play_work); | ||
166 | INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */ | ||
167 | destroy_workqueue(info->workqueue); | ||
168 | info->workqueue = NULL; | ||
169 | |||
170 | if (info->enabled) | ||
171 | vibra_disable(info); | ||
172 | } | ||
173 | |||
174 | /*** Module ***/ | ||
175 | #if CONFIG_PM | ||
176 | static int twl4030_vibra_suspend(struct device *dev) | ||
177 | { | ||
178 | struct platform_device *pdev = to_platform_device(dev); | ||
179 | struct vibra_info *info = platform_get_drvdata(pdev); | ||
180 | |||
181 | if (info->enabled) | ||
182 | vibra_disable(info); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int twl4030_vibra_resume(struct device *dev) | ||
188 | { | ||
189 | vibra_disable_leds(); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, | ||
194 | twl4030_vibra_suspend, twl4030_vibra_resume); | ||
195 | #endif | ||
196 | |||
197 | static int __devinit twl4030_vibra_probe(struct platform_device *pdev) | ||
198 | { | ||
199 | struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; | ||
200 | struct vibra_info *info; | ||
201 | int ret; | ||
202 | |||
203 | if (!pdata) { | ||
204 | dev_dbg(&pdev->dev, "platform_data not available\n"); | ||
205 | return -EINVAL; | ||
206 | } | ||
207 | |||
208 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
209 | if (!info) | ||
210 | return -ENOMEM; | ||
211 | |||
212 | info->dev = &pdev->dev; | ||
213 | info->coexist = pdata->coexist; | ||
214 | INIT_WORK(&info->play_work, vibra_play_work); | ||
215 | |||
216 | info->input_dev = input_allocate_device(); | ||
217 | if (info->input_dev == NULL) { | ||
218 | dev_err(&pdev->dev, "couldn't allocate input device\n"); | ||
219 | ret = -ENOMEM; | ||
220 | goto err_kzalloc; | ||
221 | } | ||
222 | |||
223 | input_set_drvdata(info->input_dev, info); | ||
224 | |||
225 | info->input_dev->name = "twl4030:vibrator"; | ||
226 | info->input_dev->id.version = 1; | ||
227 | info->input_dev->dev.parent = pdev->dev.parent; | ||
228 | info->input_dev->open = twl4030_vibra_open; | ||
229 | info->input_dev->close = twl4030_vibra_close; | ||
230 | __set_bit(FF_RUMBLE, info->input_dev->ffbit); | ||
231 | |||
232 | ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); | ||
233 | if (ret < 0) { | ||
234 | dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); | ||
235 | goto err_ialloc; | ||
236 | } | ||
237 | |||
238 | ret = input_register_device(info->input_dev); | ||
239 | if (ret < 0) { | ||
240 | dev_dbg(&pdev->dev, "couldn't register input device\n"); | ||
241 | goto err_iff; | ||
242 | } | ||
243 | |||
244 | vibra_disable_leds(); | ||
245 | |||
246 | platform_set_drvdata(pdev, info); | ||
247 | return 0; | ||
248 | |||
249 | err_iff: | ||
250 | input_ff_destroy(info->input_dev); | ||
251 | err_ialloc: | ||
252 | input_free_device(info->input_dev); | ||
253 | err_kzalloc: | ||
254 | kfree(info); | ||
255 | return ret; | ||
256 | } | ||
257 | |||
258 | static int __devexit twl4030_vibra_remove(struct platform_device *pdev) | ||
259 | { | ||
260 | struct vibra_info *info = platform_get_drvdata(pdev); | ||
261 | |||
262 | /* this also free ff-memless and calls close if needed */ | ||
263 | input_unregister_device(info->input_dev); | ||
264 | kfree(info); | ||
265 | platform_set_drvdata(pdev, NULL); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static struct platform_driver twl4030_vibra_driver = { | ||
271 | .probe = twl4030_vibra_probe, | ||
272 | .remove = __devexit_p(twl4030_vibra_remove), | ||
273 | .driver = { | ||
274 | .name = "twl4030-vibra", | ||
275 | .owner = THIS_MODULE, | ||
276 | #ifdef CONFIG_PM | ||
277 | .pm = &twl4030_vibra_pm_ops, | ||
278 | #endif | ||
279 | }, | ||
280 | }; | ||
281 | |||
282 | static int __init twl4030_vibra_init(void) | ||
283 | { | ||
284 | return platform_driver_register(&twl4030_vibra_driver); | ||
285 | } | ||
286 | module_init(twl4030_vibra_init); | ||
287 | |||
288 | static void __exit twl4030_vibra_exit(void) | ||
289 | { | ||
290 | platform_driver_unregister(&twl4030_vibra_driver); | ||
291 | } | ||
292 | module_exit(twl4030_vibra_exit); | ||
293 | |||
294 | MODULE_ALIAS("platform:twl4030-vibra"); | ||
295 | |||
296 | MODULE_DESCRIPTION("TWL4030 Vibra driver"); | ||
297 | MODULE_LICENSE("GPL"); | ||
298 | MODULE_AUTHOR("Nokia Corporation"); | ||
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index d3f57245420a..b9410784e6a1 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/fs.h> | 37 | #include <linux/fs.h> |
39 | #include <linux/miscdevice.h> | 38 | #include <linux/miscdevice.h> |
40 | #include <linux/uinput.h> | 39 | #include <linux/uinput.h> |
@@ -284,7 +283,6 @@ static int uinput_open(struct inode *inode, struct file *file) | |||
284 | if (!newdev) | 283 | if (!newdev) |
285 | return -ENOMEM; | 284 | return -ENOMEM; |
286 | 285 | ||
287 | lock_kernel(); | ||
288 | mutex_init(&newdev->mutex); | 286 | mutex_init(&newdev->mutex); |
289 | spin_lock_init(&newdev->requests_lock); | 287 | spin_lock_init(&newdev->requests_lock); |
290 | init_waitqueue_head(&newdev->requests_waitq); | 288 | init_waitqueue_head(&newdev->requests_waitq); |
@@ -292,7 +290,7 @@ static int uinput_open(struct inode *inode, struct file *file) | |||
292 | newdev->state = UIST_NEW_DEVICE; | 290 | newdev->state = UIST_NEW_DEVICE; |
293 | 291 | ||
294 | file->private_data = newdev; | 292 | file->private_data = newdev; |
295 | unlock_kernel(); | 293 | nonseekable_open(inode, file); |
296 | 294 | ||
297 | return 0; | 295 | return 0; |
298 | } | 296 | } |
@@ -302,25 +300,29 @@ static int uinput_validate_absbits(struct input_dev *dev) | |||
302 | unsigned int cnt; | 300 | unsigned int cnt; |
303 | int retval = 0; | 301 | int retval = 0; |
304 | 302 | ||
305 | for (cnt = 0; cnt < ABS_MAX + 1; cnt++) { | 303 | for (cnt = 0; cnt < ABS_CNT; cnt++) { |
306 | if (!test_bit(cnt, dev->absbit)) | 304 | if (!test_bit(cnt, dev->absbit)) |
307 | continue; | 305 | continue; |
308 | 306 | ||
309 | if ((dev->absmax[cnt] <= dev->absmin[cnt])) { | 307 | if (input_abs_get_max(dev, cnt) <= input_abs_get_min(dev, cnt)) { |
310 | printk(KERN_DEBUG | 308 | printk(KERN_DEBUG |
311 | "%s: invalid abs[%02x] min:%d max:%d\n", | 309 | "%s: invalid abs[%02x] min:%d max:%d\n", |
312 | UINPUT_NAME, cnt, | 310 | UINPUT_NAME, cnt, |
313 | dev->absmin[cnt], dev->absmax[cnt]); | 311 | input_abs_get_min(dev, cnt), |
312 | input_abs_get_max(dev, cnt)); | ||
314 | retval = -EINVAL; | 313 | retval = -EINVAL; |
315 | break; | 314 | break; |
316 | } | 315 | } |
317 | 316 | ||
318 | 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)) { | ||
319 | printk(KERN_DEBUG | 319 | printk(KERN_DEBUG |
320 | "%s: absflat[%02x] out of range: %d " | 320 | "%s: abs_flat #%02x out of range: %d " |
321 | "(min:%d/max:%d)\n", | 321 | "(min:%d/max:%d)\n", |
322 | UINPUT_NAME, cnt, dev->absflat[cnt], | 322 | UINPUT_NAME, cnt, |
323 | 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)); | ||
324 | retval = -EINVAL; | 326 | retval = -EINVAL; |
325 | break; | 327 | break; |
326 | } | 328 | } |
@@ -345,7 +347,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
345 | struct uinput_user_dev *user_dev; | 347 | struct uinput_user_dev *user_dev; |
346 | struct input_dev *dev; | 348 | struct input_dev *dev; |
347 | char *name; | 349 | char *name; |
348 | int size; | 350 | int i, size; |
349 | int retval; | 351 | int retval; |
350 | 352 | ||
351 | if (count != sizeof(struct uinput_user_dev)) | 353 | if (count != sizeof(struct uinput_user_dev)) |
@@ -389,11 +391,12 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
389 | dev->id.product = user_dev->id.product; | 391 | dev->id.product = user_dev->id.product; |
390 | dev->id.version = user_dev->id.version; | 392 | dev->id.version = user_dev->id.version; |
391 | 393 | ||
392 | size = sizeof(int) * (ABS_MAX + 1); | 394 | for (i = 0; i < ABS_CNT; i++) { |
393 | memcpy(dev->absmax, user_dev->absmax, size); | 395 | input_abs_set_max(dev, i, user_dev->absmax[i]); |
394 | memcpy(dev->absmin, user_dev->absmin, size); | 396 | input_abs_set_min(dev, i, user_dev->absmin[i]); |
395 | memcpy(dev->absfuzz, user_dev->absfuzz, size); | 397 | input_abs_set_fuzz(dev, i, user_dev->absfuzz[i]); |
396 | memcpy(dev->absflat, user_dev->absflat, size); | 398 | input_abs_set_flat(dev, i, user_dev->absflat[i]); |
399 | } | ||
397 | 400 | ||
398 | /* check if absmin/absmax/absfuzz/absflat are filled as | 401 | /* check if absmin/absmax/absfuzz/absflat are filled as |
399 | * told in Documentation/input/input-programming.txt */ | 402 | * told in Documentation/input/input-programming.txt */ |
@@ -401,6 +404,13 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
401 | retval = uinput_validate_absbits(dev); | 404 | retval = uinput_validate_absbits(dev); |
402 | if (retval < 0) | 405 | if (retval < 0) |
403 | goto exit; | 406 | goto exit; |
407 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { | ||
408 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; | ||
409 | input_mt_create_slots(dev, nslot); | ||
410 | input_set_events_per_packet(dev, 6 * nslot); | ||
411 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { | ||
412 | input_set_events_per_packet(dev, 60); | ||
413 | } | ||
404 | } | 414 | } |
405 | 415 | ||
406 | udev->state = UIST_SETUP_COMPLETE; | 416 | udev->state = UIST_SETUP_COMPLETE; |
@@ -801,6 +811,7 @@ static const struct file_operations uinput_fops = { | |||
801 | #ifdef CONFIG_COMPAT | 811 | #ifdef CONFIG_COMPAT |
802 | .compat_ioctl = uinput_compat_ioctl, | 812 | .compat_ioctl = uinput_compat_ioctl, |
803 | #endif | 813 | #endif |
814 | .llseek = no_llseek, | ||
804 | }; | 815 | }; |
805 | 816 | ||
806 | static struct miscdevice uinput_misc = { | 817 | static struct miscdevice uinput_misc = { |
@@ -808,6 +819,8 @@ static struct miscdevice uinput_misc = { | |||
808 | .minor = UINPUT_MINOR, | 819 | .minor = UINPUT_MINOR, |
809 | .name = UINPUT_NAME, | 820 | .name = UINPUT_NAME, |
810 | }; | 821 | }; |
822 | MODULE_ALIAS_MISCDEV(UINPUT_MINOR); | ||
823 | MODULE_ALIAS("devname:" UINPUT_NAME); | ||
811 | 824 | ||
812 | static int __init uinput_init(void) | 825 | static int __init uinput_init(void) |
813 | { | 826 | { |
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c index c8f5a9a3fa14..64f1de7960c6 100644 --- a/drivers/input/misc/winbond-cir.c +++ b/drivers/input/misc/winbond-cir.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/io.h> | 56 | #include <linux/io.h> |
57 | #include <linux/bitrev.h> | 57 | #include <linux/bitrev.h> |
58 | #include <linux/bitops.h> | 58 | #include <linux/bitops.h> |
59 | #include <linux/slab.h> | ||
59 | 60 | ||
60 | #define DRVNAME "winbond-cir" | 61 | #define DRVNAME "winbond-cir" |
61 | 62 | ||
@@ -385,26 +386,24 @@ wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode) | |||
385 | } | 386 | } |
386 | 387 | ||
387 | static int | 388 | static int |
388 | wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 389 | wbcir_getkeycode(struct input_dev *dev, |
390 | unsigned int scancode, unsigned int *keycode) | ||
389 | { | 391 | { |
390 | struct wbcir_data *data = input_get_drvdata(dev); | 392 | struct wbcir_data *data = input_get_drvdata(dev); |
391 | 393 | ||
392 | *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode); | 394 | *keycode = wbcir_do_getkeycode(data, scancode); |
393 | return 0; | 395 | return 0; |
394 | } | 396 | } |
395 | 397 | ||
396 | static int | 398 | static int |
397 | wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode) | 399 | wbcir_setkeycode(struct input_dev *dev, |
400 | unsigned int scancode, unsigned int keycode) | ||
398 | { | 401 | { |
399 | struct wbcir_data *data = input_get_drvdata(dev); | 402 | struct wbcir_data *data = input_get_drvdata(dev); |
400 | struct wbcir_keyentry *keyentry; | 403 | struct wbcir_keyentry *keyentry; |
401 | struct wbcir_keyentry *new_keyentry; | 404 | struct wbcir_keyentry *new_keyentry; |
402 | unsigned long flags; | 405 | unsigned long flags; |
403 | unsigned int old_keycode = KEY_RESERVED; | 406 | unsigned int old_keycode = KEY_RESERVED; |
404 | u32 scancode = (u32)sscancode; | ||
405 | |||
406 | if (keycode < 0 || keycode > KEY_MAX) | ||
407 | return -EINVAL; | ||
408 | 407 | ||
409 | new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); | 408 | new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); |
410 | if (!new_keyentry) | 409 | if (!new_keyentry) |
@@ -538,6 +537,7 @@ wbcir_reset_irdata(struct wbcir_data *data) | |||
538 | data->irdata_count = 0; | 537 | data->irdata_count = 0; |
539 | data->irdata_off = 0; | 538 | data->irdata_off = 0; |
540 | data->irdata_error = 0; | 539 | data->irdata_error = 0; |
540 | data->idle_count = 0; | ||
541 | } | 541 | } |
542 | 542 | ||
543 | /* Adds one bit of irdata */ | 543 | /* Adds one bit of irdata */ |
@@ -1006,7 +1006,6 @@ wbcir_irq_handler(int irqno, void *cookie) | |||
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | wbcir_reset_irdata(data); | 1008 | wbcir_reset_irdata(data); |
1009 | data->idle_count = 0; | ||
1010 | } | 1009 | } |
1011 | 1010 | ||
1012 | out: | 1011 | out: |
@@ -1018,7 +1017,7 @@ out: | |||
1018 | 1017 | ||
1019 | /***************************************************************************** | 1018 | /***************************************************************************** |
1020 | * | 1019 | * |
1021 | * SUSPEND/RESUME FUNCTIONS | 1020 | * SETUP/INIT/SUSPEND/RESUME FUNCTIONS |
1022 | * | 1021 | * |
1023 | *****************************************************************************/ | 1022 | *****************************************************************************/ |
1024 | 1023 | ||
@@ -1197,7 +1196,16 @@ finish: | |||
1197 | } | 1196 | } |
1198 | 1197 | ||
1199 | /* Disable interrupts */ | 1198 | /* Disable interrupts */ |
1199 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1200 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | 1200 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); |
1201 | |||
1202 | /* | ||
1203 | * ACPI will set the HW disable bit for SP3 which means that the | ||
1204 | * output signals are left in an undefined state which may cause | ||
1205 | * spurious interrupts which we need to ignore until the hardware | ||
1206 | * is reinitialized. | ||
1207 | */ | ||
1208 | disable_irq(data->irq); | ||
1201 | } | 1209 | } |
1202 | 1210 | ||
1203 | static int | 1211 | static int |
@@ -1207,37 +1215,15 @@ wbcir_suspend(struct pnp_dev *device, pm_message_t state) | |||
1207 | return 0; | 1215 | return 0; |
1208 | } | 1216 | } |
1209 | 1217 | ||
1210 | static int | ||
1211 | wbcir_resume(struct pnp_dev *device) | ||
1212 | { | ||
1213 | struct wbcir_data *data = pnp_get_drvdata(device); | ||
1214 | |||
1215 | /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ | ||
1216 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); | ||
1217 | |||
1218 | /* Clear CEIR_EN */ | ||
1219 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); | ||
1220 | |||
1221 | /* Enable interrupts */ | ||
1222 | wbcir_reset_irdata(data); | ||
1223 | outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); | ||
1224 | |||
1225 | return 0; | ||
1226 | } | ||
1227 | |||
1228 | |||
1229 | |||
1230 | /***************************************************************************** | ||
1231 | * | ||
1232 | * SETUP/INIT FUNCTIONS | ||
1233 | * | ||
1234 | *****************************************************************************/ | ||
1235 | |||
1236 | static void | 1218 | static void |
1237 | wbcir_cfg_ceir(struct wbcir_data *data) | 1219 | wbcir_init_hw(struct wbcir_data *data) |
1238 | { | 1220 | { |
1239 | u8 tmp; | 1221 | u8 tmp; |
1240 | 1222 | ||
1223 | /* Disable interrupts */ | ||
1224 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1225 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | ||
1226 | |||
1241 | /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ | 1227 | /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ |
1242 | tmp = protocol << 4; | 1228 | tmp = protocol << 4; |
1243 | if (invert) | 1229 | if (invert) |
@@ -1264,6 +1250,93 @@ wbcir_cfg_ceir(struct wbcir_data *data) | |||
1264 | * set SP3_IRRX_SW to binary 01, helpfully not documented | 1250 | * set SP3_IRRX_SW to binary 01, helpfully not documented |
1265 | */ | 1251 | */ |
1266 | outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); | 1252 | outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); |
1253 | |||
1254 | /* Enable extended mode */ | ||
1255 | wbcir_select_bank(data, WBCIR_BANK_2); | ||
1256 | outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1); | ||
1257 | |||
1258 | /* | ||
1259 | * Configure baud generator, IR data will be sampled at | ||
1260 | * a bitrate of: (24Mhz * prescaler) / (divisor * 16). | ||
1261 | * | ||
1262 | * The ECIR registers include a flag to change the | ||
1263 | * 24Mhz clock freq to 48Mhz. | ||
1264 | * | ||
1265 | * It's not documented in the specs, but fifo levels | ||
1266 | * other than 16 seems to be unsupported. | ||
1267 | */ | ||
1268 | |||
1269 | /* prescaler 1.0, tx/rx fifo lvl 16 */ | ||
1270 | outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); | ||
1271 | |||
1272 | /* Set baud divisor to generate one byte per bit/cell */ | ||
1273 | switch (protocol) { | ||
1274 | case IR_PROTOCOL_RC5: | ||
1275 | outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1276 | break; | ||
1277 | case IR_PROTOCOL_RC6: | ||
1278 | outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1279 | break; | ||
1280 | case IR_PROTOCOL_NEC: | ||
1281 | outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1282 | break; | ||
1283 | } | ||
1284 | outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); | ||
1285 | |||
1286 | /* Set CEIR mode */ | ||
1287 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1288 | outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR); | ||
1289 | inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */ | ||
1290 | inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */ | ||
1291 | |||
1292 | /* Disable RX demod, run-length encoding/decoding, set freq span */ | ||
1293 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1294 | outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG); | ||
1295 | |||
1296 | /* Disable timer */ | ||
1297 | wbcir_select_bank(data, WBCIR_BANK_4); | ||
1298 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); | ||
1299 | |||
1300 | /* Enable MSR interrupt, Clear AUX_IRX */ | ||
1301 | wbcir_select_bank(data, WBCIR_BANK_5); | ||
1302 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); | ||
1303 | |||
1304 | /* Disable CRC */ | ||
1305 | wbcir_select_bank(data, WBCIR_BANK_6); | ||
1306 | outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); | ||
1307 | |||
1308 | /* Set RX/TX (de)modulation freq, not really used */ | ||
1309 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1310 | outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); | ||
1311 | outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); | ||
1312 | |||
1313 | /* Set invert and pin direction */ | ||
1314 | if (invert) | ||
1315 | outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1316 | else | ||
1317 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1318 | |||
1319 | /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ | ||
1320 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1321 | outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); | ||
1322 | |||
1323 | /* Clear AUX status bits */ | ||
1324 | outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); | ||
1325 | |||
1326 | /* Enable interrupts */ | ||
1327 | wbcir_reset_irdata(data); | ||
1328 | outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); | ||
1329 | } | ||
1330 | |||
1331 | static int | ||
1332 | wbcir_resume(struct pnp_dev *device) | ||
1333 | { | ||
1334 | struct wbcir_data *data = pnp_get_drvdata(device); | ||
1335 | |||
1336 | wbcir_init_hw(data); | ||
1337 | enable_irq(data->irq); | ||
1338 | |||
1339 | return 0; | ||
1267 | } | 1340 | } |
1268 | 1341 | ||
1269 | static int __devinit | 1342 | static int __devinit |
@@ -1393,86 +1466,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) | |||
1393 | 1466 | ||
1394 | device_init_wakeup(&device->dev, 1); | 1467 | device_init_wakeup(&device->dev, 1); |
1395 | 1468 | ||
1396 | wbcir_cfg_ceir(data); | 1469 | wbcir_init_hw(data); |
1397 | |||
1398 | /* Disable interrupts */ | ||
1399 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1400 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | ||
1401 | |||
1402 | /* Enable extended mode */ | ||
1403 | wbcir_select_bank(data, WBCIR_BANK_2); | ||
1404 | outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1); | ||
1405 | |||
1406 | /* | ||
1407 | * Configure baud generator, IR data will be sampled at | ||
1408 | * a bitrate of: (24Mhz * prescaler) / (divisor * 16). | ||
1409 | * | ||
1410 | * The ECIR registers include a flag to change the | ||
1411 | * 24Mhz clock freq to 48Mhz. | ||
1412 | * | ||
1413 | * It's not documented in the specs, but fifo levels | ||
1414 | * other than 16 seems to be unsupported. | ||
1415 | */ | ||
1416 | |||
1417 | /* prescaler 1.0, tx/rx fifo lvl 16 */ | ||
1418 | outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); | ||
1419 | |||
1420 | /* Set baud divisor to generate one byte per bit/cell */ | ||
1421 | switch (protocol) { | ||
1422 | case IR_PROTOCOL_RC5: | ||
1423 | outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1424 | break; | ||
1425 | case IR_PROTOCOL_RC6: | ||
1426 | outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1427 | break; | ||
1428 | case IR_PROTOCOL_NEC: | ||
1429 | outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1430 | break; | ||
1431 | } | ||
1432 | outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); | ||
1433 | |||
1434 | /* Set CEIR mode */ | ||
1435 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1436 | outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR); | ||
1437 | inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */ | ||
1438 | inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */ | ||
1439 | |||
1440 | /* Disable RX demod, run-length encoding/decoding, set freq span */ | ||
1441 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1442 | outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG); | ||
1443 | |||
1444 | /* Disable timer */ | ||
1445 | wbcir_select_bank(data, WBCIR_BANK_4); | ||
1446 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); | ||
1447 | |||
1448 | /* Enable MSR interrupt, Clear AUX_IRX */ | ||
1449 | wbcir_select_bank(data, WBCIR_BANK_5); | ||
1450 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); | ||
1451 | |||
1452 | /* Disable CRC */ | ||
1453 | wbcir_select_bank(data, WBCIR_BANK_6); | ||
1454 | outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); | ||
1455 | |||
1456 | /* Set RX/TX (de)modulation freq, not really used */ | ||
1457 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1458 | outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); | ||
1459 | outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); | ||
1460 | |||
1461 | /* Set invert and pin direction */ | ||
1462 | if (invert) | ||
1463 | outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1464 | else | ||
1465 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1466 | |||
1467 | /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ | ||
1468 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1469 | outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); | ||
1470 | |||
1471 | /* Clear AUX status bits */ | ||
1472 | outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); | ||
1473 | |||
1474 | /* Enable interrupts */ | ||
1475 | outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); | ||
1476 | 1470 | ||
1477 | return 0; | 1471 | return 0; |
1478 | 1472 | ||
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index c0afb71a3a6d..12501de0c5cd 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/preempt.h> | 30 | #include <linux/preempt.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/slab.h> | ||
32 | #include <linux/types.h> | 33 | #include <linux/types.h> |
33 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
34 | #include <linux/leds.h> | 35 | #include <linux/leds.h> |
@@ -982,11 +983,11 @@ static int __init copy_keymap(void) | |||
982 | for (key = keymap; key->type != KE_END; key++) | 983 | for (key = keymap; key->type != KE_END; key++) |
983 | length++; | 984 | length++; |
984 | 985 | ||
985 | new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL); | 986 | new_keymap = kmemdup(keymap, length * sizeof(struct key_entry), |
987 | GFP_KERNEL); | ||
986 | if (!new_keymap) | 988 | if (!new_keymap) |
987 | return -ENOMEM; | 989 | return -ENOMEM; |
988 | 990 | ||
989 | memcpy(new_keymap, keymap, length * sizeof(struct key_entry)); | ||
990 | keymap = new_keymap; | 991 | keymap = new_keymap; |
991 | 992 | ||
992 | return 0; | 993 | return 0; |
@@ -1346,7 +1347,7 @@ static int __init wb_module_init(void) | |||
1346 | 1347 | ||
1347 | err = map_bios(); | 1348 | err = map_bios(); |
1348 | if (err) | 1349 | if (err) |
1349 | return err; | 1350 | goto err_free_keymap; |
1350 | 1351 | ||
1351 | err = platform_driver_register(&wistron_driver); | 1352 | err = platform_driver_register(&wistron_driver); |
1352 | if (err) | 1353 | if (err) |
@@ -1370,6 +1371,8 @@ static int __init wb_module_init(void) | |||
1370 | platform_driver_unregister(&wistron_driver); | 1371 | platform_driver_unregister(&wistron_driver); |
1371 | err_unmap_bios: | 1372 | err_unmap_bios: |
1372 | unmap_bios(); | 1373 | unmap_bios(); |
1374 | err_free_keymap: | ||
1375 | kfree(keymap); | ||
1373 | 1376 | ||
1374 | return err; | 1377 | return err; |
1375 | } | 1378 | } |
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index ba4f5dd7c60e..c3d7ba5f5b47 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/slab.h> | ||
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
23 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
24 | #include <linux/input.h> | 25 | #include <linux/input.h> |
@@ -97,8 +98,9 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) | |||
97 | wm831x_on->dev->phys = "wm831x_on/input0"; | 98 | wm831x_on->dev->phys = "wm831x_on/input0"; |
98 | wm831x_on->dev->dev.parent = &pdev->dev; | 99 | wm831x_on->dev->dev.parent = &pdev->dev; |
99 | 100 | ||
100 | ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq, | 101 | ret = request_threaded_irq(irq, NULL, wm831x_on_irq, |
101 | IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on); | 102 | IRQF_TRIGGER_RISING, "wm831x_on", |
103 | wm831x_on); | ||
102 | if (ret < 0) { | 104 | if (ret < 0) { |
103 | dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret); | 105 | dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret); |
104 | goto err_input_dev; | 106 | goto err_input_dev; |
@@ -114,7 +116,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) | |||
114 | return 0; | 116 | return 0; |
115 | 117 | ||
116 | err_irq: | 118 | err_irq: |
117 | wm831x_free_irq(wm831x, irq, NULL); | 119 | free_irq(irq, wm831x_on); |
118 | err_input_dev: | 120 | err_input_dev: |
119 | input_free_device(wm831x_on->dev); | 121 | input_free_device(wm831x_on->dev); |
120 | err: | 122 | err: |
@@ -127,7 +129,7 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev) | |||
127 | struct wm831x_on *wm831x_on = platform_get_drvdata(pdev); | 129 | struct wm831x_on *wm831x_on = platform_get_drvdata(pdev); |
128 | int irq = platform_get_irq(pdev, 0); | 130 | int irq = platform_get_irq(pdev, 0); |
129 | 131 | ||
130 | wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on); | 132 | free_irq(irq, wm831x_on); |
131 | cancel_delayed_work_sync(&wm831x_on->work); | 133 | cancel_delayed_work_sync(&wm831x_on->work); |
132 | input_unregister_device(wm831x_on->dev); | 134 | input_unregister_device(wm831x_on->dev); |
133 | kfree(wm831x_on); | 135 | kfree(wm831x_on); |
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c index 93a22ac0f88c..41201c6b5e68 100644 --- a/drivers/input/misc/yealink.c +++ b/drivers/input/misc/yealink.c | |||
@@ -111,7 +111,6 @@ struct yealink_dev { | |||
111 | struct yld_ctl_packet *ctl_data; | 111 | struct yld_ctl_packet *ctl_data; |
112 | dma_addr_t ctl_dma; | 112 | dma_addr_t ctl_dma; |
113 | struct usb_ctrlrequest *ctl_req; | 113 | struct usb_ctrlrequest *ctl_req; |
114 | dma_addr_t ctl_req_dma; | ||
115 | struct urb *urb_ctl; | 114 | struct urb *urb_ctl; |
116 | 115 | ||
117 | char phys[64]; /* physical device path */ | 116 | char phys[64]; /* physical device path */ |
@@ -836,12 +835,9 @@ static int usb_cleanup(struct yealink_dev *yld, int err) | |||
836 | usb_free_urb(yld->urb_irq); | 835 | usb_free_urb(yld->urb_irq); |
837 | usb_free_urb(yld->urb_ctl); | 836 | usb_free_urb(yld->urb_ctl); |
838 | 837 | ||
839 | usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)), | 838 | kfree(yld->ctl_req); |
840 | yld->ctl_req, yld->ctl_req_dma); | 839 | usb_free_coherent(yld->udev, USB_PKT_LEN, yld->ctl_data, yld->ctl_dma); |
841 | usb_buffer_free(yld->udev, USB_PKT_LEN, | 840 | usb_free_coherent(yld->udev, USB_PKT_LEN, yld->irq_data, yld->irq_dma); |
842 | yld->ctl_data, yld->ctl_dma); | ||
843 | usb_buffer_free(yld->udev, USB_PKT_LEN, | ||
844 | yld->irq_data, yld->irq_dma); | ||
845 | 841 | ||
846 | kfree(yld); | 842 | kfree(yld); |
847 | return err; | 843 | return err; |
@@ -886,18 +882,17 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
886 | return usb_cleanup(yld, -ENOMEM); | 882 | return usb_cleanup(yld, -ENOMEM); |
887 | 883 | ||
888 | /* allocate usb buffers */ | 884 | /* allocate usb buffers */ |
889 | yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN, | 885 | yld->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN, |
890 | GFP_ATOMIC, &yld->irq_dma); | 886 | GFP_ATOMIC, &yld->irq_dma); |
891 | if (yld->irq_data == NULL) | 887 | if (yld->irq_data == NULL) |
892 | return usb_cleanup(yld, -ENOMEM); | 888 | return usb_cleanup(yld, -ENOMEM); |
893 | 889 | ||
894 | yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN, | 890 | yld->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN, |
895 | GFP_ATOMIC, &yld->ctl_dma); | 891 | GFP_ATOMIC, &yld->ctl_dma); |
896 | if (!yld->ctl_data) | 892 | if (!yld->ctl_data) |
897 | return usb_cleanup(yld, -ENOMEM); | 893 | return usb_cleanup(yld, -ENOMEM); |
898 | 894 | ||
899 | yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)), | 895 | yld->ctl_req = kmalloc(sizeof(*(yld->ctl_req)), GFP_KERNEL); |
900 | GFP_ATOMIC, &yld->ctl_req_dma); | ||
901 | if (yld->ctl_req == NULL) | 896 | if (yld->ctl_req == NULL) |
902 | return usb_cleanup(yld, -ENOMEM); | 897 | return usb_cleanup(yld, -ENOMEM); |
903 | 898 | ||
@@ -936,10 +931,8 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
936 | usb_fill_control_urb(yld->urb_ctl, udev, usb_sndctrlpipe(udev, 0), | 931 | usb_fill_control_urb(yld->urb_ctl, udev, usb_sndctrlpipe(udev, 0), |
937 | (void *)yld->ctl_req, yld->ctl_data, USB_PKT_LEN, | 932 | (void *)yld->ctl_req, yld->ctl_data, USB_PKT_LEN, |
938 | urb_ctl_callback, yld); | 933 | urb_ctl_callback, yld); |
939 | yld->urb_ctl->setup_dma = yld->ctl_req_dma; | ||
940 | yld->urb_ctl->transfer_dma = yld->ctl_dma; | 934 | yld->urb_ctl->transfer_dma = yld->ctl_dma; |
941 | yld->urb_ctl->transfer_flags |= URB_NO_SETUP_DMA_MAP | | 935 | yld->urb_ctl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
942 | URB_NO_TRANSFER_DMA_MAP; | ||
943 | yld->urb_ctl->dev = udev; | 936 | yld->urb_ctl->dev = udev; |
944 | 937 | ||
945 | /* find out the physical bus location */ | 938 | /* find out the physical bus location */ |
diff --git a/drivers/input/misc/yealink.h b/drivers/input/misc/yealink.h index 48af0be9cbdf..1e0f52397010 100644 --- a/drivers/input/misc/yealink.h +++ b/drivers/input/misc/yealink.h | |||
@@ -127,7 +127,7 @@ struct yld_ctl_packet { | |||
127 | * yld_status struct. | 127 | * yld_status struct. |
128 | */ | 128 | */ |
129 | 129 | ||
130 | /* LCD, each segment must be driven seperately. | 130 | /* LCD, each segment must be driven separately. |
131 | * | 131 | * |
132 | * Layout: | 132 | * Layout: |
133 | * | 133 | * |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index c714ca2407f8..bf5fd7f6a313 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -30,6 +30,7 @@ config MOUSE_PS2 | |||
30 | <http://w1.894.telia.com/~u89404340/touchpad/index.html> | 30 | <http://w1.894.telia.com/~u89404340/touchpad/index.html> |
31 | and a new version of GPM at: | 31 | and a new version of GPM at: |
32 | <http://www.geocities.com/dt_or/gpm/gpm.html> | 32 | <http://www.geocities.com/dt_or/gpm/gpm.html> |
33 | <http://xorg.freedesktop.org/archive/individual/driver/> | ||
33 | to take advantage of the advanced features of the touchpad. | 34 | to take advantage of the advanced features of the touchpad. |
34 | 35 | ||
35 | If unsure, say Y. | 36 | If unsure, say Y. |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f93c2c0daf1f..99d58764ef03 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * the Free Software Foundation. | 15 | * the Free Software Foundation. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/slab.h> | ||
18 | #include <linux/input.h> | 19 | #include <linux/input.h> |
19 | #include <linux/serio.h> | 20 | #include <linux/serio.h> |
20 | #include <linux/libps2.h> | 21 | #include <linux/libps2.h> |
@@ -63,6 +64,8 @@ static const struct alps_model_info alps_model_data[] = { | |||
63 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, | 64 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, |
64 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, | 65 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, |
65 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ | 66 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ |
67 | { { 0x52, 0x01, 0x14 }, 0xff, 0xff, | ||
68 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ | ||
66 | }; | 69 | }; |
67 | 70 | ||
68 | /* | 71 | /* |
@@ -118,40 +121,27 @@ static void alps_report_buttons(struct psmouse *psmouse, | |||
118 | struct input_dev *dev1, struct input_dev *dev2, | 121 | struct input_dev *dev1, struct input_dev *dev2, |
119 | int left, int right, int middle) | 122 | int left, int right, int middle) |
120 | { | 123 | { |
121 | struct alps_data *priv = psmouse->private; | 124 | struct input_dev *dev; |
122 | const struct alps_model_info *model = priv->i; | ||
123 | |||
124 | if (model->flags & ALPS_PS2_INTERLEAVED) { | ||
125 | struct input_dev *dev; | ||
126 | 125 | ||
127 | /* | 126 | /* |
128 | * If shared button has already been reported on the | 127 | * If shared button has already been reported on the |
129 | * other device (dev2) then this event should be also | 128 | * other device (dev2) then this event should be also |
130 | * sent through that device. | 129 | * sent through that device. |
131 | */ | 130 | */ |
132 | dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; | 131 | dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; |
133 | input_report_key(dev, BTN_LEFT, left); | 132 | input_report_key(dev, BTN_LEFT, left); |
134 | 133 | ||
135 | dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; | 134 | dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; |
136 | input_report_key(dev, BTN_RIGHT, right); | 135 | input_report_key(dev, BTN_RIGHT, right); |
137 | 136 | ||
138 | dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; | 137 | dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; |
139 | input_report_key(dev, BTN_MIDDLE, middle); | 138 | input_report_key(dev, BTN_MIDDLE, middle); |
140 | 139 | ||
141 | /* | 140 | /* |
142 | * Sync the _other_ device now, we'll do the first | 141 | * Sync the _other_ device now, we'll do the first |
143 | * device later once we report the rest of the events. | 142 | * device later once we report the rest of the events. |
144 | */ | 143 | */ |
145 | input_sync(dev2); | 144 | input_sync(dev2); |
146 | } else { | ||
147 | /* | ||
148 | * For devices with non-interleaved packets we know what | ||
149 | * device buttons belong to so we can simply report them. | ||
150 | */ | ||
151 | input_report_key(dev1, BTN_LEFT, left); | ||
152 | input_report_key(dev1, BTN_RIGHT, right); | ||
153 | input_report_key(dev1, BTN_MIDDLE, middle); | ||
154 | } | ||
155 | } | 145 | } |
156 | 146 | ||
157 | static void alps_process_packet(struct psmouse *psmouse) | 147 | static void alps_process_packet(struct psmouse *psmouse) |
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index a185ac78a42c..ff5f61a0fd3a 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/input.h> | 22 | #include <linux/input.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/platform_device.h> | ||
24 | 25 | ||
25 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
26 | #include <asm/setup.h> | 27 | #include <asm/setup.h> |
@@ -34,10 +35,10 @@ MODULE_DESCRIPTION("Amiga mouse driver"); | |||
34 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
35 | 36 | ||
36 | static int amimouse_lastx, amimouse_lasty; | 37 | static int amimouse_lastx, amimouse_lasty; |
37 | static struct input_dev *amimouse_dev; | ||
38 | 38 | ||
39 | static irqreturn_t amimouse_interrupt(int irq, void *dummy) | 39 | static irqreturn_t amimouse_interrupt(int irq, void *data) |
40 | { | 40 | { |
41 | struct input_dev *dev = data; | ||
41 | unsigned short joy0dat, potgor; | 42 | unsigned short joy0dat, potgor; |
42 | int nx, ny, dx, dy; | 43 | int nx, ny, dx, dy; |
43 | 44 | ||
@@ -59,14 +60,14 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy) | |||
59 | 60 | ||
60 | potgor = amiga_custom.potgor; | 61 | potgor = amiga_custom.potgor; |
61 | 62 | ||
62 | input_report_rel(amimouse_dev, REL_X, dx); | 63 | input_report_rel(dev, REL_X, dx); |
63 | input_report_rel(amimouse_dev, REL_Y, dy); | 64 | input_report_rel(dev, REL_Y, dy); |
64 | 65 | ||
65 | input_report_key(amimouse_dev, BTN_LEFT, ciaa.pra & 0x40); | 66 | input_report_key(dev, BTN_LEFT, ciaa.pra & 0x40); |
66 | input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100); | 67 | input_report_key(dev, BTN_MIDDLE, potgor & 0x0100); |
67 | input_report_key(amimouse_dev, BTN_RIGHT, potgor & 0x0400); | 68 | input_report_key(dev, BTN_RIGHT, potgor & 0x0400); |
68 | 69 | ||
69 | input_sync(amimouse_dev); | 70 | input_sync(dev); |
70 | 71 | ||
71 | return IRQ_HANDLED; | 72 | return IRQ_HANDLED; |
72 | } | 73 | } |
@@ -74,63 +75,90 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy) | |||
74 | static int amimouse_open(struct input_dev *dev) | 75 | static int amimouse_open(struct input_dev *dev) |
75 | { | 76 | { |
76 | unsigned short joy0dat; | 77 | unsigned short joy0dat; |
78 | int error; | ||
77 | 79 | ||
78 | joy0dat = amiga_custom.joy0dat; | 80 | joy0dat = amiga_custom.joy0dat; |
79 | 81 | ||
80 | amimouse_lastx = joy0dat & 0xff; | 82 | amimouse_lastx = joy0dat & 0xff; |
81 | amimouse_lasty = joy0dat >> 8; | 83 | amimouse_lasty = joy0dat >> 8; |
82 | 84 | ||
83 | if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) { | 85 | error = request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", |
84 | printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB); | 86 | dev); |
85 | return -EBUSY; | 87 | if (error) |
86 | } | 88 | dev_err(&dev->dev, "Can't allocate irq %d\n", IRQ_AMIGA_VERTB); |
87 | 89 | ||
88 | return 0; | 90 | return error; |
89 | } | 91 | } |
90 | 92 | ||
91 | static void amimouse_close(struct input_dev *dev) | 93 | static void amimouse_close(struct input_dev *dev) |
92 | { | 94 | { |
93 | free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt); | 95 | free_irq(IRQ_AMIGA_VERTB, dev); |
94 | } | 96 | } |
95 | 97 | ||
96 | static int __init amimouse_init(void) | 98 | static int __init amimouse_probe(struct platform_device *pdev) |
97 | { | 99 | { |
98 | int err; | 100 | int err; |
101 | struct input_dev *dev; | ||
99 | 102 | ||
100 | if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) | 103 | dev = input_allocate_device(); |
101 | return -ENODEV; | 104 | if (!dev) |
102 | |||
103 | amimouse_dev = input_allocate_device(); | ||
104 | if (!amimouse_dev) | ||
105 | return -ENOMEM; | 105 | return -ENOMEM; |
106 | 106 | ||
107 | amimouse_dev->name = "Amiga mouse"; | 107 | dev->name = pdev->name; |
108 | amimouse_dev->phys = "amimouse/input0"; | 108 | dev->phys = "amimouse/input0"; |
109 | amimouse_dev->id.bustype = BUS_AMIGA; | 109 | dev->id.bustype = BUS_AMIGA; |
110 | amimouse_dev->id.vendor = 0x0001; | 110 | dev->id.vendor = 0x0001; |
111 | amimouse_dev->id.product = 0x0002; | 111 | dev->id.product = 0x0002; |
112 | amimouse_dev->id.version = 0x0100; | 112 | dev->id.version = 0x0100; |
113 | 113 | ||
114 | amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 114 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
115 | amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 115 | dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); |
116 | amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | | 116 | dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | |
117 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 117 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); |
118 | amimouse_dev->open = amimouse_open; | 118 | dev->open = amimouse_open; |
119 | amimouse_dev->close = amimouse_close; | 119 | dev->close = amimouse_close; |
120 | dev->dev.parent = &pdev->dev; | ||
120 | 121 | ||
121 | err = input_register_device(amimouse_dev); | 122 | err = input_register_device(dev); |
122 | if (err) { | 123 | if (err) { |
123 | input_free_device(amimouse_dev); | 124 | input_free_device(dev); |
124 | return err; | 125 | return err; |
125 | } | 126 | } |
126 | 127 | ||
128 | platform_set_drvdata(pdev, dev); | ||
129 | |||
127 | return 0; | 130 | return 0; |
128 | } | 131 | } |
129 | 132 | ||
130 | static void __exit amimouse_exit(void) | 133 | static int __exit amimouse_remove(struct platform_device *pdev) |
131 | { | 134 | { |
132 | input_unregister_device(amimouse_dev); | 135 | struct input_dev *dev = platform_get_drvdata(pdev); |
136 | |||
137 | platform_set_drvdata(pdev, NULL); | ||
138 | input_unregister_device(dev); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static struct platform_driver amimouse_driver = { | ||
143 | .remove = __exit_p(amimouse_remove), | ||
144 | .driver = { | ||
145 | .name = "amiga-mouse", | ||
146 | .owner = THIS_MODULE, | ||
147 | }, | ||
148 | }; | ||
149 | |||
150 | static int __init amimouse_init(void) | ||
151 | { | ||
152 | return platform_driver_probe(&amimouse_driver, amimouse_probe); | ||
133 | } | 153 | } |
134 | 154 | ||
135 | module_init(amimouse_init); | 155 | module_init(amimouse_init); |
156 | |||
157 | static void __exit amimouse_exit(void) | ||
158 | { | ||
159 | platform_driver_unregister(&amimouse_driver); | ||
160 | } | ||
161 | |||
136 | module_exit(amimouse_exit); | 162 | module_exit(amimouse_exit); |
163 | |||
164 | MODULE_ALIAS("platform:amiga-mouse"); | ||
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 908b5b44052f..a9cf76831634 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -806,8 +806,8 @@ static int atp_probe(struct usb_interface *iface, | |||
806 | if (!dev->urb) | 806 | if (!dev->urb) |
807 | goto err_free_devs; | 807 | goto err_free_devs; |
808 | 808 | ||
809 | dev->data = usb_buffer_alloc(dev->udev, dev->info->datalen, GFP_KERNEL, | 809 | dev->data = usb_alloc_coherent(dev->udev, dev->info->datalen, GFP_KERNEL, |
810 | &dev->urb->transfer_dma); | 810 | &dev->urb->transfer_dma); |
811 | if (!dev->data) | 811 | if (!dev->data) |
812 | goto err_free_urb; | 812 | goto err_free_urb; |
813 | 813 | ||
@@ -862,8 +862,8 @@ static int atp_probe(struct usb_interface *iface, | |||
862 | return 0; | 862 | return 0; |
863 | 863 | ||
864 | err_free_buffer: | 864 | err_free_buffer: |
865 | usb_buffer_free(dev->udev, dev->info->datalen, | 865 | usb_free_coherent(dev->udev, dev->info->datalen, |
866 | dev->data, dev->urb->transfer_dma); | 866 | dev->data, dev->urb->transfer_dma); |
867 | err_free_urb: | 867 | err_free_urb: |
868 | usb_free_urb(dev->urb); | 868 | usb_free_urb(dev->urb); |
869 | err_free_devs: | 869 | err_free_devs: |
@@ -881,8 +881,8 @@ static void atp_disconnect(struct usb_interface *iface) | |||
881 | if (dev) { | 881 | if (dev) { |
882 | usb_kill_urb(dev->urb); | 882 | usb_kill_urb(dev->urb); |
883 | input_unregister_device(dev->input); | 883 | input_unregister_device(dev->input); |
884 | usb_buffer_free(dev->udev, dev->info->datalen, | 884 | usb_free_coherent(dev->udev, dev->info->datalen, |
885 | dev->data, dev->urb->transfer_dma); | 885 | dev->data, dev->urb->transfer_dma); |
886 | usb_free_urb(dev->urb); | 886 | usb_free_urb(dev->urb); |
887 | kfree(dev); | 887 | kfree(dev); |
888 | } | 888 | } |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 4f8fe0886b2a..b95231763911 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -312,6 +312,8 @@ static void setup_events_to_report(struct input_dev *input_dev, | |||
312 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 312 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); |
313 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | 313 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); |
314 | __set_bit(BTN_LEFT, input_dev->keybit); | 314 | __set_bit(BTN_LEFT, input_dev->keybit); |
315 | |||
316 | input_set_events_per_packet(input_dev, 60); | ||
315 | } | 317 | } |
316 | 318 | ||
317 | /* report button data as logical button state */ | 319 | /* report button data as logical button state */ |
@@ -335,10 +337,14 @@ static void report_finger_data(struct input_dev *input, | |||
335 | const struct bcm5974_config *cfg, | 337 | const struct bcm5974_config *cfg, |
336 | const struct tp_finger *f) | 338 | const struct tp_finger *f) |
337 | { | 339 | { |
338 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major)); | 340 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, |
339 | input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor)); | 341 | raw2int(f->force_major) << 1); |
340 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major)); | 342 | input_report_abs(input, ABS_MT_TOUCH_MINOR, |
341 | input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor)); | 343 | raw2int(f->force_minor) << 1); |
344 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, | ||
345 | raw2int(f->size_major) << 1); | ||
346 | input_report_abs(input, ABS_MT_WIDTH_MINOR, | ||
347 | raw2int(f->size_minor) << 1); | ||
342 | input_report_abs(input, ABS_MT_ORIENTATION, | 348 | input_report_abs(input, ABS_MT_ORIENTATION, |
343 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); | 349 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); |
344 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); | 350 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); |
@@ -580,23 +586,30 @@ exit: | |||
580 | */ | 586 | */ |
581 | static int bcm5974_start_traffic(struct bcm5974 *dev) | 587 | static int bcm5974_start_traffic(struct bcm5974 *dev) |
582 | { | 588 | { |
583 | if (bcm5974_wellspring_mode(dev, true)) { | 589 | int error; |
590 | |||
591 | error = bcm5974_wellspring_mode(dev, true); | ||
592 | if (error) { | ||
584 | dprintk(1, "bcm5974: mode switch failed\n"); | 593 | dprintk(1, "bcm5974: mode switch failed\n"); |
585 | goto error; | 594 | goto err_out; |
586 | } | 595 | } |
587 | 596 | ||
588 | if (usb_submit_urb(dev->bt_urb, GFP_KERNEL)) | 597 | error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); |
589 | goto error; | 598 | if (error) |
599 | goto err_reset_mode; | ||
590 | 600 | ||
591 | if (usb_submit_urb(dev->tp_urb, GFP_KERNEL)) | 601 | error = usb_submit_urb(dev->tp_urb, GFP_KERNEL); |
602 | if (error) | ||
592 | goto err_kill_bt; | 603 | goto err_kill_bt; |
593 | 604 | ||
594 | return 0; | 605 | return 0; |
595 | 606 | ||
596 | err_kill_bt: | 607 | err_kill_bt: |
597 | usb_kill_urb(dev->bt_urb); | 608 | usb_kill_urb(dev->bt_urb); |
598 | error: | 609 | err_reset_mode: |
599 | return -EIO; | 610 | bcm5974_wellspring_mode(dev, false); |
611 | err_out: | ||
612 | return error; | ||
600 | } | 613 | } |
601 | 614 | ||
602 | static void bcm5974_pause_traffic(struct bcm5974 *dev) | 615 | static void bcm5974_pause_traffic(struct bcm5974 *dev) |
@@ -715,15 +728,15 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
715 | if (!dev->tp_urb) | 728 | if (!dev->tp_urb) |
716 | goto err_free_bt_urb; | 729 | goto err_free_bt_urb; |
717 | 730 | ||
718 | dev->bt_data = usb_buffer_alloc(dev->udev, | 731 | dev->bt_data = usb_alloc_coherent(dev->udev, |
719 | dev->cfg.bt_datalen, GFP_KERNEL, | 732 | dev->cfg.bt_datalen, GFP_KERNEL, |
720 | &dev->bt_urb->transfer_dma); | 733 | &dev->bt_urb->transfer_dma); |
721 | if (!dev->bt_data) | 734 | if (!dev->bt_data) |
722 | goto err_free_urb; | 735 | goto err_free_urb; |
723 | 736 | ||
724 | dev->tp_data = usb_buffer_alloc(dev->udev, | 737 | dev->tp_data = usb_alloc_coherent(dev->udev, |
725 | dev->cfg.tp_datalen, GFP_KERNEL, | 738 | dev->cfg.tp_datalen, GFP_KERNEL, |
726 | &dev->tp_urb->transfer_dma); | 739 | &dev->tp_urb->transfer_dma); |
727 | if (!dev->tp_data) | 740 | if (!dev->tp_data) |
728 | goto err_free_bt_buffer; | 741 | goto err_free_bt_buffer; |
729 | 742 | ||
@@ -765,10 +778,10 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
765 | return 0; | 778 | return 0; |
766 | 779 | ||
767 | err_free_buffer: | 780 | err_free_buffer: |
768 | usb_buffer_free(dev->udev, dev->cfg.tp_datalen, | 781 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
769 | dev->tp_data, dev->tp_urb->transfer_dma); | 782 | dev->tp_data, dev->tp_urb->transfer_dma); |
770 | err_free_bt_buffer: | 783 | err_free_bt_buffer: |
771 | usb_buffer_free(dev->udev, dev->cfg.bt_datalen, | 784 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
772 | dev->bt_data, dev->bt_urb->transfer_dma); | 785 | dev->bt_data, dev->bt_urb->transfer_dma); |
773 | err_free_urb: | 786 | err_free_urb: |
774 | usb_free_urb(dev->tp_urb); | 787 | usb_free_urb(dev->tp_urb); |
@@ -788,10 +801,10 @@ static void bcm5974_disconnect(struct usb_interface *iface) | |||
788 | usb_set_intfdata(iface, NULL); | 801 | usb_set_intfdata(iface, NULL); |
789 | 802 | ||
790 | input_unregister_device(dev->input); | 803 | input_unregister_device(dev->input); |
791 | usb_buffer_free(dev->udev, dev->cfg.tp_datalen, | 804 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
792 | dev->tp_data, dev->tp_urb->transfer_dma); | 805 | dev->tp_data, dev->tp_urb->transfer_dma); |
793 | usb_buffer_free(dev->udev, dev->cfg.bt_datalen, | 806 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
794 | dev->bt_data, dev->bt_urb->transfer_dma); | 807 | dev->bt_data, dev->bt_urb->transfer_dma); |
795 | usb_free_urb(dev->tp_urb); | 808 | usb_free_urb(dev->tp_urb); |
796 | usb_free_urb(dev->bt_urb); | 809 | usb_free_urb(dev->bt_urb); |
797 | kfree(dev); | 810 | kfree(dev); |
@@ -803,7 +816,6 @@ static struct usb_driver bcm5974_driver = { | |||
803 | .disconnect = bcm5974_disconnect, | 816 | .disconnect = bcm5974_disconnect, |
804 | .suspend = bcm5974_suspend, | 817 | .suspend = bcm5974_suspend, |
805 | .resume = bcm5974_resume, | 818 | .resume = bcm5974_resume, |
806 | .reset_resume = bcm5974_resume, | ||
807 | .id_table = bcm5974_table, | 819 | .id_table = bcm5974_table, |
808 | .supports_autosuspend = 1, | 820 | .supports_autosuspend = 1, |
809 | }; | 821 | }; |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index b27684f267bf..04d9bf320a4f 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -10,7 +10,10 @@ | |||
10 | * Trademarks are the property of their respective owners. | 10 | * Trademarks are the property of their respective owners. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_BASENAME ": " fmt | ||
14 | |||
13 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/slab.h> | ||
14 | #include <linux/module.h> | 17 | #include <linux/module.h> |
15 | #include <linux/input.h> | 18 | #include <linux/input.h> |
16 | #include <linux/serio.h> | 19 | #include <linux/serio.h> |
@@ -18,12 +21,16 @@ | |||
18 | #include "psmouse.h" | 21 | #include "psmouse.h" |
19 | #include "elantech.h" | 22 | #include "elantech.h" |
20 | 23 | ||
21 | #define elantech_debug(format, arg...) \ | 24 | #define elantech_debug(fmt, ...) \ |
22 | do { \ | 25 | do { \ |
23 | if (etd->debug) \ | 26 | if (etd->debug) \ |
24 | printk(KERN_DEBUG format, ##arg); \ | 27 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ |
25 | } while (0) | 28 | } while (0) |
26 | 29 | ||
30 | static bool force_elantech; | ||
31 | module_param_named(force_elantech, force_elantech, bool, 0644); | ||
32 | MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default)."); | ||
33 | |||
27 | /* | 34 | /* |
28 | * Send a Synaptics style sliced query command | 35 | * Send a Synaptics style sliced query command |
29 | */ | 36 | */ |
@@ -32,7 +39,7 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, | |||
32 | { | 39 | { |
33 | if (psmouse_sliced_command(psmouse, c) || | 40 | if (psmouse_sliced_command(psmouse, c) || |
34 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 41 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
35 | pr_err("elantech.c: synaptics_send_cmd query 0x%02x failed.\n", c); | 42 | pr_err("synaptics_send_cmd query 0x%02x failed.\n", c); |
36 | return -1; | 43 | return -1; |
37 | } | 44 | } |
38 | 45 | ||
@@ -55,13 +62,13 @@ static int elantech_ps2_command(struct psmouse *psmouse, | |||
55 | if (rc == 0) | 62 | if (rc == 0) |
56 | break; | 63 | break; |
57 | tries--; | 64 | tries--; |
58 | elantech_debug("elantech.c: retrying ps2 command 0x%02x (%d).\n", | 65 | elantech_debug("retrying ps2 command 0x%02x (%d).\n", |
59 | command, tries); | 66 | command, tries); |
60 | msleep(ETP_PS2_COMMAND_DELAY); | 67 | msleep(ETP_PS2_COMMAND_DELAY); |
61 | } while (tries > 0); | 68 | } while (tries > 0); |
62 | 69 | ||
63 | if (rc) | 70 | if (rc) |
64 | pr_err("elantech.c: ps2 command 0x%02x failed.\n", command); | 71 | pr_err("ps2 command 0x%02x failed.\n", command); |
65 | 72 | ||
66 | return rc; | 73 | return rc; |
67 | } | 74 | } |
@@ -103,7 +110,7 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, | |||
103 | } | 110 | } |
104 | 111 | ||
105 | if (rc) | 112 | if (rc) |
106 | pr_err("elantech.c: failed to read register 0x%02x.\n", reg); | 113 | pr_err("failed to read register 0x%02x.\n", reg); |
107 | else | 114 | else |
108 | *val = param[0]; | 115 | *val = param[0]; |
109 | 116 | ||
@@ -149,7 +156,7 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
149 | } | 156 | } |
150 | 157 | ||
151 | if (rc) | 158 | if (rc) |
152 | pr_err("elantech.c: failed to write register 0x%02x with value 0x%02x.\n", | 159 | pr_err("failed to write register 0x%02x with value 0x%02x.\n", |
153 | reg, val); | 160 | reg, val); |
154 | 161 | ||
155 | return rc; | 162 | return rc; |
@@ -162,7 +169,7 @@ static void elantech_packet_dump(unsigned char *packet, int size) | |||
162 | { | 169 | { |
163 | int i; | 170 | int i; |
164 | 171 | ||
165 | printk(KERN_DEBUG "elantech.c: PS/2 packet ["); | 172 | printk(KERN_DEBUG pr_fmt("PS/2 packet [")); |
166 | for (i = 0; i < size; i++) | 173 | for (i = 0; i < size; i++) |
167 | printk("%s0x%02x ", (i) ? ", " : " ", packet[i]); | 174 | printk("%s0x%02x ", (i) ? ", " : " ", packet[i]); |
168 | printk("]\n"); | 175 | printk("]\n"); |
@@ -178,36 +185,44 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
178 | struct elantech_data *etd = psmouse->private; | 185 | struct elantech_data *etd = psmouse->private; |
179 | unsigned char *packet = psmouse->packet; | 186 | unsigned char *packet = psmouse->packet; |
180 | int fingers; | 187 | int fingers; |
181 | static int old_fingers; | ||
182 | 188 | ||
183 | if (etd->fw_version_maj == 0x01) { | 189 | if (etd->fw_version < 0x020000) { |
184 | /* byte 0: D U p1 p2 1 p3 R L | 190 | /* |
185 | byte 1: f 0 th tw x9 x8 y9 y8 */ | 191 | * byte 0: D U p1 p2 1 p3 R L |
192 | * byte 1: f 0 th tw x9 x8 y9 y8 | ||
193 | */ | ||
186 | fingers = ((packet[1] & 0x80) >> 7) + | 194 | fingers = ((packet[1] & 0x80) >> 7) + |
187 | ((packet[1] & 0x30) >> 4); | 195 | ((packet[1] & 0x30) >> 4); |
188 | } else { | 196 | } else { |
189 | /* byte 0: n1 n0 p2 p1 1 p3 R L | 197 | /* |
190 | byte 1: 0 0 0 0 x9 x8 y9 y8 */ | 198 | * byte 0: n1 n0 p2 p1 1 p3 R L |
199 | * byte 1: 0 0 0 0 x9 x8 y9 y8 | ||
200 | */ | ||
191 | fingers = (packet[0] & 0xc0) >> 6; | 201 | fingers = (packet[0] & 0xc0) >> 6; |
192 | } | 202 | } |
193 | 203 | ||
194 | if (etd->jumpy_cursor) { | 204 | if (etd->jumpy_cursor) { |
195 | /* Discard packets that are likely to have bogus coordinates */ | 205 | if (fingers != 1) { |
196 | if (fingers > old_fingers) { | 206 | etd->single_finger_reports = 0; |
197 | elantech_debug("elantech.c: discarding packet\n"); | 207 | } else if (etd->single_finger_reports < 2) { |
198 | goto discard_packet_v1; | 208 | /* Discard first 2 reports of one finger, bogus */ |
209 | etd->single_finger_reports++; | ||
210 | elantech_debug("discarding packet\n"); | ||
211 | return; | ||
199 | } | 212 | } |
200 | } | 213 | } |
201 | 214 | ||
202 | input_report_key(dev, BTN_TOUCH, fingers != 0); | 215 | input_report_key(dev, BTN_TOUCH, fingers != 0); |
203 | 216 | ||
204 | /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 | 217 | /* |
205 | byte 3: y7 y6 y5 y4 y3 y2 y1 y0 */ | 218 | * byte 2: x7 x6 x5 x4 x3 x2 x1 x0 |
219 | * byte 3: y7 y6 y5 y4 y3 y2 y1 y0 | ||
220 | */ | ||
206 | if (fingers) { | 221 | if (fingers) { |
207 | input_report_abs(dev, ABS_X, | 222 | input_report_abs(dev, ABS_X, |
208 | ((packet[1] & 0x0c) << 6) | packet[2]); | 223 | ((packet[1] & 0x0c) << 6) | packet[2]); |
209 | input_report_abs(dev, ABS_Y, ETP_YMAX_V1 - | 224 | input_report_abs(dev, ABS_Y, |
210 | (((packet[1] & 0x03) << 8) | packet[3])); | 225 | ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3])); |
211 | } | 226 | } |
212 | 227 | ||
213 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 228 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
@@ -216,7 +231,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
216 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 231 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); |
217 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 232 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
218 | 233 | ||
219 | if ((etd->fw_version_maj == 0x01) && | 234 | if (etd->fw_version < 0x020000 && |
220 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 235 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
221 | /* rocker up */ | 236 | /* rocker up */ |
222 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); | 237 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); |
@@ -225,9 +240,6 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
225 | } | 240 | } |
226 | 241 | ||
227 | input_sync(dev); | 242 | input_sync(dev); |
228 | |||
229 | discard_packet_v1: | ||
230 | old_fingers = fingers; | ||
231 | } | 243 | } |
232 | 244 | ||
233 | /* | 245 | /* |
@@ -245,35 +257,56 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
245 | input_report_key(dev, BTN_TOUCH, fingers != 0); | 257 | input_report_key(dev, BTN_TOUCH, fingers != 0); |
246 | 258 | ||
247 | 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... */ | ||
248 | case 1: | 268 | case 1: |
249 | /* byte 1: x15 x14 x13 x12 x11 x10 x9 x8 | 269 | /* |
250 | byte 2: x7 x6 x5 x4 x4 x2 x1 x0 */ | 270 | * byte 1: . . . . . x10 x9 x8 |
251 | input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]); | 271 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 |
252 | /* byte 4: y15 y14 y13 y12 y11 y10 y8 y8 | 272 | */ |
253 | byte 5: y7 y6 y5 y4 y3 y2 y1 y0 */ | 273 | input_report_abs(dev, ABS_X, |
254 | input_report_abs(dev, ABS_Y, ETP_YMAX_V2 - | 274 | ((packet[1] & 0x07) << 8) | packet[2]); |
255 | ((packet[4] << 8) | packet[5])); | 275 | /* |
276 | * byte 4: . . . . . . y9 y8 | ||
277 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | ||
278 | */ | ||
279 | input_report_abs(dev, ABS_Y, | ||
280 | ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5])); | ||
256 | break; | 281 | break; |
257 | 282 | ||
258 | case 2: | 283 | case 2: |
259 | /* The coordinate of each finger is reported separately with | 284 | /* |
260 | a lower resolution for two finger touches */ | 285 | * The coordinate of each finger is reported separately |
261 | /* byte 0: . . ay8 ax8 . . . . | 286 | * with a lower resolution for two finger touches: |
262 | byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */ | 287 | * byte 0: . . ay8 ax8 . . . . |
288 | * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 | ||
289 | */ | ||
263 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; | 290 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; |
264 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ | 291 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ |
265 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); | 292 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); |
266 | /* byte 3: . . by8 bx8 . . . . | 293 | /* |
267 | byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */ | 294 | * byte 3: . . by8 bx8 . . . . |
295 | * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 | ||
296 | */ | ||
268 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; | 297 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; |
269 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ | 298 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ |
270 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); | 299 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); |
271 | /* For compatibility with the X Synaptics driver scale up one | 300 | /* |
272 | coordinate and report as ordinary mouse movent */ | 301 | * For compatibility with the X Synaptics driver scale up |
302 | * one coordinate and report as ordinary mouse movent | ||
303 | */ | ||
273 | input_report_abs(dev, ABS_X, x1 << 2); | 304 | input_report_abs(dev, ABS_X, x1 << 2); |
274 | input_report_abs(dev, ABS_Y, y1 << 2); | 305 | input_report_abs(dev, ABS_Y, y1 << 2); |
275 | /* For compatibility with the proprietary X Elantech driver | 306 | /* |
276 | report both coordinates as hat coordinates */ | 307 | * For compatibility with the proprietary X Elantech driver |
308 | * report both coordinates as hat coordinates | ||
309 | */ | ||
277 | input_report_abs(dev, ABS_HAT0X, x1); | 310 | input_report_abs(dev, ABS_HAT0X, x1); |
278 | input_report_abs(dev, ABS_HAT0Y, y1); | 311 | input_report_abs(dev, ABS_HAT0Y, y1); |
279 | input_report_abs(dev, ABS_HAT1X, x2); | 312 | input_report_abs(dev, ABS_HAT1X, x2); |
@@ -284,6 +317,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
284 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 317 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
285 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | 318 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); |
286 | 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); | ||
287 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 321 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); |
288 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 322 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
289 | 323 | ||
@@ -297,7 +331,7 @@ static int elantech_check_parity_v1(struct psmouse *psmouse) | |||
297 | unsigned char p1, p2, p3; | 331 | unsigned char p1, p2, p3; |
298 | 332 | ||
299 | /* Parity bits are placed differently */ | 333 | /* Parity bits are placed differently */ |
300 | if (etd->fw_version_maj == 0x01) { | 334 | if (etd->fw_version < 0x020000) { |
301 | /* byte 0: D U p1 p2 1 p3 R L */ | 335 | /* byte 0: D U p1 p2 1 p3 R L */ |
302 | p1 = (packet[0] & 0x20) >> 5; | 336 | p1 = (packet[0] & 0x20) >> 5; |
303 | p2 = (packet[0] & 0x10) >> 4; | 337 | p2 = (packet[0] & 0x10) >> 4; |
@@ -389,23 +423,21 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
389 | if (rc == 0) | 423 | if (rc == 0) |
390 | break; | 424 | break; |
391 | tries--; | 425 | tries--; |
392 | elantech_debug("elantech.c: retrying read (%d).\n", | 426 | elantech_debug("retrying read (%d).\n", tries); |
393 | tries); | ||
394 | msleep(ETP_READ_BACK_DELAY); | 427 | msleep(ETP_READ_BACK_DELAY); |
395 | } while (tries > 0); | 428 | } while (tries > 0); |
396 | 429 | ||
397 | if (rc) { | 430 | if (rc) { |
398 | pr_err("elantech.c: failed to read back register 0x10.\n"); | 431 | pr_err("failed to read back register 0x10.\n"); |
399 | } else if (etd->hw_version == 1 && | 432 | } else if (etd->hw_version == 1 && |
400 | !(val & ETP_R10_ABSOLUTE_MODE)) { | 433 | !(val & ETP_R10_ABSOLUTE_MODE)) { |
401 | pr_err("elantech.c: touchpad refuses " | 434 | pr_err("touchpad refuses to switch to absolute mode.\n"); |
402 | "to switch to absolute mode.\n"); | ||
403 | rc = -1; | 435 | rc = -1; |
404 | } | 436 | } |
405 | } | 437 | } |
406 | 438 | ||
407 | if (rc) | 439 | if (rc) |
408 | pr_err("elantech.c: failed to initialise registers.\n"); | 440 | pr_err("failed to initialise registers.\n"); |
409 | 441 | ||
410 | return rc; | 442 | return rc; |
411 | } | 443 | } |
@@ -433,7 +465,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
433 | switch (etd->hw_version) { | 465 | switch (etd->hw_version) { |
434 | case 1: | 466 | case 1: |
435 | /* Rocker button */ | 467 | /* Rocker button */ |
436 | if ((etd->fw_version_maj == 0x01) && | 468 | if (etd->fw_version < 0x020000 && |
437 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 469 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
438 | __set_bit(BTN_FORWARD, dev->keybit); | 470 | __set_bit(BTN_FORWARD, dev->keybit); |
439 | __set_bit(BTN_BACK, dev->keybit); | 471 | __set_bit(BTN_BACK, dev->keybit); |
@@ -443,6 +475,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
443 | break; | 475 | break; |
444 | 476 | ||
445 | case 2: | 477 | case 2: |
478 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | ||
446 | 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); |
447 | 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); |
448 | 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); |
@@ -551,6 +584,24 @@ static struct attribute_group elantech_attr_group = { | |||
551 | .attrs = elantech_attrs, | 584 | .attrs = elantech_attrs, |
552 | }; | 585 | }; |
553 | 586 | ||
587 | static bool elantech_is_signature_valid(const unsigned char *param) | ||
588 | { | ||
589 | static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10 }; | ||
590 | int i; | ||
591 | |||
592 | if (param[0] == 0) | ||
593 | return false; | ||
594 | |||
595 | if (param[1] == 0) | ||
596 | return true; | ||
597 | |||
598 | for (i = 0; i < ARRAY_SIZE(rates); i++) | ||
599 | if (param[2] == rates[i]) | ||
600 | return false; | ||
601 | |||
602 | return true; | ||
603 | } | ||
604 | |||
554 | /* | 605 | /* |
555 | * Use magic knock to detect Elantech touchpad | 606 | * Use magic knock to detect Elantech touchpad |
556 | */ | 607 | */ |
@@ -566,7 +617,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
566 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 617 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
567 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 618 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
568 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 619 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
569 | pr_debug("elantech.c: sending Elantech magic knock failed.\n"); | 620 | pr_debug("sending Elantech magic knock failed.\n"); |
570 | return -1; | 621 | return -1; |
571 | } | 622 | } |
572 | 623 | ||
@@ -575,8 +626,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
575 | * set of magic numbers | 626 | * set of magic numbers |
576 | */ | 627 | */ |
577 | if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { | 628 | if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { |
578 | pr_debug("elantech.c: " | 629 | pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", |
579 | "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", | ||
580 | param[0], param[1], param[2]); | 630 | param[0], param[1], param[2]); |
581 | return -1; | 631 | return -1; |
582 | } | 632 | } |
@@ -587,16 +637,20 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
587 | * to Elantech magic knock and there might be more. | 637 | * to Elantech magic knock and there might be more. |
588 | */ | 638 | */ |
589 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 639 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
590 | pr_debug("elantech.c: failed to query firmware version.\n"); | 640 | pr_debug("failed to query firmware version.\n"); |
591 | return -1; | 641 | return -1; |
592 | } | 642 | } |
593 | 643 | ||
594 | pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", | 644 | pr_debug("Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", |
595 | param[0], param[1], param[2]); | 645 | param[0], param[1], param[2]); |
596 | 646 | ||
597 | if (param[0] == 0 || param[1] != 0) { | 647 | if (!elantech_is_signature_valid(param)) { |
598 | pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); | 648 | if (!force_elantech) { |
599 | return -1; | 649 | pr_debug("Probably not a real Elantech touchpad. Aborting.\n"); |
650 | return -1; | ||
651 | } | ||
652 | |||
653 | pr_debug("Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n"); | ||
600 | } | 654 | } |
601 | 655 | ||
602 | if (set_properties) { | 656 | if (set_properties) { |
@@ -627,7 +681,7 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
627 | return -1; | 681 | return -1; |
628 | 682 | ||
629 | if (elantech_set_absolute_mode(psmouse)) { | 683 | if (elantech_set_absolute_mode(psmouse)) { |
630 | pr_err("elantech.c: failed to put touchpad back into absolute mode.\n"); | 684 | pr_err("failed to put touchpad back into absolute mode.\n"); |
631 | return -1; | 685 | return -1; |
632 | } | 686 | } |
633 | 687 | ||
@@ -645,7 +699,7 @@ int elantech_init(struct psmouse *psmouse) | |||
645 | 699 | ||
646 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); | 700 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); |
647 | if (!etd) | 701 | if (!etd) |
648 | return -1; | 702 | return -ENOMEM; |
649 | 703 | ||
650 | etd->parity[0] = 1; | 704 | etd->parity[0] = 1; |
651 | for (i = 1; i < 256; i++) | 705 | for (i = 1; i < 256; i++) |
@@ -655,17 +709,17 @@ int elantech_init(struct psmouse *psmouse) | |||
655 | * Do the version query again so we can store the result | 709 | * Do the version query again so we can store the result |
656 | */ | 710 | */ |
657 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 711 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
658 | pr_err("elantech.c: failed to query firmware version.\n"); | 712 | pr_err("failed to query firmware version.\n"); |
659 | goto init_fail; | 713 | goto init_fail; |
660 | } | 714 | } |
661 | etd->fw_version_maj = param[0]; | 715 | |
662 | etd->fw_version_min = param[2]; | 716 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; |
663 | 717 | ||
664 | /* | 718 | /* |
665 | * Assume every version greater than this is new EeePC style | 719 | * Assume every version greater than this is new EeePC style |
666 | * hardware with 6 byte packets | 720 | * hardware with 6 byte packets |
667 | */ | 721 | */ |
668 | if (etd->fw_version_maj >= 0x02 && etd->fw_version_min >= 0x30) { | 722 | if (etd->fw_version >= 0x020030) { |
669 | etd->hw_version = 2; | 723 | etd->hw_version = 2; |
670 | /* For now show extra debug information */ | 724 | /* For now show extra debug information */ |
671 | etd->debug = 1; | 725 | etd->debug = 1; |
@@ -675,30 +729,30 @@ int elantech_init(struct psmouse *psmouse) | |||
675 | etd->hw_version = 1; | 729 | etd->hw_version = 1; |
676 | etd->paritycheck = 1; | 730 | etd->paritycheck = 1; |
677 | } | 731 | } |
678 | pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n", | 732 | |
679 | etd->hw_version, etd->fw_version_maj, etd->fw_version_min); | 733 | pr_info("assuming hardware version %d, firmware version %d.%d.%d\n", |
734 | etd->hw_version, param[0], param[1], param[2]); | ||
680 | 735 | ||
681 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { | 736 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { |
682 | pr_err("elantech.c: failed to query capabilities.\n"); | 737 | pr_err("failed to query capabilities.\n"); |
683 | goto init_fail; | 738 | goto init_fail; |
684 | } | 739 | } |
685 | pr_info("elantech.c: Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", | 740 | pr_info("Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", |
686 | param[0], param[1], param[2]); | 741 | param[0], param[1], param[2]); |
687 | etd->capabilities = param[0]; | 742 | etd->capabilities = param[0]; |
688 | 743 | ||
689 | /* | 744 | /* |
690 | * This firmware seems to suffer from misreporting coordinates when | 745 | * This firmware suffers from misreporting coordinates when |
691 | * a touch action starts causing the mouse cursor or scrolled page | 746 | * a touch action starts causing the mouse cursor or scrolled page |
692 | * to jump. Enable a workaround. | 747 | * to jump. Enable a workaround. |
693 | */ | 748 | */ |
694 | if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) { | 749 | if (etd->fw_version == 0x020022 || etd->fw_version == 0x020600) { |
695 | pr_info("elantech.c: firmware version 2.34 detected, " | 750 | pr_info("firmware version 2.0.34/2.6.0 detected, enabling jumpy cursor workaround\n"); |
696 | "enabling jumpy cursor workaround\n"); | 751 | etd->jumpy_cursor = true; |
697 | etd->jumpy_cursor = 1; | ||
698 | } | 752 | } |
699 | 753 | ||
700 | if (elantech_set_absolute_mode(psmouse)) { | 754 | if (elantech_set_absolute_mode(psmouse)) { |
701 | pr_err("elantech.c: failed to put touchpad into absolute mode.\n"); | 755 | pr_err("failed to put touchpad into absolute mode.\n"); |
702 | goto init_fail; | 756 | goto init_fail; |
703 | } | 757 | } |
704 | 758 | ||
@@ -707,8 +761,7 @@ int elantech_init(struct psmouse *psmouse) | |||
707 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, | 761 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, |
708 | &elantech_attr_group); | 762 | &elantech_attr_group); |
709 | if (error) { | 763 | if (error) { |
710 | pr_err("elantech.c: failed to create sysfs attributes, error: %d.\n", | 764 | pr_err("failed to create sysfs attributes, error: %d.\n", error); |
711 | error); | ||
712 | goto init_fail; | 765 | goto init_fail; |
713 | } | 766 | } |
714 | 767 | ||
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index feac5f7af966..aa4aac5d2198 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -100,11 +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 fw_version_maj; | 103 | bool paritycheck; |
104 | unsigned char fw_version_min; | 104 | bool jumpy_cursor; |
105 | unsigned char hw_version; | 105 | unsigned char hw_version; |
106 | unsigned char paritycheck; | 106 | unsigned int fw_version; |
107 | unsigned char jumpy_cursor; | 107 | unsigned int single_finger_reports; |
108 | unsigned char parity[256]; | 108 | unsigned char parity[256]; |
109 | }; | 109 | }; |
110 | 110 | ||
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 90be30e93556..1d2205b24800 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -30,6 +30,7 @@ | |||
30 | */ | 30 | */ |
31 | 31 | ||
32 | #define DEBUG | 32 | #define DEBUG |
33 | #include <linux/slab.h> | ||
33 | #include <linux/input.h> | 34 | #include <linux/input.h> |
34 | #include <linux/serio.h> | 35 | #include <linux/serio.h> |
35 | #include <linux/libps2.h> | 36 | #include <linux/libps2.h> |
@@ -39,8 +40,8 @@ | |||
39 | #include "psmouse.h" | 40 | #include "psmouse.h" |
40 | #include "hgpk.h" | 41 | #include "hgpk.h" |
41 | 42 | ||
42 | static int tpdebug; | 43 | static bool tpdebug; |
43 | module_param(tpdebug, int, 0644); | 44 | module_param(tpdebug, bool, 0644); |
44 | MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); | 45 | MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); |
45 | 46 | ||
46 | static int recalib_delta = 100; | 47 | static int recalib_delta = 100; |
@@ -68,10 +69,6 @@ module_param(post_interrupt_delay, int, 0644); | |||
68 | MODULE_PARM_DESC(post_interrupt_delay, | 69 | MODULE_PARM_DESC(post_interrupt_delay, |
69 | "delay (ms) before recal after recal interrupt detected"); | 70 | "delay (ms) before recal after recal interrupt detected"); |
70 | 71 | ||
71 | static int autorecal = 1; | ||
72 | module_param(autorecal, int, 0644); | ||
73 | MODULE_PARM_DESC(autorecal, "enable recalibration in the driver"); | ||
74 | |||
75 | /* | 72 | /* |
76 | * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" | 73 | * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" |
77 | * above the pad and still have it send packets. This causes a jump cursor | 74 | * above the pad and still have it send packets. This causes a jump cursor |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 7c1d7d420ae3..c31ad11df6bb 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/serio.h> | 16 | #include <linux/serio.h> |
17 | #include <linux/libps2.h> | 17 | #include <linux/libps2.h> |
18 | #include <linux/dmi.h> | 18 | #include <linux/dmi.h> |
19 | #include <linux/slab.h> | ||
19 | 20 | ||
20 | #include "psmouse.h" | 21 | #include "psmouse.h" |
21 | #include "lifebook.h" | 22 | #include "lifebook.h" |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 543c240a85f2..c9983aee9082 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -56,36 +56,36 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) | |||
56 | /* Logitech extended packet */ | 56 | /* Logitech extended packet */ |
57 | switch ((packet[1] >> 4) | (packet[0] & 0x30)) { | 57 | switch ((packet[1] >> 4) | (packet[0] & 0x30)) { |
58 | 58 | ||
59 | case 0x0d: /* Mouse extra info */ | 59 | case 0x0d: /* Mouse extra info */ |
60 | 60 | ||
61 | input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, | 61 | input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, |
62 | (int) (packet[2] & 8) - (int) (packet[2] & 7)); | 62 | (int) (packet[2] & 8) - (int) (packet[2] & 7)); |
63 | input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1); | 63 | input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1); |
64 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1); | 64 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1); |
65 | 65 | ||
66 | break; | 66 | break; |
67 | 67 | ||
68 | case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ | 68 | case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ |
69 | 69 | ||
70 | input_report_key(dev, BTN_SIDE, (packet[2]) & 1); | 70 | input_report_key(dev, BTN_SIDE, (packet[2]) & 1); |
71 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1); | 71 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1); |
72 | input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1); | 72 | input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1); |
73 | input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1); | 73 | input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1); |
74 | input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1); | 74 | input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1); |
75 | 75 | ||
76 | break; | 76 | break; |
77 | 77 | ||
78 | case 0x0f: /* TouchPad extra info */ | 78 | case 0x0f: /* TouchPad extra info */ |
79 | 79 | ||
80 | input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, | 80 | input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, |
81 | (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7)); | 81 | (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7)); |
82 | packet[0] = packet[2] | 0x08; | 82 | packet[0] = packet[2] | 0x08; |
83 | break; | 83 | break; |
84 | 84 | ||
85 | #ifdef DEBUG | 85 | #ifdef DEBUG |
86 | default: | 86 | default: |
87 | printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", | 87 | printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", |
88 | (packet[1] >> 4) | (packet[0] & 0x30)); | 88 | (packet[1] >> 4) | (packet[0] & 0x30)); |
89 | #endif | 89 | #endif |
90 | } | 90 | } |
91 | } else { | 91 | } else { |
@@ -250,7 +250,6 @@ static const struct ps2pp_info *get_model_info(unsigned char model) | |||
250 | if (model == ps2pp_list[i].model) | 250 | if (model == ps2pp_list[i].model) |
251 | return &ps2pp_list[i]; | 251 | return &ps2pp_list[i]; |
252 | 252 | ||
253 | printk(KERN_WARNING "logips2pp: Detected unknown logitech mouse model %d\n", model); | ||
254 | return NULL; | 253 | return NULL; |
255 | } | 254 | } |
256 | 255 | ||
@@ -285,31 +284,32 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, | |||
285 | __set_bit(REL_HWHEEL, input_dev->relbit); | 284 | __set_bit(REL_HWHEEL, input_dev->relbit); |
286 | 285 | ||
287 | switch (model_info->kind) { | 286 | switch (model_info->kind) { |
288 | case PS2PP_KIND_WHEEL: | ||
289 | psmouse->name = "Wheel Mouse"; | ||
290 | break; | ||
291 | |||
292 | case PS2PP_KIND_MX: | ||
293 | psmouse->name = "MX Mouse"; | ||
294 | break; | ||
295 | 287 | ||
296 | case PS2PP_KIND_TP3: | 288 | case PS2PP_KIND_WHEEL: |
297 | psmouse->name = "TouchPad 3"; | 289 | psmouse->name = "Wheel Mouse"; |
298 | break; | 290 | break; |
299 | 291 | ||
300 | case PS2PP_KIND_TRACKMAN: | 292 | case PS2PP_KIND_MX: |
301 | psmouse->name = "TrackMan"; | 293 | psmouse->name = "MX Mouse"; |
302 | break; | 294 | break; |
303 | 295 | ||
304 | default: | 296 | case PS2PP_KIND_TP3: |
305 | /* | 297 | psmouse->name = "TouchPad 3"; |
306 | * Set name to "Mouse" only when using PS2++, | 298 | break; |
307 | * otherwise let other protocols define suitable | 299 | |
308 | * name | 300 | case PS2PP_KIND_TRACKMAN: |
309 | */ | 301 | psmouse->name = "TrackMan"; |
310 | if (using_ps2pp) | 302 | break; |
311 | psmouse->name = "Mouse"; | 303 | |
312 | break; | 304 | default: |
305 | /* | ||
306 | * Set name to "Mouse" only when using PS2++, | ||
307 | * otherwise let other protocols define suitable | ||
308 | * name | ||
309 | */ | ||
310 | if (using_ps2pp) | ||
311 | psmouse->name = "Mouse"; | ||
312 | break; | ||
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
@@ -343,7 +343,8 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
343 | if (!model || !buttons) | 343 | if (!model || !buttons) |
344 | return -1; | 344 | return -1; |
345 | 345 | ||
346 | if ((model_info = get_model_info(model)) != NULL) { | 346 | model_info = get_model_info(model); |
347 | if (model_info) { | ||
347 | 348 | ||
348 | /* | 349 | /* |
349 | * Do Logitech PS2++ / PS2T++ magic init. | 350 | * Do Logitech PS2++ / PS2T++ magic init. |
@@ -379,6 +380,9 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
379 | use_ps2pp = true; | 380 | use_ps2pp = true; |
380 | } | 381 | } |
381 | } | 382 | } |
383 | |||
384 | } else { | ||
385 | printk(KERN_WARNING "logips2pp: Detected unknown logitech mouse model %d\n", model); | ||
382 | } | 386 | } |
383 | 387 | ||
384 | if (set_properties) { | 388 | if (set_properties) { |
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/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 9774bdfaa482..cd9d0c97e429 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -39,11 +39,13 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | 40 | ||
41 | static unsigned int psmouse_max_proto = PSMOUSE_AUTO; | 41 | static unsigned int psmouse_max_proto = PSMOUSE_AUTO; |
42 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp); | 42 | static int psmouse_set_maxproto(const char *val, const struct kernel_param *); |
43 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp); | 43 | static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp); |
44 | static struct kernel_param_ops param_ops_proto_abbrev = { | ||
45 | .set = psmouse_set_maxproto, | ||
46 | .get = psmouse_get_maxproto, | ||
47 | }; | ||
44 | #define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int) | 48 | #define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int) |
45 | #define param_set_proto_abbrev psmouse_set_maxproto | ||
46 | #define param_get_proto_abbrev psmouse_get_maxproto | ||
47 | module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644); | 49 | module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644); |
48 | MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches."); | 50 | MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches."); |
49 | 51 | ||
@@ -110,6 +112,7 @@ static struct workqueue_struct *kpsmoused_wq; | |||
110 | struct psmouse_protocol { | 112 | struct psmouse_protocol { |
111 | enum psmouse_type type; | 113 | enum psmouse_type type; |
112 | bool maxproto; | 114 | bool maxproto; |
115 | bool ignore_parity; /* Protocol should ignore parity errors from KBC */ | ||
113 | const char *name; | 116 | const char *name; |
114 | const char *alias; | 117 | const char *alias; |
115 | int (*detect)(struct psmouse *, bool); | 118 | int (*detect)(struct psmouse *, bool); |
@@ -146,18 +149,18 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) | |||
146 | 149 | ||
147 | if (psmouse->type == PSMOUSE_IMEX) { | 150 | if (psmouse->type == PSMOUSE_IMEX) { |
148 | switch (packet[3] & 0xC0) { | 151 | switch (packet[3] & 0xC0) { |
149 | case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ | 152 | case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ |
150 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); | 153 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); |
151 | break; | 154 | break; |
152 | case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ | 155 | case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ |
153 | input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); | 156 | input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); |
154 | break; | 157 | break; |
155 | case 0x00: | 158 | case 0x00: |
156 | case 0xC0: | 159 | case 0xC0: |
157 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); | 160 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); |
158 | input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); | 161 | input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); |
159 | input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); | 162 | input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); |
160 | break; | 163 | break; |
161 | } | 164 | } |
162 | } | 165 | } |
163 | 166 | ||
@@ -246,31 +249,31 @@ static int psmouse_handle_byte(struct psmouse *psmouse) | |||
246 | psmouse_ret_t rc = psmouse->protocol_handler(psmouse); | 249 | psmouse_ret_t rc = psmouse->protocol_handler(psmouse); |
247 | 250 | ||
248 | switch (rc) { | 251 | switch (rc) { |
249 | case PSMOUSE_BAD_DATA: | 252 | case PSMOUSE_BAD_DATA: |
250 | if (psmouse->state == PSMOUSE_ACTIVATED) { | 253 | if (psmouse->state == PSMOUSE_ACTIVATED) { |
251 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", | 254 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", |
252 | psmouse->name, psmouse->phys, psmouse->pktcnt); | 255 | psmouse->name, psmouse->phys, psmouse->pktcnt); |
253 | if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { | 256 | if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { |
254 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 257 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
255 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); | 258 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); |
256 | serio_reconnect(psmouse->ps2dev.serio); | 259 | serio_reconnect(psmouse->ps2dev.serio); |
257 | return -1; | 260 | return -1; |
258 | } | ||
259 | } | ||
260 | psmouse->pktcnt = 0; | ||
261 | break; | ||
262 | |||
263 | case PSMOUSE_FULL_PACKET: | ||
264 | psmouse->pktcnt = 0; | ||
265 | if (psmouse->out_of_sync_cnt) { | ||
266 | psmouse->out_of_sync_cnt = 0; | ||
267 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", | ||
268 | psmouse->name, psmouse->phys); | ||
269 | } | 261 | } |
270 | break; | 262 | } |
263 | psmouse->pktcnt = 0; | ||
264 | break; | ||
265 | |||
266 | case PSMOUSE_FULL_PACKET: | ||
267 | psmouse->pktcnt = 0; | ||
268 | if (psmouse->out_of_sync_cnt) { | ||
269 | psmouse->out_of_sync_cnt = 0; | ||
270 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", | ||
271 | psmouse->name, psmouse->phys); | ||
272 | } | ||
273 | break; | ||
271 | 274 | ||
272 | case PSMOUSE_GOOD_DATA: | 275 | case PSMOUSE_GOOD_DATA: |
273 | break; | 276 | break; |
274 | } | 277 | } |
275 | return 0; | 278 | return 0; |
276 | } | 279 | } |
@@ -288,7 +291,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
288 | if (psmouse->state == PSMOUSE_IGNORE) | 291 | if (psmouse->state == PSMOUSE_IGNORE) |
289 | goto out; | 292 | goto out; |
290 | 293 | ||
291 | if (flags & (SERIO_PARITY|SERIO_TIMEOUT)) { | 294 | if (unlikely((flags & SERIO_TIMEOUT) || |
295 | ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) { | ||
296 | |||
292 | if (psmouse->state == PSMOUSE_ACTIVATED) | 297 | if (psmouse->state == PSMOUSE_ACTIVATED) |
293 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", | 298 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", |
294 | flags & SERIO_TIMEOUT ? " timeout" : "", | 299 | flags & SERIO_TIMEOUT ? " timeout" : "", |
@@ -759,6 +764,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
759 | .name = "PS/2", | 764 | .name = "PS/2", |
760 | .alias = "bare", | 765 | .alias = "bare", |
761 | .maxproto = true, | 766 | .maxproto = true, |
767 | .ignore_parity = true, | ||
762 | .detect = ps2bare_detect, | 768 | .detect = ps2bare_detect, |
763 | }, | 769 | }, |
764 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | 770 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP |
@@ -786,6 +792,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
786 | .name = "ImPS/2", | 792 | .name = "ImPS/2", |
787 | .alias = "imps", | 793 | .alias = "imps", |
788 | .maxproto = true, | 794 | .maxproto = true, |
795 | .ignore_parity = true, | ||
789 | .detect = intellimouse_detect, | 796 | .detect = intellimouse_detect, |
790 | }, | 797 | }, |
791 | { | 798 | { |
@@ -793,6 +800,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
793 | .name = "ImExPS/2", | 800 | .name = "ImExPS/2", |
794 | .alias = "exps", | 801 | .alias = "exps", |
795 | .maxproto = true, | 802 | .maxproto = true, |
803 | .ignore_parity = true, | ||
796 | .detect = im_explorer_detect, | 804 | .detect = im_explorer_detect, |
797 | }, | 805 | }, |
798 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | 806 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS |
@@ -1141,7 +1149,14 @@ static void psmouse_cleanup(struct serio *serio) | |||
1141 | psmouse_deactivate(parent); | 1149 | psmouse_deactivate(parent); |
1142 | } | 1150 | } |
1143 | 1151 | ||
1144 | psmouse_deactivate(psmouse); | 1152 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
1153 | |||
1154 | /* | ||
1155 | * Disable stream mode so cleanup routine can proceed undisturbed. | ||
1156 | */ | ||
1157 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) | ||
1158 | printk(KERN_WARNING "psmouse.c: Failed to disable mouse on %s\n", | ||
1159 | psmouse->ps2dev.serio->phys); | ||
1145 | 1160 | ||
1146 | if (psmouse->cleanup) | 1161 | if (psmouse->cleanup) |
1147 | psmouse->cleanup(psmouse); | 1162 | psmouse->cleanup(psmouse); |
@@ -1215,6 +1230,7 @@ static void psmouse_disconnect(struct serio *serio) | |||
1215 | static int psmouse_switch_protocol(struct psmouse *psmouse, | 1230 | static int psmouse_switch_protocol(struct psmouse *psmouse, |
1216 | const struct psmouse_protocol *proto) | 1231 | const struct psmouse_protocol *proto) |
1217 | { | 1232 | { |
1233 | const struct psmouse_protocol *selected_proto; | ||
1218 | struct input_dev *input_dev = psmouse->dev; | 1234 | struct input_dev *input_dev = psmouse->dev; |
1219 | 1235 | ||
1220 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; | 1236 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; |
@@ -1231,16 +1247,21 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, | |||
1231 | psmouse->pktsize = 3; | 1247 | psmouse->pktsize = 3; |
1232 | 1248 | ||
1233 | if (proto && (proto->detect || proto->init)) { | 1249 | if (proto && (proto->detect || proto->init)) { |
1234 | if (proto->detect && proto->detect(psmouse, 1) < 0) | 1250 | if (proto->detect && proto->detect(psmouse, true) < 0) |
1235 | return -1; | 1251 | return -1; |
1236 | 1252 | ||
1237 | if (proto->init && proto->init(psmouse) < 0) | 1253 | if (proto->init && proto->init(psmouse) < 0) |
1238 | return -1; | 1254 | return -1; |
1239 | 1255 | ||
1240 | psmouse->type = proto->type; | 1256 | psmouse->type = proto->type; |
1241 | } else | 1257 | selected_proto = proto; |
1258 | } else { | ||
1242 | psmouse->type = psmouse_extensions(psmouse, | 1259 | psmouse->type = psmouse_extensions(psmouse, |
1243 | psmouse_max_proto, true); | 1260 | psmouse_max_proto, true); |
1261 | selected_proto = psmouse_protocol_by_type(psmouse->type); | ||
1262 | } | ||
1263 | |||
1264 | psmouse->ignore_parity = selected_proto->ignore_parity; | ||
1244 | 1265 | ||
1245 | /* | 1266 | /* |
1246 | * If mouse's packet size is 3 there is no point in polling the | 1267 | * If mouse's packet size is 3 there is no point in polling the |
@@ -1260,7 +1281,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, | |||
1260 | psmouse->resync_time = 0; | 1281 | psmouse->resync_time = 0; |
1261 | 1282 | ||
1262 | snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", | 1283 | snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", |
1263 | psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); | 1284 | selected_proto->name, psmouse->vendor, psmouse->name); |
1264 | 1285 | ||
1265 | input_dev->name = psmouse->devname; | 1286 | input_dev->name = psmouse->devname; |
1266 | input_dev->phys = psmouse->phys; | 1287 | input_dev->phys = psmouse->phys; |
@@ -1375,6 +1396,7 @@ static int psmouse_reconnect(struct serio *serio) | |||
1375 | struct psmouse *psmouse = serio_get_drvdata(serio); | 1396 | struct psmouse *psmouse = serio_get_drvdata(serio); |
1376 | struct psmouse *parent = NULL; | 1397 | struct psmouse *parent = NULL; |
1377 | struct serio_driver *drv = serio->drv; | 1398 | struct serio_driver *drv = serio->drv; |
1399 | unsigned char type; | ||
1378 | int rc = -1; | 1400 | int rc = -1; |
1379 | 1401 | ||
1380 | if (!drv || !psmouse) { | 1402 | if (!drv || !psmouse) { |
@@ -1394,10 +1416,15 @@ static int psmouse_reconnect(struct serio *serio) | |||
1394 | if (psmouse->reconnect) { | 1416 | if (psmouse->reconnect) { |
1395 | if (psmouse->reconnect(psmouse)) | 1417 | if (psmouse->reconnect(psmouse)) |
1396 | goto out; | 1418 | goto out; |
1397 | } else if (psmouse_probe(psmouse) < 0 || | 1419 | } else { |
1398 | psmouse->type != psmouse_extensions(psmouse, | 1420 | psmouse_reset(psmouse); |
1399 | psmouse_max_proto, false)) { | 1421 | |
1400 | goto out; | 1422 | if (psmouse_probe(psmouse) < 0) |
1423 | goto out; | ||
1424 | |||
1425 | type = psmouse_extensions(psmouse, psmouse_max_proto, false); | ||
1426 | if (psmouse->type != type) | ||
1427 | goto out; | ||
1401 | } | 1428 | } |
1402 | 1429 | ||
1403 | /* ok, the device type (and capabilities) match the old one, | 1430 | /* ok, the device type (and capabilities) match the old one, |
@@ -1557,10 +1584,10 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1557 | if (!new_dev) | 1584 | if (!new_dev) |
1558 | return -ENOMEM; | 1585 | return -ENOMEM; |
1559 | 1586 | ||
1560 | while (serio->child) { | 1587 | while (!list_empty(&serio->children)) { |
1561 | if (++retry > 3) { | 1588 | if (++retry > 3) { |
1562 | printk(KERN_WARNING | 1589 | printk(KERN_WARNING |
1563 | "psmouse: failed to destroy child port, " | 1590 | "psmouse: failed to destroy children ports, " |
1564 | "protocol change aborted.\n"); | 1591 | "protocol change aborted.\n"); |
1565 | input_free_device(new_dev); | 1592 | input_free_device(new_dev); |
1566 | return -EIO; | 1593 | return -EIO; |
@@ -1654,7 +1681,7 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, | |||
1654 | } | 1681 | } |
1655 | 1682 | ||
1656 | 1683 | ||
1657 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) | 1684 | static int psmouse_set_maxproto(const char *val, const struct kernel_param *kp) |
1658 | { | 1685 | { |
1659 | const struct psmouse_protocol *proto; | 1686 | const struct psmouse_protocol *proto; |
1660 | 1687 | ||
@@ -1671,7 +1698,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) | |||
1671 | return 0; | 1698 | return 0; |
1672 | } | 1699 | } |
1673 | 1700 | ||
1674 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) | 1701 | static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp) |
1675 | { | 1702 | { |
1676 | int type = *((unsigned int *)kp->arg); | 1703 | int type = *((unsigned int *)kp->arg); |
1677 | 1704 | ||
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index e053bdd137ff..593e910bfc7a 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -47,6 +47,7 @@ struct psmouse { | |||
47 | unsigned char pktcnt; | 47 | unsigned char pktcnt; |
48 | unsigned char pktsize; | 48 | unsigned char pktsize; |
49 | unsigned char type; | 49 | unsigned char type; |
50 | bool ignore_parity; | ||
50 | bool acks_disable_command; | 51 | bool acks_disable_command; |
51 | unsigned int model; | 52 | unsigned int model; |
52 | unsigned long last; | 53 | unsigned long last; |
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index 1e827ad0afbe..943cfec15665 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
23 | #include <mach/pxa930_trkball.h> | 24 | #include <mach/pxa930_trkball.h> |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 81a6b81cb2fe..1242775fee19 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/libps2.h> | 26 | #include <linux/libps2.h> |
27 | #include <linux/serio.h> | 27 | #include <linux/serio.h> |
28 | #include <linux/jiffies.h> | 28 | #include <linux/jiffies.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include "psmouse.h" | 31 | #include "psmouse.h" |
31 | #include "sentelic.h" | 32 | #include "sentelic.h" |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index d3f5243fa093..2e300a460556 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include <linux/serio.h> | 29 | #include <linux/serio.h> |
30 | #include <linux/libps2.h> | 30 | #include <linux/libps2.h> |
31 | #include <linux/slab.h> | ||
31 | #include "psmouse.h" | 32 | #include "psmouse.h" |
32 | #include "synaptics.h" | 33 | #include "synaptics.h" |
33 | 34 | ||
@@ -35,6 +36,8 @@ | |||
35 | * The x/y limits are taken from the Synaptics TouchPad interfacing Guide, | 36 | * The x/y limits are taken from the Synaptics TouchPad interfacing Guide, |
36 | * section 2.3.2, which says that they should be valid regardless of the | 37 | * section 2.3.2, which says that they should be valid regardless of the |
37 | * actual size of the sensor. | 38 | * actual size of the sensor. |
39 | * Note that newer firmware allows querying device for maximum useable | ||
40 | * coordinates. | ||
38 | */ | 41 | */ |
39 | #define XMIN_NOMINAL 1472 | 42 | #define XMIN_NOMINAL 1472 |
40 | #define XMAX_NOMINAL 5472 | 43 | #define XMAX_NOMINAL 5472 |
@@ -136,9 +139,15 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
136 | if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) | 139 | if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) |
137 | return -1; | 140 | return -1; |
138 | priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 141 | priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
139 | priv->ext_cap = 0; | 142 | priv->ext_cap = priv->ext_cap_0c = 0; |
140 | if (!SYN_CAP_VALID(priv->capabilities)) | 143 | |
144 | /* | ||
145 | * Older firmwares had submodel ID fixed to 0x47 | ||
146 | */ | ||
147 | if (SYN_ID_FULL(priv->identity) < 0x705 && | ||
148 | SYN_CAP_SUBMODEL_ID(priv->capabilities) != 0x47) { | ||
141 | return -1; | 149 | return -1; |
150 | } | ||
142 | 151 | ||
143 | /* | 152 | /* |
144 | * Unless capExtended is set the rest of the flags should be ignored | 153 | * Unless capExtended is set the rest of the flags should be ignored |
@@ -149,7 +158,7 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
149 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { | 158 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { |
150 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { | 159 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { |
151 | printk(KERN_ERR "Synaptics claims to have extended capabilities," | 160 | printk(KERN_ERR "Synaptics claims to have extended capabilities," |
152 | " but I'm not able to read them."); | 161 | " but I'm not able to read them.\n"); |
153 | } else { | 162 | } else { |
154 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 163 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
155 | 164 | ||
@@ -161,6 +170,16 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
161 | priv->ext_cap &= 0xff0fff; | 170 | priv->ext_cap &= 0xff0fff; |
162 | } | 171 | } |
163 | } | 172 | } |
173 | |||
174 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) { | ||
175 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) { | ||
176 | printk(KERN_ERR "Synaptics claims to have extended capability 0x0c," | ||
177 | " but I'm not able to read it.\n"); | ||
178 | } else { | ||
179 | priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | ||
180 | } | ||
181 | } | ||
182 | |||
164 | return 0; | 183 | return 0; |
165 | } | 184 | } |
166 | 185 | ||
@@ -182,23 +201,34 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
182 | } | 201 | } |
183 | 202 | ||
184 | /* | 203 | /* |
185 | * Read touchpad resolution | 204 | * Read touchpad resolution and maximum reported coordinates |
186 | * Resolution is left zero if touchpad does not support the query | 205 | * Resolution is left zero if touchpad does not support the query |
187 | */ | 206 | */ |
188 | static int synaptics_resolution(struct psmouse *psmouse) | 207 | static int synaptics_resolution(struct psmouse *psmouse) |
189 | { | 208 | { |
190 | struct synaptics_data *priv = psmouse->private; | 209 | struct synaptics_data *priv = psmouse->private; |
191 | unsigned char res[3]; | 210 | unsigned char res[3]; |
211 | unsigned char max[3]; | ||
192 | 212 | ||
193 | if (SYN_ID_MAJOR(priv->identity) < 4) | 213 | if (SYN_ID_MAJOR(priv->identity) < 4) |
194 | return 0; | 214 | return 0; |
195 | 215 | ||
196 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res)) | 216 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) { |
197 | return 0; | 217 | if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) { |
218 | priv->x_res = res[0]; /* x resolution in units/mm */ | ||
219 | priv->y_res = res[2]; /* y resolution in units/mm */ | ||
220 | } | ||
221 | } | ||
198 | 222 | ||
199 | if ((res[0] != 0) && (res[1] & 0x80) && (res[2] != 0)) { | 223 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && |
200 | priv->x_res = res[0]; /* x resolution in units/mm */ | 224 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { |
201 | priv->y_res = res[2]; /* y resolution in units/mm */ | 225 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_DIMENSIONS, max)) { |
226 | printk(KERN_ERR "Synaptics claims to have dimensions query," | ||
227 | " but I'm not able to read it.\n"); | ||
228 | } else { | ||
229 | priv->x_max = (max[0] << 5) | ((max[1] & 0x0f) << 1); | ||
230 | priv->y_max = (max[2] << 5) | ((max[1] & 0xf0) >> 3); | ||
231 | } | ||
202 | } | 232 | } |
203 | 233 | ||
204 | return 0; | 234 | return 0; |
@@ -264,7 +294,29 @@ static int synaptics_pt_write(struct serio *serio, unsigned char c) | |||
264 | return 0; | 294 | return 0; |
265 | } | 295 | } |
266 | 296 | ||
267 | static inline int synaptics_is_pt_packet(unsigned char *buf) | 297 | static int synaptics_pt_start(struct serio *serio) |
298 | { | ||
299 | struct psmouse *parent = serio_get_drvdata(serio->parent); | ||
300 | struct synaptics_data *priv = parent->private; | ||
301 | |||
302 | serio_pause_rx(parent->ps2dev.serio); | ||
303 | priv->pt_port = serio; | ||
304 | serio_continue_rx(parent->ps2dev.serio); | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static void synaptics_pt_stop(struct serio *serio) | ||
310 | { | ||
311 | struct psmouse *parent = serio_get_drvdata(serio->parent); | ||
312 | struct synaptics_data *priv = parent->private; | ||
313 | |||
314 | serio_pause_rx(parent->ps2dev.serio); | ||
315 | priv->pt_port = NULL; | ||
316 | serio_continue_rx(parent->ps2dev.serio); | ||
317 | } | ||
318 | |||
319 | static int synaptics_is_pt_packet(unsigned char *buf) | ||
268 | { | 320 | { |
269 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; | 321 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; |
270 | } | 322 | } |
@@ -285,9 +337,8 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet | |||
285 | 337 | ||
286 | static void synaptics_pt_activate(struct psmouse *psmouse) | 338 | static void synaptics_pt_activate(struct psmouse *psmouse) |
287 | { | 339 | { |
288 | struct serio *ptport = psmouse->ps2dev.serio->child; | ||
289 | struct psmouse *child = serio_get_drvdata(ptport); | ||
290 | struct synaptics_data *priv = psmouse->private; | 340 | struct synaptics_data *priv = psmouse->private; |
341 | struct psmouse *child = serio_get_drvdata(priv->pt_port); | ||
291 | 342 | ||
292 | /* adjust the touchpad to child's choice of protocol */ | 343 | /* adjust the touchpad to child's choice of protocol */ |
293 | if (child) { | 344 | if (child) { |
@@ -315,6 +366,8 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
315 | strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); | 366 | strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); |
316 | strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name)); | 367 | strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name)); |
317 | serio->write = synaptics_pt_write; | 368 | serio->write = synaptics_pt_write; |
369 | serio->start = synaptics_pt_start; | ||
370 | serio->stop = synaptics_pt_stop; | ||
318 | serio->parent = psmouse->ps2dev.serio; | 371 | serio->parent = psmouse->ps2dev.serio; |
319 | 372 | ||
320 | psmouse->pt_activate = synaptics_pt_activate; | 373 | psmouse->pt_activate = synaptics_pt_activate; |
@@ -347,7 +400,15 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data | |||
347 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 400 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
348 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 401 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
349 | 402 | ||
350 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | 403 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
404 | /* | ||
405 | * Clickpad's button is transmitted as middle button, | ||
406 | * however, since it is primary button, we will report | ||
407 | * it as BTN_LEFT. | ||
408 | */ | ||
409 | hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; | ||
410 | |||
411 | } else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | ||
351 | hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; | 412 | hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; |
352 | if (hw->w == 2) | 413 | if (hw->w == 2) |
353 | hw->scroll = (signed char)(buf[1]); | 414 | hw->scroll = (signed char)(buf[1]); |
@@ -464,7 +525,9 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
464 | } | 525 | } |
465 | input_report_abs(dev, ABS_PRESSURE, hw.z); | 526 | input_report_abs(dev, ABS_PRESSURE, hw.z); |
466 | 527 | ||
467 | input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); | 528 | if (SYN_CAP_PALMDETECT(priv->capabilities)) |
529 | input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); | ||
530 | |||
468 | input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); | 531 | input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); |
469 | input_report_key(dev, BTN_LEFT, hw.left); | 532 | input_report_key(dev, BTN_LEFT, hw.left); |
470 | input_report_key(dev, BTN_RIGHT, hw.right); | 533 | input_report_key(dev, BTN_RIGHT, hw.right); |
@@ -500,19 +563,20 @@ static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned cha | |||
500 | return 0; | 563 | return 0; |
501 | 564 | ||
502 | switch (pkt_type) { | 565 | switch (pkt_type) { |
503 | case SYN_NEWABS: | ||
504 | case SYN_NEWABS_RELAXED: | ||
505 | return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx]; | ||
506 | 566 | ||
507 | case SYN_NEWABS_STRICT: | 567 | case SYN_NEWABS: |
508 | return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx]; | 568 | case SYN_NEWABS_RELAXED: |
569 | return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx]; | ||
509 | 570 | ||
510 | case SYN_OLDABS: | 571 | case SYN_NEWABS_STRICT: |
511 | return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; | 572 | return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx]; |
512 | 573 | ||
513 | default: | 574 | case SYN_OLDABS: |
514 | printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type); | 575 | return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; |
515 | return 0; | 576 | |
577 | default: | ||
578 | printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type); | ||
579 | return 0; | ||
516 | } | 580 | } |
517 | } | 581 | } |
518 | 582 | ||
@@ -537,9 +601,10 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) | |||
537 | if (unlikely(priv->pkt_type == SYN_NEWABS)) | 601 | if (unlikely(priv->pkt_type == SYN_NEWABS)) |
538 | priv->pkt_type = synaptics_detect_pkt_type(psmouse); | 602 | priv->pkt_type = synaptics_detect_pkt_type(psmouse); |
539 | 603 | ||
540 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && synaptics_is_pt_packet(psmouse->packet)) { | 604 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && |
541 | if (psmouse->ps2dev.serio->child) | 605 | synaptics_is_pt_packet(psmouse->packet)) { |
542 | synaptics_pass_pt_packet(psmouse->ps2dev.serio->child, psmouse->packet); | 606 | if (priv->pt_port) |
607 | synaptics_pass_pt_packet(priv->pt_port, psmouse->packet); | ||
543 | } else | 608 | } else |
544 | synaptics_process_packet(psmouse); | 609 | synaptics_process_packet(psmouse); |
545 | 610 | ||
@@ -558,10 +623,14 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
558 | int i; | 623 | int i; |
559 | 624 | ||
560 | __set_bit(EV_ABS, dev->evbit); | 625 | __set_bit(EV_ABS, dev->evbit); |
561 | input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); | 626 | input_set_abs_params(dev, ABS_X, |
562 | input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); | 627 | XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); |
628 | input_set_abs_params(dev, ABS_Y, | ||
629 | YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); | ||
563 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 630 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
564 | __set_bit(ABS_TOOL_WIDTH, dev->absbit); | 631 | |
632 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | ||
633 | input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); | ||
565 | 634 | ||
566 | __set_bit(EV_KEY, dev->evbit); | 635 | __set_bit(EV_KEY, dev->evbit); |
567 | __set_bit(BTN_TOUCH, dev->keybit); | 636 | __set_bit(BTN_TOUCH, dev->keybit); |
@@ -590,8 +659,14 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
590 | __clear_bit(REL_X, dev->relbit); | 659 | __clear_bit(REL_X, dev->relbit); |
591 | __clear_bit(REL_Y, dev->relbit); | 660 | __clear_bit(REL_Y, dev->relbit); |
592 | 661 | ||
593 | dev->absres[ABS_X] = priv->x_res; | 662 | input_abs_set_res(dev, ABS_X, priv->x_res); |
594 | dev->absres[ABS_Y] = priv->y_res; | 663 | input_abs_set_res(dev, ABS_Y, priv->y_res); |
664 | |||
665 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | ||
666 | /* Clickpads report only left button */ | ||
667 | __clear_bit(BTN_RIGHT, dev->keybit); | ||
668 | __clear_bit(BTN_MIDDLE, dev->keybit); | ||
669 | } | ||
595 | } | 670 | } |
596 | 671 | ||
597 | static void synaptics_disconnect(struct psmouse *psmouse) | 672 | static void synaptics_disconnect(struct psmouse *psmouse) |
@@ -680,7 +755,7 @@ int synaptics_init(struct psmouse *psmouse) | |||
680 | 755 | ||
681 | psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); | 756 | psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); |
682 | if (!priv) | 757 | if (!priv) |
683 | return -1; | 758 | return -ENOMEM; |
684 | 759 | ||
685 | psmouse_reset(psmouse); | 760 | psmouse_reset(psmouse); |
686 | 761 | ||
@@ -696,10 +771,10 @@ int synaptics_init(struct psmouse *psmouse) | |||
696 | 771 | ||
697 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 772 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
698 | 773 | ||
699 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n", | 774 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", |
700 | SYN_ID_MODEL(priv->identity), | 775 | SYN_ID_MODEL(priv->identity), |
701 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), | 776 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), |
702 | priv->model_id, priv->capabilities, priv->ext_cap); | 777 | priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c); |
703 | 778 | ||
704 | set_input_params(psmouse->dev, priv); | 779 | set_input_params(psmouse->dev, priv); |
705 | 780 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index f0f40a331dc8..613a3652f98f 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 | 18 | #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 |
19 | #define SYN_QUE_RESOLUTION 0x08 | 19 | #define SYN_QUE_RESOLUTION 0x08 |
20 | #define SYN_QUE_EXT_CAPAB 0x09 | 20 | #define SYN_QUE_EXT_CAPAB 0x09 |
21 | #define SYN_QUE_EXT_CAPAB_0C 0x0c | ||
22 | #define SYN_QUE_EXT_DIMENSIONS 0x0d | ||
21 | 23 | ||
22 | /* synatics modes */ | 24 | /* synatics modes */ |
23 | #define SYN_BIT_ABSOLUTE_MODE (1 << 7) | 25 | #define SYN_BIT_ABSOLUTE_MODE (1 << 7) |
@@ -45,9 +47,12 @@ | |||
45 | #define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3)) | 47 | #define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3)) |
46 | #define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1)) | 48 | #define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1)) |
47 | #define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0)) | 49 | #define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0)) |
48 | #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) | 50 | #define SYN_CAP_SUBMODEL_ID(c) (((c) & 0x00ff00) >> 8) |
49 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) | 51 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) |
50 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) | 52 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) |
53 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) | ||
54 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100) | ||
55 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) | ||
51 | 56 | ||
52 | /* synaptics modes query bits */ | 57 | /* synaptics modes query bits */ |
53 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 58 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
@@ -61,6 +66,7 @@ | |||
61 | #define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) | 66 | #define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) |
62 | #define SYN_ID_MAJOR(i) ((i) & 0x0f) | 67 | #define SYN_ID_MAJOR(i) ((i) & 0x0f) |
63 | #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) | 68 | #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) |
69 | #define SYN_ID_FULL(i) ((SYN_ID_MAJOR(i) << 8) | SYN_ID_MINOR(i)) | ||
64 | #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) | 70 | #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) |
65 | 71 | ||
66 | /* synaptics special commands */ | 72 | /* synaptics special commands */ |
@@ -96,13 +102,16 @@ struct synaptics_data { | |||
96 | unsigned long int model_id; /* Model-ID */ | 102 | unsigned long int model_id; /* Model-ID */ |
97 | unsigned long int capabilities; /* Capabilities */ | 103 | unsigned long int capabilities; /* Capabilities */ |
98 | unsigned long int ext_cap; /* Extended Capabilities */ | 104 | unsigned long int ext_cap; /* Extended Capabilities */ |
105 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ | ||
99 | unsigned long int identity; /* Identification */ | 106 | unsigned long int identity; /* Identification */ |
100 | int x_res; /* X resolution in units/mm */ | 107 | unsigned int x_res, y_res; /* X/Y resolution in units/mm */ |
101 | int y_res; /* Y resolution in units/mm */ | 108 | unsigned int x_max, y_max; /* Max dimensions (from FW) */ |
102 | 109 | ||
103 | unsigned char pkt_type; /* packet type - old, new, etc */ | 110 | unsigned char pkt_type; /* packet type - old, new, etc */ |
104 | unsigned char mode; /* current mode byte */ | 111 | unsigned char mode; /* current mode byte */ |
105 | int scroll; | 112 | int scroll; |
113 | |||
114 | struct serio *pt_port; /* Pass-through serio port */ | ||
106 | }; | 115 | }; |
107 | 116 | ||
108 | void synaptics_module_init(void); | 117 | void synaptics_module_init(void); |
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index 9867dfe2a638..0ae62f0bcb32 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/input.h> | 17 | #include <linux/input.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
20 | #include <linux/slab.h> | ||
20 | 21 | ||
21 | #define DRIVER_NAME "synaptics_i2c" | 22 | #define DRIVER_NAME "synaptics_i2c" |
22 | /* maximum product id is 15 characters */ | 23 | /* maximum product id is 15 characters */ |
@@ -612,7 +613,6 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client) | |||
612 | free_irq(client->irq, touch); | 613 | free_irq(client->irq, touch); |
613 | 614 | ||
614 | input_unregister_device(touch->input); | 615 | input_unregister_device(touch->input); |
615 | i2c_set_clientdata(client, NULL); | ||
616 | kfree(touch); | 616 | kfree(touch); |
617 | 617 | ||
618 | return 0; | 618 | return 0; |
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c index 909431c31ab4..1fd8f5e192f9 100644 --- a/drivers/input/mouse/touchkit_ps2.c +++ b/drivers/input/mouse/touchkit_ps2.c | |||
@@ -21,12 +21,11 @@ | |||
21 | * | 21 | * |
22 | * Based upon touchkitusb.c | 22 | * Based upon touchkitusb.c |
23 | * | 23 | * |
24 | * Vendor documentation is available in support section of: | 24 | * Vendor documentation is available at: |
25 | * http://www.egalax.com.tw/ | 25 | * http://home.eeti.com.tw/web20/drivers/Software%20Programming%20Guide_v2.0.pdf |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/slab.h> | ||
30 | 29 | ||
31 | #include <linux/input.h> | 30 | #include <linux/input.h> |
32 | #include <linux/serio.h> | 31 | #include <linux/serio.h> |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 63d4a67830f2..54b2fa892e19 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Trademarks are the property of their respective owners. | 8 | * Trademarks are the property of their respective owners. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/slab.h> | ||
11 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
12 | #include <linux/serio.h> | 13 | #include <linux/serio.h> |
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
@@ -302,7 +303,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
302 | 303 | ||
303 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); | 304 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); |
304 | if (!psmouse->private) | 305 | if (!psmouse->private) |
305 | return -1; | 306 | return -ENOMEM; |
306 | 307 | ||
307 | psmouse->vendor = "IBM"; | 308 | psmouse->vendor = "IBM"; |
308 | psmouse->name = "TrackPoint"; | 309 | psmouse->name = "TrackPoint"; |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index a13d80f7da17..2a00ddf4f23a 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/poll.h> | 18 | #include <linux/poll.h> |
20 | #include <linux/module.h> | 19 | #include <linux/module.h> |
21 | #include <linux/init.h> | 20 | #include <linux/init.h> |
@@ -23,6 +22,7 @@ | |||
23 | #include <linux/random.h> | 22 | #include <linux/random.h> |
24 | #include <linux/major.h> | 23 | #include <linux/major.h> |
25 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/kernel.h> | ||
26 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 26 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
27 | #include <linux/miscdevice.h> | 27 | #include <linux/miscdevice.h> |
28 | #endif | 28 | #endif |
@@ -58,7 +58,6 @@ struct mousedev_hw_data { | |||
58 | }; | 58 | }; |
59 | 59 | ||
60 | struct mousedev { | 60 | struct mousedev { |
61 | int exist; | ||
62 | int open; | 61 | int open; |
63 | int minor; | 62 | int minor; |
64 | struct input_handle handle; | 63 | struct input_handle handle; |
@@ -67,6 +66,7 @@ struct mousedev { | |||
67 | spinlock_t client_lock; /* protects client_list */ | 66 | spinlock_t client_lock; /* protects client_list */ |
68 | struct mutex mutex; | 67 | struct mutex mutex; |
69 | struct device dev; | 68 | struct device dev; |
69 | bool exist; | ||
70 | 70 | ||
71 | struct list_head mixdev_node; | 71 | struct list_head mixdev_node; |
72 | int mixdev_open; | 72 | int mixdev_open; |
@@ -135,11 +135,14 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
135 | switch (code) { | 135 | switch (code) { |
136 | 136 | ||
137 | case ABS_X: | 137 | case ABS_X: |
138 | |||
138 | fx(0) = value; | 139 | fx(0) = value; |
139 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 140 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
140 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; | 141 | size = input_abs_get_max(dev, ABS_X) - |
142 | input_abs_get_min(dev, ABS_X); | ||
141 | if (size == 0) | 143 | if (size == 0) |
142 | size = 256 * 2; | 144 | size = 256 * 2; |
145 | |||
143 | tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size; | 146 | tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size; |
144 | tmp += mousedev->frac_dx; | 147 | tmp += mousedev->frac_dx; |
145 | mousedev->packet.dx = tmp / FRACTION_DENOM; | 148 | mousedev->packet.dx = tmp / FRACTION_DENOM; |
@@ -151,10 +154,12 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
151 | case ABS_Y: | 154 | case ABS_Y: |
152 | fy(0) = value; | 155 | fy(0) = value; |
153 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 156 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
154 | /* use X size to keep the same scale */ | 157 | /* use X size for ABS_Y to keep the same scale */ |
155 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; | 158 | size = input_abs_get_max(dev, ABS_X) - |
159 | input_abs_get_min(dev, ABS_X); | ||
156 | if (size == 0) | 160 | if (size == 0) |
157 | size = 256 * 2; | 161 | size = 256 * 2; |
162 | |||
158 | tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size; | 163 | tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size; |
159 | tmp += mousedev->frac_dy; | 164 | tmp += mousedev->frac_dy; |
160 | mousedev->packet.dy = tmp / FRACTION_DENOM; | 165 | mousedev->packet.dy = tmp / FRACTION_DENOM; |
@@ -168,33 +173,35 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
168 | 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, |
169 | unsigned int code, int value) | 174 | unsigned int code, int value) |
170 | { | 175 | { |
171 | int size; | 176 | int min, max, size; |
172 | 177 | ||
173 | switch (code) { | 178 | switch (code) { |
174 | 179 | ||
175 | case ABS_X: | 180 | case ABS_X: |
176 | 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; | ||
177 | if (size == 0) | 185 | if (size == 0) |
178 | size = xres ? : 1; | 186 | size = xres ? : 1; |
179 | if (value > dev->absmax[ABS_X]) | 187 | |
180 | value = dev->absmax[ABS_X]; | 188 | clamp(value, min, max); |
181 | if (value < dev->absmin[ABS_X]) | 189 | |
182 | value = dev->absmin[ABS_X]; | 190 | mousedev->packet.x = ((value - min) * xres) / size; |
183 | mousedev->packet.x = | ||
184 | ((value - dev->absmin[ABS_X]) * xres) / size; | ||
185 | mousedev->packet.abs_event = 1; | 191 | mousedev->packet.abs_event = 1; |
186 | break; | 192 | break; |
187 | 193 | ||
188 | case ABS_Y: | 194 | case ABS_Y: |
189 | 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; | ||
190 | if (size == 0) | 199 | if (size == 0) |
191 | size = yres ? : 1; | 200 | size = yres ? : 1; |
192 | if (value > dev->absmax[ABS_Y]) | 201 | |
193 | value = dev->absmax[ABS_Y]; | 202 | clamp(value, min, max); |
194 | if (value < dev->absmin[ABS_Y]) | 203 | |
195 | value = dev->absmin[ABS_Y]; | 204 | mousedev->packet.y = yres - ((value - min) * yres) / size; |
196 | mousedev->packet.y = yres - | ||
197 | ((value - dev->absmin[ABS_Y]) * yres) / size; | ||
198 | mousedev->packet.abs_event = 1; | 205 | mousedev->packet.abs_event = 1; |
199 | break; | 206 | break; |
200 | } | 207 | } |
@@ -542,10 +549,8 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
542 | if (i >= MOUSEDEV_MINORS) | 549 | if (i >= MOUSEDEV_MINORS) |
543 | return -ENODEV; | 550 | return -ENODEV; |
544 | 551 | ||
545 | lock_kernel(); | ||
546 | error = mutex_lock_interruptible(&mousedev_table_mutex); | 552 | error = mutex_lock_interruptible(&mousedev_table_mutex); |
547 | if (error) { | 553 | if (error) { |
548 | unlock_kernel(); | ||
549 | return error; | 554 | return error; |
550 | } | 555 | } |
551 | mousedev = mousedev_table[i]; | 556 | mousedev = mousedev_table[i]; |
@@ -554,7 +559,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
554 | mutex_unlock(&mousedev_table_mutex); | 559 | mutex_unlock(&mousedev_table_mutex); |
555 | 560 | ||
556 | if (!mousedev) { | 561 | if (!mousedev) { |
557 | unlock_kernel(); | ||
558 | return -ENODEV; | 562 | return -ENODEV; |
559 | } | 563 | } |
560 | 564 | ||
@@ -575,7 +579,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
575 | goto err_free_client; | 579 | goto err_free_client; |
576 | 580 | ||
577 | file->private_data = client; | 581 | file->private_data = client; |
578 | unlock_kernel(); | ||
579 | return 0; | 582 | return 0; |
580 | 583 | ||
581 | err_free_client: | 584 | err_free_client: |
@@ -583,7 +586,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
583 | kfree(client); | 586 | kfree(client); |
584 | err_put_mousedev: | 587 | err_put_mousedev: |
585 | put_device(&mousedev->dev); | 588 | put_device(&mousedev->dev); |
586 | unlock_kernel(); | ||
587 | return error; | 589 | return error; |
588 | } | 590 | } |
589 | 591 | ||
@@ -771,10 +773,15 @@ static unsigned int mousedev_poll(struct file *file, poll_table *wait) | |||
771 | { | 773 | { |
772 | struct mousedev_client *client = file->private_data; | 774 | struct mousedev_client *client = file->private_data; |
773 | struct mousedev *mousedev = client->mousedev; | 775 | struct mousedev *mousedev = client->mousedev; |
776 | unsigned int mask; | ||
774 | 777 | ||
775 | poll_wait(file, &mousedev->wait, wait); | 778 | poll_wait(file, &mousedev->wait, wait); |
776 | return ((client->ready || client->buffer) ? (POLLIN | POLLRDNORM) : 0) | | 779 | |
777 | (mousedev->exist ? 0 : (POLLHUP | POLLERR)); | 780 | mask = mousedev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR; |
781 | if (client->ready || client->buffer) | ||
782 | mask |= POLLIN | POLLRDNORM; | ||
783 | |||
784 | return mask; | ||
778 | } | 785 | } |
779 | 786 | ||
780 | static const struct file_operations mousedev_fops = { | 787 | static const struct file_operations mousedev_fops = { |
@@ -785,6 +792,7 @@ static const struct file_operations mousedev_fops = { | |||
785 | .open = mousedev_open, | 792 | .open = mousedev_open, |
786 | .release = mousedev_release, | 793 | .release = mousedev_release, |
787 | .fasync = mousedev_fasync, | 794 | .fasync = mousedev_fasync, |
795 | .llseek = noop_llseek, | ||
788 | }; | 796 | }; |
789 | 797 | ||
790 | static int mousedev_install_chrdev(struct mousedev *mousedev) | 798 | static int mousedev_install_chrdev(struct mousedev *mousedev) |
@@ -808,7 +816,7 @@ static void mousedev_remove_chrdev(struct mousedev *mousedev) | |||
808 | static void mousedev_mark_dead(struct mousedev *mousedev) | 816 | static void mousedev_mark_dead(struct mousedev *mousedev) |
809 | { | 817 | { |
810 | mutex_lock(&mousedev->mutex); | 818 | mutex_lock(&mousedev->mutex); |
811 | mousedev->exist = 0; | 819 | mousedev->exist = false; |
812 | mutex_unlock(&mousedev->mutex); | 820 | mutex_unlock(&mousedev->mutex); |
813 | } | 821 | } |
814 | 822 | ||
@@ -859,7 +867,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
859 | spin_lock_init(&mousedev->client_lock); | 867 | spin_lock_init(&mousedev->client_lock); |
860 | mutex_init(&mousedev->mutex); | 868 | mutex_init(&mousedev->mutex); |
861 | lockdep_set_subclass(&mousedev->mutex, | 869 | lockdep_set_subclass(&mousedev->mutex, |
862 | minor == MOUSEDEV_MIX ? MOUSEDEV_MIX : 0); | 870 | minor == MOUSEDEV_MIX ? SINGLE_DEPTH_NESTING : 0); |
863 | init_waitqueue_head(&mousedev->wait); | 871 | init_waitqueue_head(&mousedev->wait); |
864 | 872 | ||
865 | if (minor == MOUSEDEV_MIX) | 873 | if (minor == MOUSEDEV_MIX) |
@@ -868,7 +876,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
868 | dev_set_name(&mousedev->dev, "mouse%d", minor); | 876 | dev_set_name(&mousedev->dev, "mouse%d", minor); |
869 | 877 | ||
870 | mousedev->minor = minor; | 878 | mousedev->minor = minor; |
871 | mousedev->exist = 1; | 879 | mousedev->exist = true; |
872 | mousedev->handle.dev = input_get_device(dev); | 880 | mousedev->handle.dev = input_get_device(dev); |
873 | mousedev->handle.name = dev_name(&mousedev->dev); | 881 | mousedev->handle.name = dev_name(&mousedev->dev); |
874 | mousedev->handle.handler = handler; | 882 | mousedev->handle.handler = handler; |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 7e319d65ec57..6256233d2bfb 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -21,7 +21,8 @@ if SERIO | |||
21 | config SERIO_I8042 | 21 | config SERIO_I8042 |
22 | tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86 | 22 | tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86 |
23 | default y | 23 | default y |
24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K && !BLACKFIN | 24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ |
25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN | ||
25 | help | 26 | help |
26 | i8042 is the chip over which the standard AT keyboard and PS/2 | 27 | i8042 is the chip over which the standard AT keyboard and PS/2 |
27 | mouse are connected to the computer. If you use these devices, | 28 | mouse are connected to the computer. If you use these devices, |
@@ -209,4 +210,29 @@ config SERIO_ALTERA_PS2 | |||
209 | To compile this driver as a module, choose M here: the | 210 | To compile this driver as a module, choose M here: the |
210 | module will be called altera_ps2. | 211 | module will be called altera_ps2. |
211 | 212 | ||
213 | config SERIO_AMS_DELTA | ||
214 | tristate "Amstrad Delta (E3) mailboard support" | ||
215 | depends on MACH_AMS_DELTA | ||
216 | default y | ||
217 | select AMS_DELTA_FIQ | ||
218 | ---help--- | ||
219 | Say Y here if you have an E3 and want to use its mailboard, | ||
220 | or any standard AT keyboard connected to the mailboard port. | ||
221 | |||
222 | When used for the E3 mailboard, a non-standard key table | ||
223 | must be loaded from userspace, possibly using udev extras | ||
224 | provided keymap helper utility. | ||
225 | |||
226 | To compile this driver as a module, choose M here; | ||
227 | the module will be called ams_delta_serio. | ||
228 | |||
229 | config SERIO_PS2MULT | ||
230 | tristate "TQC PS/2 multiplexer" | ||
231 | help | ||
232 | Say Y here if you have the PS/2 line multiplexer like the one | ||
233 | present on TQC boads. | ||
234 | |||
235 | To compile this driver as a module, choose M here: the | ||
236 | module will be called ps2mult. | ||
237 | |||
212 | endif | 238 | endif |
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index bf945f789d05..dbbe37616c92 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -18,8 +18,10 @@ obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o | |||
18 | obj-$(CONFIG_HP_SDC) += hp_sdc.o | 18 | obj-$(CONFIG_HP_SDC) += hp_sdc.o |
19 | obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o | 19 | obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o |
20 | obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o | 20 | obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o |
21 | obj-$(CONFIG_SERIO_PS2MULT) += ps2mult.o | ||
21 | obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o | 22 | obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o |
22 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o | 23 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o |
23 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o | 24 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o |
25 | obj-$(CONFIG_SERIO_AMS_DELTA) += ams_delta_serio.o | ||
24 | obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o | 26 | obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o |
25 | obj-$(CONFIG_SERIO_ALTERA_PS2) += altera_ps2.o | 27 | obj-$(CONFIG_SERIO_ALTERA_PS2) += altera_ps2.o |
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index 320b7ca48bf8..7998560a1904 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | #define DRV_NAME "altera_ps2" | 23 | #define DRV_NAME "altera_ps2" |
23 | 24 | ||
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c new file mode 100644 index 000000000000..8f1770e1e08b --- /dev/null +++ b/drivers/input/serio/ams_delta_serio.c | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | * Amstrad E3 (Delta) keyboard port driver | ||
3 | * | ||
4 | * Copyright (c) 2006 Matt Callow | ||
5 | * Copyright (c) 2010 Janusz Krzysztofik | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * Thanks to Cliff Lawson for his help | ||
12 | * | ||
13 | * The Amstrad Delta keyboard (aka mailboard) uses normal PC-AT style serial | ||
14 | * transmission. The keyboard port is formed of two GPIO lines, for clock | ||
15 | * and data. Due to strict timing requirements of the interface, | ||
16 | * the serial data stream is read and processed by a FIQ handler. | ||
17 | * The resulting words are fetched by this driver from a circular buffer. | ||
18 | * | ||
19 | * Standard AT keyboard driver (atkbd) is used for handling the keyboard data. | ||
20 | * However, when used with the E3 mailboard that producecs non-standard | ||
21 | * scancodes, a custom key table must be prepared and loaded from userspace. | ||
22 | */ | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/irq.h> | ||
25 | #include <linux/serio.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #include <asm/mach-types.h> | ||
29 | #include <plat/board-ams-delta.h> | ||
30 | |||
31 | #include <mach/ams-delta-fiq.h> | ||
32 | |||
33 | MODULE_AUTHOR("Matt Callow"); | ||
34 | MODULE_DESCRIPTION("AMS Delta (E3) keyboard port driver"); | ||
35 | MODULE_LICENSE("GPL"); | ||
36 | |||
37 | static struct serio *ams_delta_serio; | ||
38 | |||
39 | static int check_data(int data) | ||
40 | { | ||
41 | int i, parity = 0; | ||
42 | |||
43 | /* check valid stop bit */ | ||
44 | if (!(data & 0x400)) { | ||
45 | dev_warn(&ams_delta_serio->dev, | ||
46 | "invalid stop bit, data=0x%X\n", | ||
47 | data); | ||
48 | return SERIO_FRAME; | ||
49 | } | ||
50 | /* calculate the parity */ | ||
51 | for (i = 1; i < 10; i++) { | ||
52 | if (data & (1 << i)) | ||
53 | parity++; | ||
54 | } | ||
55 | /* it should be odd */ | ||
56 | if (!(parity & 0x01)) { | ||
57 | dev_warn(&ams_delta_serio->dev, | ||
58 | "paritiy check failed, data=0x%X parity=0x%X\n", | ||
59 | data, parity); | ||
60 | return SERIO_PARITY; | ||
61 | } | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static irqreturn_t ams_delta_serio_interrupt(int irq, void *dev_id) | ||
66 | { | ||
67 | int *circ_buff = &fiq_buffer[FIQ_CIRC_BUFF]; | ||
68 | int data, dfl; | ||
69 | u8 scancode; | ||
70 | |||
71 | fiq_buffer[FIQ_IRQ_PEND] = 0; | ||
72 | |||
73 | /* | ||
74 | * Read data from the circular buffer, check it | ||
75 | * and then pass it on the serio | ||
76 | */ | ||
77 | while (fiq_buffer[FIQ_KEYS_CNT] > 0) { | ||
78 | |||
79 | data = circ_buff[fiq_buffer[FIQ_HEAD_OFFSET]++]; | ||
80 | fiq_buffer[FIQ_KEYS_CNT]--; | ||
81 | if (fiq_buffer[FIQ_HEAD_OFFSET] == fiq_buffer[FIQ_BUF_LEN]) | ||
82 | fiq_buffer[FIQ_HEAD_OFFSET] = 0; | ||
83 | |||
84 | dfl = check_data(data); | ||
85 | scancode = (u8) (data >> 1) & 0xFF; | ||
86 | serio_interrupt(ams_delta_serio, scancode, dfl); | ||
87 | } | ||
88 | return IRQ_HANDLED; | ||
89 | } | ||
90 | |||
91 | static int ams_delta_serio_open(struct serio *serio) | ||
92 | { | ||
93 | /* enable keyboard */ | ||
94 | ams_delta_latch2_write(AMD_DELTA_LATCH2_KEYBRD_PWR, | ||
95 | AMD_DELTA_LATCH2_KEYBRD_PWR); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static void ams_delta_serio_close(struct serio *serio) | ||
101 | { | ||
102 | /* disable keyboard */ | ||
103 | ams_delta_latch2_write(AMD_DELTA_LATCH2_KEYBRD_PWR, 0); | ||
104 | } | ||
105 | |||
106 | static int __init ams_delta_serio_init(void) | ||
107 | { | ||
108 | int err; | ||
109 | |||
110 | if (!machine_is_ams_delta()) | ||
111 | return -ENODEV; | ||
112 | |||
113 | ams_delta_serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
114 | if (!ams_delta_serio) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | ams_delta_serio->id.type = SERIO_8042; | ||
118 | ams_delta_serio->open = ams_delta_serio_open; | ||
119 | ams_delta_serio->close = ams_delta_serio_close; | ||
120 | strlcpy(ams_delta_serio->name, "AMS DELTA keyboard adapter", | ||
121 | sizeof(ams_delta_serio->name)); | ||
122 | strlcpy(ams_delta_serio->phys, "GPIO/serio0", | ||
123 | sizeof(ams_delta_serio->phys)); | ||
124 | |||
125 | err = gpio_request(AMS_DELTA_GPIO_PIN_KEYBRD_DATA, "serio-data"); | ||
126 | if (err) { | ||
127 | pr_err("ams_delta_serio: Couldn't request gpio pin for data\n"); | ||
128 | goto serio; | ||
129 | } | ||
130 | gpio_direction_input(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); | ||
131 | |||
132 | err = gpio_request(AMS_DELTA_GPIO_PIN_KEYBRD_CLK, "serio-clock"); | ||
133 | if (err) { | ||
134 | pr_err("ams_delta_serio: couldn't request gpio pin for clock\n"); | ||
135 | goto gpio_data; | ||
136 | } | ||
137 | gpio_direction_input(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); | ||
138 | |||
139 | err = request_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), | ||
140 | ams_delta_serio_interrupt, IRQ_TYPE_EDGE_RISING, | ||
141 | "ams-delta-serio", 0); | ||
142 | if (err < 0) { | ||
143 | pr_err("ams_delta_serio: couldn't request gpio interrupt %d\n", | ||
144 | gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK)); | ||
145 | goto gpio_clk; | ||
146 | } | ||
147 | /* | ||
148 | * Since GPIO register handling for keyboard clock pin is performed | ||
149 | * at FIQ level, switch back from edge to simple interrupt handler | ||
150 | * to avoid bad interaction. | ||
151 | */ | ||
152 | set_irq_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), | ||
153 | handle_simple_irq); | ||
154 | |||
155 | serio_register_port(ams_delta_serio); | ||
156 | dev_info(&ams_delta_serio->dev, "%s\n", ams_delta_serio->name); | ||
157 | |||
158 | return 0; | ||
159 | gpio_clk: | ||
160 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); | ||
161 | gpio_data: | ||
162 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); | ||
163 | serio: | ||
164 | kfree(ams_delta_serio); | ||
165 | return err; | ||
166 | } | ||
167 | module_init(ams_delta_serio_init); | ||
168 | |||
169 | static void __exit ams_delta_serio_exit(void) | ||
170 | { | ||
171 | serio_unregister_port(ams_delta_serio); | ||
172 | free_irq(OMAP_GPIO_IRQ(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0); | ||
173 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); | ||
174 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); | ||
175 | kfree(ams_delta_serio); | ||
176 | } | ||
177 | module_exit(ams_delta_serio_exit); | ||
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index b54452a8c771..6ee8f0ddad51 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | /* PSIF register offsets */ | 23 | /* PSIF register offsets */ |
23 | #define PSIF_CR 0x00 | 24 | #define PSIF_CR 0x00 |
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index d1380fc72cc6..4a3084695c00 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
36 | #include <linux/err.h> | 36 | #include <linux/err.h> |
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/slab.h> | ||
38 | 39 | ||
39 | #include <asm/io.h> | 40 | #include <asm/io.h> |
40 | 41 | ||
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 06addfa7cc47..3c287dd879d3 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/slab.h> | ||
27 | #include <linux/serio.h> | 28 | #include <linux/serio.h> |
28 | #include <linux/input.h> | 29 | #include <linux/input.h> |
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 6cd03ebaf5fb..e5624d8f1709 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/module.h> | 58 | #include <linux/module.h> |
59 | #include <linux/init.h> | 59 | #include <linux/init.h> |
60 | #include <linux/interrupt.h> | 60 | #include <linux/interrupt.h> |
61 | #include <linux/slab.h> | ||
61 | #include <linux/timer.h> | 62 | #include <linux/timer.h> |
62 | #include <linux/list.h> | 63 | #include <linux/list.h> |
63 | 64 | ||
@@ -914,15 +915,15 @@ int hil_mlc_register(hil_mlc *mlc) | |||
914 | mlc->ostarted = 0; | 915 | mlc->ostarted = 0; |
915 | 916 | ||
916 | rwlock_init(&mlc->lock); | 917 | rwlock_init(&mlc->lock); |
917 | init_MUTEX(&mlc->osem); | 918 | sema_init(&mlc->osem, 1); |
918 | 919 | ||
919 | init_MUTEX(&mlc->isem); | 920 | sema_init(&mlc->isem, 1); |
920 | mlc->icount = -1; | 921 | mlc->icount = -1; |
921 | mlc->imatch = 0; | 922 | mlc->imatch = 0; |
922 | 923 | ||
923 | mlc->opercnt = 0; | 924 | mlc->opercnt = 0; |
924 | 925 | ||
925 | init_MUTEX_LOCKED(&(mlc->csem)); | 926 | sema_init(&(mlc->csem), 0); |
926 | 927 | ||
927 | hil_mlc_clear_di_scratch(mlc); | 928 | hil_mlc_clear_di_scratch(mlc); |
928 | hil_mlc_clear_di_map(mlc, 0); | 929 | hil_mlc_clear_di_map(mlc, 0); |
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index bcc2d30ec245..8c0b51c31424 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
@@ -905,7 +905,7 @@ static int __init hp_sdc_init(void) | |||
905 | ts_sync[1] = 0x0f; | 905 | ts_sync[1] = 0x0f; |
906 | ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0; | 906 | ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0; |
907 | t_sync.act.semaphore = &s_sync; | 907 | t_sync.act.semaphore = &s_sync; |
908 | init_MUTEX_LOCKED(&s_sync); | 908 | sema_init(&s_sync, 0); |
909 | hp_sdc_enqueue_transaction(&t_sync); | 909 | hp_sdc_enqueue_transaction(&t_sync); |
910 | down(&s_sync); /* Wait for t_sync to complete */ | 910 | down(&s_sync); /* Wait for t_sync to complete */ |
911 | 911 | ||
@@ -1039,7 +1039,7 @@ static int __init hp_sdc_register(void) | |||
1039 | return hp_sdc.dev_err; | 1039 | return hp_sdc.dev_err; |
1040 | } | 1040 | } |
1041 | 1041 | ||
1042 | init_MUTEX_LOCKED(&tq_init_sem); | 1042 | sema_init(&tq_init_sem, 0); |
1043 | 1043 | ||
1044 | tq_init.actidx = 0; | 1044 | tq_init.actidx = 0; |
1045 | tq_init.idx = 1; | 1045 | tq_init.idx = 1; |
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h index 847f4aad7ed5..5d48bb66aa73 100644 --- a/drivers/input/serio/i8042-io.h +++ b/drivers/input/serio/i8042-io.h | |||
@@ -27,6 +27,11 @@ | |||
27 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
28 | #elif defined(CONFIG_SH_CAYMAN) | 28 | #elif defined(CONFIG_SH_CAYMAN) |
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | #elif defined(CONFIG_PPC) | ||
31 | extern int of_i8042_kbd_irq; | ||
32 | extern int of_i8042_aux_irq; | ||
33 | # define I8042_KBD_IRQ of_i8042_kbd_irq | ||
34 | # define I8042_AUX_IRQ of_i8042_aux_irq | ||
30 | #else | 35 | #else |
31 | # define I8042_KBD_IRQ 1 | 36 | # define I8042_KBD_IRQ 1 |
32 | # define I8042_AUX_IRQ 12 | 37 | # define I8042_AUX_IRQ 12 |
diff --git a/drivers/input/serio/i8042-ppcio.h b/drivers/input/serio/i8042-ppcio.h index 2906e1b60c04..f708c75d16f1 100644 --- a/drivers/input/serio/i8042-ppcio.h +++ b/drivers/input/serio/i8042-ppcio.h | |||
@@ -52,81 +52,6 @@ static inline void i8042_platform_exit(void) | |||
52 | { | 52 | { |
53 | } | 53 | } |
54 | 54 | ||
55 | #elif defined(CONFIG_SPRUCE) | ||
56 | |||
57 | #define I8042_KBD_IRQ 22 | ||
58 | #define I8042_AUX_IRQ 21 | ||
59 | |||
60 | #define I8042_KBD_PHYS_DESC "spruceps2/serio0" | ||
61 | #define I8042_AUX_PHYS_DESC "spruceps2/serio1" | ||
62 | #define I8042_MUX_PHYS_DESC "spruceps2/serio%d" | ||
63 | |||
64 | #define I8042_COMMAND_REG 0xff810000 | ||
65 | #define I8042_DATA_REG 0xff810001 | ||
66 | |||
67 | static inline int i8042_read_data(void) | ||
68 | { | ||
69 | unsigned long kbd_data; | ||
70 | |||
71 | __raw_writel(0x00000088, 0xff500008); | ||
72 | eieio(); | ||
73 | |||
74 | __raw_writel(0x03000000, 0xff50000c); | ||
75 | eieio(); | ||
76 | |||
77 | asm volatile("lis 7,0xff88 \n\ | ||
78 | lswi 6,7,0x8 \n\ | ||
79 | mr %0,6" | ||
80 | : "=r" (kbd_data) :: "6", "7"); | ||
81 | |||
82 | __raw_writel(0x00000000, 0xff50000c); | ||
83 | eieio(); | ||
84 | |||
85 | return (unsigned char)(kbd_data >> 24); | ||
86 | } | ||
87 | |||
88 | static inline int i8042_read_status(void) | ||
89 | { | ||
90 | unsigned long kbd_status; | ||
91 | |||
92 | __raw_writel(0x00000088, 0xff500008); | ||
93 | eieio(); | ||
94 | |||
95 | __raw_writel(0x03000000, 0xff50000c); | ||
96 | eieio(); | ||
97 | |||
98 | asm volatile("lis 7,0xff88 \n\ | ||
99 | ori 7,7,0x8 \n\ | ||
100 | lswi 6,7,0x8 \n\ | ||
101 | mr %0,6" | ||
102 | : "=r" (kbd_status) :: "6", "7"); | ||
103 | |||
104 | __raw_writel(0x00000000, 0xff50000c); | ||
105 | eieio(); | ||
106 | |||
107 | return (unsigned char)(kbd_status >> 24); | ||
108 | } | ||
109 | |||
110 | static inline void i8042_write_data(int val) | ||
111 | { | ||
112 | *((unsigned char *)0xff810000) = (char)val; | ||
113 | } | ||
114 | |||
115 | static inline void i8042_write_command(int val) | ||
116 | { | ||
117 | *((unsigned char *)0xff810001) = (char)val; | ||
118 | } | ||
119 | |||
120 | static inline int i8042_platform_init(void) | ||
121 | { | ||
122 | i8042_reset = 1; | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static inline void i8042_platform_exit(void) | ||
127 | { | ||
128 | } | ||
129 | |||
130 | #else | 55 | #else |
131 | 56 | ||
132 | #include "i8042-io.h" | 57 | #include "i8042-io.h" |
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 5071af2c0604..c5cc4508d6df 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h | |||
@@ -49,28 +49,28 @@ static inline void i8042_write_command(int val) | |||
49 | #define OBP_PS2MS_NAME1 "kdmouse" | 49 | #define OBP_PS2MS_NAME1 "kdmouse" |
50 | #define OBP_PS2MS_NAME2 "mouse" | 50 | #define OBP_PS2MS_NAME2 "mouse" |
51 | 51 | ||
52 | static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_device_id *match) | 52 | static int __devinit sparc_i8042_probe(struct platform_device *op, const struct of_device_id *match) |
53 | { | 53 | { |
54 | struct device_node *dp = op->node; | 54 | struct device_node *dp = op->dev.of_node; |
55 | 55 | ||
56 | dp = dp->child; | 56 | dp = dp->child; |
57 | while (dp) { | 57 | while (dp) { |
58 | if (!strcmp(dp->name, OBP_PS2KBD_NAME1) || | 58 | if (!strcmp(dp->name, OBP_PS2KBD_NAME1) || |
59 | !strcmp(dp->name, OBP_PS2KBD_NAME2)) { | 59 | !strcmp(dp->name, OBP_PS2KBD_NAME2)) { |
60 | struct of_device *kbd = of_find_device_by_node(dp); | 60 | struct platform_device *kbd = of_find_device_by_node(dp); |
61 | unsigned int irq = kbd->irqs[0]; | 61 | unsigned int irq = kbd->archdata.irqs[0]; |
62 | if (irq == 0xffffffff) | 62 | if (irq == 0xffffffff) |
63 | irq = op->irqs[0]; | 63 | irq = op->archdata.irqs[0]; |
64 | i8042_kbd_irq = irq; | 64 | i8042_kbd_irq = irq; |
65 | kbd_iobase = of_ioremap(&kbd->resource[0], | 65 | kbd_iobase = of_ioremap(&kbd->resource[0], |
66 | 0, 8, "kbd"); | 66 | 0, 8, "kbd"); |
67 | kbd_res = &kbd->resource[0]; | 67 | kbd_res = &kbd->resource[0]; |
68 | } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) || | 68 | } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) || |
69 | !strcmp(dp->name, OBP_PS2MS_NAME2)) { | 69 | !strcmp(dp->name, OBP_PS2MS_NAME2)) { |
70 | struct of_device *ms = of_find_device_by_node(dp); | 70 | struct platform_device *ms = of_find_device_by_node(dp); |
71 | unsigned int irq = ms->irqs[0]; | 71 | unsigned int irq = ms->archdata.irqs[0]; |
72 | if (irq == 0xffffffff) | 72 | if (irq == 0xffffffff) |
73 | irq = op->irqs[0]; | 73 | irq = op->archdata.irqs[0]; |
74 | i8042_aux_irq = irq; | 74 | i8042_aux_irq = irq; |
75 | } | 75 | } |
76 | 76 | ||
@@ -80,7 +80,7 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev | |||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int __devexit sparc_i8042_remove(struct of_device *op) | 83 | static int __devexit sparc_i8042_remove(struct platform_device *op) |
84 | { | 84 | { |
85 | of_iounmap(kbd_res, kbd_iobase, 8); | 85 | of_iounmap(kbd_res, kbd_iobase, 8); |
86 | 86 | ||
@@ -96,8 +96,11 @@ static const struct of_device_id sparc_i8042_match[] = { | |||
96 | MODULE_DEVICE_TABLE(of, sparc_i8042_match); | 96 | MODULE_DEVICE_TABLE(of, sparc_i8042_match); |
97 | 97 | ||
98 | static struct of_platform_driver sparc_i8042_driver = { | 98 | static struct of_platform_driver sparc_i8042_driver = { |
99 | .name = "i8042", | 99 | .driver = { |
100 | .match_table = sparc_i8042_match, | 100 | .name = "i8042", |
101 | .owner = THIS_MODULE, | ||
102 | .of_match_table = sparc_i8042_match, | ||
103 | }, | ||
101 | .probe = sparc_i8042_probe, | 104 | .probe = sparc_i8042_probe, |
102 | .remove = __devexit_p(sparc_i8042_remove), | 105 | .remove = __devexit_p(sparc_i8042_remove), |
103 | }; | 106 | }; |
@@ -113,8 +116,7 @@ static int __init i8042_platform_init(void) | |||
113 | if (!kbd_iobase) | 116 | if (!kbd_iobase) |
114 | return -ENODEV; | 117 | return -ENODEV; |
115 | } else { | 118 | } else { |
116 | int err = of_register_driver(&sparc_i8042_driver, | 119 | int err = of_register_platform_driver(&sparc_i8042_driver); |
117 | &of_bus_type); | ||
118 | if (err) | 120 | if (err) |
119 | return err; | 121 | return err; |
120 | 122 | ||
@@ -138,7 +140,7 @@ static inline void i8042_platform_exit(void) | |||
138 | struct device_node *root = of_find_node_by_path("/"); | 140 | struct device_node *root = of_find_node_by_path("/"); |
139 | 141 | ||
140 | if (strcmp(root->name, "SUNW,JavaStation-1")) | 142 | if (strcmp(root->name, "SUNW,JavaStation-1")) |
141 | of_unregister_driver(&sparc_i8042_driver); | 143 | of_unregister_platform_driver(&sparc_i8042_driver); |
142 | } | 144 | } |
143 | 145 | ||
144 | #else /* !CONFIG_PCI */ | 146 | #else /* !CONFIG_PCI */ |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 2a5982e532f8..ed7ad7416b24 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -7,6 +7,10 @@ | |||
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #ifdef CONFIG_X86 | ||
11 | #include <asm/x86_init.h> | ||
12 | #endif | ||
13 | |||
10 | /* | 14 | /* |
11 | * Names. | 15 | * Names. |
12 | */ | 16 | */ |
@@ -166,6 +170,13 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { | |||
166 | }, | 170 | }, |
167 | }, | 171 | }, |
168 | { | 172 | { |
173 | /* Gigabyte Spring Peak - defines wrong chassis type */ | ||
174 | .matches = { | ||
175 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
176 | DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"), | ||
177 | }, | ||
178 | }, | ||
179 | { | ||
169 | .matches = { | 180 | .matches = { |
170 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 181 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
171 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), | 182 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), |
@@ -442,6 +453,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { | |||
442 | }, | 453 | }, |
443 | }, | 454 | }, |
444 | { | 455 | { |
456 | /* Medion Akoya E1222 */ | ||
457 | .matches = { | ||
458 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), | ||
459 | DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), | ||
460 | }, | ||
461 | }, | ||
462 | { | ||
445 | /* Mivvy M310 */ | 463 | /* Mivvy M310 */ |
446 | .matches = { | 464 | .matches = { |
447 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), | 465 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), |
@@ -624,6 +642,9 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * | |||
624 | strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); | 642 | strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); |
625 | } | 643 | } |
626 | 644 | ||
645 | /* Keyboard ports are always supposed to be wakeup-enabled */ | ||
646 | device_set_wakeup_enable(&dev->dev, true); | ||
647 | |||
627 | i8042_pnp_kbd_devices++; | 648 | i8042_pnp_kbd_devices++; |
628 | return 0; | 649 | return 0; |
629 | } | 650 | } |
@@ -650,8 +671,21 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id * | |||
650 | } | 671 | } |
651 | 672 | ||
652 | static struct pnp_device_id pnp_kbd_devids[] = { | 673 | static struct pnp_device_id pnp_kbd_devids[] = { |
674 | { .id = "PNP0300", .driver_data = 0 }, | ||
675 | { .id = "PNP0301", .driver_data = 0 }, | ||
676 | { .id = "PNP0302", .driver_data = 0 }, | ||
653 | { .id = "PNP0303", .driver_data = 0 }, | 677 | { .id = "PNP0303", .driver_data = 0 }, |
678 | { .id = "PNP0304", .driver_data = 0 }, | ||
679 | { .id = "PNP0305", .driver_data = 0 }, | ||
680 | { .id = "PNP0306", .driver_data = 0 }, | ||
681 | { .id = "PNP0309", .driver_data = 0 }, | ||
682 | { .id = "PNP030a", .driver_data = 0 }, | ||
654 | { .id = "PNP030b", .driver_data = 0 }, | 683 | { .id = "PNP030b", .driver_data = 0 }, |
684 | { .id = "PNP0320", .driver_data = 0 }, | ||
685 | { .id = "PNP0343", .driver_data = 0 }, | ||
686 | { .id = "PNP0344", .driver_data = 0 }, | ||
687 | { .id = "PNP0345", .driver_data = 0 }, | ||
688 | { .id = "CPQA0D7", .driver_data = 0 }, | ||
655 | { .id = "", }, | 689 | { .id = "", }, |
656 | }; | 690 | }; |
657 | 691 | ||
@@ -662,6 +696,7 @@ static struct pnp_driver i8042_pnp_kbd_driver = { | |||
662 | }; | 696 | }; |
663 | 697 | ||
664 | static struct pnp_device_id pnp_aux_devids[] = { | 698 | static struct pnp_device_id pnp_aux_devids[] = { |
699 | { .id = "AUI0200", .driver_data = 0 }, | ||
665 | { .id = "FJC6000", .driver_data = 0 }, | 700 | { .id = "FJC6000", .driver_data = 0 }, |
666 | { .id = "FJC6001", .driver_data = 0 }, | 701 | { .id = "FJC6001", .driver_data = 0 }, |
667 | { .id = "PNP0f03", .driver_data = 0 }, | 702 | { .id = "PNP0f03", .driver_data = 0 }, |
@@ -816,6 +851,12 @@ static int __init i8042_platform_init(void) | |||
816 | { | 851 | { |
817 | int retval; | 852 | int retval; |
818 | 853 | ||
854 | #ifdef CONFIG_X86 | ||
855 | /* Just return if pre-detection shows no i8042 controller exist */ | ||
856 | if (!x86_platform.i8042_detect()) | ||
857 | return -ENODEV; | ||
858 | #endif | ||
859 | |||
819 | /* | 860 | /* |
820 | * On ix86 platforms touching the i8042 data register region can do really | 861 | * On ix86 platforms touching the i8042 data register region can do really |
821 | * bad things. Because of this the region is always reserved on ix86 boxes. | 862 | * bad things. Because of this the region is always reserved on ix86 boxes. |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index d84a36e545f6..18db5a8c7478 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/rcupdate.h> | 21 | #include <linux/rcupdate.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/i8042.h> | 23 | #include <linux/i8042.h> |
24 | #include <linux/slab.h> | ||
24 | 25 | ||
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
26 | 27 | ||
@@ -38,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); | |||
38 | 39 | ||
39 | static bool i8042_nomux; | 40 | static bool i8042_nomux; |
40 | module_param_named(nomux, i8042_nomux, bool, 0); | 41 | module_param_named(nomux, i8042_nomux, bool, 0); |
41 | MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present."); | 42 | MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present."); |
42 | 43 | ||
43 | static bool i8042_unlock; | 44 | static bool i8042_unlock; |
44 | module_param_named(unlock, i8042_unlock, bool, 0); | 45 | module_param_named(unlock, i8042_unlock, bool, 0); |
@@ -60,10 +61,6 @@ static bool i8042_noloop; | |||
60 | module_param_named(noloop, i8042_noloop, bool, 0); | 61 | module_param_named(noloop, i8042_noloop, bool, 0); |
61 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); | 62 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); |
62 | 63 | ||
63 | static unsigned int i8042_blink_frequency = 500; | ||
64 | module_param_named(panicblink, i8042_blink_frequency, uint, 0600); | ||
65 | MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics"); | ||
66 | |||
67 | #ifdef CONFIG_X86 | 64 | #ifdef CONFIG_X86 |
68 | static bool i8042_dritek; | 65 | static bool i8042_dritek; |
69 | module_param_named(dritek, i8042_dritek, bool, 0); | 66 | module_param_named(dritek, i8042_dritek, bool, 0); |
@@ -430,7 +427,7 @@ static bool i8042_filter(unsigned char data, unsigned char str, | |||
430 | } | 427 | } |
431 | 428 | ||
432 | if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) { | 429 | if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) { |
433 | dbg("Filtered out by platfrom filter\n"); | 430 | dbg("Filtered out by platform filter\n"); |
434 | return true; | 431 | return true; |
435 | } | 432 | } |
436 | 433 | ||
@@ -860,9 +857,6 @@ static int i8042_controller_selftest(void) | |||
860 | unsigned char param; | 857 | unsigned char param; |
861 | int i = 0; | 858 | int i = 0; |
862 | 859 | ||
863 | if (!i8042_reset) | ||
864 | return 0; | ||
865 | |||
866 | /* | 860 | /* |
867 | * We try this 5 times; on some really fragile systems this does not | 861 | * We try this 5 times; on some really fragile systems this does not |
868 | * take the first time... | 862 | * take the first time... |
@@ -1019,7 +1013,8 @@ static void i8042_controller_reset(void) | |||
1019 | * Reset the controller if requested. | 1013 | * Reset the controller if requested. |
1020 | */ | 1014 | */ |
1021 | 1015 | ||
1022 | i8042_controller_selftest(); | 1016 | if (i8042_reset) |
1017 | i8042_controller_selftest(); | ||
1023 | 1018 | ||
1024 | /* | 1019 | /* |
1025 | * Restore the original control register setting. | 1020 | * Restore the original control register setting. |
@@ -1031,8 +1026,8 @@ static void i8042_controller_reset(void) | |||
1031 | 1026 | ||
1032 | 1027 | ||
1033 | /* | 1028 | /* |
1034 | * i8042_panic_blink() will flash the keyboard LEDs and is called when | 1029 | * i8042_panic_blink() will turn the keyboard LEDs on or off and is called |
1035 | * kernel panics. Flashing LEDs is useful for users running X who may | 1030 | * when kernel panics. Flashing LEDs is useful for users running X who may |
1036 | * not see the console and will help distingushing panics from "real" | 1031 | * not see the console and will help distingushing panics from "real" |
1037 | * lockups. | 1032 | * lockups. |
1038 | * | 1033 | * |
@@ -1042,22 +1037,12 @@ static void i8042_controller_reset(void) | |||
1042 | 1037 | ||
1043 | #define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0) | 1038 | #define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0) |
1044 | 1039 | ||
1045 | static long i8042_panic_blink(long count) | 1040 | static long i8042_panic_blink(int state) |
1046 | { | 1041 | { |
1047 | long delay = 0; | 1042 | long delay = 0; |
1048 | static long last_blink; | 1043 | char led; |
1049 | static char led; | ||
1050 | |||
1051 | /* | ||
1052 | * We expect frequency to be about 1/2s. KDB uses about 1s. | ||
1053 | * Make sure they are different. | ||
1054 | */ | ||
1055 | if (!i8042_blink_frequency) | ||
1056 | return 0; | ||
1057 | if (count - last_blink < i8042_blink_frequency) | ||
1058 | return 0; | ||
1059 | 1044 | ||
1060 | led ^= 0x01 | 0x04; | 1045 | led = (state) ? 0x01 | 0x04 : 0; |
1061 | while (i8042_read_status() & I8042_STR_IBF) | 1046 | while (i8042_read_status() & I8042_STR_IBF) |
1062 | DELAY; | 1047 | DELAY; |
1063 | dbg("%02x -> i8042 (panic blink)", 0xed); | 1048 | dbg("%02x -> i8042 (panic blink)", 0xed); |
@@ -1070,7 +1055,6 @@ static long i8042_panic_blink(long count) | |||
1070 | dbg("%02x -> i8042 (panic blink)", led); | 1055 | dbg("%02x -> i8042 (panic blink)", led); |
1071 | i8042_write_data(led); | 1056 | i8042_write_data(led); |
1072 | DELAY; | 1057 | DELAY; |
1073 | last_blink = count; | ||
1074 | return delay; | 1058 | return delay; |
1075 | } | 1059 | } |
1076 | 1060 | ||
@@ -1079,7 +1063,7 @@ static long i8042_panic_blink(long count) | |||
1079 | #ifdef CONFIG_X86 | 1063 | #ifdef CONFIG_X86 |
1080 | static void i8042_dritek_enable(void) | 1064 | static void i8042_dritek_enable(void) |
1081 | { | 1065 | { |
1082 | char param = 0x90; | 1066 | unsigned char param = 0x90; |
1083 | int error; | 1067 | int error; |
1084 | 1068 | ||
1085 | error = i8042_command(¶m, 0x1059); | 1069 | error = i8042_command(¶m, 0x1059); |
@@ -1093,23 +1077,11 @@ static void i8042_dritek_enable(void) | |||
1093 | #ifdef CONFIG_PM | 1077 | #ifdef CONFIG_PM |
1094 | 1078 | ||
1095 | /* | 1079 | /* |
1096 | * Here we try to restore the original BIOS settings to avoid | ||
1097 | * upsetting it. | ||
1098 | */ | ||
1099 | |||
1100 | static int i8042_pm_reset(struct device *dev) | ||
1101 | { | ||
1102 | i8042_controller_reset(); | ||
1103 | |||
1104 | return 0; | ||
1105 | } | ||
1106 | |||
1107 | /* | ||
1108 | * Here we try to reset everything back to a state we had | 1080 | * Here we try to reset everything back to a state we had |
1109 | * before suspending. | 1081 | * before suspending. |
1110 | */ | 1082 | */ |
1111 | 1083 | ||
1112 | static int i8042_pm_restore(struct device *dev) | 1084 | static int i8042_controller_resume(bool force_reset) |
1113 | { | 1085 | { |
1114 | int error; | 1086 | int error; |
1115 | 1087 | ||
@@ -1117,9 +1089,11 @@ static int i8042_pm_restore(struct device *dev) | |||
1117 | if (error) | 1089 | if (error) |
1118 | return error; | 1090 | return error; |
1119 | 1091 | ||
1120 | error = i8042_controller_selftest(); | 1092 | if (i8042_reset || force_reset) { |
1121 | if (error) | 1093 | error = i8042_controller_selftest(); |
1122 | return error; | 1094 | if (error) |
1095 | return error; | ||
1096 | } | ||
1123 | 1097 | ||
1124 | /* | 1098 | /* |
1125 | * Restore original CTR value and disable all ports | 1099 | * Restore original CTR value and disable all ports |
@@ -1161,9 +1135,44 @@ static int i8042_pm_restore(struct device *dev) | |||
1161 | return 0; | 1135 | return 0; |
1162 | } | 1136 | } |
1163 | 1137 | ||
1138 | /* | ||
1139 | * Here we try to restore the original BIOS settings to avoid | ||
1140 | * upsetting it. | ||
1141 | */ | ||
1142 | |||
1143 | static int i8042_pm_reset(struct device *dev) | ||
1144 | { | ||
1145 | i8042_controller_reset(); | ||
1146 | |||
1147 | return 0; | ||
1148 | } | ||
1149 | |||
1150 | static int i8042_pm_resume(struct device *dev) | ||
1151 | { | ||
1152 | /* | ||
1153 | * On resume from S2R we always try to reset the controller | ||
1154 | * to bring it in a sane state. (In case of S2D we expect | ||
1155 | * BIOS to reset the controller for us.) | ||
1156 | */ | ||
1157 | return i8042_controller_resume(true); | ||
1158 | } | ||
1159 | |||
1160 | static int i8042_pm_thaw(struct device *dev) | ||
1161 | { | ||
1162 | i8042_interrupt(0, NULL); | ||
1163 | |||
1164 | return 0; | ||
1165 | } | ||
1166 | |||
1167 | static int i8042_pm_restore(struct device *dev) | ||
1168 | { | ||
1169 | return i8042_controller_resume(false); | ||
1170 | } | ||
1171 | |||
1164 | static const struct dev_pm_ops i8042_pm_ops = { | 1172 | static const struct dev_pm_ops i8042_pm_ops = { |
1165 | .suspend = i8042_pm_reset, | 1173 | .suspend = i8042_pm_reset, |
1166 | .resume = i8042_pm_restore, | 1174 | .resume = i8042_pm_resume, |
1175 | .thaw = i8042_pm_thaw, | ||
1167 | .poweroff = i8042_pm_reset, | 1176 | .poweroff = i8042_pm_reset, |
1168 | .restore = i8042_pm_restore, | 1177 | .restore = i8042_pm_restore, |
1169 | }; | 1178 | }; |
@@ -1378,9 +1387,13 @@ static int __init i8042_probe(struct platform_device *dev) | |||
1378 | { | 1387 | { |
1379 | int error; | 1388 | int error; |
1380 | 1389 | ||
1381 | error = i8042_controller_selftest(); | 1390 | i8042_platform_device = dev; |
1382 | if (error) | 1391 | |
1383 | return error; | 1392 | if (i8042_reset) { |
1393 | error = i8042_controller_selftest(); | ||
1394 | if (error) | ||
1395 | return error; | ||
1396 | } | ||
1384 | 1397 | ||
1385 | error = i8042_controller_init(); | 1398 | error = i8042_controller_init(); |
1386 | if (error) | 1399 | if (error) |
@@ -1413,6 +1426,7 @@ static int __init i8042_probe(struct platform_device *dev) | |||
1413 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ | 1426 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ |
1414 | i8042_free_irqs(); | 1427 | i8042_free_irqs(); |
1415 | i8042_controller_reset(); | 1428 | i8042_controller_reset(); |
1429 | i8042_platform_device = NULL; | ||
1416 | 1430 | ||
1417 | return error; | 1431 | return error; |
1418 | } | 1432 | } |
@@ -1422,6 +1436,7 @@ static int __devexit i8042_remove(struct platform_device *dev) | |||
1422 | i8042_unregister_ports(); | 1436 | i8042_unregister_ports(); |
1423 | i8042_free_irqs(); | 1437 | i8042_free_irqs(); |
1424 | i8042_controller_reset(); | 1438 | i8042_controller_reset(); |
1439 | i8042_platform_device = NULL; | ||
1425 | 1440 | ||
1426 | return 0; | 1441 | return 0; |
1427 | } | 1442 | } |
@@ -1440,6 +1455,7 @@ static struct platform_driver i8042_driver = { | |||
1440 | 1455 | ||
1441 | static int __init i8042_init(void) | 1456 | static int __init i8042_init(void) |
1442 | { | 1457 | { |
1458 | struct platform_device *pdev; | ||
1443 | int err; | 1459 | int err; |
1444 | 1460 | ||
1445 | dbg_init(); | 1461 | dbg_init(); |
@@ -1452,38 +1468,25 @@ static int __init i8042_init(void) | |||
1452 | if (err) | 1468 | if (err) |
1453 | goto err_platform_exit; | 1469 | goto err_platform_exit; |
1454 | 1470 | ||
1455 | i8042_platform_device = platform_device_alloc("i8042", -1); | 1471 | pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0); |
1456 | if (!i8042_platform_device) { | 1472 | if (IS_ERR(pdev)) { |
1457 | err = -ENOMEM; | 1473 | err = PTR_ERR(pdev); |
1458 | goto err_platform_exit; | 1474 | goto err_platform_exit; |
1459 | } | 1475 | } |
1460 | 1476 | ||
1461 | err = platform_device_add(i8042_platform_device); | ||
1462 | if (err) | ||
1463 | goto err_free_device; | ||
1464 | |||
1465 | err = platform_driver_probe(&i8042_driver, i8042_probe); | ||
1466 | if (err) | ||
1467 | goto err_del_device; | ||
1468 | |||
1469 | panic_blink = i8042_panic_blink; | 1477 | panic_blink = i8042_panic_blink; |
1470 | 1478 | ||
1471 | return 0; | 1479 | return 0; |
1472 | 1480 | ||
1473 | err_del_device: | ||
1474 | platform_device_del(i8042_platform_device); | ||
1475 | err_free_device: | ||
1476 | platform_device_put(i8042_platform_device); | ||
1477 | err_platform_exit: | 1481 | err_platform_exit: |
1478 | i8042_platform_exit(); | 1482 | i8042_platform_exit(); |
1479 | |||
1480 | return err; | 1483 | return err; |
1481 | } | 1484 | } |
1482 | 1485 | ||
1483 | static void __exit i8042_exit(void) | 1486 | static void __exit i8042_exit(void) |
1484 | { | 1487 | { |
1485 | platform_driver_unregister(&i8042_driver); | ||
1486 | platform_device_unregister(i8042_platform_device); | 1488 | platform_device_unregister(i8042_platform_device); |
1489 | platform_driver_unregister(&i8042_driver); | ||
1487 | i8042_platform_exit(); | 1490 | i8042_platform_exit(); |
1488 | 1491 | ||
1489 | panic_blink = NULL; | 1492 | panic_blink = NULL; |
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index f3876acc3e83..980af94ba9c8 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/slab.h> | ||
18 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
19 | #include <linux/input.h> | 18 | #include <linux/input.h> |
20 | #include <linux/serio.h> | 19 | #include <linux/serio.h> |
diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index b089977e0ef9..26b45936f9fd 100644 --- a/drivers/input/serio/parkbd.c +++ b/drivers/input/serio/parkbd.c | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | #include <linux/module.h> | 47 | #include <linux/module.h> |
48 | #include <linux/parport.h> | 48 | #include <linux/parport.h> |
49 | #include <linux/slab.h> | ||
49 | #include <linux/init.h> | 50 | #include <linux/init.h> |
50 | #include <linux/serio.h> | 51 | #include <linux/serio.h> |
51 | 52 | ||
diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index 1dacbe0d9348..43494742541c 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
16 | #include <linux/input.h> | 16 | #include <linux/input.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
19 | #include <linux/serio.h> | 20 | #include <linux/serio.h> |
20 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
@@ -186,7 +187,7 @@ static void __devexit pcips2_remove(struct pci_dev *dev) | |||
186 | pci_disable_device(dev); | 187 | pci_disable_device(dev); |
187 | } | 188 | } |
188 | 189 | ||
189 | static struct pci_device_id pcips2_ids[] = { | 190 | static const struct pci_device_id pcips2_ids[] = { |
190 | { | 191 | { |
191 | .vendor = 0x14f2, /* MOBILITY */ | 192 | .vendor = 0x14f2, /* MOBILITY */ |
192 | .device = 0x0123, /* Keyboard */ | 193 | .device = 0x0123, /* Keyboard */ |
diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c new file mode 100644 index 000000000000..6bce22e4e495 --- /dev/null +++ b/drivers/input/serio/ps2mult.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* | ||
2 | * TQC PS/2 Multiplexer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Dmitry Eremin-Solenikov | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/serio.h> | ||
16 | |||
17 | MODULE_AUTHOR("Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>"); | ||
18 | MODULE_DESCRIPTION("TQC PS/2 Multiplexer driver"); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
21 | #define PS2MULT_KB_SELECTOR 0xA0 | ||
22 | #define PS2MULT_MS_SELECTOR 0xA1 | ||
23 | #define PS2MULT_ESCAPE 0x7D | ||
24 | #define PS2MULT_BSYNC 0x7E | ||
25 | #define PS2MULT_SESSION_START 0x55 | ||
26 | #define PS2MULT_SESSION_END 0x56 | ||
27 | |||
28 | struct ps2mult_port { | ||
29 | struct serio *serio; | ||
30 | unsigned char sel; | ||
31 | bool registered; | ||
32 | }; | ||
33 | |||
34 | #define PS2MULT_NUM_PORTS 2 | ||
35 | #define PS2MULT_KBD_PORT 0 | ||
36 | #define PS2MULT_MOUSE_PORT 1 | ||
37 | |||
38 | struct ps2mult { | ||
39 | struct serio *mx_serio; | ||
40 | struct ps2mult_port ports[PS2MULT_NUM_PORTS]; | ||
41 | |||
42 | spinlock_t lock; | ||
43 | struct ps2mult_port *in_port; | ||
44 | struct ps2mult_port *out_port; | ||
45 | bool escape; | ||
46 | }; | ||
47 | |||
48 | /* First MUST come PS2MULT_NUM_PORTS selectors */ | ||
49 | static const unsigned char ps2mult_controls[] = { | ||
50 | PS2MULT_KB_SELECTOR, PS2MULT_MS_SELECTOR, | ||
51 | PS2MULT_ESCAPE, PS2MULT_BSYNC, | ||
52 | PS2MULT_SESSION_START, PS2MULT_SESSION_END, | ||
53 | }; | ||
54 | |||
55 | static const struct serio_device_id ps2mult_serio_ids[] = { | ||
56 | { | ||
57 | .type = SERIO_RS232, | ||
58 | .proto = SERIO_PS2MULT, | ||
59 | .id = SERIO_ANY, | ||
60 | .extra = SERIO_ANY, | ||
61 | }, | ||
62 | { 0 } | ||
63 | }; | ||
64 | |||
65 | MODULE_DEVICE_TABLE(serio, ps2mult_serio_ids); | ||
66 | |||
67 | static void ps2mult_select_port(struct ps2mult *psm, struct ps2mult_port *port) | ||
68 | { | ||
69 | struct serio *mx_serio = psm->mx_serio; | ||
70 | |||
71 | serio_write(mx_serio, port->sel); | ||
72 | psm->out_port = port; | ||
73 | dev_dbg(&mx_serio->dev, "switched to sel %02x\n", port->sel); | ||
74 | } | ||
75 | |||
76 | static int ps2mult_serio_write(struct serio *serio, unsigned char data) | ||
77 | { | ||
78 | struct serio *mx_port = serio->parent; | ||
79 | struct ps2mult *psm = serio_get_drvdata(mx_port); | ||
80 | struct ps2mult_port *port = serio->port_data; | ||
81 | bool need_escape; | ||
82 | unsigned long flags; | ||
83 | |||
84 | spin_lock_irqsave(&psm->lock, flags); | ||
85 | |||
86 | if (psm->out_port != port) | ||
87 | ps2mult_select_port(psm, port); | ||
88 | |||
89 | need_escape = memchr(ps2mult_controls, data, sizeof(ps2mult_controls)); | ||
90 | |||
91 | dev_dbg(&serio->dev, | ||
92 | "write: %s%02x\n", need_escape ? "ESC " : "", data); | ||
93 | |||
94 | if (need_escape) | ||
95 | serio_write(mx_port, PS2MULT_ESCAPE); | ||
96 | |||
97 | serio_write(mx_port, data); | ||
98 | |||
99 | spin_unlock_irqrestore(&psm->lock, flags); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int ps2mult_serio_start(struct serio *serio) | ||
105 | { | ||
106 | struct ps2mult *psm = serio_get_drvdata(serio->parent); | ||
107 | struct ps2mult_port *port = serio->port_data; | ||
108 | unsigned long flags; | ||
109 | |||
110 | spin_lock_irqsave(&psm->lock, flags); | ||
111 | port->registered = true; | ||
112 | spin_unlock_irqrestore(&psm->lock, flags); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static void ps2mult_serio_stop(struct serio *serio) | ||
118 | { | ||
119 | struct ps2mult *psm = serio_get_drvdata(serio->parent); | ||
120 | struct ps2mult_port *port = serio->port_data; | ||
121 | unsigned long flags; | ||
122 | |||
123 | spin_lock_irqsave(&psm->lock, flags); | ||
124 | port->registered = false; | ||
125 | spin_unlock_irqrestore(&psm->lock, flags); | ||
126 | } | ||
127 | |||
128 | static int ps2mult_create_port(struct ps2mult *psm, int i) | ||
129 | { | ||
130 | struct serio *mx_serio = psm->mx_serio; | ||
131 | struct serio *serio; | ||
132 | |||
133 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
134 | if (!serio) | ||
135 | return -ENOMEM; | ||
136 | |||
137 | strlcpy(serio->name, "TQC PS/2 Multiplexer", sizeof(serio->name)); | ||
138 | snprintf(serio->phys, sizeof(serio->phys), | ||
139 | "%s/port%d", mx_serio->phys, i); | ||
140 | serio->id.type = SERIO_8042; | ||
141 | serio->write = ps2mult_serio_write; | ||
142 | serio->start = ps2mult_serio_start; | ||
143 | serio->stop = ps2mult_serio_stop; | ||
144 | serio->parent = psm->mx_serio; | ||
145 | serio->port_data = &psm->ports[i]; | ||
146 | |||
147 | psm->ports[i].serio = serio; | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static void ps2mult_reset(struct ps2mult *psm) | ||
153 | { | ||
154 | unsigned long flags; | ||
155 | |||
156 | spin_lock_irqsave(&psm->lock, flags); | ||
157 | |||
158 | serio_write(psm->mx_serio, PS2MULT_SESSION_END); | ||
159 | serio_write(psm->mx_serio, PS2MULT_SESSION_START); | ||
160 | |||
161 | ps2mult_select_port(psm, &psm->ports[PS2MULT_KBD_PORT]); | ||
162 | |||
163 | spin_unlock_irqrestore(&psm->lock, flags); | ||
164 | } | ||
165 | |||
166 | static int ps2mult_connect(struct serio *serio, struct serio_driver *drv) | ||
167 | { | ||
168 | struct ps2mult *psm; | ||
169 | int i; | ||
170 | int error; | ||
171 | |||
172 | if (!serio->write) | ||
173 | return -EINVAL; | ||
174 | |||
175 | psm = kzalloc(sizeof(*psm), GFP_KERNEL); | ||
176 | if (!psm) | ||
177 | return -ENOMEM; | ||
178 | |||
179 | spin_lock_init(&psm->lock); | ||
180 | psm->mx_serio = serio; | ||
181 | |||
182 | for (i = 0; i < PS2MULT_NUM_PORTS; i++) { | ||
183 | psm->ports[i].sel = ps2mult_controls[i]; | ||
184 | error = ps2mult_create_port(psm, i); | ||
185 | if (error) | ||
186 | goto err_out; | ||
187 | } | ||
188 | |||
189 | psm->in_port = psm->out_port = &psm->ports[PS2MULT_KBD_PORT]; | ||
190 | |||
191 | serio_set_drvdata(serio, psm); | ||
192 | error = serio_open(serio, drv); | ||
193 | if (error) | ||
194 | goto err_out; | ||
195 | |||
196 | ps2mult_reset(psm); | ||
197 | |||
198 | for (i = 0; i < PS2MULT_NUM_PORTS; i++) { | ||
199 | struct serio *s = psm->ports[i].serio; | ||
200 | |||
201 | dev_info(&serio->dev, "%s port at %s\n", s->name, serio->phys); | ||
202 | serio_register_port(s); | ||
203 | } | ||
204 | |||
205 | return 0; | ||
206 | |||
207 | err_out: | ||
208 | while (--i >= 0) | ||
209 | kfree(psm->ports[i].serio); | ||
210 | kfree(serio); | ||
211 | return error; | ||
212 | } | ||
213 | |||
214 | static void ps2mult_disconnect(struct serio *serio) | ||
215 | { | ||
216 | struct ps2mult *psm = serio_get_drvdata(serio); | ||
217 | |||
218 | /* Note that serio core already take care of children ports */ | ||
219 | serio_write(serio, PS2MULT_SESSION_END); | ||
220 | serio_close(serio); | ||
221 | kfree(psm); | ||
222 | |||
223 | serio_set_drvdata(serio, NULL); | ||
224 | } | ||
225 | |||
226 | static int ps2mult_reconnect(struct serio *serio) | ||
227 | { | ||
228 | struct ps2mult *psm = serio_get_drvdata(serio); | ||
229 | |||
230 | ps2mult_reset(psm); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static irqreturn_t ps2mult_interrupt(struct serio *serio, | ||
236 | unsigned char data, unsigned int dfl) | ||
237 | { | ||
238 | struct ps2mult *psm = serio_get_drvdata(serio); | ||
239 | struct ps2mult_port *in_port; | ||
240 | unsigned long flags; | ||
241 | |||
242 | dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, dfl); | ||
243 | |||
244 | spin_lock_irqsave(&psm->lock, flags); | ||
245 | |||
246 | if (psm->escape) { | ||
247 | psm->escape = false; | ||
248 | in_port = psm->in_port; | ||
249 | if (in_port->registered) | ||
250 | serio_interrupt(in_port->serio, data, dfl); | ||
251 | goto out; | ||
252 | } | ||
253 | |||
254 | switch (data) { | ||
255 | case PS2MULT_ESCAPE: | ||
256 | dev_dbg(&serio->dev, "ESCAPE\n"); | ||
257 | psm->escape = true; | ||
258 | break; | ||
259 | |||
260 | case PS2MULT_BSYNC: | ||
261 | dev_dbg(&serio->dev, "BSYNC\n"); | ||
262 | psm->in_port = psm->out_port; | ||
263 | break; | ||
264 | |||
265 | case PS2MULT_SESSION_START: | ||
266 | dev_dbg(&serio->dev, "SS\n"); | ||
267 | break; | ||
268 | |||
269 | case PS2MULT_SESSION_END: | ||
270 | dev_dbg(&serio->dev, "SE\n"); | ||
271 | break; | ||
272 | |||
273 | case PS2MULT_KB_SELECTOR: | ||
274 | dev_dbg(&serio->dev, "KB\n"); | ||
275 | psm->in_port = &psm->ports[PS2MULT_KBD_PORT]; | ||
276 | break; | ||
277 | |||
278 | case PS2MULT_MS_SELECTOR: | ||
279 | dev_dbg(&serio->dev, "MS\n"); | ||
280 | psm->in_port = &psm->ports[PS2MULT_MOUSE_PORT]; | ||
281 | break; | ||
282 | |||
283 | default: | ||
284 | in_port = psm->in_port; | ||
285 | if (in_port->registered) | ||
286 | serio_interrupt(in_port->serio, data, dfl); | ||
287 | break; | ||
288 | } | ||
289 | |||
290 | out: | ||
291 | spin_unlock_irqrestore(&psm->lock, flags); | ||
292 | return IRQ_HANDLED; | ||
293 | } | ||
294 | |||
295 | static struct serio_driver ps2mult_drv = { | ||
296 | .driver = { | ||
297 | .name = "ps2mult", | ||
298 | }, | ||
299 | .description = "TQC PS/2 Multiplexer driver", | ||
300 | .id_table = ps2mult_serio_ids, | ||
301 | .interrupt = ps2mult_interrupt, | ||
302 | .connect = ps2mult_connect, | ||
303 | .disconnect = ps2mult_disconnect, | ||
304 | .reconnect = ps2mult_reconnect, | ||
305 | }; | ||
306 | |||
307 | static int __init ps2mult_init(void) | ||
308 | { | ||
309 | return serio_register_driver(&ps2mult_drv); | ||
310 | } | ||
311 | |||
312 | static void __exit ps2mult_exit(void) | ||
313 | { | ||
314 | serio_unregister_driver(&ps2mult_drv); | ||
315 | } | ||
316 | |||
317 | module_init(ps2mult_init); | ||
318 | module_exit(ps2mult_exit); | ||
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index e36a0901646c..5eb84b3b67fb 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/err.h> | 36 | #include <linux/err.h> |
37 | #include <linux/bitops.h> | 37 | #include <linux/bitops.h> |
38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
39 | #include <linux/slab.h> | ||
39 | 40 | ||
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index ed045c99f84b..9da6fbcaaa7e 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/err.h> | 34 | #include <linux/err.h> |
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/io.h> | 36 | #include <linux/io.h> |
37 | #include <linux/slab.h> | ||
37 | 38 | ||
38 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
39 | #include <mach/hardware.h> | 40 | #include <mach/hardware.h> |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index e0f30186d513..405bf214527c 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
30 | |||
29 | #include <linux/stddef.h> | 31 | #include <linux/stddef.h> |
30 | #include <linux/module.h> | 32 | #include <linux/module.h> |
31 | #include <linux/serio.h> | 33 | #include <linux/serio.h> |
@@ -35,7 +37,6 @@ | |||
35 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
36 | #include <linux/kthread.h> | 38 | #include <linux/kthread.h> |
37 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
38 | #include <linux/freezer.h> | ||
39 | 40 | ||
40 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 41 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
41 | MODULE_DESCRIPTION("Serio abstraction core"); | 42 | MODULE_DESCRIPTION("Serio abstraction core"); |
@@ -54,7 +55,7 @@ static struct bus_type serio_bus; | |||
54 | static void serio_add_port(struct serio *serio); | 55 | static void serio_add_port(struct serio *serio); |
55 | static int serio_reconnect_port(struct serio *serio); | 56 | static int serio_reconnect_port(struct serio *serio); |
56 | static void serio_disconnect_port(struct serio *serio); | 57 | static void serio_disconnect_port(struct serio *serio); |
57 | static void serio_reconnect_chain(struct serio *serio); | 58 | static void serio_reconnect_subtree(struct serio *serio); |
58 | static void serio_attach_driver(struct serio_driver *drv); | 59 | static void serio_attach_driver(struct serio_driver *drv); |
59 | 60 | ||
60 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) | 61 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) |
@@ -119,11 +120,10 @@ static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) | |||
119 | 120 | ||
120 | error = device_bind_driver(&serio->dev); | 121 | error = device_bind_driver(&serio->dev); |
121 | if (error) { | 122 | if (error) { |
122 | printk(KERN_WARNING | 123 | dev_warn(&serio->dev, |
123 | "serio: device_bind_driver() failed " | 124 | "device_bind_driver() failed for %s (%s) and %s, error: %d\n", |
124 | "for %s (%s) and %s, error: %d\n", | 125 | serio->phys, serio->name, |
125 | serio->phys, serio->name, | 126 | drv->description, error); |
126 | drv->description, error); | ||
127 | serio_disconnect_driver(serio); | 127 | serio_disconnect_driver(serio); |
128 | serio->dev.driver = NULL; | 128 | serio->dev.driver = NULL; |
129 | return error; | 129 | return error; |
@@ -138,9 +138,9 @@ static void serio_find_driver(struct serio *serio) | |||
138 | 138 | ||
139 | error = device_attach(&serio->dev); | 139 | error = device_attach(&serio->dev); |
140 | if (error < 0) | 140 | if (error < 0) |
141 | printk(KERN_WARNING | 141 | dev_warn(&serio->dev, |
142 | "serio: device_attach() failed for %s (%s), error: %d\n", | 142 | "device_attach() failed for %s (%s), error: %d\n", |
143 | serio->phys, serio->name, error); | 143 | serio->phys, serio->name, error); |
144 | } | 144 | } |
145 | 145 | ||
146 | 146 | ||
@@ -151,7 +151,7 @@ static void serio_find_driver(struct serio *serio) | |||
151 | enum serio_event_type { | 151 | enum serio_event_type { |
152 | SERIO_RESCAN_PORT, | 152 | SERIO_RESCAN_PORT, |
153 | SERIO_RECONNECT_PORT, | 153 | SERIO_RECONNECT_PORT, |
154 | SERIO_RECONNECT_CHAIN, | 154 | SERIO_RECONNECT_SUBTREE, |
155 | SERIO_REGISTER_PORT, | 155 | SERIO_REGISTER_PORT, |
156 | SERIO_ATTACH_DRIVER, | 156 | SERIO_ATTACH_DRIVER, |
157 | }; | 157 | }; |
@@ -194,17 +194,14 @@ static int serio_queue_event(void *object, struct module *owner, | |||
194 | 194 | ||
195 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); | 195 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); |
196 | if (!event) { | 196 | if (!event) { |
197 | printk(KERN_ERR | 197 | pr_err("Not enough memory to queue event %d\n", event_type); |
198 | "serio: Not enough memory to queue event %d\n", | ||
199 | event_type); | ||
200 | retval = -ENOMEM; | 198 | retval = -ENOMEM; |
201 | goto out; | 199 | goto out; |
202 | } | 200 | } |
203 | 201 | ||
204 | if (!try_module_get(owner)) { | 202 | if (!try_module_get(owner)) { |
205 | printk(KERN_WARNING | 203 | pr_warning("Can't get module reference, dropping event %d\n", |
206 | "serio: Can't get module reference, dropping event %d\n", | 204 | event_type); |
207 | event_type); | ||
208 | kfree(event); | 205 | kfree(event); |
209 | retval = -EINVAL; | 206 | retval = -EINVAL; |
210 | goto out; | 207 | goto out; |
@@ -230,14 +227,12 @@ static void serio_free_event(struct serio_event *event) | |||
230 | 227 | ||
231 | static void serio_remove_duplicate_events(struct serio_event *event) | 228 | static void serio_remove_duplicate_events(struct serio_event *event) |
232 | { | 229 | { |
233 | struct list_head *node, *next; | 230 | struct serio_event *e, *next; |
234 | struct serio_event *e; | ||
235 | unsigned long flags; | 231 | unsigned long flags; |
236 | 232 | ||
237 | spin_lock_irqsave(&serio_event_lock, flags); | 233 | spin_lock_irqsave(&serio_event_lock, flags); |
238 | 234 | ||
239 | list_for_each_safe(node, next, &serio_event_list) { | 235 | list_for_each_entry_safe(e, next, &serio_event_list, node) { |
240 | e = list_entry(node, struct serio_event, node); | ||
241 | if (event->object == e->object) { | 236 | if (event->object == e->object) { |
242 | /* | 237 | /* |
243 | * If this event is of different type we should not | 238 | * If this event is of different type we should not |
@@ -247,7 +242,7 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
247 | if (event->type != e->type) | 242 | if (event->type != e->type) |
248 | break; | 243 | break; |
249 | 244 | ||
250 | list_del_init(node); | 245 | list_del_init(&e->node); |
251 | serio_free_event(e); | 246 | serio_free_event(e); |
252 | } | 247 | } |
253 | } | 248 | } |
@@ -258,23 +253,18 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
258 | 253 | ||
259 | static struct serio_event *serio_get_event(void) | 254 | static struct serio_event *serio_get_event(void) |
260 | { | 255 | { |
261 | struct serio_event *event; | 256 | struct serio_event *event = NULL; |
262 | struct list_head *node; | ||
263 | unsigned long flags; | 257 | unsigned long flags; |
264 | 258 | ||
265 | spin_lock_irqsave(&serio_event_lock, flags); | 259 | spin_lock_irqsave(&serio_event_lock, flags); |
266 | 260 | ||
267 | if (list_empty(&serio_event_list)) { | 261 | if (!list_empty(&serio_event_list)) { |
268 | spin_unlock_irqrestore(&serio_event_lock, flags); | 262 | event = list_first_entry(&serio_event_list, |
269 | return NULL; | 263 | struct serio_event, node); |
264 | list_del_init(&event->node); | ||
270 | } | 265 | } |
271 | 266 | ||
272 | node = serio_event_list.next; | ||
273 | event = list_entry(node, struct serio_event, node); | ||
274 | list_del_init(node); | ||
275 | |||
276 | spin_unlock_irqrestore(&serio_event_lock, flags); | 267 | spin_unlock_irqrestore(&serio_event_lock, flags); |
277 | |||
278 | return event; | 268 | return event; |
279 | } | 269 | } |
280 | 270 | ||
@@ -287,29 +277,27 @@ static void serio_handle_event(void) | |||
287 | while ((event = serio_get_event())) { | 277 | while ((event = serio_get_event())) { |
288 | 278 | ||
289 | switch (event->type) { | 279 | switch (event->type) { |
290 | case SERIO_REGISTER_PORT: | ||
291 | serio_add_port(event->object); | ||
292 | break; | ||
293 | 280 | ||
294 | case SERIO_RECONNECT_PORT: | 281 | case SERIO_REGISTER_PORT: |
295 | serio_reconnect_port(event->object); | 282 | serio_add_port(event->object); |
296 | break; | 283 | break; |
297 | 284 | ||
298 | case SERIO_RESCAN_PORT: | 285 | case SERIO_RECONNECT_PORT: |
299 | serio_disconnect_port(event->object); | 286 | serio_reconnect_port(event->object); |
300 | serio_find_driver(event->object); | 287 | break; |
301 | break; | ||
302 | 288 | ||
303 | case SERIO_RECONNECT_CHAIN: | 289 | case SERIO_RESCAN_PORT: |
304 | serio_reconnect_chain(event->object); | 290 | serio_disconnect_port(event->object); |
305 | break; | 291 | serio_find_driver(event->object); |
292 | break; | ||
306 | 293 | ||
307 | case SERIO_ATTACH_DRIVER: | 294 | case SERIO_RECONNECT_SUBTREE: |
308 | serio_attach_driver(event->object); | 295 | serio_reconnect_subtree(event->object); |
309 | break; | 296 | break; |
310 | 297 | ||
311 | default: | 298 | case SERIO_ATTACH_DRIVER: |
312 | break; | 299 | serio_attach_driver(event->object); |
300 | break; | ||
313 | } | 301 | } |
314 | 302 | ||
315 | serio_remove_duplicate_events(event); | 303 | serio_remove_duplicate_events(event); |
@@ -325,16 +313,14 @@ static void serio_handle_event(void) | |||
325 | */ | 313 | */ |
326 | static void serio_remove_pending_events(void *object) | 314 | static void serio_remove_pending_events(void *object) |
327 | { | 315 | { |
328 | struct list_head *node, *next; | 316 | struct serio_event *event, *next; |
329 | struct serio_event *event; | ||
330 | unsigned long flags; | 317 | unsigned long flags; |
331 | 318 | ||
332 | spin_lock_irqsave(&serio_event_lock, flags); | 319 | spin_lock_irqsave(&serio_event_lock, flags); |
333 | 320 | ||
334 | list_for_each_safe(node, next, &serio_event_list) { | 321 | list_for_each_entry_safe(event, next, &serio_event_list, node) { |
335 | event = list_entry(node, struct serio_event, node); | ||
336 | if (event->object == object) { | 322 | if (event->object == object) { |
337 | list_del_init(node); | 323 | list_del_init(&event->node); |
338 | serio_free_event(event); | 324 | serio_free_event(event); |
339 | } | 325 | } |
340 | } | 326 | } |
@@ -343,12 +329,10 @@ static void serio_remove_pending_events(void *object) | |||
343 | } | 329 | } |
344 | 330 | ||
345 | /* | 331 | /* |
346 | * Destroy child serio port (if any) that has not been fully registered yet. | 332 | * Locate child serio port (if any) that has not been fully registered yet. |
347 | * | 333 | * |
348 | * Note that we rely on the fact that port can have only one child and therefore | 334 | * Children are registered by driver's connect() handler so there can't be a |
349 | * only one child registration request can be pending. Additionally, children | 335 | * grandchild pending registration together with a child. |
350 | * are registered by driver's connect() handler so there can't be a grandchild | ||
351 | * pending registration together with a child. | ||
352 | */ | 336 | */ |
353 | static struct serio *serio_get_pending_child(struct serio *parent) | 337 | static struct serio *serio_get_pending_child(struct serio *parent) |
354 | { | 338 | { |
@@ -380,7 +364,6 @@ static int serio_thread(void *nothing) | |||
380 | kthread_should_stop() || !list_empty(&serio_event_list)); | 364 | kthread_should_stop() || !list_empty(&serio_event_list)); |
381 | } while (!kthread_should_stop()); | 365 | } while (!kthread_should_stop()); |
382 | 366 | ||
383 | printk(KERN_DEBUG "serio: kseriod exiting\n"); | ||
384 | return 0; | 367 | return 0; |
385 | } | 368 | } |
386 | 369 | ||
@@ -445,6 +428,11 @@ static struct attribute_group serio_id_attr_group = { | |||
445 | .attrs = serio_device_id_attrs, | 428 | .attrs = serio_device_id_attrs, |
446 | }; | 429 | }; |
447 | 430 | ||
431 | static const struct attribute_group *serio_device_attr_groups[] = { | ||
432 | &serio_id_attr_group, | ||
433 | NULL | ||
434 | }; | ||
435 | |||
448 | static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 436 | static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
449 | { | 437 | { |
450 | struct serio *serio = to_serio_port(dev); | 438 | struct serio *serio = to_serio_port(dev); |
@@ -458,7 +446,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * | |||
458 | if (!strncmp(buf, "none", count)) { | 446 | if (!strncmp(buf, "none", count)) { |
459 | serio_disconnect_port(serio); | 447 | serio_disconnect_port(serio); |
460 | } else if (!strncmp(buf, "reconnect", count)) { | 448 | } else if (!strncmp(buf, "reconnect", count)) { |
461 | serio_reconnect_chain(serio); | 449 | serio_reconnect_subtree(serio); |
462 | } else if (!strncmp(buf, "rescan", count)) { | 450 | } else if (!strncmp(buf, "rescan", count)) { |
463 | serio_disconnect_port(serio); | 451 | serio_disconnect_port(serio); |
464 | serio_find_driver(serio); | 452 | serio_find_driver(serio); |
@@ -525,6 +513,8 @@ static void serio_init_port(struct serio *serio) | |||
525 | __module_get(THIS_MODULE); | 513 | __module_get(THIS_MODULE); |
526 | 514 | ||
527 | INIT_LIST_HEAD(&serio->node); | 515 | INIT_LIST_HEAD(&serio->node); |
516 | INIT_LIST_HEAD(&serio->child_node); | ||
517 | INIT_LIST_HEAD(&serio->children); | ||
528 | spin_lock_init(&serio->lock); | 518 | spin_lock_init(&serio->lock); |
529 | mutex_init(&serio->drv_mutex); | 519 | mutex_init(&serio->drv_mutex); |
530 | device_initialize(&serio->dev); | 520 | device_initialize(&serio->dev); |
@@ -532,6 +522,7 @@ static void serio_init_port(struct serio *serio) | |||
532 | (long)atomic_inc_return(&serio_no) - 1); | 522 | (long)atomic_inc_return(&serio_no) - 1); |
533 | serio->dev.bus = &serio_bus; | 523 | serio->dev.bus = &serio_bus; |
534 | serio->dev.release = serio_release_port; | 524 | serio->dev.release = serio_release_port; |
525 | serio->dev.groups = serio_device_attr_groups; | ||
535 | if (serio->parent) { | 526 | if (serio->parent) { |
536 | serio->dev.parent = &serio->parent->dev; | 527 | serio->dev.parent = &serio->parent->dev; |
537 | serio->depth = serio->parent->depth + 1; | 528 | serio->depth = serio->parent->depth + 1; |
@@ -546,42 +537,36 @@ static void serio_init_port(struct serio *serio) | |||
546 | */ | 537 | */ |
547 | static void serio_add_port(struct serio *serio) | 538 | static void serio_add_port(struct serio *serio) |
548 | { | 539 | { |
540 | struct serio *parent = serio->parent; | ||
549 | int error; | 541 | int error; |
550 | 542 | ||
551 | if (serio->parent) { | 543 | if (parent) { |
552 | serio_pause_rx(serio->parent); | 544 | serio_pause_rx(parent); |
553 | serio->parent->child = serio; | 545 | list_add_tail(&serio->child_node, &parent->children); |
554 | serio_continue_rx(serio->parent); | 546 | serio_continue_rx(parent); |
555 | } | 547 | } |
556 | 548 | ||
557 | list_add_tail(&serio->node, &serio_list); | 549 | list_add_tail(&serio->node, &serio_list); |
550 | |||
558 | if (serio->start) | 551 | if (serio->start) |
559 | serio->start(serio); | 552 | serio->start(serio); |
553 | |||
560 | error = device_add(&serio->dev); | 554 | error = device_add(&serio->dev); |
561 | if (error) | 555 | if (error) |
562 | printk(KERN_ERR | 556 | dev_err(&serio->dev, |
563 | "serio: device_add() failed for %s (%s), error: %d\n", | 557 | "device_add() failed for %s (%s), error: %d\n", |
564 | serio->phys, serio->name, error); | 558 | serio->phys, serio->name, error); |
565 | else { | ||
566 | serio->registered = true; | ||
567 | error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | ||
568 | if (error) | ||
569 | printk(KERN_ERR | ||
570 | "serio: sysfs_create_group() failed for %s (%s), error: %d\n", | ||
571 | serio->phys, serio->name, error); | ||
572 | } | ||
573 | } | 559 | } |
574 | 560 | ||
575 | /* | 561 | /* |
576 | * serio_destroy_port() completes deregistration process and removes | 562 | * serio_destroy_port() completes unregistration process and removes |
577 | * port from the system | 563 | * port from the system |
578 | */ | 564 | */ |
579 | static void serio_destroy_port(struct serio *serio) | 565 | static void serio_destroy_port(struct serio *serio) |
580 | { | 566 | { |
581 | struct serio *child; | 567 | struct serio *child; |
582 | 568 | ||
583 | child = serio_get_pending_child(serio); | 569 | while ((child = serio_get_pending_child(serio)) != NULL) { |
584 | if (child) { | ||
585 | serio_remove_pending_events(child); | 570 | serio_remove_pending_events(child); |
586 | put_device(&child->dev); | 571 | put_device(&child->dev); |
587 | } | 572 | } |
@@ -591,16 +576,13 @@ static void serio_destroy_port(struct serio *serio) | |||
591 | 576 | ||
592 | if (serio->parent) { | 577 | if (serio->parent) { |
593 | serio_pause_rx(serio->parent); | 578 | serio_pause_rx(serio->parent); |
594 | serio->parent->child = NULL; | 579 | list_del_init(&serio->child_node); |
595 | serio_continue_rx(serio->parent); | 580 | serio_continue_rx(serio->parent); |
596 | serio->parent = NULL; | 581 | serio->parent = NULL; |
597 | } | 582 | } |
598 | 583 | ||
599 | if (serio->registered) { | 584 | if (device_is_registered(&serio->dev)) |
600 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); | ||
601 | device_del(&serio->dev); | 585 | device_del(&serio->dev); |
602 | serio->registered = false; | ||
603 | } | ||
604 | 586 | ||
605 | list_del_init(&serio->node); | 587 | list_del_init(&serio->node); |
606 | serio_remove_pending_events(serio); | 588 | serio_remove_pending_events(serio); |
@@ -626,46 +608,82 @@ static int serio_reconnect_port(struct serio *serio) | |||
626 | } | 608 | } |
627 | 609 | ||
628 | /* | 610 | /* |
629 | * Reconnect serio port and all its children (re-initialize attached devices) | 611 | * Reconnect serio port and all its children (re-initialize attached |
612 | * devices). | ||
630 | */ | 613 | */ |
631 | static void serio_reconnect_chain(struct serio *serio) | 614 | static void serio_reconnect_subtree(struct serio *root) |
632 | { | 615 | { |
616 | struct serio *s = root; | ||
617 | int error; | ||
618 | |||
633 | do { | 619 | do { |
634 | if (serio_reconnect_port(serio)) { | 620 | error = serio_reconnect_port(s); |
635 | /* Ok, old children are now gone, we are done */ | 621 | if (!error) { |
636 | break; | 622 | /* |
623 | * Reconnect was successful, move on to do the | ||
624 | * first child. | ||
625 | */ | ||
626 | if (!list_empty(&s->children)) { | ||
627 | s = list_first_entry(&s->children, | ||
628 | struct serio, child_node); | ||
629 | continue; | ||
630 | } | ||
637 | } | 631 | } |
638 | serio = serio->child; | 632 | |
639 | } while (serio); | 633 | /* |
634 | * Either it was a leaf node or reconnect failed and it | ||
635 | * became a leaf node. Continue reconnecting starting with | ||
636 | * the next sibling of the parent node. | ||
637 | */ | ||
638 | while (s != root) { | ||
639 | struct serio *parent = s->parent; | ||
640 | |||
641 | if (!list_is_last(&s->child_node, &parent->children)) { | ||
642 | s = list_entry(s->child_node.next, | ||
643 | struct serio, child_node); | ||
644 | break; | ||
645 | } | ||
646 | |||
647 | s = parent; | ||
648 | } | ||
649 | } while (s != root); | ||
640 | } | 650 | } |
641 | 651 | ||
642 | /* | 652 | /* |
643 | * serio_disconnect_port() unbinds a port from its driver. As a side effect | 653 | * serio_disconnect_port() unbinds a port from its driver. As a side effect |
644 | * all child ports are unbound and destroyed. | 654 | * all children ports are unbound and destroyed. |
645 | */ | 655 | */ |
646 | static void serio_disconnect_port(struct serio *serio) | 656 | static void serio_disconnect_port(struct serio *serio) |
647 | { | 657 | { |
648 | struct serio *s, *parent; | 658 | struct serio *s = serio; |
659 | |||
660 | /* | ||
661 | * Children ports should be disconnected and destroyed | ||
662 | * first; we travel the tree in depth-first order. | ||
663 | */ | ||
664 | while (!list_empty(&serio->children)) { | ||
665 | |||
666 | /* Locate a leaf */ | ||
667 | while (!list_empty(&s->children)) | ||
668 | s = list_first_entry(&s->children, | ||
669 | struct serio, child_node); | ||
649 | 670 | ||
650 | if (serio->child) { | ||
651 | /* | 671 | /* |
652 | * Children ports should be disconnected and destroyed | 672 | * Prune this leaf node unless it is the one we |
653 | * first, staring with the leaf one, since we don't want | 673 | * started with. |
654 | * to do recursion | ||
655 | */ | 674 | */ |
656 | for (s = serio; s->child; s = s->child) | 675 | if (s != serio) { |
657 | /* empty */; | 676 | struct serio *parent = s->parent; |
658 | |||
659 | do { | ||
660 | parent = s->parent; | ||
661 | 677 | ||
662 | device_release_driver(&s->dev); | 678 | device_release_driver(&s->dev); |
663 | serio_destroy_port(s); | 679 | serio_destroy_port(s); |
664 | } while ((s = parent) != serio); | 680 | |
681 | s = parent; | ||
682 | } | ||
665 | } | 683 | } |
666 | 684 | ||
667 | /* | 685 | /* |
668 | * Ok, no children left, now disconnect this port | 686 | * OK, no children left, now disconnect this port. |
669 | */ | 687 | */ |
670 | device_release_driver(&serio->dev); | 688 | device_release_driver(&serio->dev); |
671 | } | 689 | } |
@@ -678,7 +696,7 @@ EXPORT_SYMBOL(serio_rescan); | |||
678 | 696 | ||
679 | void serio_reconnect(struct serio *serio) | 697 | void serio_reconnect(struct serio *serio) |
680 | { | 698 | { |
681 | serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN); | 699 | serio_queue_event(serio, NULL, SERIO_RECONNECT_SUBTREE); |
682 | } | 700 | } |
683 | EXPORT_SYMBOL(serio_reconnect); | 701 | EXPORT_SYMBOL(serio_reconnect); |
684 | 702 | ||
@@ -706,14 +724,16 @@ void serio_unregister_port(struct serio *serio) | |||
706 | EXPORT_SYMBOL(serio_unregister_port); | 724 | EXPORT_SYMBOL(serio_unregister_port); |
707 | 725 | ||
708 | /* | 726 | /* |
709 | * Safely unregisters child port if one is present. | 727 | * Safely unregisters children ports if they are present. |
710 | */ | 728 | */ |
711 | void serio_unregister_child_port(struct serio *serio) | 729 | void serio_unregister_child_port(struct serio *serio) |
712 | { | 730 | { |
731 | struct serio *s, *next; | ||
732 | |||
713 | mutex_lock(&serio_mutex); | 733 | mutex_lock(&serio_mutex); |
714 | if (serio->child) { | 734 | list_for_each_entry_safe(s, next, &serio->children, child_node) { |
715 | serio_disconnect_port(serio->child); | 735 | serio_disconnect_port(s); |
716 | serio_destroy_port(serio->child); | 736 | serio_destroy_port(s); |
717 | } | 737 | } |
718 | mutex_unlock(&serio_mutex); | 738 | mutex_unlock(&serio_mutex); |
719 | } | 739 | } |
@@ -798,9 +818,8 @@ static void serio_attach_driver(struct serio_driver *drv) | |||
798 | 818 | ||
799 | error = driver_attach(&drv->driver); | 819 | error = driver_attach(&drv->driver); |
800 | if (error) | 820 | if (error) |
801 | printk(KERN_WARNING | 821 | pr_warning("driver_attach() failed for %s with error %d\n", |
802 | "serio: driver_attach() failed for %s with error %d\n", | 822 | drv->driver.name, error); |
803 | drv->driver.name, error); | ||
804 | } | 823 | } |
805 | 824 | ||
806 | int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) | 825 | int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) |
@@ -820,8 +839,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons | |||
820 | 839 | ||
821 | error = driver_register(&drv->driver); | 840 | error = driver_register(&drv->driver); |
822 | if (error) { | 841 | if (error) { |
823 | printk(KERN_ERR | 842 | pr_err("driver_register() failed for %s, error: %d\n", |
824 | "serio: driver_register() failed for %s, error: %d\n", | ||
825 | drv->driver.name, error); | 843 | drv->driver.name, error); |
826 | return error; | 844 | return error; |
827 | } | 845 | } |
@@ -987,7 +1005,7 @@ irqreturn_t serio_interrupt(struct serio *serio, | |||
987 | 1005 | ||
988 | if (likely(serio->drv)) { | 1006 | if (likely(serio->drv)) { |
989 | ret = serio->drv->interrupt(serio, data, dfl); | 1007 | ret = serio->drv->interrupt(serio, data, dfl); |
990 | } else if (!dfl && serio->registered) { | 1008 | } else if (!dfl && device_is_registered(&serio->dev)) { |
991 | serio_rescan(serio); | 1009 | serio_rescan(serio); |
992 | ret = IRQ_HANDLED; | 1010 | ret = IRQ_HANDLED; |
993 | } | 1011 | } |
@@ -1018,7 +1036,7 @@ static int __init serio_init(void) | |||
1018 | 1036 | ||
1019 | error = bus_register(&serio_bus); | 1037 | error = bus_register(&serio_bus); |
1020 | if (error) { | 1038 | if (error) { |
1021 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); | 1039 | pr_err("Failed to register serio bus, error: %d\n", error); |
1022 | return error; | 1040 | return error; |
1023 | } | 1041 | } |
1024 | 1042 | ||
@@ -1026,7 +1044,7 @@ static int __init serio_init(void) | |||
1026 | if (IS_ERR(serio_task)) { | 1044 | if (IS_ERR(serio_task)) { |
1027 | bus_unregister(&serio_bus); | 1045 | bus_unregister(&serio_bus); |
1028 | error = PTR_ERR(serio_task); | 1046 | error = PTR_ERR(serio_task); |
1029 | printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error); | 1047 | pr_err("Failed to start kseriod, error: %d\n", error); |
1030 | return error; | 1048 | return error; |
1031 | } | 1049 | } |
1032 | 1050 | ||
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 27fdaaffbb40..cd82bb125915 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -81,12 +81,12 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
81 | struct serio_raw_list *list; | 81 | struct serio_raw_list *list; |
82 | int retval = 0; | 82 | int retval = 0; |
83 | 83 | ||
84 | lock_kernel(); | ||
85 | retval = mutex_lock_interruptible(&serio_raw_mutex); | 84 | retval = mutex_lock_interruptible(&serio_raw_mutex); |
86 | if (retval) | 85 | if (retval) |
87 | goto out_bkl; | 86 | return retval; |
88 | 87 | ||
89 | if (!(serio_raw = serio_raw_locate(iminor(inode)))) { | 88 | serio_raw = serio_raw_locate(iminor(inode)); |
89 | if (!serio_raw) { | ||
90 | retval = -ENODEV; | 90 | retval = -ENODEV; |
91 | goto out; | 91 | goto out; |
92 | } | 92 | } |
@@ -96,7 +96,8 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
96 | goto out; | 96 | goto out; |
97 | } | 97 | } |
98 | 98 | ||
99 | if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) { | 99 | list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL); |
100 | if (!list) { | ||
100 | retval = -ENOMEM; | 101 | retval = -ENOMEM; |
101 | goto out; | 102 | goto out; |
102 | } | 103 | } |
@@ -109,8 +110,6 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
109 | 110 | ||
110 | out: | 111 | out: |
111 | mutex_unlock(&serio_raw_mutex); | 112 | mutex_unlock(&serio_raw_mutex); |
112 | out_bkl: | ||
113 | unlock_kernel(); | ||
114 | return retval; | 113 | return retval; |
115 | } | 114 | } |
116 | 115 | ||
@@ -244,6 +243,7 @@ static const struct file_operations serio_raw_fops = { | |||
244 | .write = serio_raw_write, | 243 | .write = serio_raw_write, |
245 | .poll = serio_raw_poll, | 244 | .poll = serio_raw_poll, |
246 | .fasync = serio_raw_fasync, | 245 | .fasync = serio_raw_fasync, |
246 | .llseek = noop_llseek, | ||
247 | }; | 247 | }; |
248 | 248 | ||
249 | 249 | ||
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 6d345112bcb7..6e362de3f412 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -165,6 +165,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u | |||
165 | serio->open = serport_serio_open; | 165 | serio->open = serport_serio_open; |
166 | serio->close = serport_serio_close; | 166 | serio->close = serport_serio_close; |
167 | serio->port_data = serport; | 167 | serio->port_data = serport; |
168 | serio->dev.parent = tty->dev; | ||
168 | 169 | ||
169 | serio_register_port(serport->serio); | 170 | serio_register_port(serport->serio); |
170 | printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name)); | 171 | printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name)); |
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index ebb22f88c842..bb14449fb022 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/serio.h> | 19 | #include <linux/serio.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/slab.h> | ||
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
23 | #include <linux/list.h> | 24 | #include <linux/list.h> |
24 | #include <linux/io.h> | 25 | #include <linux/io.h> |
@@ -231,7 +232,7 @@ static void sxps2_close(struct serio *pserio) | |||
231 | * It returns 0, if the driver is bound to the PS/2 device, or a negative | 232 | * It returns 0, if the driver is bound to the PS/2 device, or a negative |
232 | * value if there is an error. | 233 | * value if there is an error. |
233 | */ | 234 | */ |
234 | static int __devinit xps2_of_probe(struct of_device *ofdev, | 235 | static int __devinit xps2_of_probe(struct platform_device *ofdev, |
235 | const struct of_device_id *match) | 236 | const struct of_device_id *match) |
236 | { | 237 | { |
237 | struct resource r_irq; /* Interrupt resources */ | 238 | struct resource r_irq; /* Interrupt resources */ |
@@ -243,17 +244,17 @@ static int __devinit xps2_of_probe(struct of_device *ofdev, | |||
243 | int error; | 244 | int error; |
244 | 245 | ||
245 | dev_info(dev, "Device Tree Probing \'%s\'\n", | 246 | dev_info(dev, "Device Tree Probing \'%s\'\n", |
246 | ofdev->node->name); | 247 | ofdev->dev.of_node->name); |
247 | 248 | ||
248 | /* Get iospace for the device */ | 249 | /* Get iospace for the device */ |
249 | error = of_address_to_resource(ofdev->node, 0, &r_mem); | 250 | error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); |
250 | if (error) { | 251 | if (error) { |
251 | dev_err(dev, "invalid address\n"); | 252 | dev_err(dev, "invalid address\n"); |
252 | return error; | 253 | return error; |
253 | } | 254 | } |
254 | 255 | ||
255 | /* Get IRQ for the device */ | 256 | /* Get IRQ for the device */ |
256 | if (of_irq_to_resource(ofdev->node, 0, &r_irq) == NO_IRQ) { | 257 | if (of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq) == NO_IRQ) { |
257 | dev_err(dev, "no IRQ found\n"); | 258 | dev_err(dev, "no IRQ found\n"); |
258 | return -ENODEV; | 259 | return -ENODEV; |
259 | } | 260 | } |
@@ -270,7 +271,7 @@ static int __devinit xps2_of_probe(struct of_device *ofdev, | |||
270 | drvdata->irq = r_irq.start; | 271 | drvdata->irq = r_irq.start; |
271 | 272 | ||
272 | phys_addr = r_mem.start; | 273 | phys_addr = r_mem.start; |
273 | remap_size = r_mem.end - r_mem.start + 1; | 274 | remap_size = resource_size(&r_mem); |
274 | if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) { | 275 | if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) { |
275 | dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", | 276 | dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", |
276 | (unsigned long long)phys_addr); | 277 | (unsigned long long)phys_addr); |
@@ -331,7 +332,7 @@ failed1: | |||
331 | * if the driver module is being unloaded. It frees any resources allocated to | 332 | * if the driver module is being unloaded. It frees any resources allocated to |
332 | * the device. | 333 | * the device. |
333 | */ | 334 | */ |
334 | static int __devexit xps2_of_remove(struct of_device *of_dev) | 335 | static int __devexit xps2_of_remove(struct platform_device *of_dev) |
335 | { | 336 | { |
336 | struct device *dev = &of_dev->dev; | 337 | struct device *dev = &of_dev->dev; |
337 | struct xps2data *drvdata = dev_get_drvdata(dev); | 338 | struct xps2data *drvdata = dev_get_drvdata(dev); |
@@ -341,10 +342,10 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) | |||
341 | iounmap(drvdata->base_address); | 342 | iounmap(drvdata->base_address); |
342 | 343 | ||
343 | /* Get iospace of the device */ | 344 | /* Get iospace of the device */ |
344 | if (of_address_to_resource(of_dev->node, 0, &r_mem)) | 345 | if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem)) |
345 | dev_err(dev, "invalid address\n"); | 346 | dev_err(dev, "invalid address\n"); |
346 | else | 347 | else |
347 | release_mem_region(r_mem.start, r_mem.end - r_mem.start + 1); | 348 | release_mem_region(r_mem.start, resource_size(&r_mem)); |
348 | 349 | ||
349 | kfree(drvdata); | 350 | kfree(drvdata); |
350 | 351 | ||
@@ -354,15 +355,18 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) | |||
354 | } | 355 | } |
355 | 356 | ||
356 | /* Match table for of_platform binding */ | 357 | /* Match table for of_platform binding */ |
357 | static struct of_device_id xps2_of_match[] __devinitdata = { | 358 | static const struct of_device_id xps2_of_match[] __devinitconst = { |
358 | { .compatible = "xlnx,xps-ps2-1.00.a", }, | 359 | { .compatible = "xlnx,xps-ps2-1.00.a", }, |
359 | { /* end of list */ }, | 360 | { /* end of list */ }, |
360 | }; | 361 | }; |
361 | MODULE_DEVICE_TABLE(of, xps2_of_match); | 362 | MODULE_DEVICE_TABLE(of, xps2_of_match); |
362 | 363 | ||
363 | static struct of_platform_driver xps2_of_driver = { | 364 | static struct of_platform_driver xps2_of_driver = { |
364 | .name = DRIVER_NAME, | 365 | .driver = { |
365 | .match_table = xps2_of_match, | 366 | .name = DRIVER_NAME, |
367 | .owner = THIS_MODULE, | ||
368 | .of_match_table = xps2_of_match, | ||
369 | }, | ||
366 | .probe = xps2_of_probe, | 370 | .probe = xps2_of_probe, |
367 | .remove = __devexit_p(xps2_of_remove), | 371 | .remove = __devexit_p(xps2_of_remove), |
368 | }; | 372 | }; |
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index fbd3987af57f..a29a7812bd46 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c | |||
@@ -15,12 +15,44 @@ | |||
15 | 15 | ||
16 | #include <linux/input.h> | 16 | #include <linux/input.h> |
17 | #include <linux/input/sparse-keymap.h> | 17 | #include <linux/input/sparse-keymap.h> |
18 | #include <linux/slab.h> | ||
18 | 19 | ||
19 | MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); | 20 | MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); |
20 | MODULE_DESCRIPTION("Generic support for sparse keymaps"); | 21 | MODULE_DESCRIPTION("Generic support for sparse keymaps"); |
21 | MODULE_LICENSE("GPL v2"); | 22 | MODULE_LICENSE("GPL v2"); |
22 | MODULE_VERSION("0.1"); | 23 | MODULE_VERSION("0.1"); |
23 | 24 | ||
25 | static unsigned int sparse_keymap_get_key_index(struct input_dev *dev, | ||
26 | const struct key_entry *k) | ||
27 | { | ||
28 | struct key_entry *key; | ||
29 | unsigned int idx = 0; | ||
30 | |||
31 | for (key = dev->keycode; key->type != KE_END; key++) { | ||
32 | if (key->type == KE_KEY) { | ||
33 | if (key == k) | ||
34 | break; | ||
35 | idx++; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | return idx; | ||
40 | } | ||
41 | |||
42 | static struct key_entry *sparse_keymap_entry_by_index(struct input_dev *dev, | ||
43 | unsigned int index) | ||
44 | { | ||
45 | struct key_entry *key; | ||
46 | unsigned int key_cnt = 0; | ||
47 | |||
48 | for (key = dev->keycode; key->type != KE_END; key++) | ||
49 | if (key->type == KE_KEY) | ||
50 | if (key_cnt++ == index) | ||
51 | return key; | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
55 | |||
24 | /** | 56 | /** |
25 | * sparse_keymap_entry_from_scancode - perform sparse keymap lookup | 57 | * sparse_keymap_entry_from_scancode - perform sparse keymap lookup |
26 | * @dev: Input device using sparse keymap | 58 | * @dev: Input device using sparse keymap |
@@ -63,37 +95,59 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, | |||
63 | } | 95 | } |
64 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); | 96 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); |
65 | 97 | ||
66 | static int sparse_keymap_getkeycode(struct input_dev *dev, | 98 | static struct key_entry *sparse_keymap_locate(struct input_dev *dev, |
67 | int scancode, int *keycode) | 99 | const struct input_keymap_entry *ke) |
68 | { | 100 | { |
69 | const struct key_entry *key = | 101 | struct key_entry *key; |
70 | sparse_keymap_entry_from_scancode(dev, scancode); | 102 | unsigned int scancode; |
103 | |||
104 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) | ||
105 | key = sparse_keymap_entry_by_index(dev, ke->index); | ||
106 | else if (input_scancode_to_scalar(ke, &scancode) == 0) | ||
107 | key = sparse_keymap_entry_from_scancode(dev, scancode); | ||
108 | else | ||
109 | key = NULL; | ||
71 | 110 | ||
72 | if (key && key->type == KE_KEY) { | 111 | return key; |
73 | *keycode = key->keycode; | 112 | } |
74 | return 0; | 113 | |
114 | static int sparse_keymap_getkeycode(struct input_dev *dev, | ||
115 | struct input_keymap_entry *ke) | ||
116 | { | ||
117 | const struct key_entry *key; | ||
118 | |||
119 | if (dev->keycode) { | ||
120 | key = sparse_keymap_locate(dev, ke); | ||
121 | if (key && key->type == KE_KEY) { | ||
122 | ke->keycode = key->keycode; | ||
123 | if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) | ||
124 | ke->index = | ||
125 | sparse_keymap_get_key_index(dev, key); | ||
126 | ke->len = sizeof(key->code); | ||
127 | memcpy(ke->scancode, &key->code, sizeof(key->code)); | ||
128 | return 0; | ||
129 | } | ||
75 | } | 130 | } |
76 | 131 | ||
77 | return -EINVAL; | 132 | return -EINVAL; |
78 | } | 133 | } |
79 | 134 | ||
80 | static int sparse_keymap_setkeycode(struct input_dev *dev, | 135 | static int sparse_keymap_setkeycode(struct input_dev *dev, |
81 | int scancode, int keycode) | 136 | const struct input_keymap_entry *ke, |
137 | unsigned int *old_keycode) | ||
82 | { | 138 | { |
83 | struct key_entry *key; | 139 | struct key_entry *key; |
84 | int old_keycode; | 140 | |
85 | 141 | if (dev->keycode) { | |
86 | if (keycode < 0 || keycode > KEY_MAX) | 142 | key = sparse_keymap_locate(dev, ke); |
87 | return -EINVAL; | 143 | if (key && key->type == KE_KEY) { |
88 | 144 | *old_keycode = key->keycode; | |
89 | key = sparse_keymap_entry_from_scancode(dev, scancode); | 145 | key->keycode = ke->keycode; |
90 | if (key && key->type == KE_KEY) { | 146 | set_bit(ke->keycode, dev->keybit); |
91 | old_keycode = key->keycode; | 147 | if (!sparse_keymap_entry_from_keycode(dev, *old_keycode)) |
92 | key->keycode = keycode; | 148 | clear_bit(*old_keycode, dev->keybit); |
93 | set_bit(keycode, dev->keybit); | 149 | return 0; |
94 | if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) | 150 | } |
95 | clear_bit(old_keycode, dev->keybit); | ||
96 | return 0; | ||
97 | } | 151 | } |
98 | 152 | ||
99 | return -EINVAL; | 153 | return -EINVAL; |
@@ -155,15 +209,14 @@ int sparse_keymap_setup(struct input_dev *dev, | |||
155 | 209 | ||
156 | dev->keycode = map; | 210 | dev->keycode = map; |
157 | dev->keycodemax = map_size; | 211 | dev->keycodemax = map_size; |
158 | dev->getkeycode = sparse_keymap_getkeycode; | 212 | dev->getkeycode_new = sparse_keymap_getkeycode; |
159 | dev->setkeycode = sparse_keymap_setkeycode; | 213 | dev->setkeycode_new = sparse_keymap_setkeycode; |
160 | 214 | ||
161 | return 0; | 215 | return 0; |
162 | 216 | ||
163 | err_out: | 217 | err_out: |
164 | kfree(keymap); | 218 | kfree(map); |
165 | return error; | 219 | return error; |
166 | |||
167 | } | 220 | } |
168 | EXPORT_SYMBOL(sparse_keymap_setup); | 221 | EXPORT_SYMBOL(sparse_keymap_setup); |
169 | 222 | ||
@@ -173,14 +226,27 @@ EXPORT_SYMBOL(sparse_keymap_setup); | |||
173 | * | 226 | * |
174 | * This function is used to free memory allocated by sparse keymap | 227 | * This function is used to free memory allocated by sparse keymap |
175 | * in an input device that was set up by sparse_keymap_setup(). | 228 | * in an input device that was set up by sparse_keymap_setup(). |
229 | * NOTE: It is safe to cal this function while input device is | ||
230 | * still registered (however the drivers should care not to try to | ||
231 | * use freed keymap and thus have to shut off interrups/polling | ||
232 | * before freeing the keymap). | ||
176 | */ | 233 | */ |
177 | void sparse_keymap_free(struct input_dev *dev) | 234 | void sparse_keymap_free(struct input_dev *dev) |
178 | { | 235 | { |
236 | unsigned long flags; | ||
237 | |||
238 | /* | ||
239 | * Take event lock to prevent racing with input_get_keycode() | ||
240 | * and input_set_keycode() if we are called while input device | ||
241 | * is still registered. | ||
242 | */ | ||
243 | spin_lock_irqsave(&dev->event_lock, flags); | ||
244 | |||
179 | kfree(dev->keycode); | 245 | kfree(dev->keycode); |
180 | dev->keycode = NULL; | 246 | dev->keycode = NULL; |
181 | dev->keycodemax = 0; | 247 | dev->keycodemax = 0; |
182 | dev->getkeycode = NULL; | 248 | |
183 | dev->setkeycode = NULL; | 249 | spin_unlock_irqrestore(&dev->event_lock, flags); |
184 | } | 250 | } |
185 | EXPORT_SYMBOL(sparse_keymap_free); | 251 | EXPORT_SYMBOL(sparse_keymap_free); |
186 | 252 | ||
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index effb49ea24aa..58a87755b936 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig | |||
@@ -49,6 +49,17 @@ config TABLET_USB_GTCO | |||
49 | To compile this driver as a module, choose M here: the | 49 | To compile this driver as a module, choose M here: the |
50 | module will be called gtco. | 50 | module will be called gtco. |
51 | 51 | ||
52 | config TABLET_USB_HANWANG | ||
53 | tristate "Hanwang Art Master III tablet support (USB)" | ||
54 | depends on USB_ARCH_HAS_HCD | ||
55 | select USB | ||
56 | help | ||
57 | Say Y here if you want to use the USB version of the Hanwang Art | ||
58 | Master III tablet. | ||
59 | |||
60 | To compile this driver as a module, choose M here: the | ||
61 | module will be called hanwang. | ||
62 | |||
52 | config TABLET_USB_KBTAB | 63 | config TABLET_USB_KBTAB |
53 | tristate "KB Gear JamStudio tablet support (USB)" | 64 | tristate "KB Gear JamStudio tablet support (USB)" |
54 | depends on USB_ARCH_HAS_HCD | 65 | depends on USB_ARCH_HAS_HCD |
diff --git a/drivers/input/tablet/Makefile b/drivers/input/tablet/Makefile index ce8b9a9cfa40..3f6c25220638 100644 --- a/drivers/input/tablet/Makefile +++ b/drivers/input/tablet/Makefile | |||
@@ -8,5 +8,6 @@ wacom-objs := wacom_wac.o wacom_sys.o | |||
8 | obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o | 8 | obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o |
9 | obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o | 9 | obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o |
10 | obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o | 10 | obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o |
11 | obj-$(CONFIG_TABLET_USB_HANWANG) += hanwang.o | ||
11 | obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o | 12 | obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o |
12 | obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o | 13 | obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o |
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index 670c61c5a516..aea9a9399a36 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c | |||
@@ -66,18 +66,18 @@ static void usb_acecad_irq(struct urb *urb) | |||
66 | int prox, status; | 66 | int prox, status; |
67 | 67 | ||
68 | switch (urb->status) { | 68 | switch (urb->status) { |
69 | case 0: | 69 | case 0: |
70 | /* success */ | 70 | /* success */ |
71 | break; | 71 | break; |
72 | case -ECONNRESET: | 72 | case -ECONNRESET: |
73 | case -ENOENT: | 73 | case -ENOENT: |
74 | case -ESHUTDOWN: | 74 | case -ESHUTDOWN: |
75 | /* this urb is terminated, clean up */ | 75 | /* this urb is terminated, clean up */ |
76 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); | 76 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); |
77 | return; | 77 | return; |
78 | default: | 78 | default: |
79 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); | 79 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); |
80 | goto resubmit; | 80 | goto resubmit; |
81 | } | 81 | } |
82 | 82 | ||
83 | prox = (data[0] & 0x04) >> 2; | 83 | prox = (data[0] & 0x04) >> 2; |
@@ -135,7 +135,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ | |||
135 | struct usb_acecad *acecad; | 135 | struct usb_acecad *acecad; |
136 | struct input_dev *input_dev; | 136 | struct input_dev *input_dev; |
137 | int pipe, maxp; | 137 | int pipe, maxp; |
138 | int err = -ENOMEM; | 138 | int err; |
139 | 139 | ||
140 | if (interface->desc.bNumEndpoints != 1) | 140 | if (interface->desc.bNumEndpoints != 1) |
141 | return -ENODEV; | 141 | return -ENODEV; |
@@ -155,7 +155,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ | |||
155 | goto fail1; | 155 | goto fail1; |
156 | } | 156 | } |
157 | 157 | ||
158 | acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma); | 158 | acecad->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &acecad->data_dma); |
159 | if (!acecad->data) { | 159 | if (!acecad->data) { |
160 | err= -ENOMEM; | 160 | err= -ENOMEM; |
161 | goto fail1; | 161 | goto fail1; |
@@ -193,40 +193,34 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ | |||
193 | input_dev->close = usb_acecad_close; | 193 | input_dev->close = usb_acecad_close; |
194 | 194 | ||
195 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 195 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
196 | input_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | | ||
197 | BIT_MASK(ABS_PRESSURE); | ||
198 | input_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | | ||
199 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | ||
200 | input_dev->keybit[BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_TOOL_PEN) | | 196 | input_dev->keybit[BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_TOOL_PEN) | |
201 | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS) | | 197 | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS) | |
202 | BIT_MASK(BTN_STYLUS2); | 198 | BIT_MASK(BTN_STYLUS2); |
203 | 199 | ||
204 | switch (id->driver_info) { | 200 | switch (id->driver_info) { |
205 | case 0: | 201 | case 0: |
206 | input_dev->absmax[ABS_X] = 5000; | 202 | input_set_abs_params(input_dev, ABS_X, 0, 5000, 4, 0); |
207 | input_dev->absmax[ABS_Y] = 3750; | 203 | input_set_abs_params(input_dev, ABS_Y, 0, 3750, 4, 0); |
208 | input_dev->absmax[ABS_PRESSURE] = 512; | 204 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 512, 0, 0); |
209 | if (!strlen(acecad->name)) | 205 | if (!strlen(acecad->name)) |
210 | snprintf(acecad->name, sizeof(acecad->name), | 206 | snprintf(acecad->name, sizeof(acecad->name), |
211 | "USB Acecad Flair Tablet %04x:%04x", | 207 | "USB Acecad Flair Tablet %04x:%04x", |
212 | le16_to_cpu(dev->descriptor.idVendor), | 208 | le16_to_cpu(dev->descriptor.idVendor), |
213 | le16_to_cpu(dev->descriptor.idProduct)); | 209 | le16_to_cpu(dev->descriptor.idProduct)); |
214 | break; | 210 | break; |
215 | case 1: | 211 | |
216 | input_dev->absmax[ABS_X] = 3000; | 212 | case 1: |
217 | input_dev->absmax[ABS_Y] = 2250; | 213 | input_set_abs_params(input_dev, ABS_X, 0, 53000, 4, 0); |
218 | input_dev->absmax[ABS_PRESSURE] = 1024; | 214 | input_set_abs_params(input_dev, ABS_Y, 0, 2250, 4, 0); |
219 | if (!strlen(acecad->name)) | 215 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1024, 0, 0); |
220 | snprintf(acecad->name, sizeof(acecad->name), | 216 | if (!strlen(acecad->name)) |
221 | "USB Acecad 302 Tablet %04x:%04x", | 217 | snprintf(acecad->name, sizeof(acecad->name), |
222 | le16_to_cpu(dev->descriptor.idVendor), | 218 | "USB Acecad 302 Tablet %04x:%04x", |
223 | le16_to_cpu(dev->descriptor.idProduct)); | 219 | le16_to_cpu(dev->descriptor.idVendor), |
224 | break; | 220 | le16_to_cpu(dev->descriptor.idProduct)); |
221 | break; | ||
225 | } | 222 | } |
226 | 223 | ||
227 | input_dev->absfuzz[ABS_X] = 4; | ||
228 | input_dev->absfuzz[ABS_Y] = 4; | ||
229 | |||
230 | usb_fill_int_urb(acecad->irq, dev, pipe, | 224 | usb_fill_int_urb(acecad->irq, dev, pipe, |
231 | acecad->data, maxp > 8 ? 8 : maxp, | 225 | acecad->data, maxp > 8 ? 8 : maxp, |
232 | usb_acecad_irq, acecad, endpoint->bInterval); | 226 | usb_acecad_irq, acecad, endpoint->bInterval); |
@@ -241,7 +235,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ | |||
241 | 235 | ||
242 | return 0; | 236 | return 0; |
243 | 237 | ||
244 | fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma); | 238 | fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma); |
245 | fail1: input_free_device(input_dev); | 239 | fail1: input_free_device(input_dev); |
246 | kfree(acecad); | 240 | kfree(acecad); |
247 | return err; | 241 | return err; |
@@ -252,13 +246,11 @@ static void usb_acecad_disconnect(struct usb_interface *intf) | |||
252 | struct usb_acecad *acecad = usb_get_intfdata(intf); | 246 | struct usb_acecad *acecad = usb_get_intfdata(intf); |
253 | 247 | ||
254 | usb_set_intfdata(intf, NULL); | 248 | usb_set_intfdata(intf, NULL); |
255 | if (acecad) { | 249 | |
256 | usb_kill_urb(acecad->irq); | 250 | input_unregister_device(acecad->input); |
257 | input_unregister_device(acecad->input); | 251 | usb_free_urb(acecad->irq); |
258 | usb_free_urb(acecad->irq); | 252 | usb_free_coherent(acecad->usbdev, 8, acecad->data, acecad->data_dma); |
259 | usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma); | 253 | kfree(acecad); |
260 | kfree(acecad); | ||
261 | } | ||
262 | } | 254 | } |
263 | 255 | ||
264 | static struct usb_device_id usb_acecad_id_table [] = { | 256 | static struct usb_device_id usb_acecad_id_table [] = { |
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 7d005a3616d7..57b25b84d1fc 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
@@ -362,7 +362,7 @@ static const int macroKeyEvents[] = { | |||
362 | }; | 362 | }; |
363 | 363 | ||
364 | /*********************************************************************** | 364 | /*********************************************************************** |
365 | * Map values to strings and back. Every map shoudl have the following | 365 | * Map values to strings and back. Every map should have the following |
366 | * as its last element: { NULL, AIPTEK_INVALID_VALUE }. | 366 | * as its last element: { NULL, AIPTEK_INVALID_VALUE }. |
367 | */ | 367 | */ |
368 | #define AIPTEK_INVALID_VALUE -1 | 368 | #define AIPTEK_INVALID_VALUE -1 |
@@ -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 |
@@ -1711,8 +1708,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1711 | goto fail1; | 1708 | goto fail1; |
1712 | } | 1709 | } |
1713 | 1710 | ||
1714 | aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH, | 1711 | aiptek->data = usb_alloc_coherent(usbdev, AIPTEK_PACKET_LENGTH, |
1715 | GFP_ATOMIC, &aiptek->data_dma); | 1712 | GFP_ATOMIC, &aiptek->data_dma); |
1716 | if (!aiptek->data) { | 1713 | if (!aiptek->data) { |
1717 | dev_warn(&intf->dev, "cannot allocate usb buffer\n"); | 1714 | dev_warn(&intf->dev, "cannot allocate usb buffer\n"); |
1718 | goto fail1; | 1715 | goto fail1; |
@@ -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); |
@@ -1884,8 +1881,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1884 | 1881 | ||
1885 | fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); | 1882 | fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); |
1886 | fail3: usb_free_urb(aiptek->urb); | 1883 | fail3: usb_free_urb(aiptek->urb); |
1887 | fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, | 1884 | fail2: usb_free_coherent(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, |
1888 | aiptek->data_dma); | 1885 | aiptek->data_dma); |
1889 | fail1: usb_set_intfdata(intf, NULL); | 1886 | fail1: usb_set_intfdata(intf, NULL); |
1890 | input_free_device(inputdev); | 1887 | input_free_device(inputdev); |
1891 | kfree(aiptek); | 1888 | kfree(aiptek); |
@@ -1909,9 +1906,9 @@ static void aiptek_disconnect(struct usb_interface *intf) | |||
1909 | input_unregister_device(aiptek->inputdev); | 1906 | input_unregister_device(aiptek->inputdev); |
1910 | sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); | 1907 | sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); |
1911 | usb_free_urb(aiptek->urb); | 1908 | usb_free_urb(aiptek->urb); |
1912 | usb_buffer_free(interface_to_usbdev(intf), | 1909 | usb_free_coherent(interface_to_usbdev(intf), |
1913 | AIPTEK_PACKET_LENGTH, | 1910 | AIPTEK_PACKET_LENGTH, |
1914 | aiptek->data, aiptek->data_dma); | 1911 | aiptek->data, aiptek->data_dma); |
1915 | kfree(aiptek); | 1912 | kfree(aiptek); |
1916 | } | 1913 | } |
1917 | } | 1914 | } |
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index 3d32d3f4e486..8ea6afe2e992 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c | |||
@@ -92,7 +92,7 @@ Scott Hill shill@gtcocalcomp.com | |||
92 | /* DATA STRUCTURES */ | 92 | /* DATA STRUCTURES */ |
93 | 93 | ||
94 | /* Device table */ | 94 | /* Device table */ |
95 | static struct usb_device_id gtco_usbid_table [] = { | 95 | static const struct usb_device_id gtco_usbid_table[] = { |
96 | { USB_DEVICE(VENDOR_ID_GTCO, PID_400) }, | 96 | { USB_DEVICE(VENDOR_ID_GTCO, PID_400) }, |
97 | { USB_DEVICE(VENDOR_ID_GTCO, PID_401) }, | 97 | { USB_DEVICE(VENDOR_ID_GTCO, PID_401) }, |
98 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) }, | 98 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) }, |
@@ -850,8 +850,8 @@ static int gtco_probe(struct usb_interface *usbinterface, | |||
850 | gtco->usbdev = usb_get_dev(interface_to_usbdev(usbinterface)); | 850 | gtco->usbdev = usb_get_dev(interface_to_usbdev(usbinterface)); |
851 | 851 | ||
852 | /* Allocate some data for incoming reports */ | 852 | /* Allocate some data for incoming reports */ |
853 | gtco->buffer = usb_buffer_alloc(gtco->usbdev, REPORT_MAX_SIZE, | 853 | gtco->buffer = usb_alloc_coherent(gtco->usbdev, REPORT_MAX_SIZE, |
854 | GFP_KERNEL, >co->buf_dma); | 854 | GFP_KERNEL, >co->buf_dma); |
855 | if (!gtco->buffer) { | 855 | if (!gtco->buffer) { |
856 | err("No more memory for us buffers"); | 856 | err("No more memory for us buffers"); |
857 | error = -ENOMEM; | 857 | error = -ENOMEM; |
@@ -982,8 +982,8 @@ static int gtco_probe(struct usb_interface *usbinterface, | |||
982 | err_free_urb: | 982 | err_free_urb: |
983 | usb_free_urb(gtco->urbinfo); | 983 | usb_free_urb(gtco->urbinfo); |
984 | err_free_buf: | 984 | err_free_buf: |
985 | usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE, | 985 | usb_free_coherent(gtco->usbdev, REPORT_MAX_SIZE, |
986 | gtco->buffer, gtco->buf_dma); | 986 | gtco->buffer, gtco->buf_dma); |
987 | err_free_devs: | 987 | err_free_devs: |
988 | input_free_device(input_dev); | 988 | input_free_device(input_dev); |
989 | kfree(gtco); | 989 | kfree(gtco); |
@@ -1005,8 +1005,8 @@ static void gtco_disconnect(struct usb_interface *interface) | |||
1005 | input_unregister_device(gtco->inputdevice); | 1005 | input_unregister_device(gtco->inputdevice); |
1006 | usb_kill_urb(gtco->urbinfo); | 1006 | usb_kill_urb(gtco->urbinfo); |
1007 | usb_free_urb(gtco->urbinfo); | 1007 | usb_free_urb(gtco->urbinfo); |
1008 | usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE, | 1008 | usb_free_coherent(gtco->usbdev, REPORT_MAX_SIZE, |
1009 | gtco->buffer, gtco->buf_dma); | 1009 | gtco->buffer, gtco->buf_dma); |
1010 | kfree(gtco); | 1010 | kfree(gtco); |
1011 | } | 1011 | } |
1012 | 1012 | ||
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c new file mode 100644 index 000000000000..6504b627b234 --- /dev/null +++ b/drivers/input/tablet/hanwang.c | |||
@@ -0,0 +1,446 @@ | |||
1 | /* | ||
2 | * USB Hanwang tablet support | ||
3 | * | ||
4 | * Copyright (c) 2010 Xing Wei <weixing@hanwang.com.cn> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/usb/input.h> | ||
31 | |||
32 | #define DRIVER_AUTHOR "Xing Wei <weixing@hanwang.com.cn>" | ||
33 | #define DRIVER_DESC "USB Hanwang tablet driver" | ||
34 | #define DRIVER_LICENSE "GPL" | ||
35 | |||
36 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
37 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
38 | MODULE_LICENSE(DRIVER_LICENSE); | ||
39 | |||
40 | #define USB_VENDOR_ID_HANWANG 0x0b57 | ||
41 | #define HANWANG_TABLET_INT_CLASS 0x0003 | ||
42 | #define HANWANG_TABLET_INT_SUB_CLASS 0x0001 | ||
43 | #define HANWANG_TABLET_INT_PROTOCOL 0x0002 | ||
44 | |||
45 | #define ART_MASTER_PKGLEN_MAX 10 | ||
46 | |||
47 | /* device IDs */ | ||
48 | #define STYLUS_DEVICE_ID 0x02 | ||
49 | #define TOUCH_DEVICE_ID 0x03 | ||
50 | #define CURSOR_DEVICE_ID 0x06 | ||
51 | #define ERASER_DEVICE_ID 0x0A | ||
52 | #define PAD_DEVICE_ID 0x0F | ||
53 | |||
54 | /* match vendor and interface info */ | ||
55 | #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \ | ||
56 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR \ | ||
57 | | USB_DEVICE_ID_MATCH_INT_INFO, \ | ||
58 | .idVendor = (vend), \ | ||
59 | .bInterfaceClass = (cl), \ | ||
60 | .bInterfaceSubClass = (sc), \ | ||
61 | .bInterfaceProtocol = (pr) | ||
62 | |||
63 | enum hanwang_tablet_type { | ||
64 | HANWANG_ART_MASTER_III, | ||
65 | HANWANG_ART_MASTER_HD, | ||
66 | }; | ||
67 | |||
68 | struct hanwang { | ||
69 | unsigned char *data; | ||
70 | dma_addr_t data_dma; | ||
71 | struct input_dev *dev; | ||
72 | struct usb_device *usbdev; | ||
73 | struct urb *irq; | ||
74 | const struct hanwang_features *features; | ||
75 | unsigned int current_tool; | ||
76 | unsigned int current_id; | ||
77 | char name[64]; | ||
78 | char phys[32]; | ||
79 | }; | ||
80 | |||
81 | struct hanwang_features { | ||
82 | unsigned short pid; | ||
83 | char *name; | ||
84 | enum hanwang_tablet_type type; | ||
85 | int pkg_len; | ||
86 | int max_x; | ||
87 | int max_y; | ||
88 | int max_tilt_x; | ||
89 | int max_tilt_y; | ||
90 | int max_pressure; | ||
91 | }; | ||
92 | |||
93 | static const struct hanwang_features features_array[] = { | ||
94 | { 0x8528, "Hanwang Art Master III 0906", HANWANG_ART_MASTER_III, | ||
95 | ART_MASTER_PKGLEN_MAX, 0x5757, 0x3692, 0x3f, 0x7f, 2048 }, | ||
96 | { 0x8529, "Hanwang Art Master III 0604", HANWANG_ART_MASTER_III, | ||
97 | ART_MASTER_PKGLEN_MAX, 0x3d84, 0x2672, 0x3f, 0x7f, 2048 }, | ||
98 | { 0x852a, "Hanwang Art Master III 1308", HANWANG_ART_MASTER_III, | ||
99 | ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 }, | ||
100 | { 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD, | ||
101 | ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 }, | ||
102 | }; | ||
103 | |||
104 | static const int hw_eventtypes[] = { | ||
105 | EV_KEY, EV_ABS, EV_MSC, | ||
106 | }; | ||
107 | |||
108 | static const int hw_absevents[] = { | ||
109 | ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL, | ||
110 | ABS_RX, ABS_RY, ABS_PRESSURE, ABS_MISC, | ||
111 | }; | ||
112 | |||
113 | static const int hw_btnevents[] = { | ||
114 | BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER, | ||
115 | BTN_TOOL_MOUSE, BTN_TOOL_FINGER, | ||
116 | BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8, | ||
117 | }; | ||
118 | |||
119 | static const int hw_mscevents[] = { | ||
120 | MSC_SERIAL, | ||
121 | }; | ||
122 | |||
123 | static void hanwang_parse_packet(struct hanwang *hanwang) | ||
124 | { | ||
125 | unsigned char *data = hanwang->data; | ||
126 | struct input_dev *input_dev = hanwang->dev; | ||
127 | struct usb_device *dev = hanwang->usbdev; | ||
128 | enum hanwang_tablet_type type = hanwang->features->type; | ||
129 | int i; | ||
130 | u16 x, y, p; | ||
131 | |||
132 | switch (data[0]) { | ||
133 | case 0x02: /* data packet */ | ||
134 | switch (data[1]) { | ||
135 | case 0x80: /* tool prox out */ | ||
136 | hanwang->current_id = 0; | ||
137 | input_report_key(input_dev, hanwang->current_tool, 0); | ||
138 | break; | ||
139 | |||
140 | case 0xc2: /* first time tool prox in */ | ||
141 | switch (data[3] & 0xf0) { | ||
142 | case 0x20: /* art_master III */ | ||
143 | case 0x30: /* art_master_HD */ | ||
144 | hanwang->current_id = STYLUS_DEVICE_ID; | ||
145 | hanwang->current_tool = BTN_TOOL_PEN; | ||
146 | input_report_key(input_dev, BTN_TOOL_PEN, 1); | ||
147 | break; | ||
148 | case 0xa0: /* art_master III */ | ||
149 | case 0xb0: /* art_master_HD */ | ||
150 | hanwang->current_id = ERASER_DEVICE_ID; | ||
151 | hanwang->current_tool = BTN_TOOL_RUBBER; | ||
152 | input_report_key(input_dev, BTN_TOOL_RUBBER, 1); | ||
153 | break; | ||
154 | default: | ||
155 | hanwang->current_id = 0; | ||
156 | dev_dbg(&dev->dev, | ||
157 | "unknown tablet tool %02x ", data[0]); | ||
158 | break; | ||
159 | } | ||
160 | break; | ||
161 | |||
162 | default: /* tool data packet */ | ||
163 | x = (data[2] << 8) | data[3]; | ||
164 | y = (data[4] << 8) | data[5]; | ||
165 | |||
166 | switch (type) { | ||
167 | case HANWANG_ART_MASTER_III: | ||
168 | p = (data[6] << 3) | | ||
169 | ((data[7] & 0xc0) >> 5) | | ||
170 | (data[1] & 0x01); | ||
171 | break; | ||
172 | |||
173 | case HANWANG_ART_MASTER_HD: | ||
174 | p = (data[7] >> 6) | (data[6] << 2); | ||
175 | break; | ||
176 | |||
177 | default: | ||
178 | p = 0; | ||
179 | break; | ||
180 | } | ||
181 | |||
182 | input_report_abs(input_dev, ABS_X, | ||
183 | le16_to_cpup((__le16 *)&x)); | ||
184 | input_report_abs(input_dev, ABS_Y, | ||
185 | le16_to_cpup((__le16 *)&y)); | ||
186 | input_report_abs(input_dev, ABS_PRESSURE, | ||
187 | le16_to_cpup((__le16 *)&p)); | ||
188 | input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f); | ||
189 | input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f); | ||
190 | input_report_key(input_dev, BTN_STYLUS, data[1] & 0x02); | ||
191 | input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04); | ||
192 | break; | ||
193 | } | ||
194 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
195 | input_event(input_dev, EV_MSC, MSC_SERIAL, | ||
196 | hanwang->features->pid); | ||
197 | break; | ||
198 | |||
199 | case 0x0c: | ||
200 | /* roll wheel */ | ||
201 | hanwang->current_id = PAD_DEVICE_ID; | ||
202 | |||
203 | switch (type) { | ||
204 | case HANWANG_ART_MASTER_III: | ||
205 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | ||
206 | data[2] || data[3]); | ||
207 | input_report_abs(input_dev, ABS_WHEEL, data[1]); | ||
208 | input_report_key(input_dev, BTN_0, data[2]); | ||
209 | for (i = 0; i < 8; i++) | ||
210 | input_report_key(input_dev, | ||
211 | BTN_1 + i, data[3] & (1 << i)); | ||
212 | break; | ||
213 | |||
214 | case HANWANG_ART_MASTER_HD: | ||
215 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | ||
216 | data[2] || data[3] || data[4] || | ||
217 | data[5] || data[6]); | ||
218 | input_report_abs(input_dev, ABS_RX, | ||
219 | ((data[1] & 0x1f) << 8) | data[2]); | ||
220 | input_report_abs(input_dev, ABS_RY, | ||
221 | ((data[3] & 0x1f) << 8) | data[4]); | ||
222 | input_report_key(input_dev, BTN_0, data[5] & 0x01); | ||
223 | for (i = 0; i < 4; i++) { | ||
224 | input_report_key(input_dev, | ||
225 | BTN_1 + i, data[5] & (1 << i)); | ||
226 | input_report_key(input_dev, | ||
227 | BTN_5 + i, data[6] & (1 << i)); | ||
228 | } | ||
229 | break; | ||
230 | } | ||
231 | |||
232 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
233 | input_event(input_dev, EV_MSC, MSC_SERIAL, 0xffffffff); | ||
234 | break; | ||
235 | |||
236 | default: | ||
237 | dev_dbg(&dev->dev, "error packet %02x ", data[0]); | ||
238 | break; | ||
239 | } | ||
240 | |||
241 | input_sync(input_dev); | ||
242 | } | ||
243 | |||
244 | static void hanwang_irq(struct urb *urb) | ||
245 | { | ||
246 | struct hanwang *hanwang = urb->context; | ||
247 | struct usb_device *dev = hanwang->usbdev; | ||
248 | int retval; | ||
249 | |||
250 | switch (urb->status) { | ||
251 | case 0: | ||
252 | /* success */; | ||
253 | hanwang_parse_packet(hanwang); | ||
254 | break; | ||
255 | case -ECONNRESET: | ||
256 | case -ENOENT: | ||
257 | case -ESHUTDOWN: | ||
258 | /* this urb is terminated, clean up */ | ||
259 | dev_err(&dev->dev, "%s - urb shutting down with status: %d", | ||
260 | __func__, urb->status); | ||
261 | return; | ||
262 | default: | ||
263 | dev_err(&dev->dev, "%s - nonzero urb status received: %d", | ||
264 | __func__, urb->status); | ||
265 | break; | ||
266 | } | ||
267 | |||
268 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
269 | if (retval) | ||
270 | dev_err(&dev->dev, "%s - usb_submit_urb failed with result %d", | ||
271 | __func__, retval); | ||
272 | } | ||
273 | |||
274 | static int hanwang_open(struct input_dev *dev) | ||
275 | { | ||
276 | struct hanwang *hanwang = input_get_drvdata(dev); | ||
277 | |||
278 | hanwang->irq->dev = hanwang->usbdev; | ||
279 | if (usb_submit_urb(hanwang->irq, GFP_KERNEL)) | ||
280 | return -EIO; | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static void hanwang_close(struct input_dev *dev) | ||
286 | { | ||
287 | struct hanwang *hanwang = input_get_drvdata(dev); | ||
288 | |||
289 | usb_kill_urb(hanwang->irq); | ||
290 | } | ||
291 | |||
292 | static bool get_features(struct usb_device *dev, struct hanwang *hanwang) | ||
293 | { | ||
294 | int i; | ||
295 | |||
296 | for (i = 0; i < ARRAY_SIZE(features_array); i++) { | ||
297 | if (le16_to_cpu(dev->descriptor.idProduct) == | ||
298 | features_array[i].pid) { | ||
299 | hanwang->features = &features_array[i]; | ||
300 | return true; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | return false; | ||
305 | } | ||
306 | |||
307 | |||
308 | static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
309 | { | ||
310 | struct usb_device *dev = interface_to_usbdev(intf); | ||
311 | struct usb_endpoint_descriptor *endpoint; | ||
312 | struct hanwang *hanwang; | ||
313 | struct input_dev *input_dev; | ||
314 | int error; | ||
315 | int i; | ||
316 | |||
317 | hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL); | ||
318 | input_dev = input_allocate_device(); | ||
319 | if (!hanwang || !input_dev) { | ||
320 | error = -ENOMEM; | ||
321 | goto fail1; | ||
322 | } | ||
323 | |||
324 | if (!get_features(dev, hanwang)) { | ||
325 | error = -ENXIO; | ||
326 | goto fail1; | ||
327 | } | ||
328 | |||
329 | hanwang->data = usb_alloc_coherent(dev, hanwang->features->pkg_len, | ||
330 | GFP_KERNEL, &hanwang->data_dma); | ||
331 | if (!hanwang->data) { | ||
332 | error = -ENOMEM; | ||
333 | goto fail1; | ||
334 | } | ||
335 | |||
336 | hanwang->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
337 | if (!hanwang->irq) { | ||
338 | error = -ENOMEM; | ||
339 | goto fail2; | ||
340 | } | ||
341 | |||
342 | hanwang->usbdev = dev; | ||
343 | hanwang->dev = input_dev; | ||
344 | |||
345 | usb_make_path(dev, hanwang->phys, sizeof(hanwang->phys)); | ||
346 | strlcat(hanwang->phys, "/input0", sizeof(hanwang->phys)); | ||
347 | |||
348 | strlcpy(hanwang->name, hanwang->features->name, sizeof(hanwang->name)); | ||
349 | input_dev->name = hanwang->name; | ||
350 | input_dev->phys = hanwang->phys; | ||
351 | usb_to_input_id(dev, &input_dev->id); | ||
352 | input_dev->dev.parent = &intf->dev; | ||
353 | |||
354 | input_set_drvdata(input_dev, hanwang); | ||
355 | |||
356 | input_dev->open = hanwang_open; | ||
357 | input_dev->close = hanwang_close; | ||
358 | |||
359 | for (i = 0; i < ARRAY_SIZE(hw_eventtypes); ++i) | ||
360 | __set_bit(hw_eventtypes[i], input_dev->evbit); | ||
361 | |||
362 | for (i = 0; i < ARRAY_SIZE(hw_absevents); ++i) | ||
363 | __set_bit(hw_absevents[i], input_dev->absbit); | ||
364 | |||
365 | for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i) | ||
366 | __set_bit(hw_btnevents[i], input_dev->keybit); | ||
367 | |||
368 | for (i = 0; i < ARRAY_SIZE(hw_mscevents); ++i) | ||
369 | __set_bit(hw_mscevents[i], input_dev->mscbit); | ||
370 | |||
371 | input_set_abs_params(input_dev, ABS_X, | ||
372 | 0, hanwang->features->max_x, 4, 0); | ||
373 | input_set_abs_params(input_dev, ABS_Y, | ||
374 | 0, hanwang->features->max_y, 4, 0); | ||
375 | input_set_abs_params(input_dev, ABS_TILT_X, | ||
376 | 0, hanwang->features->max_tilt_x, 0, 0); | ||
377 | input_set_abs_params(input_dev, ABS_TILT_Y, | ||
378 | 0, hanwang->features->max_tilt_y, 0, 0); | ||
379 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
380 | 0, hanwang->features->max_pressure, 0, 0); | ||
381 | |||
382 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | ||
383 | usb_fill_int_urb(hanwang->irq, dev, | ||
384 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | ||
385 | hanwang->data, hanwang->features->pkg_len, | ||
386 | hanwang_irq, hanwang, endpoint->bInterval); | ||
387 | hanwang->irq->transfer_dma = hanwang->data_dma; | ||
388 | hanwang->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
389 | |||
390 | error = input_register_device(hanwang->dev); | ||
391 | if (error) | ||
392 | goto fail3; | ||
393 | |||
394 | usb_set_intfdata(intf, hanwang); | ||
395 | |||
396 | return 0; | ||
397 | |||
398 | fail3: usb_free_urb(hanwang->irq); | ||
399 | fail2: usb_free_coherent(dev, hanwang->features->pkg_len, | ||
400 | hanwang->data, hanwang->data_dma); | ||
401 | fail1: input_free_device(input_dev); | ||
402 | kfree(hanwang); | ||
403 | return error; | ||
404 | |||
405 | } | ||
406 | |||
407 | static void hanwang_disconnect(struct usb_interface *intf) | ||
408 | { | ||
409 | struct hanwang *hanwang = usb_get_intfdata(intf); | ||
410 | |||
411 | input_unregister_device(hanwang->dev); | ||
412 | usb_free_urb(hanwang->irq); | ||
413 | usb_free_coherent(interface_to_usbdev(intf), | ||
414 | hanwang->features->pkg_len, hanwang->data, | ||
415 | hanwang->data_dma); | ||
416 | kfree(hanwang); | ||
417 | usb_set_intfdata(intf, NULL); | ||
418 | } | ||
419 | |||
420 | static const struct usb_device_id hanwang_ids[] = { | ||
421 | { HANWANG_TABLET_DEVICE(USB_VENDOR_ID_HANWANG, HANWANG_TABLET_INT_CLASS, | ||
422 | HANWANG_TABLET_INT_SUB_CLASS, HANWANG_TABLET_INT_PROTOCOL) }, | ||
423 | {} | ||
424 | }; | ||
425 | |||
426 | MODULE_DEVICE_TABLE(usb, hanwang_ids); | ||
427 | |||
428 | static struct usb_driver hanwang_driver = { | ||
429 | .name = "hanwang", | ||
430 | .probe = hanwang_probe, | ||
431 | .disconnect = hanwang_disconnect, | ||
432 | .id_table = hanwang_ids, | ||
433 | }; | ||
434 | |||
435 | static int __init hanwang_init(void) | ||
436 | { | ||
437 | return usb_register(&hanwang_driver); | ||
438 | } | ||
439 | |||
440 | static void __exit hanwang_exit(void) | ||
441 | { | ||
442 | usb_deregister(&hanwang_driver); | ||
443 | } | ||
444 | |||
445 | module_init(hanwang_init); | ||
446 | module_exit(hanwang_exit); | ||
diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c index 6682b17bf844..290f4e57b589 100644 --- a/drivers/input/tablet/kbtab.c +++ b/drivers/input/tablet/kbtab.c | |||
@@ -34,10 +34,6 @@ struct kbtab { | |||
34 | struct input_dev *dev; | 34 | struct input_dev *dev; |
35 | struct usb_device *usbdev; | 35 | struct usb_device *usbdev; |
36 | struct urb *irq; | 36 | struct urb *irq; |
37 | int x, y; | ||
38 | int button; | ||
39 | int pressure; | ||
40 | __u32 serial[2]; | ||
41 | char phys[32]; | 37 | char phys[32]; |
42 | }; | 38 | }; |
43 | 39 | ||
@@ -46,6 +42,7 @@ static void kbtab_irq(struct urb *urb) | |||
46 | struct kbtab *kbtab = urb->context; | 42 | struct kbtab *kbtab = urb->context; |
47 | unsigned char *data = kbtab->data; | 43 | unsigned char *data = kbtab->data; |
48 | struct input_dev *dev = kbtab->dev; | 44 | struct input_dev *dev = kbtab->dev; |
45 | int pressure; | ||
49 | int retval; | 46 | int retval; |
50 | 47 | ||
51 | switch (urb->status) { | 48 | switch (urb->status) { |
@@ -63,31 +60,27 @@ static void kbtab_irq(struct urb *urb) | |||
63 | goto exit; | 60 | goto exit; |
64 | } | 61 | } |
65 | 62 | ||
66 | kbtab->x = get_unaligned_le16(&data[1]); | ||
67 | kbtab->y = get_unaligned_le16(&data[3]); | ||
68 | |||
69 | kbtab->pressure = (data[5]); | ||
70 | 63 | ||
71 | input_report_key(dev, BTN_TOOL_PEN, 1); | 64 | input_report_key(dev, BTN_TOOL_PEN, 1); |
72 | 65 | ||
73 | input_report_abs(dev, ABS_X, kbtab->x); | 66 | input_report_abs(dev, ABS_X, get_unaligned_le16(&data[1])); |
74 | input_report_abs(dev, ABS_Y, kbtab->y); | 67 | input_report_abs(dev, ABS_Y, get_unaligned_le16(&data[3])); |
75 | 68 | ||
76 | /*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/ | 69 | /*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/ |
77 | input_report_key(dev, BTN_RIGHT, data[0] & 0x02); | 70 | input_report_key(dev, BTN_RIGHT, data[0] & 0x02); |
78 | 71 | ||
79 | if (-1 == kb_pressure_click) { | 72 | pressure = data[5]; |
80 | input_report_abs(dev, ABS_PRESSURE, kbtab->pressure); | 73 | if (kb_pressure_click == -1) |
81 | } else { | 74 | input_report_abs(dev, ABS_PRESSURE, pressure); |
82 | input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0); | 75 | else |
83 | }; | 76 | input_report_key(dev, BTN_LEFT, pressure > kb_pressure_click ? 1 : 0); |
84 | 77 | ||
85 | input_sync(dev); | 78 | input_sync(dev); |
86 | 79 | ||
87 | exit: | 80 | exit: |
88 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 81 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
89 | if (retval) | 82 | if (retval) |
90 | err ("%s - usb_submit_urb failed with result %d", | 83 | err("%s - usb_submit_urb failed with result %d", |
91 | __func__, retval); | 84 | __func__, retval); |
92 | } | 85 | } |
93 | 86 | ||
@@ -129,7 +122,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
129 | if (!kbtab || !input_dev) | 122 | if (!kbtab || !input_dev) |
130 | goto fail1; | 123 | goto fail1; |
131 | 124 | ||
132 | kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma); | 125 | kbtab->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &kbtab->data_dma); |
133 | if (!kbtab->data) | 126 | if (!kbtab->data) |
134 | goto fail1; | 127 | goto fail1; |
135 | 128 | ||
@@ -153,13 +146,11 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
153 | input_dev->open = kbtab_open; | 146 | input_dev->open = kbtab_open; |
154 | input_dev->close = kbtab_close; | 147 | input_dev->close = kbtab_close; |
155 | 148 | ||
156 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | | 149 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
157 | BIT_MASK(EV_MSC); | 150 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= |
158 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | | 151 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); |
159 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | 152 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= |
160 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | | 153 | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_TOUCH); |
161 | BIT_MASK(BTN_TOUCH); | ||
162 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | ||
163 | input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0); | 154 | input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0); |
164 | input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0); | 155 | input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0); |
165 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0); | 156 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0); |
@@ -182,7 +173,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
182 | return 0; | 173 | return 0; |
183 | 174 | ||
184 | fail3: usb_free_urb(kbtab->irq); | 175 | fail3: usb_free_urb(kbtab->irq); |
185 | fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma); | 176 | fail2: usb_free_coherent(dev, 8, kbtab->data, kbtab->data_dma); |
186 | fail1: input_free_device(input_dev); | 177 | fail1: input_free_device(input_dev); |
187 | kfree(kbtab); | 178 | kfree(kbtab); |
188 | return error; | 179 | return error; |
@@ -193,13 +184,11 @@ static void kbtab_disconnect(struct usb_interface *intf) | |||
193 | struct kbtab *kbtab = usb_get_intfdata(intf); | 184 | struct kbtab *kbtab = usb_get_intfdata(intf); |
194 | 185 | ||
195 | usb_set_intfdata(intf, NULL); | 186 | usb_set_intfdata(intf, NULL); |
196 | if (kbtab) { | 187 | |
197 | usb_kill_urb(kbtab->irq); | 188 | input_unregister_device(kbtab->dev); |
198 | input_unregister_device(kbtab->dev); | 189 | usb_free_urb(kbtab->irq); |
199 | usb_free_urb(kbtab->irq); | 190 | usb_free_coherent(kbtab->usbdev, 8, kbtab->data, kbtab->data_dma); |
200 | usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma); | 191 | kfree(kbtab); |
201 | kfree(kbtab); | ||
202 | } | ||
203 | } | 192 | } |
204 | 193 | ||
205 | static struct usb_driver kbtab_driver = { | 194 | static struct usb_driver kbtab_driver = { |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 16310f368dab..de5adb109030 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -85,6 +85,7 @@ | |||
85 | #include <linux/kernel.h> | 85 | #include <linux/kernel.h> |
86 | #include <linux/slab.h> | 86 | #include <linux/slab.h> |
87 | #include <linux/module.h> | 87 | #include <linux/module.h> |
88 | #include <linux/mod_devicetable.h> | ||
88 | #include <linux/init.h> | 89 | #include <linux/init.h> |
89 | #include <linux/usb/input.h> | 90 | #include <linux/usb/input.h> |
90 | #include <asm/unaligned.h> | 91 | #include <asm/unaligned.h> |
@@ -105,44 +106,19 @@ MODULE_LICENSE(DRIVER_LICENSE); | |||
105 | 106 | ||
106 | struct wacom { | 107 | struct wacom { |
107 | dma_addr_t data_dma; | 108 | dma_addr_t data_dma; |
108 | struct input_dev *dev; | ||
109 | struct usb_device *usbdev; | 109 | struct usb_device *usbdev; |
110 | struct usb_interface *intf; | 110 | struct usb_interface *intf; |
111 | struct urb *irq; | 111 | struct urb *irq; |
112 | struct wacom_wac *wacom_wac; | 112 | struct wacom_wac wacom_wac; |
113 | struct mutex lock; | 113 | struct mutex lock; |
114 | unsigned int open:1; | 114 | bool open; |
115 | char phys[32]; | 115 | char phys[32]; |
116 | }; | 116 | }; |
117 | 117 | ||
118 | struct wacom_combo { | 118 | extern const struct usb_device_id wacom_ids[]; |
119 | struct wacom *wacom; | ||
120 | struct urb *urb; | ||
121 | }; | ||
122 | |||
123 | extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); | ||
124 | extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); | ||
125 | extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); | ||
126 | extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data); | ||
127 | extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value); | ||
128 | extern void wacom_input_sync(void *wcombo); | ||
129 | extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
130 | extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
131 | extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
132 | extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
133 | extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
134 | extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
135 | extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
136 | extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
137 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
138 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
139 | extern void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
140 | extern void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
141 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
142 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
143 | extern __u16 wacom_le16_to_cpu(unsigned char *data); | ||
144 | extern __u16 wacom_be16_to_cpu(unsigned char *data); | ||
145 | extern struct wacom_features *get_wacom_feature(const struct usb_device_id *id); | ||
146 | extern const struct usb_device_id *get_device_table(void); | ||
147 | 119 | ||
120 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); | ||
121 | void wacom_setup_device_quirks(struct wacom_features *features); | ||
122 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | ||
123 | struct wacom_wac *wacom_wac); | ||
148 | #endif | 124 | #endif |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 072f33b3b2b0..fc381498b798 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -11,8 +11,8 @@ | |||
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "wacom.h" | ||
15 | #include "wacom_wac.h" | 14 | #include "wacom_wac.h" |
15 | #include "wacom.h" | ||
16 | 16 | ||
17 | /* defines to get HID report descriptor */ | 17 | /* defines to get HID report descriptor */ |
18 | #define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) | 18 | #define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) |
@@ -70,15 +70,9 @@ static int usb_set_report(struct usb_interface *intf, unsigned char type, | |||
70 | buf, size, 1000); | 70 | buf, size, 1000); |
71 | } | 71 | } |
72 | 72 | ||
73 | static struct input_dev * get_input_dev(struct wacom_combo *wcombo) | ||
74 | { | ||
75 | return wcombo->wacom->dev; | ||
76 | } | ||
77 | |||
78 | static void wacom_sys_irq(struct urb *urb) | 73 | static void wacom_sys_irq(struct urb *urb) |
79 | { | 74 | { |
80 | struct wacom *wacom = urb->context; | 75 | struct wacom *wacom = urb->context; |
81 | struct wacom_combo wcombo; | ||
82 | int retval; | 76 | int retval; |
83 | 77 | ||
84 | switch (urb->status) { | 78 | switch (urb->status) { |
@@ -96,207 +90,55 @@ static void wacom_sys_irq(struct urb *urb) | |||
96 | goto exit; | 90 | goto exit; |
97 | } | 91 | } |
98 | 92 | ||
99 | wcombo.wacom = wacom; | 93 | wacom_wac_irq(&wacom->wacom_wac, urb->actual_length); |
100 | wcombo.urb = urb; | ||
101 | |||
102 | if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) | ||
103 | input_sync(get_input_dev(&wcombo)); | ||
104 | 94 | ||
105 | exit: | 95 | exit: |
106 | usb_mark_last_busy(wacom->usbdev); | 96 | usb_mark_last_busy(wacom->usbdev); |
107 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 97 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
108 | if (retval) | 98 | if (retval) |
109 | err ("%s - usb_submit_urb failed with result %d", | 99 | err ("%s - usb_submit_urb failed with result %d", |
110 | __func__, retval); | 100 | __func__, retval); |
111 | } | 101 | } |
112 | 102 | ||
113 | void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) | ||
114 | { | ||
115 | input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); | ||
116 | } | ||
117 | |||
118 | void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) | ||
119 | { | ||
120 | input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); | ||
121 | } | ||
122 | |||
123 | void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) | ||
124 | { | ||
125 | input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); | ||
126 | } | ||
127 | |||
128 | void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) | ||
129 | { | ||
130 | input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); | ||
131 | } | ||
132 | |||
133 | __u16 wacom_be16_to_cpu(unsigned char *data) | ||
134 | { | ||
135 | __u16 value; | ||
136 | value = be16_to_cpu(*(__be16 *) data); | ||
137 | return value; | ||
138 | } | ||
139 | |||
140 | __u16 wacom_le16_to_cpu(unsigned char *data) | ||
141 | { | ||
142 | __u16 value; | ||
143 | value = le16_to_cpu(*(__le16 *) data); | ||
144 | return value; | ||
145 | } | ||
146 | |||
147 | void wacom_input_sync(void *wcombo) | ||
148 | { | ||
149 | input_sync(get_input_dev((struct wacom_combo *)wcombo)); | ||
150 | } | ||
151 | |||
152 | static int wacom_open(struct input_dev *dev) | 103 | static int wacom_open(struct input_dev *dev) |
153 | { | 104 | { |
154 | struct wacom *wacom = input_get_drvdata(dev); | 105 | struct wacom *wacom = input_get_drvdata(dev); |
106 | int retval = 0; | ||
155 | 107 | ||
156 | mutex_lock(&wacom->lock); | 108 | if (usb_autopm_get_interface(wacom->intf) < 0) |
157 | |||
158 | wacom->irq->dev = wacom->usbdev; | ||
159 | |||
160 | if (usb_autopm_get_interface(wacom->intf) < 0) { | ||
161 | mutex_unlock(&wacom->lock); | ||
162 | return -EIO; | 109 | return -EIO; |
163 | } | 110 | |
111 | mutex_lock(&wacom->lock); | ||
164 | 112 | ||
165 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { | 113 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { |
166 | usb_autopm_put_interface(wacom->intf); | 114 | retval = -EIO; |
167 | mutex_unlock(&wacom->lock); | 115 | goto out; |
168 | return -EIO; | ||
169 | } | 116 | } |
170 | 117 | ||
171 | wacom->open = 1; | 118 | wacom->open = true; |
172 | wacom->intf->needs_remote_wakeup = 1; | 119 | wacom->intf->needs_remote_wakeup = 1; |
173 | 120 | ||
121 | out: | ||
174 | mutex_unlock(&wacom->lock); | 122 | mutex_unlock(&wacom->lock); |
175 | return 0; | 123 | usb_autopm_put_interface(wacom->intf); |
124 | return retval; | ||
176 | } | 125 | } |
177 | 126 | ||
178 | static void wacom_close(struct input_dev *dev) | 127 | static void wacom_close(struct input_dev *dev) |
179 | { | 128 | { |
180 | struct wacom *wacom = input_get_drvdata(dev); | 129 | struct wacom *wacom = input_get_drvdata(dev); |
130 | int autopm_error; | ||
131 | |||
132 | autopm_error = usb_autopm_get_interface(wacom->intf); | ||
181 | 133 | ||
182 | mutex_lock(&wacom->lock); | 134 | mutex_lock(&wacom->lock); |
183 | usb_kill_urb(wacom->irq); | 135 | usb_kill_urb(wacom->irq); |
184 | wacom->open = 0; | 136 | wacom->open = false; |
185 | wacom->intf->needs_remote_wakeup = 0; | 137 | wacom->intf->needs_remote_wakeup = 0; |
186 | mutex_unlock(&wacom->lock); | 138 | mutex_unlock(&wacom->lock); |
187 | } | ||
188 | 139 | ||
189 | void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 140 | if (!autopm_error) |
190 | { | 141 | usb_autopm_put_interface(wacom->intf); |
191 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_1) | | ||
192 | BIT_MASK(BTN_5); | ||
193 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | ||
194 | } | ||
195 | |||
196 | void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
197 | { | ||
198 | input_dev->evbit[0] |= BIT_MASK(EV_MSC); | ||
199 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | ||
200 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); | ||
201 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | | ||
202 | BIT_MASK(BTN_4); | ||
203 | } | ||
204 | |||
205 | void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
206 | { | ||
207 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | ||
208 | input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); | ||
209 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | | ||
210 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | ||
211 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | ||
212 | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | | ||
213 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); | ||
214 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); | ||
215 | } | ||
216 | |||
217 | void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
218 | { | ||
219 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); | ||
220 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | | ||
221 | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); | ||
222 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | ||
223 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
224 | } | ||
225 | |||
226 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
227 | { | ||
228 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | | ||
229 | BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); | ||
230 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | ||
231 | } | ||
232 | |||
233 | void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
234 | { | ||
235 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); | ||
236 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); | ||
237 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6); | ||
238 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
239 | } | ||
240 | |||
241 | void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
242 | { | ||
243 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_7) | BIT_MASK(BTN_8); | ||
244 | } | ||
245 | |||
246 | void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
247 | { | ||
248 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); | ||
249 | } | ||
250 | |||
251 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
252 | { | ||
253 | input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); | ||
254 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | ||
255 | input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); | ||
256 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | | ||
257 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | | ||
258 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); | ||
259 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | ||
260 | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | | ||
261 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | | ||
262 | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | | ||
263 | BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); | ||
264 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); | ||
265 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); | ||
266 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); | ||
267 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); | ||
268 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); | ||
269 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); | ||
270 | } | ||
271 | |||
272 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
273 | { | ||
274 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | | ||
275 | BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_STYLUS2); | ||
276 | } | ||
277 | |||
278 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
279 | { | ||
280 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); | ||
281 | } | ||
282 | |||
283 | void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
284 | { | ||
285 | if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP || | ||
286 | wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { | ||
287 | input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0); | ||
288 | input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0); | ||
289 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
294 | { | ||
295 | if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { | ||
296 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP); | ||
297 | input_dev->evbit[0] |= BIT_MASK(EV_MSC); | ||
298 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | ||
299 | } | ||
300 | } | 142 | } |
301 | 143 | ||
302 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, | 144 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, |
@@ -357,20 +199,33 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
357 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 199 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
358 | features->device_type = BTN_TOOL_TRIPLETAP; | 200 | features->device_type = BTN_TOOL_TRIPLETAP; |
359 | } | 201 | } |
360 | features->x_max = | 202 | if (features->type == BAMBOO_PT) { |
361 | wacom_le16_to_cpu(&report[i + 3]); | 203 | /* need to reset back */ |
362 | features->x_phy = | 204 | features->pktlen = WACOM_PKGLEN_BBTOUCH; |
363 | wacom_le16_to_cpu(&report[i + 6]); | 205 | features->device_type = BTN_TOOL_TRIPLETAP; |
364 | features->unit = report[i + 9]; | 206 | features->x_phy = |
365 | features->unitExpo = report[i + 11]; | 207 | get_unaligned_le16(&report[i + 5]); |
366 | i += 12; | 208 | features->x_max = |
209 | get_unaligned_le16(&report[i + 8]); | ||
210 | i += 15; | ||
211 | } else { | ||
212 | features->x_max = | ||
213 | get_unaligned_le16(&report[i + 3]); | ||
214 | features->x_phy = | ||
215 | get_unaligned_le16(&report[i + 6]); | ||
216 | features->unit = report[i + 9]; | ||
217 | features->unitExpo = report[i + 11]; | ||
218 | i += 12; | ||
219 | } | ||
367 | } else if (pen) { | 220 | } else if (pen) { |
368 | /* penabled only accepts exact bytes of data */ | 221 | /* penabled only accepts exact bytes of data */ |
369 | if (features->type == TABLETPC2FG) | 222 | if (features->type == TABLETPC2FG) |
370 | features->pktlen = WACOM_PKGLEN_PENABLED; | 223 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
224 | if (features->type == BAMBOO_PT) | ||
225 | features->pktlen = WACOM_PKGLEN_BBFUN; | ||
371 | features->device_type = BTN_TOOL_PEN; | 226 | features->device_type = BTN_TOOL_PEN; |
372 | features->x_max = | 227 | features->x_max = |
373 | wacom_le16_to_cpu(&report[i + 3]); | 228 | get_unaligned_le16(&report[i + 3]); |
374 | i += 4; | 229 | i += 4; |
375 | } | 230 | } |
376 | } else if (usage == WCM_DIGITIZER) { | 231 | } else if (usage == WCM_DIGITIZER) { |
@@ -392,24 +247,35 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
392 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 247 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
393 | features->device_type = BTN_TOOL_TRIPLETAP; | 248 | features->device_type = BTN_TOOL_TRIPLETAP; |
394 | features->y_max = | 249 | features->y_max = |
395 | wacom_le16_to_cpu(&report[i + 3]); | 250 | get_unaligned_le16(&report[i + 3]); |
396 | features->y_phy = | 251 | features->y_phy = |
397 | wacom_le16_to_cpu(&report[i + 6]); | 252 | get_unaligned_le16(&report[i + 6]); |
398 | i += 7; | 253 | i += 7; |
254 | } else if (features->type == BAMBOO_PT) { | ||
255 | /* need to reset back */ | ||
256 | features->pktlen = WACOM_PKGLEN_BBTOUCH; | ||
257 | features->device_type = BTN_TOOL_TRIPLETAP; | ||
258 | features->y_phy = | ||
259 | get_unaligned_le16(&report[i + 3]); | ||
260 | features->y_max = | ||
261 | get_unaligned_le16(&report[i + 6]); | ||
262 | i += 12; | ||
399 | } else { | 263 | } else { |
400 | features->y_max = | 264 | features->y_max = |
401 | features->x_max; | 265 | features->x_max; |
402 | features->y_phy = | 266 | features->y_phy = |
403 | wacom_le16_to_cpu(&report[i + 3]); | 267 | get_unaligned_le16(&report[i + 3]); |
404 | i += 4; | 268 | i += 4; |
405 | } | 269 | } |
406 | } else if (pen) { | 270 | } else if (pen) { |
407 | /* penabled only accepts exact bytes of data */ | 271 | /* penabled only accepts exact bytes of data */ |
408 | if (features->type == TABLETPC2FG) | 272 | if (features->type == TABLETPC2FG) |
409 | features->pktlen = WACOM_PKGLEN_PENABLED; | 273 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
274 | if (features->type == BAMBOO_PT) | ||
275 | features->pktlen = WACOM_PKGLEN_BBFUN; | ||
410 | features->device_type = BTN_TOOL_PEN; | 276 | features->device_type = BTN_TOOL_PEN; |
411 | features->y_max = | 277 | features->y_max = |
412 | wacom_le16_to_cpu(&report[i + 3]); | 278 | get_unaligned_le16(&report[i + 3]); |
413 | i += 4; | 279 | i += 4; |
414 | } | 280 | } |
415 | } | 281 | } |
@@ -428,7 +294,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
428 | case HID_USAGE_UNDEFINED: | 294 | case HID_USAGE_UNDEFINED: |
429 | if (usage == WCM_DESKTOP && finger) /* capacity */ | 295 | if (usage == WCM_DESKTOP && finger) /* capacity */ |
430 | features->pressure_max = | 296 | features->pressure_max = |
431 | wacom_le16_to_cpu(&report[i + 3]); | 297 | get_unaligned_le16(&report[i + 3]); |
432 | i += 4; | 298 | i += 4; |
433 | break; | 299 | break; |
434 | } | 300 | } |
@@ -457,8 +323,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
457 | if (!rep_data) | 323 | if (!rep_data) |
458 | return error; | 324 | return error; |
459 | 325 | ||
460 | /* ask to report tablet data if it is 2FGT or not a Tablet PC */ | 326 | /* ask to report tablet data if it is 2FGT Tablet PC or |
461 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | 327 | * not a Tablet PC */ |
328 | if (features->type == TABLETPC2FG) { | ||
462 | do { | 329 | do { |
463 | rep_data[0] = 3; | 330 | rep_data[0] = 3; |
464 | rep_data[1] = 4; | 331 | rep_data[1] = 4; |
@@ -470,7 +337,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
470 | WAC_HID_FEATURE_REPORT, report_id, | 337 | WAC_HID_FEATURE_REPORT, report_id, |
471 | rep_data, 3); | 338 | rep_data, 3); |
472 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); | 339 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); |
473 | } else if (features->type != TABLETPC && features->type != TABLETPC2FG) { | 340 | } else if (features->type != TABLETPC) { |
474 | do { | 341 | do { |
475 | rep_data[0] = 2; | 342 | rep_data[0] = 2; |
476 | rep_data[1] = 2; | 343 | rep_data[1] = 2; |
@@ -495,11 +362,16 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
495 | struct usb_host_interface *interface = intf->cur_altsetting; | 362 | struct usb_host_interface *interface = intf->cur_altsetting; |
496 | struct hid_descriptor *hid_desc; | 363 | struct hid_descriptor *hid_desc; |
497 | 364 | ||
498 | /* default device to penabled */ | 365 | /* default features */ |
499 | features->device_type = BTN_TOOL_PEN; | 366 | features->device_type = BTN_TOOL_PEN; |
500 | 367 | features->x_fuzz = 4; | |
501 | /* only Tablet PCs need to retrieve the info */ | 368 | features->y_fuzz = 4; |
502 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) | 369 | features->pressure_fuzz = 0; |
370 | features->distance_fuzz = 0; | ||
371 | |||
372 | /* only Tablet PCs and Bamboo P&T need to retrieve the info */ | ||
373 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && | ||
374 | (features->type != BAMBOO_PT)) | ||
503 | goto out; | 375 | goto out; |
504 | 376 | ||
505 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | 377 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { |
@@ -514,16 +386,85 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
514 | if (error) | 386 | if (error) |
515 | goto out; | 387 | goto out; |
516 | 388 | ||
517 | /* touch device found but size is not defined. use default */ | ||
518 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | ||
519 | features->x_max = 1023; | ||
520 | features->y_max = 1023; | ||
521 | } | ||
522 | |||
523 | out: | 389 | out: |
524 | return error; | 390 | return error; |
525 | } | 391 | } |
526 | 392 | ||
393 | struct wacom_usbdev_data { | ||
394 | struct list_head list; | ||
395 | struct kref kref; | ||
396 | struct usb_device *dev; | ||
397 | struct wacom_shared shared; | ||
398 | }; | ||
399 | |||
400 | static LIST_HEAD(wacom_udev_list); | ||
401 | static DEFINE_MUTEX(wacom_udev_list_lock); | ||
402 | |||
403 | static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev) | ||
404 | { | ||
405 | struct wacom_usbdev_data *data; | ||
406 | |||
407 | list_for_each_entry(data, &wacom_udev_list, list) { | ||
408 | if (data->dev == dev) { | ||
409 | kref_get(&data->kref); | ||
410 | return data; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | return NULL; | ||
415 | } | ||
416 | |||
417 | static int wacom_add_shared_data(struct wacom_wac *wacom, | ||
418 | struct usb_device *dev) | ||
419 | { | ||
420 | struct wacom_usbdev_data *data; | ||
421 | int retval = 0; | ||
422 | |||
423 | mutex_lock(&wacom_udev_list_lock); | ||
424 | |||
425 | data = wacom_get_usbdev_data(dev); | ||
426 | if (!data) { | ||
427 | data = kzalloc(sizeof(struct wacom_usbdev_data), GFP_KERNEL); | ||
428 | if (!data) { | ||
429 | retval = -ENOMEM; | ||
430 | goto out; | ||
431 | } | ||
432 | |||
433 | kref_init(&data->kref); | ||
434 | data->dev = dev; | ||
435 | list_add_tail(&data->list, &wacom_udev_list); | ||
436 | } | ||
437 | |||
438 | wacom->shared = &data->shared; | ||
439 | |||
440 | out: | ||
441 | mutex_unlock(&wacom_udev_list_lock); | ||
442 | return retval; | ||
443 | } | ||
444 | |||
445 | static void wacom_release_shared_data(struct kref *kref) | ||
446 | { | ||
447 | struct wacom_usbdev_data *data = | ||
448 | container_of(kref, struct wacom_usbdev_data, kref); | ||
449 | |||
450 | mutex_lock(&wacom_udev_list_lock); | ||
451 | list_del(&data->list); | ||
452 | mutex_unlock(&wacom_udev_list_lock); | ||
453 | |||
454 | kfree(data); | ||
455 | } | ||
456 | |||
457 | static void wacom_remove_shared_data(struct wacom_wac *wacom) | ||
458 | { | ||
459 | struct wacom_usbdev_data *data; | ||
460 | |||
461 | if (wacom->shared) { | ||
462 | data = container_of(wacom->shared, struct wacom_usbdev_data, shared); | ||
463 | kref_put(&data->kref, wacom_release_shared_data); | ||
464 | wacom->shared = NULL; | ||
465 | } | ||
466 | } | ||
467 | |||
527 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | 468 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
528 | { | 469 | { |
529 | struct usb_device *dev = interface_to_usbdev(intf); | 470 | struct usb_device *dev = interface_to_usbdev(intf); |
@@ -532,42 +473,46 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
532 | struct wacom_wac *wacom_wac; | 473 | struct wacom_wac *wacom_wac; |
533 | struct wacom_features *features; | 474 | struct wacom_features *features; |
534 | struct input_dev *input_dev; | 475 | struct input_dev *input_dev; |
535 | int error = -ENOMEM; | 476 | int error; |
477 | |||
478 | if (!id->driver_info) | ||
479 | return -EINVAL; | ||
536 | 480 | ||
537 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 481 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
538 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); | ||
539 | input_dev = input_allocate_device(); | 482 | input_dev = input_allocate_device(); |
540 | if (!wacom || !input_dev || !wacom_wac) | 483 | if (!wacom || !input_dev) { |
484 | error = -ENOMEM; | ||
541 | goto fail1; | 485 | goto fail1; |
486 | } | ||
542 | 487 | ||
543 | wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, GFP_KERNEL, &wacom->data_dma); | 488 | wacom_wac = &wacom->wacom_wac; |
544 | if (!wacom_wac->data) | 489 | wacom_wac->features = *((struct wacom_features *)id->driver_info); |
490 | features = &wacom_wac->features; | ||
491 | if (features->pktlen > WACOM_PKGLEN_MAX) { | ||
492 | error = -EINVAL; | ||
545 | goto fail1; | 493 | goto fail1; |
494 | } | ||
495 | |||
496 | wacom_wac->data = usb_alloc_coherent(dev, WACOM_PKGLEN_MAX, | ||
497 | GFP_KERNEL, &wacom->data_dma); | ||
498 | if (!wacom_wac->data) { | ||
499 | error = -ENOMEM; | ||
500 | goto fail1; | ||
501 | } | ||
546 | 502 | ||
547 | wacom->irq = usb_alloc_urb(0, GFP_KERNEL); | 503 | wacom->irq = usb_alloc_urb(0, GFP_KERNEL); |
548 | if (!wacom->irq) | 504 | if (!wacom->irq) { |
505 | error = -ENOMEM; | ||
549 | goto fail2; | 506 | goto fail2; |
507 | } | ||
550 | 508 | ||
551 | wacom->usbdev = dev; | 509 | wacom->usbdev = dev; |
552 | wacom->dev = input_dev; | ||
553 | wacom->intf = intf; | 510 | wacom->intf = intf; |
554 | mutex_init(&wacom->lock); | 511 | mutex_init(&wacom->lock); |
555 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); | 512 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); |
556 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); | 513 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); |
557 | 514 | ||
558 | wacom_wac->features = features = get_wacom_feature(id); | 515 | wacom_wac->input = input_dev; |
559 | BUG_ON(features->pktlen > WACOM_PKGLEN_MAX); | ||
560 | |||
561 | input_dev->name = wacom_wac->features->name; | ||
562 | wacom->wacom_wac = wacom_wac; | ||
563 | usb_to_input_id(dev, &input_dev->id); | ||
564 | |||
565 | input_dev->dev.parent = &intf->dev; | ||
566 | |||
567 | input_set_drvdata(input_dev, wacom); | ||
568 | |||
569 | input_dev->open = wacom_open; | ||
570 | input_dev->close = wacom_close; | ||
571 | 516 | ||
572 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | 517 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
573 | 518 | ||
@@ -576,15 +521,30 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
576 | if (error) | 521 | if (error) |
577 | goto fail2; | 522 | goto fail2; |
578 | 523 | ||
579 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 524 | wacom_setup_device_quirks(features); |
580 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); | ||
581 | 525 | ||
582 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); | 526 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
583 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); | ||
584 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); | ||
585 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); | ||
586 | 527 | ||
587 | wacom_init_input_dev(input_dev, wacom_wac); | 528 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { |
529 | /* Append the device type to the name */ | ||
530 | strlcat(wacom_wac->name, | ||
531 | features->device_type == BTN_TOOL_PEN ? | ||
532 | " Pen" : " Finger", | ||
533 | sizeof(wacom_wac->name)); | ||
534 | |||
535 | error = wacom_add_shared_data(wacom_wac, dev); | ||
536 | if (error) | ||
537 | goto fail3; | ||
538 | } | ||
539 | |||
540 | input_dev->name = wacom_wac->name; | ||
541 | input_dev->dev.parent = &intf->dev; | ||
542 | input_dev->open = wacom_open; | ||
543 | input_dev->close = wacom_close; | ||
544 | usb_to_input_id(dev, &input_dev->id); | ||
545 | input_set_drvdata(input_dev, wacom); | ||
546 | |||
547 | wacom_setup_input_capabilities(input_dev, wacom_wac); | ||
588 | 548 | ||
589 | usb_fill_int_urb(wacom->irq, dev, | 549 | usb_fill_int_urb(wacom->irq, dev, |
590 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | 550 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), |
@@ -593,9 +553,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
593 | wacom->irq->transfer_dma = wacom->data_dma; | 553 | wacom->irq->transfer_dma = wacom->data_dma; |
594 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 554 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
595 | 555 | ||
596 | error = input_register_device(wacom->dev); | 556 | error = input_register_device(input_dev); |
597 | if (error) | 557 | if (error) |
598 | goto fail3; | 558 | goto fail4; |
599 | 559 | ||
600 | /* Note that if query fails it is not a hard failure */ | 560 | /* Note that if query fails it is not a hard failure */ |
601 | wacom_query_tablet_data(intf, features); | 561 | wacom_query_tablet_data(intf, features); |
@@ -603,11 +563,11 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
603 | usb_set_intfdata(intf, wacom); | 563 | usb_set_intfdata(intf, wacom); |
604 | return 0; | 564 | return 0; |
605 | 565 | ||
566 | fail4: wacom_remove_shared_data(wacom_wac); | ||
606 | fail3: usb_free_urb(wacom->irq); | 567 | fail3: usb_free_urb(wacom->irq); |
607 | fail2: usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma); | 568 | fail2: usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma); |
608 | fail1: input_free_device(input_dev); | 569 | fail1: input_free_device(input_dev); |
609 | kfree(wacom); | 570 | kfree(wacom); |
610 | kfree(wacom_wac); | ||
611 | return error; | 571 | return error; |
612 | } | 572 | } |
613 | 573 | ||
@@ -618,11 +578,11 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
618 | usb_set_intfdata(intf, NULL); | 578 | usb_set_intfdata(intf, NULL); |
619 | 579 | ||
620 | usb_kill_urb(wacom->irq); | 580 | usb_kill_urb(wacom->irq); |
621 | input_unregister_device(wacom->dev); | 581 | input_unregister_device(wacom->wacom_wac.input); |
622 | usb_free_urb(wacom->irq); | 582 | usb_free_urb(wacom->irq); |
623 | usb_buffer_free(interface_to_usbdev(intf), WACOM_PKGLEN_MAX, | 583 | usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX, |
624 | wacom->wacom_wac->data, wacom->data_dma); | 584 | wacom->wacom_wac.data, wacom->data_dma); |
625 | kfree(wacom->wacom_wac); | 585 | wacom_remove_shared_data(&wacom->wacom_wac); |
626 | kfree(wacom); | 586 | kfree(wacom); |
627 | } | 587 | } |
628 | 588 | ||
@@ -640,17 +600,19 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message) | |||
640 | static int wacom_resume(struct usb_interface *intf) | 600 | static int wacom_resume(struct usb_interface *intf) |
641 | { | 601 | { |
642 | struct wacom *wacom = usb_get_intfdata(intf); | 602 | struct wacom *wacom = usb_get_intfdata(intf); |
643 | struct wacom_features *features = wacom->wacom_wac->features; | 603 | struct wacom_features *features = &wacom->wacom_wac.features; |
644 | int rv; | 604 | int rv; |
645 | 605 | ||
646 | mutex_lock(&wacom->lock); | 606 | mutex_lock(&wacom->lock); |
647 | if (wacom->open) { | 607 | |
608 | /* switch to wacom mode first */ | ||
609 | wacom_query_tablet_data(intf, features); | ||
610 | |||
611 | if (wacom->open) | ||
648 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); | 612 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); |
649 | /* switch to wacom mode if needed */ | 613 | else |
650 | if (!wacom_retrieve_hid_descriptor(intf, features)) | ||
651 | wacom_query_tablet_data(intf, features); | ||
652 | } else | ||
653 | rv = 0; | 614 | rv = 0; |
615 | |||
654 | mutex_unlock(&wacom->lock); | 616 | mutex_unlock(&wacom->lock); |
655 | 617 | ||
656 | return rv; | 618 | return rv; |
@@ -663,6 +625,7 @@ static int wacom_reset_resume(struct usb_interface *intf) | |||
663 | 625 | ||
664 | static struct usb_driver wacom_driver = { | 626 | static struct usb_driver wacom_driver = { |
665 | .name = "wacom", | 627 | .name = "wacom", |
628 | .id_table = wacom_ids, | ||
666 | .probe = wacom_probe, | 629 | .probe = wacom_probe, |
667 | .disconnect = wacom_disconnect, | 630 | .disconnect = wacom_disconnect, |
668 | .suspend = wacom_suspend, | 631 | .suspend = wacom_suspend, |
@@ -674,7 +637,7 @@ static struct usb_driver wacom_driver = { | |||
674 | static int __init wacom_init(void) | 637 | static int __init wacom_init(void) |
675 | { | 638 | { |
676 | int result; | 639 | int result; |
677 | wacom_driver.id_table = get_device_table(); | 640 | |
678 | result = usb_register(&wacom_driver); | 641 | result = usb_register(&wacom_driver); |
679 | if (result == 0) | 642 | if (result == 0) |
680 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | 643 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 1056f149fe31..b3252ef1e279 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -11,51 +11,58 @@ | |||
11 | * the Free Software Foundation; either version 2 of the License, or | 11 | * the Free Software Foundation; either version 2 of the License, or |
12 | * (at your option) any later version. | 12 | * (at your option) any later version. |
13 | */ | 13 | */ |
14 | #include "wacom.h" | 14 | |
15 | #include "wacom_wac.h" | 15 | #include "wacom_wac.h" |
16 | #include "wacom.h" | ||
16 | 17 | ||
17 | static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) | 18 | static int wacom_penpartner_irq(struct wacom_wac *wacom) |
18 | { | 19 | { |
19 | unsigned char *data = wacom->data; | 20 | unsigned char *data = wacom->data; |
21 | struct input_dev *input = wacom->input; | ||
20 | 22 | ||
21 | switch (data[0]) { | 23 | switch (data[0]) { |
22 | case 1: | 24 | case 1: |
23 | if (data[5] & 0x80) { | 25 | if (data[5] & 0x80) { |
24 | wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 26 | wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
25 | wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; | 27 | wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; |
26 | wacom_report_key(wcombo, wacom->tool[0], 1); | 28 | input_report_key(input, wacom->tool[0], 1); |
27 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ | 29 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ |
28 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | 30 | input_report_abs(input, ABS_X, get_unaligned_le16(&data[1])); |
29 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | 31 | input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3])); |
30 | wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127); | 32 | input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127); |
31 | wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -127)); | 33 | input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -127)); |
32 | wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); | 34 | input_report_key(input, BTN_STYLUS, (data[5] & 0x40)); |
33 | } else { | 35 | } else { |
34 | wacom_report_key(wcombo, wacom->tool[0], 0); | 36 | input_report_key(input, wacom->tool[0], 0); |
35 | wacom_report_abs(wcombo, ABS_MISC, 0); /* report tool id */ | 37 | input_report_abs(input, ABS_MISC, 0); /* report tool id */ |
36 | wacom_report_abs(wcombo, ABS_PRESSURE, -1); | 38 | input_report_abs(input, ABS_PRESSURE, -1); |
37 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 39 | input_report_key(input, BTN_TOUCH, 0); |
38 | } | 40 | } |
39 | break; | 41 | break; |
40 | case 2: | 42 | |
41 | wacom_report_key(wcombo, BTN_TOOL_PEN, 1); | 43 | case 2: |
42 | wacom_report_abs(wcombo, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ | 44 | input_report_key(input, BTN_TOOL_PEN, 1); |
43 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | 45 | input_report_abs(input, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ |
44 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | 46 | input_report_abs(input, ABS_X, get_unaligned_le16(&data[1])); |
45 | wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127); | 47 | input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3])); |
46 | wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20)); | 48 | input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127); |
47 | wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); | 49 | input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20)); |
48 | break; | 50 | input_report_key(input, BTN_STYLUS, (data[5] & 0x40)); |
49 | default: | 51 | break; |
50 | printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); | 52 | |
51 | return 0; | 53 | default: |
54 | printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); | ||
55 | return 0; | ||
52 | } | 56 | } |
57 | |||
53 | return 1; | 58 | return 1; |
54 | } | 59 | } |
55 | 60 | ||
56 | static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | 61 | static int wacom_pl_irq(struct wacom_wac *wacom) |
57 | { | 62 | { |
63 | struct wacom_features *features = &wacom->features; | ||
58 | unsigned char *data = wacom->data; | 64 | unsigned char *data = wacom->data; |
65 | struct input_dev *input = wacom->input; | ||
59 | int prox, pressure; | 66 | int prox, pressure; |
60 | 67 | ||
61 | if (data[0] != WACOM_REPORT_PENABLED) { | 68 | if (data[0] != WACOM_REPORT_PENABLED) { |
@@ -68,9 +75,9 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | |||
68 | if (prox) { | 75 | if (prox) { |
69 | wacom->id[0] = ERASER_DEVICE_ID; | 76 | wacom->id[0] = ERASER_DEVICE_ID; |
70 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); | 77 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); |
71 | if (wacom->features->pressure_max > 255) | 78 | if (features->pressure_max > 255) |
72 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); | 79 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); |
73 | pressure += (wacom->features->pressure_max + 1) / 2; | 80 | pressure += (features->pressure_max + 1) / 2; |
74 | 81 | ||
75 | /* | 82 | /* |
76 | * if going from out of proximity into proximity select between the eraser | 83 | * if going from out of proximity into proximity select between the eraser |
@@ -89,8 +96,8 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | |||
89 | /* was entered with stylus2 pressed */ | 96 | /* was entered with stylus2 pressed */ |
90 | if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { | 97 | if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { |
91 | /* report out proximity for previous tool */ | 98 | /* report out proximity for previous tool */ |
92 | wacom_report_key(wcombo, wacom->tool[1], 0); | 99 | input_report_key(input, wacom->tool[1], 0); |
93 | wacom_input_sync(wcombo); | 100 | input_sync(input); |
94 | wacom->tool[1] = BTN_TOOL_PEN; | 101 | wacom->tool[1] = BTN_TOOL_PEN; |
95 | return 0; | 102 | return 0; |
96 | } | 103 | } |
@@ -100,32 +107,33 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | |||
100 | wacom->tool[1] = BTN_TOOL_PEN; | 107 | wacom->tool[1] = BTN_TOOL_PEN; |
101 | wacom->id[0] = STYLUS_DEVICE_ID; | 108 | wacom->id[0] = STYLUS_DEVICE_ID; |
102 | } | 109 | } |
103 | wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */ | 110 | input_report_key(input, wacom->tool[1], prox); /* report in proximity for tool */ |
104 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ | 111 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ |
105 | wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); | 112 | input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); |
106 | wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); | 113 | input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); |
107 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | 114 | input_report_abs(input, ABS_PRESSURE, pressure); |
108 | 115 | ||
109 | wacom_report_key(wcombo, BTN_TOUCH, data[4] & 0x08); | 116 | input_report_key(input, BTN_TOUCH, data[4] & 0x08); |
110 | wacom_report_key(wcombo, BTN_STYLUS, data[4] & 0x10); | 117 | input_report_key(input, BTN_STYLUS, data[4] & 0x10); |
111 | /* Only allow the stylus2 button to be reported for the pen tool. */ | 118 | /* Only allow the stylus2 button to be reported for the pen tool. */ |
112 | wacom_report_key(wcombo, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); | 119 | input_report_key(input, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); |
113 | } else { | 120 | } else { |
114 | /* report proximity-out of a (valid) tool */ | 121 | /* report proximity-out of a (valid) tool */ |
115 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | 122 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { |
116 | /* Unknown tool selected default to pen tool */ | 123 | /* Unknown tool selected default to pen tool */ |
117 | wacom->tool[1] = BTN_TOOL_PEN; | 124 | wacom->tool[1] = BTN_TOOL_PEN; |
118 | } | 125 | } |
119 | wacom_report_key(wcombo, wacom->tool[1], prox); | 126 | input_report_key(input, wacom->tool[1], prox); |
120 | } | 127 | } |
121 | 128 | ||
122 | wacom->tool[0] = prox; /* Save proximity state */ | 129 | wacom->tool[0] = prox; /* Save proximity state */ |
123 | return 1; | 130 | return 1; |
124 | } | 131 | } |
125 | 132 | ||
126 | static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) | 133 | static int wacom_ptu_irq(struct wacom_wac *wacom) |
127 | { | 134 | { |
128 | unsigned char *data = wacom->data; | 135 | unsigned char *data = wacom->data; |
136 | struct input_dev *input = wacom->input; | ||
129 | 137 | ||
130 | if (data[0] != WACOM_REPORT_PENABLED) { | 138 | if (data[0] != WACOM_REPORT_PENABLED) { |
131 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); | 139 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); |
@@ -133,39 +141,74 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) | |||
133 | } | 141 | } |
134 | 142 | ||
135 | if (data[1] & 0x04) { | 143 | if (data[1] & 0x04) { |
136 | wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20); | 144 | input_report_key(input, BTN_TOOL_RUBBER, data[1] & 0x20); |
137 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08); | 145 | input_report_key(input, BTN_TOUCH, data[1] & 0x08); |
138 | wacom->id[0] = ERASER_DEVICE_ID; | 146 | wacom->id[0] = ERASER_DEVICE_ID; |
139 | } else { | 147 | } else { |
140 | wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20); | 148 | input_report_key(input, BTN_TOOL_PEN, data[1] & 0x20); |
141 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); | 149 | input_report_key(input, BTN_TOUCH, data[1] & 0x01); |
142 | wacom->id[0] = STYLUS_DEVICE_ID; | 150 | wacom->id[0] = STYLUS_DEVICE_ID; |
143 | } | 151 | } |
144 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ | 152 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ |
145 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | 153 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); |
146 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | 154 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); |
147 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | 155 | input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6])); |
148 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 156 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); |
149 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); | 157 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); |
158 | return 1; | ||
159 | } | ||
160 | |||
161 | static int wacom_dtu_irq(struct wacom_wac *wacom) | ||
162 | { | ||
163 | struct wacom_features *features = &wacom->features; | ||
164 | char *data = wacom->data; | ||
165 | struct input_dev *input = wacom->input; | ||
166 | int prox = data[1] & 0x20, pressure; | ||
167 | |||
168 | dbg("wacom_dtu_irq: received report #%d", data[0]); | ||
169 | |||
170 | if (prox) { | ||
171 | /* Going into proximity select tool */ | ||
172 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
173 | if (wacom->tool[0] == BTN_TOOL_PEN) | ||
174 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
175 | else | ||
176 | wacom->id[0] = ERASER_DEVICE_ID; | ||
177 | } | ||
178 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); | ||
179 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); | ||
180 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); | ||
181 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); | ||
182 | pressure = ((data[7] & 0x01) << 8) | data[6]; | ||
183 | if (pressure < 0) | ||
184 | pressure = features->pressure_max + pressure + 1; | ||
185 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
186 | input_report_key(input, BTN_TOUCH, data[1] & 0x05); | ||
187 | if (!prox) /* out-prox */ | ||
188 | wacom->id[0] = 0; | ||
189 | input_report_key(input, wacom->tool[0], prox); | ||
190 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
150 | return 1; | 191 | return 1; |
151 | } | 192 | } |
152 | 193 | ||
153 | static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | 194 | static int wacom_graphire_irq(struct wacom_wac *wacom) |
154 | { | 195 | { |
196 | struct wacom_features *features = &wacom->features; | ||
155 | unsigned char *data = wacom->data; | 197 | unsigned char *data = wacom->data; |
156 | int x, y, rw; | 198 | struct input_dev *input = wacom->input; |
157 | static int penData = 0; | 199 | int prox; |
200 | int rw = 0; | ||
201 | int retval = 0; | ||
158 | 202 | ||
159 | if (data[0] != WACOM_REPORT_PENABLED) { | 203 | if (data[0] != WACOM_REPORT_PENABLED) { |
160 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); | 204 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); |
161 | return 0; | 205 | goto exit; |
162 | } | 206 | } |
163 | 207 | ||
164 | if (data[1] & 0x80) { | 208 | prox = data[1] & 0x80; |
165 | /* in prox and not a pad data */ | 209 | if (prox || wacom->id[0]) { |
166 | penData = 1; | 210 | if (prox) { |
167 | 211 | switch ((data[1] >> 5) & 3) { | |
168 | switch ((data[1] >> 5) & 3) { | ||
169 | 212 | ||
170 | case 0: /* Pen */ | 213 | case 0: /* Pen */ |
171 | wacom->tool[0] = BTN_TOOL_PEN; | 214 | wacom->tool[0] = BTN_TOOL_PEN; |
@@ -178,133 +221,93 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
178 | break; | 221 | break; |
179 | 222 | ||
180 | case 2: /* Mouse with wheel */ | 223 | case 2: /* Mouse with wheel */ |
181 | wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); | 224 | input_report_key(input, BTN_MIDDLE, data[1] & 0x04); |
182 | if (wacom->features->type == WACOM_G4 || | ||
183 | wacom->features->type == WACOM_MO) { | ||
184 | rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); | ||
185 | wacom_report_rel(wcombo, REL_WHEEL, -rw); | ||
186 | } else | ||
187 | wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); | ||
188 | /* fall through */ | 225 | /* fall through */ |
189 | 226 | ||
190 | case 3: /* Mouse without wheel */ | 227 | case 3: /* Mouse without wheel */ |
191 | wacom->tool[0] = BTN_TOOL_MOUSE; | 228 | wacom->tool[0] = BTN_TOOL_MOUSE; |
192 | wacom->id[0] = CURSOR_DEVICE_ID; | 229 | wacom->id[0] = CURSOR_DEVICE_ID; |
193 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); | ||
194 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); | ||
195 | if (wacom->features->type == WACOM_G4 || | ||
196 | wacom->features->type == WACOM_MO) | ||
197 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); | ||
198 | else | ||
199 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); | ||
200 | break; | 230 | break; |
231 | } | ||
201 | } | 232 | } |
202 | x = wacom_le16_to_cpu(&data[2]); | 233 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); |
203 | y = wacom_le16_to_cpu(&data[4]); | 234 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); |
204 | wacom_report_abs(wcombo, ABS_X, x); | ||
205 | wacom_report_abs(wcombo, ABS_Y, y); | ||
206 | if (wacom->tool[0] != BTN_TOOL_MOUSE) { | 235 | if (wacom->tool[0] != BTN_TOOL_MOUSE) { |
207 | wacom_report_abs(wcombo, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); | 236 | input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); |
208 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); | 237 | input_report_key(input, BTN_TOUCH, data[1] & 0x01); |
209 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 238 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); |
210 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); | 239 | input_report_key(input, BTN_STYLUS2, data[1] & 0x04); |
211 | } | ||
212 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ | ||
213 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
214 | } else if (wacom->id[0]) { | ||
215 | wacom_report_abs(wcombo, ABS_X, 0); | ||
216 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
217 | if (wacom->tool[0] == BTN_TOOL_MOUSE) { | ||
218 | wacom_report_key(wcombo, BTN_LEFT, 0); | ||
219 | wacom_report_key(wcombo, BTN_RIGHT, 0); | ||
220 | wacom_report_abs(wcombo, ABS_DISTANCE, 0); | ||
221 | } else { | 240 | } else { |
222 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | 241 | input_report_key(input, BTN_LEFT, data[1] & 0x01); |
223 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 242 | input_report_key(input, BTN_RIGHT, data[1] & 0x02); |
224 | wacom_report_key(wcombo, BTN_STYLUS, 0); | 243 | if (features->type == WACOM_G4 || |
225 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 244 | features->type == WACOM_MO) { |
245 | input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f); | ||
246 | rw = (data[7] & 0x04) - (data[7] & 0x03); | ||
247 | } else { | ||
248 | input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f); | ||
249 | rw = -(signed char)data[6]; | ||
250 | } | ||
251 | input_report_rel(input, REL_WHEEL, rw); | ||
226 | } | 252 | } |
227 | wacom->id[0] = 0; | 253 | |
228 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | 254 | if (!prox) |
229 | wacom_report_key(wcombo, wacom->tool[0], 0); | 255 | wacom->id[0] = 0; |
256 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ | ||
257 | input_report_key(input, wacom->tool[0], prox); | ||
258 | input_sync(input); /* sync last event */ | ||
230 | } | 259 | } |
231 | 260 | ||
232 | /* send pad data */ | 261 | /* send pad data */ |
233 | switch (wacom->features->type) { | 262 | switch (features->type) { |
234 | case WACOM_G4: | 263 | case WACOM_G4: |
235 | if (data[7] & 0xf8) { | 264 | prox = data[7] & 0xf8; |
236 | if (penData) { | 265 | if (prox || wacom->id[1]) { |
237 | wacom_input_sync(wcombo); /* sync last event */ | ||
238 | if (!wacom->id[0]) | ||
239 | penData = 0; | ||
240 | } | ||
241 | wacom->id[1] = PAD_DEVICE_ID; | 266 | wacom->id[1] = PAD_DEVICE_ID; |
242 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 267 | input_report_key(input, BTN_0, (data[7] & 0x40)); |
243 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 268 | input_report_key(input, BTN_4, (data[7] & 0x80)); |
244 | rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); | 269 | rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); |
245 | wacom_report_rel(wcombo, REL_WHEEL, rw); | 270 | input_report_rel(input, REL_WHEEL, rw); |
246 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 271 | input_report_key(input, BTN_TOOL_FINGER, 0xf0); |
247 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 272 | if (!prox) |
248 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 273 | wacom->id[1] = 0; |
249 | } else if (wacom->id[1]) { | 274 | input_report_abs(input, ABS_MISC, wacom->id[1]); |
250 | if (penData) { | 275 | input_event(input, EV_MSC, MSC_SERIAL, 0xf0); |
251 | wacom_input_sync(wcombo); /* sync last event */ | 276 | retval = 1; |
252 | if (!wacom->id[0]) | ||
253 | penData = 0; | ||
254 | } | ||
255 | wacom->id[1] = 0; | ||
256 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | ||
257 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | ||
258 | wacom_report_rel(wcombo, REL_WHEEL, 0); | ||
259 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | ||
260 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
261 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
262 | } | 277 | } |
263 | break; | 278 | break; |
264 | case WACOM_MO: | 279 | |
265 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { | 280 | case WACOM_MO: |
266 | if (penData) { | 281 | prox = (data[7] & 0xf8) || data[8]; |
267 | wacom_input_sync(wcombo); /* sync last event */ | 282 | if (prox || wacom->id[1]) { |
268 | if (!wacom->id[0]) | ||
269 | penData = 0; | ||
270 | } | ||
271 | wacom->id[1] = PAD_DEVICE_ID; | 283 | wacom->id[1] = PAD_DEVICE_ID; |
272 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 284 | input_report_key(input, BTN_0, (data[7] & 0x08)); |
273 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 285 | input_report_key(input, BTN_1, (data[7] & 0x20)); |
274 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); | 286 | input_report_key(input, BTN_4, (data[7] & 0x10)); |
275 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); | 287 | input_report_key(input, BTN_5, (data[7] & 0x40)); |
276 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); | 288 | input_report_abs(input, ABS_WHEEL, (data[8] & 0x7f)); |
277 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 289 | input_report_key(input, BTN_TOOL_FINGER, 0xf0); |
278 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 290 | if (!prox) |
279 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 291 | wacom->id[1] = 0; |
280 | } else if (wacom->id[1]) { | 292 | input_report_abs(input, ABS_MISC, wacom->id[1]); |
281 | if (penData) { | 293 | input_event(input, EV_MSC, MSC_SERIAL, 0xf0); |
282 | wacom_input_sync(wcombo); /* sync last event */ | ||
283 | if (!wacom->id[0]) | ||
284 | penData = 0; | ||
285 | } | ||
286 | wacom->id[1] = 0; | ||
287 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | ||
288 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | ||
289 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); | ||
290 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); | ||
291 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); | ||
292 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | ||
293 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
294 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
295 | } | 294 | } |
295 | retval = 1; | ||
296 | break; | 296 | break; |
297 | } | 297 | } |
298 | return 1; | 298 | exit: |
299 | return retval; | ||
299 | } | 300 | } |
300 | 301 | ||
301 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | 302 | static int wacom_intuos_inout(struct wacom_wac *wacom) |
302 | { | 303 | { |
304 | struct wacom_features *features = &wacom->features; | ||
303 | unsigned char *data = wacom->data; | 305 | unsigned char *data = wacom->data; |
306 | struct input_dev *input = wacom->input; | ||
304 | int idx = 0; | 307 | int idx = 0; |
305 | 308 | ||
306 | /* tool number */ | 309 | /* tool number */ |
307 | if (wacom->features->type == INTUOS) | 310 | if (features->type == INTUOS) |
308 | idx = data[1] & 0x01; | 311 | idx = data[1] & 0x01; |
309 | 312 | ||
310 | /* Enter report */ | 313 | /* Enter report */ |
@@ -314,139 +317,159 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
314 | (data[4] << 20) + (data[5] << 12) + | 317 | (data[4] << 20) + (data[5] << 12) + |
315 | (data[6] << 4) + (data[7] >> 4); | 318 | (data[6] << 4) + (data[7] >> 4); |
316 | 319 | ||
317 | wacom->id[idx] = (data[2] << 4) | (data[3] >> 4); | 320 | wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) | |
318 | switch (wacom->id[idx]) { | 321 | ((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12); |
319 | case 0x812: /* Inking pen */ | 322 | |
320 | case 0x801: /* Intuos3 Inking pen */ | 323 | switch (wacom->id[idx] & 0xfffff) { |
321 | case 0x20802: /* Intuos4 Classic Pen */ | 324 | case 0x812: /* Inking pen */ |
322 | case 0x012: | 325 | case 0x801: /* Intuos3 Inking pen */ |
323 | wacom->tool[idx] = BTN_TOOL_PENCIL; | 326 | case 0x20802: /* Intuos4 Inking Pen */ |
324 | break; | 327 | case 0x012: |
325 | case 0x822: /* Pen */ | 328 | wacom->tool[idx] = BTN_TOOL_PENCIL; |
326 | case 0x842: | 329 | break; |
327 | case 0x852: | 330 | |
328 | case 0x823: /* Intuos3 Grip Pen */ | 331 | case 0x822: /* Pen */ |
329 | case 0x813: /* Intuos3 Classic Pen */ | 332 | case 0x842: |
330 | case 0x885: /* Intuos3 Marker Pen */ | 333 | case 0x852: |
331 | case 0x802: /* Intuos4 Grip Pen Eraser */ | 334 | case 0x823: /* Intuos3 Grip Pen */ |
332 | case 0x804: /* Intuos4 Marker Pen */ | 335 | case 0x813: /* Intuos3 Classic Pen */ |
333 | case 0x40802: /* Intuos4 Classic Pen */ | 336 | case 0x885: /* Intuos3 Marker Pen */ |
334 | case 0x022: | 337 | case 0x802: /* Intuos4 General Pen */ |
335 | wacom->tool[idx] = BTN_TOOL_PEN; | 338 | case 0x804: /* Intuos4 Marker Pen */ |
336 | break; | 339 | case 0x40802: /* Intuos4 Classic Pen */ |
337 | case 0x832: /* Stroke pen */ | 340 | case 0x022: |
338 | case 0x032: | 341 | wacom->tool[idx] = BTN_TOOL_PEN; |
339 | wacom->tool[idx] = BTN_TOOL_BRUSH; | 342 | break; |
340 | break; | 343 | |
341 | case 0x007: /* Mouse 4D and 2D */ | 344 | case 0x832: /* Stroke pen */ |
342 | case 0x09c: | 345 | case 0x032: |
343 | case 0x094: | 346 | wacom->tool[idx] = BTN_TOOL_BRUSH; |
344 | case 0x017: /* Intuos3 2D Mouse */ | 347 | break; |
345 | case 0x806: /* Intuos4 Mouse */ | 348 | |
346 | wacom->tool[idx] = BTN_TOOL_MOUSE; | 349 | case 0x007: /* Mouse 4D and 2D */ |
347 | break; | 350 | case 0x09c: |
348 | case 0x096: /* Lens cursor */ | 351 | case 0x094: |
349 | case 0x097: /* Intuos3 Lens cursor */ | 352 | case 0x017: /* Intuos3 2D Mouse */ |
350 | case 0x006: /* Intuos4 Lens cursor */ | 353 | case 0x806: /* Intuos4 Mouse */ |
351 | wacom->tool[idx] = BTN_TOOL_LENS; | 354 | wacom->tool[idx] = BTN_TOOL_MOUSE; |
352 | break; | 355 | break; |
353 | case 0x82a: /* Eraser */ | 356 | |
354 | case 0x85a: | 357 | case 0x096: /* Lens cursor */ |
355 | case 0x91a: | 358 | case 0x097: /* Intuos3 Lens cursor */ |
356 | case 0xd1a: | 359 | case 0x006: /* Intuos4 Lens cursor */ |
357 | case 0x0fa: | 360 | wacom->tool[idx] = BTN_TOOL_LENS; |
358 | case 0x82b: /* Intuos3 Grip Pen Eraser */ | 361 | break; |
359 | case 0x81b: /* Intuos3 Classic Pen Eraser */ | 362 | |
360 | case 0x91b: /* Intuos3 Airbrush Eraser */ | 363 | case 0x82a: /* Eraser */ |
361 | case 0x80c: /* Intuos4 Marker Pen Eraser */ | 364 | case 0x85a: |
362 | case 0x80a: /* Intuos4 Grip Pen Eraser */ | 365 | case 0x91a: |
363 | case 0x4080a: /* Intuos4 Classic Pen Eraser */ | 366 | case 0xd1a: |
364 | case 0x90a: /* Intuos4 Airbrush Eraser */ | 367 | case 0x0fa: |
365 | wacom->tool[idx] = BTN_TOOL_RUBBER; | 368 | case 0x82b: /* Intuos3 Grip Pen Eraser */ |
366 | break; | 369 | case 0x81b: /* Intuos3 Classic Pen Eraser */ |
367 | case 0xd12: | 370 | case 0x91b: /* Intuos3 Airbrush Eraser */ |
368 | case 0x912: | 371 | case 0x80c: /* Intuos4 Marker Pen Eraser */ |
369 | case 0x112: | 372 | case 0x80a: /* Intuos4 General Pen Eraser */ |
370 | case 0x913: /* Intuos3 Airbrush */ | 373 | case 0x4080a: /* Intuos4 Classic Pen Eraser */ |
371 | case 0x902: /* Intuos4 Airbrush */ | 374 | case 0x90a: /* Intuos4 Airbrush Eraser */ |
372 | wacom->tool[idx] = BTN_TOOL_AIRBRUSH; | 375 | wacom->tool[idx] = BTN_TOOL_RUBBER; |
373 | break; | 376 | break; |
374 | default: /* Unknown tool */ | 377 | |
375 | wacom->tool[idx] = BTN_TOOL_PEN; | 378 | case 0xd12: |
379 | case 0x912: | ||
380 | case 0x112: | ||
381 | case 0x913: /* Intuos3 Airbrush */ | ||
382 | case 0x902: /* Intuos4 Airbrush */ | ||
383 | wacom->tool[idx] = BTN_TOOL_AIRBRUSH; | ||
384 | break; | ||
385 | |||
386 | default: /* Unknown tool */ | ||
387 | wacom->tool[idx] = BTN_TOOL_PEN; | ||
388 | break; | ||
376 | } | 389 | } |
377 | return 1; | 390 | return 1; |
378 | } | 391 | } |
379 | 392 | ||
393 | /* older I4 styli don't work with new Cintiqs */ | ||
394 | if (!((wacom->id[idx] >> 20) & 0x01) && | ||
395 | (features->type == WACOM_21UX2)) | ||
396 | return 1; | ||
397 | |||
380 | /* Exit report */ | 398 | /* Exit report */ |
381 | if ((data[1] & 0xfe) == 0x80) { | 399 | if ((data[1] & 0xfe) == 0x80) { |
382 | /* | 400 | /* |
383 | * Reset all states otherwise we lose the initial states | 401 | * Reset all states otherwise we lose the initial states |
384 | * when in-prox next time | 402 | * when in-prox next time |
385 | */ | 403 | */ |
386 | wacom_report_abs(wcombo, ABS_X, 0); | 404 | input_report_abs(input, ABS_X, 0); |
387 | wacom_report_abs(wcombo, ABS_Y, 0); | 405 | input_report_abs(input, ABS_Y, 0); |
388 | wacom_report_abs(wcombo, ABS_DISTANCE, 0); | 406 | input_report_abs(input, ABS_DISTANCE, 0); |
389 | wacom_report_abs(wcombo, ABS_TILT_X, 0); | 407 | input_report_abs(input, ABS_TILT_X, 0); |
390 | wacom_report_abs(wcombo, ABS_TILT_Y, 0); | 408 | input_report_abs(input, ABS_TILT_Y, 0); |
391 | if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { | 409 | if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { |
392 | wacom_report_key(wcombo, BTN_LEFT, 0); | 410 | input_report_key(input, BTN_LEFT, 0); |
393 | wacom_report_key(wcombo, BTN_MIDDLE, 0); | 411 | input_report_key(input, BTN_MIDDLE, 0); |
394 | wacom_report_key(wcombo, BTN_RIGHT, 0); | 412 | input_report_key(input, BTN_RIGHT, 0); |
395 | wacom_report_key(wcombo, BTN_SIDE, 0); | 413 | input_report_key(input, BTN_SIDE, 0); |
396 | wacom_report_key(wcombo, BTN_EXTRA, 0); | 414 | input_report_key(input, BTN_EXTRA, 0); |
397 | wacom_report_abs(wcombo, ABS_THROTTLE, 0); | 415 | input_report_abs(input, ABS_THROTTLE, 0); |
398 | wacom_report_abs(wcombo, ABS_RZ, 0); | 416 | input_report_abs(input, ABS_RZ, 0); |
399 | } else { | 417 | } else { |
400 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | 418 | input_report_abs(input, ABS_PRESSURE, 0); |
401 | wacom_report_key(wcombo, BTN_STYLUS, 0); | 419 | input_report_key(input, BTN_STYLUS, 0); |
402 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 420 | input_report_key(input, BTN_STYLUS2, 0); |
403 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 421 | input_report_key(input, BTN_TOUCH, 0); |
404 | wacom_report_abs(wcombo, ABS_WHEEL, 0); | 422 | input_report_abs(input, ABS_WHEEL, 0); |
405 | if (wacom->features->type >= INTUOS3S) | 423 | if (features->type >= INTUOS3S) |
406 | wacom_report_abs(wcombo, ABS_Z, 0); | 424 | input_report_abs(input, ABS_Z, 0); |
407 | } | 425 | } |
408 | wacom_report_key(wcombo, wacom->tool[idx], 0); | 426 | input_report_key(input, wacom->tool[idx], 0); |
409 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | 427 | input_report_abs(input, ABS_MISC, 0); /* reset tool id */ |
410 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 428 | input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); |
411 | wacom->id[idx] = 0; | 429 | wacom->id[idx] = 0; |
412 | return 2; | 430 | return 2; |
413 | } | 431 | } |
414 | return 0; | 432 | return 0; |
415 | } | 433 | } |
416 | 434 | ||
417 | static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) | 435 | static void wacom_intuos_general(struct wacom_wac *wacom) |
418 | { | 436 | { |
437 | struct wacom_features *features = &wacom->features; | ||
419 | unsigned char *data = wacom->data; | 438 | unsigned char *data = wacom->data; |
439 | struct input_dev *input = wacom->input; | ||
420 | unsigned int t; | 440 | unsigned int t; |
421 | 441 | ||
422 | /* general pen packet */ | 442 | /* general pen packet */ |
423 | if ((data[1] & 0xb8) == 0xa0) { | 443 | if ((data[1] & 0xb8) == 0xa0) { |
424 | t = (data[6] << 2) | ((data[7] >> 6) & 3); | 444 | t = (data[6] << 2) | ((data[7] >> 6) & 3); |
425 | if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) | 445 | if ((features->type >= INTUOS4S && features->type <= INTUOS4L) || |
446 | features->type == WACOM_21UX2) { | ||
426 | t = (t << 1) | (data[1] & 1); | 447 | t = (t << 1) | (data[1] & 1); |
427 | wacom_report_abs(wcombo, ABS_PRESSURE, t); | 448 | } |
428 | wacom_report_abs(wcombo, ABS_TILT_X, | 449 | input_report_abs(input, ABS_PRESSURE, t); |
450 | input_report_abs(input, ABS_TILT_X, | ||
429 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 451 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); |
430 | wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); | 452 | input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); |
431 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 2); | 453 | input_report_key(input, BTN_STYLUS, data[1] & 2); |
432 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 4); | 454 | input_report_key(input, BTN_STYLUS2, data[1] & 4); |
433 | wacom_report_key(wcombo, BTN_TOUCH, t > 10); | 455 | input_report_key(input, BTN_TOUCH, t > 10); |
434 | } | 456 | } |
435 | 457 | ||
436 | /* airbrush second packet */ | 458 | /* airbrush second packet */ |
437 | if ((data[1] & 0xbc) == 0xb4) { | 459 | if ((data[1] & 0xbc) == 0xb4) { |
438 | wacom_report_abs(wcombo, ABS_WHEEL, | 460 | input_report_abs(input, ABS_WHEEL, |
439 | (data[6] << 2) | ((data[7] >> 6) & 3)); | 461 | (data[6] << 2) | ((data[7] >> 6) & 3)); |
440 | wacom_report_abs(wcombo, ABS_TILT_X, | 462 | input_report_abs(input, ABS_TILT_X, |
441 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 463 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); |
442 | wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); | 464 | input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); |
443 | } | 465 | } |
444 | return; | ||
445 | } | 466 | } |
446 | 467 | ||
447 | static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | 468 | static int wacom_intuos_irq(struct wacom_wac *wacom) |
448 | { | 469 | { |
470 | struct wacom_features *features = &wacom->features; | ||
449 | unsigned char *data = wacom->data; | 471 | unsigned char *data = wacom->data; |
472 | struct input_dev *input = wacom->input; | ||
450 | unsigned int t; | 473 | unsigned int t; |
451 | int idx = 0, result; | 474 | int idx = 0, result; |
452 | 475 | ||
@@ -457,7 +480,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
457 | } | 480 | } |
458 | 481 | ||
459 | /* tool number */ | 482 | /* tool number */ |
460 | if (wacom->features->type == INTUOS) | 483 | if (features->type == INTUOS) |
461 | idx = data[1] & 0x01; | 484 | idx = data[1] & 0x01; |
462 | 485 | ||
463 | /* pad packets. Works as a second tool and is always in prox */ | 486 | /* pad packets. Works as a second tool and is always in prox */ |
@@ -466,269 +489,311 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
466 | if (wacom->tool[1] != BTN_TOOL_FINGER) | 489 | if (wacom->tool[1] != BTN_TOOL_FINGER) |
467 | wacom->tool[1] = BTN_TOOL_FINGER; | 490 | wacom->tool[1] = BTN_TOOL_FINGER; |
468 | 491 | ||
469 | if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { | 492 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { |
470 | wacom_report_key(wcombo, BTN_0, (data[2] & 0x01)); | 493 | input_report_key(input, BTN_0, (data[2] & 0x01)); |
471 | wacom_report_key(wcombo, BTN_1, (data[3] & 0x01)); | 494 | input_report_key(input, BTN_1, (data[3] & 0x01)); |
472 | wacom_report_key(wcombo, BTN_2, (data[3] & 0x02)); | 495 | input_report_key(input, BTN_2, (data[3] & 0x02)); |
473 | wacom_report_key(wcombo, BTN_3, (data[3] & 0x04)); | 496 | input_report_key(input, BTN_3, (data[3] & 0x04)); |
474 | wacom_report_key(wcombo, BTN_4, (data[3] & 0x08)); | 497 | input_report_key(input, BTN_4, (data[3] & 0x08)); |
475 | wacom_report_key(wcombo, BTN_5, (data[3] & 0x10)); | 498 | input_report_key(input, BTN_5, (data[3] & 0x10)); |
476 | wacom_report_key(wcombo, BTN_6, (data[3] & 0x20)); | 499 | input_report_key(input, BTN_6, (data[3] & 0x20)); |
477 | if (data[1] & 0x80) { | 500 | if (data[1] & 0x80) { |
478 | wacom_report_abs(wcombo, ABS_WHEEL, (data[1] & 0x7f)); | 501 | input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); |
479 | } else { | 502 | } else { |
480 | /* Out of proximity, clear wheel value. */ | 503 | /* Out of proximity, clear wheel value. */ |
481 | wacom_report_abs(wcombo, ABS_WHEEL, 0); | 504 | input_report_abs(input, ABS_WHEEL, 0); |
482 | } | 505 | } |
483 | if (wacom->features->type != INTUOS4S) { | 506 | if (features->type != INTUOS4S) { |
484 | wacom_report_key(wcombo, BTN_7, (data[3] & 0x40)); | 507 | input_report_key(input, BTN_7, (data[3] & 0x40)); |
485 | wacom_report_key(wcombo, BTN_8, (data[3] & 0x80)); | 508 | input_report_key(input, BTN_8, (data[3] & 0x80)); |
486 | } | 509 | } |
487 | if (data[1] | (data[2] & 0x01) | data[3]) { | 510 | if (data[1] | (data[2] & 0x01) | data[3]) { |
488 | wacom_report_key(wcombo, wacom->tool[1], 1); | 511 | input_report_key(input, wacom->tool[1], 1); |
489 | wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); | 512 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); |
490 | } else { | 513 | } else { |
491 | wacom_report_key(wcombo, wacom->tool[1], 0); | 514 | input_report_key(input, wacom->tool[1], 0); |
492 | wacom_report_abs(wcombo, ABS_MISC, 0); | 515 | input_report_abs(input, ABS_MISC, 0); |
493 | } | 516 | } |
494 | } else { | 517 | } else { |
495 | wacom_report_key(wcombo, BTN_0, (data[5] & 0x01)); | 518 | if (features->type == WACOM_21UX2) { |
496 | wacom_report_key(wcombo, BTN_1, (data[5] & 0x02)); | 519 | input_report_key(input, BTN_0, (data[5] & 0x01)); |
497 | wacom_report_key(wcombo, BTN_2, (data[5] & 0x04)); | 520 | input_report_key(input, BTN_1, (data[6] & 0x01)); |
498 | wacom_report_key(wcombo, BTN_3, (data[5] & 0x08)); | 521 | input_report_key(input, BTN_2, (data[6] & 0x02)); |
499 | wacom_report_key(wcombo, BTN_4, (data[6] & 0x01)); | 522 | input_report_key(input, BTN_3, (data[6] & 0x04)); |
500 | wacom_report_key(wcombo, BTN_5, (data[6] & 0x02)); | 523 | input_report_key(input, BTN_4, (data[6] & 0x08)); |
501 | wacom_report_key(wcombo, BTN_6, (data[6] & 0x04)); | 524 | input_report_key(input, BTN_5, (data[6] & 0x10)); |
502 | wacom_report_key(wcombo, BTN_7, (data[6] & 0x08)); | 525 | input_report_key(input, BTN_6, (data[6] & 0x20)); |
503 | wacom_report_key(wcombo, BTN_8, (data[5] & 0x10)); | 526 | input_report_key(input, BTN_7, (data[6] & 0x40)); |
504 | wacom_report_key(wcombo, BTN_9, (data[6] & 0x10)); | 527 | input_report_key(input, BTN_8, (data[6] & 0x80)); |
505 | wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); | 528 | input_report_key(input, BTN_9, (data[7] & 0x01)); |
506 | wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); | 529 | input_report_key(input, BTN_A, (data[8] & 0x01)); |
507 | 530 | input_report_key(input, BTN_B, (data[8] & 0x02)); | |
508 | if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | | 531 | input_report_key(input, BTN_C, (data[8] & 0x04)); |
509 | data[2] | (data[3] & 0x1f) | data[4]) { | 532 | input_report_key(input, BTN_X, (data[8] & 0x08)); |
510 | wacom_report_key(wcombo, wacom->tool[1], 1); | 533 | input_report_key(input, BTN_Y, (data[8] & 0x10)); |
511 | wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); | 534 | input_report_key(input, BTN_Z, (data[8] & 0x20)); |
535 | input_report_key(input, BTN_BASE, (data[8] & 0x40)); | ||
536 | input_report_key(input, BTN_BASE2, (data[8] & 0x80)); | ||
537 | } else { | ||
538 | input_report_key(input, BTN_0, (data[5] & 0x01)); | ||
539 | input_report_key(input, BTN_1, (data[5] & 0x02)); | ||
540 | input_report_key(input, BTN_2, (data[5] & 0x04)); | ||
541 | input_report_key(input, BTN_3, (data[5] & 0x08)); | ||
542 | input_report_key(input, BTN_4, (data[6] & 0x01)); | ||
543 | input_report_key(input, BTN_5, (data[6] & 0x02)); | ||
544 | input_report_key(input, BTN_6, (data[6] & 0x04)); | ||
545 | input_report_key(input, BTN_7, (data[6] & 0x08)); | ||
546 | input_report_key(input, BTN_8, (data[5] & 0x10)); | ||
547 | input_report_key(input, BTN_9, (data[6] & 0x10)); | ||
548 | } | ||
549 | input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); | ||
550 | input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); | ||
551 | |||
552 | if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) | | ||
553 | data[2] | (data[3] & 0x1f) | data[4] | data[8] | | ||
554 | (data[7] & 0x01)) { | ||
555 | input_report_key(input, wacom->tool[1], 1); | ||
556 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
512 | } else { | 557 | } else { |
513 | wacom_report_key(wcombo, wacom->tool[1], 0); | 558 | input_report_key(input, wacom->tool[1], 0); |
514 | wacom_report_abs(wcombo, ABS_MISC, 0); | 559 | input_report_abs(input, ABS_MISC, 0); |
515 | } | 560 | } |
516 | } | 561 | } |
517 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff); | 562 | input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff); |
518 | return 1; | 563 | return 1; |
519 | } | 564 | } |
520 | 565 | ||
521 | /* process in/out prox events */ | 566 | /* process in/out prox events */ |
522 | result = wacom_intuos_inout(wacom, wcombo); | 567 | result = wacom_intuos_inout(wacom); |
523 | if (result) | 568 | if (result) |
524 | return result-1; | 569 | return result - 1; |
525 | 570 | ||
526 | /* don't proceed if we don't know the ID */ | 571 | /* don't proceed if we don't know the ID */ |
527 | if (!wacom->id[idx]) | 572 | if (!wacom->id[idx]) |
528 | return 0; | 573 | return 0; |
529 | 574 | ||
530 | /* Only large Intuos support Lense Cursor */ | 575 | /* Only large Intuos support Lense Cursor */ |
531 | if ((wacom->tool[idx] == BTN_TOOL_LENS) | 576 | if (wacom->tool[idx] == BTN_TOOL_LENS && |
532 | && ((wacom->features->type == INTUOS3) | 577 | (features->type == INTUOS3 || |
533 | || (wacom->features->type == INTUOS3S) | 578 | features->type == INTUOS3S || |
534 | || (wacom->features->type == INTUOS4) | 579 | features->type == INTUOS4 || |
535 | || (wacom->features->type == INTUOS4S))) | 580 | features->type == INTUOS4S)) { |
581 | |||
536 | return 0; | 582 | return 0; |
583 | } | ||
537 | 584 | ||
538 | /* Cintiq doesn't send data when RDY bit isn't set */ | 585 | /* Cintiq doesn't send data when RDY bit isn't set */ |
539 | if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) | 586 | if (features->type == CINTIQ && !(data[1] & 0x40)) |
540 | return 0; | 587 | return 0; |
541 | 588 | ||
542 | if (wacom->features->type >= INTUOS3S) { | 589 | if (features->type >= INTUOS3S) { |
543 | wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); | 590 | input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); |
544 | wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); | 591 | input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); |
545 | wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); | 592 | input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); |
546 | } else { | 593 | } else { |
547 | wacom_report_abs(wcombo, ABS_X, wacom_be16_to_cpu(&data[2])); | 594 | input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[2])); |
548 | wacom_report_abs(wcombo, ABS_Y, wacom_be16_to_cpu(&data[4])); | 595 | input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[4])); |
549 | wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); | 596 | input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); |
550 | } | 597 | } |
551 | 598 | ||
552 | /* process general packets */ | 599 | /* process general packets */ |
553 | wacom_intuos_general(wacom, wcombo); | 600 | wacom_intuos_general(wacom); |
554 | 601 | ||
555 | /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ | 602 | /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ |
556 | if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { | 603 | if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { |
557 | 604 | ||
558 | if (data[1] & 0x02) { | 605 | if (data[1] & 0x02) { |
559 | /* Rotation packet */ | 606 | /* Rotation packet */ |
560 | if (wacom->features->type >= INTUOS3S) { | 607 | if (features->type >= INTUOS3S) { |
561 | /* I3 marker pen rotation */ | 608 | /* I3 marker pen rotation */ |
562 | t = (data[6] << 3) | ((data[7] >> 5) & 7); | 609 | t = (data[6] << 3) | ((data[7] >> 5) & 7); |
563 | t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : | 610 | t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : |
564 | ((t-1) / 2 + 450)) : (450 - t / 2) ; | 611 | ((t-1) / 2 + 450)) : (450 - t / 2) ; |
565 | wacom_report_abs(wcombo, ABS_Z, t); | 612 | input_report_abs(input, ABS_Z, t); |
566 | } else { | 613 | } else { |
567 | /* 4D mouse rotation packet */ | 614 | /* 4D mouse rotation packet */ |
568 | t = (data[6] << 3) | ((data[7] >> 5) & 7); | 615 | t = (data[6] << 3) | ((data[7] >> 5) & 7); |
569 | wacom_report_abs(wcombo, ABS_RZ, (data[7] & 0x20) ? | 616 | input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? |
570 | ((t - 1) / 2) : -t / 2); | 617 | ((t - 1) / 2) : -t / 2); |
571 | } | 618 | } |
572 | 619 | ||
573 | } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) { | 620 | } else if (!(data[1] & 0x10) && features->type < INTUOS3S) { |
574 | /* 4D mouse packet */ | 621 | /* 4D mouse packet */ |
575 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); | 622 | input_report_key(input, BTN_LEFT, data[8] & 0x01); |
576 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); | 623 | input_report_key(input, BTN_MIDDLE, data[8] & 0x02); |
577 | wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04); | 624 | input_report_key(input, BTN_RIGHT, data[8] & 0x04); |
578 | 625 | ||
579 | wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x20); | 626 | input_report_key(input, BTN_SIDE, data[8] & 0x20); |
580 | wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x10); | 627 | input_report_key(input, BTN_EXTRA, data[8] & 0x10); |
581 | t = (data[6] << 2) | ((data[7] >> 6) & 3); | 628 | t = (data[6] << 2) | ((data[7] >> 6) & 3); |
582 | wacom_report_abs(wcombo, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); | 629 | input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); |
583 | 630 | ||
584 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { | 631 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { |
585 | /* I4 mouse */ | 632 | /* I4 mouse */ |
586 | if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { | 633 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { |
587 | wacom_report_key(wcombo, BTN_LEFT, data[6] & 0x01); | 634 | input_report_key(input, BTN_LEFT, data[6] & 0x01); |
588 | wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02); | 635 | input_report_key(input, BTN_MIDDLE, data[6] & 0x02); |
589 | wacom_report_key(wcombo, BTN_RIGHT, data[6] & 0x04); | 636 | input_report_key(input, BTN_RIGHT, data[6] & 0x04); |
590 | wacom_report_rel(wcombo, REL_WHEEL, ((data[7] & 0x80) >> 7) | 637 | input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7) |
591 | - ((data[7] & 0x40) >> 6)); | 638 | - ((data[7] & 0x40) >> 6)); |
592 | wacom_report_key(wcombo, BTN_SIDE, data[6] & 0x08); | 639 | input_report_key(input, BTN_SIDE, data[6] & 0x08); |
593 | wacom_report_key(wcombo, BTN_EXTRA, data[6] & 0x10); | 640 | input_report_key(input, BTN_EXTRA, data[6] & 0x10); |
594 | 641 | ||
595 | wacom_report_abs(wcombo, ABS_TILT_X, | 642 | input_report_abs(input, ABS_TILT_X, |
596 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 643 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); |
597 | wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); | 644 | input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); |
598 | } else { | 645 | } else { |
599 | /* 2D mouse packet */ | 646 | /* 2D mouse packet */ |
600 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04); | 647 | input_report_key(input, BTN_LEFT, data[8] & 0x04); |
601 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08); | 648 | input_report_key(input, BTN_MIDDLE, data[8] & 0x08); |
602 | wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10); | 649 | input_report_key(input, BTN_RIGHT, data[8] & 0x10); |
603 | wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01) | 650 | input_report_rel(input, REL_WHEEL, (data[8] & 0x01) |
604 | - ((data[8] & 0x02) >> 1)); | 651 | - ((data[8] & 0x02) >> 1)); |
605 | 652 | ||
606 | /* I3 2D mouse side buttons */ | 653 | /* I3 2D mouse side buttons */ |
607 | if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { | 654 | if (features->type >= INTUOS3S && features->type <= INTUOS3L) { |
608 | wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); | 655 | input_report_key(input, BTN_SIDE, data[8] & 0x40); |
609 | wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); | 656 | input_report_key(input, BTN_EXTRA, data[8] & 0x20); |
610 | } | 657 | } |
611 | } | 658 | } |
612 | } else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L || | 659 | } else if ((features->type < INTUOS3S || features->type == INTUOS3L || |
613 | wacom->features->type == INTUOS4L) && | 660 | features->type == INTUOS4L) && |
614 | wacom->tool[idx] == BTN_TOOL_LENS) { | 661 | wacom->tool[idx] == BTN_TOOL_LENS) { |
615 | /* Lens cursor packets */ | 662 | /* Lens cursor packets */ |
616 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); | 663 | input_report_key(input, BTN_LEFT, data[8] & 0x01); |
617 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); | 664 | input_report_key(input, BTN_MIDDLE, data[8] & 0x02); |
618 | wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04); | 665 | input_report_key(input, BTN_RIGHT, data[8] & 0x04); |
619 | wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x10); | 666 | input_report_key(input, BTN_SIDE, data[8] & 0x10); |
620 | wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x08); | 667 | input_report_key(input, BTN_EXTRA, data[8] & 0x08); |
621 | } | 668 | } |
622 | } | 669 | } |
623 | 670 | ||
624 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */ | 671 | input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */ |
625 | wacom_report_key(wcombo, wacom->tool[idx], 1); | 672 | input_report_key(input, wacom->tool[idx], 1); |
626 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 673 | input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); |
627 | return 1; | 674 | return 1; |
628 | } | 675 | } |
629 | 676 | ||
630 | 677 | ||
631 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) | 678 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, char *data, int idx) |
632 | { | 679 | { |
633 | wacom_report_abs(wcombo, ABS_X, | 680 | struct input_dev *input = wacom->input; |
634 | (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); | 681 | int finger = idx + 1; |
635 | wacom_report_abs(wcombo, ABS_Y, | 682 | int x = le16_to_cpup((__le16 *)&data[finger * 2]) & 0x7fff; |
636 | (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); | 683 | int y = le16_to_cpup((__le16 *)&data[4 + finger * 2]) & 0x7fff; |
637 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 684 | |
638 | wacom_report_key(wcombo, wacom->tool[idx], 1); | 685 | /* |
639 | if (idx) | 686 | * Work around input core suppressing "duplicate" events since |
640 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 687 | * we are abusing ABS_X/ABS_Y to transmit multi-finger data. |
641 | else | 688 | * This should go away once we switch to true multitouch |
642 | wacom_report_key(wcombo, BTN_TOUCH, 1); | 689 | * protocol. |
690 | */ | ||
691 | if (wacom->last_finger != finger) { | ||
692 | if (x == input_abs_get_val(input, ABS_X)) | ||
693 | x++; | ||
694 | |||
695 | if (y == input_abs_get_val(input, ABS_Y)) | ||
696 | y++; | ||
697 | } | ||
698 | |||
699 | input_report_abs(input, ABS_X, x); | ||
700 | input_report_abs(input, ABS_Y, y); | ||
701 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
702 | input_report_key(input, wacom->tool[finger], 1); | ||
703 | if (!idx) | ||
704 | input_report_key(input, BTN_TOUCH, 1); | ||
705 | input_event(input, EV_MSC, MSC_SERIAL, finger); | ||
706 | input_sync(input); | ||
707 | |||
708 | wacom->last_finger = finger; | ||
643 | } | 709 | } |
644 | 710 | ||
645 | static void wacom_tpc_touch_out(struct wacom_wac *wacom, void *wcombo, int idx) | 711 | static void wacom_tpc_touch_out(struct wacom_wac *wacom, int idx) |
646 | { | 712 | { |
647 | wacom_report_abs(wcombo, ABS_X, 0); | 713 | struct input_dev *input = wacom->input; |
648 | wacom_report_abs(wcombo, ABS_Y, 0); | 714 | int finger = idx + 1; |
649 | wacom_report_abs(wcombo, ABS_MISC, 0); | 715 | |
650 | wacom_report_key(wcombo, wacom->tool[idx], 0); | 716 | input_report_abs(input, ABS_X, 0); |
651 | if (idx) | 717 | input_report_abs(input, ABS_Y, 0); |
652 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 718 | input_report_abs(input, ABS_MISC, 0); |
653 | else | 719 | input_report_key(input, wacom->tool[finger], 0); |
654 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 720 | if (!idx) |
655 | return; | 721 | input_report_key(input, BTN_TOUCH, 0); |
722 | input_event(input, EV_MSC, MSC_SERIAL, finger); | ||
723 | input_sync(input); | ||
656 | } | 724 | } |
657 | 725 | ||
658 | static void wacom_tpc_touch_in(struct wacom_wac *wacom, void *wcombo) | 726 | static void wacom_tpc_touch_in(struct wacom_wac *wacom, size_t len) |
659 | { | 727 | { |
660 | char *data = wacom->data; | 728 | char *data = wacom->data; |
661 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; | 729 | struct input_dev *input = wacom->input; |
662 | static int firstFinger = 0; | ||
663 | static int secondFinger = 0; | ||
664 | 730 | ||
665 | wacom->tool[0] = BTN_TOOL_DOUBLETAP; | 731 | wacom->tool[1] = BTN_TOOL_DOUBLETAP; |
666 | wacom->id[0] = TOUCH_DEVICE_ID; | 732 | wacom->id[0] = TOUCH_DEVICE_ID; |
667 | wacom->tool[1] = BTN_TOOL_TRIPLETAP; | 733 | wacom->tool[2] = BTN_TOOL_TRIPLETAP; |
734 | |||
735 | if (len != WACOM_PKGLEN_TPC1FG) { | ||
668 | 736 | ||
669 | if (urb->actual_length != WACOM_PKGLEN_TPC1FG) { | ||
670 | switch (data[0]) { | 737 | switch (data[0]) { |
671 | case WACOM_REPORT_TPC1FG: | ||
672 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | ||
673 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | ||
674 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | ||
675 | wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); | ||
676 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
677 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
678 | break; | ||
679 | case WACOM_REPORT_TPC2FG: | ||
680 | /* keep this byte to send proper out-prox event */ | ||
681 | wacom->id[1] = data[1] & 0x03; | ||
682 | |||
683 | if (data[1] & 0x01) { | ||
684 | wacom_tpc_finger_in(wacom, wcombo, data, 0); | ||
685 | firstFinger = 1; | ||
686 | } else if (firstFinger) { | ||
687 | wacom_tpc_touch_out(wacom, wcombo, 0); | ||
688 | } | ||
689 | 738 | ||
690 | if (data[1] & 0x02) { | 739 | case WACOM_REPORT_TPC1FG: |
691 | /* sync first finger data */ | 740 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); |
692 | if (firstFinger) | 741 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); |
693 | wacom_input_sync(wcombo); | 742 | input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6])); |
743 | input_report_key(input, BTN_TOUCH, le16_to_cpup((__le16 *)&data[6])); | ||
744 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
745 | input_report_key(input, wacom->tool[1], 1); | ||
746 | input_sync(input); | ||
747 | break; | ||
694 | 748 | ||
695 | wacom_tpc_finger_in(wacom, wcombo, data, 1); | 749 | case WACOM_REPORT_TPC2FG: |
696 | secondFinger = 1; | 750 | if (data[1] & 0x01) |
697 | } else if (secondFinger) { | 751 | wacom_tpc_finger_in(wacom, data, 0); |
698 | /* sync first finger data */ | 752 | else if (wacom->id[1] & 0x01) |
699 | if (firstFinger) | 753 | wacom_tpc_touch_out(wacom, 0); |
700 | wacom_input_sync(wcombo); | ||
701 | 754 | ||
702 | wacom_tpc_touch_out(wacom, wcombo, 1); | 755 | if (data[1] & 0x02) |
703 | secondFinger = 0; | 756 | wacom_tpc_finger_in(wacom, data, 1); |
704 | } | 757 | else if (wacom->id[1] & 0x02) |
705 | if (!(data[1] & 0x01)) | 758 | wacom_tpc_touch_out(wacom, 1); |
706 | firstFinger = 0; | 759 | break; |
707 | break; | ||
708 | } | 760 | } |
709 | } else { | 761 | } else { |
710 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | 762 | input_report_abs(input, ABS_X, get_unaligned_le16(&data[1])); |
711 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | 763 | input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3])); |
712 | wacom_report_key(wcombo, BTN_TOUCH, 1); | 764 | input_report_key(input, BTN_TOUCH, 1); |
713 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 765 | input_report_abs(input, ABS_MISC, wacom->id[1]); |
714 | wacom_report_key(wcombo, wacom->tool[0], 1); | 766 | input_report_key(input, wacom->tool[1], 1); |
767 | input_sync(input); | ||
715 | } | 768 | } |
716 | return; | ||
717 | } | 769 | } |
718 | 770 | ||
719 | static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | 771 | static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) |
720 | { | 772 | { |
773 | struct wacom_features *features = &wacom->features; | ||
721 | char *data = wacom->data; | 774 | char *data = wacom->data; |
722 | int prox = 0, pressure, idx = -1; | 775 | struct input_dev *input = wacom->input; |
723 | static int stylusInProx, touchInProx = 1, touchOut; | 776 | int prox = 0, pressure; |
724 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; | 777 | int retval = 0; |
725 | 778 | ||
726 | dbg("wacom_tpc_irq: received report #%d", data[0]); | 779 | dbg("wacom_tpc_irq: received report #%d", data[0]); |
727 | 780 | ||
728 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG || /* single touch */ | 781 | if (len == WACOM_PKGLEN_TPC1FG || /* single touch */ |
729 | data[0] == WACOM_REPORT_TPC1FG || /* single touch */ | 782 | data[0] == WACOM_REPORT_TPC1FG || /* single touch */ |
730 | data[0] == WACOM_REPORT_TPC2FG) { /* 2FG touch */ | 783 | data[0] == WACOM_REPORT_TPC2FG) { /* 2FG touch */ |
731 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG) { /* with touch */ | 784 | |
785 | if (wacom->shared->stylus_in_proximity) { | ||
786 | if (wacom->id[1] & 0x01) | ||
787 | wacom_tpc_touch_out(wacom, 0); | ||
788 | |||
789 | if (wacom->id[1] & 0x02) | ||
790 | wacom_tpc_touch_out(wacom, 1); | ||
791 | |||
792 | wacom->id[1] = 0; | ||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | if (len == WACOM_PKGLEN_TPC1FG) { /* with touch */ | ||
732 | prox = data[0] & 0x01; | 797 | prox = data[0] & 0x01; |
733 | } else { /* with capacity */ | 798 | } else { /* with capacity */ |
734 | if (data[0] == WACOM_REPORT_TPC1FG) | 799 | if (data[0] == WACOM_REPORT_TPC1FG) |
@@ -739,317 +804,715 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
739 | prox = data[1] & 0x03; | 804 | prox = data[1] & 0x03; |
740 | } | 805 | } |
741 | 806 | ||
742 | if (!stylusInProx) { /* stylus not in prox */ | 807 | if (prox) { |
743 | if (prox) { | 808 | if (!wacom->id[1]) |
744 | if (touchInProx) { | 809 | wacom->last_finger = 1; |
745 | wacom_tpc_touch_in(wacom, wcombo); | 810 | wacom_tpc_touch_in(wacom, len); |
746 | touchOut = 1; | 811 | } else { |
747 | return 1; | 812 | if (data[0] == WACOM_REPORT_TPC2FG) { |
748 | } | ||
749 | } else { | ||
750 | /* 2FGT out-prox */ | 813 | /* 2FGT out-prox */ |
751 | if (data[0] == WACOM_REPORT_TPC2FG) { | 814 | if (wacom->id[1] & 0x01) |
752 | idx = (wacom->id[1] & 0x01) - 1; | 815 | wacom_tpc_touch_out(wacom, 0); |
753 | if (idx == 0) { | 816 | |
754 | wacom_tpc_touch_out(wacom, wcombo, idx); | 817 | if (wacom->id[1] & 0x02) |
755 | /* sync first finger event */ | 818 | wacom_tpc_touch_out(wacom, 1); |
756 | if (wacom->id[1] & 0x02) | 819 | } else |
757 | wacom_input_sync(wcombo); | 820 | /* one finger touch */ |
758 | } | 821 | wacom_tpc_touch_out(wacom, 0); |
759 | idx = (wacom->id[1] & 0x02) - 1; | 822 | |
760 | if (idx == 1) | 823 | wacom->id[0] = 0; |
761 | wacom_tpc_touch_out(wacom, wcombo, idx); | ||
762 | } else /* one finger touch */ | ||
763 | wacom_tpc_touch_out(wacom, wcombo, 0); | ||
764 | touchOut = 0; | ||
765 | touchInProx = 1; | ||
766 | return 1; | ||
767 | } | ||
768 | } else if (touchOut || !prox) { /* force touch out-prox */ | ||
769 | wacom_tpc_touch_out(wacom, wcombo, 0); | ||
770 | touchOut = 0; | ||
771 | touchInProx = 1; | ||
772 | return 1; | ||
773 | } | 824 | } |
825 | /* keep prox bit to send proper out-prox event */ | ||
826 | wacom->id[1] = prox; | ||
774 | } else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */ | 827 | } else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */ |
775 | prox = data[1] & 0x20; | 828 | prox = data[1] & 0x20; |
776 | 829 | ||
777 | touchInProx = 0; | 830 | if (!wacom->shared->stylus_in_proximity) { /* first in prox */ |
831 | /* Going into proximity select tool */ | ||
832 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
833 | if (wacom->tool[0] == BTN_TOOL_PEN) | ||
834 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
835 | else | ||
836 | wacom->id[0] = ERASER_DEVICE_ID; | ||
778 | 837 | ||
779 | if (prox) { /* in prox */ | 838 | wacom->shared->stylus_in_proximity = true; |
780 | if (!wacom->id[0]) { | 839 | } |
781 | /* Going into proximity select tool */ | 840 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); |
782 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 841 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); |
783 | if (wacom->tool[0] == BTN_TOOL_PEN) | 842 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); |
784 | wacom->id[0] = STYLUS_DEVICE_ID; | 843 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); |
785 | else | 844 | pressure = ((data[7] & 0x01) << 8) | data[6]; |
786 | wacom->id[0] = ERASER_DEVICE_ID; | 845 | if (pressure < 0) |
846 | pressure = features->pressure_max + pressure + 1; | ||
847 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
848 | input_report_key(input, BTN_TOUCH, data[1] & 0x05); | ||
849 | if (!prox) { /* out-prox */ | ||
850 | wacom->id[0] = 0; | ||
851 | wacom->shared->stylus_in_proximity = false; | ||
852 | } | ||
853 | input_report_key(input, wacom->tool[0], prox); | ||
854 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
855 | retval = 1; | ||
856 | } | ||
857 | return retval; | ||
858 | } | ||
859 | |||
860 | static int wacom_bpt_touch(struct wacom_wac *wacom) | ||
861 | { | ||
862 | struct wacom_features *features = &wacom->features; | ||
863 | struct input_dev *input = wacom->input; | ||
864 | unsigned char *data = wacom->data; | ||
865 | int sp = 0, sx = 0, sy = 0, count = 0; | ||
866 | int i; | ||
867 | |||
868 | for (i = 0; i < 2; i++) { | ||
869 | int p = data[9 * i + 2]; | ||
870 | input_mt_slot(input, i); | ||
871 | /* | ||
872 | * Touch events need to be disabled while stylus is | ||
873 | * in proximity because user's hand is resting on touchpad | ||
874 | * and sending unwanted events. User expects tablet buttons | ||
875 | * to continue working though. | ||
876 | */ | ||
877 | if (p && !wacom->shared->stylus_in_proximity) { | ||
878 | int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; | ||
879 | int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; | ||
880 | if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { | ||
881 | x <<= 5; | ||
882 | y <<= 5; | ||
787 | } | 883 | } |
788 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 884 | input_report_abs(input, ABS_MT_PRESSURE, p); |
789 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); | 885 | input_report_abs(input, ABS_MT_POSITION_X, x); |
790 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | 886 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
791 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | 887 | if (wacom->id[i] < 0) |
792 | pressure = ((data[7] & 0x01) << 8) | data[6]; | 888 | wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID; |
793 | if (pressure < 0) | 889 | if (!count++) |
794 | pressure = wacom->features->pressure_max + pressure + 1; | 890 | sp = p, sx = x, sy = y; |
795 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | ||
796 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); | ||
797 | } else { | 891 | } else { |
798 | wacom_report_abs(wcombo, ABS_X, 0); | 892 | wacom->id[i] = -1; |
799 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
800 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | ||
801 | wacom_report_key(wcombo, BTN_STYLUS, 0); | ||
802 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | ||
803 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
804 | wacom->id[0] = 0; | ||
805 | /* pen is out so touch can be enabled now */ | ||
806 | touchInProx = 1; | ||
807 | } | 893 | } |
808 | wacom_report_key(wcombo, wacom->tool[0], prox); | 894 | input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]); |
809 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
810 | stylusInProx = prox; | ||
811 | return 1; | ||
812 | } | 895 | } |
896 | |||
897 | input_report_key(input, BTN_TOUCH, count > 0); | ||
898 | input_report_key(input, BTN_TOOL_FINGER, count == 1); | ||
899 | input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2); | ||
900 | |||
901 | input_report_abs(input, ABS_PRESSURE, sp); | ||
902 | input_report_abs(input, ABS_X, sx); | ||
903 | input_report_abs(input, ABS_Y, sy); | ||
904 | |||
905 | input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); | ||
906 | input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); | ||
907 | input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0); | ||
908 | input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0); | ||
909 | |||
910 | input_sync(input); | ||
911 | |||
813 | return 0; | 912 | return 0; |
814 | } | 913 | } |
815 | 914 | ||
816 | int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | 915 | static int wacom_bpt_pen(struct wacom_wac *wacom) |
817 | { | 916 | { |
818 | switch (wacom_wac->features->type) { | 917 | struct input_dev *input = wacom->input; |
819 | case PENPARTNER: | 918 | unsigned char *data = wacom->data; |
820 | return wacom_penpartner_irq(wacom_wac, wcombo); | 919 | int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; |
821 | 920 | ||
822 | case PL: | 921 | /* |
823 | return wacom_pl_irq(wacom_wac, wcombo); | 922 | * Similar to Graphire protocol, data[1] & 0x20 is proximity and |
824 | 923 | * data[1] & 0x18 is tool ID. 0x30 is safety check to ignore | |
825 | case WACOM_G4: | 924 | * 2 unused tool ID's. |
826 | case GRAPHIRE: | 925 | */ |
827 | case WACOM_MO: | 926 | prox = (data[1] & 0x30) == 0x30; |
828 | return wacom_graphire_irq(wacom_wac, wcombo); | 927 | |
829 | 928 | /* | |
830 | case PTU: | 929 | * All reports shared between PEN and RUBBER tool must be |
831 | return wacom_ptu_irq(wacom_wac, wcombo); | 930 | * forced to a known starting value (zero) when transitioning to |
832 | 931 | * out-of-prox. | |
833 | case INTUOS: | 932 | * |
834 | case INTUOS3S: | 933 | * If not reset then, to userspace, it will look like lost events |
835 | case INTUOS3: | 934 | * if new tool comes in-prox with same values as previous tool sent. |
836 | case INTUOS3L: | 935 | * |
837 | case INTUOS4S: | 936 | * Hardware does report zero in most out-of-prox cases but not all. |
838 | case INTUOS4: | 937 | */ |
839 | case INTUOS4L: | 938 | if (prox) { |
840 | case CINTIQ: | 939 | if (!wacom->shared->stylus_in_proximity) { |
841 | case WACOM_BEE: | 940 | if (data[1] & 0x08) { |
842 | return wacom_intuos_irq(wacom_wac, wcombo); | 941 | wacom->tool[0] = BTN_TOOL_RUBBER; |
843 | 942 | wacom->id[0] = ERASER_DEVICE_ID; | |
844 | case TABLETPC: | 943 | } else { |
845 | case TABLETPC2FG: | 944 | wacom->tool[0] = BTN_TOOL_PEN; |
846 | return wacom_tpc_irq(wacom_wac, wcombo); | 945 | wacom->id[0] = STYLUS_DEVICE_ID; |
847 | 946 | } | |
848 | default: | 947 | wacom->shared->stylus_in_proximity = true; |
849 | return 0; | 948 | } |
949 | x = le16_to_cpup((__le16 *)&data[2]); | ||
950 | y = le16_to_cpup((__le16 *)&data[4]); | ||
951 | p = le16_to_cpup((__le16 *)&data[6]); | ||
952 | d = data[8]; | ||
953 | pen = data[1] & 0x01; | ||
954 | btn1 = data[1] & 0x02; | ||
955 | btn2 = data[1] & 0x04; | ||
850 | } | 956 | } |
957 | |||
958 | input_report_key(input, BTN_TOUCH, pen); | ||
959 | input_report_key(input, BTN_STYLUS, btn1); | ||
960 | input_report_key(input, BTN_STYLUS2, btn2); | ||
961 | |||
962 | input_report_abs(input, ABS_X, x); | ||
963 | input_report_abs(input, ABS_Y, y); | ||
964 | input_report_abs(input, ABS_PRESSURE, p); | ||
965 | input_report_abs(input, ABS_DISTANCE, d); | ||
966 | |||
967 | if (!prox) { | ||
968 | wacom->id[0] = 0; | ||
969 | wacom->shared->stylus_in_proximity = false; | ||
970 | } | ||
971 | |||
972 | input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */ | ||
973 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ | ||
974 | |||
975 | return 1; | ||
976 | } | ||
977 | |||
978 | static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) | ||
979 | { | ||
980 | if (len == WACOM_PKGLEN_BBTOUCH) | ||
981 | return wacom_bpt_touch(wacom); | ||
982 | else if (len == WACOM_PKGLEN_BBFUN) | ||
983 | return wacom_bpt_pen(wacom); | ||
984 | |||
851 | return 0; | 985 | return 0; |
852 | } | 986 | } |
853 | 987 | ||
854 | void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 988 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) |
855 | { | 989 | { |
856 | switch (wacom_wac->features->type) { | 990 | bool sync; |
857 | case WACOM_MO: | 991 | |
858 | input_dev_mo(input_dev, wacom_wac); | 992 | switch (wacom_wac->features.type) { |
859 | case WACOM_G4: | 993 | case PENPARTNER: |
860 | input_dev_g4(input_dev, wacom_wac); | 994 | sync = wacom_penpartner_irq(wacom_wac); |
861 | /* fall through */ | 995 | break; |
862 | case GRAPHIRE: | 996 | |
863 | input_dev_g(input_dev, wacom_wac); | 997 | case PL: |
864 | break; | 998 | sync = wacom_pl_irq(wacom_wac); |
865 | case WACOM_BEE: | 999 | break; |
866 | input_dev_bee(input_dev, wacom_wac); | 1000 | |
867 | case INTUOS3: | 1001 | case WACOM_G4: |
868 | case INTUOS3L: | 1002 | case GRAPHIRE: |
869 | case CINTIQ: | 1003 | case WACOM_MO: |
870 | input_dev_i3(input_dev, wacom_wac); | 1004 | sync = wacom_graphire_irq(wacom_wac); |
871 | /* fall through */ | 1005 | break; |
872 | case INTUOS3S: | 1006 | |
873 | input_dev_i3s(input_dev, wacom_wac); | 1007 | case PTU: |
874 | /* fall through */ | 1008 | sync = wacom_ptu_irq(wacom_wac); |
875 | case INTUOS: | 1009 | break; |
876 | input_dev_i(input_dev, wacom_wac); | 1010 | |
877 | break; | 1011 | case DTU: |
878 | case INTUOS4: | 1012 | sync = wacom_dtu_irq(wacom_wac); |
879 | case INTUOS4L: | 1013 | break; |
880 | input_dev_i4(input_dev, wacom_wac); | 1014 | |
881 | /* fall through */ | 1015 | case INTUOS: |
882 | case INTUOS4S: | 1016 | case INTUOS3S: |
883 | input_dev_i4s(input_dev, wacom_wac); | 1017 | case INTUOS3: |
884 | input_dev_i(input_dev, wacom_wac); | 1018 | case INTUOS3L: |
885 | break; | 1019 | case INTUOS4S: |
886 | case TABLETPC2FG: | 1020 | case INTUOS4: |
887 | input_dev_tpc2fg(input_dev, wacom_wac); | 1021 | case INTUOS4L: |
888 | /* fall through */ | 1022 | case CINTIQ: |
889 | case TABLETPC: | 1023 | case WACOM_BEE: |
890 | input_dev_tpc(input_dev, wacom_wac); | 1024 | case WACOM_21UX2: |
891 | if (wacom_wac->features->device_type != BTN_TOOL_PEN) | 1025 | sync = wacom_intuos_irq(wacom_wac); |
892 | break; /* no need to process stylus stuff */ | 1026 | break; |
893 | 1027 | ||
894 | /* fall through */ | 1028 | case TABLETPC: |
895 | case PL: | 1029 | case TABLETPC2FG: |
896 | case PTU: | 1030 | sync = wacom_tpc_irq(wacom_wac, len); |
897 | input_dev_pl(input_dev, wacom_wac); | 1031 | break; |
898 | /* fall through */ | 1032 | |
899 | case PENPARTNER: | 1033 | case BAMBOO_PT: |
900 | input_dev_pt(input_dev, wacom_wac); | 1034 | sync = wacom_bpt_irq(wacom_wac, len); |
901 | break; | 1035 | break; |
1036 | |||
1037 | default: | ||
1038 | sync = false; | ||
1039 | break; | ||
902 | } | 1040 | } |
903 | return; | 1041 | |
1042 | if (sync) | ||
1043 | input_sync(wacom_wac->input); | ||
904 | } | 1044 | } |
905 | 1045 | ||
906 | static struct wacom_features wacom_features[] = { | 1046 | static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) |
907 | { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }, | 1047 | { |
908 | { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }, | 1048 | struct input_dev *input_dev = wacom_wac->input; |
909 | { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }, | 1049 | |
910 | { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }, | 1050 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); |
911 | { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }, | 1051 | |
912 | { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }, | 1052 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
913 | { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }, | 1053 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); |
914 | { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }, | 1054 | __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); |
915 | { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }, | 1055 | __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); |
916 | { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }, | 1056 | __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); |
917 | { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }, | 1057 | __set_bit(BTN_STYLUS, input_dev->keybit); |
918 | { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }, | 1058 | __set_bit(BTN_STYLUS2, input_dev->keybit); |
919 | { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }, | 1059 | |
920 | { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }, | 1060 | input_set_abs_params(input_dev, ABS_DISTANCE, |
921 | { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }, | 1061 | 0, wacom_wac->features.distance_max, 0, 0); |
922 | { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }, | 1062 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); |
923 | { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }, | 1063 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); |
924 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }, | 1064 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); |
925 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }, | 1065 | } |
926 | { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, | ||
927 | { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }, | ||
928 | { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }, | ||
929 | { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }, | ||
930 | { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }, | ||
931 | { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }, | ||
932 | { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }, | ||
933 | { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }, | ||
934 | { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }, | ||
935 | { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }, | ||
936 | { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }, | ||
937 | { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }, | ||
938 | { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }, | ||
939 | { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }, | ||
940 | { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }, | ||
941 | { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }, | ||
942 | { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }, | ||
943 | { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }, | ||
944 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, | ||
945 | { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }, | ||
946 | { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }, | ||
947 | { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }, | ||
948 | { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }, | ||
949 | { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }, | ||
950 | { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }, | ||
951 | { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }, | ||
952 | { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }, | ||
953 | { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }, | ||
954 | { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }, | ||
955 | { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }, | ||
956 | { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }, | ||
957 | { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }, | ||
958 | { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }, | ||
959 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }, | ||
960 | { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }, | ||
961 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }, | ||
962 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }, | ||
963 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, | ||
964 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, | ||
965 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, | ||
966 | { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }, | ||
967 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }, | ||
968 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }, | ||
969 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, | ||
970 | { } | ||
971 | }; | ||
972 | 1066 | ||
973 | static struct usb_device_id wacom_ids[] = { | 1067 | static void wacom_setup_intuos(struct wacom_wac *wacom_wac) |
974 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, | 1068 | { |
975 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, | 1069 | struct input_dev *input_dev = wacom_wac->input; |
976 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, | 1070 | |
977 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, | 1071 | input_set_capability(input_dev, EV_REL, REL_WHEEL); |
978 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, | 1072 | |
979 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, | 1073 | wacom_setup_cintiq(wacom_wac); |
980 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, | 1074 | |
981 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, | 1075 | __set_bit(BTN_LEFT, input_dev->keybit); |
982 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, | 1076 | __set_bit(BTN_RIGHT, input_dev->keybit); |
983 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, | 1077 | __set_bit(BTN_MIDDLE, input_dev->keybit); |
984 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x19) }, | 1078 | __set_bit(BTN_SIDE, input_dev->keybit); |
985 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, | 1079 | __set_bit(BTN_EXTRA, input_dev->keybit); |
986 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, | 1080 | __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); |
987 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, | 1081 | __set_bit(BTN_TOOL_LENS, input_dev->keybit); |
988 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, | ||
989 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, | ||
990 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, | ||
991 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) }, | ||
992 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, | ||
993 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, | ||
994 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, | ||
995 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, | ||
996 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, | ||
997 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, | ||
998 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, | ||
999 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, | ||
1000 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, | ||
1001 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, | ||
1002 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, | ||
1003 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, | ||
1004 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, | ||
1005 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, | ||
1006 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, | ||
1007 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, | ||
1008 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) }, | ||
1009 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, | ||
1010 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, | ||
1011 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, | ||
1012 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, | ||
1013 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, | ||
1014 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, | ||
1015 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, | ||
1016 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, | ||
1017 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, | ||
1018 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, | ||
1019 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, | ||
1020 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, | ||
1021 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, | ||
1022 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) }, | ||
1023 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) }, | ||
1024 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) }, | ||
1025 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) }, | ||
1026 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, | ||
1027 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, | ||
1028 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, | ||
1029 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) }, | ||
1030 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, | ||
1031 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, | ||
1032 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, | ||
1033 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9F) }, | ||
1034 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE2) }, | ||
1035 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE3) }, | ||
1036 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | ||
1037 | { } | ||
1038 | }; | ||
1039 | 1082 | ||
1040 | const struct usb_device_id *get_device_table(void) | 1083 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); |
1084 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); | ||
1085 | } | ||
1086 | |||
1087 | void wacom_setup_device_quirks(struct wacom_features *features) | ||
1041 | { | 1088 | { |
1042 | const struct usb_device_id *id_table = wacom_ids; | ||
1043 | 1089 | ||
1044 | return id_table; | 1090 | /* touch device found but size is not defined. use default */ |
1091 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | ||
1092 | features->x_max = 1023; | ||
1093 | features->y_max = 1023; | ||
1094 | } | ||
1095 | |||
1096 | /* these device have multiple inputs */ | ||
1097 | if (features->type == TABLETPC || features->type == TABLETPC2FG || | ||
1098 | features->type == BAMBOO_PT) | ||
1099 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; | ||
1100 | |||
1101 | /* quirks for bamboo touch */ | ||
1102 | if (features->type == BAMBOO_PT && | ||
1103 | features->device_type == BTN_TOOL_TRIPLETAP) { | ||
1104 | features->x_max <<= 5; | ||
1105 | features->y_max <<= 5; | ||
1106 | features->x_fuzz <<= 5; | ||
1107 | features->y_fuzz <<= 5; | ||
1108 | features->pressure_max = 256; | ||
1109 | features->pressure_fuzz = 16; | ||
1110 | features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES; | ||
1111 | } | ||
1045 | } | 1112 | } |
1046 | 1113 | ||
1047 | struct wacom_features * get_wacom_feature(const struct usb_device_id *id) | 1114 | void wacom_setup_input_capabilities(struct input_dev *input_dev, |
1115 | struct wacom_wac *wacom_wac) | ||
1048 | { | 1116 | { |
1049 | int index = id - wacom_ids; | 1117 | struct wacom_features *features = &wacom_wac->features; |
1050 | struct wacom_features *wf = &wacom_features[index]; | 1118 | int i; |
1119 | |||
1120 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1121 | |||
1122 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1123 | |||
1124 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, | ||
1125 | features->x_fuzz, 0); | ||
1126 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, | ||
1127 | features->y_fuzz, 0); | ||
1128 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, | ||
1129 | features->pressure_fuzz, 0); | ||
1130 | |||
1131 | __set_bit(ABS_MISC, input_dev->absbit); | ||
1132 | |||
1133 | switch (wacom_wac->features.type) { | ||
1134 | case WACOM_MO: | ||
1135 | __set_bit(BTN_1, input_dev->keybit); | ||
1136 | __set_bit(BTN_5, input_dev->keybit); | ||
1137 | |||
1138 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | ||
1139 | /* fall through */ | ||
1140 | |||
1141 | case WACOM_G4: | ||
1142 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | ||
1143 | |||
1144 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1145 | __set_bit(BTN_0, input_dev->keybit); | ||
1146 | __set_bit(BTN_4, input_dev->keybit); | ||
1147 | /* fall through */ | ||
1148 | |||
1149 | case GRAPHIRE: | ||
1150 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | ||
1151 | |||
1152 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
1153 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
1154 | __set_bit(BTN_MIDDLE, input_dev->keybit); | ||
1155 | |||
1156 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | ||
1157 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | ||
1158 | __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); | ||
1159 | __set_bit(BTN_STYLUS, input_dev->keybit); | ||
1160 | __set_bit(BTN_STYLUS2, input_dev->keybit); | ||
1161 | break; | ||
1162 | |||
1163 | case WACOM_21UX2: | ||
1164 | __set_bit(BTN_A, input_dev->keybit); | ||
1165 | __set_bit(BTN_B, input_dev->keybit); | ||
1166 | __set_bit(BTN_C, input_dev->keybit); | ||
1167 | __set_bit(BTN_X, input_dev->keybit); | ||
1168 | __set_bit(BTN_Y, input_dev->keybit); | ||
1169 | __set_bit(BTN_Z, input_dev->keybit); | ||
1170 | __set_bit(BTN_BASE, input_dev->keybit); | ||
1171 | __set_bit(BTN_BASE2, input_dev->keybit); | ||
1172 | /* fall through */ | ||
1173 | |||
1174 | case WACOM_BEE: | ||
1175 | __set_bit(BTN_8, input_dev->keybit); | ||
1176 | __set_bit(BTN_9, input_dev->keybit); | ||
1177 | /* fall through */ | ||
1178 | |||
1179 | case CINTIQ: | ||
1180 | for (i = 0; i < 8; i++) | ||
1181 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
1182 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1183 | |||
1184 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | ||
1185 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | ||
1186 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
1187 | wacom_setup_cintiq(wacom_wac); | ||
1188 | break; | ||
1189 | |||
1190 | case INTUOS3: | ||
1191 | case INTUOS3L: | ||
1192 | __set_bit(BTN_4, input_dev->keybit); | ||
1193 | __set_bit(BTN_5, input_dev->keybit); | ||
1194 | __set_bit(BTN_6, input_dev->keybit); | ||
1195 | __set_bit(BTN_7, input_dev->keybit); | ||
1196 | |||
1197 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | ||
1198 | /* fall through */ | ||
1199 | |||
1200 | case INTUOS3S: | ||
1201 | __set_bit(BTN_0, input_dev->keybit); | ||
1202 | __set_bit(BTN_1, input_dev->keybit); | ||
1203 | __set_bit(BTN_2, input_dev->keybit); | ||
1204 | __set_bit(BTN_3, input_dev->keybit); | ||
1205 | |||
1206 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1207 | |||
1208 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | ||
1209 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
1210 | /* fall through */ | ||
1211 | |||
1212 | case INTUOS: | ||
1213 | wacom_setup_intuos(wacom_wac); | ||
1214 | break; | ||
1215 | |||
1216 | case INTUOS4: | ||
1217 | case INTUOS4L: | ||
1218 | __set_bit(BTN_7, input_dev->keybit); | ||
1219 | __set_bit(BTN_8, input_dev->keybit); | ||
1220 | /* fall through */ | ||
1221 | |||
1222 | case INTUOS4S: | ||
1223 | for (i = 0; i < 7; i++) | ||
1224 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
1225 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1226 | |||
1227 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
1228 | wacom_setup_intuos(wacom_wac); | ||
1229 | break; | ||
1051 | 1230 | ||
1052 | return wf; | 1231 | case TABLETPC2FG: |
1232 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | ||
1233 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | ||
1234 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | ||
1235 | } | ||
1236 | /* fall through */ | ||
1237 | |||
1238 | case TABLETPC: | ||
1239 | if (features->device_type == BTN_TOOL_DOUBLETAP || | ||
1240 | features->device_type == BTN_TOOL_TRIPLETAP) { | ||
1241 | input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0); | ||
1242 | input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0); | ||
1243 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1244 | } | ||
1245 | |||
1246 | if (features->device_type != BTN_TOOL_PEN) | ||
1247 | break; /* no need to process stylus stuff */ | ||
1248 | |||
1249 | /* fall through */ | ||
1250 | |||
1251 | case PL: | ||
1252 | case PTU: | ||
1253 | case DTU: | ||
1254 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | ||
1255 | __set_bit(BTN_STYLUS, input_dev->keybit); | ||
1256 | __set_bit(BTN_STYLUS2, input_dev->keybit); | ||
1257 | /* fall through */ | ||
1258 | |||
1259 | case PENPARTNER: | ||
1260 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | ||
1261 | break; | ||
1262 | |||
1263 | case BAMBOO_PT: | ||
1264 | __clear_bit(ABS_MISC, input_dev->absbit); | ||
1265 | |||
1266 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | ||
1267 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
1268 | __set_bit(BTN_FORWARD, input_dev->keybit); | ||
1269 | __set_bit(BTN_BACK, input_dev->keybit); | ||
1270 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
1271 | |||
1272 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1273 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1274 | |||
1275 | input_mt_create_slots(input_dev, 2); | ||
1276 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1277 | 0, features->x_max, | ||
1278 | features->x_fuzz, 0); | ||
1279 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1280 | 0, features->y_max, | ||
1281 | features->y_fuzz, 0); | ||
1282 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | ||
1283 | 0, features->pressure_max, | ||
1284 | features->pressure_fuzz, 0); | ||
1285 | input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, | ||
1286 | MAX_TRACKING_ID, 0, 0); | ||
1287 | } else if (features->device_type == BTN_TOOL_PEN) { | ||
1288 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | ||
1289 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | ||
1290 | __set_bit(BTN_STYLUS, input_dev->keybit); | ||
1291 | __set_bit(BTN_STYLUS2, input_dev->keybit); | ||
1292 | } | ||
1293 | break; | ||
1294 | } | ||
1053 | } | 1295 | } |
1054 | 1296 | ||
1297 | static const struct wacom_features wacom_features_0x00 = | ||
1298 | { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }; | ||
1299 | static const struct wacom_features wacom_features_0x10 = | ||
1300 | { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; | ||
1301 | static const struct wacom_features wacom_features_0x11 = | ||
1302 | { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; | ||
1303 | static const struct wacom_features wacom_features_0x12 = | ||
1304 | { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }; | ||
1305 | static const struct wacom_features wacom_features_0x13 = | ||
1306 | { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }; | ||
1307 | static const struct wacom_features wacom_features_0x14 = | ||
1308 | { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; | ||
1309 | static const struct wacom_features wacom_features_0x15 = | ||
1310 | { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }; | ||
1311 | static const struct wacom_features wacom_features_0x16 = | ||
1312 | { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }; | ||
1313 | static const struct wacom_features wacom_features_0x17 = | ||
1314 | { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; | ||
1315 | static const struct wacom_features wacom_features_0x18 = | ||
1316 | { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }; | ||
1317 | static const struct wacom_features wacom_features_0x19 = | ||
1318 | { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; | ||
1319 | static const struct wacom_features wacom_features_0x60 = | ||
1320 | { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; | ||
1321 | static const struct wacom_features wacom_features_0x61 = | ||
1322 | { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }; | ||
1323 | static const struct wacom_features wacom_features_0x62 = | ||
1324 | { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; | ||
1325 | static const struct wacom_features wacom_features_0x63 = | ||
1326 | { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }; | ||
1327 | static const struct wacom_features wacom_features_0x64 = | ||
1328 | { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }; | ||
1329 | static const struct wacom_features wacom_features_0x65 = | ||
1330 | { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; | ||
1331 | static const struct wacom_features wacom_features_0x69 = | ||
1332 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; | ||
1333 | static const struct wacom_features wacom_features_0x20 = | ||
1334 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; | ||
1335 | static const struct wacom_features wacom_features_0x21 = | ||
1336 | { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | ||
1337 | static const struct wacom_features wacom_features_0x22 = | ||
1338 | { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; | ||
1339 | static const struct wacom_features wacom_features_0x23 = | ||
1340 | { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; | ||
1341 | static const struct wacom_features wacom_features_0x24 = | ||
1342 | { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; | ||
1343 | static const struct wacom_features wacom_features_0x30 = | ||
1344 | { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }; | ||
1345 | static const struct wacom_features wacom_features_0x31 = | ||
1346 | { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }; | ||
1347 | static const struct wacom_features wacom_features_0x32 = | ||
1348 | { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }; | ||
1349 | static const struct wacom_features wacom_features_0x33 = | ||
1350 | { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }; | ||
1351 | static const struct wacom_features wacom_features_0x34 = | ||
1352 | { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }; | ||
1353 | static const struct wacom_features wacom_features_0x35 = | ||
1354 | { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }; | ||
1355 | static const struct wacom_features wacom_features_0x37 = | ||
1356 | { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }; | ||
1357 | static const struct wacom_features wacom_features_0x38 = | ||
1358 | { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; | ||
1359 | static const struct wacom_features wacom_features_0x39 = | ||
1360 | { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }; | ||
1361 | static const struct wacom_features wacom_features_0xC4 = | ||
1362 | { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; | ||
1363 | static const struct wacom_features wacom_features_0xC0 = | ||
1364 | { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; | ||
1365 | static const struct wacom_features wacom_features_0xC2 = | ||
1366 | { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; | ||
1367 | static const struct wacom_features wacom_features_0x03 = | ||
1368 | { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }; | ||
1369 | static const struct wacom_features wacom_features_0x41 = | ||
1370 | { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; | ||
1371 | static const struct wacom_features wacom_features_0x42 = | ||
1372 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | ||
1373 | static const struct wacom_features wacom_features_0x43 = | ||
1374 | { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; | ||
1375 | static const struct wacom_features wacom_features_0x44 = | ||
1376 | { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; | ||
1377 | static const struct wacom_features wacom_features_0x45 = | ||
1378 | { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; | ||
1379 | static const struct wacom_features wacom_features_0xB0 = | ||
1380 | { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }; | ||
1381 | static const struct wacom_features wacom_features_0xB1 = | ||
1382 | { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }; | ||
1383 | static const struct wacom_features wacom_features_0xB2 = | ||
1384 | { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }; | ||
1385 | static const struct wacom_features wacom_features_0xB3 = | ||
1386 | { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }; | ||
1387 | static const struct wacom_features wacom_features_0xB4 = | ||
1388 | { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }; | ||
1389 | static const struct wacom_features wacom_features_0xB5 = | ||
1390 | { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }; | ||
1391 | static const struct wacom_features wacom_features_0xB7 = | ||
1392 | { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }; | ||
1393 | static const struct wacom_features wacom_features_0xB8 = | ||
1394 | { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }; | ||
1395 | static const struct wacom_features wacom_features_0xB9 = | ||
1396 | { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }; | ||
1397 | static const struct wacom_features wacom_features_0xBA = | ||
1398 | { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }; | ||
1399 | static const struct wacom_features wacom_features_0xBB = | ||
1400 | { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }; | ||
1401 | static const struct wacom_features wacom_features_0xBC = | ||
1402 | { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, 63, INTUOS4 }; | ||
1403 | static const struct wacom_features wacom_features_0x3F = | ||
1404 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }; | ||
1405 | static const struct wacom_features wacom_features_0xC5 = | ||
1406 | { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }; | ||
1407 | static const struct wacom_features wacom_features_0xC6 = | ||
1408 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; | ||
1409 | static const struct wacom_features wacom_features_0xC7 = | ||
1410 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; | ||
1411 | static const struct wacom_features wacom_features_0xCE = | ||
1412 | { "Wacom DTU2231", WACOM_PKGLEN_GRAPHIRE, 47864, 27011, 511, 0, DTU }; | ||
1413 | static const struct wacom_features wacom_features_0xF0 = | ||
1414 | { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, 0, DTU }; | ||
1415 | static const struct wacom_features wacom_features_0xCC = | ||
1416 | { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, 63, WACOM_21UX2 }; | ||
1417 | static const struct wacom_features wacom_features_0x90 = | ||
1418 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | ||
1419 | static const struct wacom_features wacom_features_0x93 = | ||
1420 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | ||
1421 | static const struct wacom_features wacom_features_0x9A = | ||
1422 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | ||
1423 | static const struct wacom_features wacom_features_0x9F = | ||
1424 | { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | ||
1425 | static const struct wacom_features wacom_features_0xE2 = | ||
1426 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; | ||
1427 | static const struct wacom_features wacom_features_0xE3 = | ||
1428 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; | ||
1429 | static const struct wacom_features wacom_features_0x47 = | ||
1430 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | ||
1431 | static struct wacom_features wacom_features_0xD0 = | ||
1432 | { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1433 | static struct wacom_features wacom_features_0xD1 = | ||
1434 | { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1435 | static struct wacom_features wacom_features_0xD2 = | ||
1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1437 | static struct wacom_features wacom_features_0xD3 = | ||
1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | ||
1439 | |||
1440 | #define USB_DEVICE_WACOM(prod) \ | ||
1441 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | ||
1442 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | ||
1443 | |||
1444 | const struct usb_device_id wacom_ids[] = { | ||
1445 | { USB_DEVICE_WACOM(0x00) }, | ||
1446 | { USB_DEVICE_WACOM(0x10) }, | ||
1447 | { USB_DEVICE_WACOM(0x11) }, | ||
1448 | { USB_DEVICE_WACOM(0x12) }, | ||
1449 | { USB_DEVICE_WACOM(0x13) }, | ||
1450 | { USB_DEVICE_WACOM(0x14) }, | ||
1451 | { USB_DEVICE_WACOM(0x15) }, | ||
1452 | { USB_DEVICE_WACOM(0x16) }, | ||
1453 | { USB_DEVICE_WACOM(0x17) }, | ||
1454 | { USB_DEVICE_WACOM(0x18) }, | ||
1455 | { USB_DEVICE_WACOM(0x19) }, | ||
1456 | { USB_DEVICE_WACOM(0x60) }, | ||
1457 | { USB_DEVICE_WACOM(0x61) }, | ||
1458 | { USB_DEVICE_WACOM(0x62) }, | ||
1459 | { USB_DEVICE_WACOM(0x63) }, | ||
1460 | { USB_DEVICE_WACOM(0x64) }, | ||
1461 | { USB_DEVICE_WACOM(0x65) }, | ||
1462 | { USB_DEVICE_WACOM(0x69) }, | ||
1463 | { USB_DEVICE_WACOM(0x20) }, | ||
1464 | { USB_DEVICE_WACOM(0x21) }, | ||
1465 | { USB_DEVICE_WACOM(0x22) }, | ||
1466 | { USB_DEVICE_WACOM(0x23) }, | ||
1467 | { USB_DEVICE_WACOM(0x24) }, | ||
1468 | { USB_DEVICE_WACOM(0x30) }, | ||
1469 | { USB_DEVICE_WACOM(0x31) }, | ||
1470 | { USB_DEVICE_WACOM(0x32) }, | ||
1471 | { USB_DEVICE_WACOM(0x33) }, | ||
1472 | { USB_DEVICE_WACOM(0x34) }, | ||
1473 | { USB_DEVICE_WACOM(0x35) }, | ||
1474 | { USB_DEVICE_WACOM(0x37) }, | ||
1475 | { USB_DEVICE_WACOM(0x38) }, | ||
1476 | { USB_DEVICE_WACOM(0x39) }, | ||
1477 | { USB_DEVICE_WACOM(0xC4) }, | ||
1478 | { USB_DEVICE_WACOM(0xC0) }, | ||
1479 | { USB_DEVICE_WACOM(0xC2) }, | ||
1480 | { USB_DEVICE_WACOM(0x03) }, | ||
1481 | { USB_DEVICE_WACOM(0x41) }, | ||
1482 | { USB_DEVICE_WACOM(0x42) }, | ||
1483 | { USB_DEVICE_WACOM(0x43) }, | ||
1484 | { USB_DEVICE_WACOM(0x44) }, | ||
1485 | { USB_DEVICE_WACOM(0x45) }, | ||
1486 | { USB_DEVICE_WACOM(0xB0) }, | ||
1487 | { USB_DEVICE_WACOM(0xB1) }, | ||
1488 | { USB_DEVICE_WACOM(0xB2) }, | ||
1489 | { USB_DEVICE_WACOM(0xB3) }, | ||
1490 | { USB_DEVICE_WACOM(0xB4) }, | ||
1491 | { USB_DEVICE_WACOM(0xB5) }, | ||
1492 | { USB_DEVICE_WACOM(0xB7) }, | ||
1493 | { USB_DEVICE_WACOM(0xB8) }, | ||
1494 | { USB_DEVICE_WACOM(0xB9) }, | ||
1495 | { USB_DEVICE_WACOM(0xBA) }, | ||
1496 | { USB_DEVICE_WACOM(0xBB) }, | ||
1497 | { USB_DEVICE_WACOM(0xBC) }, | ||
1498 | { USB_DEVICE_WACOM(0x3F) }, | ||
1499 | { USB_DEVICE_WACOM(0xC5) }, | ||
1500 | { USB_DEVICE_WACOM(0xC6) }, | ||
1501 | { USB_DEVICE_WACOM(0xC7) }, | ||
1502 | { USB_DEVICE_WACOM(0xCE) }, | ||
1503 | { USB_DEVICE_WACOM(0xD0) }, | ||
1504 | { USB_DEVICE_WACOM(0xD1) }, | ||
1505 | { USB_DEVICE_WACOM(0xD2) }, | ||
1506 | { USB_DEVICE_WACOM(0xD3) }, | ||
1507 | { USB_DEVICE_WACOM(0xF0) }, | ||
1508 | { USB_DEVICE_WACOM(0xCC) }, | ||
1509 | { USB_DEVICE_WACOM(0x90) }, | ||
1510 | { USB_DEVICE_WACOM(0x93) }, | ||
1511 | { USB_DEVICE_WACOM(0x9A) }, | ||
1512 | { USB_DEVICE_WACOM(0x9F) }, | ||
1513 | { USB_DEVICE_WACOM(0xE2) }, | ||
1514 | { USB_DEVICE_WACOM(0xE3) }, | ||
1515 | { USB_DEVICE_WACOM(0x47) }, | ||
1516 | { } | ||
1517 | }; | ||
1055 | MODULE_DEVICE_TABLE(usb, wacom_ids); | 1518 | MODULE_DEVICE_TABLE(usb, wacom_ids); |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index ee01e1902785..00ca01541d89 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -9,17 +9,19 @@ | |||
9 | #ifndef WACOM_WAC_H | 9 | #ifndef WACOM_WAC_H |
10 | #define WACOM_WAC_H | 10 | #define WACOM_WAC_H |
11 | 11 | ||
12 | #include <linux/types.h> | ||
13 | |||
12 | /* maximum packet length for USB devices */ | 14 | /* maximum packet length for USB devices */ |
13 | #define WACOM_PKGLEN_MAX 32 | 15 | #define WACOM_PKGLEN_MAX 32 |
14 | 16 | ||
15 | /* packet length for individual models */ | 17 | /* packet length for individual models */ |
16 | #define WACOM_PKGLEN_PENPRTN 7 | 18 | #define WACOM_PKGLEN_PENPRTN 7 |
17 | #define WACOM_PKGLEN_GRAPHIRE 8 | 19 | #define WACOM_PKGLEN_GRAPHIRE 8 |
18 | #define WACOM_PKGLEN_BBFUN 9 | 20 | #define WACOM_PKGLEN_BBFUN 9 |
19 | #define WACOM_PKGLEN_INTUOS 10 | 21 | #define WACOM_PKGLEN_INTUOS 10 |
20 | #define WACOM_PKGLEN_PENABLED 8 | ||
21 | #define WACOM_PKGLEN_TPC1FG 5 | 22 | #define WACOM_PKGLEN_TPC1FG 5 |
22 | #define WACOM_PKGLEN_TPC2FG 14 | 23 | #define WACOM_PKGLEN_TPC2FG 14 |
24 | #define WACOM_PKGLEN_BBTOUCH 20 | ||
23 | 25 | ||
24 | /* device IDs */ | 26 | /* device IDs */ |
25 | #define STYLUS_DEVICE_ID 0x02 | 27 | #define STYLUS_DEVICE_ID 0x02 |
@@ -36,12 +38,21 @@ | |||
36 | #define WACOM_REPORT_TPC1FG 6 | 38 | #define WACOM_REPORT_TPC1FG 6 |
37 | #define WACOM_REPORT_TPC2FG 13 | 39 | #define WACOM_REPORT_TPC2FG 13 |
38 | 40 | ||
41 | /* device quirks */ | ||
42 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 | ||
43 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 | ||
44 | |||
45 | /* largest reported tracking id */ | ||
46 | #define MAX_TRACKING_ID 0xfff | ||
47 | |||
39 | enum { | 48 | enum { |
40 | PENPARTNER = 0, | 49 | PENPARTNER = 0, |
41 | GRAPHIRE, | 50 | GRAPHIRE, |
42 | WACOM_G4, | 51 | WACOM_G4, |
43 | PTU, | 52 | PTU, |
44 | PL, | 53 | PL, |
54 | DTU, | ||
55 | BAMBOO_PT, | ||
45 | INTUOS, | 56 | INTUOS, |
46 | INTUOS3S, | 57 | INTUOS3S, |
47 | INTUOS3, | 58 | INTUOS3, |
@@ -49,6 +60,7 @@ enum { | |||
49 | INTUOS4S, | 60 | INTUOS4S, |
50 | INTUOS4, | 61 | INTUOS4, |
51 | INTUOS4L, | 62 | INTUOS4L, |
63 | WACOM_21UX2, | ||
52 | CINTIQ, | 64 | CINTIQ, |
53 | WACOM_BEE, | 65 | WACOM_BEE, |
54 | WACOM_MO, | 66 | WACOM_MO, |
@@ -58,7 +70,7 @@ enum { | |||
58 | }; | 70 | }; |
59 | 71 | ||
60 | struct wacom_features { | 72 | struct wacom_features { |
61 | char *name; | 73 | const char *name; |
62 | int pktlen; | 74 | int pktlen; |
63 | int x_max; | 75 | int x_max; |
64 | int y_max; | 76 | int y_max; |
@@ -70,14 +82,28 @@ struct wacom_features { | |||
70 | int y_phy; | 82 | int y_phy; |
71 | unsigned char unit; | 83 | unsigned char unit; |
72 | unsigned char unitExpo; | 84 | unsigned char unitExpo; |
85 | int x_fuzz; | ||
86 | int y_fuzz; | ||
87 | int pressure_fuzz; | ||
88 | int distance_fuzz; | ||
89 | unsigned quirks; | ||
90 | }; | ||
91 | |||
92 | struct wacom_shared { | ||
93 | bool stylus_in_proximity; | ||
73 | }; | 94 | }; |
74 | 95 | ||
75 | struct wacom_wac { | 96 | struct wacom_wac { |
97 | char name[64]; | ||
76 | unsigned char *data; | 98 | unsigned char *data; |
77 | int tool[2]; | 99 | int tool[3]; |
78 | int id[2]; | 100 | int id[3]; |
79 | __u32 serial[2]; | 101 | __u32 serial[2]; |
80 | struct wacom_features *features; | 102 | int last_finger; |
103 | int trk_id; | ||
104 | struct wacom_features features; | ||
105 | struct wacom_shared *shared; | ||
106 | struct input_dev *input; | ||
81 | }; | 107 | }; |
82 | 108 | ||
83 | #endif | 109 | #endif |
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c new file mode 100644 index 000000000000..b3aebc2166ba --- /dev/null +++ b/drivers/input/touchscreen/88pm860x-ts.c | |||
@@ -0,0 +1,237 @@ | |||
1 | /* | ||
2 | * Touchscreen driver for Marvell 88PM860x | ||
3 | * | ||
4 | * Copyright (C) 2009 Marvell International Ltd. | ||
5 | * Haojian Zhuang <haojian.zhuang@marvell.com> | ||
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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/input.h> | ||
16 | #include <linux/mfd/88pm860x.h> | ||
17 | #include <linux/slab.h> | ||
18 | |||
19 | #define MEAS_LEN (8) | ||
20 | #define ACCURATE_BIT (12) | ||
21 | |||
22 | /* touch register */ | ||
23 | #define MEAS_EN3 (0x52) | ||
24 | |||
25 | #define MEAS_TSIX_1 (0x8D) | ||
26 | #define MEAS_TSIX_2 (0x8E) | ||
27 | #define MEAS_TSIY_1 (0x8F) | ||
28 | #define MEAS_TSIY_2 (0x90) | ||
29 | #define MEAS_TSIZ1_1 (0x91) | ||
30 | #define MEAS_TSIZ1_2 (0x92) | ||
31 | #define MEAS_TSIZ2_1 (0x93) | ||
32 | #define MEAS_TSIZ2_2 (0x94) | ||
33 | |||
34 | /* bit definitions of touch */ | ||
35 | #define MEAS_PD_EN (1 << 3) | ||
36 | #define MEAS_TSIX_EN (1 << 4) | ||
37 | #define MEAS_TSIY_EN (1 << 5) | ||
38 | #define MEAS_TSIZ1_EN (1 << 6) | ||
39 | #define MEAS_TSIZ2_EN (1 << 7) | ||
40 | |||
41 | struct pm860x_touch { | ||
42 | struct input_dev *idev; | ||
43 | struct i2c_client *i2c; | ||
44 | struct pm860x_chip *chip; | ||
45 | int irq; | ||
46 | int res_x; /* resistor of Xplate */ | ||
47 | }; | ||
48 | |||
49 | static irqreturn_t pm860x_touch_handler(int irq, void *data) | ||
50 | { | ||
51 | struct pm860x_touch *touch = data; | ||
52 | struct pm860x_chip *chip = touch->chip; | ||
53 | unsigned char buf[MEAS_LEN]; | ||
54 | int x, y, pen_down; | ||
55 | int z1, z2, rt = 0; | ||
56 | int ret; | ||
57 | |||
58 | ret = pm860x_bulk_read(touch->i2c, MEAS_TSIX_1, MEAS_LEN, buf); | ||
59 | if (ret < 0) | ||
60 | goto out; | ||
61 | |||
62 | pen_down = buf[1] & (1 << 6); | ||
63 | x = ((buf[0] & 0xFF) << 4) | (buf[1] & 0x0F); | ||
64 | y = ((buf[2] & 0xFF) << 4) | (buf[3] & 0x0F); | ||
65 | z1 = ((buf[4] & 0xFF) << 4) | (buf[5] & 0x0F); | ||
66 | z2 = ((buf[6] & 0xFF) << 4) | (buf[7] & 0x0F); | ||
67 | |||
68 | if (pen_down) { | ||
69 | if ((x != 0) && (z1 != 0) && (touch->res_x != 0)) { | ||
70 | rt = z2 / z1 - 1; | ||
71 | rt = (rt * touch->res_x * x) >> ACCURATE_BIT; | ||
72 | dev_dbg(chip->dev, "z1:%d, z2:%d, rt:%d\n", | ||
73 | z1, z2, rt); | ||
74 | } | ||
75 | input_report_abs(touch->idev, ABS_X, x); | ||
76 | input_report_abs(touch->idev, ABS_Y, y); | ||
77 | input_report_abs(touch->idev, ABS_PRESSURE, rt); | ||
78 | input_report_key(touch->idev, BTN_TOUCH, 1); | ||
79 | dev_dbg(chip->dev, "pen down at [%d, %d].\n", x, y); | ||
80 | } else { | ||
81 | input_report_abs(touch->idev, ABS_PRESSURE, 0); | ||
82 | input_report_key(touch->idev, BTN_TOUCH, 0); | ||
83 | dev_dbg(chip->dev, "pen release\n"); | ||
84 | } | ||
85 | input_sync(touch->idev); | ||
86 | |||
87 | out: | ||
88 | return IRQ_HANDLED; | ||
89 | } | ||
90 | |||
91 | static int pm860x_touch_open(struct input_dev *dev) | ||
92 | { | ||
93 | struct pm860x_touch *touch = input_get_drvdata(dev); | ||
94 | int data, ret; | ||
95 | |||
96 | data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN | ||
97 | | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN; | ||
98 | ret = pm860x_set_bits(touch->i2c, MEAS_EN3, data, data); | ||
99 | if (ret < 0) | ||
100 | goto out; | ||
101 | return 0; | ||
102 | out: | ||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | static void pm860x_touch_close(struct input_dev *dev) | ||
107 | { | ||
108 | struct pm860x_touch *touch = input_get_drvdata(dev); | ||
109 | int data; | ||
110 | |||
111 | data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN | ||
112 | | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN; | ||
113 | pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); | ||
114 | } | ||
115 | |||
116 | static int __devinit pm860x_touch_probe(struct platform_device *pdev) | ||
117 | { | ||
118 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
119 | struct pm860x_platform_data *pm860x_pdata = \ | ||
120 | pdev->dev.parent->platform_data; | ||
121 | struct pm860x_touch_pdata *pdata = NULL; | ||
122 | struct pm860x_touch *touch; | ||
123 | int irq, ret; | ||
124 | |||
125 | irq = platform_get_irq(pdev, 0); | ||
126 | if (irq < 0) { | ||
127 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | |||
131 | if (!pm860x_pdata) { | ||
132 | dev_err(&pdev->dev, "platform data is missing\n"); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | |||
136 | pdata = pm860x_pdata->touch; | ||
137 | if (!pdata) { | ||
138 | dev_err(&pdev->dev, "touchscreen data is missing\n"); | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | |||
142 | touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); | ||
143 | if (touch == NULL) | ||
144 | return -ENOMEM; | ||
145 | dev_set_drvdata(&pdev->dev, touch); | ||
146 | |||
147 | touch->idev = input_allocate_device(); | ||
148 | if (touch->idev == NULL) { | ||
149 | dev_err(&pdev->dev, "Failed to allocate input device!\n"); | ||
150 | ret = -ENOMEM; | ||
151 | goto out; | ||
152 | } | ||
153 | |||
154 | touch->idev->name = "88pm860x-touch"; | ||
155 | touch->idev->phys = "88pm860x/input0"; | ||
156 | touch->idev->id.bustype = BUS_I2C; | ||
157 | touch->idev->dev.parent = &pdev->dev; | ||
158 | touch->idev->open = pm860x_touch_open; | ||
159 | touch->idev->close = pm860x_touch_close; | ||
160 | touch->chip = chip; | ||
161 | touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | ||
162 | touch->irq = irq + chip->irq_base; | ||
163 | touch->res_x = pdata->res_x; | ||
164 | input_set_drvdata(touch->idev, touch); | ||
165 | |||
166 | ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, | ||
167 | IRQF_ONESHOT, "touch", touch); | ||
168 | if (ret < 0) | ||
169 | goto out_irq; | ||
170 | |||
171 | __set_bit(EV_ABS, touch->idev->evbit); | ||
172 | __set_bit(ABS_X, touch->idev->absbit); | ||
173 | __set_bit(ABS_Y, touch->idev->absbit); | ||
174 | __set_bit(ABS_PRESSURE, touch->idev->absbit); | ||
175 | __set_bit(EV_SYN, touch->idev->evbit); | ||
176 | __set_bit(EV_KEY, touch->idev->evbit); | ||
177 | __set_bit(BTN_TOUCH, touch->idev->keybit); | ||
178 | |||
179 | input_set_abs_params(touch->idev, ABS_X, 0, 1 << ACCURATE_BIT, 0, 0); | ||
180 | input_set_abs_params(touch->idev, ABS_Y, 0, 1 << ACCURATE_BIT, 0, 0); | ||
181 | input_set_abs_params(touch->idev, ABS_PRESSURE, 0, 1 << ACCURATE_BIT, | ||
182 | 0, 0); | ||
183 | |||
184 | ret = input_register_device(touch->idev); | ||
185 | if (ret < 0) { | ||
186 | dev_err(chip->dev, "Failed to register touch!\n"); | ||
187 | goto out_rg; | ||
188 | } | ||
189 | |||
190 | platform_set_drvdata(pdev, touch); | ||
191 | return 0; | ||
192 | out_rg: | ||
193 | free_irq(touch->irq, touch); | ||
194 | out_irq: | ||
195 | input_free_device(touch->idev); | ||
196 | out: | ||
197 | kfree(touch); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | static int __devexit pm860x_touch_remove(struct platform_device *pdev) | ||
202 | { | ||
203 | struct pm860x_touch *touch = platform_get_drvdata(pdev); | ||
204 | |||
205 | input_unregister_device(touch->idev); | ||
206 | free_irq(touch->irq, touch); | ||
207 | platform_set_drvdata(pdev, NULL); | ||
208 | kfree(touch); | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static struct platform_driver pm860x_touch_driver = { | ||
213 | .driver = { | ||
214 | .name = "88pm860x-touch", | ||
215 | .owner = THIS_MODULE, | ||
216 | }, | ||
217 | .probe = pm860x_touch_probe, | ||
218 | .remove = __devexit_p(pm860x_touch_remove), | ||
219 | }; | ||
220 | |||
221 | static int __init pm860x_touch_init(void) | ||
222 | { | ||
223 | return platform_driver_register(&pm860x_touch_driver); | ||
224 | } | ||
225 | module_init(pm860x_touch_init); | ||
226 | |||
227 | static void __exit pm860x_touch_exit(void) | ||
228 | { | ||
229 | platform_driver_unregister(&pm860x_touch_driver); | ||
230 | } | ||
231 | module_exit(pm860x_touch_exit); | ||
232 | |||
233 | MODULE_DESCRIPTION("Touchscreen driver for Marvell Semiconductor 88PM860x"); | ||
234 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); | ||
235 | MODULE_LICENSE("GPL"); | ||
236 | MODULE_ALIAS("platform:88pm860x-touch"); | ||
237 | |||
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index dfafc76da4fb..06ea8da95c62 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -11,18 +11,31 @@ menuconfig INPUT_TOUCHSCREEN | |||
11 | 11 | ||
12 | if INPUT_TOUCHSCREEN | 12 | if INPUT_TOUCHSCREEN |
13 | 13 | ||
14 | config TOUCHSCREEN_88PM860X | ||
15 | tristate "Marvell 88PM860x touchscreen" | ||
16 | depends on MFD_88PM860X | ||
17 | help | ||
18 | Say Y here if you have a 88PM860x PMIC and want to enable | ||
19 | support for the built-in touchscreen. | ||
20 | |||
21 | If unsure, say N. | ||
22 | |||
23 | To compile this driver as a module, choose M here: the | ||
24 | module will be called 88pm860x-ts. | ||
25 | |||
14 | config TOUCHSCREEN_ADS7846 | 26 | config TOUCHSCREEN_ADS7846 |
15 | tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" | 27 | tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens" |
16 | depends on SPI_MASTER | 28 | depends on SPI_MASTER |
17 | depends on HWMON = n || HWMON | 29 | depends on HWMON = n || HWMON |
18 | help | 30 | help |
19 | Say Y here if you have a touchscreen interface using the | 31 | Say Y here if you have a touchscreen interface using the |
20 | ADS7846/TSC2046 or ADS7843 controller, and your board-specific | 32 | ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller, |
21 | setup code includes that in its table of SPI devices. | 33 | and your board-specific setup code includes that in its |
34 | table of SPI devices. | ||
22 | 35 | ||
23 | If HWMON is selected, and the driver is told the reference voltage | 36 | If HWMON is selected, and the driver is told the reference voltage |
24 | on your board, you will also get hwmon interfaces for the voltage | 37 | on your board, you will also get hwmon interfaces for the voltage |
25 | (and on ads7846/tsc2046, temperature) sensors of this chip. | 38 | (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip. |
26 | 39 | ||
27 | If unsure, say N (but it's safe to say "Y"). | 40 | If unsure, say N (but it's safe to say "Y"). |
28 | 41 | ||
@@ -42,37 +55,36 @@ config TOUCHSCREEN_AD7877 | |||
42 | To compile this driver as a module, choose M here: the | 55 | To compile this driver as a module, choose M here: the |
43 | module will be called ad7877. | 56 | module will be called ad7877. |
44 | 57 | ||
45 | config TOUCHSCREEN_AD7879_I2C | 58 | config TOUCHSCREEN_AD7879 |
46 | tristate "AD7879 based touchscreens: AD7879-1 I2C Interface" | 59 | tristate "Analog Devices AD7879-1/AD7889-1 touchscreen interface" |
47 | depends on I2C | ||
48 | select TOUCHSCREEN_AD7879 | ||
49 | help | 60 | help |
50 | Say Y here if you have a touchscreen interface using the | 61 | Say Y here if you want to support a touchscreen interface using |
51 | AD7879-1/AD7889-1 controller, and your board-specific | 62 | the AD7879-1/AD7889-1 controller. |
52 | initialization code includes that in its table of I2C devices. | ||
53 | 63 | ||
54 | If unsure, say N (but it's safe to say "Y"). | 64 | You should select a bus connection too. |
55 | 65 | ||
56 | To compile this driver as a module, choose M here: the | 66 | To compile this driver as a module, choose M here: the |
57 | module will be called ad7879. | 67 | module will be called ad7879. |
58 | 68 | ||
69 | config TOUCHSCREEN_AD7879_I2C | ||
70 | tristate "support I2C bus connection" | ||
71 | depends on TOUCHSCREEN_AD7879 && I2C | ||
72 | help | ||
73 | Say Y here if you have AD7879-1/AD7889-1 hooked to an I2C bus. | ||
74 | |||
75 | To compile this driver as a module, choose M here: the | ||
76 | module will be called ad7879-i2c. | ||
77 | |||
59 | config TOUCHSCREEN_AD7879_SPI | 78 | config TOUCHSCREEN_AD7879_SPI |
60 | tristate "AD7879 based touchscreens: AD7879 SPI Interface" | 79 | tristate "support SPI bus connection" |
61 | depends on SPI_MASTER && TOUCHSCREEN_AD7879_I2C = n | 80 | depends on TOUCHSCREEN_AD7879 && SPI_MASTER |
62 | select TOUCHSCREEN_AD7879 | ||
63 | help | 81 | help |
64 | Say Y here if you have a touchscreen interface using the | 82 | Say Y here if you have AD7879-1/AD7889-1 hooked to a SPI bus. |
65 | AD7879/AD7889 controller, and your board-specific initialization | ||
66 | code includes that in its table of SPI devices. | ||
67 | 83 | ||
68 | If unsure, say N (but it's safe to say "Y"). | 84 | If unsure, say N (but it's safe to say "Y"). |
69 | 85 | ||
70 | To compile this driver as a module, choose M here: the | 86 | To compile this driver as a module, choose M here: the |
71 | module will be called ad7879. | 87 | module will be called ad7879-spi. |
72 | |||
73 | config TOUCHSCREEN_AD7879 | ||
74 | tristate | ||
75 | default n | ||
76 | 88 | ||
77 | config TOUCHSCREEN_BITSY | 89 | config TOUCHSCREEN_BITSY |
78 | tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" | 90 | tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" |
@@ -86,22 +98,31 @@ config TOUCHSCREEN_BITSY | |||
86 | To compile this driver as a module, choose M here: the | 98 | To compile this driver as a module, choose M here: the |
87 | module will be called h3600_ts_input. | 99 | module will be called h3600_ts_input. |
88 | 100 | ||
89 | config TOUCHSCREEN_CORGI | 101 | config TOUCHSCREEN_BU21013 |
90 | tristate "SharpSL (Corgi and Spitz series) touchscreen driver (DEPRECATED)" | 102 | tristate "BU21013 based touch panel controllers" |
91 | depends on PXA_SHARPSL | 103 | depends on I2C |
92 | select CORGI_SSP_DEPRECATED | ||
93 | default y | ||
94 | help | 104 | help |
95 | Say Y here to enable the driver for the touchscreen on the | 105 | Say Y here if you have a bu21013 touchscreen connected to |
96 | Sharp SL-C7xx and SL-Cxx00 series of PDAs. | 106 | your system. |
97 | 107 | ||
98 | If unsure, say N. | 108 | If unsure, say N. |
99 | 109 | ||
100 | To compile this driver as a module, choose M here: the | 110 | To compile this driver as a module, choose M here: the |
101 | module will be called corgi_ts. | 111 | module will be called bu21013_ts. |
112 | |||
113 | config TOUCHSCREEN_CY8CTMG110 | ||
114 | tristate "cy8ctmg110 touchscreen" | ||
115 | depends on I2C | ||
116 | depends on GPIOLIB | ||
102 | 117 | ||
103 | NOTE: this driver is deprecated, try enable SPI and generic | 118 | help |
104 | ADS7846-based touchscreen driver. | 119 | Say Y here if you have a cy8ctmg110 capacitive touchscreen on |
120 | an AAVA device. | ||
121 | |||
122 | If unsure, say N. | ||
123 | |||
124 | To compile this driver as a module, choose M here: the | ||
125 | module will be called cy8ctmg110_ts. | ||
105 | 126 | ||
106 | config TOUCHSCREEN_DA9034 | 127 | config TOUCHSCREEN_DA9034 |
107 | tristate "Touchscreen support for Dialog Semiconductor DA9034" | 128 | tristate "Touchscreen support for Dialog Semiconductor DA9034" |
@@ -123,6 +144,18 @@ config TOUCHSCREEN_DYNAPRO | |||
123 | To compile this driver as a module, choose M here: the | 144 | To compile this driver as a module, choose M here: the |
124 | module will be called dynapro. | 145 | module will be called dynapro. |
125 | 146 | ||
147 | config TOUCHSCREEN_HAMPSHIRE | ||
148 | tristate "Hampshire serial touchscreen" | ||
149 | select SERIO | ||
150 | help | ||
151 | Say Y here if you have a Hampshire serial touchscreen connected to | ||
152 | your system. | ||
153 | |||
154 | If unsure, say N. | ||
155 | |||
156 | To compile this driver as a module, choose M here: the | ||
157 | module will be called hampshire. | ||
158 | |||
126 | config TOUCHSCREEN_EETI | 159 | config TOUCHSCREEN_EETI |
127 | tristate "EETI touchscreen panel support" | 160 | tristate "EETI touchscreen panel support" |
128 | depends on I2C | 161 | depends on I2C |
@@ -146,9 +179,9 @@ config TOUCHSCREEN_FUJITSU | |||
146 | module will be called fujitsu-ts. | 179 | module will be called fujitsu-ts. |
147 | 180 | ||
148 | config TOUCHSCREEN_S3C2410 | 181 | config TOUCHSCREEN_S3C2410 |
149 | tristate "Samsung S3C2410 touchscreen input driver" | 182 | tristate "Samsung S3C2410/generic touchscreen input driver" |
150 | depends on ARCH_S3C2410 | 183 | depends on ARCH_S3C2410 || SAMSUNG_DEV_TS |
151 | select S3C24XX_ADC | 184 | select S3C_ADC |
152 | help | 185 | help |
153 | Say Y here if you have the s3c2410 touchscreen. | 186 | Say Y here if you have the s3c2410 touchscreen. |
154 | 187 | ||
@@ -193,6 +226,16 @@ config TOUCHSCREEN_WACOM_W8001 | |||
193 | To compile this driver as a module, choose M here: the | 226 | To compile this driver as a module, choose M here: the |
194 | module will be called wacom_w8001. | 227 | module will be called wacom_w8001. |
195 | 228 | ||
229 | config TOUCHSCREEN_LPC32XX | ||
230 | tristate "LPC32XX touchscreen controller" | ||
231 | depends on ARCH_LPC32XX | ||
232 | help | ||
233 | Say Y here if you have a LPC32XX device and want | ||
234 | to support the built-in touchscreen. | ||
235 | |||
236 | To compile this driver as a module, choose M here: the | ||
237 | module will be called lpc32xx_ts. | ||
238 | |||
196 | config TOUCHSCREEN_MCS5000 | 239 | config TOUCHSCREEN_MCS5000 |
197 | tristate "MELFAS MCS-5000 touchscreen" | 240 | tristate "MELFAS MCS-5000 touchscreen" |
198 | depends on I2C | 241 | depends on I2C |
@@ -229,6 +272,18 @@ config TOUCHSCREEN_INEXIO | |||
229 | To compile this driver as a module, choose M here: the | 272 | To compile this driver as a module, choose M here: the |
230 | module will be called inexio. | 273 | module will be called inexio. |
231 | 274 | ||
275 | config TOUCHSCREEN_INTEL_MID | ||
276 | tristate "Intel MID platform resistive touchscreen" | ||
277 | depends on INTEL_SCU_IPC | ||
278 | help | ||
279 | Say Y here if you have a Intel MID based touchscreen in | ||
280 | your system. | ||
281 | |||
282 | If unsure, say N. | ||
283 | |||
284 | To compile this driver as a module, choose M here: the | ||
285 | module will be called intel_mid_touch. | ||
286 | |||
232 | config TOUCHSCREEN_MK712 | 287 | config TOUCHSCREEN_MK712 |
233 | tristate "ICS MicroClock MK712 touchscreen" | 288 | tristate "ICS MicroClock MK712 touchscreen" |
234 | help | 289 | help |
@@ -284,6 +339,18 @@ config TOUCHSCREEN_PENMOUNT | |||
284 | To compile this driver as a module, choose M here: the | 339 | To compile this driver as a module, choose M here: the |
285 | module will be called penmount. | 340 | module will be called penmount. |
286 | 341 | ||
342 | config TOUCHSCREEN_QT602240 | ||
343 | tristate "QT602240 I2C Touchscreen" | ||
344 | depends on I2C | ||
345 | help | ||
346 | Say Y here if you have the AT42QT602240/ATMXT224 I2C touchscreen | ||
347 | connected to your system. | ||
348 | |||
349 | If unsure, say N. | ||
350 | |||
351 | To compile this driver as a module, choose M here: the | ||
352 | module will be called qt602240_ts. | ||
353 | |||
287 | config TOUCHSCREEN_MIGOR | 354 | config TOUCHSCREEN_MIGOR |
288 | tristate "Renesas MIGO-R touchscreen" | 355 | tristate "Renesas MIGO-R touchscreen" |
289 | depends on SH_MIGOR && I2C | 356 | depends on SH_MIGOR && I2C |
@@ -295,6 +362,15 @@ config TOUCHSCREEN_MIGOR | |||
295 | To compile this driver as a module, choose M here: the | 362 | To compile this driver as a module, choose M here: the |
296 | module will be called migor_ts. | 363 | module will be called migor_ts. |
297 | 364 | ||
365 | config TOUCHSCREEN_TNETV107X | ||
366 | tristate "TI TNETV107X touchscreen support" | ||
367 | depends on ARCH_DAVINCI_TNETV107X | ||
368 | help | ||
369 | Say Y here if you want to use the TNETV107X touchscreen. | ||
370 | |||
371 | To compile this driver as a module, choose M here: the | ||
372 | module will be called tnetv107x-ts. | ||
373 | |||
298 | config TOUCHSCREEN_TOUCHRIGHT | 374 | config TOUCHSCREEN_TOUCHRIGHT |
299 | tristate "Touchright serial touchscreen" | 375 | tristate "Touchright serial touchscreen" |
300 | select SERIO | 376 | select SERIO |
@@ -532,9 +608,14 @@ config TOUCHSCREEN_USB_ZYTRONIC | |||
532 | bool "Zytronic controller" if EMBEDDED | 608 | bool "Zytronic controller" if EMBEDDED |
533 | depends on TOUCHSCREEN_USB_COMPOSITE | 609 | depends on TOUCHSCREEN_USB_COMPOSITE |
534 | 610 | ||
535 | config TOUCHSCREEN_USB_ETT_TC5UH | 611 | config TOUCHSCREEN_USB_ETT_TC45USB |
612 | default y | ||
613 | bool "ET&T USB series TC4UM/TC5UH touchscreen controler support" if EMBEDDED | ||
614 | depends on TOUCHSCREEN_USB_COMPOSITE | ||
615 | |||
616 | config TOUCHSCREEN_USB_NEXIO | ||
536 | default y | 617 | default y |
537 | bool "ET&T TC5UH touchscreen controler support" if EMBEDDED | 618 | bool "NEXIO/iNexio device support" if EMBEDDED |
538 | depends on TOUCHSCREEN_USB_COMPOSITE | 619 | depends on TOUCHSCREEN_USB_COMPOSITE |
539 | 620 | ||
540 | config TOUCHSCREEN_TOUCHIT213 | 621 | config TOUCHSCREEN_TOUCHIT213 |
@@ -577,4 +658,27 @@ config TOUCHSCREEN_PCAP | |||
577 | 658 | ||
578 | To compile this driver as a module, choose M here: the | 659 | To compile this driver as a module, choose M here: the |
579 | module will be called pcap_ts. | 660 | module will be called pcap_ts. |
661 | |||
662 | config TOUCHSCREEN_TPS6507X | ||
663 | tristate "TPS6507x based touchscreens" | ||
664 | depends on I2C | ||
665 | help | ||
666 | Say Y here if you have a TPS6507x based touchscreen | ||
667 | controller. | ||
668 | |||
669 | If unsure, say N. | ||
670 | |||
671 | To compile this driver as a module, choose M here: the | ||
672 | module will be called tps6507x_ts. | ||
673 | |||
674 | config TOUCHSCREEN_STMPE | ||
675 | tristate "STMicroelectronics STMPE touchscreens" | ||
676 | depends on MFD_STMPE | ||
677 | help | ||
678 | Say Y here if you want support for STMicroelectronics | ||
679 | STMPE touchscreen controllers. | ||
680 | |||
681 | To compile this driver as a module, choose M here: the | ||
682 | module will be called stmpe-ts. | ||
683 | |||
580 | endif | 684 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index d61a3b4def9a..7cc1b4f4b677 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -6,18 +6,26 @@ | |||
6 | 6 | ||
7 | wm97xx-ts-y := wm97xx-core.o | 7 | wm97xx-ts-y := wm97xx-core.o |
8 | 8 | ||
9 | obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o | ||
9 | obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o | 10 | obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o |
10 | obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o | 11 | obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o |
12 | obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o | ||
13 | obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o | ||
11 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o | 14 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o |
12 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o | 15 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o |
13 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | 16 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o |
14 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o | 17 | obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o |
18 | obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o | ||
19 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o | ||
15 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o | 20 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o |
21 | obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o | ||
16 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 22 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
17 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | 23 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o |
18 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 24 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
19 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 25 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
20 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o | 26 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o |
27 | obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o | ||
28 | obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o | ||
21 | obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o | 29 | obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o |
22 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o | 30 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o |
23 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o | 31 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o |
@@ -29,7 +37,10 @@ obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o | |||
29 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o | 37 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o |
30 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o | 38 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o |
31 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o | 39 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o |
40 | obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o | ||
32 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o | 41 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o |
42 | obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o | ||
43 | obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o | ||
33 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o | 44 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o |
34 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o | 45 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o |
35 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o | 46 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o |
@@ -37,7 +48,6 @@ obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o | |||
37 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o | 48 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o |
38 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o | 49 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o |
39 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o | 50 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o |
40 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o | ||
41 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o | 51 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o |
42 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o | 52 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o |
43 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o | 53 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o |
@@ -45,3 +55,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o | |||
45 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o | 55 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o |
46 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o | 56 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o |
47 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o | 57 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o |
58 | obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o | ||
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index eb83939c705e..a1952fcc083e 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <linux/spi/ad7877.h> | 46 | #include <linux/spi/ad7877.h> |
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | 48 | ||
49 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) | 49 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(100) |
50 | 50 | ||
51 | #define MAX_SPI_FREQ_HZ 20000000 | 51 | #define MAX_SPI_FREQ_HZ 20000000 |
52 | #define MAX_12BIT ((1<<12)-1) | 52 | #define MAX_12BIT ((1<<12)-1) |
@@ -156,9 +156,14 @@ struct ser_req { | |||
156 | u16 reset; | 156 | u16 reset; |
157 | u16 ref_on; | 157 | u16 ref_on; |
158 | u16 command; | 158 | u16 command; |
159 | u16 sample; | ||
160 | struct spi_message msg; | 159 | struct spi_message msg; |
161 | struct spi_transfer xfer[6]; | 160 | struct spi_transfer xfer[6]; |
161 | |||
162 | /* | ||
163 | * DMA (thus cache coherency maintenance) requires the | ||
164 | * transfer buffers to live in their own cache lines. | ||
165 | */ | ||
166 | u16 sample ____cacheline_aligned; | ||
162 | }; | 167 | }; |
163 | 168 | ||
164 | struct ad7877 { | 169 | struct ad7877 { |
@@ -182,23 +187,26 @@ struct ad7877 { | |||
182 | u8 averaging; | 187 | u8 averaging; |
183 | u8 pen_down_acc_interval; | 188 | u8 pen_down_acc_interval; |
184 | 189 | ||
185 | u16 conversion_data[AD7877_NR_SENSE]; | ||
186 | |||
187 | struct spi_transfer xfer[AD7877_NR_SENSE + 2]; | 190 | struct spi_transfer xfer[AD7877_NR_SENSE + 2]; |
188 | struct spi_message msg; | 191 | struct spi_message msg; |
189 | 192 | ||
190 | struct mutex mutex; | 193 | struct mutex mutex; |
191 | unsigned disabled:1; /* P: mutex */ | 194 | bool disabled; /* P: mutex */ |
192 | unsigned gpio3:1; /* P: mutex */ | 195 | bool gpio3; /* P: mutex */ |
193 | unsigned gpio4:1; /* P: mutex */ | 196 | bool gpio4; /* P: mutex */ |
194 | 197 | ||
195 | spinlock_t lock; | 198 | spinlock_t lock; |
196 | struct timer_list timer; /* P: lock */ | 199 | struct timer_list timer; /* P: lock */ |
197 | unsigned pending:1; /* P: lock */ | 200 | |
201 | /* | ||
202 | * DMA (thus cache coherency maintenance) requires the | ||
203 | * transfer buffers to live in their own cache lines. | ||
204 | */ | ||
205 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; | ||
198 | }; | 206 | }; |
199 | 207 | ||
200 | static int gpio3; | 208 | static bool gpio3; |
201 | module_param(gpio3, int, 0); | 209 | module_param(gpio3, bool, 0); |
202 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); | 210 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); |
203 | 211 | ||
204 | /* | 212 | /* |
@@ -221,6 +229,7 @@ static int ad7877_read(struct spi_device *spi, u16 reg) | |||
221 | AD7877_READADD(reg)); | 229 | AD7877_READADD(reg)); |
222 | req->xfer[0].tx_buf = &req->command; | 230 | req->xfer[0].tx_buf = &req->command; |
223 | req->xfer[0].len = 2; | 231 | req->xfer[0].len = 2; |
232 | req->xfer[0].cs_change = 1; | ||
224 | 233 | ||
225 | req->xfer[1].rx_buf = &req->sample; | 234 | req->xfer[1].rx_buf = &req->sample; |
226 | req->xfer[1].len = 2; | 235 | req->xfer[1].len = 2; |
@@ -286,20 +295,25 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command) | |||
286 | 295 | ||
287 | req->xfer[0].tx_buf = &req->reset; | 296 | req->xfer[0].tx_buf = &req->reset; |
288 | req->xfer[0].len = 2; | 297 | req->xfer[0].len = 2; |
298 | req->xfer[0].cs_change = 1; | ||
289 | 299 | ||
290 | req->xfer[1].tx_buf = &req->ref_on; | 300 | req->xfer[1].tx_buf = &req->ref_on; |
291 | req->xfer[1].len = 2; | 301 | req->xfer[1].len = 2; |
292 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; | 302 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; |
303 | req->xfer[1].cs_change = 1; | ||
293 | 304 | ||
294 | req->xfer[2].tx_buf = &req->command; | 305 | req->xfer[2].tx_buf = &req->command; |
295 | req->xfer[2].len = 2; | 306 | req->xfer[2].len = 2; |
296 | req->xfer[2].delay_usecs = ts->vref_delay_usecs; | 307 | req->xfer[2].delay_usecs = ts->vref_delay_usecs; |
308 | req->xfer[2].cs_change = 1; | ||
297 | 309 | ||
298 | req->xfer[3].rx_buf = &req->sample; | 310 | req->xfer[3].rx_buf = &req->sample; |
299 | req->xfer[3].len = 2; | 311 | req->xfer[3].len = 2; |
312 | req->xfer[3].cs_change = 1; | ||
300 | 313 | ||
301 | req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/ | 314 | req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/ |
302 | req->xfer[4].len = 2; | 315 | req->xfer[4].len = 2; |
316 | req->xfer[4].cs_change = 1; | ||
303 | 317 | ||
304 | req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/ | 318 | req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/ |
305 | req->xfer[5].len = 2; | 319 | req->xfer[5].len = 2; |
@@ -318,7 +332,7 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command) | |||
318 | return status ? : sample; | 332 | return status ? : sample; |
319 | } | 333 | } |
320 | 334 | ||
321 | static void ad7877_rx(struct ad7877 *ts) | 335 | static int ad7877_process_data(struct ad7877 *ts) |
322 | { | 336 | { |
323 | struct input_dev *input_dev = ts->input; | 337 | struct input_dev *input_dev = ts->input; |
324 | unsigned Rt; | 338 | unsigned Rt; |
@@ -345,11 +359,25 @@ static void ad7877_rx(struct ad7877 *ts) | |||
345 | Rt /= z1; | 359 | Rt /= z1; |
346 | Rt = (Rt + 2047) >> 12; | 360 | Rt = (Rt + 2047) >> 12; |
347 | 361 | ||
362 | /* | ||
363 | * Sample found inconsistent, pressure is beyond | ||
364 | * the maximum. Don't report it to user space. | ||
365 | */ | ||
366 | if (Rt > ts->pressure_max) | ||
367 | return -EINVAL; | ||
368 | |||
369 | if (!timer_pending(&ts->timer)) | ||
370 | input_report_key(input_dev, BTN_TOUCH, 1); | ||
371 | |||
348 | input_report_abs(input_dev, ABS_X, x); | 372 | input_report_abs(input_dev, ABS_X, x); |
349 | input_report_abs(input_dev, ABS_Y, y); | 373 | input_report_abs(input_dev, ABS_Y, y); |
350 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | 374 | input_report_abs(input_dev, ABS_PRESSURE, Rt); |
351 | input_sync(input_dev); | 375 | input_sync(input_dev); |
376 | |||
377 | return 0; | ||
352 | } | 378 | } |
379 | |||
380 | return -EINVAL; | ||
353 | } | 381 | } |
354 | 382 | ||
355 | static inline void ad7877_ts_event_release(struct ad7877 *ts) | 383 | static inline void ad7877_ts_event_release(struct ad7877 *ts) |
@@ -357,72 +385,56 @@ static inline void ad7877_ts_event_release(struct ad7877 *ts) | |||
357 | struct input_dev *input_dev = ts->input; | 385 | struct input_dev *input_dev = ts->input; |
358 | 386 | ||
359 | input_report_abs(input_dev, ABS_PRESSURE, 0); | 387 | input_report_abs(input_dev, ABS_PRESSURE, 0); |
388 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
360 | input_sync(input_dev); | 389 | input_sync(input_dev); |
361 | } | 390 | } |
362 | 391 | ||
363 | static void ad7877_timer(unsigned long handle) | 392 | static void ad7877_timer(unsigned long handle) |
364 | { | 393 | { |
365 | struct ad7877 *ts = (void *)handle; | 394 | struct ad7877 *ts = (void *)handle; |
395 | unsigned long flags; | ||
366 | 396 | ||
397 | spin_lock_irqsave(&ts->lock, flags); | ||
367 | ad7877_ts_event_release(ts); | 398 | ad7877_ts_event_release(ts); |
399 | spin_unlock_irqrestore(&ts->lock, flags); | ||
368 | } | 400 | } |
369 | 401 | ||
370 | static irqreturn_t ad7877_irq(int irq, void *handle) | 402 | static irqreturn_t ad7877_irq(int irq, void *handle) |
371 | { | 403 | { |
372 | struct ad7877 *ts = handle; | 404 | struct ad7877 *ts = handle; |
373 | unsigned long flags; | 405 | unsigned long flags; |
374 | int status; | 406 | int error; |
375 | 407 | ||
376 | /* | 408 | error = spi_sync(ts->spi, &ts->msg); |
377 | * The repeated conversion sequencer controlled by TMR kicked off | 409 | if (error) { |
378 | * too fast. We ignore the last and process the sample sequence | 410 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", error); |
379 | * currently in the queue. It can't be older than 9.4ms, and we | 411 | goto out; |
380 | * need to avoid that ts->msg doesn't get issued twice while in work. | 412 | } |
381 | */ | ||
382 | 413 | ||
383 | spin_lock_irqsave(&ts->lock, flags); | 414 | spin_lock_irqsave(&ts->lock, flags); |
384 | if (!ts->pending) { | 415 | error = ad7877_process_data(ts); |
385 | ts->pending = 1; | 416 | if (!error) |
386 | 417 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | |
387 | status = spi_async(ts->spi, &ts->msg); | ||
388 | if (status) | ||
389 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", status); | ||
390 | } | ||
391 | spin_unlock_irqrestore(&ts->lock, flags); | 418 | spin_unlock_irqrestore(&ts->lock, flags); |
392 | 419 | ||
420 | out: | ||
393 | return IRQ_HANDLED; | 421 | return IRQ_HANDLED; |
394 | } | 422 | } |
395 | 423 | ||
396 | static void ad7877_callback(void *_ts) | ||
397 | { | ||
398 | struct ad7877 *ts = _ts; | ||
399 | |||
400 | spin_lock_irq(&ts->lock); | ||
401 | |||
402 | ad7877_rx(ts); | ||
403 | ts->pending = 0; | ||
404 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | ||
405 | |||
406 | spin_unlock_irq(&ts->lock); | ||
407 | } | ||
408 | |||
409 | static void ad7877_disable(struct ad7877 *ts) | 424 | static void ad7877_disable(struct ad7877 *ts) |
410 | { | 425 | { |
411 | mutex_lock(&ts->mutex); | 426 | mutex_lock(&ts->mutex); |
412 | 427 | ||
413 | if (!ts->disabled) { | 428 | if (!ts->disabled) { |
414 | ts->disabled = 1; | 429 | ts->disabled = true; |
415 | disable_irq(ts->spi->irq); | 430 | disable_irq(ts->spi->irq); |
416 | 431 | ||
417 | /* Wait for spi_async callback */ | ||
418 | while (ts->pending) | ||
419 | msleep(1); | ||
420 | |||
421 | if (del_timer_sync(&ts->timer)) | 432 | if (del_timer_sync(&ts->timer)) |
422 | ad7877_ts_event_release(ts); | 433 | ad7877_ts_event_release(ts); |
423 | } | 434 | } |
424 | 435 | ||
425 | /* we know the chip's in lowpower mode since we always | 436 | /* |
437 | * We know the chip's in lowpower mode since we always | ||
426 | * leave it that way after every request | 438 | * leave it that way after every request |
427 | */ | 439 | */ |
428 | 440 | ||
@@ -434,7 +446,7 @@ static void ad7877_enable(struct ad7877 *ts) | |||
434 | mutex_lock(&ts->mutex); | 446 | mutex_lock(&ts->mutex); |
435 | 447 | ||
436 | if (ts->disabled) { | 448 | if (ts->disabled) { |
437 | ts->disabled = 0; | 449 | ts->disabled = false; |
438 | enable_irq(ts->spi->irq); | 450 | enable_irq(ts->spi->irq); |
439 | } | 451 | } |
440 | 452 | ||
@@ -444,7 +456,7 @@ static void ad7877_enable(struct ad7877 *ts) | |||
444 | #define SHOW(name) static ssize_t \ | 456 | #define SHOW(name) static ssize_t \ |
445 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ | 457 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ |
446 | { \ | 458 | { \ |
447 | struct ad7877 *ts = dev_get_drvdata(dev); \ | 459 | struct ad7877 *ts = dev_get_drvdata(dev); \ |
448 | ssize_t v = ad7877_read_adc(ts->spi, \ | 460 | ssize_t v = ad7877_read_adc(ts->spi, \ |
449 | AD7877_READ_CHAN(name)); \ | 461 | AD7877_READ_CHAN(name)); \ |
450 | if (v < 0) \ | 462 | if (v < 0) \ |
@@ -464,7 +476,7 @@ SHOW(temp2) | |||
464 | static ssize_t ad7877_disable_show(struct device *dev, | 476 | static ssize_t ad7877_disable_show(struct device *dev, |
465 | struct device_attribute *attr, char *buf) | 477 | struct device_attribute *attr, char *buf) |
466 | { | 478 | { |
467 | struct ad7877 *ts = dev_get_drvdata(dev); | 479 | struct ad7877 *ts = dev_get_drvdata(dev); |
468 | 480 | ||
469 | return sprintf(buf, "%u\n", ts->disabled); | 481 | return sprintf(buf, "%u\n", ts->disabled); |
470 | } | 482 | } |
@@ -494,7 +506,7 @@ static DEVICE_ATTR(disable, 0664, ad7877_disable_show, ad7877_disable_store); | |||
494 | static ssize_t ad7877_dac_show(struct device *dev, | 506 | static ssize_t ad7877_dac_show(struct device *dev, |
495 | struct device_attribute *attr, char *buf) | 507 | struct device_attribute *attr, char *buf) |
496 | { | 508 | { |
497 | struct ad7877 *ts = dev_get_drvdata(dev); | 509 | struct ad7877 *ts = dev_get_drvdata(dev); |
498 | 510 | ||
499 | return sprintf(buf, "%u\n", ts->dac); | 511 | return sprintf(buf, "%u\n", ts->dac); |
500 | } | 512 | } |
@@ -524,7 +536,7 @@ static DEVICE_ATTR(dac, 0664, ad7877_dac_show, ad7877_dac_store); | |||
524 | static ssize_t ad7877_gpio3_show(struct device *dev, | 536 | static ssize_t ad7877_gpio3_show(struct device *dev, |
525 | struct device_attribute *attr, char *buf) | 537 | struct device_attribute *attr, char *buf) |
526 | { | 538 | { |
527 | struct ad7877 *ts = dev_get_drvdata(dev); | 539 | struct ad7877 *ts = dev_get_drvdata(dev); |
528 | 540 | ||
529 | return sprintf(buf, "%u\n", ts->gpio3); | 541 | return sprintf(buf, "%u\n", ts->gpio3); |
530 | } | 542 | } |
@@ -555,7 +567,7 @@ static DEVICE_ATTR(gpio3, 0664, ad7877_gpio3_show, ad7877_gpio3_store); | |||
555 | static ssize_t ad7877_gpio4_show(struct device *dev, | 567 | static ssize_t ad7877_gpio4_show(struct device *dev, |
556 | struct device_attribute *attr, char *buf) | 568 | struct device_attribute *attr, char *buf) |
557 | { | 569 | { |
558 | struct ad7877 *ts = dev_get_drvdata(dev); | 570 | struct ad7877 *ts = dev_get_drvdata(dev); |
559 | 571 | ||
560 | return sprintf(buf, "%u\n", ts->gpio4); | 572 | return sprintf(buf, "%u\n", ts->gpio4); |
561 | } | 573 | } |
@@ -588,16 +600,35 @@ static struct attribute *ad7877_attributes[] = { | |||
588 | &dev_attr_temp2.attr, | 600 | &dev_attr_temp2.attr, |
589 | &dev_attr_aux1.attr, | 601 | &dev_attr_aux1.attr, |
590 | &dev_attr_aux2.attr, | 602 | &dev_attr_aux2.attr, |
603 | &dev_attr_aux3.attr, | ||
591 | &dev_attr_bat1.attr, | 604 | &dev_attr_bat1.attr, |
592 | &dev_attr_bat2.attr, | 605 | &dev_attr_bat2.attr, |
593 | &dev_attr_disable.attr, | 606 | &dev_attr_disable.attr, |
594 | &dev_attr_dac.attr, | 607 | &dev_attr_dac.attr, |
608 | &dev_attr_gpio3.attr, | ||
595 | &dev_attr_gpio4.attr, | 609 | &dev_attr_gpio4.attr, |
596 | NULL | 610 | NULL |
597 | }; | 611 | }; |
598 | 612 | ||
613 | static mode_t ad7877_attr_is_visible(struct kobject *kobj, | ||
614 | struct attribute *attr, int n) | ||
615 | { | ||
616 | mode_t mode = attr->mode; | ||
617 | |||
618 | if (attr == &dev_attr_aux3.attr) { | ||
619 | if (gpio3) | ||
620 | mode = 0; | ||
621 | } else if (attr == &dev_attr_gpio3.attr) { | ||
622 | if (!gpio3) | ||
623 | mode = 0; | ||
624 | } | ||
625 | |||
626 | return mode; | ||
627 | } | ||
628 | |||
599 | static const struct attribute_group ad7877_attr_group = { | 629 | static const struct attribute_group ad7877_attr_group = { |
600 | .attrs = ad7877_attributes, | 630 | .is_visible = ad7877_attr_is_visible, |
631 | .attrs = ad7877_attributes, | ||
601 | }; | 632 | }; |
602 | 633 | ||
603 | static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) | 634 | static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) |
@@ -626,22 +657,25 @@ static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) | |||
626 | 657 | ||
627 | spi_message_init(m); | 658 | spi_message_init(m); |
628 | 659 | ||
629 | m->complete = ad7877_callback; | ||
630 | m->context = ts; | 660 | m->context = ts; |
631 | 661 | ||
632 | ts->xfer[0].tx_buf = &ts->cmd_crtl1; | 662 | ts->xfer[0].tx_buf = &ts->cmd_crtl1; |
633 | ts->xfer[0].len = 2; | 663 | ts->xfer[0].len = 2; |
664 | ts->xfer[0].cs_change = 1; | ||
634 | 665 | ||
635 | spi_message_add_tail(&ts->xfer[0], m); | 666 | spi_message_add_tail(&ts->xfer[0], m); |
636 | 667 | ||
637 | ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */ | 668 | ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */ |
638 | ts->xfer[1].len = 2; | 669 | ts->xfer[1].len = 2; |
670 | ts->xfer[1].cs_change = 1; | ||
639 | 671 | ||
640 | spi_message_add_tail(&ts->xfer[1], m); | 672 | spi_message_add_tail(&ts->xfer[1], m); |
641 | 673 | ||
642 | for (i = 0; i < 11; i++) { | 674 | for (i = 0; i < AD7877_NR_SENSE; i++) { |
643 | ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i]; | 675 | ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i]; |
644 | ts->xfer[i + 2].len = 2; | 676 | ts->xfer[i + 2].len = 2; |
677 | if (i < (AD7877_NR_SENSE - 1)) | ||
678 | ts->xfer[i + 2].cs_change = 1; | ||
645 | spi_message_add_tail(&ts->xfer[i + 2], m); | 679 | spi_message_add_tail(&ts->xfer[i + 2], m); |
646 | } | 680 | } |
647 | } | 681 | } |
@@ -670,6 +704,13 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
670 | return -EINVAL; | 704 | return -EINVAL; |
671 | } | 705 | } |
672 | 706 | ||
707 | spi->bits_per_word = 16; | ||
708 | err = spi_setup(spi); | ||
709 | if (err) { | ||
710 | dev_dbg(&spi->dev, "spi master doesn't support 16 bits/word\n"); | ||
711 | return err; | ||
712 | } | ||
713 | |||
673 | ts = kzalloc(sizeof(struct ad7877), GFP_KERNEL); | 714 | ts = kzalloc(sizeof(struct ad7877), GFP_KERNEL); |
674 | input_dev = input_allocate_device(); | 715 | input_dev = input_allocate_device(); |
675 | if (!ts || !input_dev) { | 716 | if (!ts || !input_dev) { |
@@ -702,6 +743,8 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
702 | input_dev->phys = ts->phys; | 743 | input_dev->phys = ts->phys; |
703 | input_dev->dev.parent = &spi->dev; | 744 | input_dev->dev.parent = &spi->dev; |
704 | 745 | ||
746 | __set_bit(EV_KEY, input_dev->evbit); | ||
747 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
705 | __set_bit(EV_ABS, input_dev->evbit); | 748 | __set_bit(EV_ABS, input_dev->evbit); |
706 | __set_bit(ABS_X, input_dev->absbit); | 749 | __set_bit(ABS_X, input_dev->absbit); |
707 | __set_bit(ABS_Y, input_dev->absbit); | 750 | __set_bit(ABS_Y, input_dev->absbit); |
@@ -736,8 +779,9 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
736 | 779 | ||
737 | /* Request AD7877 /DAV GPIO interrupt */ | 780 | /* Request AD7877 /DAV GPIO interrupt */ |
738 | 781 | ||
739 | err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING, | 782 | err = request_threaded_irq(spi->irq, NULL, ad7877_irq, |
740 | spi->dev.driver->name, ts); | 783 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
784 | spi->dev.driver->name, ts); | ||
741 | if (err) { | 785 | if (err) { |
742 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 786 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
743 | goto err_free_mem; | 787 | goto err_free_mem; |
@@ -747,20 +791,12 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
747 | if (err) | 791 | if (err) |
748 | goto err_free_irq; | 792 | goto err_free_irq; |
749 | 793 | ||
750 | err = device_create_file(&spi->dev, | ||
751 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
752 | if (err) | ||
753 | goto err_remove_attr_group; | ||
754 | |||
755 | err = input_register_device(input_dev); | 794 | err = input_register_device(input_dev); |
756 | if (err) | 795 | if (err) |
757 | goto err_remove_attr; | 796 | goto err_remove_attr_group; |
758 | 797 | ||
759 | return 0; | 798 | return 0; |
760 | 799 | ||
761 | err_remove_attr: | ||
762 | device_remove_file(&spi->dev, | ||
763 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
764 | err_remove_attr_group: | 800 | err_remove_attr_group: |
765 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | 801 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); |
766 | err_free_irq: | 802 | err_free_irq: |
@@ -774,11 +810,9 @@ err_free_mem: | |||
774 | 810 | ||
775 | static int __devexit ad7877_remove(struct spi_device *spi) | 811 | static int __devexit ad7877_remove(struct spi_device *spi) |
776 | { | 812 | { |
777 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | 813 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); |
778 | 814 | ||
779 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | 815 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); |
780 | device_remove_file(&spi->dev, | ||
781 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
782 | 816 | ||
783 | ad7877_disable(ts); | 817 | ad7877_disable(ts); |
784 | free_irq(ts->spi->irq, ts); | 818 | free_irq(ts->spi->irq, ts); |
diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c new file mode 100644 index 000000000000..d82a38ee9a3e --- /dev/null +++ b/drivers/input/touchscreen/ad7879-i2c.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * AD7879-1/AD7889-1 touchscreen (I2C bus) | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/input.h> /* BUS_I2C */ | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/types.h> | ||
13 | |||
14 | #include "ad7879.h" | ||
15 | |||
16 | #define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ | ||
17 | |||
18 | #ifdef CONFIG_PM | ||
19 | static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) | ||
20 | { | ||
21 | struct ad7879 *ts = i2c_get_clientdata(client); | ||
22 | |||
23 | ad7879_suspend(ts); | ||
24 | |||
25 | return 0; | ||
26 | } | ||
27 | |||
28 | static int ad7879_i2c_resume(struct i2c_client *client) | ||
29 | { | ||
30 | struct ad7879 *ts = i2c_get_clientdata(client); | ||
31 | |||
32 | ad7879_resume(ts); | ||
33 | |||
34 | return 0; | ||
35 | } | ||
36 | #else | ||
37 | # define ad7879_i2c_suspend NULL | ||
38 | # define ad7879_i2c_resume NULL | ||
39 | #endif | ||
40 | |||
41 | /* All registers are word-sized. | ||
42 | * AD7879 uses a high-byte first convention. | ||
43 | */ | ||
44 | static int ad7879_i2c_read(struct device *dev, u8 reg) | ||
45 | { | ||
46 | struct i2c_client *client = to_i2c_client(dev); | ||
47 | |||
48 | return swab16(i2c_smbus_read_word_data(client, reg)); | ||
49 | } | ||
50 | |||
51 | static int ad7879_i2c_multi_read(struct device *dev, | ||
52 | u8 first_reg, u8 count, u16 *buf) | ||
53 | { | ||
54 | struct i2c_client *client = to_i2c_client(dev); | ||
55 | u8 idx; | ||
56 | |||
57 | i2c_smbus_read_i2c_block_data(client, first_reg, count * 2, (u8 *)buf); | ||
58 | |||
59 | for (idx = 0; idx < count; ++idx) | ||
60 | buf[idx] = swab16(buf[idx]); | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int ad7879_i2c_write(struct device *dev, u8 reg, u16 val) | ||
66 | { | ||
67 | struct i2c_client *client = to_i2c_client(dev); | ||
68 | |||
69 | return i2c_smbus_write_word_data(client, reg, swab16(val)); | ||
70 | } | ||
71 | |||
72 | static const struct ad7879_bus_ops ad7879_i2c_bus_ops = { | ||
73 | .bustype = BUS_I2C, | ||
74 | .read = ad7879_i2c_read, | ||
75 | .multi_read = ad7879_i2c_multi_read, | ||
76 | .write = ad7879_i2c_write, | ||
77 | }; | ||
78 | |||
79 | static int __devinit ad7879_i2c_probe(struct i2c_client *client, | ||
80 | const struct i2c_device_id *id) | ||
81 | { | ||
82 | struct ad7879 *ts; | ||
83 | |||
84 | if (!i2c_check_functionality(client->adapter, | ||
85 | I2C_FUNC_SMBUS_WORD_DATA)) { | ||
86 | dev_err(&client->dev, "SMBUS Word Data not Supported\n"); | ||
87 | return -EIO; | ||
88 | } | ||
89 | |||
90 | ts = ad7879_probe(&client->dev, AD7879_DEVID, client->irq, | ||
91 | &ad7879_i2c_bus_ops); | ||
92 | if (IS_ERR(ts)) | ||
93 | return PTR_ERR(ts); | ||
94 | |||
95 | i2c_set_clientdata(client, ts); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int __devexit ad7879_i2c_remove(struct i2c_client *client) | ||
101 | { | ||
102 | struct ad7879 *ts = i2c_get_clientdata(client); | ||
103 | |||
104 | ad7879_remove(ts); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static const struct i2c_device_id ad7879_id[] = { | ||
110 | { "ad7879", 0 }, | ||
111 | { "ad7889", 0 }, | ||
112 | { } | ||
113 | }; | ||
114 | MODULE_DEVICE_TABLE(i2c, ad7879_id); | ||
115 | |||
116 | static struct i2c_driver ad7879_i2c_driver = { | ||
117 | .driver = { | ||
118 | .name = "ad7879", | ||
119 | .owner = THIS_MODULE, | ||
120 | }, | ||
121 | .probe = ad7879_i2c_probe, | ||
122 | .remove = __devexit_p(ad7879_i2c_remove), | ||
123 | .suspend = ad7879_i2c_suspend, | ||
124 | .resume = ad7879_i2c_resume, | ||
125 | .id_table = ad7879_id, | ||
126 | }; | ||
127 | |||
128 | static int __init ad7879_i2c_init(void) | ||
129 | { | ||
130 | return i2c_add_driver(&ad7879_i2c_driver); | ||
131 | } | ||
132 | module_init(ad7879_i2c_init); | ||
133 | |||
134 | static void __exit ad7879_i2c_exit(void) | ||
135 | { | ||
136 | i2c_del_driver(&ad7879_i2c_driver); | ||
137 | } | ||
138 | module_exit(ad7879_i2c_exit); | ||
139 | |||
140 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
141 | MODULE_DESCRIPTION("AD7879(-1) touchscreen I2C bus driver"); | ||
142 | MODULE_LICENSE("GPL"); | ||
143 | MODULE_ALIAS("i2c:ad7879"); | ||
diff --git a/drivers/input/touchscreen/ad7879-spi.c b/drivers/input/touchscreen/ad7879-spi.c new file mode 100644 index 000000000000..59c6e68c4325 --- /dev/null +++ b/drivers/input/touchscreen/ad7879-spi.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | * AD7879/AD7889 touchscreen (SPI bus) | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/input.h> /* BUS_SPI */ | ||
10 | #include <linux/spi/spi.h> | ||
11 | |||
12 | #include "ad7879.h" | ||
13 | |||
14 | #define AD7879_DEVID 0x7A /* AD7879/AD7889 */ | ||
15 | |||
16 | #define MAX_SPI_FREQ_HZ 5000000 | ||
17 | #define AD7879_CMD_MAGIC 0xE000 | ||
18 | #define AD7879_CMD_READ (1 << 10) | ||
19 | #define AD7879_CMD(reg) (AD7879_CMD_MAGIC | ((reg) & 0xF)) | ||
20 | #define AD7879_WRITECMD(reg) (AD7879_CMD(reg)) | ||
21 | #define AD7879_READCMD(reg) (AD7879_CMD(reg) | AD7879_CMD_READ) | ||
22 | |||
23 | #ifdef CONFIG_PM | ||
24 | static int ad7879_spi_suspend(struct spi_device *spi, pm_message_t message) | ||
25 | { | ||
26 | struct ad7879 *ts = spi_get_drvdata(spi); | ||
27 | |||
28 | ad7879_suspend(ts); | ||
29 | |||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | static int ad7879_spi_resume(struct spi_device *spi) | ||
34 | { | ||
35 | struct ad7879 *ts = spi_get_drvdata(spi); | ||
36 | |||
37 | ad7879_resume(ts); | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | #else | ||
42 | # define ad7879_spi_suspend NULL | ||
43 | # define ad7879_spi_resume NULL | ||
44 | #endif | ||
45 | |||
46 | /* | ||
47 | * ad7879_read/write are only used for initial setup and for sysfs controls. | ||
48 | * The main traffic is done in ad7879_collect(). | ||
49 | */ | ||
50 | |||
51 | static int ad7879_spi_xfer(struct spi_device *spi, | ||
52 | u16 cmd, u8 count, u16 *tx_buf, u16 *rx_buf) | ||
53 | { | ||
54 | struct spi_message msg; | ||
55 | struct spi_transfer *xfers; | ||
56 | void *spi_data; | ||
57 | u16 *command; | ||
58 | u16 *_rx_buf = _rx_buf; /* shut gcc up */ | ||
59 | u8 idx; | ||
60 | int ret; | ||
61 | |||
62 | xfers = spi_data = kzalloc(sizeof(*xfers) * (count + 2), GFP_KERNEL); | ||
63 | if (!spi_data) | ||
64 | return -ENOMEM; | ||
65 | |||
66 | spi_message_init(&msg); | ||
67 | |||
68 | command = spi_data; | ||
69 | command[0] = cmd; | ||
70 | if (count == 1) { | ||
71 | /* ad7879_spi_{read,write} gave us buf on stack */ | ||
72 | command[1] = *tx_buf; | ||
73 | tx_buf = &command[1]; | ||
74 | _rx_buf = rx_buf; | ||
75 | rx_buf = &command[2]; | ||
76 | } | ||
77 | |||
78 | ++xfers; | ||
79 | xfers[0].tx_buf = command; | ||
80 | xfers[0].len = 2; | ||
81 | spi_message_add_tail(&xfers[0], &msg); | ||
82 | ++xfers; | ||
83 | |||
84 | for (idx = 0; idx < count; ++idx) { | ||
85 | if (rx_buf) | ||
86 | xfers[idx].rx_buf = &rx_buf[idx]; | ||
87 | if (tx_buf) | ||
88 | xfers[idx].tx_buf = &tx_buf[idx]; | ||
89 | xfers[idx].len = 2; | ||
90 | spi_message_add_tail(&xfers[idx], &msg); | ||
91 | } | ||
92 | |||
93 | ret = spi_sync(spi, &msg); | ||
94 | |||
95 | if (count == 1) | ||
96 | _rx_buf[0] = command[2]; | ||
97 | |||
98 | kfree(spi_data); | ||
99 | |||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | static int ad7879_spi_multi_read(struct device *dev, | ||
104 | u8 first_reg, u8 count, u16 *buf) | ||
105 | { | ||
106 | struct spi_device *spi = to_spi_device(dev); | ||
107 | |||
108 | return ad7879_spi_xfer(spi, AD7879_READCMD(first_reg), count, NULL, buf); | ||
109 | } | ||
110 | |||
111 | static int ad7879_spi_read(struct device *dev, u8 reg) | ||
112 | { | ||
113 | struct spi_device *spi = to_spi_device(dev); | ||
114 | u16 ret, dummy; | ||
115 | |||
116 | return ad7879_spi_xfer(spi, AD7879_READCMD(reg), 1, &dummy, &ret) ? : ret; | ||
117 | } | ||
118 | |||
119 | static int ad7879_spi_write(struct device *dev, u8 reg, u16 val) | ||
120 | { | ||
121 | struct spi_device *spi = to_spi_device(dev); | ||
122 | u16 dummy; | ||
123 | |||
124 | return ad7879_spi_xfer(spi, AD7879_WRITECMD(reg), 1, &val, &dummy); | ||
125 | } | ||
126 | |||
127 | static const struct ad7879_bus_ops ad7879_spi_bus_ops = { | ||
128 | .bustype = BUS_SPI, | ||
129 | .read = ad7879_spi_read, | ||
130 | .multi_read = ad7879_spi_multi_read, | ||
131 | .write = ad7879_spi_write, | ||
132 | }; | ||
133 | |||
134 | static int __devinit ad7879_spi_probe(struct spi_device *spi) | ||
135 | { | ||
136 | struct ad7879 *ts; | ||
137 | int err; | ||
138 | |||
139 | /* don't exceed max specified SPI CLK frequency */ | ||
140 | if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) { | ||
141 | dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | spi->bits_per_word = 16; | ||
146 | err = spi_setup(spi); | ||
147 | if (err) { | ||
148 | dev_dbg(&spi->dev, "spi master doesn't support 16 bits/word\n"); | ||
149 | return err; | ||
150 | } | ||
151 | |||
152 | ts = ad7879_probe(&spi->dev, AD7879_DEVID, spi->irq, &ad7879_spi_bus_ops); | ||
153 | if (IS_ERR(ts)) | ||
154 | return PTR_ERR(ts); | ||
155 | |||
156 | spi_set_drvdata(spi, ts); | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int __devexit ad7879_spi_remove(struct spi_device *spi) | ||
162 | { | ||
163 | struct ad7879 *ts = spi_get_drvdata(spi); | ||
164 | |||
165 | ad7879_remove(ts); | ||
166 | spi_set_drvdata(spi, NULL); | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static struct spi_driver ad7879_spi_driver = { | ||
172 | .driver = { | ||
173 | .name = "ad7879", | ||
174 | .bus = &spi_bus_type, | ||
175 | .owner = THIS_MODULE, | ||
176 | }, | ||
177 | .probe = ad7879_spi_probe, | ||
178 | .remove = __devexit_p(ad7879_spi_remove), | ||
179 | .suspend = ad7879_spi_suspend, | ||
180 | .resume = ad7879_spi_resume, | ||
181 | }; | ||
182 | |||
183 | static int __init ad7879_spi_init(void) | ||
184 | { | ||
185 | return spi_register_driver(&ad7879_spi_driver); | ||
186 | } | ||
187 | module_init(ad7879_spi_init); | ||
188 | |||
189 | static void __exit ad7879_spi_exit(void) | ||
190 | { | ||
191 | spi_unregister_driver(&ad7879_spi_driver); | ||
192 | } | ||
193 | module_exit(ad7879_spi_exit); | ||
194 | |||
195 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
196 | MODULE_DESCRIPTION("AD7879(-1) touchscreen SPI bus driver"); | ||
197 | MODULE_LICENSE("GPL"); | ||
198 | MODULE_ALIAS("spi:ad7879"); | ||
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index 794d070c6900..ba6f0bd1e762 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -1,25 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2008-2009 Michael Hennerich, Analog Devices Inc. | 2 | * AD7879/AD7889 based touchscreen and GPIO driver |
3 | * | 3 | * |
4 | * Description: AD7879/AD7889 based touchscreen, and GPIO driver | 4 | * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc. |
5 | * (I2C/SPI Interface) | ||
6 | * | 5 | * |
7 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 6 | * Licensed under the GPL-2 or later. |
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, see the file COPYING, or write | ||
21 | * to the Free Software Foundation, Inc., | ||
22 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
23 | * | 7 | * |
24 | * History: | 8 | * History: |
25 | * Copyright (c) 2005 David Brownell | 9 | * Copyright (c) 2005 David Brownell |
@@ -44,12 +28,12 @@ | |||
44 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
45 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
46 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
47 | #include <linux/workqueue.h> | ||
48 | #include <linux/spi/spi.h> | 31 | #include <linux/spi/spi.h> |
49 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
50 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
51 | 34 | ||
52 | #include <linux/spi/ad7879.h> | 35 | #include <linux/spi/ad7879.h> |
36 | #include "ad7879.h" | ||
53 | 37 | ||
54 | #define AD7879_REG_ZEROS 0 | 38 | #define AD7879_REG_ZEROS 0 |
55 | #define AD7879_REG_CTRL1 1 | 39 | #define AD7879_REG_CTRL1 1 |
@@ -120,30 +104,19 @@ enum { | |||
120 | #define MAX_12BIT ((1<<12)-1) | 104 | #define MAX_12BIT ((1<<12)-1) |
121 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) | 105 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) |
122 | 106 | ||
123 | #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) | ||
124 | #define AD7879_DEVID 0x7A | ||
125 | typedef struct spi_device bus_device; | ||
126 | #elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE) | ||
127 | #define AD7879_DEVID 0x79 | ||
128 | typedef struct i2c_client bus_device; | ||
129 | #endif | ||
130 | |||
131 | struct ad7879 { | 107 | struct ad7879 { |
132 | bus_device *bus; | 108 | const struct ad7879_bus_ops *bops; |
109 | |||
110 | struct device *dev; | ||
133 | struct input_dev *input; | 111 | struct input_dev *input; |
134 | struct work_struct work; | ||
135 | struct timer_list timer; | 112 | struct timer_list timer; |
136 | #ifdef CONFIG_GPIOLIB | 113 | #ifdef CONFIG_GPIOLIB |
137 | struct gpio_chip gc; | 114 | struct gpio_chip gc; |
138 | #endif | ||
139 | struct mutex mutex; | 115 | struct mutex mutex; |
140 | unsigned disabled:1; /* P: mutex */ | ||
141 | |||
142 | #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) | ||
143 | struct spi_message msg; | ||
144 | struct spi_transfer xfer[AD7879_NR_SENSE + 1]; | ||
145 | u16 cmd; | ||
146 | #endif | 116 | #endif |
117 | unsigned int irq; | ||
118 | bool disabled; /* P: input->mutex */ | ||
119 | bool suspended; /* P: input->mutex */ | ||
147 | u16 conversion_data[AD7879_NR_SENSE]; | 120 | u16 conversion_data[AD7879_NR_SENSE]; |
148 | char phys[32]; | 121 | char phys[32]; |
149 | u8 first_conversion_delay; | 122 | u8 first_conversion_delay; |
@@ -158,11 +131,22 @@ struct ad7879 { | |||
158 | u16 cmd_crtl3; | 131 | u16 cmd_crtl3; |
159 | }; | 132 | }; |
160 | 133 | ||
161 | static int ad7879_read(bus_device *, u8); | 134 | static int ad7879_read(struct ad7879 *ts, u8 reg) |
162 | static int ad7879_write(bus_device *, u8, u16); | 135 | { |
163 | static void ad7879_collect(struct ad7879 *); | 136 | return ts->bops->read(ts->dev, reg); |
137 | } | ||
138 | |||
139 | static int ad7879_multi_read(struct ad7879 *ts, u8 first_reg, u8 count, u16 *buf) | ||
140 | { | ||
141 | return ts->bops->multi_read(ts->dev, first_reg, count, buf); | ||
142 | } | ||
164 | 143 | ||
165 | static void ad7879_report(struct ad7879 *ts) | 144 | static int ad7879_write(struct ad7879 *ts, u8 reg, u16 val) |
145 | { | ||
146 | return ts->bops->write(ts->dev, reg, val); | ||
147 | } | ||
148 | |||
149 | static int ad7879_report(struct ad7879 *ts) | ||
166 | { | 150 | { |
167 | struct input_dev *input_dev = ts->input; | 151 | struct input_dev *input_dev = ts->input; |
168 | unsigned Rt; | 152 | unsigned Rt; |
@@ -175,12 +159,14 @@ static void ad7879_report(struct ad7879 *ts) | |||
175 | 159 | ||
176 | /* | 160 | /* |
177 | * The samples processed here are already preprocessed by the AD7879. | 161 | * The samples processed here are already preprocessed by the AD7879. |
178 | * The preprocessing function consists of a median and an averaging filter. | 162 | * The preprocessing function consists of a median and an averaging |
179 | * The combination of these two techniques provides a robust solution, | 163 | * filter. The combination of these two techniques provides a robust |
180 | * discarding the spurious noise in the signal and keeping only the data of interest. | 164 | * solution, discarding the spurious noise in the signal and keeping |
181 | * The size of both filters is programmable. (dev.platform_data, see linux/spi/ad7879.h) | 165 | * only the data of interest. The size of both filters is |
182 | * Other user-programmable conversion controls include variable acquisition time, | 166 | * programmable. (dev.platform_data, see linux/spi/ad7879.h) Other |
183 | * and first conversion delay. Up to 16 averages can be taken per conversion. | 167 | * user-programmable conversion controls include variable acquisition |
168 | * time, and first conversion delay. Up to 16 averages can be taken | ||
169 | * per conversion. | ||
184 | */ | 170 | */ |
185 | 171 | ||
186 | if (likely(x && z1)) { | 172 | if (likely(x && z1)) { |
@@ -189,21 +175,17 @@ static void ad7879_report(struct ad7879 *ts) | |||
189 | Rt /= z1; | 175 | Rt /= z1; |
190 | Rt = (Rt + 2047) >> 12; | 176 | Rt = (Rt + 2047) >> 12; |
191 | 177 | ||
178 | if (!timer_pending(&ts->timer)) | ||
179 | input_report_key(input_dev, BTN_TOUCH, 1); | ||
180 | |||
192 | input_report_abs(input_dev, ABS_X, x); | 181 | input_report_abs(input_dev, ABS_X, x); |
193 | input_report_abs(input_dev, ABS_Y, y); | 182 | input_report_abs(input_dev, ABS_Y, y); |
194 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | 183 | input_report_abs(input_dev, ABS_PRESSURE, Rt); |
195 | input_sync(input_dev); | 184 | input_sync(input_dev); |
185 | return 0; | ||
196 | } | 186 | } |
197 | } | ||
198 | |||
199 | static void ad7879_work(struct work_struct *work) | ||
200 | { | ||
201 | struct ad7879 *ts = container_of(work, struct ad7879, work); | ||
202 | 187 | ||
203 | /* use keventd context to read the result registers */ | 188 | return -EINVAL; |
204 | ad7879_collect(ts); | ||
205 | ad7879_report(ts); | ||
206 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | ||
207 | } | 189 | } |
208 | 190 | ||
209 | static void ad7879_ts_event_release(struct ad7879 *ts) | 191 | static void ad7879_ts_event_release(struct ad7879 *ts) |
@@ -211,6 +193,7 @@ static void ad7879_ts_event_release(struct ad7879 *ts) | |||
211 | struct input_dev *input_dev = ts->input; | 193 | struct input_dev *input_dev = ts->input; |
212 | 194 | ||
213 | input_report_abs(input_dev, ABS_PRESSURE, 0); | 195 | input_report_abs(input_dev, ABS_PRESSURE, 0); |
196 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
214 | input_sync(input_dev); | 197 | input_sync(input_dev); |
215 | } | 198 | } |
216 | 199 | ||
@@ -225,56 +208,98 @@ static irqreturn_t ad7879_irq(int irq, void *handle) | |||
225 | { | 208 | { |
226 | struct ad7879 *ts = handle; | 209 | struct ad7879 *ts = handle; |
227 | 210 | ||
228 | /* The repeated conversion sequencer controlled by TMR kicked off too fast. | 211 | ad7879_multi_read(ts, AD7879_REG_XPLUS, AD7879_NR_SENSE, ts->conversion_data); |
229 | * We ignore the last and process the sample sequence currently in the queue. | ||
230 | * It can't be older than 9.4ms | ||
231 | */ | ||
232 | 212 | ||
233 | if (!work_pending(&ts->work)) | 213 | if (!ad7879_report(ts)) |
234 | schedule_work(&ts->work); | 214 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); |
235 | 215 | ||
236 | return IRQ_HANDLED; | 216 | return IRQ_HANDLED; |
237 | } | 217 | } |
238 | 218 | ||
239 | static void ad7879_setup(struct ad7879 *ts) | 219 | static void __ad7879_enable(struct ad7879 *ts) |
240 | { | 220 | { |
241 | ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); | 221 | ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2); |
242 | ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3); | 222 | ad7879_write(ts, AD7879_REG_CTRL3, ts->cmd_crtl3); |
243 | ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1); | 223 | ad7879_write(ts, AD7879_REG_CTRL1, ts->cmd_crtl1); |
224 | |||
225 | enable_irq(ts->irq); | ||
244 | } | 226 | } |
245 | 227 | ||
246 | static void ad7879_disable(struct ad7879 *ts) | 228 | static void __ad7879_disable(struct ad7879 *ts) |
247 | { | 229 | { |
248 | mutex_lock(&ts->mutex); | 230 | disable_irq(ts->irq); |
231 | |||
232 | if (del_timer_sync(&ts->timer)) | ||
233 | ad7879_ts_event_release(ts); | ||
234 | |||
235 | ad7879_write(ts, AD7879_REG_CTRL2, AD7879_PM(AD7879_PM_SHUTDOWN)); | ||
236 | } | ||
249 | 237 | ||
250 | if (!ts->disabled) { | ||
251 | 238 | ||
252 | ts->disabled = 1; | 239 | static int ad7879_open(struct input_dev *input) |
253 | disable_irq(ts->bus->irq); | 240 | { |
241 | struct ad7879 *ts = input_get_drvdata(input); | ||
254 | 242 | ||
255 | cancel_work_sync(&ts->work); | 243 | /* protected by input->mutex */ |
244 | if (!ts->disabled && !ts->suspended) | ||
245 | __ad7879_enable(ts); | ||
256 | 246 | ||
257 | if (del_timer_sync(&ts->timer)) | 247 | return 0; |
258 | ad7879_ts_event_release(ts); | 248 | } |
259 | 249 | ||
260 | ad7879_write(ts->bus, AD7879_REG_CTRL2, | 250 | static void ad7879_close(struct input_dev* input) |
261 | AD7879_PM(AD7879_PM_SHUTDOWN)); | 251 | { |
262 | } | 252 | struct ad7879 *ts = input_get_drvdata(input); |
263 | 253 | ||
264 | mutex_unlock(&ts->mutex); | 254 | /* protected by input->mutex */ |
255 | if (!ts->disabled && !ts->suspended) | ||
256 | __ad7879_disable(ts); | ||
265 | } | 257 | } |
266 | 258 | ||
267 | static void ad7879_enable(struct ad7879 *ts) | 259 | void ad7879_suspend(struct ad7879 *ts) |
268 | { | 260 | { |
269 | mutex_lock(&ts->mutex); | 261 | mutex_lock(&ts->input->mutex); |
262 | |||
263 | if (!ts->suspended && !ts->disabled && ts->input->users) | ||
264 | __ad7879_disable(ts); | ||
265 | |||
266 | ts->suspended = true; | ||
270 | 267 | ||
271 | if (ts->disabled) { | 268 | mutex_unlock(&ts->input->mutex); |
272 | ad7879_setup(ts); | 269 | } |
273 | ts->disabled = 0; | 270 | EXPORT_SYMBOL(ad7879_suspend); |
274 | enable_irq(ts->bus->irq); | 271 | |
272 | void ad7879_resume(struct ad7879 *ts) | ||
273 | { | ||
274 | mutex_lock(&ts->input->mutex); | ||
275 | |||
276 | if (ts->suspended && !ts->disabled && ts->input->users) | ||
277 | __ad7879_enable(ts); | ||
278 | |||
279 | ts->suspended = false; | ||
280 | |||
281 | mutex_unlock(&ts->input->mutex); | ||
282 | } | ||
283 | EXPORT_SYMBOL(ad7879_resume); | ||
284 | |||
285 | static void ad7879_toggle(struct ad7879 *ts, bool disable) | ||
286 | { | ||
287 | mutex_lock(&ts->input->mutex); | ||
288 | |||
289 | if (!ts->suspended && ts->input->users != 0) { | ||
290 | |||
291 | if (disable) { | ||
292 | if (ts->disabled) | ||
293 | __ad7879_enable(ts); | ||
294 | } else { | ||
295 | if (!ts->disabled) | ||
296 | __ad7879_disable(ts); | ||
297 | } | ||
275 | } | 298 | } |
276 | 299 | ||
277 | mutex_unlock(&ts->mutex); | 300 | ts->disabled = disable; |
301 | |||
302 | mutex_unlock(&ts->input->mutex); | ||
278 | } | 303 | } |
279 | 304 | ||
280 | static ssize_t ad7879_disable_show(struct device *dev, | 305 | static ssize_t ad7879_disable_show(struct device *dev, |
@@ -297,10 +322,7 @@ static ssize_t ad7879_disable_store(struct device *dev, | |||
297 | if (error) | 322 | if (error) |
298 | return error; | 323 | return error; |
299 | 324 | ||
300 | if (val) | 325 | ad7879_toggle(ts, val); |
301 | ad7879_disable(ts); | ||
302 | else | ||
303 | ad7879_enable(ts); | ||
304 | 326 | ||
305 | return count; | 327 | return count; |
306 | } | 328 | } |
@@ -325,7 +347,7 @@ static int ad7879_gpio_direction_input(struct gpio_chip *chip, | |||
325 | 347 | ||
326 | mutex_lock(&ts->mutex); | 348 | mutex_lock(&ts->mutex); |
327 | ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL; | 349 | ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL; |
328 | err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); | 350 | err = ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2); |
329 | mutex_unlock(&ts->mutex); | 351 | mutex_unlock(&ts->mutex); |
330 | 352 | ||
331 | return err; | 353 | return err; |
@@ -345,7 +367,7 @@ static int ad7879_gpio_direction_output(struct gpio_chip *chip, | |||
345 | else | 367 | else |
346 | ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; | 368 | ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; |
347 | 369 | ||
348 | err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); | 370 | err = ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2); |
349 | mutex_unlock(&ts->mutex); | 371 | mutex_unlock(&ts->mutex); |
350 | 372 | ||
351 | return err; | 373 | return err; |
@@ -357,7 +379,7 @@ static int ad7879_gpio_get_value(struct gpio_chip *chip, unsigned gpio) | |||
357 | u16 val; | 379 | u16 val; |
358 | 380 | ||
359 | mutex_lock(&ts->mutex); | 381 | mutex_lock(&ts->mutex); |
360 | val = ad7879_read(ts->bus, AD7879_REG_CTRL2); | 382 | val = ad7879_read(ts, AD7879_REG_CTRL2); |
361 | mutex_unlock(&ts->mutex); | 383 | mutex_unlock(&ts->mutex); |
362 | 384 | ||
363 | return !!(val & AD7879_GPIO_DATA); | 385 | return !!(val & AD7879_GPIO_DATA); |
@@ -374,16 +396,17 @@ static void ad7879_gpio_set_value(struct gpio_chip *chip, | |||
374 | else | 396 | else |
375 | ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; | 397 | ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; |
376 | 398 | ||
377 | ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); | 399 | ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2); |
378 | mutex_unlock(&ts->mutex); | 400 | mutex_unlock(&ts->mutex); |
379 | } | 401 | } |
380 | 402 | ||
381 | static int __devinit ad7879_gpio_add(struct device *dev) | 403 | static int ad7879_gpio_add(struct ad7879 *ts, |
404 | const struct ad7879_platform_data *pdata) | ||
382 | { | 405 | { |
383 | struct ad7879 *ts = dev_get_drvdata(dev); | ||
384 | struct ad7879_platform_data *pdata = dev->platform_data; | ||
385 | int ret = 0; | 406 | int ret = 0; |
386 | 407 | ||
408 | mutex_init(&ts->mutex); | ||
409 | |||
387 | if (pdata->gpio_export) { | 410 | if (pdata->gpio_export) { |
388 | ts->gc.direction_input = ad7879_gpio_direction_input; | 411 | ts->gc.direction_input = ad7879_gpio_direction_input; |
389 | ts->gc.direction_output = ad7879_gpio_direction_output; | 412 | ts->gc.direction_output = ad7879_gpio_direction_output; |
@@ -394,72 +417,75 @@ static int __devinit ad7879_gpio_add(struct device *dev) | |||
394 | ts->gc.ngpio = 1; | 417 | ts->gc.ngpio = 1; |
395 | ts->gc.label = "AD7879-GPIO"; | 418 | ts->gc.label = "AD7879-GPIO"; |
396 | ts->gc.owner = THIS_MODULE; | 419 | ts->gc.owner = THIS_MODULE; |
397 | ts->gc.dev = dev; | 420 | ts->gc.dev = ts->dev; |
398 | 421 | ||
399 | ret = gpiochip_add(&ts->gc); | 422 | ret = gpiochip_add(&ts->gc); |
400 | if (ret) | 423 | if (ret) |
401 | dev_err(dev, "failed to register gpio %d\n", | 424 | dev_err(ts->dev, "failed to register gpio %d\n", |
402 | ts->gc.base); | 425 | ts->gc.base); |
403 | } | 426 | } |
404 | 427 | ||
405 | return ret; | 428 | return ret; |
406 | } | 429 | } |
407 | 430 | ||
408 | /* | 431 | static void ad7879_gpio_remove(struct ad7879 *ts) |
409 | * We mark ad7879_gpio_remove inline so there is a chance the code | ||
410 | * gets discarded when not needed. We can't do __devinit/__devexit | ||
411 | * markup since it is used in both probe and remove methods. | ||
412 | */ | ||
413 | static inline void ad7879_gpio_remove(struct device *dev) | ||
414 | { | 432 | { |
415 | struct ad7879 *ts = dev_get_drvdata(dev); | 433 | const struct ad7879_platform_data *pdata = ts->dev->platform_data; |
416 | struct ad7879_platform_data *pdata = dev->platform_data; | ||
417 | int ret; | 434 | int ret; |
418 | 435 | ||
419 | if (pdata->gpio_export) { | 436 | if (pdata->gpio_export) { |
420 | ret = gpiochip_remove(&ts->gc); | 437 | ret = gpiochip_remove(&ts->gc); |
421 | if (ret) | 438 | if (ret) |
422 | dev_err(dev, "failed to remove gpio %d\n", | 439 | dev_err(ts->dev, "failed to remove gpio %d\n", |
423 | ts->gc.base); | 440 | ts->gc.base); |
424 | } | 441 | } |
425 | } | 442 | } |
426 | #else | 443 | #else |
427 | static inline int ad7879_gpio_add(struct device *dev) | 444 | static inline int ad7879_gpio_add(struct ad7879 *ts, |
445 | const struct ad7879_platform_data *pdata) | ||
428 | { | 446 | { |
429 | return 0; | 447 | return 0; |
430 | } | 448 | } |
431 | 449 | ||
432 | static inline void ad7879_gpio_remove(struct device *dev) | 450 | static inline void ad7879_gpio_remove(struct ad7879 *ts) |
433 | { | 451 | { |
434 | } | 452 | } |
435 | #endif | 453 | #endif |
436 | 454 | ||
437 | static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | 455 | struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned int irq, |
456 | const struct ad7879_bus_ops *bops) | ||
438 | { | 457 | { |
458 | struct ad7879_platform_data *pdata = dev->platform_data; | ||
459 | struct ad7879 *ts; | ||
439 | struct input_dev *input_dev; | 460 | struct input_dev *input_dev; |
440 | struct ad7879_platform_data *pdata = bus->dev.platform_data; | ||
441 | int err; | 461 | int err; |
442 | u16 revid; | 462 | u16 revid; |
443 | 463 | ||
444 | if (!bus->irq) { | 464 | if (!irq) { |
445 | dev_err(&bus->dev, "no IRQ?\n"); | 465 | dev_err(dev, "no IRQ?\n"); |
446 | return -ENODEV; | 466 | err = -EINVAL; |
467 | goto err_out; | ||
447 | } | 468 | } |
448 | 469 | ||
449 | if (!pdata) { | 470 | if (!pdata) { |
450 | dev_err(&bus->dev, "no platform data?\n"); | 471 | dev_err(dev, "no platform data?\n"); |
451 | return -ENODEV; | 472 | err = -EINVAL; |
473 | goto err_out; | ||
452 | } | 474 | } |
453 | 475 | ||
476 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | ||
454 | input_dev = input_allocate_device(); | 477 | input_dev = input_allocate_device(); |
455 | if (!input_dev) | 478 | if (!ts || !input_dev) { |
456 | return -ENOMEM; | 479 | err = -ENOMEM; |
480 | goto err_free_mem; | ||
481 | } | ||
457 | 482 | ||
483 | ts->bops = bops; | ||
484 | ts->dev = dev; | ||
458 | ts->input = input_dev; | 485 | ts->input = input_dev; |
486 | ts->irq = irq; | ||
459 | 487 | ||
460 | setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts); | 488 | setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts); |
461 | INIT_WORK(&ts->work, ad7879_work); | ||
462 | mutex_init(&ts->mutex); | ||
463 | 489 | ||
464 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | 490 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; |
465 | ts->pressure_max = pdata->pressure_max ? : ~0; | 491 | ts->pressure_max = pdata->pressure_max ? : ~0; |
@@ -470,17 +496,26 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
470 | ts->pen_down_acc_interval = pdata->pen_down_acc_interval; | 496 | ts->pen_down_acc_interval = pdata->pen_down_acc_interval; |
471 | ts->median = pdata->median; | 497 | ts->median = pdata->median; |
472 | 498 | ||
473 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev)); | 499 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev)); |
474 | 500 | ||
475 | input_dev->name = "AD7879 Touchscreen"; | 501 | input_dev->name = "AD7879 Touchscreen"; |
476 | input_dev->phys = ts->phys; | 502 | input_dev->phys = ts->phys; |
477 | input_dev->dev.parent = &bus->dev; | 503 | input_dev->dev.parent = dev; |
504 | input_dev->id.bustype = bops->bustype; | ||
505 | |||
506 | input_dev->open = ad7879_open; | ||
507 | input_dev->close = ad7879_close; | ||
508 | |||
509 | input_set_drvdata(input_dev, ts); | ||
478 | 510 | ||
479 | __set_bit(EV_ABS, input_dev->evbit); | 511 | __set_bit(EV_ABS, input_dev->evbit); |
480 | __set_bit(ABS_X, input_dev->absbit); | 512 | __set_bit(ABS_X, input_dev->absbit); |
481 | __set_bit(ABS_Y, input_dev->absbit); | 513 | __set_bit(ABS_Y, input_dev->absbit); |
482 | __set_bit(ABS_PRESSURE, input_dev->absbit); | 514 | __set_bit(ABS_PRESSURE, input_dev->absbit); |
483 | 515 | ||
516 | __set_bit(EV_KEY, input_dev->evbit); | ||
517 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
518 | |||
484 | input_set_abs_params(input_dev, ABS_X, | 519 | input_set_abs_params(input_dev, ABS_X, |
485 | pdata->x_min ? : 0, | 520 | pdata->x_min ? : 0, |
486 | pdata->x_max ? : MAX_12BIT, | 521 | pdata->x_max ? : MAX_12BIT, |
@@ -492,17 +527,18 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
492 | input_set_abs_params(input_dev, ABS_PRESSURE, | 527 | input_set_abs_params(input_dev, ABS_PRESSURE, |
493 | pdata->pressure_min, pdata->pressure_max, 0, 0); | 528 | pdata->pressure_min, pdata->pressure_max, 0, 0); |
494 | 529 | ||
495 | err = ad7879_write(bus, AD7879_REG_CTRL2, AD7879_RESET); | 530 | err = ad7879_write(ts, AD7879_REG_CTRL2, AD7879_RESET); |
496 | |||
497 | if (err < 0) { | 531 | if (err < 0) { |
498 | dev_err(&bus->dev, "Failed to write %s\n", input_dev->name); | 532 | dev_err(dev, "Failed to write %s\n", input_dev->name); |
499 | goto err_free_mem; | 533 | goto err_free_mem; |
500 | } | 534 | } |
501 | 535 | ||
502 | revid = ad7879_read(bus, AD7879_REG_REVID); | 536 | revid = ad7879_read(ts, AD7879_REG_REVID); |
503 | 537 | input_dev->id.product = (revid & 0xff); | |
504 | if ((revid & 0xFF) != AD7879_DEVID) { | 538 | input_dev->id.version = revid >> 8; |
505 | dev_err(&bus->dev, "Failed to probe %s\n", input_dev->name); | 539 | if (input_dev->id.product != devid) { |
540 | dev_err(dev, "Failed to probe %s (%x vs %x)\n", | ||
541 | input_dev->name, devid, revid); | ||
506 | err = -ENODEV; | 542 | err = -ENODEV; |
507 | goto err_free_mem; | 543 | goto err_free_mem; |
508 | } | 544 | } |
@@ -524,21 +560,21 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
524 | AD7879_ACQ(ts->acquisition_time) | | 560 | AD7879_ACQ(ts->acquisition_time) | |
525 | AD7879_TMR(ts->pen_down_acc_interval); | 561 | AD7879_TMR(ts->pen_down_acc_interval); |
526 | 562 | ||
527 | ad7879_setup(ts); | 563 | err = request_threaded_irq(ts->irq, NULL, ad7879_irq, |
528 | 564 | IRQF_TRIGGER_FALLING, | |
529 | err = request_irq(bus->irq, ad7879_irq, | 565 | dev_name(dev), ts); |
530 | IRQF_TRIGGER_FALLING, bus->dev.driver->name, ts); | ||
531 | |||
532 | if (err) { | 566 | if (err) { |
533 | dev_err(&bus->dev, "irq %d busy?\n", bus->irq); | 567 | dev_err(dev, "irq %d busy?\n", ts->irq); |
534 | goto err_free_mem; | 568 | goto err_free_mem; |
535 | } | 569 | } |
536 | 570 | ||
537 | err = sysfs_create_group(&bus->dev.kobj, &ad7879_attr_group); | 571 | __ad7879_disable(ts); |
572 | |||
573 | err = sysfs_create_group(&dev->kobj, &ad7879_attr_group); | ||
538 | if (err) | 574 | if (err) |
539 | goto err_free_irq; | 575 | goto err_free_irq; |
540 | 576 | ||
541 | err = ad7879_gpio_add(&bus->dev); | 577 | err = ad7879_gpio_add(ts, pdata); |
542 | if (err) | 578 | if (err) |
543 | goto err_remove_attr; | 579 | goto err_remove_attr; |
544 | 580 | ||
@@ -546,324 +582,32 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
546 | if (err) | 582 | if (err) |
547 | goto err_remove_gpio; | 583 | goto err_remove_gpio; |
548 | 584 | ||
549 | dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n", | 585 | return ts; |
550 | revid >> 8, bus->irq); | ||
551 | |||
552 | return 0; | ||
553 | 586 | ||
554 | err_remove_gpio: | 587 | err_remove_gpio: |
555 | ad7879_gpio_remove(&bus->dev); | 588 | ad7879_gpio_remove(ts); |
556 | err_remove_attr: | 589 | err_remove_attr: |
557 | sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group); | 590 | sysfs_remove_group(&dev->kobj, &ad7879_attr_group); |
558 | err_free_irq: | 591 | err_free_irq: |
559 | free_irq(bus->irq, ts); | 592 | free_irq(ts->irq, ts); |
560 | err_free_mem: | 593 | err_free_mem: |
561 | input_free_device(input_dev); | 594 | input_free_device(input_dev); |
562 | |||
563 | return err; | ||
564 | } | ||
565 | |||
566 | static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts) | ||
567 | { | ||
568 | ad7879_gpio_remove(&bus->dev); | ||
569 | ad7879_disable(ts); | ||
570 | sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group); | ||
571 | free_irq(ts->bus->irq, ts); | ||
572 | input_unregister_device(ts->input); | ||
573 | dev_dbg(&bus->dev, "unregistered touchscreen\n"); | ||
574 | |||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | #ifdef CONFIG_PM | ||
579 | static int ad7879_suspend(bus_device *bus, pm_message_t message) | ||
580 | { | ||
581 | struct ad7879 *ts = dev_get_drvdata(&bus->dev); | ||
582 | |||
583 | ad7879_disable(ts); | ||
584 | |||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | static int ad7879_resume(bus_device *bus) | ||
589 | { | ||
590 | struct ad7879 *ts = dev_get_drvdata(&bus->dev); | ||
591 | |||
592 | ad7879_enable(ts); | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | #else | ||
597 | #define ad7879_suspend NULL | ||
598 | #define ad7879_resume NULL | ||
599 | #endif | ||
600 | |||
601 | #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) | ||
602 | #define MAX_SPI_FREQ_HZ 5000000 | ||
603 | #define AD7879_CMD_MAGIC 0xE000 | ||
604 | #define AD7879_CMD_READ (1 << 10) | ||
605 | #define AD7879_WRITECMD(reg) (AD7879_CMD_MAGIC | (reg & 0xF)) | ||
606 | #define AD7879_READCMD(reg) (AD7879_CMD_MAGIC | AD7879_CMD_READ | (reg & 0xF)) | ||
607 | |||
608 | struct ser_req { | ||
609 | u16 command; | ||
610 | u16 data; | ||
611 | struct spi_message msg; | ||
612 | struct spi_transfer xfer[2]; | ||
613 | }; | ||
614 | |||
615 | /* | ||
616 | * ad7879_read/write are only used for initial setup and for sysfs controls. | ||
617 | * The main traffic is done in ad7879_collect(). | ||
618 | */ | ||
619 | |||
620 | static int ad7879_read(struct spi_device *spi, u8 reg) | ||
621 | { | ||
622 | struct ser_req *req; | ||
623 | int status, ret; | ||
624 | |||
625 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
626 | if (!req) | ||
627 | return -ENOMEM; | ||
628 | |||
629 | spi_message_init(&req->msg); | ||
630 | |||
631 | req->command = (u16) AD7879_READCMD(reg); | ||
632 | req->xfer[0].tx_buf = &req->command; | ||
633 | req->xfer[0].len = 2; | ||
634 | |||
635 | req->xfer[1].rx_buf = &req->data; | ||
636 | req->xfer[1].len = 2; | ||
637 | |||
638 | spi_message_add_tail(&req->xfer[0], &req->msg); | ||
639 | spi_message_add_tail(&req->xfer[1], &req->msg); | ||
640 | |||
641 | status = spi_sync(spi, &req->msg); | ||
642 | ret = status ? : req->data; | ||
643 | |||
644 | kfree(req); | ||
645 | |||
646 | return ret; | ||
647 | } | ||
648 | |||
649 | static int ad7879_write(struct spi_device *spi, u8 reg, u16 val) | ||
650 | { | ||
651 | struct ser_req *req; | ||
652 | int status; | ||
653 | |||
654 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
655 | if (!req) | ||
656 | return -ENOMEM; | ||
657 | |||
658 | spi_message_init(&req->msg); | ||
659 | |||
660 | req->command = (u16) AD7879_WRITECMD(reg); | ||
661 | req->xfer[0].tx_buf = &req->command; | ||
662 | req->xfer[0].len = 2; | ||
663 | |||
664 | req->data = val; | ||
665 | req->xfer[1].tx_buf = &req->data; | ||
666 | req->xfer[1].len = 2; | ||
667 | |||
668 | spi_message_add_tail(&req->xfer[0], &req->msg); | ||
669 | spi_message_add_tail(&req->xfer[1], &req->msg); | ||
670 | |||
671 | status = spi_sync(spi, &req->msg); | ||
672 | |||
673 | kfree(req); | ||
674 | |||
675 | return status; | ||
676 | } | ||
677 | |||
678 | static void ad7879_collect(struct ad7879 *ts) | ||
679 | { | ||
680 | int status = spi_sync(ts->bus, &ts->msg); | ||
681 | |||
682 | if (status) | ||
683 | dev_err(&ts->bus->dev, "spi_sync --> %d\n", status); | ||
684 | } | ||
685 | |||
686 | static void ad7879_setup_ts_def_msg(struct ad7879 *ts) | ||
687 | { | ||
688 | struct spi_message *m; | ||
689 | int i; | ||
690 | |||
691 | ts->cmd = (u16) AD7879_READCMD(AD7879_REG_XPLUS); | ||
692 | |||
693 | m = &ts->msg; | ||
694 | spi_message_init(m); | ||
695 | ts->xfer[0].tx_buf = &ts->cmd; | ||
696 | ts->xfer[0].len = 2; | ||
697 | |||
698 | spi_message_add_tail(&ts->xfer[0], m); | ||
699 | |||
700 | for (i = 0; i < AD7879_NR_SENSE; i++) { | ||
701 | ts->xfer[i + 1].rx_buf = &ts->conversion_data[i]; | ||
702 | ts->xfer[i + 1].len = 2; | ||
703 | spi_message_add_tail(&ts->xfer[i + 1], m); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | static int __devinit ad7879_probe(struct spi_device *spi) | ||
708 | { | ||
709 | struct ad7879 *ts; | ||
710 | int error; | ||
711 | |||
712 | /* don't exceed max specified SPI CLK frequency */ | ||
713 | if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) { | ||
714 | dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz); | ||
715 | return -EINVAL; | ||
716 | } | ||
717 | |||
718 | ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL); | ||
719 | if (!ts) | ||
720 | return -ENOMEM; | ||
721 | |||
722 | dev_set_drvdata(&spi->dev, ts); | ||
723 | ts->bus = spi; | ||
724 | |||
725 | ad7879_setup_ts_def_msg(ts); | ||
726 | |||
727 | error = ad7879_construct(spi, ts); | ||
728 | if (error) { | ||
729 | dev_set_drvdata(&spi->dev, NULL); | ||
730 | kfree(ts); | ||
731 | } | ||
732 | |||
733 | return error; | ||
734 | } | ||
735 | |||
736 | static int __devexit ad7879_remove(struct spi_device *spi) | ||
737 | { | ||
738 | struct ad7879 *ts = dev_get_drvdata(&spi->dev); | ||
739 | |||
740 | ad7879_destroy(spi, ts); | ||
741 | dev_set_drvdata(&spi->dev, NULL); | ||
742 | kfree(ts); | 595 | kfree(ts); |
743 | 596 | err_out: | |
744 | return 0; | 597 | return ERR_PTR(err); |
745 | } | 598 | } |
599 | EXPORT_SYMBOL(ad7879_probe); | ||
746 | 600 | ||
747 | static struct spi_driver ad7879_driver = { | 601 | void ad7879_remove(struct ad7879 *ts) |
748 | .driver = { | ||
749 | .name = "ad7879", | ||
750 | .bus = &spi_bus_type, | ||
751 | .owner = THIS_MODULE, | ||
752 | }, | ||
753 | .probe = ad7879_probe, | ||
754 | .remove = __devexit_p(ad7879_remove), | ||
755 | .suspend = ad7879_suspend, | ||
756 | .resume = ad7879_resume, | ||
757 | }; | ||
758 | |||
759 | static int __init ad7879_init(void) | ||
760 | { | ||
761 | return spi_register_driver(&ad7879_driver); | ||
762 | } | ||
763 | module_init(ad7879_init); | ||
764 | |||
765 | static void __exit ad7879_exit(void) | ||
766 | { | ||
767 | spi_unregister_driver(&ad7879_driver); | ||
768 | } | ||
769 | module_exit(ad7879_exit); | ||
770 | |||
771 | #elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE) | ||
772 | |||
773 | /* All registers are word-sized. | ||
774 | * AD7879 uses a high-byte first convention. | ||
775 | */ | ||
776 | static int ad7879_read(struct i2c_client *client, u8 reg) | ||
777 | { | 602 | { |
778 | return swab16(i2c_smbus_read_word_data(client, reg)); | 603 | ad7879_gpio_remove(ts); |
779 | } | 604 | sysfs_remove_group(&ts->dev->kobj, &ad7879_attr_group); |
780 | 605 | free_irq(ts->irq, ts); | |
781 | static int ad7879_write(struct i2c_client *client, u8 reg, u16 val) | 606 | input_unregister_device(ts->input); |
782 | { | ||
783 | return i2c_smbus_write_word_data(client, reg, swab16(val)); | ||
784 | } | ||
785 | |||
786 | static void ad7879_collect(struct ad7879 *ts) | ||
787 | { | ||
788 | int i; | ||
789 | |||
790 | for (i = 0; i < AD7879_NR_SENSE; i++) | ||
791 | ts->conversion_data[i] = ad7879_read(ts->bus, | ||
792 | AD7879_REG_XPLUS + i); | ||
793 | } | ||
794 | |||
795 | static int __devinit ad7879_probe(struct i2c_client *client, | ||
796 | const struct i2c_device_id *id) | ||
797 | { | ||
798 | struct ad7879 *ts; | ||
799 | int error; | ||
800 | |||
801 | if (!i2c_check_functionality(client->adapter, | ||
802 | I2C_FUNC_SMBUS_WORD_DATA)) { | ||
803 | dev_err(&client->dev, "SMBUS Word Data not Supported\n"); | ||
804 | return -EIO; | ||
805 | } | ||
806 | |||
807 | ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL); | ||
808 | if (!ts) | ||
809 | return -ENOMEM; | ||
810 | |||
811 | i2c_set_clientdata(client, ts); | ||
812 | ts->bus = client; | ||
813 | |||
814 | error = ad7879_construct(client, ts); | ||
815 | if (error) { | ||
816 | i2c_set_clientdata(client, NULL); | ||
817 | kfree(ts); | ||
818 | } | ||
819 | |||
820 | return error; | ||
821 | } | ||
822 | |||
823 | static int __devexit ad7879_remove(struct i2c_client *client) | ||
824 | { | ||
825 | struct ad7879 *ts = dev_get_drvdata(&client->dev); | ||
826 | |||
827 | ad7879_destroy(client, ts); | ||
828 | i2c_set_clientdata(client, NULL); | ||
829 | kfree(ts); | 607 | kfree(ts); |
830 | |||
831 | return 0; | ||
832 | } | ||
833 | |||
834 | static const struct i2c_device_id ad7879_id[] = { | ||
835 | { "ad7879", 0 }, | ||
836 | { "ad7889", 0 }, | ||
837 | { } | ||
838 | }; | ||
839 | MODULE_DEVICE_TABLE(i2c, ad7879_id); | ||
840 | |||
841 | static struct i2c_driver ad7879_driver = { | ||
842 | .driver = { | ||
843 | .name = "ad7879", | ||
844 | .owner = THIS_MODULE, | ||
845 | }, | ||
846 | .probe = ad7879_probe, | ||
847 | .remove = __devexit_p(ad7879_remove), | ||
848 | .suspend = ad7879_suspend, | ||
849 | .resume = ad7879_resume, | ||
850 | .id_table = ad7879_id, | ||
851 | }; | ||
852 | |||
853 | static int __init ad7879_init(void) | ||
854 | { | ||
855 | return i2c_add_driver(&ad7879_driver); | ||
856 | } | ||
857 | module_init(ad7879_init); | ||
858 | |||
859 | static void __exit ad7879_exit(void) | ||
860 | { | ||
861 | i2c_del_driver(&ad7879_driver); | ||
862 | } | 608 | } |
863 | module_exit(ad7879_exit); | 609 | EXPORT_SYMBOL(ad7879_remove); |
864 | #endif | ||
865 | 610 | ||
866 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 611 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
867 | MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver"); | 612 | MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver"); |
868 | MODULE_LICENSE("GPL"); | 613 | MODULE_LICENSE("GPL"); |
869 | MODULE_ALIAS("spi:ad7879"); | ||
diff --git a/drivers/input/touchscreen/ad7879.h b/drivers/input/touchscreen/ad7879.h new file mode 100644 index 000000000000..6b45a27236c7 --- /dev/null +++ b/drivers/input/touchscreen/ad7879.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * AD7879/AD7889 touchscreen (bus interfaces) | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #ifndef _AD7879_H_ | ||
10 | #define _AD7879_H_ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | |||
14 | struct ad7879; | ||
15 | struct device; | ||
16 | |||
17 | struct ad7879_bus_ops { | ||
18 | u16 bustype; | ||
19 | int (*read)(struct device *dev, u8 reg); | ||
20 | int (*multi_read)(struct device *dev, u8 first_reg, u8 count, u16 *buf); | ||
21 | int (*write)(struct device *dev, u8 reg, u16 val); | ||
22 | }; | ||
23 | |||
24 | void ad7879_suspend(struct ad7879 *); | ||
25 | void ad7879_resume(struct ad7879 *); | ||
26 | struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned irq, | ||
27 | const struct ad7879_bus_ops *bops); | ||
28 | void ad7879_remove(struct ad7879 *); | ||
29 | |||
30 | #endif | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 52d2ca147d8f..14ea54b78e46 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -17,9 +17,11 @@ | |||
17 | * it under the terms of the GNU General Public License version 2 as | 17 | * it under the terms of the GNU General Public License version 2 as |
18 | * published by the Free Software Foundation. | 18 | * published by the Free Software Foundation. |
19 | */ | 19 | */ |
20 | #include <linux/types.h> | ||
20 | #include <linux/hwmon.h> | 21 | #include <linux/hwmon.h> |
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
22 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/sched.h> | ||
23 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
24 | #include <linux/input.h> | 26 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
@@ -27,6 +29,7 @@ | |||
27 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
28 | #include <linux/spi/spi.h> | 30 | #include <linux/spi/spi.h> |
29 | #include <linux/spi/ads7846.h> | 31 | #include <linux/spi/ads7846.h> |
32 | #include <linux/regulator/consumer.h> | ||
30 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
31 | 34 | ||
32 | /* | 35 | /* |
@@ -35,6 +38,7 @@ | |||
35 | * TSC2046 is just newer ads7846 silicon. | 38 | * TSC2046 is just newer ads7846 silicon. |
36 | * Support for ads7843 tested on Atmel at91sam926x-EK. | 39 | * Support for ads7843 tested on Atmel at91sam926x-EK. |
37 | * Support for ads7845 has only been stubbed in. | 40 | * Support for ads7845 has only been stubbed in. |
41 | * Support for Analog Devices AD7873 and AD7843 tested. | ||
38 | * | 42 | * |
39 | * IRQ handling needs a workaround because of a shortcoming in handling | 43 | * IRQ handling needs a workaround because of a shortcoming in handling |
40 | * edge triggered IRQs on some platforms like the OMAP1/2. These | 44 | * edge triggered IRQs on some platforms like the OMAP1/2. These |
@@ -50,22 +54,25 @@ | |||
50 | * files. | 54 | * files. |
51 | */ | 55 | */ |
52 | 56 | ||
53 | #define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */ | 57 | #define TS_POLL_DELAY 1 /* ms delay before the first sample */ |
54 | #define TS_POLL_PERIOD (5 * 1000000) /* ns delay between samples */ | 58 | #define TS_POLL_PERIOD 5 /* ms delay between samples */ |
55 | 59 | ||
56 | /* this driver doesn't aim at the peak continuous sample rate */ | 60 | /* this driver doesn't aim at the peak continuous sample rate */ |
57 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) | 61 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) |
58 | 62 | ||
59 | struct ts_event { | 63 | struct ts_event { |
60 | /* For portability, we can't read 12 bit values using SPI (which | 64 | /* |
61 | * would make the controller deliver them as native byteorder u16 | 65 | * For portability, we can't read 12 bit values using SPI (which |
66 | * would make the controller deliver them as native byte order u16 | ||
62 | * with msbs zeroed). Instead, we read them as two 8-bit values, | 67 | * with msbs zeroed). Instead, we read them as two 8-bit values, |
63 | * *** WHICH NEED BYTESWAPPING *** and range adjustment. | 68 | * *** WHICH NEED BYTESWAPPING *** and range adjustment. |
64 | */ | 69 | */ |
65 | u16 x; | 70 | u16 x; |
66 | u16 y; | 71 | u16 y; |
67 | u16 z1, z2; | 72 | u16 z1, z2; |
68 | int ignore; | 73 | bool ignore; |
74 | u8 x_buf[3]; | ||
75 | u8 y_buf[3]; | ||
69 | }; | 76 | }; |
70 | 77 | ||
71 | /* | 78 | /* |
@@ -77,6 +84,8 @@ struct ads7846_packet { | |||
77 | u8 read_x, read_y, read_z1, read_z2, pwrdown; | 84 | u8 read_x, read_y, read_z1, read_z2, pwrdown; |
78 | u16 dummy; /* for the pwrdown read */ | 85 | u16 dummy; /* for the pwrdown read */ |
79 | struct ts_event tc; | 86 | struct ts_event tc; |
87 | /* for ads7845 with mpc5121 psc spi we use 3-byte buffers */ | ||
88 | u8 read_x_cmd[3], read_y_cmd[3], pwrdown_cmd[3]; | ||
80 | }; | 89 | }; |
81 | 90 | ||
82 | struct ads7846 { | 91 | struct ads7846 { |
@@ -85,6 +94,7 @@ struct ads7846 { | |||
85 | char name[32]; | 94 | char name[32]; |
86 | 95 | ||
87 | struct spi_device *spi; | 96 | struct spi_device *spi; |
97 | struct regulator *reg; | ||
88 | 98 | ||
89 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) | 99 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) |
90 | struct attribute_group *attr_group; | 100 | struct attribute_group *attr_group; |
@@ -103,8 +113,11 @@ struct ads7846 { | |||
103 | 113 | ||
104 | struct spi_transfer xfer[18]; | 114 | struct spi_transfer xfer[18]; |
105 | struct spi_message msg[5]; | 115 | struct spi_message msg[5]; |
106 | struct spi_message *last_msg; | 116 | int msg_count; |
107 | int msg_idx; | 117 | wait_queue_head_t wait; |
118 | |||
119 | bool pendown; | ||
120 | |||
108 | int read_cnt; | 121 | int read_cnt; |
109 | int read_rep; | 122 | int read_rep; |
110 | int last_read; | 123 | int last_read; |
@@ -115,14 +128,10 @@ struct ads7846 { | |||
115 | 128 | ||
116 | u16 penirq_recheck_delay_usecs; | 129 | u16 penirq_recheck_delay_usecs; |
117 | 130 | ||
118 | spinlock_t lock; | 131 | struct mutex lock; |
119 | struct hrtimer timer; | 132 | bool stopped; /* P: lock */ |
120 | unsigned pendown:1; /* P: lock */ | 133 | bool disabled; /* P: lock */ |
121 | unsigned pending:1; /* P: lock */ | 134 | bool suspended; /* P: lock */ |
122 | // FIXME remove "irq_disabled" | ||
123 | unsigned irq_disabled:1; /* P: lock */ | ||
124 | unsigned disabled:1; | ||
125 | unsigned is_suspended:1; | ||
126 | 135 | ||
127 | int (*filter)(void *data, int data_idx, int *val); | 136 | int (*filter)(void *data, int data_idx, int *val); |
128 | void *filter_data; | 137 | void *filter_data; |
@@ -158,7 +167,7 @@ struct ads7846 { | |||
158 | #define ADS_12_BIT (0 << 3) | 167 | #define ADS_12_BIT (0 << 3) |
159 | #define ADS_SER (1 << 2) /* non-differential */ | 168 | #define ADS_SER (1 << 2) /* non-differential */ |
160 | #define ADS_DFR (0 << 2) /* differential */ | 169 | #define ADS_DFR (0 << 2) /* differential */ |
161 | #define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */ | 170 | #define ADS_PD10_PDOWN (0 << 0) /* low power mode + penirq */ |
162 | #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ | 171 | #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ |
163 | #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ | 172 | #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ |
164 | #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ | 173 | #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ |
@@ -186,6 +195,78 @@ struct ads7846 { | |||
186 | #define REF_ON (READ_12BIT_DFR(x, 1, 1)) | 195 | #define REF_ON (READ_12BIT_DFR(x, 1, 1)) |
187 | #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) | 196 | #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) |
188 | 197 | ||
198 | /* Must be called with ts->lock held */ | ||
199 | static void ads7846_stop(struct ads7846 *ts) | ||
200 | { | ||
201 | if (!ts->disabled && !ts->suspended) { | ||
202 | /* Signal IRQ thread to stop polling and disable the handler. */ | ||
203 | ts->stopped = true; | ||
204 | mb(); | ||
205 | wake_up(&ts->wait); | ||
206 | disable_irq(ts->spi->irq); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* Must be called with ts->lock held */ | ||
211 | static void ads7846_restart(struct ads7846 *ts) | ||
212 | { | ||
213 | if (!ts->disabled && !ts->suspended) { | ||
214 | /* Tell IRQ thread that it may poll the device. */ | ||
215 | ts->stopped = false; | ||
216 | mb(); | ||
217 | enable_irq(ts->spi->irq); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /* Must be called with ts->lock held */ | ||
222 | static void __ads7846_disable(struct ads7846 *ts) | ||
223 | { | ||
224 | ads7846_stop(ts); | ||
225 | regulator_disable(ts->reg); | ||
226 | |||
227 | /* | ||
228 | * We know the chip's in low power mode since we always | ||
229 | * leave it that way after every request | ||
230 | */ | ||
231 | } | ||
232 | |||
233 | /* Must be called with ts->lock held */ | ||
234 | static void __ads7846_enable(struct ads7846 *ts) | ||
235 | { | ||
236 | regulator_enable(ts->reg); | ||
237 | ads7846_restart(ts); | ||
238 | } | ||
239 | |||
240 | static void ads7846_disable(struct ads7846 *ts) | ||
241 | { | ||
242 | mutex_lock(&ts->lock); | ||
243 | |||
244 | if (!ts->disabled) { | ||
245 | |||
246 | if (!ts->suspended) | ||
247 | __ads7846_disable(ts); | ||
248 | |||
249 | ts->disabled = true; | ||
250 | } | ||
251 | |||
252 | mutex_unlock(&ts->lock); | ||
253 | } | ||
254 | |||
255 | static void ads7846_enable(struct ads7846 *ts) | ||
256 | { | ||
257 | mutex_lock(&ts->lock); | ||
258 | |||
259 | if (ts->disabled) { | ||
260 | |||
261 | ts->disabled = false; | ||
262 | |||
263 | if (!ts->suspended) | ||
264 | __ads7846_enable(ts); | ||
265 | } | ||
266 | |||
267 | mutex_unlock(&ts->lock); | ||
268 | } | ||
269 | |||
189 | /*--------------------------------------------------------------------------*/ | 270 | /*--------------------------------------------------------------------------*/ |
190 | 271 | ||
191 | /* | 272 | /* |
@@ -204,23 +285,23 @@ struct ser_req { | |||
204 | struct spi_transfer xfer[6]; | 285 | struct spi_transfer xfer[6]; |
205 | }; | 286 | }; |
206 | 287 | ||
207 | static void ads7846_enable(struct ads7846 *ts); | 288 | struct ads7845_ser_req { |
208 | static void ads7846_disable(struct ads7846 *ts); | 289 | u8 command[3]; |
209 | 290 | u8 pwrdown[3]; | |
210 | static int device_suspended(struct device *dev) | 291 | u8 sample[3]; |
211 | { | 292 | struct spi_message msg; |
212 | struct ads7846 *ts = dev_get_drvdata(dev); | 293 | struct spi_transfer xfer[2]; |
213 | return ts->is_suspended || ts->disabled; | 294 | }; |
214 | } | ||
215 | 295 | ||
216 | static int ads7846_read12_ser(struct device *dev, unsigned command) | 296 | static int ads7846_read12_ser(struct device *dev, unsigned command) |
217 | { | 297 | { |
218 | struct spi_device *spi = to_spi_device(dev); | 298 | struct spi_device *spi = to_spi_device(dev); |
219 | struct ads7846 *ts = dev_get_drvdata(dev); | 299 | struct ads7846 *ts = dev_get_drvdata(dev); |
220 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 300 | struct ser_req *req; |
221 | int status; | 301 | int status; |
222 | int use_internal; | 302 | int use_internal; |
223 | 303 | ||
304 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
224 | if (!req) | 305 | if (!req) |
225 | return -ENOMEM; | 306 | return -ENOMEM; |
226 | 307 | ||
@@ -267,11 +348,11 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
267 | CS_CHANGE(req->xfer[5]); | 348 | CS_CHANGE(req->xfer[5]); |
268 | spi_message_add_tail(&req->xfer[5], &req->msg); | 349 | spi_message_add_tail(&req->xfer[5], &req->msg); |
269 | 350 | ||
270 | ts->irq_disabled = 1; | 351 | mutex_lock(&ts->lock); |
271 | disable_irq(spi->irq); | 352 | ads7846_stop(ts); |
272 | status = spi_sync(spi, &req->msg); | 353 | status = spi_sync(spi, &req->msg); |
273 | ts->irq_disabled = 0; | 354 | ads7846_restart(ts); |
274 | enable_irq(spi->irq); | 355 | mutex_unlock(&ts->lock); |
275 | 356 | ||
276 | if (status == 0) { | 357 | if (status == 0) { |
277 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ | 358 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ |
@@ -284,6 +365,42 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
284 | return status; | 365 | return status; |
285 | } | 366 | } |
286 | 367 | ||
368 | static int ads7845_read12_ser(struct device *dev, unsigned command) | ||
369 | { | ||
370 | struct spi_device *spi = to_spi_device(dev); | ||
371 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
372 | struct ads7845_ser_req *req; | ||
373 | int status; | ||
374 | |||
375 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
376 | if (!req) | ||
377 | return -ENOMEM; | ||
378 | |||
379 | spi_message_init(&req->msg); | ||
380 | |||
381 | req->command[0] = (u8) command; | ||
382 | req->xfer[0].tx_buf = req->command; | ||
383 | req->xfer[0].rx_buf = req->sample; | ||
384 | req->xfer[0].len = 3; | ||
385 | spi_message_add_tail(&req->xfer[0], &req->msg); | ||
386 | |||
387 | mutex_lock(&ts->lock); | ||
388 | ads7846_stop(ts); | ||
389 | status = spi_sync(spi, &req->msg); | ||
390 | ads7846_restart(ts); | ||
391 | mutex_unlock(&ts->lock); | ||
392 | |||
393 | if (status == 0) { | ||
394 | /* BE12 value, then padding */ | ||
395 | status = be16_to_cpu(*((u16 *)&req->sample[1])); | ||
396 | status = status >> 3; | ||
397 | status &= 0x0fff; | ||
398 | } | ||
399 | |||
400 | kfree(req); | ||
401 | return status; | ||
402 | } | ||
403 | |||
287 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) | 404 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) |
288 | 405 | ||
289 | #define SHOW(name, var, adjust) static ssize_t \ | 406 | #define SHOW(name, var, adjust) static ssize_t \ |
@@ -324,6 +441,7 @@ static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) | |||
324 | /* external resistors may scale vAUX into 0..vREF */ | 441 | /* external resistors may scale vAUX into 0..vREF */ |
325 | retval *= ts->vref_mv; | 442 | retval *= ts->vref_mv; |
326 | retval = retval >> 12; | 443 | retval = retval >> 12; |
444 | |||
327 | return retval; | 445 | return retval; |
328 | } | 446 | } |
329 | 447 | ||
@@ -334,13 +452,13 @@ static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v) | |||
334 | /* ads7846 has a resistor ladder to scale this signal down */ | 452 | /* ads7846 has a resistor ladder to scale this signal down */ |
335 | if (ts->model == 7846) | 453 | if (ts->model == 7846) |
336 | retval *= 4; | 454 | retval *= 4; |
455 | |||
337 | return retval; | 456 | return retval; |
338 | } | 457 | } |
339 | 458 | ||
340 | SHOW(in0_input, vaux, vaux_adjust) | 459 | SHOW(in0_input, vaux, vaux_adjust) |
341 | SHOW(in1_input, vbatt, vbatt_adjust) | 460 | SHOW(in1_input, vbatt, vbatt_adjust) |
342 | 461 | ||
343 | |||
344 | static struct attribute *ads7846_attributes[] = { | 462 | static struct attribute *ads7846_attributes[] = { |
345 | &dev_attr_temp0.attr, | 463 | &dev_attr_temp0.attr, |
346 | &dev_attr_temp1.attr, | 464 | &dev_attr_temp1.attr, |
@@ -448,17 +566,12 @@ static inline void ads784x_hwmon_unregister(struct spi_device *spi, | |||
448 | } | 566 | } |
449 | #endif | 567 | #endif |
450 | 568 | ||
451 | static int is_pen_down(struct device *dev) | ||
452 | { | ||
453 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
454 | |||
455 | return ts->pendown; | ||
456 | } | ||
457 | |||
458 | static ssize_t ads7846_pen_down_show(struct device *dev, | 569 | static ssize_t ads7846_pen_down_show(struct device *dev, |
459 | struct device_attribute *attr, char *buf) | 570 | struct device_attribute *attr, char *buf) |
460 | { | 571 | { |
461 | return sprintf(buf, "%u\n", is_pen_down(dev)); | 572 | struct ads7846 *ts = dev_get_drvdata(dev); |
573 | |||
574 | return sprintf(buf, "%u\n", ts->pendown); | ||
462 | } | 575 | } |
463 | 576 | ||
464 | static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); | 577 | static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); |
@@ -466,7 +579,7 @@ static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); | |||
466 | static ssize_t ads7846_disable_show(struct device *dev, | 579 | static ssize_t ads7846_disable_show(struct device *dev, |
467 | struct device_attribute *attr, char *buf) | 580 | struct device_attribute *attr, char *buf) |
468 | { | 581 | { |
469 | struct ads7846 *ts = dev_get_drvdata(dev); | 582 | struct ads7846 *ts = dev_get_drvdata(dev); |
470 | 583 | ||
471 | return sprintf(buf, "%u\n", ts->disabled); | 584 | return sprintf(buf, "%u\n", ts->disabled); |
472 | } | 585 | } |
@@ -481,15 +594,11 @@ static ssize_t ads7846_disable_store(struct device *dev, | |||
481 | if (strict_strtoul(buf, 10, &i)) | 594 | if (strict_strtoul(buf, 10, &i)) |
482 | return -EINVAL; | 595 | return -EINVAL; |
483 | 596 | ||
484 | spin_lock_irq(&ts->lock); | ||
485 | |||
486 | if (i) | 597 | if (i) |
487 | ads7846_disable(ts); | 598 | ads7846_disable(ts); |
488 | else | 599 | else |
489 | ads7846_enable(ts); | 600 | ads7846_enable(ts); |
490 | 601 | ||
491 | spin_unlock_irq(&ts->lock); | ||
492 | |||
493 | return count; | 602 | return count; |
494 | } | 603 | } |
495 | 604 | ||
@@ -519,28 +628,153 @@ static void null_wait_for_sync(void) | |||
519 | { | 628 | { |
520 | } | 629 | } |
521 | 630 | ||
522 | /* | 631 | static int ads7846_debounce_filter(void *ads, int data_idx, int *val) |
523 | * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, | 632 | { |
524 | * to retrieve touchscreen status. | 633 | struct ads7846 *ts = ads; |
525 | * | 634 | |
526 | * The SPI transfer completion callback does the real work. It reports | 635 | if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { |
527 | * touchscreen events and reactivates the timer (or IRQ) as appropriate. | 636 | /* Start over collecting consistent readings. */ |
528 | */ | 637 | ts->read_rep = 0; |
638 | /* | ||
639 | * Repeat it, if this was the first read or the read | ||
640 | * wasn't consistent enough. | ||
641 | */ | ||
642 | if (ts->read_cnt < ts->debounce_max) { | ||
643 | ts->last_read = *val; | ||
644 | ts->read_cnt++; | ||
645 | return ADS7846_FILTER_REPEAT; | ||
646 | } else { | ||
647 | /* | ||
648 | * Maximum number of debouncing reached and still | ||
649 | * not enough number of consistent readings. Abort | ||
650 | * the whole sample, repeat it in the next sampling | ||
651 | * period. | ||
652 | */ | ||
653 | ts->read_cnt = 0; | ||
654 | return ADS7846_FILTER_IGNORE; | ||
655 | } | ||
656 | } else { | ||
657 | if (++ts->read_rep > ts->debounce_rep) { | ||
658 | /* | ||
659 | * Got a good reading for this coordinate, | ||
660 | * go for the next one. | ||
661 | */ | ||
662 | ts->read_cnt = 0; | ||
663 | ts->read_rep = 0; | ||
664 | return ADS7846_FILTER_OK; | ||
665 | } else { | ||
666 | /* Read more values that are consistent. */ | ||
667 | ts->read_cnt++; | ||
668 | return ADS7846_FILTER_REPEAT; | ||
669 | } | ||
670 | } | ||
671 | } | ||
672 | |||
673 | static int ads7846_no_filter(void *ads, int data_idx, int *val) | ||
674 | { | ||
675 | return ADS7846_FILTER_OK; | ||
676 | } | ||
677 | |||
678 | static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m) | ||
679 | { | ||
680 | struct spi_transfer *t = | ||
681 | list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
682 | |||
683 | if (ts->model == 7845) { | ||
684 | return be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3; | ||
685 | } else { | ||
686 | /* | ||
687 | * adjust: on-wire is a must-ignore bit, a BE12 value, then | ||
688 | * padding; built from two 8 bit values written msb-first. | ||
689 | */ | ||
690 | return be16_to_cpup((__be16 *)t->rx_buf) >> 3; | ||
691 | } | ||
692 | } | ||
693 | |||
694 | static void ads7846_update_value(struct spi_message *m, int val) | ||
695 | { | ||
696 | struct spi_transfer *t = | ||
697 | list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
698 | |||
699 | *(u16 *)t->rx_buf = val; | ||
700 | } | ||
701 | |||
702 | static void ads7846_read_state(struct ads7846 *ts) | ||
703 | { | ||
704 | struct ads7846_packet *packet = ts->packet; | ||
705 | struct spi_message *m; | ||
706 | int msg_idx = 0; | ||
707 | int val; | ||
708 | int action; | ||
709 | int error; | ||
710 | |||
711 | while (msg_idx < ts->msg_count) { | ||
712 | |||
713 | ts->wait_for_sync(); | ||
714 | |||
715 | m = &ts->msg[msg_idx]; | ||
716 | error = spi_sync(ts->spi, m); | ||
717 | if (error) { | ||
718 | dev_err(&ts->spi->dev, "spi_async --> %d\n", error); | ||
719 | packet->tc.ignore = true; | ||
720 | return; | ||
721 | } | ||
722 | |||
723 | /* | ||
724 | * Last message is power down request, no need to convert | ||
725 | * or filter the value. | ||
726 | */ | ||
727 | if (msg_idx < ts->msg_count - 1) { | ||
728 | |||
729 | val = ads7846_get_value(ts, m); | ||
730 | |||
731 | action = ts->filter(ts->filter_data, msg_idx, &val); | ||
732 | switch (action) { | ||
733 | case ADS7846_FILTER_REPEAT: | ||
734 | continue; | ||
735 | |||
736 | case ADS7846_FILTER_IGNORE: | ||
737 | packet->tc.ignore = true; | ||
738 | msg_idx = ts->msg_count - 1; | ||
739 | continue; | ||
740 | |||
741 | case ADS7846_FILTER_OK: | ||
742 | ads7846_update_value(m, val); | ||
743 | packet->tc.ignore = false; | ||
744 | msg_idx++; | ||
745 | break; | ||
746 | |||
747 | default: | ||
748 | BUG(); | ||
749 | } | ||
750 | } else { | ||
751 | msg_idx++; | ||
752 | } | ||
753 | } | ||
754 | } | ||
529 | 755 | ||
530 | static void ads7846_rx(void *ads) | 756 | static void ads7846_report_state(struct ads7846 *ts) |
531 | { | 757 | { |
532 | struct ads7846 *ts = ads; | 758 | struct ads7846_packet *packet = ts->packet; |
533 | struct ads7846_packet *packet = ts->packet; | 759 | unsigned int Rt; |
534 | unsigned Rt; | 760 | u16 x, y, z1, z2; |
535 | u16 x, y, z1, z2; | ||
536 | 761 | ||
537 | /* ads7846_rx_val() did in-place conversion (including byteswap) from | 762 | /* |
538 | * on-the-wire format as part of debouncing to get stable readings. | 763 | * ads7846_get_value() does in-place conversion (including byte swap) |
764 | * from on-the-wire format as part of debouncing to get stable | ||
765 | * readings. | ||
539 | */ | 766 | */ |
540 | x = packet->tc.x; | 767 | if (ts->model == 7845) { |
541 | y = packet->tc.y; | 768 | x = *(u16 *)packet->tc.x_buf; |
542 | z1 = packet->tc.z1; | 769 | y = *(u16 *)packet->tc.y_buf; |
543 | z2 = packet->tc.z2; | 770 | z1 = 0; |
771 | z2 = 0; | ||
772 | } else { | ||
773 | x = packet->tc.x; | ||
774 | y = packet->tc.y; | ||
775 | z1 = packet->tc.z1; | ||
776 | z2 = packet->tc.z2; | ||
777 | } | ||
544 | 778 | ||
545 | /* range filtering */ | 779 | /* range filtering */ |
546 | if (x == MAX_12BIT) | 780 | if (x == MAX_12BIT) |
@@ -548,6 +782,12 @@ static void ads7846_rx(void *ads) | |||
548 | 782 | ||
549 | if (ts->model == 7843) { | 783 | if (ts->model == 7843) { |
550 | Rt = ts->pressure_max / 2; | 784 | Rt = ts->pressure_max / 2; |
785 | } else if (ts->model == 7845) { | ||
786 | if (get_pendown_state(ts)) | ||
787 | Rt = ts->pressure_max / 2; | ||
788 | else | ||
789 | Rt = 0; | ||
790 | dev_vdbg(&ts->spi->dev, "x/y: %d/%d, PD %d\n", x, y, Rt); | ||
551 | } else if (likely(x && z1)) { | 791 | } else if (likely(x && z1)) { |
552 | /* compute touch pressure resistance using equation #2 */ | 792 | /* compute touch pressure resistance using equation #2 */ |
553 | Rt = z2; | 793 | Rt = z2; |
@@ -560,19 +800,19 @@ static void ads7846_rx(void *ads) | |||
560 | Rt = 0; | 800 | Rt = 0; |
561 | } | 801 | } |
562 | 802 | ||
563 | /* Sample found inconsistent by debouncing or pressure is beyond | 803 | /* |
804 | * Sample found inconsistent by debouncing or pressure is beyond | ||
564 | * the maximum. Don't report it to user space, repeat at least | 805 | * the maximum. Don't report it to user space, repeat at least |
565 | * once more the measurement | 806 | * once more the measurement |
566 | */ | 807 | */ |
567 | if (packet->tc.ignore || Rt > ts->pressure_max) { | 808 | if (packet->tc.ignore || Rt > ts->pressure_max) { |
568 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", | 809 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", |
569 | packet->tc.ignore, Rt); | 810 | packet->tc.ignore, Rt); |
570 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | ||
571 | HRTIMER_MODE_REL); | ||
572 | return; | 811 | return; |
573 | } | 812 | } |
574 | 813 | ||
575 | /* Maybe check the pendown state before reporting. This discards | 814 | /* |
815 | * Maybe check the pendown state before reporting. This discards | ||
576 | * false readings when the pen is lifted. | 816 | * false readings when the pen is lifted. |
577 | */ | 817 | */ |
578 | if (ts->penirq_recheck_delay_usecs) { | 818 | if (ts->penirq_recheck_delay_usecs) { |
@@ -581,8 +821,9 @@ static void ads7846_rx(void *ads) | |||
581 | Rt = 0; | 821 | Rt = 0; |
582 | } | 822 | } |
583 | 823 | ||
584 | /* NOTE: We can't rely on the pressure to determine the pen down | 824 | /* |
585 | * state, even this controller has a pressure sensor. The pressure | 825 | * NOTE: We can't rely on the pressure to determine the pen down |
826 | * state, even this controller has a pressure sensor. The pressure | ||
586 | * value can fluctuate for quite a while after lifting the pen and | 827 | * value can fluctuate for quite a while after lifting the pen and |
587 | * in some cases may not even settle at the expected value. | 828 | * in some cases may not even settle at the expected value. |
588 | * | 829 | * |
@@ -592,15 +833,15 @@ static void ads7846_rx(void *ads) | |||
592 | if (Rt) { | 833 | if (Rt) { |
593 | struct input_dev *input = ts->input; | 834 | struct input_dev *input = ts->input; |
594 | 835 | ||
836 | if (ts->swap_xy) | ||
837 | swap(x, y); | ||
838 | |||
595 | if (!ts->pendown) { | 839 | if (!ts->pendown) { |
596 | input_report_key(input, BTN_TOUCH, 1); | 840 | input_report_key(input, BTN_TOUCH, 1); |
597 | ts->pendown = 1; | 841 | ts->pendown = true; |
598 | dev_vdbg(&ts->spi->dev, "DOWN\n"); | 842 | dev_vdbg(&ts->spi->dev, "DOWN\n"); |
599 | } | 843 | } |
600 | 844 | ||
601 | if (ts->swap_xy) | ||
602 | swap(x, y); | ||
603 | |||
604 | input_report_abs(input, ABS_X, x); | 845 | input_report_abs(input, ABS_X, x); |
605 | input_report_abs(input, ABS_Y, y); | 846 | input_report_abs(input, ABS_Y, y); |
606 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); | 847 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); |
@@ -608,232 +849,94 @@ static void ads7846_rx(void *ads) | |||
608 | input_sync(input); | 849 | input_sync(input); |
609 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); | 850 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); |
610 | } | 851 | } |
611 | |||
612 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | ||
613 | HRTIMER_MODE_REL); | ||
614 | } | 852 | } |
615 | 853 | ||
616 | static int ads7846_debounce(void *ads, int data_idx, int *val) | 854 | static irqreturn_t ads7846_hard_irq(int irq, void *handle) |
617 | { | 855 | { |
618 | struct ads7846 *ts = ads; | 856 | struct ads7846 *ts = handle; |
619 | 857 | ||
620 | if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { | 858 | return get_pendown_state(ts) ? IRQ_WAKE_THREAD : IRQ_HANDLED; |
621 | /* Start over collecting consistent readings. */ | ||
622 | ts->read_rep = 0; | ||
623 | /* Repeat it, if this was the first read or the read | ||
624 | * wasn't consistent enough. */ | ||
625 | if (ts->read_cnt < ts->debounce_max) { | ||
626 | ts->last_read = *val; | ||
627 | ts->read_cnt++; | ||
628 | return ADS7846_FILTER_REPEAT; | ||
629 | } else { | ||
630 | /* Maximum number of debouncing reached and still | ||
631 | * not enough number of consistent readings. Abort | ||
632 | * the whole sample, repeat it in the next sampling | ||
633 | * period. | ||
634 | */ | ||
635 | ts->read_cnt = 0; | ||
636 | return ADS7846_FILTER_IGNORE; | ||
637 | } | ||
638 | } else { | ||
639 | if (++ts->read_rep > ts->debounce_rep) { | ||
640 | /* Got a good reading for this coordinate, | ||
641 | * go for the next one. */ | ||
642 | ts->read_cnt = 0; | ||
643 | ts->read_rep = 0; | ||
644 | return ADS7846_FILTER_OK; | ||
645 | } else { | ||
646 | /* Read more values that are consistent. */ | ||
647 | ts->read_cnt++; | ||
648 | return ADS7846_FILTER_REPEAT; | ||
649 | } | ||
650 | } | ||
651 | } | 859 | } |
652 | 860 | ||
653 | static int ads7846_no_filter(void *ads, int data_idx, int *val) | ||
654 | { | ||
655 | return ADS7846_FILTER_OK; | ||
656 | } | ||
657 | 861 | ||
658 | static void ads7846_rx_val(void *ads) | 862 | static irqreturn_t ads7846_irq(int irq, void *handle) |
659 | { | 863 | { |
660 | struct ads7846 *ts = ads; | 864 | struct ads7846 *ts = handle; |
661 | struct ads7846_packet *packet = ts->packet; | ||
662 | struct spi_message *m; | ||
663 | struct spi_transfer *t; | ||
664 | int val; | ||
665 | int action; | ||
666 | int status; | ||
667 | 865 | ||
668 | m = &ts->msg[ts->msg_idx]; | 866 | /* Start with a small delay before checking pendown state */ |
669 | t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | 867 | msleep(TS_POLL_DELAY); |
670 | 868 | ||
671 | /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; | 869 | while (!ts->stopped && get_pendown_state(ts)) { |
672 | * built from two 8 bit values written msb-first. | ||
673 | */ | ||
674 | val = be16_to_cpup((__be16 *)t->rx_buf) >> 3; | ||
675 | 870 | ||
676 | action = ts->filter(ts->filter_data, ts->msg_idx, &val); | 871 | /* pen is down, continue with the measurement */ |
677 | switch (action) { | 872 | ads7846_read_state(ts); |
678 | case ADS7846_FILTER_REPEAT: | ||
679 | break; | ||
680 | case ADS7846_FILTER_IGNORE: | ||
681 | packet->tc.ignore = 1; | ||
682 | /* Last message will contain ads7846_rx() as the | ||
683 | * completion function. | ||
684 | */ | ||
685 | m = ts->last_msg; | ||
686 | break; | ||
687 | case ADS7846_FILTER_OK: | ||
688 | *(u16 *)t->rx_buf = val; | ||
689 | packet->tc.ignore = 0; | ||
690 | m = &ts->msg[++ts->msg_idx]; | ||
691 | break; | ||
692 | default: | ||
693 | BUG(); | ||
694 | } | ||
695 | ts->wait_for_sync(); | ||
696 | status = spi_async(ts->spi, m); | ||
697 | if (status) | ||
698 | dev_err(&ts->spi->dev, "spi_async --> %d\n", | ||
699 | status); | ||
700 | } | ||
701 | |||
702 | static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) | ||
703 | { | ||
704 | struct ads7846 *ts = container_of(handle, struct ads7846, timer); | ||
705 | int status = 0; | ||
706 | 873 | ||
707 | spin_lock(&ts->lock); | 874 | if (!ts->stopped) |
875 | ads7846_report_state(ts); | ||
708 | 876 | ||
709 | if (unlikely(!get_pendown_state(ts) || | 877 | wait_event_timeout(ts->wait, ts->stopped, |
710 | device_suspended(&ts->spi->dev))) { | 878 | msecs_to_jiffies(TS_POLL_PERIOD)); |
711 | if (ts->pendown) { | 879 | } |
712 | struct input_dev *input = ts->input; | ||
713 | 880 | ||
714 | input_report_key(input, BTN_TOUCH, 0); | 881 | if (ts->pendown) { |
715 | input_report_abs(input, ABS_PRESSURE, 0); | 882 | struct input_dev *input = ts->input; |
716 | input_sync(input); | ||
717 | 883 | ||
718 | ts->pendown = 0; | 884 | input_report_key(input, BTN_TOUCH, 0); |
719 | dev_vdbg(&ts->spi->dev, "UP\n"); | 885 | input_report_abs(input, ABS_PRESSURE, 0); |
720 | } | 886 | input_sync(input); |
721 | 887 | ||
722 | /* measurement cycle ended */ | 888 | ts->pendown = false; |
723 | if (!device_suspended(&ts->spi->dev)) { | 889 | dev_vdbg(&ts->spi->dev, "UP\n"); |
724 | ts->irq_disabled = 0; | ||
725 | enable_irq(ts->spi->irq); | ||
726 | } | ||
727 | ts->pending = 0; | ||
728 | } else { | ||
729 | /* pen is still down, continue with the measurement */ | ||
730 | ts->msg_idx = 0; | ||
731 | ts->wait_for_sync(); | ||
732 | status = spi_async(ts->spi, &ts->msg[0]); | ||
733 | if (status) | ||
734 | dev_err(&ts->spi->dev, "spi_async --> %d\n", status); | ||
735 | } | 890 | } |
736 | 891 | ||
737 | spin_unlock(&ts->lock); | 892 | return IRQ_HANDLED; |
738 | return HRTIMER_NORESTART; | ||
739 | } | 893 | } |
740 | 894 | ||
741 | static irqreturn_t ads7846_irq(int irq, void *handle) | 895 | static int ads7846_suspend(struct spi_device *spi, pm_message_t message) |
742 | { | 896 | { |
743 | struct ads7846 *ts = handle; | 897 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
744 | unsigned long flags; | ||
745 | |||
746 | spin_lock_irqsave(&ts->lock, flags); | ||
747 | if (likely(get_pendown_state(ts))) { | ||
748 | if (!ts->irq_disabled) { | ||
749 | /* The ARM do_simple_IRQ() dispatcher doesn't act | ||
750 | * like the other dispatchers: it will report IRQs | ||
751 | * even after they've been disabled. We work around | ||
752 | * that here. (The "generic irq" framework may help...) | ||
753 | */ | ||
754 | ts->irq_disabled = 1; | ||
755 | disable_irq_nosync(ts->spi->irq); | ||
756 | ts->pending = 1; | ||
757 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), | ||
758 | HRTIMER_MODE_REL); | ||
759 | } | ||
760 | } | ||
761 | spin_unlock_irqrestore(&ts->lock, flags); | ||
762 | 898 | ||
763 | return IRQ_HANDLED; | 899 | mutex_lock(&ts->lock); |
764 | } | ||
765 | 900 | ||
766 | /*--------------------------------------------------------------------------*/ | 901 | if (!ts->suspended) { |
767 | 902 | ||
768 | /* Must be called with ts->lock held */ | 903 | if (!ts->disabled) |
769 | static void ads7846_disable(struct ads7846 *ts) | 904 | __ads7846_disable(ts); |
770 | { | ||
771 | if (ts->disabled) | ||
772 | return; | ||
773 | 905 | ||
774 | ts->disabled = 1; | 906 | if (device_may_wakeup(&ts->spi->dev)) |
907 | enable_irq_wake(ts->spi->irq); | ||
775 | 908 | ||
776 | /* are we waiting for IRQ, or polling? */ | 909 | ts->suspended = true; |
777 | if (!ts->pending) { | ||
778 | ts->irq_disabled = 1; | ||
779 | disable_irq(ts->spi->irq); | ||
780 | } else { | ||
781 | /* the timer will run at least once more, and | ||
782 | * leave everything in a clean state, IRQ disabled | ||
783 | */ | ||
784 | while (ts->pending) { | ||
785 | spin_unlock_irq(&ts->lock); | ||
786 | msleep(1); | ||
787 | spin_lock_irq(&ts->lock); | ||
788 | } | ||
789 | } | 910 | } |
790 | 911 | ||
791 | /* we know the chip's in lowpower mode since we always | 912 | mutex_unlock(&ts->lock); |
792 | * leave it that way after every request | ||
793 | */ | ||
794 | } | ||
795 | 913 | ||
796 | /* Must be called with ts->lock held */ | 914 | return 0; |
797 | static void ads7846_enable(struct ads7846 *ts) | ||
798 | { | ||
799 | if (!ts->disabled) | ||
800 | return; | ||
801 | |||
802 | ts->disabled = 0; | ||
803 | ts->irq_disabled = 0; | ||
804 | enable_irq(ts->spi->irq); | ||
805 | } | 915 | } |
806 | 916 | ||
807 | static int ads7846_suspend(struct spi_device *spi, pm_message_t message) | 917 | static int ads7846_resume(struct spi_device *spi) |
808 | { | 918 | { |
809 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 919 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
810 | 920 | ||
811 | spin_lock_irq(&ts->lock); | 921 | mutex_lock(&ts->lock); |
812 | 922 | ||
813 | ts->is_suspended = 1; | 923 | if (ts->suspended) { |
814 | ads7846_disable(ts); | ||
815 | 924 | ||
816 | spin_unlock_irq(&ts->lock); | 925 | ts->suspended = false; |
817 | 926 | ||
818 | return 0; | 927 | if (device_may_wakeup(&ts->spi->dev)) |
819 | 928 | disable_irq_wake(ts->spi->irq); | |
820 | } | ||
821 | |||
822 | static int ads7846_resume(struct spi_device *spi) | ||
823 | { | ||
824 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | ||
825 | |||
826 | spin_lock_irq(&ts->lock); | ||
827 | 929 | ||
828 | ts->is_suspended = 0; | 930 | if (!ts->disabled) |
829 | ads7846_enable(ts); | 931 | __ads7846_enable(ts); |
932 | } | ||
830 | 933 | ||
831 | spin_unlock_irq(&ts->lock); | 934 | mutex_unlock(&ts->lock); |
832 | 935 | ||
833 | return 0; | 936 | return 0; |
834 | } | 937 | } |
835 | 938 | ||
836 | static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) | 939 | static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) |
837 | { | 940 | { |
838 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 941 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
839 | int err; | 942 | int err; |
@@ -855,149 +958,64 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) | |||
855 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); | 958 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); |
856 | if (err) { | 959 | if (err) { |
857 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", | 960 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", |
858 | pdata->gpio_pendown); | 961 | pdata->gpio_pendown); |
859 | return err; | 962 | return err; |
860 | } | 963 | } |
861 | 964 | ||
862 | ts->gpio_pendown = pdata->gpio_pendown; | 965 | ts->gpio_pendown = pdata->gpio_pendown; |
966 | |||
863 | return 0; | 967 | return 0; |
864 | } | 968 | } |
865 | 969 | ||
866 | static int __devinit ads7846_probe(struct spi_device *spi) | 970 | /* |
971 | * Set up the transfers to read touchscreen state; this assumes we | ||
972 | * use formula #2 for pressure, not #3. | ||
973 | */ | ||
974 | static void __devinit ads7846_setup_spi_msg(struct ads7846 *ts, | ||
975 | const struct ads7846_platform_data *pdata) | ||
867 | { | 976 | { |
868 | struct ads7846 *ts; | 977 | struct spi_message *m = &ts->msg[0]; |
869 | struct ads7846_packet *packet; | 978 | struct spi_transfer *x = ts->xfer; |
870 | struct input_dev *input_dev; | 979 | struct ads7846_packet *packet = ts->packet; |
871 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 980 | int vref = pdata->keep_vref_on; |
872 | struct spi_message *m; | ||
873 | struct spi_transfer *x; | ||
874 | int vref; | ||
875 | int err; | ||
876 | |||
877 | if (!spi->irq) { | ||
878 | dev_dbg(&spi->dev, "no IRQ?\n"); | ||
879 | return -ENODEV; | ||
880 | } | ||
881 | |||
882 | if (!pdata) { | ||
883 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
884 | return -ENODEV; | ||
885 | } | ||
886 | |||
887 | /* don't exceed max specified sample rate */ | ||
888 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { | ||
889 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | ||
890 | (spi->max_speed_hz/SAMPLE_BITS)/1000); | ||
891 | return -EINVAL; | ||
892 | } | ||
893 | |||
894 | /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except | ||
895 | * that even if the hardware can do that, the SPI controller driver | ||
896 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | ||
897 | */ | ||
898 | spi->bits_per_word = 8; | ||
899 | spi->mode = SPI_MODE_0; | ||
900 | err = spi_setup(spi); | ||
901 | if (err < 0) | ||
902 | return err; | ||
903 | 981 | ||
904 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); | 982 | if (ts->model == 7873) { |
905 | packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); | 983 | /* |
906 | input_dev = input_allocate_device(); | 984 | * The AD7873 is almost identical to the ADS7846 |
907 | if (!ts || !packet || !input_dev) { | 985 | * keep VREF off during differential/ratiometric |
908 | err = -ENOMEM; | 986 | * conversion modes. |
909 | goto err_free_mem; | 987 | */ |
988 | ts->model = 7846; | ||
989 | vref = 0; | ||
910 | } | 990 | } |
911 | 991 | ||
912 | dev_set_drvdata(&spi->dev, ts); | 992 | ts->msg_count = 1; |
913 | |||
914 | ts->packet = packet; | ||
915 | ts->spi = spi; | ||
916 | ts->input = input_dev; | ||
917 | ts->vref_mv = pdata->vref_mv; | ||
918 | ts->swap_xy = pdata->swap_xy; | ||
919 | |||
920 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
921 | ts->timer.function = ads7846_timer; | ||
922 | |||
923 | spin_lock_init(&ts->lock); | ||
924 | |||
925 | ts->model = pdata->model ? : 7846; | ||
926 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | ||
927 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
928 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
929 | |||
930 | if (pdata->filter != NULL) { | ||
931 | if (pdata->filter_init != NULL) { | ||
932 | err = pdata->filter_init(pdata, &ts->filter_data); | ||
933 | if (err < 0) | ||
934 | goto err_free_mem; | ||
935 | } | ||
936 | ts->filter = pdata->filter; | ||
937 | ts->filter_cleanup = pdata->filter_cleanup; | ||
938 | } else if (pdata->debounce_max) { | ||
939 | ts->debounce_max = pdata->debounce_max; | ||
940 | if (ts->debounce_max < 2) | ||
941 | ts->debounce_max = 2; | ||
942 | ts->debounce_tol = pdata->debounce_tol; | ||
943 | ts->debounce_rep = pdata->debounce_rep; | ||
944 | ts->filter = ads7846_debounce; | ||
945 | ts->filter_data = ts; | ||
946 | } else | ||
947 | ts->filter = ads7846_no_filter; | ||
948 | |||
949 | err = setup_pendown(spi, ts); | ||
950 | if (err) | ||
951 | goto err_cleanup_filter; | ||
952 | |||
953 | if (pdata->penirq_recheck_delay_usecs) | ||
954 | ts->penirq_recheck_delay_usecs = | ||
955 | pdata->penirq_recheck_delay_usecs; | ||
956 | |||
957 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; | ||
958 | |||
959 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | ||
960 | snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); | ||
961 | |||
962 | input_dev->name = ts->name; | ||
963 | input_dev->phys = ts->phys; | ||
964 | input_dev->dev.parent = &spi->dev; | ||
965 | |||
966 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
967 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
968 | input_set_abs_params(input_dev, ABS_X, | ||
969 | pdata->x_min ? : 0, | ||
970 | pdata->x_max ? : MAX_12BIT, | ||
971 | 0, 0); | ||
972 | input_set_abs_params(input_dev, ABS_Y, | ||
973 | pdata->y_min ? : 0, | ||
974 | pdata->y_max ? : MAX_12BIT, | ||
975 | 0, 0); | ||
976 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
977 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
978 | |||
979 | vref = pdata->keep_vref_on; | ||
980 | |||
981 | /* set up the transfers to read touchscreen state; this assumes we | ||
982 | * use formula #2 for pressure, not #3. | ||
983 | */ | ||
984 | m = &ts->msg[0]; | ||
985 | x = ts->xfer; | ||
986 | |||
987 | spi_message_init(m); | 993 | spi_message_init(m); |
994 | m->context = ts; | ||
988 | 995 | ||
989 | /* y- still on; turn on only y+ (and ADC) */ | 996 | if (ts->model == 7845) { |
990 | packet->read_y = READ_Y(vref); | 997 | packet->read_y_cmd[0] = READ_Y(vref); |
991 | x->tx_buf = &packet->read_y; | 998 | packet->read_y_cmd[1] = 0; |
992 | x->len = 1; | 999 | packet->read_y_cmd[2] = 0; |
993 | spi_message_add_tail(x, m); | 1000 | x->tx_buf = &packet->read_y_cmd[0]; |
1001 | x->rx_buf = &packet->tc.y_buf[0]; | ||
1002 | x->len = 3; | ||
1003 | spi_message_add_tail(x, m); | ||
1004 | } else { | ||
1005 | /* y- still on; turn on only y+ (and ADC) */ | ||
1006 | packet->read_y = READ_Y(vref); | ||
1007 | x->tx_buf = &packet->read_y; | ||
1008 | x->len = 1; | ||
1009 | spi_message_add_tail(x, m); | ||
994 | 1010 | ||
995 | x++; | 1011 | x++; |
996 | x->rx_buf = &packet->tc.y; | 1012 | x->rx_buf = &packet->tc.y; |
997 | x->len = 2; | 1013 | x->len = 2; |
998 | spi_message_add_tail(x, m); | 1014 | spi_message_add_tail(x, m); |
1015 | } | ||
999 | 1016 | ||
1000 | /* the first sample after switching drivers can be low quality; | 1017 | /* |
1018 | * The first sample after switching drivers can be low quality; | ||
1001 | * optionally discard it, using a second one after the signals | 1019 | * optionally discard it, using a second one after the signals |
1002 | * have had enough time to stabilize. | 1020 | * have had enough time to stabilize. |
1003 | */ | 1021 | */ |
@@ -1015,23 +1033,33 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1015 | spi_message_add_tail(x, m); | 1033 | spi_message_add_tail(x, m); |
1016 | } | 1034 | } |
1017 | 1035 | ||
1018 | m->complete = ads7846_rx_val; | 1036 | ts->msg_count++; |
1019 | m->context = ts; | ||
1020 | |||
1021 | m++; | 1037 | m++; |
1022 | spi_message_init(m); | 1038 | spi_message_init(m); |
1039 | m->context = ts; | ||
1023 | 1040 | ||
1024 | /* turn y- off, x+ on, then leave in lowpower */ | 1041 | if (ts->model == 7845) { |
1025 | x++; | 1042 | x++; |
1026 | packet->read_x = READ_X(vref); | 1043 | packet->read_x_cmd[0] = READ_X(vref); |
1027 | x->tx_buf = &packet->read_x; | 1044 | packet->read_x_cmd[1] = 0; |
1028 | x->len = 1; | 1045 | packet->read_x_cmd[2] = 0; |
1029 | spi_message_add_tail(x, m); | 1046 | x->tx_buf = &packet->read_x_cmd[0]; |
1047 | x->rx_buf = &packet->tc.x_buf[0]; | ||
1048 | x->len = 3; | ||
1049 | spi_message_add_tail(x, m); | ||
1050 | } else { | ||
1051 | /* turn y- off, x+ on, then leave in lowpower */ | ||
1052 | x++; | ||
1053 | packet->read_x = READ_X(vref); | ||
1054 | x->tx_buf = &packet->read_x; | ||
1055 | x->len = 1; | ||
1056 | spi_message_add_tail(x, m); | ||
1030 | 1057 | ||
1031 | x++; | 1058 | x++; |
1032 | x->rx_buf = &packet->tc.x; | 1059 | x->rx_buf = &packet->tc.x; |
1033 | x->len = 2; | 1060 | x->len = 2; |
1034 | spi_message_add_tail(x, m); | 1061 | spi_message_add_tail(x, m); |
1062 | } | ||
1035 | 1063 | ||
1036 | /* ... maybe discard first sample ... */ | 1064 | /* ... maybe discard first sample ... */ |
1037 | if (pdata->settle_delay_usecs) { | 1065 | if (pdata->settle_delay_usecs) { |
@@ -1048,13 +1076,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1048 | spi_message_add_tail(x, m); | 1076 | spi_message_add_tail(x, m); |
1049 | } | 1077 | } |
1050 | 1078 | ||
1051 | m->complete = ads7846_rx_val; | ||
1052 | m->context = ts; | ||
1053 | |||
1054 | /* turn y+ off, x- on; we'll use formula #2 */ | 1079 | /* turn y+ off, x- on; we'll use formula #2 */ |
1055 | if (ts->model == 7846) { | 1080 | if (ts->model == 7846) { |
1081 | ts->msg_count++; | ||
1056 | m++; | 1082 | m++; |
1057 | spi_message_init(m); | 1083 | spi_message_init(m); |
1084 | m->context = ts; | ||
1058 | 1085 | ||
1059 | x++; | 1086 | x++; |
1060 | packet->read_z1 = READ_Z1(vref); | 1087 | packet->read_z1 = READ_Z1(vref); |
@@ -1082,11 +1109,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1082 | spi_message_add_tail(x, m); | 1109 | spi_message_add_tail(x, m); |
1083 | } | 1110 | } |
1084 | 1111 | ||
1085 | m->complete = ads7846_rx_val; | 1112 | ts->msg_count++; |
1086 | m->context = ts; | ||
1087 | |||
1088 | m++; | 1113 | m++; |
1089 | spi_message_init(m); | 1114 | spi_message_init(m); |
1115 | m->context = ts; | ||
1090 | 1116 | ||
1091 | x++; | 1117 | x++; |
1092 | packet->read_z2 = READ_Z2(vref); | 1118 | packet->read_z2 = READ_Z2(vref); |
@@ -1113,43 +1139,179 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1113 | x->len = 2; | 1139 | x->len = 2; |
1114 | spi_message_add_tail(x, m); | 1140 | spi_message_add_tail(x, m); |
1115 | } | 1141 | } |
1116 | |||
1117 | m->complete = ads7846_rx_val; | ||
1118 | m->context = ts; | ||
1119 | } | 1142 | } |
1120 | 1143 | ||
1121 | /* power down */ | 1144 | /* power down */ |
1145 | ts->msg_count++; | ||
1122 | m++; | 1146 | m++; |
1123 | spi_message_init(m); | 1147 | spi_message_init(m); |
1148 | m->context = ts; | ||
1124 | 1149 | ||
1125 | x++; | 1150 | if (ts->model == 7845) { |
1126 | packet->pwrdown = PWRDOWN; | 1151 | x++; |
1127 | x->tx_buf = &packet->pwrdown; | 1152 | packet->pwrdown_cmd[0] = PWRDOWN; |
1128 | x->len = 1; | 1153 | packet->pwrdown_cmd[1] = 0; |
1129 | spi_message_add_tail(x, m); | 1154 | packet->pwrdown_cmd[2] = 0; |
1155 | x->tx_buf = &packet->pwrdown_cmd[0]; | ||
1156 | x->len = 3; | ||
1157 | } else { | ||
1158 | x++; | ||
1159 | packet->pwrdown = PWRDOWN; | ||
1160 | x->tx_buf = &packet->pwrdown; | ||
1161 | x->len = 1; | ||
1162 | spi_message_add_tail(x, m); | ||
1163 | |||
1164 | x++; | ||
1165 | x->rx_buf = &packet->dummy; | ||
1166 | x->len = 2; | ||
1167 | } | ||
1130 | 1168 | ||
1131 | x++; | ||
1132 | x->rx_buf = &packet->dummy; | ||
1133 | x->len = 2; | ||
1134 | CS_CHANGE(*x); | 1169 | CS_CHANGE(*x); |
1135 | spi_message_add_tail(x, m); | 1170 | spi_message_add_tail(x, m); |
1171 | } | ||
1136 | 1172 | ||
1137 | m->complete = ads7846_rx; | 1173 | static int __devinit ads7846_probe(struct spi_device *spi) |
1138 | m->context = ts; | 1174 | { |
1175 | struct ads7846 *ts; | ||
1176 | struct ads7846_packet *packet; | ||
1177 | struct input_dev *input_dev; | ||
1178 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | ||
1179 | unsigned long irq_flags; | ||
1180 | int err; | ||
1181 | |||
1182 | if (!spi->irq) { | ||
1183 | dev_dbg(&spi->dev, "no IRQ?\n"); | ||
1184 | return -ENODEV; | ||
1185 | } | ||
1186 | |||
1187 | if (!pdata) { | ||
1188 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
1189 | return -ENODEV; | ||
1190 | } | ||
1191 | |||
1192 | /* don't exceed max specified sample rate */ | ||
1193 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { | ||
1194 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | ||
1195 | (spi->max_speed_hz/SAMPLE_BITS)/1000); | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1198 | |||
1199 | /* We'd set TX word size 8 bits and RX word size to 13 bits ... except | ||
1200 | * that even if the hardware can do that, the SPI controller driver | ||
1201 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | ||
1202 | */ | ||
1203 | spi->bits_per_word = 8; | ||
1204 | spi->mode = SPI_MODE_0; | ||
1205 | err = spi_setup(spi); | ||
1206 | if (err < 0) | ||
1207 | return err; | ||
1208 | |||
1209 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); | ||
1210 | packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); | ||
1211 | input_dev = input_allocate_device(); | ||
1212 | if (!ts || !packet || !input_dev) { | ||
1213 | err = -ENOMEM; | ||
1214 | goto err_free_mem; | ||
1215 | } | ||
1216 | |||
1217 | dev_set_drvdata(&spi->dev, ts); | ||
1218 | |||
1219 | ts->packet = packet; | ||
1220 | ts->spi = spi; | ||
1221 | ts->input = input_dev; | ||
1222 | ts->vref_mv = pdata->vref_mv; | ||
1223 | ts->swap_xy = pdata->swap_xy; | ||
1224 | |||
1225 | mutex_init(&ts->lock); | ||
1226 | init_waitqueue_head(&ts->wait); | ||
1227 | |||
1228 | ts->model = pdata->model ? : 7846; | ||
1229 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | ||
1230 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
1231 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
1232 | |||
1233 | if (pdata->filter != NULL) { | ||
1234 | if (pdata->filter_init != NULL) { | ||
1235 | err = pdata->filter_init(pdata, &ts->filter_data); | ||
1236 | if (err < 0) | ||
1237 | goto err_free_mem; | ||
1238 | } | ||
1239 | ts->filter = pdata->filter; | ||
1240 | ts->filter_cleanup = pdata->filter_cleanup; | ||
1241 | } else if (pdata->debounce_max) { | ||
1242 | ts->debounce_max = pdata->debounce_max; | ||
1243 | if (ts->debounce_max < 2) | ||
1244 | ts->debounce_max = 2; | ||
1245 | ts->debounce_tol = pdata->debounce_tol; | ||
1246 | ts->debounce_rep = pdata->debounce_rep; | ||
1247 | ts->filter = ads7846_debounce_filter; | ||
1248 | ts->filter_data = ts; | ||
1249 | } else { | ||
1250 | ts->filter = ads7846_no_filter; | ||
1251 | } | ||
1252 | |||
1253 | err = ads7846_setup_pendown(spi, ts); | ||
1254 | if (err) | ||
1255 | goto err_cleanup_filter; | ||
1256 | |||
1257 | if (pdata->penirq_recheck_delay_usecs) | ||
1258 | ts->penirq_recheck_delay_usecs = | ||
1259 | pdata->penirq_recheck_delay_usecs; | ||
1139 | 1260 | ||
1140 | ts->last_msg = m; | 1261 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; |
1262 | |||
1263 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | ||
1264 | snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); | ||
1141 | 1265 | ||
1142 | if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, | 1266 | input_dev->name = ts->name; |
1143 | spi->dev.driver->name, ts)) { | 1267 | input_dev->phys = ts->phys; |
1268 | input_dev->dev.parent = &spi->dev; | ||
1269 | |||
1270 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1271 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
1272 | input_set_abs_params(input_dev, ABS_X, | ||
1273 | pdata->x_min ? : 0, | ||
1274 | pdata->x_max ? : MAX_12BIT, | ||
1275 | 0, 0); | ||
1276 | input_set_abs_params(input_dev, ABS_Y, | ||
1277 | pdata->y_min ? : 0, | ||
1278 | pdata->y_max ? : MAX_12BIT, | ||
1279 | 0, 0); | ||
1280 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
1281 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
1282 | |||
1283 | ads7846_setup_spi_msg(ts, pdata); | ||
1284 | |||
1285 | ts->reg = regulator_get(&spi->dev, "vcc"); | ||
1286 | if (IS_ERR(ts->reg)) { | ||
1287 | err = PTR_ERR(ts->reg); | ||
1288 | dev_err(&spi->dev, "unable to get regulator: %d\n", err); | ||
1289 | goto err_free_gpio; | ||
1290 | } | ||
1291 | |||
1292 | err = regulator_enable(ts->reg); | ||
1293 | if (err) { | ||
1294 | dev_err(&spi->dev, "unable to enable regulator: %d\n", err); | ||
1295 | goto err_put_regulator; | ||
1296 | } | ||
1297 | |||
1298 | irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; | ||
1299 | irq_flags |= IRQF_ONESHOT; | ||
1300 | |||
1301 | err = request_threaded_irq(spi->irq, ads7846_hard_irq, ads7846_irq, | ||
1302 | irq_flags, spi->dev.driver->name, ts); | ||
1303 | if (err && !pdata->irq_flags) { | ||
1144 | dev_info(&spi->dev, | 1304 | dev_info(&spi->dev, |
1145 | "trying pin change workaround on irq %d\n", spi->irq); | 1305 | "trying pin change workaround on irq %d\n", spi->irq); |
1146 | err = request_irq(spi->irq, ads7846_irq, | 1306 | irq_flags |= IRQF_TRIGGER_RISING; |
1147 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 1307 | err = request_threaded_irq(spi->irq, |
1148 | spi->dev.driver->name, ts); | 1308 | ads7846_hard_irq, ads7846_irq, |
1149 | if (err) { | 1309 | irq_flags, spi->dev.driver->name, ts); |
1150 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 1310 | } |
1151 | goto err_free_gpio; | 1311 | |
1152 | } | 1312 | if (err) { |
1313 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | ||
1314 | goto err_disable_regulator; | ||
1153 | } | 1315 | } |
1154 | 1316 | ||
1155 | err = ads784x_hwmon_register(spi, ts); | 1317 | err = ads784x_hwmon_register(spi, ts); |
@@ -1158,11 +1320,15 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1158 | 1320 | ||
1159 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); | 1321 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); |
1160 | 1322 | ||
1161 | /* take a first sample, leaving nPENIRQ active and vREF off; avoid | 1323 | /* |
1324 | * Take a first sample, leaving nPENIRQ active and vREF off; avoid | ||
1162 | * the touchscreen, in case it's not connected. | 1325 | * the touchscreen, in case it's not connected. |
1163 | */ | 1326 | */ |
1164 | (void) ads7846_read12_ser(&spi->dev, | 1327 | if (ts->model == 7845) |
1165 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); | 1328 | ads7845_read12_ser(&spi->dev, PWRDOWN); |
1329 | else | ||
1330 | (void) ads7846_read12_ser(&spi->dev, | ||
1331 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); | ||
1166 | 1332 | ||
1167 | err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); | 1333 | err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); |
1168 | if (err) | 1334 | if (err) |
@@ -1172,6 +1338,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1172 | if (err) | 1338 | if (err) |
1173 | goto err_remove_attr_group; | 1339 | goto err_remove_attr_group; |
1174 | 1340 | ||
1341 | device_init_wakeup(&spi->dev, pdata->wakeup); | ||
1342 | |||
1175 | return 0; | 1343 | return 0; |
1176 | 1344 | ||
1177 | err_remove_attr_group: | 1345 | err_remove_attr_group: |
@@ -1180,6 +1348,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1180 | ads784x_hwmon_unregister(spi, ts); | 1348 | ads784x_hwmon_unregister(spi, ts); |
1181 | err_free_irq: | 1349 | err_free_irq: |
1182 | free_irq(spi->irq, ts); | 1350 | free_irq(spi->irq, ts); |
1351 | err_disable_regulator: | ||
1352 | regulator_disable(ts->reg); | ||
1353 | err_put_regulator: | ||
1354 | regulator_put(ts->reg); | ||
1183 | err_free_gpio: | 1355 | err_free_gpio: |
1184 | if (ts->gpio_pendown != -1) | 1356 | if (ts->gpio_pendown != -1) |
1185 | gpio_free(ts->gpio_pendown); | 1357 | gpio_free(ts->gpio_pendown); |
@@ -1195,18 +1367,21 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1195 | 1367 | ||
1196 | static int __devexit ads7846_remove(struct spi_device *spi) | 1368 | static int __devexit ads7846_remove(struct spi_device *spi) |
1197 | { | 1369 | { |
1198 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 1370 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
1199 | |||
1200 | ads784x_hwmon_unregister(spi, ts); | ||
1201 | input_unregister_device(ts->input); | ||
1202 | 1371 | ||
1203 | ads7846_suspend(spi, PMSG_SUSPEND); | 1372 | device_init_wakeup(&spi->dev, false); |
1204 | 1373 | ||
1205 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); | 1374 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); |
1206 | 1375 | ||
1376 | ads7846_disable(ts); | ||
1207 | free_irq(ts->spi->irq, ts); | 1377 | free_irq(ts->spi->irq, ts); |
1208 | /* suspend left the IRQ disabled */ | 1378 | |
1209 | enable_irq(ts->spi->irq); | 1379 | input_unregister_device(ts->input); |
1380 | |||
1381 | ads784x_hwmon_unregister(spi, ts); | ||
1382 | |||
1383 | regulator_disable(ts->reg); | ||
1384 | regulator_put(ts->reg); | ||
1210 | 1385 | ||
1211 | if (ts->gpio_pendown != -1) | 1386 | if (ts->gpio_pendown != -1) |
1212 | gpio_free(ts->gpio_pendown); | 1387 | gpio_free(ts->gpio_pendown); |
@@ -1218,6 +1393,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
1218 | kfree(ts); | 1393 | kfree(ts); |
1219 | 1394 | ||
1220 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | 1395 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); |
1396 | |||
1221 | return 0; | 1397 | return 0; |
1222 | } | 1398 | } |
1223 | 1399 | ||
diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c index a12242f77e23..fa8e56bd9094 100644 --- a/drivers/input/touchscreen/atmel-wm97xx.c +++ b/drivers/input/touchscreen/atmel-wm97xx.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | #define AC97C_ICA 0x10 | 24 | #define AC97C_ICA 0x10 |
24 | #define AC97C_CBRHR 0x30 | 25 | #define AC97C_CBRHR 0x30 |
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c new file mode 100644 index 000000000000..ccde58602563 --- /dev/null +++ b/drivers/input/touchscreen/bu21013_ts.c | |||
@@ -0,0 +1,648 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson | ||
4 | * License terms:GNU General Public License (GPL) version 2 | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/workqueue.h> | ||
12 | #include <linux/input.h> | ||
13 | #include <linux/input/bu21013.h> | ||
14 | #include <linux/slab.h> | ||
15 | |||
16 | #define PEN_DOWN_INTR 0 | ||
17 | #define MAX_FINGERS 2 | ||
18 | #define RESET_DELAY 30 | ||
19 | #define PENUP_TIMEOUT (10) | ||
20 | #define DELTA_MIN 16 | ||
21 | #define MASK_BITS 0x03 | ||
22 | #define SHIFT_8 8 | ||
23 | #define SHIFT_2 2 | ||
24 | #define LENGTH_OF_BUFFER 11 | ||
25 | #define I2C_RETRY_COUNT 5 | ||
26 | |||
27 | #define BU21013_SENSORS_BTN_0_7_REG 0x70 | ||
28 | #define BU21013_SENSORS_BTN_8_15_REG 0x71 | ||
29 | #define BU21013_SENSORS_BTN_16_23_REG 0x72 | ||
30 | #define BU21013_X1_POS_MSB_REG 0x73 | ||
31 | #define BU21013_X1_POS_LSB_REG 0x74 | ||
32 | #define BU21013_Y1_POS_MSB_REG 0x75 | ||
33 | #define BU21013_Y1_POS_LSB_REG 0x76 | ||
34 | #define BU21013_X2_POS_MSB_REG 0x77 | ||
35 | #define BU21013_X2_POS_LSB_REG 0x78 | ||
36 | #define BU21013_Y2_POS_MSB_REG 0x79 | ||
37 | #define BU21013_Y2_POS_LSB_REG 0x7A | ||
38 | #define BU21013_INT_CLR_REG 0xE8 | ||
39 | #define BU21013_INT_MODE_REG 0xE9 | ||
40 | #define BU21013_GAIN_REG 0xEA | ||
41 | #define BU21013_OFFSET_MODE_REG 0xEB | ||
42 | #define BU21013_XY_EDGE_REG 0xEC | ||
43 | #define BU21013_RESET_REG 0xED | ||
44 | #define BU21013_CALIB_REG 0xEE | ||
45 | #define BU21013_DONE_REG 0xEF | ||
46 | #define BU21013_SENSOR_0_7_REG 0xF0 | ||
47 | #define BU21013_SENSOR_8_15_REG 0xF1 | ||
48 | #define BU21013_SENSOR_16_23_REG 0xF2 | ||
49 | #define BU21013_POS_MODE1_REG 0xF3 | ||
50 | #define BU21013_POS_MODE2_REG 0xF4 | ||
51 | #define BU21013_CLK_MODE_REG 0xF5 | ||
52 | #define BU21013_IDLE_REG 0xFA | ||
53 | #define BU21013_FILTER_REG 0xFB | ||
54 | #define BU21013_TH_ON_REG 0xFC | ||
55 | #define BU21013_TH_OFF_REG 0xFD | ||
56 | |||
57 | |||
58 | #define BU21013_RESET_ENABLE 0x01 | ||
59 | |||
60 | #define BU21013_SENSORS_EN_0_7 0x3F | ||
61 | #define BU21013_SENSORS_EN_8_15 0xFC | ||
62 | #define BU21013_SENSORS_EN_16_23 0x1F | ||
63 | |||
64 | #define BU21013_POS_MODE1_0 0x02 | ||
65 | #define BU21013_POS_MODE1_1 0x04 | ||
66 | #define BU21013_POS_MODE1_2 0x08 | ||
67 | |||
68 | #define BU21013_POS_MODE2_ZERO 0x01 | ||
69 | #define BU21013_POS_MODE2_AVG1 0x02 | ||
70 | #define BU21013_POS_MODE2_AVG2 0x04 | ||
71 | #define BU21013_POS_MODE2_EN_XY 0x08 | ||
72 | #define BU21013_POS_MODE2_EN_RAW 0x10 | ||
73 | #define BU21013_POS_MODE2_MULTI 0x80 | ||
74 | |||
75 | #define BU21013_CLK_MODE_DIV 0x01 | ||
76 | #define BU21013_CLK_MODE_EXT 0x02 | ||
77 | #define BU21013_CLK_MODE_CALIB 0x80 | ||
78 | |||
79 | #define BU21013_IDLET_0 0x01 | ||
80 | #define BU21013_IDLET_1 0x02 | ||
81 | #define BU21013_IDLET_2 0x04 | ||
82 | #define BU21013_IDLET_3 0x08 | ||
83 | #define BU21013_IDLE_INTERMIT_EN 0x10 | ||
84 | |||
85 | #define BU21013_DELTA_0_6 0x7F | ||
86 | #define BU21013_FILTER_EN 0x80 | ||
87 | |||
88 | #define BU21013_INT_MODE_LEVEL 0x00 | ||
89 | #define BU21013_INT_MODE_EDGE 0x01 | ||
90 | |||
91 | #define BU21013_GAIN_0 0x01 | ||
92 | #define BU21013_GAIN_1 0x02 | ||
93 | #define BU21013_GAIN_2 0x04 | ||
94 | |||
95 | #define BU21013_OFFSET_MODE_DEFAULT 0x00 | ||
96 | #define BU21013_OFFSET_MODE_MOVE 0x01 | ||
97 | #define BU21013_OFFSET_MODE_DISABLE 0x02 | ||
98 | |||
99 | #define BU21013_TH_ON_0 0x01 | ||
100 | #define BU21013_TH_ON_1 0x02 | ||
101 | #define BU21013_TH_ON_2 0x04 | ||
102 | #define BU21013_TH_ON_3 0x08 | ||
103 | #define BU21013_TH_ON_4 0x10 | ||
104 | #define BU21013_TH_ON_5 0x20 | ||
105 | #define BU21013_TH_ON_6 0x40 | ||
106 | #define BU21013_TH_ON_7 0x80 | ||
107 | #define BU21013_TH_ON_MAX 0xFF | ||
108 | |||
109 | #define BU21013_TH_OFF_0 0x01 | ||
110 | #define BU21013_TH_OFF_1 0x02 | ||
111 | #define BU21013_TH_OFF_2 0x04 | ||
112 | #define BU21013_TH_OFF_3 0x08 | ||
113 | #define BU21013_TH_OFF_4 0x10 | ||
114 | #define BU21013_TH_OFF_5 0x20 | ||
115 | #define BU21013_TH_OFF_6 0x40 | ||
116 | #define BU21013_TH_OFF_7 0x80 | ||
117 | #define BU21013_TH_OFF_MAX 0xFF | ||
118 | |||
119 | #define BU21013_X_EDGE_0 0x01 | ||
120 | #define BU21013_X_EDGE_1 0x02 | ||
121 | #define BU21013_X_EDGE_2 0x04 | ||
122 | #define BU21013_X_EDGE_3 0x08 | ||
123 | #define BU21013_Y_EDGE_0 0x10 | ||
124 | #define BU21013_Y_EDGE_1 0x20 | ||
125 | #define BU21013_Y_EDGE_2 0x40 | ||
126 | #define BU21013_Y_EDGE_3 0x80 | ||
127 | |||
128 | #define BU21013_DONE 0x01 | ||
129 | #define BU21013_NUMBER_OF_X_SENSORS (6) | ||
130 | #define BU21013_NUMBER_OF_Y_SENSORS (11) | ||
131 | |||
132 | #define DRIVER_TP "bu21013_tp" | ||
133 | |||
134 | /** | ||
135 | * struct bu21013_ts_data - touch panel data structure | ||
136 | * @client: pointer to the i2c client | ||
137 | * @wait: variable to wait_queue_head_t structure | ||
138 | * @touch_stopped: touch stop flag | ||
139 | * @chip: pointer to the touch panel controller | ||
140 | * @in_dev: pointer to the input device structure | ||
141 | * @intr_pin: interrupt pin value | ||
142 | * | ||
143 | * Touch panel device data structure | ||
144 | */ | ||
145 | struct bu21013_ts_data { | ||
146 | struct i2c_client *client; | ||
147 | wait_queue_head_t wait; | ||
148 | bool touch_stopped; | ||
149 | const struct bu21013_platform_device *chip; | ||
150 | struct input_dev *in_dev; | ||
151 | unsigned int intr_pin; | ||
152 | }; | ||
153 | |||
154 | /** | ||
155 | * bu21013_read_block_data(): read the touch co-ordinates | ||
156 | * @data: bu21013_ts_data structure pointer | ||
157 | * @buf: byte pointer | ||
158 | * | ||
159 | * Read the touch co-ordinates using i2c read block into buffer | ||
160 | * and returns integer. | ||
161 | */ | ||
162 | static int bu21013_read_block_data(struct bu21013_ts_data *data, u8 *buf) | ||
163 | { | ||
164 | int ret, i; | ||
165 | |||
166 | for (i = 0; i < I2C_RETRY_COUNT; i++) { | ||
167 | ret = i2c_smbus_read_i2c_block_data | ||
168 | (data->client, BU21013_SENSORS_BTN_0_7_REG, | ||
169 | LENGTH_OF_BUFFER, buf); | ||
170 | if (ret == LENGTH_OF_BUFFER) | ||
171 | return 0; | ||
172 | } | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * bu21013_do_touch_report(): Get the touch co-ordinates | ||
178 | * @data: bu21013_ts_data structure pointer | ||
179 | * | ||
180 | * Get the touch co-ordinates from touch sensor registers and writes | ||
181 | * into device structure and returns integer. | ||
182 | */ | ||
183 | static int bu21013_do_touch_report(struct bu21013_ts_data *data) | ||
184 | { | ||
185 | u8 buf[LENGTH_OF_BUFFER]; | ||
186 | unsigned int pos_x[2], pos_y[2]; | ||
187 | bool has_x_sensors, has_y_sensors; | ||
188 | int finger_down_count = 0; | ||
189 | int i; | ||
190 | |||
191 | if (data == NULL) | ||
192 | return -EINVAL; | ||
193 | |||
194 | if (bu21013_read_block_data(data, buf) < 0) | ||
195 | return -EINVAL; | ||
196 | |||
197 | has_x_sensors = hweight32(buf[0] & BU21013_SENSORS_EN_0_7); | ||
198 | has_y_sensors = hweight32(((buf[1] & BU21013_SENSORS_EN_8_15) | | ||
199 | ((buf[2] & BU21013_SENSORS_EN_16_23) << SHIFT_8)) >> SHIFT_2); | ||
200 | if (!has_x_sensors || !has_y_sensors) | ||
201 | return 0; | ||
202 | |||
203 | for (i = 0; i < MAX_FINGERS; i++) { | ||
204 | const u8 *p = &buf[4 * i + 3]; | ||
205 | unsigned int x = p[0] << SHIFT_2 | (p[1] & MASK_BITS); | ||
206 | unsigned int y = p[2] << SHIFT_2 | (p[3] & MASK_BITS); | ||
207 | if (x == 0 || y == 0) | ||
208 | continue; | ||
209 | pos_x[finger_down_count] = x; | ||
210 | pos_y[finger_down_count] = y; | ||
211 | finger_down_count++; | ||
212 | } | ||
213 | |||
214 | if (finger_down_count) { | ||
215 | if (finger_down_count == 2 && | ||
216 | (abs(pos_x[0] - pos_x[1]) < DELTA_MIN || | ||
217 | abs(pos_y[0] - pos_y[1]) < DELTA_MIN)) { | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | for (i = 0; i < finger_down_count; i++) { | ||
222 | if (data->chip->x_flip) | ||
223 | pos_x[i] = data->chip->touch_x_max - pos_x[i]; | ||
224 | if (data->chip->y_flip) | ||
225 | pos_y[i] = data->chip->touch_y_max - pos_y[i]; | ||
226 | |||
227 | input_report_abs(data->in_dev, | ||
228 | ABS_MT_POSITION_X, pos_x[i]); | ||
229 | input_report_abs(data->in_dev, | ||
230 | ABS_MT_POSITION_Y, pos_y[i]); | ||
231 | input_mt_sync(data->in_dev); | ||
232 | } | ||
233 | } else | ||
234 | input_mt_sync(data->in_dev); | ||
235 | |||
236 | input_sync(data->in_dev); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | /** | ||
241 | * bu21013_gpio_irq() - gpio thread function for touch interrupt | ||
242 | * @irq: irq value | ||
243 | * @device_data: void pointer | ||
244 | * | ||
245 | * This gpio thread function for touch interrupt | ||
246 | * and returns irqreturn_t. | ||
247 | */ | ||
248 | static irqreturn_t bu21013_gpio_irq(int irq, void *device_data) | ||
249 | { | ||
250 | struct bu21013_ts_data *data = device_data; | ||
251 | struct i2c_client *i2c = data->client; | ||
252 | int retval; | ||
253 | |||
254 | do { | ||
255 | retval = bu21013_do_touch_report(data); | ||
256 | if (retval < 0) { | ||
257 | dev_err(&i2c->dev, "bu21013_do_touch_report failed\n"); | ||
258 | return IRQ_NONE; | ||
259 | } | ||
260 | |||
261 | data->intr_pin = data->chip->irq_read_val(); | ||
262 | if (data->intr_pin == PEN_DOWN_INTR) | ||
263 | wait_event_timeout(data->wait, data->touch_stopped, | ||
264 | msecs_to_jiffies(2)); | ||
265 | } while (!data->intr_pin && !data->touch_stopped); | ||
266 | |||
267 | return IRQ_HANDLED; | ||
268 | } | ||
269 | |||
270 | /** | ||
271 | * bu21013_init_chip() - power on sequence for the bu21013 controller | ||
272 | * @data: device structure pointer | ||
273 | * | ||
274 | * This function is used to power on | ||
275 | * the bu21013 controller and returns integer. | ||
276 | */ | ||
277 | static int bu21013_init_chip(struct bu21013_ts_data *data) | ||
278 | { | ||
279 | int retval; | ||
280 | struct i2c_client *i2c = data->client; | ||
281 | |||
282 | retval = i2c_smbus_write_byte_data(i2c, BU21013_RESET_REG, | ||
283 | BU21013_RESET_ENABLE); | ||
284 | if (retval < 0) { | ||
285 | dev_err(&i2c->dev, "BU21013_RESET reg write failed\n"); | ||
286 | return retval; | ||
287 | } | ||
288 | msleep(RESET_DELAY); | ||
289 | |||
290 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_0_7_REG, | ||
291 | BU21013_SENSORS_EN_0_7); | ||
292 | if (retval < 0) { | ||
293 | dev_err(&i2c->dev, "BU21013_SENSOR_0_7 reg write failed\n"); | ||
294 | return retval; | ||
295 | } | ||
296 | |||
297 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_8_15_REG, | ||
298 | BU21013_SENSORS_EN_8_15); | ||
299 | if (retval < 0) { | ||
300 | dev_err(&i2c->dev, "BU21013_SENSOR_8_15 reg write failed\n"); | ||
301 | return retval; | ||
302 | } | ||
303 | |||
304 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_16_23_REG, | ||
305 | BU21013_SENSORS_EN_16_23); | ||
306 | if (retval < 0) { | ||
307 | dev_err(&i2c->dev, "BU21013_SENSOR_16_23 reg write failed\n"); | ||
308 | return retval; | ||
309 | } | ||
310 | |||
311 | retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE1_REG, | ||
312 | (BU21013_POS_MODE1_0 | BU21013_POS_MODE1_1)); | ||
313 | if (retval < 0) { | ||
314 | dev_err(&i2c->dev, "BU21013_POS_MODE1 reg write failed\n"); | ||
315 | return retval; | ||
316 | } | ||
317 | |||
318 | retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE2_REG, | ||
319 | (BU21013_POS_MODE2_ZERO | BU21013_POS_MODE2_AVG1 | | ||
320 | BU21013_POS_MODE2_AVG2 | BU21013_POS_MODE2_EN_RAW | | ||
321 | BU21013_POS_MODE2_MULTI)); | ||
322 | if (retval < 0) { | ||
323 | dev_err(&i2c->dev, "BU21013_POS_MODE2 reg write failed\n"); | ||
324 | return retval; | ||
325 | } | ||
326 | |||
327 | if (data->chip->ext_clk) | ||
328 | retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG, | ||
329 | (BU21013_CLK_MODE_EXT | BU21013_CLK_MODE_CALIB)); | ||
330 | else | ||
331 | retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG, | ||
332 | (BU21013_CLK_MODE_DIV | BU21013_CLK_MODE_CALIB)); | ||
333 | if (retval < 0) { | ||
334 | dev_err(&i2c->dev, "BU21013_CLK_MODE reg write failed\n"); | ||
335 | return retval; | ||
336 | } | ||
337 | |||
338 | retval = i2c_smbus_write_byte_data(i2c, BU21013_IDLE_REG, | ||
339 | (BU21013_IDLET_0 | BU21013_IDLE_INTERMIT_EN)); | ||
340 | if (retval < 0) { | ||
341 | dev_err(&i2c->dev, "BU21013_IDLE reg write failed\n"); | ||
342 | return retval; | ||
343 | } | ||
344 | |||
345 | retval = i2c_smbus_write_byte_data(i2c, BU21013_INT_MODE_REG, | ||
346 | BU21013_INT_MODE_LEVEL); | ||
347 | if (retval < 0) { | ||
348 | dev_err(&i2c->dev, "BU21013_INT_MODE reg write failed\n"); | ||
349 | return retval; | ||
350 | } | ||
351 | |||
352 | retval = i2c_smbus_write_byte_data(i2c, BU21013_FILTER_REG, | ||
353 | (BU21013_DELTA_0_6 | | ||
354 | BU21013_FILTER_EN)); | ||
355 | if (retval < 0) { | ||
356 | dev_err(&i2c->dev, "BU21013_FILTER reg write failed\n"); | ||
357 | return retval; | ||
358 | } | ||
359 | |||
360 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_ON_REG, | ||
361 | BU21013_TH_ON_5); | ||
362 | if (retval < 0) { | ||
363 | dev_err(&i2c->dev, "BU21013_TH_ON reg write failed\n"); | ||
364 | return retval; | ||
365 | } | ||
366 | |||
367 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_OFF_REG, | ||
368 | BU21013_TH_OFF_4 || BU21013_TH_OFF_3); | ||
369 | if (retval < 0) { | ||
370 | dev_err(&i2c->dev, "BU21013_TH_OFF reg write failed\n"); | ||
371 | return retval; | ||
372 | } | ||
373 | |||
374 | retval = i2c_smbus_write_byte_data(i2c, BU21013_GAIN_REG, | ||
375 | (BU21013_GAIN_0 | BU21013_GAIN_1)); | ||
376 | if (retval < 0) { | ||
377 | dev_err(&i2c->dev, "BU21013_GAIN reg write failed\n"); | ||
378 | return retval; | ||
379 | } | ||
380 | |||
381 | retval = i2c_smbus_write_byte_data(i2c, BU21013_OFFSET_MODE_REG, | ||
382 | BU21013_OFFSET_MODE_DEFAULT); | ||
383 | if (retval < 0) { | ||
384 | dev_err(&i2c->dev, "BU21013_OFFSET_MODE reg write failed\n"); | ||
385 | return retval; | ||
386 | } | ||
387 | |||
388 | retval = i2c_smbus_write_byte_data(i2c, BU21013_XY_EDGE_REG, | ||
389 | (BU21013_X_EDGE_0 | BU21013_X_EDGE_2 | | ||
390 | BU21013_Y_EDGE_1 | BU21013_Y_EDGE_3)); | ||
391 | if (retval < 0) { | ||
392 | dev_err(&i2c->dev, "BU21013_XY_EDGE reg write failed\n"); | ||
393 | return retval; | ||
394 | } | ||
395 | |||
396 | retval = i2c_smbus_write_byte_data(i2c, BU21013_DONE_REG, | ||
397 | BU21013_DONE); | ||
398 | if (retval < 0) { | ||
399 | dev_err(&i2c->dev, "BU21013_REG_DONE reg write failed\n"); | ||
400 | return retval; | ||
401 | } | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * bu21013_free_irq() - frees IRQ registered for touchscreen | ||
408 | * @bu21013_data: device structure pointer | ||
409 | * | ||
410 | * This function signals interrupt thread to stop processing and | ||
411 | * frees interrupt. | ||
412 | */ | ||
413 | static void bu21013_free_irq(struct bu21013_ts_data *bu21013_data) | ||
414 | { | ||
415 | bu21013_data->touch_stopped = true; | ||
416 | wake_up(&bu21013_data->wait); | ||
417 | free_irq(bu21013_data->chip->irq, bu21013_data); | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * bu21013_probe() - initializes the i2c-client touchscreen driver | ||
422 | * @client: i2c client structure pointer | ||
423 | * @id: i2c device id pointer | ||
424 | * | ||
425 | * This function used to initializes the i2c-client touchscreen | ||
426 | * driver and returns integer. | ||
427 | */ | ||
428 | static int __devinit bu21013_probe(struct i2c_client *client, | ||
429 | const struct i2c_device_id *id) | ||
430 | { | ||
431 | struct bu21013_ts_data *bu21013_data; | ||
432 | struct input_dev *in_dev; | ||
433 | const struct bu21013_platform_device *pdata = | ||
434 | client->dev.platform_data; | ||
435 | int error; | ||
436 | |||
437 | if (!i2c_check_functionality(client->adapter, | ||
438 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
439 | dev_err(&client->dev, "i2c smbus byte data not supported\n"); | ||
440 | return -EIO; | ||
441 | } | ||
442 | |||
443 | if (!pdata) { | ||
444 | dev_err(&client->dev, "platform data not defined\n"); | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | |||
448 | bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL); | ||
449 | in_dev = input_allocate_device(); | ||
450 | if (!bu21013_data || !in_dev) { | ||
451 | dev_err(&client->dev, "device memory alloc failed\n"); | ||
452 | error = -ENOMEM; | ||
453 | goto err_free_mem; | ||
454 | } | ||
455 | |||
456 | bu21013_data->in_dev = in_dev; | ||
457 | bu21013_data->chip = pdata; | ||
458 | bu21013_data->client = client; | ||
459 | bu21013_data->touch_stopped = false; | ||
460 | init_waitqueue_head(&bu21013_data->wait); | ||
461 | |||
462 | /* configure the gpio pins */ | ||
463 | if (pdata->cs_en) { | ||
464 | error = pdata->cs_en(pdata->cs_pin); | ||
465 | if (error < 0) { | ||
466 | dev_err(&client->dev, "chip init failed\n"); | ||
467 | goto err_free_mem; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | /* configure the touch panel controller */ | ||
472 | error = bu21013_init_chip(bu21013_data); | ||
473 | if (error) { | ||
474 | dev_err(&client->dev, "error in bu21013 config\n"); | ||
475 | goto err_cs_disable; | ||
476 | } | ||
477 | |||
478 | /* register the device to input subsystem */ | ||
479 | in_dev->name = DRIVER_TP; | ||
480 | in_dev->id.bustype = BUS_I2C; | ||
481 | in_dev->dev.parent = &client->dev; | ||
482 | |||
483 | __set_bit(EV_SYN, in_dev->evbit); | ||
484 | __set_bit(EV_KEY, in_dev->evbit); | ||
485 | __set_bit(EV_ABS, in_dev->evbit); | ||
486 | |||
487 | input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0, | ||
488 | pdata->x_max_res, 0, 0); | ||
489 | input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0, | ||
490 | pdata->y_max_res, 0, 0); | ||
491 | input_set_drvdata(in_dev, bu21013_data); | ||
492 | |||
493 | error = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq, | ||
494 | IRQF_TRIGGER_FALLING | IRQF_SHARED, | ||
495 | DRIVER_TP, bu21013_data); | ||
496 | if (error) { | ||
497 | dev_err(&client->dev, "request irq %d failed\n", pdata->irq); | ||
498 | goto err_cs_disable; | ||
499 | } | ||
500 | |||
501 | error = input_register_device(in_dev); | ||
502 | if (error) { | ||
503 | dev_err(&client->dev, "failed to register input device\n"); | ||
504 | goto err_free_irq; | ||
505 | } | ||
506 | |||
507 | device_init_wakeup(&client->dev, pdata->wakeup); | ||
508 | i2c_set_clientdata(client, bu21013_data); | ||
509 | |||
510 | return 0; | ||
511 | |||
512 | err_free_irq: | ||
513 | bu21013_free_irq(bu21013_data); | ||
514 | err_cs_disable: | ||
515 | pdata->cs_dis(pdata->cs_pin); | ||
516 | err_free_mem: | ||
517 | input_free_device(bu21013_data->in_dev); | ||
518 | kfree(bu21013_data); | ||
519 | |||
520 | return error; | ||
521 | } | ||
522 | /** | ||
523 | * bu21013_remove() - removes the i2c-client touchscreen driver | ||
524 | * @client: i2c client structure pointer | ||
525 | * | ||
526 | * This function uses to remove the i2c-client | ||
527 | * touchscreen driver and returns integer. | ||
528 | */ | ||
529 | static int __devexit bu21013_remove(struct i2c_client *client) | ||
530 | { | ||
531 | struct bu21013_ts_data *bu21013_data = i2c_get_clientdata(client); | ||
532 | |||
533 | bu21013_free_irq(bu21013_data); | ||
534 | |||
535 | bu21013_data->chip->cs_dis(bu21013_data->chip->cs_pin); | ||
536 | |||
537 | input_unregister_device(bu21013_data->in_dev); | ||
538 | kfree(bu21013_data); | ||
539 | |||
540 | device_init_wakeup(&client->dev, false); | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | #ifdef CONFIG_PM | ||
546 | /** | ||
547 | * bu21013_suspend() - suspend the touch screen controller | ||
548 | * @dev: pointer to device structure | ||
549 | * | ||
550 | * This function is used to suspend the | ||
551 | * touch panel controller and returns integer | ||
552 | */ | ||
553 | static int bu21013_suspend(struct device *dev) | ||
554 | { | ||
555 | struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev); | ||
556 | struct i2c_client *client = bu21013_data->client; | ||
557 | |||
558 | bu21013_data->touch_stopped = true; | ||
559 | if (device_may_wakeup(&client->dev)) | ||
560 | enable_irq_wake(bu21013_data->chip->irq); | ||
561 | else | ||
562 | disable_irq(bu21013_data->chip->irq); | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | /** | ||
568 | * bu21013_resume() - resume the touch screen controller | ||
569 | * @dev: pointer to device structure | ||
570 | * | ||
571 | * This function is used to resume the touch panel | ||
572 | * controller and returns integer. | ||
573 | */ | ||
574 | static int bu21013_resume(struct device *dev) | ||
575 | { | ||
576 | struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev); | ||
577 | struct i2c_client *client = bu21013_data->client; | ||
578 | int retval; | ||
579 | |||
580 | retval = bu21013_init_chip(bu21013_data); | ||
581 | if (retval < 0) { | ||
582 | dev_err(&client->dev, "bu21013 controller config failed\n"); | ||
583 | return retval; | ||
584 | } | ||
585 | |||
586 | bu21013_data->touch_stopped = false; | ||
587 | |||
588 | if (device_may_wakeup(&client->dev)) | ||
589 | disable_irq_wake(bu21013_data->chip->irq); | ||
590 | else | ||
591 | enable_irq(bu21013_data->chip->irq); | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | static const struct dev_pm_ops bu21013_dev_pm_ops = { | ||
597 | .suspend = bu21013_suspend, | ||
598 | .resume = bu21013_resume, | ||
599 | }; | ||
600 | #endif | ||
601 | |||
602 | static const struct i2c_device_id bu21013_id[] = { | ||
603 | { DRIVER_TP, 0 }, | ||
604 | { } | ||
605 | }; | ||
606 | MODULE_DEVICE_TABLE(i2c, bu21013_id); | ||
607 | |||
608 | static struct i2c_driver bu21013_driver = { | ||
609 | .driver = { | ||
610 | .name = DRIVER_TP, | ||
611 | .owner = THIS_MODULE, | ||
612 | #ifdef CONFIG_PM | ||
613 | .pm = &bu21013_dev_pm_ops, | ||
614 | #endif | ||
615 | }, | ||
616 | .probe = bu21013_probe, | ||
617 | .remove = __devexit_p(bu21013_remove), | ||
618 | .id_table = bu21013_id, | ||
619 | }; | ||
620 | |||
621 | /** | ||
622 | * bu21013_init() - initializes the bu21013 touchscreen driver | ||
623 | * | ||
624 | * This function used to initializes the bu21013 | ||
625 | * touchscreen driver and returns integer. | ||
626 | */ | ||
627 | static int __init bu21013_init(void) | ||
628 | { | ||
629 | return i2c_add_driver(&bu21013_driver); | ||
630 | } | ||
631 | |||
632 | /** | ||
633 | * bu21013_exit() - de-initializes the bu21013 touchscreen driver | ||
634 | * | ||
635 | * This function uses to de-initializes the bu21013 | ||
636 | * touchscreen driver and returns none. | ||
637 | */ | ||
638 | static void __exit bu21013_exit(void) | ||
639 | { | ||
640 | i2c_del_driver(&bu21013_driver); | ||
641 | } | ||
642 | |||
643 | module_init(bu21013_init); | ||
644 | module_exit(bu21013_exit); | ||
645 | |||
646 | MODULE_LICENSE("GPL v2"); | ||
647 | MODULE_AUTHOR("Naveen Kumar G <naveen.gaddipati@stericsson.com>"); | ||
648 | MODULE_DESCRIPTION("bu21013 touch screen controller driver"); | ||
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c deleted file mode 100644 index 94a1919d439d..000000000000 --- a/drivers/input/touchscreen/corgi_ts.c +++ /dev/null | |||
@@ -1,385 +0,0 @@ | |||
1 | /* | ||
2 | * Touchscreen driver for Sharp SL-C7xx and SL-Cxx00 models | ||
3 | * | ||
4 | * Copyright (c) 2004-2005 Richard Purdie | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | |||
13 | #include <linux/delay.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/input.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/irq.h> | ||
21 | |||
22 | #include <mach/sharpsl.h> | ||
23 | #include <mach/hardware.h> | ||
24 | #include <mach/pxa2xx-gpio.h> | ||
25 | |||
26 | |||
27 | #define PWR_MODE_ACTIVE 0 | ||
28 | #define PWR_MODE_SUSPEND 1 | ||
29 | |||
30 | #define X_AXIS_MAX 3830 | ||
31 | #define X_AXIS_MIN 150 | ||
32 | #define Y_AXIS_MAX 3830 | ||
33 | #define Y_AXIS_MIN 190 | ||
34 | #define PRESSURE_MIN 0 | ||
35 | #define PRESSURE_MAX 15000 | ||
36 | |||
37 | struct ts_event { | ||
38 | short pressure; | ||
39 | short x; | ||
40 | short y; | ||
41 | }; | ||
42 | |||
43 | struct corgi_ts { | ||
44 | struct input_dev *input; | ||
45 | struct timer_list timer; | ||
46 | struct ts_event tc; | ||
47 | int pendown; | ||
48 | int power_mode; | ||
49 | int irq_gpio; | ||
50 | struct corgits_machinfo *machinfo; | ||
51 | }; | ||
52 | |||
53 | #ifdef CONFIG_PXA25x | ||
54 | #define CCNT(a) asm volatile ("mrc p14, 0, %0, C1, C0, 0" : "=r"(a)) | ||
55 | #define PMNC_GET(x) asm volatile ("mrc p14, 0, %0, C0, C0, 0" : "=r"(x)) | ||
56 | #define PMNC_SET(x) asm volatile ("mcr p14, 0, %0, C0, C0, 0" : : "r"(x)) | ||
57 | #endif | ||
58 | #ifdef CONFIG_PXA27x | ||
59 | #define CCNT(a) asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a)) | ||
60 | #define PMNC_GET(x) asm volatile ("mrc p14, 0, %0, C0, C1, 0" : "=r"(x)) | ||
61 | #define PMNC_SET(x) asm volatile ("mcr p14, 0, %0, C0, C1, 0" : : "r"(x)) | ||
62 | #endif | ||
63 | |||
64 | /* ADS7846 Touch Screen Controller bit definitions */ | ||
65 | #define ADSCTRL_PD0 (1u << 0) /* PD0 */ | ||
66 | #define ADSCTRL_PD1 (1u << 1) /* PD1 */ | ||
67 | #define ADSCTRL_DFR (1u << 2) /* SER/DFR */ | ||
68 | #define ADSCTRL_MOD (1u << 3) /* Mode */ | ||
69 | #define ADSCTRL_ADR_SH 4 /* Address setting */ | ||
70 | #define ADSCTRL_STS (1u << 7) /* Start Bit */ | ||
71 | |||
72 | /* External Functions */ | ||
73 | extern unsigned int get_clk_frequency_khz(int info); | ||
74 | |||
75 | static unsigned long calc_waittime(struct corgi_ts *corgi_ts) | ||
76 | { | ||
77 | unsigned long hsync_invperiod = corgi_ts->machinfo->get_hsync_invperiod(); | ||
78 | |||
79 | if (hsync_invperiod) | ||
80 | return get_clk_frequency_khz(0)*1000/hsync_invperiod; | ||
81 | else | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int sync_receive_data_send_cmd(struct corgi_ts *corgi_ts, int doRecive, int doSend, | ||
86 | unsigned int address, unsigned long wait_time) | ||
87 | { | ||
88 | unsigned long timer1 = 0, timer2, pmnc = 0; | ||
89 | int pos = 0; | ||
90 | |||
91 | if (wait_time && doSend) { | ||
92 | PMNC_GET(pmnc); | ||
93 | if (!(pmnc & 0x01)) | ||
94 | PMNC_SET(0x01); | ||
95 | |||
96 | /* polling HSync */ | ||
97 | corgi_ts->machinfo->wait_hsync(); | ||
98 | /* get CCNT */ | ||
99 | CCNT(timer1); | ||
100 | } | ||
101 | |||
102 | if (doRecive) | ||
103 | pos = corgi_ssp_ads7846_get(); | ||
104 | |||
105 | if (doSend) { | ||
106 | int cmd = ADSCTRL_PD0 | ADSCTRL_PD1 | (address << ADSCTRL_ADR_SH) | ADSCTRL_STS; | ||
107 | /* dummy command */ | ||
108 | corgi_ssp_ads7846_put(cmd); | ||
109 | corgi_ssp_ads7846_get(); | ||
110 | |||
111 | if (wait_time) { | ||
112 | /* Wait after HSync */ | ||
113 | CCNT(timer2); | ||
114 | if (timer2-timer1 > wait_time) { | ||
115 | /* too slow - timeout, try again */ | ||
116 | corgi_ts->machinfo->wait_hsync(); | ||
117 | /* get CCNT */ | ||
118 | CCNT(timer1); | ||
119 | /* Wait after HSync */ | ||
120 | CCNT(timer2); | ||
121 | } | ||
122 | while (timer2 - timer1 < wait_time) | ||
123 | CCNT(timer2); | ||
124 | } | ||
125 | corgi_ssp_ads7846_put(cmd); | ||
126 | if (wait_time && !(pmnc & 0x01)) | ||
127 | PMNC_SET(pmnc); | ||
128 | } | ||
129 | return pos; | ||
130 | } | ||
131 | |||
132 | static int read_xydata(struct corgi_ts *corgi_ts) | ||
133 | { | ||
134 | unsigned int x, y, z1, z2; | ||
135 | unsigned long flags, wait_time; | ||
136 | |||
137 | /* critical section */ | ||
138 | local_irq_save(flags); | ||
139 | corgi_ssp_ads7846_lock(); | ||
140 | wait_time = calc_waittime(corgi_ts); | ||
141 | |||
142 | /* Y-axis */ | ||
143 | sync_receive_data_send_cmd(corgi_ts, 0, 1, 1u, wait_time); | ||
144 | |||
145 | /* Y-axis */ | ||
146 | sync_receive_data_send_cmd(corgi_ts, 1, 1, 1u, wait_time); | ||
147 | |||
148 | /* X-axis */ | ||
149 | y = sync_receive_data_send_cmd(corgi_ts, 1, 1, 5u, wait_time); | ||
150 | |||
151 | /* Z1 */ | ||
152 | x = sync_receive_data_send_cmd(corgi_ts, 1, 1, 3u, wait_time); | ||
153 | |||
154 | /* Z2 */ | ||
155 | z1 = sync_receive_data_send_cmd(corgi_ts, 1, 1, 4u, wait_time); | ||
156 | z2 = sync_receive_data_send_cmd(corgi_ts, 1, 0, 4u, wait_time); | ||
157 | |||
158 | /* Power-Down Enable */ | ||
159 | corgi_ssp_ads7846_put((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
160 | corgi_ssp_ads7846_get(); | ||
161 | |||
162 | corgi_ssp_ads7846_unlock(); | ||
163 | local_irq_restore(flags); | ||
164 | |||
165 | if (x== 0 || y == 0 || z1 == 0 || (x * (z2 - z1) / z1) >= 15000) { | ||
166 | corgi_ts->tc.pressure = 0; | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | corgi_ts->tc.x = x; | ||
171 | corgi_ts->tc.y = y; | ||
172 | corgi_ts->tc.pressure = (x * (z2 - z1)) / z1; | ||
173 | return 1; | ||
174 | } | ||
175 | |||
176 | static void new_data(struct corgi_ts *corgi_ts) | ||
177 | { | ||
178 | struct input_dev *dev = corgi_ts->input; | ||
179 | |||
180 | if (corgi_ts->power_mode != PWR_MODE_ACTIVE) | ||
181 | return; | ||
182 | |||
183 | if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0) | ||
184 | return; | ||
185 | |||
186 | input_report_abs(dev, ABS_X, corgi_ts->tc.x); | ||
187 | input_report_abs(dev, ABS_Y, corgi_ts->tc.y); | ||
188 | input_report_abs(dev, ABS_PRESSURE, corgi_ts->tc.pressure); | ||
189 | input_report_key(dev, BTN_TOUCH, corgi_ts->pendown); | ||
190 | input_sync(dev); | ||
191 | } | ||
192 | |||
193 | static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) | ||
194 | { | ||
195 | if ((GPLR(IRQ_TO_GPIO(corgi_ts->irq_gpio)) & GPIO_bit(IRQ_TO_GPIO(corgi_ts->irq_gpio))) == 0) { | ||
196 | /* Disable Interrupt */ | ||
197 | set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_NONE); | ||
198 | if (read_xydata(corgi_ts)) { | ||
199 | corgi_ts->pendown = 1; | ||
200 | new_data(corgi_ts); | ||
201 | } | ||
202 | mod_timer(&corgi_ts->timer, jiffies + HZ / 100); | ||
203 | } else { | ||
204 | if (corgi_ts->pendown == 1 || corgi_ts->pendown == 2) { | ||
205 | mod_timer(&corgi_ts->timer, jiffies + HZ / 100); | ||
206 | corgi_ts->pendown++; | ||
207 | return; | ||
208 | } | ||
209 | |||
210 | if (corgi_ts->pendown) { | ||
211 | corgi_ts->tc.pressure = 0; | ||
212 | new_data(corgi_ts); | ||
213 | } | ||
214 | |||
215 | /* Enable Falling Edge */ | ||
216 | set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING); | ||
217 | corgi_ts->pendown = 0; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | static void corgi_ts_timer(unsigned long data) | ||
222 | { | ||
223 | struct corgi_ts *corgits_data = (struct corgi_ts *) data; | ||
224 | |||
225 | ts_interrupt_main(corgits_data, 1); | ||
226 | } | ||
227 | |||
228 | static irqreturn_t ts_interrupt(int irq, void *dev_id) | ||
229 | { | ||
230 | struct corgi_ts *corgits_data = dev_id; | ||
231 | |||
232 | ts_interrupt_main(corgits_data, 0); | ||
233 | return IRQ_HANDLED; | ||
234 | } | ||
235 | |||
236 | #ifdef CONFIG_PM | ||
237 | static int corgits_suspend(struct platform_device *dev, pm_message_t state) | ||
238 | { | ||
239 | struct corgi_ts *corgi_ts = platform_get_drvdata(dev); | ||
240 | |||
241 | if (corgi_ts->pendown) { | ||
242 | del_timer_sync(&corgi_ts->timer); | ||
243 | corgi_ts->tc.pressure = 0; | ||
244 | new_data(corgi_ts); | ||
245 | corgi_ts->pendown = 0; | ||
246 | } | ||
247 | corgi_ts->power_mode = PWR_MODE_SUSPEND; | ||
248 | |||
249 | corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static int corgits_resume(struct platform_device *dev) | ||
255 | { | ||
256 | struct corgi_ts *corgi_ts = platform_get_drvdata(dev); | ||
257 | |||
258 | corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
259 | /* Enable Falling Edge */ | ||
260 | set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING); | ||
261 | corgi_ts->power_mode = PWR_MODE_ACTIVE; | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | #else | ||
266 | #define corgits_suspend NULL | ||
267 | #define corgits_resume NULL | ||
268 | #endif | ||
269 | |||
270 | static int __devinit corgits_probe(struct platform_device *pdev) | ||
271 | { | ||
272 | struct corgi_ts *corgi_ts; | ||
273 | struct input_dev *input_dev; | ||
274 | int err = -ENOMEM; | ||
275 | |||
276 | corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL); | ||
277 | input_dev = input_allocate_device(); | ||
278 | if (!corgi_ts || !input_dev) | ||
279 | goto fail1; | ||
280 | |||
281 | platform_set_drvdata(pdev, corgi_ts); | ||
282 | |||
283 | corgi_ts->machinfo = pdev->dev.platform_data; | ||
284 | corgi_ts->irq_gpio = platform_get_irq(pdev, 0); | ||
285 | |||
286 | if (corgi_ts->irq_gpio < 0) { | ||
287 | err = -ENODEV; | ||
288 | goto fail1; | ||
289 | } | ||
290 | |||
291 | corgi_ts->input = input_dev; | ||
292 | |||
293 | init_timer(&corgi_ts->timer); | ||
294 | corgi_ts->timer.data = (unsigned long) corgi_ts; | ||
295 | corgi_ts->timer.function = corgi_ts_timer; | ||
296 | |||
297 | input_dev->name = "Corgi Touchscreen"; | ||
298 | input_dev->phys = "corgits/input0"; | ||
299 | input_dev->id.bustype = BUS_HOST; | ||
300 | input_dev->id.vendor = 0x0001; | ||
301 | input_dev->id.product = 0x0002; | ||
302 | input_dev->id.version = 0x0100; | ||
303 | input_dev->dev.parent = &pdev->dev; | ||
304 | |||
305 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
306 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
307 | input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0); | ||
308 | input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0); | ||
309 | input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0); | ||
310 | |||
311 | pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN); | ||
312 | |||
313 | /* Initiaize ADS7846 Difference Reference mode */ | ||
314 | corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
315 | mdelay(5); | ||
316 | corgi_ssp_ads7846_putget((3u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
317 | mdelay(5); | ||
318 | corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
319 | mdelay(5); | ||
320 | corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
321 | mdelay(5); | ||
322 | |||
323 | if (request_irq(corgi_ts->irq_gpio, ts_interrupt, IRQF_DISABLED, "ts", corgi_ts)) { | ||
324 | err = -EBUSY; | ||
325 | goto fail1; | ||
326 | } | ||
327 | |||
328 | err = input_register_device(corgi_ts->input); | ||
329 | if (err) | ||
330 | goto fail2; | ||
331 | |||
332 | corgi_ts->power_mode = PWR_MODE_ACTIVE; | ||
333 | |||
334 | /* Enable Falling Edge */ | ||
335 | set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING); | ||
336 | |||
337 | return 0; | ||
338 | |||
339 | fail2: free_irq(corgi_ts->irq_gpio, corgi_ts); | ||
340 | fail1: input_free_device(input_dev); | ||
341 | kfree(corgi_ts); | ||
342 | return err; | ||
343 | } | ||
344 | |||
345 | static int __devexit corgits_remove(struct platform_device *pdev) | ||
346 | { | ||
347 | struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); | ||
348 | |||
349 | free_irq(corgi_ts->irq_gpio, corgi_ts); | ||
350 | del_timer_sync(&corgi_ts->timer); | ||
351 | corgi_ts->machinfo->put_hsync(); | ||
352 | input_unregister_device(corgi_ts->input); | ||
353 | kfree(corgi_ts); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static struct platform_driver corgits_driver = { | ||
359 | .probe = corgits_probe, | ||
360 | .remove = __devexit_p(corgits_remove), | ||
361 | .suspend = corgits_suspend, | ||
362 | .resume = corgits_resume, | ||
363 | .driver = { | ||
364 | .name = "corgi-ts", | ||
365 | .owner = THIS_MODULE, | ||
366 | }, | ||
367 | }; | ||
368 | |||
369 | static int __init corgits_init(void) | ||
370 | { | ||
371 | return platform_driver_register(&corgits_driver); | ||
372 | } | ||
373 | |||
374 | static void __exit corgits_exit(void) | ||
375 | { | ||
376 | platform_driver_unregister(&corgits_driver); | ||
377 | } | ||
378 | |||
379 | module_init(corgits_init); | ||
380 | module_exit(corgits_exit); | ||
381 | |||
382 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | ||
383 | MODULE_DESCRIPTION("Corgi TouchScreen Driver"); | ||
384 | MODULE_LICENSE("GPL"); | ||
385 | MODULE_ALIAS("platform:corgi-ts"); | ||
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c new file mode 100644 index 000000000000..d0c3a7229adf --- /dev/null +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c | |||
@@ -0,0 +1,363 @@ | |||
1 | /* | ||
2 | * Driver for cypress touch screen controller | ||
3 | * | ||
4 | * Copyright (c) 2009 Aava Mobile | ||
5 | * | ||
6 | * Some cleanups by Alan Cox <alan@linux.intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <linux/input/cy8ctmg110_pdata.h> | ||
31 | |||
32 | #define CY8CTMG110_DRIVER_NAME "cy8ctmg110" | ||
33 | |||
34 | /* Touch coordinates */ | ||
35 | #define CY8CTMG110_X_MIN 0 | ||
36 | #define CY8CTMG110_Y_MIN 0 | ||
37 | #define CY8CTMG110_X_MAX 759 | ||
38 | #define CY8CTMG110_Y_MAX 465 | ||
39 | |||
40 | |||
41 | /* cy8ctmg110 register definitions */ | ||
42 | #define CY8CTMG110_TOUCH_WAKEUP_TIME 0 | ||
43 | #define CY8CTMG110_TOUCH_SLEEP_TIME 2 | ||
44 | #define CY8CTMG110_TOUCH_X1 3 | ||
45 | #define CY8CTMG110_TOUCH_Y1 5 | ||
46 | #define CY8CTMG110_TOUCH_X2 7 | ||
47 | #define CY8CTMG110_TOUCH_Y2 9 | ||
48 | #define CY8CTMG110_FINGERS 11 | ||
49 | #define CY8CTMG110_GESTURE 12 | ||
50 | #define CY8CTMG110_REG_MAX 13 | ||
51 | |||
52 | |||
53 | /* | ||
54 | * The touch driver structure. | ||
55 | */ | ||
56 | struct cy8ctmg110 { | ||
57 | struct input_dev *input; | ||
58 | char phys[32]; | ||
59 | struct i2c_client *client; | ||
60 | int reset_pin; | ||
61 | int irq_pin; | ||
62 | }; | ||
63 | |||
64 | /* | ||
65 | * cy8ctmg110_power is the routine that is called when touch hardware | ||
66 | * will powered off or on. | ||
67 | */ | ||
68 | static void cy8ctmg110_power(struct cy8ctmg110 *ts, bool poweron) | ||
69 | { | ||
70 | if (ts->reset_pin) | ||
71 | gpio_direction_output(ts->reset_pin, 1 - poweron); | ||
72 | } | ||
73 | |||
74 | static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg, | ||
75 | unsigned char len, unsigned char *value) | ||
76 | { | ||
77 | struct i2c_client *client = tsc->client; | ||
78 | int ret; | ||
79 | unsigned char i2c_data[6]; | ||
80 | |||
81 | BUG_ON(len > 5); | ||
82 | |||
83 | i2c_data[0] = reg; | ||
84 | memcpy(i2c_data + 1, value, len); | ||
85 | |||
86 | ret = i2c_master_send(client, i2c_data, len + 1); | ||
87 | if (ret != 1) { | ||
88 | dev_err(&client->dev, "i2c write data cmd failed\n"); | ||
89 | return ret ? ret : -EIO; | ||
90 | } | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static int cy8ctmg110_read_regs(struct cy8ctmg110 *tsc, | ||
96 | unsigned char *data, unsigned char len, unsigned char cmd) | ||
97 | { | ||
98 | struct i2c_client *client = tsc->client; | ||
99 | int ret; | ||
100 | struct i2c_msg msg[2] = { | ||
101 | /* first write slave position to i2c devices */ | ||
102 | { client->addr, 0, 1, &cmd }, | ||
103 | /* Second read data from position */ | ||
104 | { client->addr, I2C_M_RD, len, data } | ||
105 | }; | ||
106 | |||
107 | ret = i2c_transfer(client->adapter, msg, 2); | ||
108 | if (ret < 0) | ||
109 | return ret; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc) | ||
115 | { | ||
116 | struct input_dev *input = tsc->input; | ||
117 | unsigned char reg_p[CY8CTMG110_REG_MAX]; | ||
118 | int x, y; | ||
119 | |||
120 | memset(reg_p, 0, CY8CTMG110_REG_MAX); | ||
121 | |||
122 | /* Reading coordinates */ | ||
123 | if (cy8ctmg110_read_regs(tsc, reg_p, 9, CY8CTMG110_TOUCH_X1) != 0) | ||
124 | return -EIO; | ||
125 | |||
126 | y = reg_p[2] << 8 | reg_p[3]; | ||
127 | x = reg_p[0] << 8 | reg_p[1]; | ||
128 | |||
129 | /* Number of touch */ | ||
130 | if (reg_p[8] == 0) { | ||
131 | input_report_key(input, BTN_TOUCH, 0); | ||
132 | } else { | ||
133 | input_report_key(input, BTN_TOUCH, 1); | ||
134 | input_report_abs(input, ABS_X, x); | ||
135 | input_report_abs(input, ABS_Y, y); | ||
136 | } | ||
137 | |||
138 | input_sync(input); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int cy8ctmg110_set_sleepmode(struct cy8ctmg110 *ts, bool sleep) | ||
144 | { | ||
145 | unsigned char reg_p[3]; | ||
146 | |||
147 | if (sleep) { | ||
148 | reg_p[0] = 0x00; | ||
149 | reg_p[1] = 0xff; | ||
150 | reg_p[2] = 5; | ||
151 | } else { | ||
152 | reg_p[0] = 0x10; | ||
153 | reg_p[1] = 0xff; | ||
154 | reg_p[2] = 0; | ||
155 | } | ||
156 | |||
157 | return cy8ctmg110_write_regs(ts, CY8CTMG110_TOUCH_WAKEUP_TIME, 3, reg_p); | ||
158 | } | ||
159 | |||
160 | static irqreturn_t cy8ctmg110_irq_thread(int irq, void *dev_id) | ||
161 | { | ||
162 | struct cy8ctmg110 *tsc = dev_id; | ||
163 | |||
164 | cy8ctmg110_touch_pos(tsc); | ||
165 | |||
166 | return IRQ_HANDLED; | ||
167 | } | ||
168 | |||
169 | static int __devinit cy8ctmg110_probe(struct i2c_client *client, | ||
170 | const struct i2c_device_id *id) | ||
171 | { | ||
172 | const struct cy8ctmg110_pdata *pdata = client->dev.platform_data; | ||
173 | struct cy8ctmg110 *ts; | ||
174 | struct input_dev *input_dev; | ||
175 | int err; | ||
176 | |||
177 | /* No pdata no way forward */ | ||
178 | if (pdata == NULL) { | ||
179 | dev_err(&client->dev, "no pdata\n"); | ||
180 | return -ENODEV; | ||
181 | } | ||
182 | |||
183 | if (!i2c_check_functionality(client->adapter, | ||
184 | I2C_FUNC_SMBUS_READ_WORD_DATA)) | ||
185 | return -EIO; | ||
186 | |||
187 | ts = kzalloc(sizeof(struct cy8ctmg110), GFP_KERNEL); | ||
188 | input_dev = input_allocate_device(); | ||
189 | if (!ts || !input_dev) { | ||
190 | err = -ENOMEM; | ||
191 | goto err_free_mem; | ||
192 | } | ||
193 | |||
194 | ts->client = client; | ||
195 | ts->input = input_dev; | ||
196 | |||
197 | snprintf(ts->phys, sizeof(ts->phys), | ||
198 | "%s/input0", dev_name(&client->dev)); | ||
199 | |||
200 | input_dev->name = CY8CTMG110_DRIVER_NAME " Touchscreen"; | ||
201 | input_dev->phys = ts->phys; | ||
202 | input_dev->id.bustype = BUS_I2C; | ||
203 | input_dev->dev.parent = &client->dev; | ||
204 | |||
205 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
206 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
207 | |||
208 | input_set_abs_params(input_dev, ABS_X, | ||
209 | CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 4, 0); | ||
210 | input_set_abs_params(input_dev, ABS_Y, | ||
211 | CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 4, 0); | ||
212 | |||
213 | if (ts->reset_pin) { | ||
214 | err = gpio_request(ts->reset_pin, NULL); | ||
215 | if (err) { | ||
216 | dev_err(&client->dev, | ||
217 | "Unable to request GPIO pin %d.\n", | ||
218 | ts->reset_pin); | ||
219 | goto err_free_mem; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | cy8ctmg110_power(ts, true); | ||
224 | cy8ctmg110_set_sleepmode(ts, false); | ||
225 | |||
226 | err = gpio_request(ts->irq_pin, "touch_irq_key"); | ||
227 | if (err < 0) { | ||
228 | dev_err(&client->dev, | ||
229 | "Failed to request GPIO %d, error %d\n", | ||
230 | ts->irq_pin, err); | ||
231 | goto err_shutoff_device; | ||
232 | } | ||
233 | |||
234 | err = gpio_direction_input(ts->irq_pin); | ||
235 | if (err < 0) { | ||
236 | dev_err(&client->dev, | ||
237 | "Failed to configure input direction for GPIO %d, error %d\n", | ||
238 | ts->irq_pin, err); | ||
239 | goto err_free_irq_gpio; | ||
240 | } | ||
241 | |||
242 | client->irq = gpio_to_irq(ts->irq_pin); | ||
243 | if (client->irq < 0) { | ||
244 | err = client->irq; | ||
245 | dev_err(&client->dev, | ||
246 | "Unable to get irq number for GPIO %d, error %d\n", | ||
247 | ts->irq_pin, err); | ||
248 | goto err_free_irq_gpio; | ||
249 | } | ||
250 | |||
251 | err = request_threaded_irq(client->irq, NULL, cy8ctmg110_irq_thread, | ||
252 | IRQF_TRIGGER_RISING, "touch_reset_key", ts); | ||
253 | if (err < 0) { | ||
254 | dev_err(&client->dev, | ||
255 | "irq %d busy? error %d\n", client->irq, err); | ||
256 | goto err_free_irq_gpio; | ||
257 | } | ||
258 | |||
259 | err = input_register_device(input_dev); | ||
260 | if (err) | ||
261 | goto err_free_irq; | ||
262 | |||
263 | i2c_set_clientdata(client, ts); | ||
264 | device_init_wakeup(&client->dev, 1); | ||
265 | return 0; | ||
266 | |||
267 | err_free_irq: | ||
268 | free_irq(client->irq, ts); | ||
269 | err_free_irq_gpio: | ||
270 | gpio_free(ts->irq_pin); | ||
271 | err_shutoff_device: | ||
272 | cy8ctmg110_set_sleepmode(ts, true); | ||
273 | cy8ctmg110_power(ts, false); | ||
274 | if (ts->reset_pin) | ||
275 | gpio_free(ts->reset_pin); | ||
276 | err_free_mem: | ||
277 | input_free_device(input_dev); | ||
278 | kfree(ts); | ||
279 | return err; | ||
280 | } | ||
281 | |||
282 | #ifdef CONFIG_PM | ||
283 | static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) | ||
284 | { | ||
285 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | ||
286 | |||
287 | if (device_may_wakeup(&client->dev)) | ||
288 | enable_irq_wake(client->irq); | ||
289 | else { | ||
290 | cy8ctmg110_set_sleepmode(ts, true); | ||
291 | cy8ctmg110_power(ts, false); | ||
292 | } | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int cy8ctmg110_resume(struct i2c_client *client) | ||
297 | { | ||
298 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | ||
299 | |||
300 | if (device_may_wakeup(&client->dev)) | ||
301 | disable_irq_wake(client->irq); | ||
302 | else { | ||
303 | cy8ctmg110_power(ts, true); | ||
304 | cy8ctmg110_set_sleepmode(ts, false); | ||
305 | } | ||
306 | return 0; | ||
307 | } | ||
308 | #endif | ||
309 | |||
310 | static int __devexit cy8ctmg110_remove(struct i2c_client *client) | ||
311 | { | ||
312 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | ||
313 | |||
314 | cy8ctmg110_set_sleepmode(ts, true); | ||
315 | cy8ctmg110_power(ts, false); | ||
316 | |||
317 | free_irq(client->irq, ts); | ||
318 | input_unregister_device(ts->input); | ||
319 | gpio_free(ts->irq_pin); | ||
320 | if (ts->reset_pin) | ||
321 | gpio_free(ts->reset_pin); | ||
322 | kfree(ts); | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static struct i2c_device_id cy8ctmg110_idtable[] = { | ||
328 | { CY8CTMG110_DRIVER_NAME, 1 }, | ||
329 | { } | ||
330 | }; | ||
331 | |||
332 | MODULE_DEVICE_TABLE(i2c, cy8ctmg110_idtable); | ||
333 | |||
334 | static struct i2c_driver cy8ctmg110_driver = { | ||
335 | .driver = { | ||
336 | .owner = THIS_MODULE, | ||
337 | .name = CY8CTMG110_DRIVER_NAME, | ||
338 | }, | ||
339 | .id_table = cy8ctmg110_idtable, | ||
340 | .probe = cy8ctmg110_probe, | ||
341 | .remove = __devexit_p(cy8ctmg110_remove), | ||
342 | #ifdef CONFIG_PM | ||
343 | .suspend = cy8ctmg110_suspend, | ||
344 | .resume = cy8ctmg110_resume, | ||
345 | #endif | ||
346 | }; | ||
347 | |||
348 | static int __init cy8ctmg110_init(void) | ||
349 | { | ||
350 | return i2c_add_driver(&cy8ctmg110_driver); | ||
351 | } | ||
352 | |||
353 | static void __exit cy8ctmg110_exit(void) | ||
354 | { | ||
355 | i2c_del_driver(&cy8ctmg110_driver); | ||
356 | } | ||
357 | |||
358 | module_init(cy8ctmg110_init); | ||
359 | module_exit(cy8ctmg110_exit); | ||
360 | |||
361 | MODULE_AUTHOR("Samuli Konttila <samuli.konttila@aavamobile.com>"); | ||
362 | MODULE_DESCRIPTION("cy8ctmg110 TouchScreen Driver"); | ||
363 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c index 3ffd4c4b170c..2b72a5923c16 100644 --- a/drivers/input/touchscreen/da9034-ts.c +++ b/drivers/input/touchscreen/da9034-ts.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/workqueue.h> | 20 | #include <linux/workqueue.h> |
21 | #include <linux/mfd/da903x.h> | 21 | #include <linux/mfd/da903x.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | #define DA9034_MANUAL_CTRL 0x50 | 24 | #define DA9034_MANUAL_CTRL 0x50 |
24 | #define DA9034_LDO_ADC_EN (1 << 4) | 25 | #define DA9034_LDO_ADC_EN (1 << 4) |
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 9029bd3f34e5..7a3a916f84a8 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/timer.h> | 33 | #include <linux/timer.h> |
34 | #include <linux/gpio.h> | 34 | #include <linux/gpio.h> |
35 | #include <linux/input/eeti_ts.h> | 35 | #include <linux/input/eeti_ts.h> |
36 | #include <linux/slab.h> | ||
36 | 37 | ||
37 | static int flip_x; | 38 | static int flip_x; |
38 | module_param(flip_x, bool, 0644); | 39 | module_param(flip_x, bool, 0644); |
@@ -123,14 +124,25 @@ static irqreturn_t eeti_ts_isr(int irq, void *dev_id) | |||
123 | return IRQ_HANDLED; | 124 | return IRQ_HANDLED; |
124 | } | 125 | } |
125 | 126 | ||
126 | static int eeti_ts_open(struct input_dev *dev) | 127 | static void eeti_ts_start(struct eeti_ts_priv *priv) |
127 | { | 128 | { |
128 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | ||
129 | |||
130 | enable_irq(priv->irq); | 129 | enable_irq(priv->irq); |
131 | 130 | ||
132 | /* Read the events once to arm the IRQ */ | 131 | /* Read the events once to arm the IRQ */ |
133 | eeti_ts_read(&priv->work); | 132 | eeti_ts_read(&priv->work); |
133 | } | ||
134 | |||
135 | static void eeti_ts_stop(struct eeti_ts_priv *priv) | ||
136 | { | ||
137 | disable_irq(priv->irq); | ||
138 | cancel_work_sync(&priv->work); | ||
139 | } | ||
140 | |||
141 | static int eeti_ts_open(struct input_dev *dev) | ||
142 | { | ||
143 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | ||
144 | |||
145 | eeti_ts_start(priv); | ||
134 | 146 | ||
135 | return 0; | 147 | return 0; |
136 | } | 148 | } |
@@ -139,8 +151,7 @@ static void eeti_ts_close(struct input_dev *dev) | |||
139 | { | 151 | { |
140 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | 152 | struct eeti_ts_priv *priv = input_get_drvdata(dev); |
141 | 153 | ||
142 | disable_irq(priv->irq); | 154 | eeti_ts_stop(priv); |
143 | cancel_work_sync(&priv->work); | ||
144 | } | 155 | } |
145 | 156 | ||
146 | static int __devinit eeti_ts_probe(struct i2c_client *client, | 157 | static int __devinit eeti_ts_probe(struct i2c_client *client, |
@@ -152,10 +163,12 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
152 | unsigned int irq_flags; | 163 | unsigned int irq_flags; |
153 | int err = -ENOMEM; | 164 | int err = -ENOMEM; |
154 | 165 | ||
155 | /* In contrast to what's described in the datasheet, there seems | 166 | /* |
167 | * In contrast to what's described in the datasheet, there seems | ||
156 | * to be no way of probing the presence of that device using I2C | 168 | * to be no way of probing the presence of that device using I2C |
157 | * commands. So we need to blindly believe it is there, and wait | 169 | * commands. So we need to blindly believe it is there, and wait |
158 | * for interrupts to occur. */ | 170 | * for interrupts to occur. |
171 | */ | ||
159 | 172 | ||
160 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 173 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
161 | if (!priv) { | 174 | if (!priv) { |
@@ -211,9 +224,11 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
211 | goto err2; | 224 | goto err2; |
212 | } | 225 | } |
213 | 226 | ||
214 | /* Disable the irq for now. It will be enabled once the input device | 227 | /* |
215 | * is opened. */ | 228 | * Disable the device for now. It will be enabled once the |
216 | disable_irq(priv->irq); | 229 | * input device is opened. |
230 | */ | ||
231 | eeti_ts_stop(priv); | ||
217 | 232 | ||
218 | device_init_wakeup(&client->dev, 0); | 233 | device_init_wakeup(&client->dev, 0); |
219 | return 0; | 234 | return 0; |
@@ -223,7 +238,6 @@ err2: | |||
223 | input = NULL; /* so we dont try to free it below */ | 238 | input = NULL; /* so we dont try to free it below */ |
224 | err1: | 239 | err1: |
225 | input_free_device(input); | 240 | input_free_device(input); |
226 | i2c_set_clientdata(client, NULL); | ||
227 | kfree(priv); | 241 | kfree(priv); |
228 | err0: | 242 | err0: |
229 | return err; | 243 | return err; |
@@ -234,8 +248,13 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) | |||
234 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 248 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
235 | 249 | ||
236 | free_irq(priv->irq, priv); | 250 | free_irq(priv->irq, priv); |
251 | /* | ||
252 | * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it | ||
253 | * so that device still works if we reload the driver. | ||
254 | */ | ||
255 | enable_irq(priv->irq); | ||
256 | |||
237 | input_unregister_device(priv->input); | 257 | input_unregister_device(priv->input); |
238 | i2c_set_clientdata(client, NULL); | ||
239 | kfree(priv); | 258 | kfree(priv); |
240 | 259 | ||
241 | return 0; | 260 | return 0; |
@@ -245,6 +264,14 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) | |||
245 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 264 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) |
246 | { | 265 | { |
247 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 266 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
267 | struct input_dev *input_dev = priv->input; | ||
268 | |||
269 | mutex_lock(&input_dev->mutex); | ||
270 | |||
271 | if (input_dev->users) | ||
272 | eeti_ts_stop(priv); | ||
273 | |||
274 | mutex_unlock(&input_dev->mutex); | ||
248 | 275 | ||
249 | if (device_may_wakeup(&client->dev)) | 276 | if (device_may_wakeup(&client->dev)) |
250 | enable_irq_wake(priv->irq); | 277 | enable_irq_wake(priv->irq); |
@@ -255,10 +282,18 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | |||
255 | static int eeti_ts_resume(struct i2c_client *client) | 282 | static int eeti_ts_resume(struct i2c_client *client) |
256 | { | 283 | { |
257 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 284 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
285 | struct input_dev *input_dev = priv->input; | ||
258 | 286 | ||
259 | if (device_may_wakeup(&client->dev)) | 287 | if (device_may_wakeup(&client->dev)) |
260 | disable_irq_wake(priv->irq); | 288 | disable_irq_wake(priv->irq); |
261 | 289 | ||
290 | mutex_lock(&input_dev->mutex); | ||
291 | |||
292 | if (input_dev->users) | ||
293 | eeti_ts_start(priv); | ||
294 | |||
295 | mutex_unlock(&input_dev->mutex); | ||
296 | |||
262 | return 0; | 297 | return 0; |
263 | } | 298 | } |
264 | #else | 299 | #else |
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 8f38c5e55ce6..486d31ba9c09 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c | |||
@@ -72,45 +72,49 @@ static void elo_process_data_10(struct elo *elo, unsigned char data) | |||
72 | struct input_dev *dev = elo->dev; | 72 | struct input_dev *dev = elo->dev; |
73 | 73 | ||
74 | elo->data[elo->idx] = data; | 74 | elo->data[elo->idx] = data; |
75 | switch (elo->idx++) { | ||
76 | case 0: | ||
77 | elo->csum = 0xaa; | ||
78 | if (data != ELO10_LEAD_BYTE) { | ||
79 | pr_debug("elo: unsynchronized data: 0x%02x\n", data); | ||
80 | elo->idx = 0; | ||
81 | } | ||
82 | break; | ||
83 | 75 | ||
84 | case 9: | 76 | switch (elo->idx++) { |
77 | case 0: | ||
78 | elo->csum = 0xaa; | ||
79 | if (data != ELO10_LEAD_BYTE) { | ||
80 | dev_dbg(&elo->serio->dev, | ||
81 | "unsynchronized data: 0x%02x\n", data); | ||
85 | elo->idx = 0; | 82 | elo->idx = 0; |
86 | if (data != elo->csum) { | 83 | } |
87 | pr_debug("elo: bad checksum: 0x%02x, expected 0x%02x\n", | 84 | break; |
88 | data, elo->csum); | 85 | |
89 | break; | 86 | case 9: |
90 | } | 87 | elo->idx = 0; |
91 | if (elo->data[1] != elo->expected_packet) { | 88 | if (data != elo->csum) { |
92 | if (elo->data[1] != ELO10_TOUCH_PACKET) | 89 | dev_dbg(&elo->serio->dev, |
93 | pr_debug("elo: unexpected packet: 0x%02x\n", | 90 | "bad checksum: 0x%02x, expected 0x%02x\n", |
94 | elo->data[1]); | 91 | data, elo->csum); |
95 | break; | 92 | break; |
96 | } | 93 | } |
97 | if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) { | 94 | if (elo->data[1] != elo->expected_packet) { |
98 | input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); | 95 | if (elo->data[1] != ELO10_TOUCH_PACKET) |
99 | input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); | 96 | dev_dbg(&elo->serio->dev, |
100 | if (elo->data[2] & ELO10_PRESSURE) | 97 | "unexpected packet: 0x%02x\n", |
101 | input_report_abs(dev, ABS_PRESSURE, | 98 | elo->data[1]); |
102 | (elo->data[8] << 8) | elo->data[7]); | ||
103 | input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH); | ||
104 | input_sync(dev); | ||
105 | } else if (elo->data[1] == ELO10_ACK_PACKET) { | ||
106 | if (elo->data[2] == '0') | ||
107 | elo->expected_packet = ELO10_TOUCH_PACKET; | ||
108 | complete(&elo->cmd_done); | ||
109 | } else { | ||
110 | memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN); | ||
111 | elo->expected_packet = ELO10_ACK_PACKET; | ||
112 | } | ||
113 | break; | 99 | break; |
100 | } | ||
101 | if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) { | ||
102 | input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); | ||
103 | input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); | ||
104 | if (elo->data[2] & ELO10_PRESSURE) | ||
105 | input_report_abs(dev, ABS_PRESSURE, | ||
106 | (elo->data[8] << 8) | elo->data[7]); | ||
107 | input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH); | ||
108 | input_sync(dev); | ||
109 | } else if (elo->data[1] == ELO10_ACK_PACKET) { | ||
110 | if (elo->data[2] == '0') | ||
111 | elo->expected_packet = ELO10_TOUCH_PACKET; | ||
112 | complete(&elo->cmd_done); | ||
113 | } else { | ||
114 | memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN); | ||
115 | elo->expected_packet = ELO10_ACK_PACKET; | ||
116 | } | ||
117 | break; | ||
114 | } | 118 | } |
115 | elo->csum += data; | 119 | elo->csum += data; |
116 | } | 120 | } |
@@ -123,42 +127,53 @@ static void elo_process_data_6(struct elo *elo, unsigned char data) | |||
123 | 127 | ||
124 | switch (elo->idx++) { | 128 | switch (elo->idx++) { |
125 | 129 | ||
126 | case 0: if ((data & 0xc0) != 0xc0) elo->idx = 0; break; | 130 | case 0: |
127 | case 1: if ((data & 0xc0) != 0x80) elo->idx = 0; break; | 131 | if ((data & 0xc0) != 0xc0) |
128 | case 2: if ((data & 0xc0) != 0x40) elo->idx = 0; break; | 132 | elo->idx = 0; |
129 | 133 | break; | |
130 | case 3: | ||
131 | if (data & 0xc0) { | ||
132 | elo->idx = 0; | ||
133 | break; | ||
134 | } | ||
135 | 134 | ||
136 | input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f)); | 135 | case 1: |
137 | input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f)); | 136 | if ((data & 0xc0) != 0x80) |
137 | elo->idx = 0; | ||
138 | break; | ||
138 | 139 | ||
139 | if (elo->id == 2) { | 140 | case 2: |
140 | input_report_key(dev, BTN_TOUCH, 1); | 141 | if ((data & 0xc0) != 0x40) |
141 | input_sync(dev); | 142 | elo->idx = 0; |
142 | elo->idx = 0; | 143 | break; |
143 | } | ||
144 | 144 | ||
145 | case 3: | ||
146 | if (data & 0xc0) { | ||
147 | elo->idx = 0; | ||
145 | break; | 148 | break; |
149 | } | ||
146 | 150 | ||
147 | case 4: | 151 | input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f)); |
148 | if (data) { | 152 | input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f)); |
149 | input_sync(dev); | ||
150 | elo->idx = 0; | ||
151 | } | ||
152 | break; | ||
153 | 153 | ||
154 | case 5: | 154 | if (elo->id == 2) { |
155 | if ((data & 0xf0) == 0) { | 155 | input_report_key(dev, BTN_TOUCH, 1); |
156 | input_report_abs(dev, ABS_PRESSURE, elo->data[5]); | ||
157 | input_report_key(dev, BTN_TOUCH, !!elo->data[5]); | ||
158 | } | ||
159 | input_sync(dev); | 156 | input_sync(dev); |
160 | elo->idx = 0; | 157 | elo->idx = 0; |
161 | break; | 158 | } |
159 | |||
160 | break; | ||
161 | |||
162 | case 4: | ||
163 | if (data) { | ||
164 | input_sync(dev); | ||
165 | elo->idx = 0; | ||
166 | } | ||
167 | break; | ||
168 | |||
169 | case 5: | ||
170 | if ((data & 0xf0) == 0) { | ||
171 | input_report_abs(dev, ABS_PRESSURE, elo->data[5]); | ||
172 | input_report_key(dev, BTN_TOUCH, !!elo->data[5]); | ||
173 | } | ||
174 | input_sync(dev); | ||
175 | elo->idx = 0; | ||
176 | break; | ||
162 | } | 177 | } |
163 | } | 178 | } |
164 | 179 | ||
@@ -170,17 +185,17 @@ static void elo_process_data_3(struct elo *elo, unsigned char data) | |||
170 | 185 | ||
171 | switch (elo->idx++) { | 186 | switch (elo->idx++) { |
172 | 187 | ||
173 | case 0: | 188 | case 0: |
174 | if ((data & 0x7f) != 0x01) | 189 | if ((data & 0x7f) != 0x01) |
175 | elo->idx = 0; | ||
176 | break; | ||
177 | case 2: | ||
178 | input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80)); | ||
179 | input_report_abs(dev, ABS_X, elo->data[1]); | ||
180 | input_report_abs(dev, ABS_Y, elo->data[2]); | ||
181 | input_sync(dev); | ||
182 | elo->idx = 0; | 190 | elo->idx = 0; |
183 | break; | 191 | break; |
192 | case 2: | ||
193 | input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80)); | ||
194 | input_report_abs(dev, ABS_X, elo->data[1]); | ||
195 | input_report_abs(dev, ABS_Y, elo->data[2]); | ||
196 | input_sync(dev); | ||
197 | elo->idx = 0; | ||
198 | break; | ||
184 | } | 199 | } |
185 | } | 200 | } |
186 | 201 | ||
@@ -189,19 +204,19 @@ static irqreturn_t elo_interrupt(struct serio *serio, | |||
189 | { | 204 | { |
190 | struct elo *elo = serio_get_drvdata(serio); | 205 | struct elo *elo = serio_get_drvdata(serio); |
191 | 206 | ||
192 | switch(elo->id) { | 207 | switch (elo->id) { |
193 | case 0: | 208 | case 0: |
194 | elo_process_data_10(elo, data); | 209 | elo_process_data_10(elo, data); |
195 | break; | 210 | break; |
196 | 211 | ||
197 | case 1: | 212 | case 1: |
198 | case 2: | 213 | case 2: |
199 | elo_process_data_6(elo, data); | 214 | elo_process_data_6(elo, data); |
200 | break; | 215 | break; |
201 | 216 | ||
202 | case 3: | 217 | case 3: |
203 | elo_process_data_3(elo, data); | 218 | elo_process_data_3(elo, data); |
204 | break; | 219 | break; |
205 | } | 220 | } |
206 | 221 | ||
207 | return IRQ_HANDLED; | 222 | return IRQ_HANDLED; |
@@ -261,10 +276,10 @@ static int elo_setup_10(struct elo *elo) | |||
261 | if (packet[3] & ELO10_PRESSURE) | 276 | if (packet[3] & ELO10_PRESSURE) |
262 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 277 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
263 | 278 | ||
264 | printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, " | 279 | dev_info(&elo->serio->dev, |
265 | "features: 0x%02x, controller: 0x%02x\n", | 280 | "%sTouch touchscreen, fw: %02x.%02x, features: 0x%02x, controller: 0x%02x\n", |
266 | elo_types[(packet[1] -'0') & 0x03], | 281 | elo_types[(packet[1] -'0') & 0x03], |
267 | packet[5], packet[4], packet[3], packet[7]); | 282 | packet[5], packet[4], packet[3], packet[7]); |
268 | 283 | ||
269 | return 0; | 284 | return 0; |
270 | } | 285 | } |
@@ -330,24 +345,24 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) | |||
330 | 345 | ||
331 | switch (elo->id) { | 346 | switch (elo->id) { |
332 | 347 | ||
333 | case 0: /* 10-byte protocol */ | 348 | case 0: /* 10-byte protocol */ |
334 | if (elo_setup_10(elo)) | 349 | if (elo_setup_10(elo)) |
335 | goto fail3; | 350 | goto fail3; |
336 | 351 | ||
337 | break; | 352 | break; |
338 | 353 | ||
339 | case 1: /* 6-byte protocol */ | 354 | case 1: /* 6-byte protocol */ |
340 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0); | 355 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0); |
341 | 356 | ||
342 | case 2: /* 4-byte protocol */ | 357 | case 2: /* 4-byte protocol */ |
343 | input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); | 358 | input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); |
344 | input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); | 359 | input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); |
345 | break; | 360 | break; |
346 | 361 | ||
347 | case 3: /* 3-byte protocol */ | 362 | case 3: /* 3-byte protocol */ |
348 | input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0); | 363 | input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0); |
349 | input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0); | 364 | input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0); |
350 | break; | 365 | break; |
351 | } | 366 | } |
352 | 367 | ||
353 | err = input_register_device(elo->dev); | 368 | err = input_register_device(elo->dev); |
diff --git a/drivers/input/touchscreen/hampshire.c b/drivers/input/touchscreen/hampshire.c new file mode 100644 index 000000000000..2da6cc31bb21 --- /dev/null +++ b/drivers/input/touchscreen/hampshire.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * Hampshire serial touchscreen driver | ||
3 | * | ||
4 | * Copyright (c) 2010 Adam Bennett | ||
5 | * Based on the dynapro driver (c) Tias Guns | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License version 2 as published by | ||
12 | * the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | /* | ||
16 | * 2010/04/08 Adam Bennett <abennett72@gmail.com> | ||
17 | * Copied dynapro.c and edited for Hampshire 4-byte protocol | ||
18 | */ | ||
19 | |||
20 | #include <linux/errno.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <linux/serio.h> | ||
26 | #include <linux/init.h> | ||
27 | |||
28 | #define DRIVER_DESC "Hampshire serial touchscreen driver" | ||
29 | |||
30 | MODULE_AUTHOR("Adam Bennett <abennett72@gmail.com>"); | ||
31 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* | ||
35 | * Definitions & global arrays. | ||
36 | */ | ||
37 | |||
38 | #define HAMPSHIRE_FORMAT_TOUCH_BIT 0x40 | ||
39 | #define HAMPSHIRE_FORMAT_LENGTH 4 | ||
40 | #define HAMPSHIRE_RESPONSE_BEGIN_BYTE 0x80 | ||
41 | |||
42 | #define HAMPSHIRE_MIN_XC 0 | ||
43 | #define HAMPSHIRE_MAX_XC 0x1000 | ||
44 | #define HAMPSHIRE_MIN_YC 0 | ||
45 | #define HAMPSHIRE_MAX_YC 0x1000 | ||
46 | |||
47 | #define HAMPSHIRE_GET_XC(data) (((data[3] & 0x0c) >> 2) | (data[1] << 2) | ((data[0] & 0x38) << 6)) | ||
48 | #define HAMPSHIRE_GET_YC(data) ((data[3] & 0x03) | (data[2] << 2) | ((data[0] & 0x07) << 9)) | ||
49 | #define HAMPSHIRE_GET_TOUCHED(data) (HAMPSHIRE_FORMAT_TOUCH_BIT & data[0]) | ||
50 | |||
51 | /* | ||
52 | * Per-touchscreen data. | ||
53 | */ | ||
54 | |||
55 | struct hampshire { | ||
56 | struct input_dev *dev; | ||
57 | struct serio *serio; | ||
58 | int idx; | ||
59 | unsigned char data[HAMPSHIRE_FORMAT_LENGTH]; | ||
60 | char phys[32]; | ||
61 | }; | ||
62 | |||
63 | static void hampshire_process_data(struct hampshire *phampshire) | ||
64 | { | ||
65 | struct input_dev *dev = phampshire->dev; | ||
66 | |||
67 | if (HAMPSHIRE_FORMAT_LENGTH == ++phampshire->idx) { | ||
68 | input_report_abs(dev, ABS_X, HAMPSHIRE_GET_XC(phampshire->data)); | ||
69 | input_report_abs(dev, ABS_Y, HAMPSHIRE_GET_YC(phampshire->data)); | ||
70 | input_report_key(dev, BTN_TOUCH, | ||
71 | HAMPSHIRE_GET_TOUCHED(phampshire->data)); | ||
72 | input_sync(dev); | ||
73 | |||
74 | phampshire->idx = 0; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static irqreturn_t hampshire_interrupt(struct serio *serio, | ||
79 | unsigned char data, unsigned int flags) | ||
80 | { | ||
81 | struct hampshire *phampshire = serio_get_drvdata(serio); | ||
82 | |||
83 | phampshire->data[phampshire->idx] = data; | ||
84 | |||
85 | if (HAMPSHIRE_RESPONSE_BEGIN_BYTE & phampshire->data[0]) | ||
86 | hampshire_process_data(phampshire); | ||
87 | else | ||
88 | dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n", | ||
89 | phampshire->data[0]); | ||
90 | |||
91 | return IRQ_HANDLED; | ||
92 | } | ||
93 | |||
94 | static void hampshire_disconnect(struct serio *serio) | ||
95 | { | ||
96 | struct hampshire *phampshire = serio_get_drvdata(serio); | ||
97 | |||
98 | input_get_device(phampshire->dev); | ||
99 | input_unregister_device(phampshire->dev); | ||
100 | serio_close(serio); | ||
101 | serio_set_drvdata(serio, NULL); | ||
102 | input_put_device(phampshire->dev); | ||
103 | kfree(phampshire); | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * hampshire_connect() is the routine that is called when someone adds a | ||
108 | * new serio device that supports hampshire protocol and registers it as | ||
109 | * an input device. This is usually accomplished using inputattach. | ||
110 | */ | ||
111 | |||
112 | static int hampshire_connect(struct serio *serio, struct serio_driver *drv) | ||
113 | { | ||
114 | struct hampshire *phampshire; | ||
115 | struct input_dev *input_dev; | ||
116 | int err; | ||
117 | |||
118 | phampshire = kzalloc(sizeof(struct hampshire), GFP_KERNEL); | ||
119 | input_dev = input_allocate_device(); | ||
120 | if (!phampshire || !input_dev) { | ||
121 | err = -ENOMEM; | ||
122 | goto fail1; | ||
123 | } | ||
124 | |||
125 | phampshire->serio = serio; | ||
126 | phampshire->dev = input_dev; | ||
127 | snprintf(phampshire->phys, sizeof(phampshire->phys), | ||
128 | "%s/input0", serio->phys); | ||
129 | |||
130 | input_dev->name = "Hampshire Serial TouchScreen"; | ||
131 | input_dev->phys = phampshire->phys; | ||
132 | input_dev->id.bustype = BUS_RS232; | ||
133 | input_dev->id.vendor = SERIO_HAMPSHIRE; | ||
134 | input_dev->id.product = 0; | ||
135 | input_dev->id.version = 0x0001; | ||
136 | input_dev->dev.parent = &serio->dev; | ||
137 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
138 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
139 | input_set_abs_params(phampshire->dev, ABS_X, | ||
140 | HAMPSHIRE_MIN_XC, HAMPSHIRE_MAX_XC, 0, 0); | ||
141 | input_set_abs_params(phampshire->dev, ABS_Y, | ||
142 | HAMPSHIRE_MIN_YC, HAMPSHIRE_MAX_YC, 0, 0); | ||
143 | |||
144 | serio_set_drvdata(serio, phampshire); | ||
145 | |||
146 | err = serio_open(serio, drv); | ||
147 | if (err) | ||
148 | goto fail2; | ||
149 | |||
150 | err = input_register_device(phampshire->dev); | ||
151 | if (err) | ||
152 | goto fail3; | ||
153 | |||
154 | return 0; | ||
155 | |||
156 | fail3: serio_close(serio); | ||
157 | fail2: serio_set_drvdata(serio, NULL); | ||
158 | fail1: input_free_device(input_dev); | ||
159 | kfree(phampshire); | ||
160 | return err; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * The serio driver structure. | ||
165 | */ | ||
166 | |||
167 | static struct serio_device_id hampshire_serio_ids[] = { | ||
168 | { | ||
169 | .type = SERIO_RS232, | ||
170 | .proto = SERIO_HAMPSHIRE, | ||
171 | .id = SERIO_ANY, | ||
172 | .extra = SERIO_ANY, | ||
173 | }, | ||
174 | { 0 } | ||
175 | }; | ||
176 | |||
177 | MODULE_DEVICE_TABLE(serio, hampshire_serio_ids); | ||
178 | |||
179 | static struct serio_driver hampshire_drv = { | ||
180 | .driver = { | ||
181 | .name = "hampshire", | ||
182 | }, | ||
183 | .description = DRIVER_DESC, | ||
184 | .id_table = hampshire_serio_ids, | ||
185 | .interrupt = hampshire_interrupt, | ||
186 | .connect = hampshire_connect, | ||
187 | .disconnect = hampshire_disconnect, | ||
188 | }; | ||
189 | |||
190 | /* | ||
191 | * The functions for inserting/removing us as a module. | ||
192 | */ | ||
193 | |||
194 | static int __init hampshire_init(void) | ||
195 | { | ||
196 | return serio_register_driver(&hampshire_drv); | ||
197 | } | ||
198 | |||
199 | static void __exit hampshire_exit(void) | ||
200 | { | ||
201 | serio_unregister_driver(&hampshire_drv); | ||
202 | } | ||
203 | |||
204 | module_init(hampshire_init); | ||
205 | module_exit(hampshire_exit); | ||
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index a89700e7ace4..dd4e8f020b99 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
@@ -28,29 +28,29 @@ static void do_softint(struct work_struct *work) | |||
28 | u8 scpdr; | 28 | u8 scpdr; |
29 | int touched = 0; | 29 | int touched = 0; |
30 | 30 | ||
31 | if (ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN) { | 31 | if (__raw_readb(PHDR) & PHDR_TS_PEN_DOWN) { |
32 | scpdr = ctrl_inb(SCPDR); | 32 | scpdr = __raw_readb(SCPDR); |
33 | scpdr |= SCPDR_TS_SCAN_ENABLE; | 33 | scpdr |= SCPDR_TS_SCAN_ENABLE; |
34 | scpdr &= ~SCPDR_TS_SCAN_Y; | 34 | scpdr &= ~SCPDR_TS_SCAN_Y; |
35 | ctrl_outb(scpdr, SCPDR); | 35 | __raw_writeb(scpdr, SCPDR); |
36 | udelay(30); | 36 | udelay(30); |
37 | 37 | ||
38 | absy = adc_single(ADC_CHANNEL_TS_Y); | 38 | absy = adc_single(ADC_CHANNEL_TS_Y); |
39 | 39 | ||
40 | scpdr = ctrl_inb(SCPDR); | 40 | scpdr = __raw_readb(SCPDR); |
41 | scpdr |= SCPDR_TS_SCAN_Y; | 41 | scpdr |= SCPDR_TS_SCAN_Y; |
42 | scpdr &= ~SCPDR_TS_SCAN_X; | 42 | scpdr &= ~SCPDR_TS_SCAN_X; |
43 | ctrl_outb(scpdr, SCPDR); | 43 | __raw_writeb(scpdr, SCPDR); |
44 | udelay(30); | 44 | udelay(30); |
45 | 45 | ||
46 | absx = adc_single(ADC_CHANNEL_TS_X); | 46 | absx = adc_single(ADC_CHANNEL_TS_X); |
47 | 47 | ||
48 | scpdr = ctrl_inb(SCPDR); | 48 | scpdr = __raw_readb(SCPDR); |
49 | scpdr |= SCPDR_TS_SCAN_X; | 49 | scpdr |= SCPDR_TS_SCAN_X; |
50 | scpdr &= ~SCPDR_TS_SCAN_ENABLE; | 50 | scpdr &= ~SCPDR_TS_SCAN_ENABLE; |
51 | ctrl_outb(scpdr, SCPDR); | 51 | __raw_writeb(scpdr, SCPDR); |
52 | udelay(100); | 52 | udelay(100); |
53 | touched = ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN; | 53 | touched = __raw_readb(PHDR) & PHDR_TS_PEN_DOWN; |
54 | } | 54 | } |
55 | 55 | ||
56 | if (touched) { | 56 | if (touched) { |
@@ -107,8 +107,7 @@ static int __init hp680_ts_init(void) | |||
107 | return 0; | 107 | return 0; |
108 | 108 | ||
109 | fail2: free_irq(HP680_TS_IRQ, NULL); | 109 | fail2: free_irq(HP680_TS_IRQ, NULL); |
110 | cancel_delayed_work(&work); | 110 | cancel_delayed_work_sync(&work); |
111 | flush_scheduled_work(); | ||
112 | fail1: input_free_device(hp680_ts_dev); | 111 | fail1: input_free_device(hp680_ts_dev); |
113 | return err; | 112 | return err; |
114 | } | 113 | } |
@@ -116,8 +115,7 @@ static int __init hp680_ts_init(void) | |||
116 | static void __exit hp680_ts_exit(void) | 115 | static void __exit hp680_ts_exit(void) |
117 | { | 116 | { |
118 | free_irq(HP680_TS_IRQ, NULL); | 117 | free_irq(HP680_TS_IRQ, NULL); |
119 | cancel_delayed_work(&work); | 118 | cancel_delayed_work_sync(&work); |
120 | flush_scheduled_work(); | ||
121 | input_unregister_device(hp680_ts_dev); | 119 | input_unregister_device(hp680_ts_dev); |
122 | } | 120 | } |
123 | 121 | ||
diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c new file mode 100644 index 000000000000..c0307b22d86f --- /dev/null +++ b/drivers/input/touchscreen/intel-mid-touch.c | |||
@@ -0,0 +1,687 @@ | |||
1 | /* | ||
2 | * Intel MID Resistive Touch Screen Driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Intel Corp | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
20 | * | ||
21 | * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com) | ||
22 | * Ramesh Agarwal (ramesh.agarwal@intel.com) | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
24 | * | ||
25 | * TODO: | ||
26 | * review conversion of r/m/w sequences | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/input.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/err.h> | ||
34 | #include <linux/param.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/irq.h> | ||
38 | #include <linux/delay.h> | ||
39 | #include <asm/intel_scu_ipc.h> | ||
40 | |||
41 | /* PMIC Interrupt registers */ | ||
42 | #define PMIC_REG_ID1 0x00 /* PMIC ID1 register */ | ||
43 | |||
44 | /* PMIC Interrupt registers */ | ||
45 | #define PMIC_REG_INT 0x04 /* PMIC interrupt register */ | ||
46 | #define PMIC_REG_MINT 0x05 /* PMIC interrupt mask register */ | ||
47 | |||
48 | /* ADC Interrupt registers */ | ||
49 | #define PMIC_REG_ADCINT 0x5F /* ADC interrupt register */ | ||
50 | #define PMIC_REG_MADCINT 0x60 /* ADC interrupt mask register */ | ||
51 | |||
52 | /* ADC Control registers */ | ||
53 | #define PMIC_REG_ADCCNTL1 0x61 /* ADC control register */ | ||
54 | |||
55 | /* ADC Channel Selection registers */ | ||
56 | #define PMICADDR0 0xA4 | ||
57 | #define END_OF_CHANNEL 0x1F | ||
58 | |||
59 | /* ADC Result register */ | ||
60 | #define PMIC_REG_ADCSNS0H 0x64 | ||
61 | |||
62 | /* ADC channels for touch screen */ | ||
63 | #define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */ | ||
64 | #define MRST_TS_CHAN11 0xB /* Touch screen X- connection */ | ||
65 | #define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */ | ||
66 | #define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */ | ||
67 | |||
68 | /* Touch screen channel BIAS constants */ | ||
69 | #define MRST_XBIAS 0x20 | ||
70 | #define MRST_YBIAS 0x40 | ||
71 | #define MRST_ZBIAS 0x80 | ||
72 | |||
73 | /* Touch screen coordinates */ | ||
74 | #define MRST_X_MIN 10 | ||
75 | #define MRST_X_MAX 1024 | ||
76 | #define MRST_X_FUZZ 5 | ||
77 | #define MRST_Y_MIN 10 | ||
78 | #define MRST_Y_MAX 1024 | ||
79 | #define MRST_Y_FUZZ 5 | ||
80 | #define MRST_PRESSURE_MIN 0 | ||
81 | #define MRST_PRESSURE_NOMINAL 50 | ||
82 | #define MRST_PRESSURE_MAX 100 | ||
83 | |||
84 | #define WAIT_ADC_COMPLETION 10 /* msec */ | ||
85 | |||
86 | /* PMIC ADC round robin delays */ | ||
87 | #define ADC_LOOP_DELAY0 0x0 /* Continuous loop */ | ||
88 | #define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */ | ||
89 | |||
90 | /* PMIC Vendor Identifiers */ | ||
91 | #define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */ | ||
92 | #define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */ | ||
93 | #define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */ | ||
94 | #define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */ | ||
95 | |||
96 | /* Touch screen device structure */ | ||
97 | struct mrstouch_dev { | ||
98 | struct device *dev; /* device associated with touch screen */ | ||
99 | struct input_dev *input; | ||
100 | char phys[32]; | ||
101 | u16 asr; /* Address selection register */ | ||
102 | int irq; | ||
103 | unsigned int vendor; /* PMIC vendor */ | ||
104 | unsigned int rev; /* PMIC revision */ | ||
105 | |||
106 | int (*read_prepare)(struct mrstouch_dev *tsdev); | ||
107 | int (*read)(struct mrstouch_dev *tsdev, u16 *x, u16 *y, u16 *z); | ||
108 | int (*read_finish)(struct mrstouch_dev *tsdev); | ||
109 | }; | ||
110 | |||
111 | |||
112 | /*************************** NEC and Maxim Interface ************************/ | ||
113 | |||
114 | static int mrstouch_nec_adc_read_prepare(struct mrstouch_dev *tsdev) | ||
115 | { | ||
116 | return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0, 0x20); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Enables PENDET interrupt. | ||
121 | */ | ||
122 | static int mrstouch_nec_adc_read_finish(struct mrstouch_dev *tsdev) | ||
123 | { | ||
124 | int err; | ||
125 | |||
126 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x20, 0x20); | ||
127 | if (!err) | ||
128 | err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, 0, 0x05); | ||
129 | |||
130 | return err; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Reads PMIC ADC touch screen result | ||
135 | * Reads ADC storage registers for higher 7 and lower 3 bits and | ||
136 | * converts the two readings into a single value and turns off gain bit | ||
137 | */ | ||
138 | static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm) | ||
139 | { | ||
140 | int err; | ||
141 | u16 result; | ||
142 | u32 res; | ||
143 | |||
144 | result = PMIC_REG_ADCSNS0H + offset; | ||
145 | |||
146 | if (chan == MRST_TS_CHAN12) | ||
147 | result += 4; | ||
148 | |||
149 | err = intel_scu_ipc_ioread32(result, &res); | ||
150 | if (err) | ||
151 | return err; | ||
152 | |||
153 | /* Mash the bits up */ | ||
154 | |||
155 | *vp = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
156 | *vp |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
157 | *vp &= 0x3FF; | ||
158 | |||
159 | res >>= 16; | ||
160 | |||
161 | *vm = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
162 | *vm |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
163 | *vm &= 0x3FF; | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Enables X, Y and Z bias values | ||
170 | * Enables YPYM for X channels and XPXM for Y channels | ||
171 | */ | ||
172 | static int mrstouch_ts_bias_set(uint offset, uint bias) | ||
173 | { | ||
174 | int count; | ||
175 | u16 chan, start; | ||
176 | u16 reg[4]; | ||
177 | u8 data[4]; | ||
178 | |||
179 | chan = PMICADDR0 + offset; | ||
180 | start = MRST_TS_CHAN10; | ||
181 | |||
182 | for (count = 0; count <= 3; count++) { | ||
183 | reg[count] = chan++; | ||
184 | data[count] = bias | (start + count); | ||
185 | } | ||
186 | |||
187 | return intel_scu_ipc_writev(reg, data, 4); | ||
188 | } | ||
189 | |||
190 | /* To read touch screen channel values */ | ||
191 | static int mrstouch_nec_adc_read(struct mrstouch_dev *tsdev, | ||
192 | u16 *x, u16 *y, u16 *z) | ||
193 | { | ||
194 | int err; | ||
195 | u16 xm, ym, zm; | ||
196 | |||
197 | /* configure Y bias for X channels */ | ||
198 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_YBIAS); | ||
199 | if (err) | ||
200 | goto ipc_error; | ||
201 | |||
202 | msleep(WAIT_ADC_COMPLETION); | ||
203 | |||
204 | /* read x+ and x- channels */ | ||
205 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, x, &xm); | ||
206 | if (err) | ||
207 | goto ipc_error; | ||
208 | |||
209 | /* configure x bias for y channels */ | ||
210 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_XBIAS); | ||
211 | if (err) | ||
212 | goto ipc_error; | ||
213 | |||
214 | msleep(WAIT_ADC_COMPLETION); | ||
215 | |||
216 | /* read y+ and y- channels */ | ||
217 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, y, &ym); | ||
218 | if (err) | ||
219 | goto ipc_error; | ||
220 | |||
221 | /* configure z bias for x and y channels */ | ||
222 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_ZBIAS); | ||
223 | if (err) | ||
224 | goto ipc_error; | ||
225 | |||
226 | msleep(WAIT_ADC_COMPLETION); | ||
227 | |||
228 | /* read z+ and z- channels */ | ||
229 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, z, &zm); | ||
230 | if (err) | ||
231 | goto ipc_error; | ||
232 | |||
233 | return 0; | ||
234 | |||
235 | ipc_error: | ||
236 | dev_err(tsdev->dev, "ipc error during adc read\n"); | ||
237 | return err; | ||
238 | } | ||
239 | |||
240 | |||
241 | /*************************** Freescale Interface ************************/ | ||
242 | |||
243 | static int mrstouch_fs_adc_read_prepare(struct mrstouch_dev *tsdev) | ||
244 | { | ||
245 | int err, count; | ||
246 | u16 chan; | ||
247 | u16 reg[5]; | ||
248 | u8 data[5]; | ||
249 | |||
250 | /* Stop the ADC */ | ||
251 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02); | ||
252 | if (err) | ||
253 | goto ipc_error; | ||
254 | |||
255 | chan = PMICADDR0 + tsdev->asr; | ||
256 | |||
257 | /* Set X BIAS */ | ||
258 | for (count = 0; count <= 3; count++) { | ||
259 | reg[count] = chan++; | ||
260 | data[count] = 0x2A; | ||
261 | } | ||
262 | reg[count] = chan++; /* Dummy */ | ||
263 | data[count] = 0; | ||
264 | |||
265 | err = intel_scu_ipc_writev(reg, data, 5); | ||
266 | if (err) | ||
267 | goto ipc_error; | ||
268 | |||
269 | msleep(WAIT_ADC_COMPLETION); | ||
270 | |||
271 | /* Set Y BIAS */ | ||
272 | for (count = 0; count <= 3; count++) { | ||
273 | reg[count] = chan++; | ||
274 | data[count] = 0x4A; | ||
275 | } | ||
276 | reg[count] = chan++; /* Dummy */ | ||
277 | data[count] = 0; | ||
278 | |||
279 | err = intel_scu_ipc_writev(reg, data, 5); | ||
280 | if (err) | ||
281 | goto ipc_error; | ||
282 | |||
283 | msleep(WAIT_ADC_COMPLETION); | ||
284 | |||
285 | /* Set Z BIAS */ | ||
286 | err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A); | ||
287 | if (err) | ||
288 | goto ipc_error; | ||
289 | |||
290 | msleep(WAIT_ADC_COMPLETION); | ||
291 | |||
292 | return 0; | ||
293 | |||
294 | ipc_error: | ||
295 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
296 | return err; | ||
297 | } | ||
298 | |||
299 | static int mrstouch_fs_adc_read(struct mrstouch_dev *tsdev, | ||
300 | u16 *x, u16 *y, u16 *z) | ||
301 | { | ||
302 | int err; | ||
303 | u16 result; | ||
304 | u16 reg[4]; | ||
305 | u8 data[4]; | ||
306 | |||
307 | result = PMIC_REG_ADCSNS0H + tsdev->asr; | ||
308 | |||
309 | reg[0] = result + 4; | ||
310 | reg[1] = result + 5; | ||
311 | reg[2] = result + 16; | ||
312 | reg[3] = result + 17; | ||
313 | |||
314 | err = intel_scu_ipc_readv(reg, data, 4); | ||
315 | if (err) | ||
316 | goto ipc_error; | ||
317 | |||
318 | *x = data[0] << 3; /* Higher 7 bits */ | ||
319 | *x |= data[1] & 0x7; /* Lower 3 bits */ | ||
320 | *x &= 0x3FF; | ||
321 | |||
322 | *y = data[2] << 3; /* Higher 7 bits */ | ||
323 | *y |= data[3] & 0x7; /* Lower 3 bits */ | ||
324 | *y &= 0x3FF; | ||
325 | |||
326 | /* Read Z value */ | ||
327 | reg[0] = result + 28; | ||
328 | reg[1] = result + 29; | ||
329 | |||
330 | err = intel_scu_ipc_readv(reg, data, 4); | ||
331 | if (err) | ||
332 | goto ipc_error; | ||
333 | |||
334 | *z = data[0] << 3; /* Higher 7 bits */ | ||
335 | *z |= data[1] & 0x7; /* Lower 3 bits */ | ||
336 | *z &= 0x3FF; | ||
337 | |||
338 | return 0; | ||
339 | |||
340 | ipc_error: | ||
341 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
342 | return err; | ||
343 | } | ||
344 | |||
345 | static int mrstouch_fs_adc_read_finish(struct mrstouch_dev *tsdev) | ||
346 | { | ||
347 | int err, count; | ||
348 | u16 chan; | ||
349 | u16 reg[5]; | ||
350 | u8 data[5]; | ||
351 | |||
352 | /* Clear all TS channels */ | ||
353 | chan = PMICADDR0 + tsdev->asr; | ||
354 | for (count = 0; count <= 4; count++) { | ||
355 | reg[count] = chan++; | ||
356 | data[count] = 0; | ||
357 | } | ||
358 | err = intel_scu_ipc_writev(reg, data, 5); | ||
359 | if (err) | ||
360 | goto ipc_error; | ||
361 | |||
362 | for (count = 0; count <= 4; count++) { | ||
363 | reg[count] = chan++; | ||
364 | data[count] = 0; | ||
365 | } | ||
366 | err = intel_scu_ipc_writev(reg, data, 5); | ||
367 | if (err) | ||
368 | goto ipc_error; | ||
369 | |||
370 | err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000); | ||
371 | if (err) | ||
372 | goto ipc_error; | ||
373 | |||
374 | /* Start ADC */ | ||
375 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02); | ||
376 | if (err) | ||
377 | goto ipc_error; | ||
378 | |||
379 | return 0; | ||
380 | |||
381 | ipc_error: | ||
382 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
383 | return err; | ||
384 | } | ||
385 | |||
386 | static void mrstouch_report_event(struct input_dev *input, | ||
387 | unsigned int x, unsigned int y, unsigned int z) | ||
388 | { | ||
389 | if (z > MRST_PRESSURE_NOMINAL) { | ||
390 | /* Pen touched, report button touch and coordinates */ | ||
391 | input_report_key(input, BTN_TOUCH, 1); | ||
392 | input_report_abs(input, ABS_X, x); | ||
393 | input_report_abs(input, ABS_Y, y); | ||
394 | } else { | ||
395 | input_report_key(input, BTN_TOUCH, 0); | ||
396 | } | ||
397 | |||
398 | input_report_abs(input, ABS_PRESSURE, z); | ||
399 | input_sync(input); | ||
400 | } | ||
401 | |||
402 | /* PENDET interrupt handler */ | ||
403 | static irqreturn_t mrstouch_pendet_irq(int irq, void *dev_id) | ||
404 | { | ||
405 | struct mrstouch_dev *tsdev = dev_id; | ||
406 | u16 x, y, z; | ||
407 | |||
408 | /* | ||
409 | * Should we lower thread priority? Probably not, since we are | ||
410 | * not spinning but sleeping... | ||
411 | */ | ||
412 | |||
413 | if (tsdev->read_prepare(tsdev)) | ||
414 | goto out; | ||
415 | |||
416 | do { | ||
417 | if (tsdev->read(tsdev, &x, &y, &z)) | ||
418 | break; | ||
419 | |||
420 | mrstouch_report_event(tsdev->input, x, y, z); | ||
421 | } while (z > MRST_PRESSURE_NOMINAL); | ||
422 | |||
423 | tsdev->read_finish(tsdev); | ||
424 | |||
425 | out: | ||
426 | return IRQ_HANDLED; | ||
427 | } | ||
428 | |||
429 | /* Utility to read PMIC ID */ | ||
430 | static int __devinit mrstouch_read_pmic_id(uint *vendor, uint *rev) | ||
431 | { | ||
432 | int err; | ||
433 | u8 r; | ||
434 | |||
435 | err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r); | ||
436 | if (err) | ||
437 | return err; | ||
438 | |||
439 | *vendor = r & 0x7; | ||
440 | *rev = (r >> 3) & 0x7; | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * Parse ADC channels to find end of the channel configured by other ADC user | ||
447 | * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels | ||
448 | */ | ||
449 | static int __devinit mrstouch_chan_parse(struct mrstouch_dev *tsdev) | ||
450 | { | ||
451 | int err, i, found; | ||
452 | u8 r8; | ||
453 | |||
454 | found = -1; | ||
455 | |||
456 | for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) { | ||
457 | if (found >= 0) | ||
458 | break; | ||
459 | |||
460 | err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8); | ||
461 | if (err) | ||
462 | return err; | ||
463 | |||
464 | if (r8 == END_OF_CHANNEL) { | ||
465 | found = i; | ||
466 | break; | ||
467 | } | ||
468 | } | ||
469 | if (found < 0) | ||
470 | return 0; | ||
471 | |||
472 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
473 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 18)) | ||
474 | return -ENOSPC; | ||
475 | } else { | ||
476 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 4)) | ||
477 | return -ENOSPC; | ||
478 | } | ||
479 | return found; | ||
480 | } | ||
481 | |||
482 | |||
483 | /* | ||
484 | * Writes touch screen channels to ADC address selection registers | ||
485 | */ | ||
486 | static int __devinit mrstouch_ts_chan_set(uint offset) | ||
487 | { | ||
488 | u16 chan; | ||
489 | |||
490 | int ret, count; | ||
491 | |||
492 | chan = PMICADDR0 + offset; | ||
493 | for (count = 0; count <= 3; count++) { | ||
494 | ret = intel_scu_ipc_iowrite8(chan++, MRST_TS_CHAN10 + count); | ||
495 | if (ret) | ||
496 | return ret; | ||
497 | } | ||
498 | return intel_scu_ipc_iowrite8(chan++, END_OF_CHANNEL); | ||
499 | } | ||
500 | |||
501 | /* Initialize ADC */ | ||
502 | static int __devinit mrstouch_adc_init(struct mrstouch_dev *tsdev) | ||
503 | { | ||
504 | int err, start; | ||
505 | u8 ra, rm; | ||
506 | |||
507 | err = mrstouch_read_pmic_id(&tsdev->vendor, &tsdev->rev); | ||
508 | if (err) { | ||
509 | dev_err(tsdev->dev, "Unable to read PMIC id\n"); | ||
510 | return err; | ||
511 | } | ||
512 | |||
513 | switch (tsdev->vendor) { | ||
514 | case PMIC_VENDOR_NEC: | ||
515 | case PMIC_VENDOR_MAXIM: | ||
516 | tsdev->read_prepare = mrstouch_nec_adc_read_prepare; | ||
517 | tsdev->read = mrstouch_nec_adc_read; | ||
518 | tsdev->read_finish = mrstouch_nec_adc_read_finish; | ||
519 | break; | ||
520 | |||
521 | case PMIC_VENDOR_FS: | ||
522 | tsdev->read_prepare = mrstouch_fs_adc_read_prepare; | ||
523 | tsdev->read = mrstouch_fs_adc_read; | ||
524 | tsdev->read_finish = mrstouch_fs_adc_read_finish; | ||
525 | break; | ||
526 | |||
527 | default: | ||
528 | dev_err(tsdev->dev, | ||
529 | "Unsupported touchscreen: %d\n", tsdev->vendor); | ||
530 | return -ENXIO; | ||
531 | } | ||
532 | |||
533 | start = mrstouch_chan_parse(tsdev); | ||
534 | if (start < 0) { | ||
535 | dev_err(tsdev->dev, "Unable to parse channels\n"); | ||
536 | return start; | ||
537 | } | ||
538 | |||
539 | tsdev->asr = start; | ||
540 | |||
541 | /* | ||
542 | * ADC power on, start, enable PENDET and set loop delay | ||
543 | * ADC loop delay is set to 4.5 ms approximately | ||
544 | * Loop delay more than this results in jitter in adc readings | ||
545 | * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET | ||
546 | * interrupt generation sometimes. | ||
547 | */ | ||
548 | |||
549 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
550 | ra = 0xE0 | ADC_LOOP_DELAY0; | ||
551 | rm = 0x5; | ||
552 | } else { | ||
553 | /* NEC and MAXIm not consistent with loop delay 0 */ | ||
554 | ra = 0xE0 | ADC_LOOP_DELAY1; | ||
555 | rm = 0x0; | ||
556 | |||
557 | /* configure touch screen channels */ | ||
558 | err = mrstouch_ts_chan_set(tsdev->asr); | ||
559 | if (err) | ||
560 | return err; | ||
561 | } | ||
562 | |||
563 | err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7); | ||
564 | if (err) | ||
565 | return err; | ||
566 | |||
567 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03); | ||
568 | if (err) | ||
569 | return err; | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | |||
575 | /* Probe function for touch screen driver */ | ||
576 | static int __devinit mrstouch_probe(struct platform_device *pdev) | ||
577 | { | ||
578 | struct mrstouch_dev *tsdev; | ||
579 | struct input_dev *input; | ||
580 | int err; | ||
581 | int irq; | ||
582 | |||
583 | irq = platform_get_irq(pdev, 0); | ||
584 | if (irq < 0) { | ||
585 | dev_err(&pdev->dev, "no interrupt assigned\n"); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | |||
589 | tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL); | ||
590 | input = input_allocate_device(); | ||
591 | if (!tsdev || !input) { | ||
592 | dev_err(&pdev->dev, "unable to allocate memory\n"); | ||
593 | err = -ENOMEM; | ||
594 | goto err_free_mem; | ||
595 | } | ||
596 | |||
597 | tsdev->dev = &pdev->dev; | ||
598 | tsdev->input = input; | ||
599 | tsdev->irq = irq; | ||
600 | |||
601 | snprintf(tsdev->phys, sizeof(tsdev->phys), | ||
602 | "%s/input0", dev_name(tsdev->dev)); | ||
603 | |||
604 | err = mrstouch_adc_init(tsdev); | ||
605 | if (err) { | ||
606 | dev_err(&pdev->dev, "ADC initialization failed\n"); | ||
607 | goto err_free_mem; | ||
608 | } | ||
609 | |||
610 | input->name = "mrst_touchscreen"; | ||
611 | input->phys = tsdev->phys; | ||
612 | input->dev.parent = tsdev->dev; | ||
613 | |||
614 | input->id.vendor = tsdev->vendor; | ||
615 | input->id.version = tsdev->rev; | ||
616 | |||
617 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
618 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
619 | |||
620 | input_set_abs_params(tsdev->input, ABS_X, | ||
621 | MRST_X_MIN, MRST_X_MAX, MRST_X_FUZZ, 0); | ||
622 | input_set_abs_params(tsdev->input, ABS_Y, | ||
623 | MRST_Y_MIN, MRST_Y_MAX, MRST_Y_FUZZ, 0); | ||
624 | input_set_abs_params(tsdev->input, ABS_PRESSURE, | ||
625 | MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0); | ||
626 | |||
627 | err = request_threaded_irq(tsdev->irq, NULL, mrstouch_pendet_irq, | ||
628 | 0, "mrstouch", tsdev); | ||
629 | if (err) { | ||
630 | dev_err(tsdev->dev, "unable to allocate irq\n"); | ||
631 | goto err_free_mem; | ||
632 | } | ||
633 | |||
634 | err = input_register_device(tsdev->input); | ||
635 | if (err) { | ||
636 | dev_err(tsdev->dev, "unable to register input device\n"); | ||
637 | goto err_free_irq; | ||
638 | } | ||
639 | |||
640 | platform_set_drvdata(pdev, tsdev); | ||
641 | return 0; | ||
642 | |||
643 | err_free_irq: | ||
644 | free_irq(tsdev->irq, tsdev); | ||
645 | err_free_mem: | ||
646 | input_free_device(input); | ||
647 | kfree(tsdev); | ||
648 | return err; | ||
649 | } | ||
650 | |||
651 | static int __devexit mrstouch_remove(struct platform_device *pdev) | ||
652 | { | ||
653 | struct mrstouch_dev *tsdev = platform_get_drvdata(pdev); | ||
654 | |||
655 | free_irq(tsdev->irq, tsdev); | ||
656 | input_unregister_device(tsdev->input); | ||
657 | kfree(tsdev); | ||
658 | |||
659 | platform_set_drvdata(pdev, NULL); | ||
660 | |||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | static struct platform_driver mrstouch_driver = { | ||
665 | .driver = { | ||
666 | .name = "pmic_touch", | ||
667 | .owner = THIS_MODULE, | ||
668 | }, | ||
669 | .probe = mrstouch_probe, | ||
670 | .remove = __devexit_p(mrstouch_remove), | ||
671 | }; | ||
672 | |||
673 | static int __init mrstouch_init(void) | ||
674 | { | ||
675 | return platform_driver_register(&mrstouch_driver); | ||
676 | } | ||
677 | module_init(mrstouch_init); | ||
678 | |||
679 | static void __exit mrstouch_exit(void) | ||
680 | { | ||
681 | platform_driver_unregister(&mrstouch_driver); | ||
682 | } | ||
683 | module_exit(mrstouch_exit); | ||
684 | |||
685 | MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com"); | ||
686 | MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver"); | ||
687 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index c8b7e8a45c4d..4b0a061811ff 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
23 | #include <mach/jornada720.h> | 24 | #include <mach/jornada720.h> |
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c new file mode 100644 index 000000000000..dcf803f5a1f7 --- /dev/null +++ b/drivers/input/touchscreen/lpc32xx_ts.c | |||
@@ -0,0 +1,411 @@ | |||
1 | /* | ||
2 | * LPC32xx built-in touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2010 NXP Semiconductors | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/slab.h> | ||
25 | |||
26 | /* | ||
27 | * Touchscreen controller register offsets | ||
28 | */ | ||
29 | #define LPC32XX_TSC_STAT 0x00 | ||
30 | #define LPC32XX_TSC_SEL 0x04 | ||
31 | #define LPC32XX_TSC_CON 0x08 | ||
32 | #define LPC32XX_TSC_FIFO 0x0C | ||
33 | #define LPC32XX_TSC_DTR 0x10 | ||
34 | #define LPC32XX_TSC_RTR 0x14 | ||
35 | #define LPC32XX_TSC_UTR 0x18 | ||
36 | #define LPC32XX_TSC_TTR 0x1C | ||
37 | #define LPC32XX_TSC_DXP 0x20 | ||
38 | #define LPC32XX_TSC_MIN_X 0x24 | ||
39 | #define LPC32XX_TSC_MAX_X 0x28 | ||
40 | #define LPC32XX_TSC_MIN_Y 0x2C | ||
41 | #define LPC32XX_TSC_MAX_Y 0x30 | ||
42 | #define LPC32XX_TSC_AUX_UTR 0x34 | ||
43 | #define LPC32XX_TSC_AUX_MIN 0x38 | ||
44 | #define LPC32XX_TSC_AUX_MAX 0x3C | ||
45 | |||
46 | #define LPC32XX_TSC_STAT_FIFO_OVRRN (1 << 8) | ||
47 | #define LPC32XX_TSC_STAT_FIFO_EMPTY (1 << 7) | ||
48 | |||
49 | #define LPC32XX_TSC_SEL_DEFVAL 0x0284 | ||
50 | |||
51 | #define LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 (0x1 << 11) | ||
52 | #define LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(s) ((10 - (s)) << 7) | ||
53 | #define LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(s) ((10 - (s)) << 4) | ||
54 | #define LPC32XX_TSC_ADCCON_POWER_UP (1 << 2) | ||
55 | #define LPC32XX_TSC_ADCCON_AUTO_EN (1 << 0) | ||
56 | |||
57 | #define LPC32XX_TSC_FIFO_TS_P_LEVEL (1 << 31) | ||
58 | #define LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(x) (((x) & 0x03FF0000) >> 16) | ||
59 | #define LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(y) ((y) & 0x000003FF) | ||
60 | |||
61 | #define LPC32XX_TSC_ADCDAT_VALUE_MASK 0x000003FF | ||
62 | |||
63 | #define LPC32XX_TSC_MIN_XY_VAL 0x0 | ||
64 | #define LPC32XX_TSC_MAX_XY_VAL 0x3FF | ||
65 | |||
66 | #define MOD_NAME "ts-lpc32xx" | ||
67 | |||
68 | #define tsc_readl(dev, reg) \ | ||
69 | __raw_readl((dev)->tsc_base + (reg)) | ||
70 | #define tsc_writel(dev, reg, val) \ | ||
71 | __raw_writel((val), (dev)->tsc_base + (reg)) | ||
72 | |||
73 | struct lpc32xx_tsc { | ||
74 | struct input_dev *dev; | ||
75 | void __iomem *tsc_base; | ||
76 | int irq; | ||
77 | struct clk *clk; | ||
78 | }; | ||
79 | |||
80 | static void lpc32xx_fifo_clear(struct lpc32xx_tsc *tsc) | ||
81 | { | ||
82 | while (!(tsc_readl(tsc, LPC32XX_TSC_STAT) & | ||
83 | LPC32XX_TSC_STAT_FIFO_EMPTY)) | ||
84 | tsc_readl(tsc, LPC32XX_TSC_FIFO); | ||
85 | } | ||
86 | |||
87 | static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id) | ||
88 | { | ||
89 | u32 tmp, rv[4], xs[4], ys[4]; | ||
90 | int idx; | ||
91 | struct lpc32xx_tsc *tsc = dev_id; | ||
92 | struct input_dev *input = tsc->dev; | ||
93 | |||
94 | tmp = tsc_readl(tsc, LPC32XX_TSC_STAT); | ||
95 | |||
96 | if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) { | ||
97 | /* FIFO overflow - throw away samples */ | ||
98 | lpc32xx_fifo_clear(tsc); | ||
99 | return IRQ_HANDLED; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Gather and normalize 4 samples. Pen-up events may have less | ||
104 | * than 4 samples, but its ok to pop 4 and let the last sample | ||
105 | * pen status check drop the samples. | ||
106 | */ | ||
107 | idx = 0; | ||
108 | while (idx < 4 && | ||
109 | !(tsc_readl(tsc, LPC32XX_TSC_STAT) & | ||
110 | LPC32XX_TSC_STAT_FIFO_EMPTY)) { | ||
111 | tmp = tsc_readl(tsc, LPC32XX_TSC_FIFO); | ||
112 | xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - | ||
113 | LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp); | ||
114 | ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - | ||
115 | LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp); | ||
116 | rv[idx] = tmp; | ||
117 | idx++; | ||
118 | } | ||
119 | |||
120 | /* Data is only valid if pen is still down in last sample */ | ||
121 | if (!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL) && idx == 4) { | ||
122 | /* Use average of 2nd and 3rd sample for position */ | ||
123 | input_report_abs(input, ABS_X, (xs[1] + xs[2]) / 2); | ||
124 | input_report_abs(input, ABS_Y, (ys[1] + ys[2]) / 2); | ||
125 | input_report_key(input, BTN_TOUCH, 1); | ||
126 | } else { | ||
127 | input_report_key(input, BTN_TOUCH, 0); | ||
128 | } | ||
129 | |||
130 | input_sync(input); | ||
131 | |||
132 | return IRQ_HANDLED; | ||
133 | } | ||
134 | |||
135 | static void lpc32xx_stop_tsc(struct lpc32xx_tsc *tsc) | ||
136 | { | ||
137 | /* Disable auto mode */ | ||
138 | tsc_writel(tsc, LPC32XX_TSC_CON, | ||
139 | tsc_readl(tsc, LPC32XX_TSC_CON) & | ||
140 | ~LPC32XX_TSC_ADCCON_AUTO_EN); | ||
141 | |||
142 | clk_disable(tsc->clk); | ||
143 | } | ||
144 | |||
145 | static void lpc32xx_setup_tsc(struct lpc32xx_tsc *tsc) | ||
146 | { | ||
147 | u32 tmp; | ||
148 | |||
149 | clk_enable(tsc->clk); | ||
150 | |||
151 | tmp = tsc_readl(tsc, LPC32XX_TSC_CON) & ~LPC32XX_TSC_ADCCON_POWER_UP; | ||
152 | |||
153 | /* Set the TSC FIFO depth to 4 samples @ 10-bits per sample (max) */ | ||
154 | tmp = LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 | | ||
155 | LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(10) | | ||
156 | LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(10); | ||
157 | tsc_writel(tsc, LPC32XX_TSC_CON, tmp); | ||
158 | |||
159 | /* These values are all preset */ | ||
160 | tsc_writel(tsc, LPC32XX_TSC_SEL, LPC32XX_TSC_SEL_DEFVAL); | ||
161 | tsc_writel(tsc, LPC32XX_TSC_MIN_X, LPC32XX_TSC_MIN_XY_VAL); | ||
162 | tsc_writel(tsc, LPC32XX_TSC_MAX_X, LPC32XX_TSC_MAX_XY_VAL); | ||
163 | tsc_writel(tsc, LPC32XX_TSC_MIN_Y, LPC32XX_TSC_MIN_XY_VAL); | ||
164 | tsc_writel(tsc, LPC32XX_TSC_MAX_Y, LPC32XX_TSC_MAX_XY_VAL); | ||
165 | |||
166 | /* Aux support is not used */ | ||
167 | tsc_writel(tsc, LPC32XX_TSC_AUX_UTR, 0); | ||
168 | tsc_writel(tsc, LPC32XX_TSC_AUX_MIN, 0); | ||
169 | tsc_writel(tsc, LPC32XX_TSC_AUX_MAX, 0); | ||
170 | |||
171 | /* | ||
172 | * Set sample rate to about 240Hz per X/Y pair. A single measurement | ||
173 | * consists of 4 pairs which gives about a 60Hz sample rate based on | ||
174 | * a stable 32768Hz clock source. Values are in clocks. | ||
175 | * Rate is (32768 / (RTR + XCONV + RTR + YCONV + DXP + TTR + UTR) / 4 | ||
176 | */ | ||
177 | tsc_writel(tsc, LPC32XX_TSC_RTR, 0x2); | ||
178 | tsc_writel(tsc, LPC32XX_TSC_DTR, 0x2); | ||
179 | tsc_writel(tsc, LPC32XX_TSC_TTR, 0x10); | ||
180 | tsc_writel(tsc, LPC32XX_TSC_DXP, 0x4); | ||
181 | tsc_writel(tsc, LPC32XX_TSC_UTR, 88); | ||
182 | |||
183 | lpc32xx_fifo_clear(tsc); | ||
184 | |||
185 | /* Enable automatic ts event capture */ | ||
186 | tsc_writel(tsc, LPC32XX_TSC_CON, tmp | LPC32XX_TSC_ADCCON_AUTO_EN); | ||
187 | } | ||
188 | |||
189 | static int lpc32xx_ts_open(struct input_dev *dev) | ||
190 | { | ||
191 | struct lpc32xx_tsc *tsc = input_get_drvdata(dev); | ||
192 | |||
193 | lpc32xx_setup_tsc(tsc); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static void lpc32xx_ts_close(struct input_dev *dev) | ||
199 | { | ||
200 | struct lpc32xx_tsc *tsc = input_get_drvdata(dev); | ||
201 | |||
202 | lpc32xx_stop_tsc(tsc); | ||
203 | } | ||
204 | |||
205 | static int __devinit lpc32xx_ts_probe(struct platform_device *pdev) | ||
206 | { | ||
207 | struct lpc32xx_tsc *tsc; | ||
208 | struct input_dev *input; | ||
209 | struct resource *res; | ||
210 | resource_size_t size; | ||
211 | int irq; | ||
212 | int error; | ||
213 | |||
214 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
215 | if (!res) { | ||
216 | dev_err(&pdev->dev, "Can't get memory resource\n"); | ||
217 | return -ENOENT; | ||
218 | } | ||
219 | |||
220 | irq = platform_get_irq(pdev, 0); | ||
221 | if (irq < 0) { | ||
222 | dev_err(&pdev->dev, "Can't get interrupt resource\n"); | ||
223 | return irq; | ||
224 | } | ||
225 | |||
226 | tsc = kzalloc(sizeof(*tsc), GFP_KERNEL); | ||
227 | input = input_allocate_device(); | ||
228 | if (!tsc || !input) { | ||
229 | dev_err(&pdev->dev, "failed allocating memory\n"); | ||
230 | error = -ENOMEM; | ||
231 | goto err_free_mem; | ||
232 | } | ||
233 | |||
234 | tsc->dev = input; | ||
235 | tsc->irq = irq; | ||
236 | |||
237 | size = resource_size(res); | ||
238 | |||
239 | if (!request_mem_region(res->start, size, pdev->name)) { | ||
240 | dev_err(&pdev->dev, "TSC registers are not free\n"); | ||
241 | error = -EBUSY; | ||
242 | goto err_free_mem; | ||
243 | } | ||
244 | |||
245 | tsc->tsc_base = ioremap(res->start, size); | ||
246 | if (!tsc->tsc_base) { | ||
247 | dev_err(&pdev->dev, "Can't map memory\n"); | ||
248 | error = -ENOMEM; | ||
249 | goto err_release_mem; | ||
250 | } | ||
251 | |||
252 | tsc->clk = clk_get(&pdev->dev, NULL); | ||
253 | if (IS_ERR(tsc->clk)) { | ||
254 | dev_err(&pdev->dev, "failed getting clock\n"); | ||
255 | error = PTR_ERR(tsc->clk); | ||
256 | goto err_unmap; | ||
257 | } | ||
258 | |||
259 | input->name = MOD_NAME; | ||
260 | input->phys = "lpc32xx/input0"; | ||
261 | input->id.bustype = BUS_HOST; | ||
262 | input->id.vendor = 0x0001; | ||
263 | input->id.product = 0x0002; | ||
264 | input->id.version = 0x0100; | ||
265 | input->dev.parent = &pdev->dev; | ||
266 | input->open = lpc32xx_ts_open; | ||
267 | input->close = lpc32xx_ts_close; | ||
268 | |||
269 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
270 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
271 | input_set_abs_params(input, ABS_X, LPC32XX_TSC_MIN_XY_VAL, | ||
272 | LPC32XX_TSC_MAX_XY_VAL, 0, 0); | ||
273 | input_set_abs_params(input, ABS_Y, LPC32XX_TSC_MIN_XY_VAL, | ||
274 | LPC32XX_TSC_MAX_XY_VAL, 0, 0); | ||
275 | |||
276 | input_set_drvdata(input, tsc); | ||
277 | |||
278 | error = request_irq(tsc->irq, lpc32xx_ts_interrupt, | ||
279 | IRQF_DISABLED, pdev->name, tsc); | ||
280 | if (error) { | ||
281 | dev_err(&pdev->dev, "failed requesting interrupt\n"); | ||
282 | goto err_put_clock; | ||
283 | } | ||
284 | |||
285 | error = input_register_device(input); | ||
286 | if (error) { | ||
287 | dev_err(&pdev->dev, "failed registering input device\n"); | ||
288 | goto err_free_irq; | ||
289 | } | ||
290 | |||
291 | platform_set_drvdata(pdev, tsc); | ||
292 | device_init_wakeup(&pdev->dev, 1); | ||
293 | |||
294 | return 0; | ||
295 | |||
296 | err_free_irq: | ||
297 | free_irq(tsc->irq, tsc); | ||
298 | err_put_clock: | ||
299 | clk_put(tsc->clk); | ||
300 | err_unmap: | ||
301 | iounmap(tsc->tsc_base); | ||
302 | err_release_mem: | ||
303 | release_mem_region(res->start, size); | ||
304 | err_free_mem: | ||
305 | input_free_device(input); | ||
306 | kfree(tsc); | ||
307 | |||
308 | return error; | ||
309 | } | ||
310 | |||
311 | static int __devexit lpc32xx_ts_remove(struct platform_device *pdev) | ||
312 | { | ||
313 | struct lpc32xx_tsc *tsc = platform_get_drvdata(pdev); | ||
314 | struct resource *res; | ||
315 | |||
316 | device_init_wakeup(&pdev->dev, 0); | ||
317 | free_irq(tsc->irq, tsc); | ||
318 | |||
319 | input_unregister_device(tsc->dev); | ||
320 | |||
321 | clk_put(tsc->clk); | ||
322 | |||
323 | iounmap(tsc->tsc_base); | ||
324 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
325 | release_mem_region(res->start, resource_size(res)); | ||
326 | |||
327 | kfree(tsc); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | #ifdef CONFIG_PM | ||
333 | static int lpc32xx_ts_suspend(struct device *dev) | ||
334 | { | ||
335 | struct lpc32xx_tsc *tsc = dev_get_drvdata(dev); | ||
336 | struct input_dev *input = tsc->dev; | ||
337 | |||
338 | /* | ||
339 | * Suspend and resume can be called when the device hasn't been | ||
340 | * enabled. If there are no users that have the device open, then | ||
341 | * avoid calling the TSC stop and start functions as the TSC | ||
342 | * isn't yet clocked. | ||
343 | */ | ||
344 | mutex_lock(&input->mutex); | ||
345 | |||
346 | if (input->users) { | ||
347 | if (device_may_wakeup(dev)) | ||
348 | enable_irq_wake(tsc->irq); | ||
349 | else | ||
350 | lpc32xx_stop_tsc(tsc); | ||
351 | } | ||
352 | |||
353 | mutex_unlock(&input->mutex); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int lpc32xx_ts_resume(struct device *dev) | ||
359 | { | ||
360 | struct lpc32xx_tsc *tsc = dev_get_drvdata(dev); | ||
361 | struct input_dev *input = tsc->dev; | ||
362 | |||
363 | mutex_lock(&input->mutex); | ||
364 | |||
365 | if (input->users) { | ||
366 | if (device_may_wakeup(dev)) | ||
367 | disable_irq_wake(tsc->irq); | ||
368 | else | ||
369 | lpc32xx_setup_tsc(tsc); | ||
370 | } | ||
371 | |||
372 | mutex_unlock(&input->mutex); | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static const struct dev_pm_ops lpc32xx_ts_pm_ops = { | ||
378 | .suspend = lpc32xx_ts_suspend, | ||
379 | .resume = lpc32xx_ts_resume, | ||
380 | }; | ||
381 | #define LPC32XX_TS_PM_OPS (&lpc32xx_ts_pm_ops) | ||
382 | #else | ||
383 | #define LPC32XX_TS_PM_OPS NULL | ||
384 | #endif | ||
385 | |||
386 | static struct platform_driver lpc32xx_ts_driver = { | ||
387 | .probe = lpc32xx_ts_probe, | ||
388 | .remove = __devexit_p(lpc32xx_ts_remove), | ||
389 | .driver = { | ||
390 | .name = MOD_NAME, | ||
391 | .owner = THIS_MODULE, | ||
392 | .pm = LPC32XX_TS_PM_OPS, | ||
393 | }, | ||
394 | }; | ||
395 | |||
396 | static int __init lpc32xx_ts_init(void) | ||
397 | { | ||
398 | return platform_driver_register(&lpc32xx_ts_driver); | ||
399 | } | ||
400 | module_init(lpc32xx_ts_init); | ||
401 | |||
402 | static void __exit lpc32xx_ts_exit(void) | ||
403 | { | ||
404 | platform_driver_unregister(&lpc32xx_ts_driver); | ||
405 | } | ||
406 | module_exit(lpc32xx_ts_exit); | ||
407 | |||
408 | MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com"); | ||
409 | MODULE_DESCRIPTION("LPC32XX TSC Driver"); | ||
410 | MODULE_LICENSE("GPL"); | ||
411 | MODULE_ALIAS("platform:lpc32xx_ts"); | ||
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 6cdcf2a6e036..b6b8b1c7ecea 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c | |||
@@ -153,6 +153,9 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) | |||
153 | if (pressure) | 153 | if (pressure) |
154 | p = MODR; | 154 | p = MODR; |
155 | 155 | ||
156 | dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n", | ||
157 | x, y, p); | ||
158 | |||
156 | /* are samples valid */ | 159 | /* are samples valid */ |
157 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || | 160 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || |
158 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || | 161 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || |
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c index be115b3b65eb..c5bc62d85bb6 100644 --- a/drivers/input/touchscreen/mc13783_ts.c +++ b/drivers/input/touchscreen/mc13783_ts.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/slab.h> | ||
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | 22 | ||
22 | #define MC13783_TS_NAME "mc13783-ts" | 23 | #define MC13783_TS_NAME "mc13783-ts" |
@@ -44,7 +45,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data) | |||
44 | { | 45 | { |
45 | struct mc13783_ts_priv *priv = data; | 46 | struct mc13783_ts_priv *priv = data; |
46 | 47 | ||
47 | mc13783_ackirq(priv->mc13783, irq); | 48 | mc13783_irq_ack(priv->mc13783, irq); |
48 | 49 | ||
49 | /* | 50 | /* |
50 | * Kick off reading coordinates. Note that if work happens already | 51 | * Kick off reading coordinates. Note that if work happens already |
@@ -135,7 +136,7 @@ static int mc13783_ts_open(struct input_dev *dev) | |||
135 | 136 | ||
136 | mc13783_lock(priv->mc13783); | 137 | mc13783_lock(priv->mc13783); |
137 | 138 | ||
138 | mc13783_ackirq(priv->mc13783, MC13783_IRQ_TS); | 139 | mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TS); |
139 | 140 | ||
140 | ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS, | 141 | ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS, |
141 | mc13783_ts_handler, MC13783_TS_NAME, priv); | 142 | mc13783_ts_handler, MC13783_TS_NAME, priv); |
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 4c28b89757f9..6ee9940aaf5b 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c | |||
@@ -16,10 +16,11 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/i2c/mcs5000_ts.h> | 19 | #include <linux/i2c/mcs.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/input.h> | 21 | #include <linux/input.h> |
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/slab.h> | ||
23 | 24 | ||
24 | /* Registers */ | 25 | /* Registers */ |
25 | #define MCS5000_TS_STATUS 0x00 | 26 | #define MCS5000_TS_STATUS 0x00 |
@@ -104,7 +105,7 @@ enum mcs5000_ts_read_offset { | |||
104 | struct mcs5000_ts_data { | 105 | struct mcs5000_ts_data { |
105 | struct i2c_client *client; | 106 | struct i2c_client *client; |
106 | struct input_dev *input_dev; | 107 | struct input_dev *input_dev; |
107 | const struct mcs5000_ts_platform_data *platform_data; | 108 | const struct mcs_platform_data *platform_data; |
108 | }; | 109 | }; |
109 | 110 | ||
110 | static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id) | 111 | static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id) |
@@ -163,7 +164,7 @@ static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id) | |||
163 | 164 | ||
164 | static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data) | 165 | static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data) |
165 | { | 166 | { |
166 | const struct mcs5000_ts_platform_data *platform_data = | 167 | const struct mcs_platform_data *platform_data = |
167 | data->platform_data; | 168 | data->platform_data; |
168 | struct i2c_client *client = data->client; | 169 | struct i2c_client *client = data->client; |
169 | 170 | ||
@@ -255,7 +256,6 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client) | |||
255 | free_irq(client->irq, data); | 256 | free_irq(client->irq, data); |
256 | input_unregister_device(data->input_dev); | 257 | input_unregister_device(data->input_dev); |
257 | kfree(data); | 258 | kfree(data); |
258 | i2c_set_clientdata(client, NULL); | ||
259 | 259 | ||
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c index 141dd584330e..defe5dd3627c 100644 --- a/drivers/input/touchscreen/migor_ts.c +++ b/drivers/input/touchscreen/migor_ts.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/slab.h> | ||
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
27 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
28 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index efd3aebaba5f..36e57deacd03 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c | |||
@@ -17,7 +17,7 @@ | |||
17 | * found in Gateway AOL Connected Touchpad computers. | 17 | * found in Gateway AOL Connected Touchpad computers. |
18 | * | 18 | * |
19 | * Documentation for ICS MK712 can be found at: | 19 | * Documentation for ICS MK712 can be found at: |
20 | * http://www.icst.com/pdf/mk712.pdf | 20 | * http://www.idt.com/products/getDoc.cfm?docID=18713923 |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* | 23 | /* |
diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c index b79097e3028a..ea6ef16e59b4 100644 --- a/drivers/input/touchscreen/pcap_ts.c +++ b/drivers/input/touchscreen/pcap_ts.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/slab.h> | ||
17 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
18 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
19 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
diff --git a/drivers/input/touchscreen/qt602240_ts.c b/drivers/input/touchscreen/qt602240_ts.c new file mode 100644 index 000000000000..66b26ad3032a --- /dev/null +++ b/drivers/input/touchscreen/qt602240_ts.c | |||
@@ -0,0 +1,1401 @@ | |||
1 | /* | ||
2 | * AT42QT602240/ATMXT224 Touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/firmware.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/i2c/qt602240_ts.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | /* Version */ | ||
25 | #define QT602240_VER_20 20 | ||
26 | #define QT602240_VER_21 21 | ||
27 | #define QT602240_VER_22 22 | ||
28 | |||
29 | /* Slave addresses */ | ||
30 | #define QT602240_APP_LOW 0x4a | ||
31 | #define QT602240_APP_HIGH 0x4b | ||
32 | #define QT602240_BOOT_LOW 0x24 | ||
33 | #define QT602240_BOOT_HIGH 0x25 | ||
34 | |||
35 | /* Firmware */ | ||
36 | #define QT602240_FW_NAME "qt602240.fw" | ||
37 | |||
38 | /* Registers */ | ||
39 | #define QT602240_FAMILY_ID 0x00 | ||
40 | #define QT602240_VARIANT_ID 0x01 | ||
41 | #define QT602240_VERSION 0x02 | ||
42 | #define QT602240_BUILD 0x03 | ||
43 | #define QT602240_MATRIX_X_SIZE 0x04 | ||
44 | #define QT602240_MATRIX_Y_SIZE 0x05 | ||
45 | #define QT602240_OBJECT_NUM 0x06 | ||
46 | #define QT602240_OBJECT_START 0x07 | ||
47 | |||
48 | #define QT602240_OBJECT_SIZE 6 | ||
49 | |||
50 | /* Object types */ | ||
51 | #define QT602240_DEBUG_DIAGNOSTIC 37 | ||
52 | #define QT602240_GEN_MESSAGE 5 | ||
53 | #define QT602240_GEN_COMMAND 6 | ||
54 | #define QT602240_GEN_POWER 7 | ||
55 | #define QT602240_GEN_ACQUIRE 8 | ||
56 | #define QT602240_TOUCH_MULTI 9 | ||
57 | #define QT602240_TOUCH_KEYARRAY 15 | ||
58 | #define QT602240_TOUCH_PROXIMITY 23 | ||
59 | #define QT602240_PROCI_GRIPFACE 20 | ||
60 | #define QT602240_PROCG_NOISE 22 | ||
61 | #define QT602240_PROCI_ONETOUCH 24 | ||
62 | #define QT602240_PROCI_TWOTOUCH 27 | ||
63 | #define QT602240_SPT_COMMSCONFIG 18 /* firmware ver 21 over */ | ||
64 | #define QT602240_SPT_GPIOPWM 19 | ||
65 | #define QT602240_SPT_SELFTEST 25 | ||
66 | #define QT602240_SPT_CTECONFIG 28 | ||
67 | #define QT602240_SPT_USERDATA 38 /* firmware ver 21 over */ | ||
68 | |||
69 | /* QT602240_GEN_COMMAND field */ | ||
70 | #define QT602240_COMMAND_RESET 0 | ||
71 | #define QT602240_COMMAND_BACKUPNV 1 | ||
72 | #define QT602240_COMMAND_CALIBRATE 2 | ||
73 | #define QT602240_COMMAND_REPORTALL 3 | ||
74 | #define QT602240_COMMAND_DIAGNOSTIC 5 | ||
75 | |||
76 | /* QT602240_GEN_POWER field */ | ||
77 | #define QT602240_POWER_IDLEACQINT 0 | ||
78 | #define QT602240_POWER_ACTVACQINT 1 | ||
79 | #define QT602240_POWER_ACTV2IDLETO 2 | ||
80 | |||
81 | /* QT602240_GEN_ACQUIRE field */ | ||
82 | #define QT602240_ACQUIRE_CHRGTIME 0 | ||
83 | #define QT602240_ACQUIRE_TCHDRIFT 2 | ||
84 | #define QT602240_ACQUIRE_DRIFTST 3 | ||
85 | #define QT602240_ACQUIRE_TCHAUTOCAL 4 | ||
86 | #define QT602240_ACQUIRE_SYNC 5 | ||
87 | #define QT602240_ACQUIRE_ATCHCALST 6 | ||
88 | #define QT602240_ACQUIRE_ATCHCALSTHR 7 | ||
89 | |||
90 | /* QT602240_TOUCH_MULTI field */ | ||
91 | #define QT602240_TOUCH_CTRL 0 | ||
92 | #define QT602240_TOUCH_XORIGIN 1 | ||
93 | #define QT602240_TOUCH_YORIGIN 2 | ||
94 | #define QT602240_TOUCH_XSIZE 3 | ||
95 | #define QT602240_TOUCH_YSIZE 4 | ||
96 | #define QT602240_TOUCH_BLEN 6 | ||
97 | #define QT602240_TOUCH_TCHTHR 7 | ||
98 | #define QT602240_TOUCH_TCHDI 8 | ||
99 | #define QT602240_TOUCH_ORIENT 9 | ||
100 | #define QT602240_TOUCH_MOVHYSTI 11 | ||
101 | #define QT602240_TOUCH_MOVHYSTN 12 | ||
102 | #define QT602240_TOUCH_NUMTOUCH 14 | ||
103 | #define QT602240_TOUCH_MRGHYST 15 | ||
104 | #define QT602240_TOUCH_MRGTHR 16 | ||
105 | #define QT602240_TOUCH_AMPHYST 17 | ||
106 | #define QT602240_TOUCH_XRANGE_LSB 18 | ||
107 | #define QT602240_TOUCH_XRANGE_MSB 19 | ||
108 | #define QT602240_TOUCH_YRANGE_LSB 20 | ||
109 | #define QT602240_TOUCH_YRANGE_MSB 21 | ||
110 | #define QT602240_TOUCH_XLOCLIP 22 | ||
111 | #define QT602240_TOUCH_XHICLIP 23 | ||
112 | #define QT602240_TOUCH_YLOCLIP 24 | ||
113 | #define QT602240_TOUCH_YHICLIP 25 | ||
114 | #define QT602240_TOUCH_XEDGECTRL 26 | ||
115 | #define QT602240_TOUCH_XEDGEDIST 27 | ||
116 | #define QT602240_TOUCH_YEDGECTRL 28 | ||
117 | #define QT602240_TOUCH_YEDGEDIST 29 | ||
118 | #define QT602240_TOUCH_JUMPLIMIT 30 /* firmware ver 22 over */ | ||
119 | |||
120 | /* QT602240_PROCI_GRIPFACE field */ | ||
121 | #define QT602240_GRIPFACE_CTRL 0 | ||
122 | #define QT602240_GRIPFACE_XLOGRIP 1 | ||
123 | #define QT602240_GRIPFACE_XHIGRIP 2 | ||
124 | #define QT602240_GRIPFACE_YLOGRIP 3 | ||
125 | #define QT602240_GRIPFACE_YHIGRIP 4 | ||
126 | #define QT602240_GRIPFACE_MAXTCHS 5 | ||
127 | #define QT602240_GRIPFACE_SZTHR1 7 | ||
128 | #define QT602240_GRIPFACE_SZTHR2 8 | ||
129 | #define QT602240_GRIPFACE_SHPTHR1 9 | ||
130 | #define QT602240_GRIPFACE_SHPTHR2 10 | ||
131 | #define QT602240_GRIPFACE_SUPEXTTO 11 | ||
132 | |||
133 | /* QT602240_PROCI_NOISE field */ | ||
134 | #define QT602240_NOISE_CTRL 0 | ||
135 | #define QT602240_NOISE_OUTFLEN 1 | ||
136 | #define QT602240_NOISE_GCAFUL_LSB 3 | ||
137 | #define QT602240_NOISE_GCAFUL_MSB 4 | ||
138 | #define QT602240_NOISE_GCAFLL_LSB 5 | ||
139 | #define QT602240_NOISE_GCAFLL_MSB 6 | ||
140 | #define QT602240_NOISE_ACTVGCAFVALID 7 | ||
141 | #define QT602240_NOISE_NOISETHR 8 | ||
142 | #define QT602240_NOISE_FREQHOPSCALE 10 | ||
143 | #define QT602240_NOISE_FREQ0 11 | ||
144 | #define QT602240_NOISE_FREQ1 12 | ||
145 | #define QT602240_NOISE_FREQ2 13 | ||
146 | #define QT602240_NOISE_FREQ3 14 | ||
147 | #define QT602240_NOISE_FREQ4 15 | ||
148 | #define QT602240_NOISE_IDLEGCAFVALID 16 | ||
149 | |||
150 | /* QT602240_SPT_COMMSCONFIG */ | ||
151 | #define QT602240_COMMS_CTRL 0 | ||
152 | #define QT602240_COMMS_CMD 1 | ||
153 | |||
154 | /* QT602240_SPT_CTECONFIG field */ | ||
155 | #define QT602240_CTE_CTRL 0 | ||
156 | #define QT602240_CTE_CMD 1 | ||
157 | #define QT602240_CTE_MODE 2 | ||
158 | #define QT602240_CTE_IDLEGCAFDEPTH 3 | ||
159 | #define QT602240_CTE_ACTVGCAFDEPTH 4 | ||
160 | #define QT602240_CTE_VOLTAGE 5 /* firmware ver 21 over */ | ||
161 | |||
162 | #define QT602240_VOLTAGE_DEFAULT 2700000 | ||
163 | #define QT602240_VOLTAGE_STEP 10000 | ||
164 | |||
165 | /* Define for QT602240_GEN_COMMAND */ | ||
166 | #define QT602240_BOOT_VALUE 0xa5 | ||
167 | #define QT602240_BACKUP_VALUE 0x55 | ||
168 | #define QT602240_BACKUP_TIME 25 /* msec */ | ||
169 | #define QT602240_RESET_TIME 65 /* msec */ | ||
170 | |||
171 | #define QT602240_FWRESET_TIME 175 /* msec */ | ||
172 | |||
173 | /* Command to unlock bootloader */ | ||
174 | #define QT602240_UNLOCK_CMD_MSB 0xaa | ||
175 | #define QT602240_UNLOCK_CMD_LSB 0xdc | ||
176 | |||
177 | /* Bootloader mode status */ | ||
178 | #define QT602240_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */ | ||
179 | #define QT602240_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */ | ||
180 | #define QT602240_FRAME_CRC_CHECK 0x02 | ||
181 | #define QT602240_FRAME_CRC_FAIL 0x03 | ||
182 | #define QT602240_FRAME_CRC_PASS 0x04 | ||
183 | #define QT602240_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */ | ||
184 | #define QT602240_BOOT_STATUS_MASK 0x3f | ||
185 | |||
186 | /* Touch status */ | ||
187 | #define QT602240_SUPPRESS (1 << 1) | ||
188 | #define QT602240_AMP (1 << 2) | ||
189 | #define QT602240_VECTOR (1 << 3) | ||
190 | #define QT602240_MOVE (1 << 4) | ||
191 | #define QT602240_RELEASE (1 << 5) | ||
192 | #define QT602240_PRESS (1 << 6) | ||
193 | #define QT602240_DETECT (1 << 7) | ||
194 | |||
195 | /* Touchscreen absolute values */ | ||
196 | #define QT602240_MAX_XC 0x3ff | ||
197 | #define QT602240_MAX_YC 0x3ff | ||
198 | #define QT602240_MAX_AREA 0xff | ||
199 | |||
200 | #define QT602240_MAX_FINGER 10 | ||
201 | |||
202 | /* Initial register values recommended from chip vendor */ | ||
203 | static const u8 init_vals_ver_20[] = { | ||
204 | /* QT602240_GEN_COMMAND(6) */ | ||
205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
206 | /* QT602240_GEN_POWER(7) */ | ||
207 | 0x20, 0xff, 0x32, | ||
208 | /* QT602240_GEN_ACQUIRE(8) */ | ||
209 | 0x08, 0x05, 0x05, 0x00, 0x00, 0x00, 0x05, 0x14, | ||
210 | /* QT602240_TOUCH_MULTI(9) */ | ||
211 | 0x00, 0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
212 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
213 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x64, | ||
214 | /* QT602240_TOUCH_KEYARRAY(15) */ | ||
215 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
216 | 0x00, | ||
217 | /* QT602240_SPT_GPIOPWM(19) */ | ||
218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
219 | 0x00, 0x00, | ||
220 | /* QT602240_PROCI_GRIPFACE(20) */ | ||
221 | 0x00, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x1e, 0x14, 0x04, | ||
222 | 0x1e, 0x00, | ||
223 | /* QT602240_PROCG_NOISE(22) */ | ||
224 | 0x05, 0x00, 0x00, 0x19, 0x00, 0xe7, 0xff, 0x04, 0x32, 0x00, | ||
225 | 0x01, 0x0a, 0x0f, 0x14, 0x00, 0x00, 0xe8, | ||
226 | /* QT602240_TOUCH_PROXIMITY(23) */ | ||
227 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
228 | 0x00, 0x00, 0x00, | ||
229 | /* QT602240_PROCI_ONETOUCH(24) */ | ||
230 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
232 | /* QT602240_SPT_SELFTEST(25) */ | ||
233 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
234 | 0x00, 0x00, 0x00, 0x00, | ||
235 | /* QT602240_PROCI_TWOTOUCH(27) */ | ||
236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
237 | /* QT602240_SPT_CTECONFIG(28) */ | ||
238 | 0x00, 0x00, 0x00, 0x04, 0x08, | ||
239 | }; | ||
240 | |||
241 | static const u8 init_vals_ver_21[] = { | ||
242 | /* QT602240_GEN_COMMAND(6) */ | ||
243 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
244 | /* QT602240_GEN_POWER(7) */ | ||
245 | 0x20, 0xff, 0x32, | ||
246 | /* QT602240_GEN_ACQUIRE(8) */ | ||
247 | 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, | ||
248 | /* QT602240_TOUCH_MULTI(9) */ | ||
249 | 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
250 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
252 | /* QT602240_TOUCH_KEYARRAY(15) */ | ||
253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
254 | 0x00, | ||
255 | /* QT602240_SPT_GPIOPWM(19) */ | ||
256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
258 | /* QT602240_PROCI_GRIPFACE(20) */ | ||
259 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, | ||
260 | 0x0f, 0x0a, | ||
261 | /* QT602240_PROCG_NOISE(22) */ | ||
262 | 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, | ||
263 | 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, | ||
264 | /* QT602240_TOUCH_PROXIMITY(23) */ | ||
265 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
266 | 0x00, 0x00, 0x00, | ||
267 | /* QT602240_PROCI_ONETOUCH(24) */ | ||
268 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
269 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
270 | /* QT602240_SPT_SELFTEST(25) */ | ||
271 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
272 | 0x00, 0x00, 0x00, 0x00, | ||
273 | /* QT602240_PROCI_TWOTOUCH(27) */ | ||
274 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
275 | /* QT602240_SPT_CTECONFIG(28) */ | ||
276 | 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, | ||
277 | }; | ||
278 | |||
279 | static const u8 init_vals_ver_22[] = { | ||
280 | /* QT602240_GEN_COMMAND(6) */ | ||
281 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
282 | /* QT602240_GEN_POWER(7) */ | ||
283 | 0x20, 0xff, 0x32, | ||
284 | /* QT602240_GEN_ACQUIRE(8) */ | ||
285 | 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, | ||
286 | /* QT602240_TOUCH_MULTI(9) */ | ||
287 | 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
288 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
289 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
290 | 0x00, | ||
291 | /* QT602240_TOUCH_KEYARRAY(15) */ | ||
292 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
293 | 0x00, | ||
294 | /* QT602240_SPT_GPIOPWM(19) */ | ||
295 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
296 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
297 | /* QT602240_PROCI_GRIPFACE(20) */ | ||
298 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, | ||
299 | 0x0f, 0x0a, | ||
300 | /* QT602240_PROCG_NOISE(22) */ | ||
301 | 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, | ||
302 | 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, | ||
303 | /* QT602240_TOUCH_PROXIMITY(23) */ | ||
304 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
305 | 0x00, 0x00, 0x00, 0x00, 0x00, | ||
306 | /* QT602240_PROCI_ONETOUCH(24) */ | ||
307 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
308 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
309 | /* QT602240_SPT_SELFTEST(25) */ | ||
310 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
311 | 0x00, 0x00, 0x00, 0x00, | ||
312 | /* QT602240_PROCI_TWOTOUCH(27) */ | ||
313 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
314 | /* QT602240_SPT_CTECONFIG(28) */ | ||
315 | 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, | ||
316 | }; | ||
317 | |||
318 | struct qt602240_info { | ||
319 | u8 family_id; | ||
320 | u8 variant_id; | ||
321 | u8 version; | ||
322 | u8 build; | ||
323 | u8 matrix_xsize; | ||
324 | u8 matrix_ysize; | ||
325 | u8 object_num; | ||
326 | }; | ||
327 | |||
328 | struct qt602240_object { | ||
329 | u8 type; | ||
330 | u16 start_address; | ||
331 | u8 size; | ||
332 | u8 instances; | ||
333 | u8 num_report_ids; | ||
334 | |||
335 | /* to map object and message */ | ||
336 | u8 max_reportid; | ||
337 | }; | ||
338 | |||
339 | struct qt602240_message { | ||
340 | u8 reportid; | ||
341 | u8 message[7]; | ||
342 | u8 checksum; | ||
343 | }; | ||
344 | |||
345 | struct qt602240_finger { | ||
346 | int status; | ||
347 | int x; | ||
348 | int y; | ||
349 | int area; | ||
350 | }; | ||
351 | |||
352 | /* Each client has this additional data */ | ||
353 | struct qt602240_data { | ||
354 | struct i2c_client *client; | ||
355 | struct input_dev *input_dev; | ||
356 | const struct qt602240_platform_data *pdata; | ||
357 | struct qt602240_object *object_table; | ||
358 | struct qt602240_info info; | ||
359 | struct qt602240_finger finger[QT602240_MAX_FINGER]; | ||
360 | unsigned int irq; | ||
361 | }; | ||
362 | |||
363 | static bool qt602240_object_readable(unsigned int type) | ||
364 | { | ||
365 | switch (type) { | ||
366 | case QT602240_GEN_MESSAGE: | ||
367 | case QT602240_GEN_COMMAND: | ||
368 | case QT602240_GEN_POWER: | ||
369 | case QT602240_GEN_ACQUIRE: | ||
370 | case QT602240_TOUCH_MULTI: | ||
371 | case QT602240_TOUCH_KEYARRAY: | ||
372 | case QT602240_TOUCH_PROXIMITY: | ||
373 | case QT602240_PROCI_GRIPFACE: | ||
374 | case QT602240_PROCG_NOISE: | ||
375 | case QT602240_PROCI_ONETOUCH: | ||
376 | case QT602240_PROCI_TWOTOUCH: | ||
377 | case QT602240_SPT_COMMSCONFIG: | ||
378 | case QT602240_SPT_GPIOPWM: | ||
379 | case QT602240_SPT_SELFTEST: | ||
380 | case QT602240_SPT_CTECONFIG: | ||
381 | case QT602240_SPT_USERDATA: | ||
382 | return true; | ||
383 | default: | ||
384 | return false; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | static bool qt602240_object_writable(unsigned int type) | ||
389 | { | ||
390 | switch (type) { | ||
391 | case QT602240_GEN_COMMAND: | ||
392 | case QT602240_GEN_POWER: | ||
393 | case QT602240_GEN_ACQUIRE: | ||
394 | case QT602240_TOUCH_MULTI: | ||
395 | case QT602240_TOUCH_KEYARRAY: | ||
396 | case QT602240_TOUCH_PROXIMITY: | ||
397 | case QT602240_PROCI_GRIPFACE: | ||
398 | case QT602240_PROCG_NOISE: | ||
399 | case QT602240_PROCI_ONETOUCH: | ||
400 | case QT602240_PROCI_TWOTOUCH: | ||
401 | case QT602240_SPT_GPIOPWM: | ||
402 | case QT602240_SPT_SELFTEST: | ||
403 | case QT602240_SPT_CTECONFIG: | ||
404 | return true; | ||
405 | default: | ||
406 | return false; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void qt602240_dump_message(struct device *dev, | ||
411 | struct qt602240_message *message) | ||
412 | { | ||
413 | dev_dbg(dev, "reportid:\t0x%x\n", message->reportid); | ||
414 | dev_dbg(dev, "message1:\t0x%x\n", message->message[0]); | ||
415 | dev_dbg(dev, "message2:\t0x%x\n", message->message[1]); | ||
416 | dev_dbg(dev, "message3:\t0x%x\n", message->message[2]); | ||
417 | dev_dbg(dev, "message4:\t0x%x\n", message->message[3]); | ||
418 | dev_dbg(dev, "message5:\t0x%x\n", message->message[4]); | ||
419 | dev_dbg(dev, "message6:\t0x%x\n", message->message[5]); | ||
420 | dev_dbg(dev, "message7:\t0x%x\n", message->message[6]); | ||
421 | dev_dbg(dev, "checksum:\t0x%x\n", message->checksum); | ||
422 | } | ||
423 | |||
424 | static int qt602240_check_bootloader(struct i2c_client *client, | ||
425 | unsigned int state) | ||
426 | { | ||
427 | u8 val; | ||
428 | |||
429 | recheck: | ||
430 | if (i2c_master_recv(client, &val, 1) != 1) { | ||
431 | dev_err(&client->dev, "%s: i2c recv failed\n", __func__); | ||
432 | return -EIO; | ||
433 | } | ||
434 | |||
435 | switch (state) { | ||
436 | case QT602240_WAITING_BOOTLOAD_CMD: | ||
437 | case QT602240_WAITING_FRAME_DATA: | ||
438 | val &= ~QT602240_BOOT_STATUS_MASK; | ||
439 | break; | ||
440 | case QT602240_FRAME_CRC_PASS: | ||
441 | if (val == QT602240_FRAME_CRC_CHECK) | ||
442 | goto recheck; | ||
443 | break; | ||
444 | default: | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | |||
448 | if (val != state) { | ||
449 | dev_err(&client->dev, "Unvalid bootloader mode state\n"); | ||
450 | return -EINVAL; | ||
451 | } | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int qt602240_unlock_bootloader(struct i2c_client *client) | ||
457 | { | ||
458 | u8 buf[2]; | ||
459 | |||
460 | buf[0] = QT602240_UNLOCK_CMD_LSB; | ||
461 | buf[1] = QT602240_UNLOCK_CMD_MSB; | ||
462 | |||
463 | if (i2c_master_send(client, buf, 2) != 2) { | ||
464 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
465 | return -EIO; | ||
466 | } | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int qt602240_fw_write(struct i2c_client *client, | ||
472 | const u8 *data, unsigned int frame_size) | ||
473 | { | ||
474 | if (i2c_master_send(client, data, frame_size) != frame_size) { | ||
475 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
476 | return -EIO; | ||
477 | } | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int __qt602240_read_reg(struct i2c_client *client, | ||
483 | u16 reg, u16 len, void *val) | ||
484 | { | ||
485 | struct i2c_msg xfer[2]; | ||
486 | u8 buf[2]; | ||
487 | |||
488 | buf[0] = reg & 0xff; | ||
489 | buf[1] = (reg >> 8) & 0xff; | ||
490 | |||
491 | /* Write register */ | ||
492 | xfer[0].addr = client->addr; | ||
493 | xfer[0].flags = 0; | ||
494 | xfer[0].len = 2; | ||
495 | xfer[0].buf = buf; | ||
496 | |||
497 | /* Read data */ | ||
498 | xfer[1].addr = client->addr; | ||
499 | xfer[1].flags = I2C_M_RD; | ||
500 | xfer[1].len = len; | ||
501 | xfer[1].buf = val; | ||
502 | |||
503 | if (i2c_transfer(client->adapter, xfer, 2) != 2) { | ||
504 | dev_err(&client->dev, "%s: i2c transfer failed\n", __func__); | ||
505 | return -EIO; | ||
506 | } | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static int qt602240_read_reg(struct i2c_client *client, u16 reg, u8 *val) | ||
512 | { | ||
513 | return __qt602240_read_reg(client, reg, 1, val); | ||
514 | } | ||
515 | |||
516 | static int qt602240_write_reg(struct i2c_client *client, u16 reg, u8 val) | ||
517 | { | ||
518 | u8 buf[3]; | ||
519 | |||
520 | buf[0] = reg & 0xff; | ||
521 | buf[1] = (reg >> 8) & 0xff; | ||
522 | buf[2] = val; | ||
523 | |||
524 | if (i2c_master_send(client, buf, 3) != 3) { | ||
525 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
526 | return -EIO; | ||
527 | } | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static int qt602240_read_object_table(struct i2c_client *client, | ||
533 | u16 reg, u8 *object_buf) | ||
534 | { | ||
535 | return __qt602240_read_reg(client, reg, QT602240_OBJECT_SIZE, | ||
536 | object_buf); | ||
537 | } | ||
538 | |||
539 | static struct qt602240_object * | ||
540 | qt602240_get_object(struct qt602240_data *data, u8 type) | ||
541 | { | ||
542 | struct qt602240_object *object; | ||
543 | int i; | ||
544 | |||
545 | for (i = 0; i < data->info.object_num; i++) { | ||
546 | object = data->object_table + i; | ||
547 | if (object->type == type) | ||
548 | return object; | ||
549 | } | ||
550 | |||
551 | dev_err(&data->client->dev, "Invalid object type\n"); | ||
552 | return NULL; | ||
553 | } | ||
554 | |||
555 | static int qt602240_read_message(struct qt602240_data *data, | ||
556 | struct qt602240_message *message) | ||
557 | { | ||
558 | struct qt602240_object *object; | ||
559 | u16 reg; | ||
560 | |||
561 | object = qt602240_get_object(data, QT602240_GEN_MESSAGE); | ||
562 | if (!object) | ||
563 | return -EINVAL; | ||
564 | |||
565 | reg = object->start_address; | ||
566 | return __qt602240_read_reg(data->client, reg, | ||
567 | sizeof(struct qt602240_message), message); | ||
568 | } | ||
569 | |||
570 | static int qt602240_read_object(struct qt602240_data *data, | ||
571 | u8 type, u8 offset, u8 *val) | ||
572 | { | ||
573 | struct qt602240_object *object; | ||
574 | u16 reg; | ||
575 | |||
576 | object = qt602240_get_object(data, type); | ||
577 | if (!object) | ||
578 | return -EINVAL; | ||
579 | |||
580 | reg = object->start_address; | ||
581 | return __qt602240_read_reg(data->client, reg + offset, 1, val); | ||
582 | } | ||
583 | |||
584 | static int qt602240_write_object(struct qt602240_data *data, | ||
585 | u8 type, u8 offset, u8 val) | ||
586 | { | ||
587 | struct qt602240_object *object; | ||
588 | u16 reg; | ||
589 | |||
590 | object = qt602240_get_object(data, type); | ||
591 | if (!object) | ||
592 | return -EINVAL; | ||
593 | |||
594 | reg = object->start_address; | ||
595 | return qt602240_write_reg(data->client, reg + offset, val); | ||
596 | } | ||
597 | |||
598 | static void qt602240_input_report(struct qt602240_data *data, int single_id) | ||
599 | { | ||
600 | struct qt602240_finger *finger = data->finger; | ||
601 | struct input_dev *input_dev = data->input_dev; | ||
602 | int status = finger[single_id].status; | ||
603 | int finger_num = 0; | ||
604 | int id; | ||
605 | |||
606 | for (id = 0; id < QT602240_MAX_FINGER; id++) { | ||
607 | if (!finger[id].status) | ||
608 | continue; | ||
609 | |||
610 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, | ||
611 | finger[id].status != QT602240_RELEASE ? | ||
612 | finger[id].area : 0); | ||
613 | input_report_abs(input_dev, ABS_MT_POSITION_X, | ||
614 | finger[id].x); | ||
615 | input_report_abs(input_dev, ABS_MT_POSITION_Y, | ||
616 | finger[id].y); | ||
617 | input_mt_sync(input_dev); | ||
618 | |||
619 | if (finger[id].status == QT602240_RELEASE) | ||
620 | finger[id].status = 0; | ||
621 | else | ||
622 | finger_num++; | ||
623 | } | ||
624 | |||
625 | input_report_key(input_dev, BTN_TOUCH, finger_num > 0); | ||
626 | |||
627 | if (status != QT602240_RELEASE) { | ||
628 | input_report_abs(input_dev, ABS_X, finger[single_id].x); | ||
629 | input_report_abs(input_dev, ABS_Y, finger[single_id].y); | ||
630 | } | ||
631 | |||
632 | input_sync(input_dev); | ||
633 | } | ||
634 | |||
635 | static void qt602240_input_touchevent(struct qt602240_data *data, | ||
636 | struct qt602240_message *message, int id) | ||
637 | { | ||
638 | struct qt602240_finger *finger = data->finger; | ||
639 | struct device *dev = &data->client->dev; | ||
640 | u8 status = message->message[0]; | ||
641 | int x; | ||
642 | int y; | ||
643 | int area; | ||
644 | |||
645 | /* Check the touch is present on the screen */ | ||
646 | if (!(status & QT602240_DETECT)) { | ||
647 | if (status & QT602240_RELEASE) { | ||
648 | dev_dbg(dev, "[%d] released\n", id); | ||
649 | |||
650 | finger[id].status = QT602240_RELEASE; | ||
651 | qt602240_input_report(data, id); | ||
652 | } | ||
653 | return; | ||
654 | } | ||
655 | |||
656 | /* Check only AMP detection */ | ||
657 | if (!(status & (QT602240_PRESS | QT602240_MOVE))) | ||
658 | return; | ||
659 | |||
660 | x = (message->message[1] << 2) | ((message->message[3] & ~0x3f) >> 6); | ||
661 | y = (message->message[2] << 2) | ((message->message[3] & ~0xf3) >> 2); | ||
662 | area = message->message[4]; | ||
663 | |||
664 | dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, | ||
665 | status & QT602240_MOVE ? "moved" : "pressed", | ||
666 | x, y, area); | ||
667 | |||
668 | finger[id].status = status & QT602240_MOVE ? | ||
669 | QT602240_MOVE : QT602240_PRESS; | ||
670 | finger[id].x = x; | ||
671 | finger[id].y = y; | ||
672 | finger[id].area = area; | ||
673 | |||
674 | qt602240_input_report(data, id); | ||
675 | } | ||
676 | |||
677 | static irqreturn_t qt602240_interrupt(int irq, void *dev_id) | ||
678 | { | ||
679 | struct qt602240_data *data = dev_id; | ||
680 | struct qt602240_message message; | ||
681 | struct qt602240_object *object; | ||
682 | struct device *dev = &data->client->dev; | ||
683 | int id; | ||
684 | u8 reportid; | ||
685 | u8 max_reportid; | ||
686 | u8 min_reportid; | ||
687 | |||
688 | do { | ||
689 | if (qt602240_read_message(data, &message)) { | ||
690 | dev_err(dev, "Failed to read message\n"); | ||
691 | goto end; | ||
692 | } | ||
693 | |||
694 | reportid = message.reportid; | ||
695 | |||
696 | /* whether reportid is thing of QT602240_TOUCH_MULTI */ | ||
697 | object = qt602240_get_object(data, QT602240_TOUCH_MULTI); | ||
698 | if (!object) | ||
699 | goto end; | ||
700 | |||
701 | max_reportid = object->max_reportid; | ||
702 | min_reportid = max_reportid - object->num_report_ids + 1; | ||
703 | id = reportid - min_reportid; | ||
704 | |||
705 | if (reportid >= min_reportid && reportid <= max_reportid) | ||
706 | qt602240_input_touchevent(data, &message, id); | ||
707 | else | ||
708 | qt602240_dump_message(dev, &message); | ||
709 | } while (reportid != 0xff); | ||
710 | |||
711 | end: | ||
712 | return IRQ_HANDLED; | ||
713 | } | ||
714 | |||
715 | static int qt602240_check_reg_init(struct qt602240_data *data) | ||
716 | { | ||
717 | struct qt602240_object *object; | ||
718 | struct device *dev = &data->client->dev; | ||
719 | int index = 0; | ||
720 | int i, j; | ||
721 | u8 version = data->info.version; | ||
722 | u8 *init_vals; | ||
723 | |||
724 | switch (version) { | ||
725 | case QT602240_VER_20: | ||
726 | init_vals = (u8 *)init_vals_ver_20; | ||
727 | break; | ||
728 | case QT602240_VER_21: | ||
729 | init_vals = (u8 *)init_vals_ver_21; | ||
730 | break; | ||
731 | case QT602240_VER_22: | ||
732 | init_vals = (u8 *)init_vals_ver_22; | ||
733 | break; | ||
734 | default: | ||
735 | dev_err(dev, "Firmware version %d doesn't support\n", version); | ||
736 | return -EINVAL; | ||
737 | } | ||
738 | |||
739 | for (i = 0; i < data->info.object_num; i++) { | ||
740 | object = data->object_table + i; | ||
741 | |||
742 | if (!qt602240_object_writable(object->type)) | ||
743 | continue; | ||
744 | |||
745 | for (j = 0; j < object->size + 1; j++) | ||
746 | qt602240_write_object(data, object->type, j, | ||
747 | init_vals[index + j]); | ||
748 | |||
749 | index += object->size + 1; | ||
750 | } | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static int qt602240_check_matrix_size(struct qt602240_data *data) | ||
756 | { | ||
757 | const struct qt602240_platform_data *pdata = data->pdata; | ||
758 | struct device *dev = &data->client->dev; | ||
759 | int mode = -1; | ||
760 | int error; | ||
761 | u8 val; | ||
762 | |||
763 | dev_dbg(dev, "Number of X lines: %d\n", pdata->x_line); | ||
764 | dev_dbg(dev, "Number of Y lines: %d\n", pdata->y_line); | ||
765 | |||
766 | switch (pdata->x_line) { | ||
767 | case 0 ... 15: | ||
768 | if (pdata->y_line <= 14) | ||
769 | mode = 0; | ||
770 | break; | ||
771 | case 16: | ||
772 | if (pdata->y_line <= 12) | ||
773 | mode = 1; | ||
774 | if (pdata->y_line == 13 || pdata->y_line == 14) | ||
775 | mode = 0; | ||
776 | break; | ||
777 | case 17: | ||
778 | if (pdata->y_line <= 11) | ||
779 | mode = 2; | ||
780 | if (pdata->y_line == 12 || pdata->y_line == 13) | ||
781 | mode = 1; | ||
782 | break; | ||
783 | case 18: | ||
784 | if (pdata->y_line <= 10) | ||
785 | mode = 3; | ||
786 | if (pdata->y_line == 11 || pdata->y_line == 12) | ||
787 | mode = 2; | ||
788 | break; | ||
789 | case 19: | ||
790 | if (pdata->y_line <= 9) | ||
791 | mode = 4; | ||
792 | if (pdata->y_line == 10 || pdata->y_line == 11) | ||
793 | mode = 3; | ||
794 | break; | ||
795 | case 20: | ||
796 | mode = 4; | ||
797 | } | ||
798 | |||
799 | if (mode < 0) { | ||
800 | dev_err(dev, "Invalid X/Y lines\n"); | ||
801 | return -EINVAL; | ||
802 | } | ||
803 | |||
804 | error = qt602240_read_object(data, QT602240_SPT_CTECONFIG, | ||
805 | QT602240_CTE_MODE, &val); | ||
806 | if (error) | ||
807 | return error; | ||
808 | |||
809 | if (mode == val) | ||
810 | return 0; | ||
811 | |||
812 | /* Change the CTE configuration */ | ||
813 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
814 | QT602240_CTE_CTRL, 1); | ||
815 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
816 | QT602240_CTE_MODE, mode); | ||
817 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
818 | QT602240_CTE_CTRL, 0); | ||
819 | |||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | static int qt602240_make_highchg(struct qt602240_data *data) | ||
824 | { | ||
825 | struct device *dev = &data->client->dev; | ||
826 | int count = 10; | ||
827 | int error; | ||
828 | u8 val; | ||
829 | |||
830 | /* Read dummy message to make high CHG pin */ | ||
831 | do { | ||
832 | error = qt602240_read_object(data, QT602240_GEN_MESSAGE, 0, &val); | ||
833 | if (error) | ||
834 | return error; | ||
835 | } while ((val != 0xff) && --count); | ||
836 | |||
837 | if (!count) { | ||
838 | dev_err(dev, "CHG pin isn't cleared\n"); | ||
839 | return -EBUSY; | ||
840 | } | ||
841 | |||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | static void qt602240_handle_pdata(struct qt602240_data *data) | ||
846 | { | ||
847 | const struct qt602240_platform_data *pdata = data->pdata; | ||
848 | u8 voltage; | ||
849 | |||
850 | /* Set touchscreen lines */ | ||
851 | qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_XSIZE, | ||
852 | pdata->x_line); | ||
853 | qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_YSIZE, | ||
854 | pdata->y_line); | ||
855 | |||
856 | /* Set touchscreen orient */ | ||
857 | qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_ORIENT, | ||
858 | pdata->orient); | ||
859 | |||
860 | /* Set touchscreen burst length */ | ||
861 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
862 | QT602240_TOUCH_BLEN, pdata->blen); | ||
863 | |||
864 | /* Set touchscreen threshold */ | ||
865 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
866 | QT602240_TOUCH_TCHTHR, pdata->threshold); | ||
867 | |||
868 | /* Set touchscreen resolution */ | ||
869 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
870 | QT602240_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff); | ||
871 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
872 | QT602240_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8); | ||
873 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
874 | QT602240_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff); | ||
875 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
876 | QT602240_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8); | ||
877 | |||
878 | /* Set touchscreen voltage */ | ||
879 | if (data->info.version >= QT602240_VER_21 && pdata->voltage) { | ||
880 | if (pdata->voltage < QT602240_VOLTAGE_DEFAULT) { | ||
881 | voltage = (QT602240_VOLTAGE_DEFAULT - pdata->voltage) / | ||
882 | QT602240_VOLTAGE_STEP; | ||
883 | voltage = 0xff - voltage + 1; | ||
884 | } else | ||
885 | voltage = (pdata->voltage - QT602240_VOLTAGE_DEFAULT) / | ||
886 | QT602240_VOLTAGE_STEP; | ||
887 | |||
888 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
889 | QT602240_CTE_VOLTAGE, voltage); | ||
890 | } | ||
891 | } | ||
892 | |||
893 | static int qt602240_get_info(struct qt602240_data *data) | ||
894 | { | ||
895 | struct i2c_client *client = data->client; | ||
896 | struct qt602240_info *info = &data->info; | ||
897 | int error; | ||
898 | u8 val; | ||
899 | |||
900 | error = qt602240_read_reg(client, QT602240_FAMILY_ID, &val); | ||
901 | if (error) | ||
902 | return error; | ||
903 | info->family_id = val; | ||
904 | |||
905 | error = qt602240_read_reg(client, QT602240_VARIANT_ID, &val); | ||
906 | if (error) | ||
907 | return error; | ||
908 | info->variant_id = val; | ||
909 | |||
910 | error = qt602240_read_reg(client, QT602240_VERSION, &val); | ||
911 | if (error) | ||
912 | return error; | ||
913 | info->version = val; | ||
914 | |||
915 | error = qt602240_read_reg(client, QT602240_BUILD, &val); | ||
916 | if (error) | ||
917 | return error; | ||
918 | info->build = val; | ||
919 | |||
920 | error = qt602240_read_reg(client, QT602240_OBJECT_NUM, &val); | ||
921 | if (error) | ||
922 | return error; | ||
923 | info->object_num = val; | ||
924 | |||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static int qt602240_get_object_table(struct qt602240_data *data) | ||
929 | { | ||
930 | int error; | ||
931 | int i; | ||
932 | u16 reg; | ||
933 | u8 reportid = 0; | ||
934 | u8 buf[QT602240_OBJECT_SIZE]; | ||
935 | |||
936 | for (i = 0; i < data->info.object_num; i++) { | ||
937 | struct qt602240_object *object = data->object_table + i; | ||
938 | |||
939 | reg = QT602240_OBJECT_START + QT602240_OBJECT_SIZE * i; | ||
940 | error = qt602240_read_object_table(data->client, reg, buf); | ||
941 | if (error) | ||
942 | return error; | ||
943 | |||
944 | object->type = buf[0]; | ||
945 | object->start_address = (buf[2] << 8) | buf[1]; | ||
946 | object->size = buf[3]; | ||
947 | object->instances = buf[4]; | ||
948 | object->num_report_ids = buf[5]; | ||
949 | |||
950 | if (object->num_report_ids) { | ||
951 | reportid += object->num_report_ids * | ||
952 | (object->instances + 1); | ||
953 | object->max_reportid = reportid; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | static int qt602240_initialize(struct qt602240_data *data) | ||
961 | { | ||
962 | struct i2c_client *client = data->client; | ||
963 | struct qt602240_info *info = &data->info; | ||
964 | int error; | ||
965 | u8 val; | ||
966 | |||
967 | error = qt602240_get_info(data); | ||
968 | if (error) | ||
969 | return error; | ||
970 | |||
971 | data->object_table = kcalloc(info->object_num, | ||
972 | sizeof(struct qt602240_data), | ||
973 | GFP_KERNEL); | ||
974 | if (!data->object_table) { | ||
975 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
976 | return -ENOMEM; | ||
977 | } | ||
978 | |||
979 | /* Get object table information */ | ||
980 | error = qt602240_get_object_table(data); | ||
981 | if (error) | ||
982 | return error; | ||
983 | |||
984 | /* Check register init values */ | ||
985 | error = qt602240_check_reg_init(data); | ||
986 | if (error) | ||
987 | return error; | ||
988 | |||
989 | /* Check X/Y matrix size */ | ||
990 | error = qt602240_check_matrix_size(data); | ||
991 | if (error) | ||
992 | return error; | ||
993 | |||
994 | error = qt602240_make_highchg(data); | ||
995 | if (error) | ||
996 | return error; | ||
997 | |||
998 | qt602240_handle_pdata(data); | ||
999 | |||
1000 | /* Backup to memory */ | ||
1001 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1002 | QT602240_COMMAND_BACKUPNV, | ||
1003 | QT602240_BACKUP_VALUE); | ||
1004 | msleep(QT602240_BACKUP_TIME); | ||
1005 | |||
1006 | /* Soft reset */ | ||
1007 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1008 | QT602240_COMMAND_RESET, 1); | ||
1009 | msleep(QT602240_RESET_TIME); | ||
1010 | |||
1011 | /* Update matrix size at info struct */ | ||
1012 | error = qt602240_read_reg(client, QT602240_MATRIX_X_SIZE, &val); | ||
1013 | if (error) | ||
1014 | return error; | ||
1015 | info->matrix_xsize = val; | ||
1016 | |||
1017 | error = qt602240_read_reg(client, QT602240_MATRIX_Y_SIZE, &val); | ||
1018 | if (error) | ||
1019 | return error; | ||
1020 | info->matrix_ysize = val; | ||
1021 | |||
1022 | dev_info(&client->dev, | ||
1023 | "Family ID: %d Variant ID: %d Version: %d Build: %d\n", | ||
1024 | info->family_id, info->variant_id, info->version, | ||
1025 | info->build); | ||
1026 | |||
1027 | dev_info(&client->dev, | ||
1028 | "Matrix X Size: %d Matrix Y Size: %d Object Num: %d\n", | ||
1029 | info->matrix_xsize, info->matrix_ysize, | ||
1030 | info->object_num); | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | static ssize_t qt602240_object_show(struct device *dev, | ||
1036 | struct device_attribute *attr, char *buf) | ||
1037 | { | ||
1038 | struct qt602240_data *data = dev_get_drvdata(dev); | ||
1039 | struct qt602240_object *object; | ||
1040 | int count = 0; | ||
1041 | int i, j; | ||
1042 | int error; | ||
1043 | u8 val; | ||
1044 | |||
1045 | for (i = 0; i < data->info.object_num; i++) { | ||
1046 | object = data->object_table + i; | ||
1047 | |||
1048 | count += sprintf(buf + count, | ||
1049 | "Object Table Element %d(Type %d)\n", | ||
1050 | i + 1, object->type); | ||
1051 | |||
1052 | if (!qt602240_object_readable(object->type)) { | ||
1053 | count += sprintf(buf + count, "\n"); | ||
1054 | continue; | ||
1055 | } | ||
1056 | |||
1057 | for (j = 0; j < object->size + 1; j++) { | ||
1058 | error = qt602240_read_object(data, | ||
1059 | object->type, j, &val); | ||
1060 | if (error) | ||
1061 | return error; | ||
1062 | |||
1063 | count += sprintf(buf + count, | ||
1064 | " Byte %d: 0x%x (%d)\n", j, val, val); | ||
1065 | } | ||
1066 | |||
1067 | count += sprintf(buf + count, "\n"); | ||
1068 | } | ||
1069 | |||
1070 | return count; | ||
1071 | } | ||
1072 | |||
1073 | static int qt602240_load_fw(struct device *dev, const char *fn) | ||
1074 | { | ||
1075 | struct qt602240_data *data = dev_get_drvdata(dev); | ||
1076 | struct i2c_client *client = data->client; | ||
1077 | const struct firmware *fw = NULL; | ||
1078 | unsigned int frame_size; | ||
1079 | unsigned int pos = 0; | ||
1080 | int ret; | ||
1081 | |||
1082 | ret = request_firmware(&fw, fn, dev); | ||
1083 | if (ret) { | ||
1084 | dev_err(dev, "Unable to open firmware %s\n", fn); | ||
1085 | return ret; | ||
1086 | } | ||
1087 | |||
1088 | /* Change to the bootloader mode */ | ||
1089 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1090 | QT602240_COMMAND_RESET, QT602240_BOOT_VALUE); | ||
1091 | msleep(QT602240_RESET_TIME); | ||
1092 | |||
1093 | /* Change to slave address of bootloader */ | ||
1094 | if (client->addr == QT602240_APP_LOW) | ||
1095 | client->addr = QT602240_BOOT_LOW; | ||
1096 | else | ||
1097 | client->addr = QT602240_BOOT_HIGH; | ||
1098 | |||
1099 | ret = qt602240_check_bootloader(client, QT602240_WAITING_BOOTLOAD_CMD); | ||
1100 | if (ret) | ||
1101 | goto out; | ||
1102 | |||
1103 | /* Unlock bootloader */ | ||
1104 | qt602240_unlock_bootloader(client); | ||
1105 | |||
1106 | while (pos < fw->size) { | ||
1107 | ret = qt602240_check_bootloader(client, | ||
1108 | QT602240_WAITING_FRAME_DATA); | ||
1109 | if (ret) | ||
1110 | goto out; | ||
1111 | |||
1112 | frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); | ||
1113 | |||
1114 | /* We should add 2 at frame size as the the firmware data is not | ||
1115 | * included the CRC bytes. | ||
1116 | */ | ||
1117 | frame_size += 2; | ||
1118 | |||
1119 | /* Write one frame to device */ | ||
1120 | qt602240_fw_write(client, fw->data + pos, frame_size); | ||
1121 | |||
1122 | ret = qt602240_check_bootloader(client, | ||
1123 | QT602240_FRAME_CRC_PASS); | ||
1124 | if (ret) | ||
1125 | goto out; | ||
1126 | |||
1127 | pos += frame_size; | ||
1128 | |||
1129 | dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); | ||
1130 | } | ||
1131 | |||
1132 | out: | ||
1133 | release_firmware(fw); | ||
1134 | |||
1135 | /* Change to slave address of application */ | ||
1136 | if (client->addr == QT602240_BOOT_LOW) | ||
1137 | client->addr = QT602240_APP_LOW; | ||
1138 | else | ||
1139 | client->addr = QT602240_APP_HIGH; | ||
1140 | |||
1141 | return ret; | ||
1142 | } | ||
1143 | |||
1144 | static ssize_t qt602240_update_fw_store(struct device *dev, | ||
1145 | struct device_attribute *attr, | ||
1146 | const char *buf, size_t count) | ||
1147 | { | ||
1148 | struct qt602240_data *data = dev_get_drvdata(dev); | ||
1149 | unsigned int version; | ||
1150 | int error; | ||
1151 | |||
1152 | if (sscanf(buf, "%u", &version) != 1) { | ||
1153 | dev_err(dev, "Invalid values\n"); | ||
1154 | return -EINVAL; | ||
1155 | } | ||
1156 | |||
1157 | if (data->info.version < QT602240_VER_21 || version < QT602240_VER_21) { | ||
1158 | dev_err(dev, "FW update supported starting with version 21\n"); | ||
1159 | return -EINVAL; | ||
1160 | } | ||
1161 | |||
1162 | disable_irq(data->irq); | ||
1163 | |||
1164 | error = qt602240_load_fw(dev, QT602240_FW_NAME); | ||
1165 | if (error) { | ||
1166 | dev_err(dev, "The firmware update failed(%d)\n", error); | ||
1167 | count = error; | ||
1168 | } else { | ||
1169 | dev_dbg(dev, "The firmware update succeeded\n"); | ||
1170 | |||
1171 | /* Wait for reset */ | ||
1172 | msleep(QT602240_FWRESET_TIME); | ||
1173 | |||
1174 | kfree(data->object_table); | ||
1175 | data->object_table = NULL; | ||
1176 | |||
1177 | qt602240_initialize(data); | ||
1178 | } | ||
1179 | |||
1180 | enable_irq(data->irq); | ||
1181 | |||
1182 | return count; | ||
1183 | } | ||
1184 | |||
1185 | static DEVICE_ATTR(object, 0444, qt602240_object_show, NULL); | ||
1186 | static DEVICE_ATTR(update_fw, 0664, NULL, qt602240_update_fw_store); | ||
1187 | |||
1188 | static struct attribute *qt602240_attrs[] = { | ||
1189 | &dev_attr_object.attr, | ||
1190 | &dev_attr_update_fw.attr, | ||
1191 | NULL | ||
1192 | }; | ||
1193 | |||
1194 | static const struct attribute_group qt602240_attr_group = { | ||
1195 | .attrs = qt602240_attrs, | ||
1196 | }; | ||
1197 | |||
1198 | static void qt602240_start(struct qt602240_data *data) | ||
1199 | { | ||
1200 | /* Touch enable */ | ||
1201 | qt602240_write_object(data, | ||
1202 | QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0x83); | ||
1203 | } | ||
1204 | |||
1205 | static void qt602240_stop(struct qt602240_data *data) | ||
1206 | { | ||
1207 | /* Touch disable */ | ||
1208 | qt602240_write_object(data, | ||
1209 | QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0); | ||
1210 | } | ||
1211 | |||
1212 | static int qt602240_input_open(struct input_dev *dev) | ||
1213 | { | ||
1214 | struct qt602240_data *data = input_get_drvdata(dev); | ||
1215 | |||
1216 | qt602240_start(data); | ||
1217 | |||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1221 | static void qt602240_input_close(struct input_dev *dev) | ||
1222 | { | ||
1223 | struct qt602240_data *data = input_get_drvdata(dev); | ||
1224 | |||
1225 | qt602240_stop(data); | ||
1226 | } | ||
1227 | |||
1228 | static int __devinit qt602240_probe(struct i2c_client *client, | ||
1229 | const struct i2c_device_id *id) | ||
1230 | { | ||
1231 | struct qt602240_data *data; | ||
1232 | struct input_dev *input_dev; | ||
1233 | int error; | ||
1234 | |||
1235 | if (!client->dev.platform_data) | ||
1236 | return -EINVAL; | ||
1237 | |||
1238 | data = kzalloc(sizeof(struct qt602240_data), GFP_KERNEL); | ||
1239 | input_dev = input_allocate_device(); | ||
1240 | if (!data || !input_dev) { | ||
1241 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
1242 | error = -ENOMEM; | ||
1243 | goto err_free_mem; | ||
1244 | } | ||
1245 | |||
1246 | input_dev->name = "AT42QT602240/ATMXT224 Touchscreen"; | ||
1247 | input_dev->id.bustype = BUS_I2C; | ||
1248 | input_dev->dev.parent = &client->dev; | ||
1249 | input_dev->open = qt602240_input_open; | ||
1250 | input_dev->close = qt602240_input_close; | ||
1251 | |||
1252 | __set_bit(EV_ABS, input_dev->evbit); | ||
1253 | __set_bit(EV_KEY, input_dev->evbit); | ||
1254 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1255 | |||
1256 | /* For single touch */ | ||
1257 | input_set_abs_params(input_dev, ABS_X, | ||
1258 | 0, QT602240_MAX_XC, 0, 0); | ||
1259 | input_set_abs_params(input_dev, ABS_Y, | ||
1260 | 0, QT602240_MAX_YC, 0, 0); | ||
1261 | |||
1262 | /* For multi touch */ | ||
1263 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
1264 | 0, QT602240_MAX_AREA, 0, 0); | ||
1265 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1266 | 0, QT602240_MAX_XC, 0, 0); | ||
1267 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1268 | 0, QT602240_MAX_YC, 0, 0); | ||
1269 | |||
1270 | input_set_drvdata(input_dev, data); | ||
1271 | |||
1272 | data->client = client; | ||
1273 | data->input_dev = input_dev; | ||
1274 | data->pdata = client->dev.platform_data; | ||
1275 | data->irq = client->irq; | ||
1276 | |||
1277 | i2c_set_clientdata(client, data); | ||
1278 | |||
1279 | error = qt602240_initialize(data); | ||
1280 | if (error) | ||
1281 | goto err_free_object; | ||
1282 | |||
1283 | error = request_threaded_irq(client->irq, NULL, qt602240_interrupt, | ||
1284 | IRQF_TRIGGER_FALLING, client->dev.driver->name, data); | ||
1285 | if (error) { | ||
1286 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
1287 | goto err_free_object; | ||
1288 | } | ||
1289 | |||
1290 | error = input_register_device(input_dev); | ||
1291 | if (error) | ||
1292 | goto err_free_irq; | ||
1293 | |||
1294 | error = sysfs_create_group(&client->dev.kobj, &qt602240_attr_group); | ||
1295 | if (error) | ||
1296 | goto err_unregister_device; | ||
1297 | |||
1298 | return 0; | ||
1299 | |||
1300 | err_unregister_device: | ||
1301 | input_unregister_device(input_dev); | ||
1302 | input_dev = NULL; | ||
1303 | err_free_irq: | ||
1304 | free_irq(client->irq, data); | ||
1305 | err_free_object: | ||
1306 | kfree(data->object_table); | ||
1307 | err_free_mem: | ||
1308 | input_free_device(input_dev); | ||
1309 | kfree(data); | ||
1310 | return error; | ||
1311 | } | ||
1312 | |||
1313 | static int __devexit qt602240_remove(struct i2c_client *client) | ||
1314 | { | ||
1315 | struct qt602240_data *data = i2c_get_clientdata(client); | ||
1316 | |||
1317 | sysfs_remove_group(&client->dev.kobj, &qt602240_attr_group); | ||
1318 | free_irq(data->irq, data); | ||
1319 | input_unregister_device(data->input_dev); | ||
1320 | kfree(data->object_table); | ||
1321 | kfree(data); | ||
1322 | |||
1323 | return 0; | ||
1324 | } | ||
1325 | |||
1326 | #ifdef CONFIG_PM | ||
1327 | static int qt602240_suspend(struct i2c_client *client, pm_message_t mesg) | ||
1328 | { | ||
1329 | struct qt602240_data *data = i2c_get_clientdata(client); | ||
1330 | struct input_dev *input_dev = data->input_dev; | ||
1331 | |||
1332 | mutex_lock(&input_dev->mutex); | ||
1333 | |||
1334 | if (input_dev->users) | ||
1335 | qt602240_stop(data); | ||
1336 | |||
1337 | mutex_unlock(&input_dev->mutex); | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | static int qt602240_resume(struct i2c_client *client) | ||
1343 | { | ||
1344 | struct qt602240_data *data = i2c_get_clientdata(client); | ||
1345 | struct input_dev *input_dev = data->input_dev; | ||
1346 | |||
1347 | /* Soft reset */ | ||
1348 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1349 | QT602240_COMMAND_RESET, 1); | ||
1350 | |||
1351 | msleep(QT602240_RESET_TIME); | ||
1352 | |||
1353 | mutex_lock(&input_dev->mutex); | ||
1354 | |||
1355 | if (input_dev->users) | ||
1356 | qt602240_start(data); | ||
1357 | |||
1358 | mutex_unlock(&input_dev->mutex); | ||
1359 | |||
1360 | return 0; | ||
1361 | } | ||
1362 | #else | ||
1363 | #define qt602240_suspend NULL | ||
1364 | #define qt602240_resume NULL | ||
1365 | #endif | ||
1366 | |||
1367 | static const struct i2c_device_id qt602240_id[] = { | ||
1368 | { "qt602240_ts", 0 }, | ||
1369 | { } | ||
1370 | }; | ||
1371 | MODULE_DEVICE_TABLE(i2c, qt602240_id); | ||
1372 | |||
1373 | static struct i2c_driver qt602240_driver = { | ||
1374 | .driver = { | ||
1375 | .name = "qt602240_ts", | ||
1376 | .owner = THIS_MODULE, | ||
1377 | }, | ||
1378 | .probe = qt602240_probe, | ||
1379 | .remove = __devexit_p(qt602240_remove), | ||
1380 | .suspend = qt602240_suspend, | ||
1381 | .resume = qt602240_resume, | ||
1382 | .id_table = qt602240_id, | ||
1383 | }; | ||
1384 | |||
1385 | static int __init qt602240_init(void) | ||
1386 | { | ||
1387 | return i2c_add_driver(&qt602240_driver); | ||
1388 | } | ||
1389 | |||
1390 | static void __exit qt602240_exit(void) | ||
1391 | { | ||
1392 | i2c_del_driver(&qt602240_driver); | ||
1393 | } | ||
1394 | |||
1395 | module_init(qt602240_init); | ||
1396 | module_exit(qt602240_exit); | ||
1397 | |||
1398 | /* Module information */ | ||
1399 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
1400 | MODULE_DESCRIPTION("AT42QT602240/ATMXT224 Touchscreen driver"); | ||
1401 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index 6386b441ef85..8feb7f3c8be1 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/slab.h> | ||
30 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
31 | #include <linux/input.h> | 30 | #include <linux/input.h> |
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
@@ -38,9 +37,7 @@ | |||
38 | 37 | ||
39 | #include <plat/adc.h> | 38 | #include <plat/adc.h> |
40 | #include <plat/regs-adc.h> | 39 | #include <plat/regs-adc.h> |
41 | 40 | #include <plat/ts.h> | |
42 | #include <mach/regs-gpio.h> | ||
43 | #include <mach/ts.h> | ||
44 | 41 | ||
45 | #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) | 42 | #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) |
46 | 43 | ||
@@ -58,6 +55,8 @@ | |||
58 | S3C2410_ADCTSC_AUTO_PST | \ | 55 | S3C2410_ADCTSC_AUTO_PST | \ |
59 | S3C2410_ADCTSC_XY_PST(0)) | 56 | S3C2410_ADCTSC_XY_PST(0)) |
60 | 57 | ||
58 | #define FEAT_PEN_IRQ (1 << 0) /* HAS ADCCLRINTPNDNUP */ | ||
59 | |||
61 | /* Per-touchscreen data. */ | 60 | /* Per-touchscreen data. */ |
62 | 61 | ||
63 | /** | 62 | /** |
@@ -72,6 +71,7 @@ | |||
72 | * @irq_tc: The interrupt number for pen up/down interrupt | 71 | * @irq_tc: The interrupt number for pen up/down interrupt |
73 | * @count: The number of samples collected. | 72 | * @count: The number of samples collected. |
74 | * @shift: The log2 of the maximum count to read in one go. | 73 | * @shift: The log2 of the maximum count to read in one go. |
74 | * @features: The features supported by the TSADC MOdule. | ||
75 | */ | 75 | */ |
76 | struct s3c2410ts { | 76 | struct s3c2410ts { |
77 | struct s3c_adc_client *client; | 77 | struct s3c_adc_client *client; |
@@ -84,26 +84,12 @@ struct s3c2410ts { | |||
84 | int irq_tc; | 84 | int irq_tc; |
85 | int count; | 85 | int count; |
86 | int shift; | 86 | int shift; |
87 | int features; | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | static struct s3c2410ts ts; | 90 | static struct s3c2410ts ts; |
90 | 91 | ||
91 | /** | 92 | /** |
92 | * s3c2410_ts_connect - configure gpio for s3c2410 systems | ||
93 | * | ||
94 | * Configure the GPIO for the S3C2410 system, where we have external FETs | ||
95 | * connected to the device (later systems such as the S3C2440 integrate | ||
96 | * these into the device). | ||
97 | */ | ||
98 | static inline void s3c2410_ts_connect(void) | ||
99 | { | ||
100 | s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON); | ||
101 | s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON); | ||
102 | s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON); | ||
103 | s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON); | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * get_down - return the down state of the pen | 93 | * get_down - return the down state of the pen |
108 | * @data0: The data read from ADCDAT0 register. | 94 | * @data0: The data read from ADCDAT0 register. |
109 | * @data1: The data read from ADCDAT1 register. | 95 | * @data1: The data read from ADCDAT1 register. |
@@ -128,27 +114,29 @@ static void touch_timer_fire(unsigned long data) | |||
128 | 114 | ||
129 | down = get_down(data0, data1); | 115 | down = get_down(data0, data1); |
130 | 116 | ||
131 | if (ts.count == (1 << ts.shift)) { | 117 | if (down) { |
132 | ts.xp >>= ts.shift; | 118 | if (ts.count == (1 << ts.shift)) { |
133 | ts.yp >>= ts.shift; | 119 | ts.xp >>= ts.shift; |
120 | ts.yp >>= ts.shift; | ||
134 | 121 | ||
135 | dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n", | 122 | dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n", |
136 | __func__, ts.xp, ts.yp, ts.count); | 123 | __func__, ts.xp, ts.yp, ts.count); |
137 | 124 | ||
138 | input_report_abs(ts.input, ABS_X, ts.xp); | 125 | input_report_abs(ts.input, ABS_X, ts.xp); |
139 | input_report_abs(ts.input, ABS_Y, ts.yp); | 126 | input_report_abs(ts.input, ABS_Y, ts.yp); |
140 | 127 | ||
141 | input_report_key(ts.input, BTN_TOUCH, 1); | 128 | input_report_key(ts.input, BTN_TOUCH, 1); |
142 | input_sync(ts.input); | 129 | input_sync(ts.input); |
143 | 130 | ||
144 | ts.xp = 0; | 131 | ts.xp = 0; |
145 | ts.yp = 0; | 132 | ts.yp = 0; |
146 | ts.count = 0; | 133 | ts.count = 0; |
147 | } | 134 | } |
148 | 135 | ||
149 | if (down) { | ||
150 | s3c_adc_start(ts.client, 0, 1 << ts.shift); | 136 | s3c_adc_start(ts.client, 0, 1 << ts.shift); |
151 | } else { | 137 | } else { |
138 | ts.xp = 0; | ||
139 | ts.yp = 0; | ||
152 | ts.count = 0; | 140 | ts.count = 0; |
153 | 141 | ||
154 | input_report_key(ts.input, BTN_TOUCH, 0); | 142 | input_report_key(ts.input, BTN_TOUCH, 0); |
@@ -185,7 +173,12 @@ static irqreturn_t stylus_irq(int irq, void *dev_id) | |||
185 | if (down) | 173 | if (down) |
186 | s3c_adc_start(ts.client, 0, 1 << ts.shift); | 174 | s3c_adc_start(ts.client, 0, 1 << ts.shift); |
187 | else | 175 | else |
188 | dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count); | 176 | dev_dbg(ts.dev, "%s: count=%d\n", __func__, ts.count); |
177 | |||
178 | if (ts.features & FEAT_PEN_IRQ) { | ||
179 | /* Clear pen down/up interrupt */ | ||
180 | writel(0x0, ts.io + S3C64XX_ADCCLRINTPNDNUP); | ||
181 | } | ||
189 | 182 | ||
190 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
191 | } | 184 | } |
@@ -295,9 +288,9 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) | |||
295 | goto err_clk; | 288 | goto err_clk; |
296 | } | 289 | } |
297 | 290 | ||
298 | /* Configure the touchscreen external FETs on the S3C2410 */ | 291 | /* inititalise the gpio */ |
299 | if (!platform_get_device_id(pdev)->driver_data) | 292 | if (info->cfg_gpio) |
300 | s3c2410_ts_connect(); | 293 | info->cfg_gpio(to_platform_device(ts.dev)); |
301 | 294 | ||
302 | ts.client = s3c_adc_register(pdev, s3c24xx_ts_select, | 295 | ts.client = s3c_adc_register(pdev, s3c24xx_ts_select, |
303 | s3c24xx_ts_conversion, 1); | 296 | s3c24xx_ts_conversion, 1); |
@@ -333,6 +326,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) | |||
333 | ts.input->id.version = 0x0102; | 326 | ts.input->id.version = 0x0102; |
334 | 327 | ||
335 | ts.shift = info->oversampling_shift; | 328 | ts.shift = info->oversampling_shift; |
329 | ts.features = platform_get_device_id(pdev)->driver_data; | ||
336 | 330 | ||
337 | ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED, | 331 | ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED, |
338 | "s3c2410_ts_pen", ts.input); | 332 | "s3c2410_ts_pen", ts.input); |
@@ -356,7 +350,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) | |||
356 | err_tcirq: | 350 | err_tcirq: |
357 | free_irq(ts.irq_tc, ts.input); | 351 | free_irq(ts.irq_tc, ts.input); |
358 | err_inputdev: | 352 | err_inputdev: |
359 | input_unregister_device(ts.input); | 353 | input_free_device(ts.input); |
360 | err_iomap: | 354 | err_iomap: |
361 | iounmap(ts.io); | 355 | iounmap(ts.io); |
362 | err_clk: | 356 | err_clk: |
@@ -401,6 +395,7 @@ static int s3c2410ts_resume(struct device *dev) | |||
401 | struct s3c2410_ts_mach_info *info = pdev->dev.platform_data; | 395 | struct s3c2410_ts_mach_info *info = pdev->dev.platform_data; |
402 | 396 | ||
403 | clk_enable(ts.clock); | 397 | clk_enable(ts.clock); |
398 | enable_irq(ts.irq_tc); | ||
404 | 399 | ||
405 | /* Initialise registers */ | 400 | /* Initialise registers */ |
406 | if ((info->delay & 0xffff) > 0) | 401 | if ((info->delay & 0xffff) > 0) |
@@ -419,14 +414,15 @@ static struct dev_pm_ops s3c_ts_pmops = { | |||
419 | 414 | ||
420 | static struct platform_device_id s3cts_driver_ids[] = { | 415 | static struct platform_device_id s3cts_driver_ids[] = { |
421 | { "s3c2410-ts", 0 }, | 416 | { "s3c2410-ts", 0 }, |
422 | { "s3c2440-ts", 1 }, | 417 | { "s3c2440-ts", 0 }, |
418 | { "s3c64xx-ts", FEAT_PEN_IRQ }, | ||
423 | { } | 419 | { } |
424 | }; | 420 | }; |
425 | MODULE_DEVICE_TABLE(platform, s3cts_driver_ids); | 421 | MODULE_DEVICE_TABLE(platform, s3cts_driver_ids); |
426 | 422 | ||
427 | static struct platform_driver s3c_ts_driver = { | 423 | static struct platform_driver s3c_ts_driver = { |
428 | .driver = { | 424 | .driver = { |
429 | .name = "s3c24xx-ts", | 425 | .name = "samsung-ts", |
430 | .owner = THIS_MODULE, | 426 | .owner = THIS_MODULE, |
431 | #ifdef CONFIG_PM | 427 | #ifdef CONFIG_PM |
432 | .pm = &s3c_ts_pmops, | 428 | .pm = &s3c_ts_pmops, |
diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c new file mode 100644 index 000000000000..ae88e13c99ff --- /dev/null +++ b/drivers/input/touchscreen/stmpe-ts.c | |||
@@ -0,0 +1,400 @@ | |||
1 | /* STMicroelectronics STMPE811 Touchscreen Driver | ||
2 | * | ||
3 | * (C) 2010 Luotao Fu <l.fu@pengutronix.de> | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | |||
26 | #include <linux/mfd/stmpe.h> | ||
27 | |||
28 | /* Register layouts and functionalities are identical on all stmpexxx variants | ||
29 | * with touchscreen controller | ||
30 | */ | ||
31 | #define STMPE_REG_INT_STA 0x0B | ||
32 | #define STMPE_REG_ADC_CTRL1 0x20 | ||
33 | #define STMPE_REG_ADC_CTRL2 0x21 | ||
34 | #define STMPE_REG_TSC_CTRL 0x40 | ||
35 | #define STMPE_REG_TSC_CFG 0x41 | ||
36 | #define STMPE_REG_FIFO_TH 0x4A | ||
37 | #define STMPE_REG_FIFO_STA 0x4B | ||
38 | #define STMPE_REG_FIFO_SIZE 0x4C | ||
39 | #define STMPE_REG_TSC_DATA_XYZ 0x52 | ||
40 | #define STMPE_REG_TSC_FRACTION_Z 0x56 | ||
41 | #define STMPE_REG_TSC_I_DRIVE 0x58 | ||
42 | |||
43 | #define OP_MOD_XYZ 0 | ||
44 | |||
45 | #define STMPE_TSC_CTRL_TSC_EN (1<<0) | ||
46 | |||
47 | #define STMPE_FIFO_STA_RESET (1<<0) | ||
48 | |||
49 | #define STMPE_IRQ_TOUCH_DET 0 | ||
50 | |||
51 | #define SAMPLE_TIME(x) ((x & 0xf) << 4) | ||
52 | #define MOD_12B(x) ((x & 0x1) << 3) | ||
53 | #define REF_SEL(x) ((x & 0x1) << 1) | ||
54 | #define ADC_FREQ(x) (x & 0x3) | ||
55 | #define AVE_CTRL(x) ((x & 0x3) << 6) | ||
56 | #define DET_DELAY(x) ((x & 0x7) << 3) | ||
57 | #define SETTLING(x) (x & 0x7) | ||
58 | #define FRACTION_Z(x) (x & 0x7) | ||
59 | #define I_DRIVE(x) (x & 0x1) | ||
60 | #define OP_MODE(x) ((x & 0x7) << 1) | ||
61 | |||
62 | #define STMPE_TS_NAME "stmpe-ts" | ||
63 | #define XY_MASK 0xfff | ||
64 | |||
65 | struct stmpe_touch { | ||
66 | struct stmpe *stmpe; | ||
67 | struct input_dev *idev; | ||
68 | struct delayed_work work; | ||
69 | struct device *dev; | ||
70 | u8 sample_time; | ||
71 | u8 mod_12b; | ||
72 | u8 ref_sel; | ||
73 | u8 adc_freq; | ||
74 | u8 ave_ctrl; | ||
75 | u8 touch_det_delay; | ||
76 | u8 settling; | ||
77 | u8 fraction_z; | ||
78 | u8 i_drive; | ||
79 | }; | ||
80 | |||
81 | static int __stmpe_reset_fifo(struct stmpe *stmpe) | ||
82 | { | ||
83 | int ret; | ||
84 | |||
85 | ret = stmpe_set_bits(stmpe, STMPE_REG_FIFO_STA, | ||
86 | STMPE_FIFO_STA_RESET, STMPE_FIFO_STA_RESET); | ||
87 | if (ret) | ||
88 | return ret; | ||
89 | |||
90 | return stmpe_set_bits(stmpe, STMPE_REG_FIFO_STA, | ||
91 | STMPE_FIFO_STA_RESET, 0); | ||
92 | } | ||
93 | |||
94 | static void stmpe_work(struct work_struct *work) | ||
95 | { | ||
96 | int int_sta; | ||
97 | u32 timeout = 40; | ||
98 | |||
99 | struct stmpe_touch *ts = | ||
100 | container_of(work, struct stmpe_touch, work.work); | ||
101 | |||
102 | int_sta = stmpe_reg_read(ts->stmpe, STMPE_REG_INT_STA); | ||
103 | |||
104 | /* | ||
105 | * touch_det sometimes get desasserted or just get stuck. This appears | ||
106 | * to be a silicon bug, We still have to clearify this with the | ||
107 | * manufacture. As a workaround We release the key anyway if the | ||
108 | * touch_det keeps coming in after 4ms, while the FIFO contains no value | ||
109 | * during the whole time. | ||
110 | */ | ||
111 | while ((int_sta & (1 << STMPE_IRQ_TOUCH_DET)) && (timeout > 0)) { | ||
112 | timeout--; | ||
113 | int_sta = stmpe_reg_read(ts->stmpe, STMPE_REG_INT_STA); | ||
114 | udelay(100); | ||
115 | } | ||
116 | |||
117 | /* reset the FIFO before we report release event */ | ||
118 | __stmpe_reset_fifo(ts->stmpe); | ||
119 | |||
120 | input_report_abs(ts->idev, ABS_PRESSURE, 0); | ||
121 | input_sync(ts->idev); | ||
122 | } | ||
123 | |||
124 | static irqreturn_t stmpe_ts_handler(int irq, void *data) | ||
125 | { | ||
126 | u8 data_set[4]; | ||
127 | int x, y, z; | ||
128 | struct stmpe_touch *ts = data; | ||
129 | |||
130 | /* | ||
131 | * Cancel scheduled polling for release if we have new value | ||
132 | * available. Wait if the polling is already running. | ||
133 | */ | ||
134 | cancel_delayed_work_sync(&ts->work); | ||
135 | |||
136 | /* | ||
137 | * The FIFO sometimes just crashes and stops generating interrupts. This | ||
138 | * appears to be a silicon bug. We still have to clearify this with | ||
139 | * the manufacture. As a workaround we disable the TSC while we are | ||
140 | * collecting data and flush the FIFO after reading | ||
141 | */ | ||
142 | stmpe_set_bits(ts->stmpe, STMPE_REG_TSC_CTRL, | ||
143 | STMPE_TSC_CTRL_TSC_EN, 0); | ||
144 | |||
145 | stmpe_block_read(ts->stmpe, STMPE_REG_TSC_DATA_XYZ, 4, data_set); | ||
146 | |||
147 | x = (data_set[0] << 4) | (data_set[1] >> 4); | ||
148 | y = ((data_set[1] & 0xf) << 8) | data_set[2]; | ||
149 | z = data_set[3]; | ||
150 | |||
151 | input_report_abs(ts->idev, ABS_X, x); | ||
152 | input_report_abs(ts->idev, ABS_Y, y); | ||
153 | input_report_abs(ts->idev, ABS_PRESSURE, z); | ||
154 | input_sync(ts->idev); | ||
155 | |||
156 | /* flush the FIFO after we have read out our values. */ | ||
157 | __stmpe_reset_fifo(ts->stmpe); | ||
158 | |||
159 | /* reenable the tsc */ | ||
160 | stmpe_set_bits(ts->stmpe, STMPE_REG_TSC_CTRL, | ||
161 | STMPE_TSC_CTRL_TSC_EN, STMPE_TSC_CTRL_TSC_EN); | ||
162 | |||
163 | /* start polling for touch_det to detect release */ | ||
164 | schedule_delayed_work(&ts->work, HZ / 50); | ||
165 | |||
166 | return IRQ_HANDLED; | ||
167 | } | ||
168 | |||
169 | static int __devinit stmpe_init_hw(struct stmpe_touch *ts) | ||
170 | { | ||
171 | int ret; | ||
172 | u8 adc_ctrl1, adc_ctrl1_mask, tsc_cfg, tsc_cfg_mask; | ||
173 | struct stmpe *stmpe = ts->stmpe; | ||
174 | struct device *dev = ts->dev; | ||
175 | |||
176 | ret = stmpe_enable(stmpe, STMPE_BLOCK_TOUCHSCREEN | STMPE_BLOCK_ADC); | ||
177 | if (ret) { | ||
178 | dev_err(dev, "Could not enable clock for ADC and TS\n"); | ||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | adc_ctrl1 = SAMPLE_TIME(ts->sample_time) | MOD_12B(ts->mod_12b) | | ||
183 | REF_SEL(ts->ref_sel); | ||
184 | adc_ctrl1_mask = SAMPLE_TIME(0xff) | MOD_12B(0xff) | REF_SEL(0xff); | ||
185 | |||
186 | ret = stmpe_set_bits(stmpe, STMPE_REG_ADC_CTRL1, | ||
187 | adc_ctrl1_mask, adc_ctrl1); | ||
188 | if (ret) { | ||
189 | dev_err(dev, "Could not setup ADC\n"); | ||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | ret = stmpe_set_bits(stmpe, STMPE_REG_ADC_CTRL2, | ||
194 | ADC_FREQ(0xff), ADC_FREQ(ts->adc_freq)); | ||
195 | if (ret) { | ||
196 | dev_err(dev, "Could not setup ADC\n"); | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | tsc_cfg = AVE_CTRL(ts->ave_ctrl) | DET_DELAY(ts->touch_det_delay) | | ||
201 | SETTLING(ts->settling); | ||
202 | tsc_cfg_mask = AVE_CTRL(0xff) | DET_DELAY(0xff) | SETTLING(0xff); | ||
203 | |||
204 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_CFG, tsc_cfg_mask, tsc_cfg); | ||
205 | if (ret) { | ||
206 | dev_err(dev, "Could not config touch\n"); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_FRACTION_Z, | ||
211 | FRACTION_Z(0xff), FRACTION_Z(ts->fraction_z)); | ||
212 | if (ret) { | ||
213 | dev_err(dev, "Could not config touch\n"); | ||
214 | return ret; | ||
215 | } | ||
216 | |||
217 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_I_DRIVE, | ||
218 | I_DRIVE(0xff), I_DRIVE(ts->i_drive)); | ||
219 | if (ret) { | ||
220 | dev_err(dev, "Could not config touch\n"); | ||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | /* set FIFO to 1 for single point reading */ | ||
225 | ret = stmpe_reg_write(stmpe, STMPE_REG_FIFO_TH, 1); | ||
226 | if (ret) { | ||
227 | dev_err(dev, "Could not set FIFO\n"); | ||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_CTRL, | ||
232 | OP_MODE(0xff), OP_MODE(OP_MOD_XYZ)); | ||
233 | if (ret) { | ||
234 | dev_err(dev, "Could not set mode\n"); | ||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int stmpe_ts_open(struct input_dev *dev) | ||
242 | { | ||
243 | struct stmpe_touch *ts = input_get_drvdata(dev); | ||
244 | int ret = 0; | ||
245 | |||
246 | ret = __stmpe_reset_fifo(ts->stmpe); | ||
247 | if (ret) | ||
248 | return ret; | ||
249 | |||
250 | return stmpe_set_bits(ts->stmpe, STMPE_REG_TSC_CTRL, | ||
251 | STMPE_TSC_CTRL_TSC_EN, STMPE_TSC_CTRL_TSC_EN); | ||
252 | } | ||
253 | |||
254 | static void stmpe_ts_close(struct input_dev *dev) | ||
255 | { | ||
256 | struct stmpe_touch *ts = input_get_drvdata(dev); | ||
257 | |||
258 | cancel_delayed_work_sync(&ts->work); | ||
259 | |||
260 | stmpe_set_bits(ts->stmpe, STMPE_REG_TSC_CTRL, | ||
261 | STMPE_TSC_CTRL_TSC_EN, 0); | ||
262 | } | ||
263 | |||
264 | static int __devinit stmpe_input_probe(struct platform_device *pdev) | ||
265 | { | ||
266 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | ||
267 | struct stmpe_platform_data *pdata = stmpe->pdata; | ||
268 | struct stmpe_touch *ts; | ||
269 | struct input_dev *idev; | ||
270 | struct stmpe_ts_platform_data *ts_pdata = NULL; | ||
271 | int ret; | ||
272 | int ts_irq; | ||
273 | |||
274 | ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); | ||
275 | if (ts_irq < 0) | ||
276 | return ts_irq; | ||
277 | |||
278 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | ||
279 | if (!ts) { | ||
280 | ret = -ENOMEM; | ||
281 | goto err_out; | ||
282 | } | ||
283 | |||
284 | idev = input_allocate_device(); | ||
285 | if (!idev) { | ||
286 | ret = -ENOMEM; | ||
287 | goto err_free_ts; | ||
288 | } | ||
289 | |||
290 | platform_set_drvdata(pdev, ts); | ||
291 | ts->stmpe = stmpe; | ||
292 | ts->idev = idev; | ||
293 | ts->dev = &pdev->dev; | ||
294 | |||
295 | if (pdata) | ||
296 | ts_pdata = pdata->ts; | ||
297 | |||
298 | if (ts_pdata) { | ||
299 | ts->sample_time = ts_pdata->sample_time; | ||
300 | ts->mod_12b = ts_pdata->mod_12b; | ||
301 | ts->ref_sel = ts_pdata->ref_sel; | ||
302 | ts->adc_freq = ts_pdata->adc_freq; | ||
303 | ts->ave_ctrl = ts_pdata->ave_ctrl; | ||
304 | ts->touch_det_delay = ts_pdata->touch_det_delay; | ||
305 | ts->settling = ts_pdata->settling; | ||
306 | ts->fraction_z = ts_pdata->fraction_z; | ||
307 | ts->i_drive = ts_pdata->i_drive; | ||
308 | } | ||
309 | |||
310 | INIT_DELAYED_WORK(&ts->work, stmpe_work); | ||
311 | |||
312 | ret = request_threaded_irq(ts_irq, NULL, stmpe_ts_handler, | ||
313 | IRQF_ONESHOT, STMPE_TS_NAME, ts); | ||
314 | if (ret) { | ||
315 | dev_err(&pdev->dev, "Failed to request IRQ %d\n", ts_irq); | ||
316 | goto err_free_input; | ||
317 | } | ||
318 | |||
319 | ret = stmpe_init_hw(ts); | ||
320 | if (ret) | ||
321 | goto err_free_irq; | ||
322 | |||
323 | idev->name = STMPE_TS_NAME; | ||
324 | idev->id.bustype = BUS_I2C; | ||
325 | idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
326 | idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
327 | |||
328 | idev->open = stmpe_ts_open; | ||
329 | idev->close = stmpe_ts_close; | ||
330 | |||
331 | input_set_drvdata(idev, ts); | ||
332 | |||
333 | input_set_abs_params(idev, ABS_X, 0, XY_MASK, 0, 0); | ||
334 | input_set_abs_params(idev, ABS_Y, 0, XY_MASK, 0, 0); | ||
335 | input_set_abs_params(idev, ABS_PRESSURE, 0x0, 0xff, 0, 0); | ||
336 | |||
337 | ret = input_register_device(idev); | ||
338 | if (ret) { | ||
339 | dev_err(&pdev->dev, "Could not register input device\n"); | ||
340 | goto err_free_irq; | ||
341 | } | ||
342 | |||
343 | return ret; | ||
344 | |||
345 | err_free_irq: | ||
346 | free_irq(ts_irq, ts); | ||
347 | err_free_input: | ||
348 | input_free_device(idev); | ||
349 | platform_set_drvdata(pdev, NULL); | ||
350 | err_free_ts: | ||
351 | kfree(ts); | ||
352 | err_out: | ||
353 | return ret; | ||
354 | } | ||
355 | |||
356 | static int __devexit stmpe_ts_remove(struct platform_device *pdev) | ||
357 | { | ||
358 | struct stmpe_touch *ts = platform_get_drvdata(pdev); | ||
359 | unsigned int ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); | ||
360 | |||
361 | stmpe_disable(ts->stmpe, STMPE_BLOCK_TOUCHSCREEN); | ||
362 | |||
363 | free_irq(ts_irq, ts); | ||
364 | |||
365 | platform_set_drvdata(pdev, NULL); | ||
366 | |||
367 | input_unregister_device(ts->idev); | ||
368 | |||
369 | kfree(ts); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static struct platform_driver stmpe_ts_driver = { | ||
375 | .driver = { | ||
376 | .name = STMPE_TS_NAME, | ||
377 | .owner = THIS_MODULE, | ||
378 | }, | ||
379 | .probe = stmpe_input_probe, | ||
380 | .remove = __devexit_p(stmpe_ts_remove), | ||
381 | }; | ||
382 | |||
383 | static int __init stmpe_ts_init(void) | ||
384 | { | ||
385 | return platform_driver_register(&stmpe_ts_driver); | ||
386 | } | ||
387 | |||
388 | module_init(stmpe_ts_init); | ||
389 | |||
390 | static void __exit stmpe_ts_exit(void) | ||
391 | { | ||
392 | platform_driver_unregister(&stmpe_ts_driver); | ||
393 | } | ||
394 | |||
395 | module_exit(stmpe_ts_exit); | ||
396 | |||
397 | MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); | ||
398 | MODULE_DESCRIPTION("STMPEXXX touchscreen driver"); | ||
399 | MODULE_LICENSE("GPL"); | ||
400 | MODULE_ALIAS("platform:" STMPE_TS_NAME); | ||
diff --git a/drivers/input/touchscreen/tnetv107x-ts.c b/drivers/input/touchscreen/tnetv107x-ts.c new file mode 100644 index 000000000000..cf1dba2e267c --- /dev/null +++ b/drivers/input/touchscreen/tnetv107x-ts.c | |||
@@ -0,0 +1,396 @@ | |||
1 | /* | ||
2 | * Texas Instruments TNETV107X Touchscreen Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/ctype.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/clk.h> | ||
26 | |||
27 | #include <mach/tnetv107x.h> | ||
28 | |||
29 | #define TSC_PENUP_POLL (HZ / 5) | ||
30 | #define IDLE_TIMEOUT 100 /* msec */ | ||
31 | |||
32 | /* | ||
33 | * The first and last samples of a touch interval are usually garbage and need | ||
34 | * to be filtered out with these devices. The following definitions control | ||
35 | * the number of samples skipped. | ||
36 | */ | ||
37 | #define TSC_HEAD_SKIP 1 | ||
38 | #define TSC_TAIL_SKIP 1 | ||
39 | #define TSC_SKIP (TSC_HEAD_SKIP + TSC_TAIL_SKIP + 1) | ||
40 | #define TSC_SAMPLES (TSC_SKIP + 1) | ||
41 | |||
42 | /* Register Offsets */ | ||
43 | struct tsc_regs { | ||
44 | u32 rev; | ||
45 | u32 tscm; | ||
46 | u32 bwcm; | ||
47 | u32 swc; | ||
48 | u32 adcchnl; | ||
49 | u32 adcdata; | ||
50 | u32 chval[4]; | ||
51 | }; | ||
52 | |||
53 | /* TSC Mode Configuration Register (tscm) bits */ | ||
54 | #define WMODE BIT(0) | ||
55 | #define TSKIND BIT(1) | ||
56 | #define ZMEASURE_EN BIT(2) | ||
57 | #define IDLE BIT(3) | ||
58 | #define TSC_EN BIT(4) | ||
59 | #define STOP BIT(5) | ||
60 | #define ONE_SHOT BIT(6) | ||
61 | #define SINGLE BIT(7) | ||
62 | #define AVG BIT(8) | ||
63 | #define AVGNUM(x) (((x) & 0x03) << 9) | ||
64 | #define PVSTC(x) (((x) & 0x07) << 11) | ||
65 | #define PON BIT(14) | ||
66 | #define PONBG BIT(15) | ||
67 | #define AFERST BIT(16) | ||
68 | |||
69 | /* ADC DATA Capture Register bits */ | ||
70 | #define DATA_VALID BIT(16) | ||
71 | |||
72 | /* Register Access Macros */ | ||
73 | #define tsc_read(ts, reg) __raw_readl(&(ts)->regs->reg) | ||
74 | #define tsc_write(ts, reg, val) __raw_writel(val, &(ts)->regs->reg); | ||
75 | #define tsc_set_bits(ts, reg, val) \ | ||
76 | tsc_write(ts, reg, tsc_read(ts, reg) | (val)) | ||
77 | #define tsc_clr_bits(ts, reg, val) \ | ||
78 | tsc_write(ts, reg, tsc_read(ts, reg) & ~(val)) | ||
79 | |||
80 | struct sample { | ||
81 | int x, y, p; | ||
82 | }; | ||
83 | |||
84 | struct tsc_data { | ||
85 | struct input_dev *input_dev; | ||
86 | struct resource *res; | ||
87 | struct tsc_regs __iomem *regs; | ||
88 | struct timer_list timer; | ||
89 | spinlock_t lock; | ||
90 | struct clk *clk; | ||
91 | struct device *dev; | ||
92 | int sample_count; | ||
93 | struct sample samples[TSC_SAMPLES]; | ||
94 | int tsc_irq; | ||
95 | }; | ||
96 | |||
97 | static int tsc_read_sample(struct tsc_data *ts, struct sample* sample) | ||
98 | { | ||
99 | int x, y, z1, z2, t, p = 0; | ||
100 | u32 val; | ||
101 | |||
102 | val = tsc_read(ts, chval[0]); | ||
103 | if (val & DATA_VALID) | ||
104 | x = val & 0xffff; | ||
105 | else | ||
106 | return -EINVAL; | ||
107 | |||
108 | y = tsc_read(ts, chval[1]) & 0xffff; | ||
109 | z1 = tsc_read(ts, chval[2]) & 0xffff; | ||
110 | z2 = tsc_read(ts, chval[3]) & 0xffff; | ||
111 | |||
112 | if (z1) { | ||
113 | t = ((600 * x) * (z2 - z1)); | ||
114 | p = t / (u32) (z1 << 12); | ||
115 | if (p < 0) | ||
116 | p = 0; | ||
117 | } | ||
118 | |||
119 | sample->x = x; | ||
120 | sample->y = y; | ||
121 | sample->p = p; | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static void tsc_poll(unsigned long data) | ||
127 | { | ||
128 | struct tsc_data *ts = (struct tsc_data *)data; | ||
129 | unsigned long flags; | ||
130 | int i, val, x, y, p; | ||
131 | |||
132 | spin_lock_irqsave(&ts->lock, flags); | ||
133 | |||
134 | if (ts->sample_count >= TSC_SKIP) { | ||
135 | input_report_abs(ts->input_dev, ABS_PRESSURE, 0); | ||
136 | input_report_key(ts->input_dev, BTN_TOUCH, 0); | ||
137 | input_sync(ts->input_dev); | ||
138 | } else if (ts->sample_count > 0) { | ||
139 | /* | ||
140 | * A touch event lasted less than our skip count. Salvage and | ||
141 | * report anyway. | ||
142 | */ | ||
143 | for (i = 0, val = 0; i < ts->sample_count; i++) | ||
144 | val += ts->samples[i].x; | ||
145 | x = val / ts->sample_count; | ||
146 | |||
147 | for (i = 0, val = 0; i < ts->sample_count; i++) | ||
148 | val += ts->samples[i].y; | ||
149 | y = val / ts->sample_count; | ||
150 | |||
151 | for (i = 0, val = 0; i < ts->sample_count; i++) | ||
152 | val += ts->samples[i].p; | ||
153 | p = val / ts->sample_count; | ||
154 | |||
155 | input_report_abs(ts->input_dev, ABS_X, x); | ||
156 | input_report_abs(ts->input_dev, ABS_Y, y); | ||
157 | input_report_abs(ts->input_dev, ABS_PRESSURE, p); | ||
158 | input_report_key(ts->input_dev, BTN_TOUCH, 1); | ||
159 | input_sync(ts->input_dev); | ||
160 | } | ||
161 | |||
162 | ts->sample_count = 0; | ||
163 | |||
164 | spin_unlock_irqrestore(&ts->lock, flags); | ||
165 | } | ||
166 | |||
167 | static irqreturn_t tsc_irq(int irq, void *dev_id) | ||
168 | { | ||
169 | struct tsc_data *ts = (struct tsc_data *)dev_id; | ||
170 | struct sample *sample; | ||
171 | int index; | ||
172 | |||
173 | spin_lock(&ts->lock); | ||
174 | |||
175 | index = ts->sample_count % TSC_SAMPLES; | ||
176 | sample = &ts->samples[index]; | ||
177 | if (tsc_read_sample(ts, sample) < 0) | ||
178 | goto out; | ||
179 | |||
180 | if (++ts->sample_count >= TSC_SKIP) { | ||
181 | index = (ts->sample_count - TSC_TAIL_SKIP - 1) % TSC_SAMPLES; | ||
182 | sample = &ts->samples[index]; | ||
183 | |||
184 | input_report_abs(ts->input_dev, ABS_X, sample->x); | ||
185 | input_report_abs(ts->input_dev, ABS_Y, sample->y); | ||
186 | input_report_abs(ts->input_dev, ABS_PRESSURE, sample->p); | ||
187 | if (ts->sample_count == TSC_SKIP) | ||
188 | input_report_key(ts->input_dev, BTN_TOUCH, 1); | ||
189 | input_sync(ts->input_dev); | ||
190 | } | ||
191 | mod_timer(&ts->timer, jiffies + TSC_PENUP_POLL); | ||
192 | out: | ||
193 | spin_unlock(&ts->lock); | ||
194 | return IRQ_HANDLED; | ||
195 | } | ||
196 | |||
197 | static int tsc_start(struct input_dev *dev) | ||
198 | { | ||
199 | struct tsc_data *ts = input_get_drvdata(dev); | ||
200 | unsigned long timeout = jiffies + msecs_to_jiffies(IDLE_TIMEOUT); | ||
201 | u32 val; | ||
202 | |||
203 | clk_enable(ts->clk); | ||
204 | |||
205 | /* Go to idle mode, before any initialization */ | ||
206 | while (time_after(timeout, jiffies)) { | ||
207 | if (tsc_read(ts, tscm) & IDLE) | ||
208 | break; | ||
209 | } | ||
210 | |||
211 | if (time_before(timeout, jiffies)) { | ||
212 | dev_warn(ts->dev, "timeout waiting for idle\n"); | ||
213 | clk_disable(ts->clk); | ||
214 | return -EIO; | ||
215 | } | ||
216 | |||
217 | /* Configure TSC Control register*/ | ||
218 | val = (PONBG | PON | PVSTC(4) | ONE_SHOT | ZMEASURE_EN); | ||
219 | tsc_write(ts, tscm, val); | ||
220 | |||
221 | /* Bring TSC out of reset: Clear AFE reset bit */ | ||
222 | val &= ~(AFERST); | ||
223 | tsc_write(ts, tscm, val); | ||
224 | |||
225 | /* Configure all pins for hardware control*/ | ||
226 | tsc_write(ts, bwcm, 0); | ||
227 | |||
228 | /* Finally enable the TSC */ | ||
229 | tsc_set_bits(ts, tscm, TSC_EN); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static void tsc_stop(struct input_dev *dev) | ||
235 | { | ||
236 | struct tsc_data *ts = input_get_drvdata(dev); | ||
237 | |||
238 | tsc_clr_bits(ts, tscm, TSC_EN); | ||
239 | synchronize_irq(ts->tsc_irq); | ||
240 | del_timer_sync(&ts->timer); | ||
241 | clk_disable(ts->clk); | ||
242 | } | ||
243 | |||
244 | static int __devinit tsc_probe(struct platform_device *pdev) | ||
245 | { | ||
246 | struct device *dev = &pdev->dev; | ||
247 | struct tsc_data *ts; | ||
248 | int error = 0; | ||
249 | u32 rev = 0; | ||
250 | |||
251 | ts = kzalloc(sizeof(struct tsc_data), GFP_KERNEL); | ||
252 | if (!ts) { | ||
253 | dev_err(dev, "cannot allocate device info\n"); | ||
254 | return -ENOMEM; | ||
255 | } | ||
256 | |||
257 | ts->dev = dev; | ||
258 | spin_lock_init(&ts->lock); | ||
259 | setup_timer(&ts->timer, tsc_poll, (unsigned long)ts); | ||
260 | platform_set_drvdata(pdev, ts); | ||
261 | |||
262 | ts->tsc_irq = platform_get_irq(pdev, 0); | ||
263 | if (ts->tsc_irq < 0) { | ||
264 | dev_err(dev, "cannot determine device interrupt\n"); | ||
265 | error = -ENODEV; | ||
266 | goto error_res; | ||
267 | } | ||
268 | |||
269 | ts->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
270 | if (!ts->res) { | ||
271 | dev_err(dev, "cannot determine register area\n"); | ||
272 | error = -ENODEV; | ||
273 | goto error_res; | ||
274 | } | ||
275 | |||
276 | if (!request_mem_region(ts->res->start, resource_size(ts->res), | ||
277 | pdev->name)) { | ||
278 | dev_err(dev, "cannot claim register memory\n"); | ||
279 | ts->res = NULL; | ||
280 | error = -EINVAL; | ||
281 | goto error_res; | ||
282 | } | ||
283 | |||
284 | ts->regs = ioremap(ts->res->start, resource_size(ts->res)); | ||
285 | if (!ts->regs) { | ||
286 | dev_err(dev, "cannot map register memory\n"); | ||
287 | error = -ENOMEM; | ||
288 | goto error_map; | ||
289 | } | ||
290 | |||
291 | ts->clk = clk_get(dev, NULL); | ||
292 | if (!ts->clk) { | ||
293 | dev_err(dev, "cannot claim device clock\n"); | ||
294 | error = -EINVAL; | ||
295 | goto error_clk; | ||
296 | } | ||
297 | |||
298 | error = request_threaded_irq(ts->tsc_irq, NULL, tsc_irq, 0, | ||
299 | dev_name(dev), ts); | ||
300 | if (error < 0) { | ||
301 | dev_err(ts->dev, "Could not allocate ts irq\n"); | ||
302 | goto error_irq; | ||
303 | } | ||
304 | |||
305 | ts->input_dev = input_allocate_device(); | ||
306 | if (!ts->input_dev) { | ||
307 | dev_err(dev, "cannot allocate input device\n"); | ||
308 | error = -ENOMEM; | ||
309 | goto error_input; | ||
310 | } | ||
311 | input_set_drvdata(ts->input_dev, ts); | ||
312 | |||
313 | ts->input_dev->name = pdev->name; | ||
314 | ts->input_dev->id.bustype = BUS_HOST; | ||
315 | ts->input_dev->dev.parent = &pdev->dev; | ||
316 | ts->input_dev->open = tsc_start; | ||
317 | ts->input_dev->close = tsc_stop; | ||
318 | |||
319 | clk_enable(ts->clk); | ||
320 | rev = tsc_read(ts, rev); | ||
321 | ts->input_dev->id.product = ((rev >> 8) & 0x07); | ||
322 | ts->input_dev->id.version = ((rev >> 16) & 0xfff); | ||
323 | clk_disable(ts->clk); | ||
324 | |||
325 | __set_bit(EV_KEY, ts->input_dev->evbit); | ||
326 | __set_bit(EV_ABS, ts->input_dev->evbit); | ||
327 | __set_bit(BTN_TOUCH, ts->input_dev->keybit); | ||
328 | |||
329 | input_set_abs_params(ts->input_dev, ABS_X, 0, 0xffff, 5, 0); | ||
330 | input_set_abs_params(ts->input_dev, ABS_Y, 0, 0xffff, 5, 0); | ||
331 | input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 4095, 128, 0); | ||
332 | |||
333 | error = input_register_device(ts->input_dev); | ||
334 | if (error < 0) { | ||
335 | dev_err(dev, "failed input device registration\n"); | ||
336 | goto error_reg; | ||
337 | } | ||
338 | |||
339 | return 0; | ||
340 | |||
341 | error_reg: | ||
342 | input_free_device(ts->input_dev); | ||
343 | error_input: | ||
344 | free_irq(ts->tsc_irq, ts); | ||
345 | error_irq: | ||
346 | clk_put(ts->clk); | ||
347 | error_clk: | ||
348 | iounmap(ts->regs); | ||
349 | error_map: | ||
350 | release_mem_region(ts->res->start, resource_size(ts->res)); | ||
351 | error_res: | ||
352 | platform_set_drvdata(pdev, NULL); | ||
353 | kfree(ts); | ||
354 | |||
355 | return error; | ||
356 | } | ||
357 | |||
358 | static int __devexit tsc_remove(struct platform_device *pdev) | ||
359 | { | ||
360 | struct tsc_data *ts = platform_get_drvdata(pdev); | ||
361 | |||
362 | input_unregister_device(ts->input_dev); | ||
363 | free_irq(ts->tsc_irq, ts); | ||
364 | clk_put(ts->clk); | ||
365 | iounmap(ts->regs); | ||
366 | release_mem_region(ts->res->start, resource_size(ts->res)); | ||
367 | platform_set_drvdata(pdev, NULL); | ||
368 | kfree(ts); | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static struct platform_driver tsc_driver = { | ||
374 | .probe = tsc_probe, | ||
375 | .remove = __devexit_p(tsc_remove), | ||
376 | .driver.name = "tnetv107x-ts", | ||
377 | .driver.owner = THIS_MODULE, | ||
378 | }; | ||
379 | |||
380 | static int __init tsc_init(void) | ||
381 | { | ||
382 | return platform_driver_register(&tsc_driver); | ||
383 | } | ||
384 | |||
385 | static void __exit tsc_exit(void) | ||
386 | { | ||
387 | platform_driver_unregister(&tsc_driver); | ||
388 | } | ||
389 | |||
390 | module_init(tsc_init); | ||
391 | module_exit(tsc_exit); | ||
392 | |||
393 | MODULE_AUTHOR("Cyril Chemparathy"); | ||
394 | MODULE_DESCRIPTION("TNETV107X Touchscreen Driver"); | ||
395 | MODULE_ALIAS("platform: tnetv107x-ts"); | ||
396 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c new file mode 100644 index 000000000000..c8c136cf7bbc --- /dev/null +++ b/drivers/input/touchscreen/tps6507x-ts.c | |||
@@ -0,0 +1,394 @@ | |||
1 | /* | ||
2 | * drivers/input/touchscreen/tps6507x_ts.c | ||
3 | * | ||
4 | * Touchscreen driver for the tps6507x chip. | ||
5 | * | ||
6 | * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com) | ||
7 | * | ||
8 | * Credits: | ||
9 | * | ||
10 | * Using code from tsc2007, MtekVision Co., Ltd. | ||
11 | * | ||
12 | * For licencing details see kernel-base/COPYING | ||
13 | * | ||
14 | * TPS65070, TPS65073, TPS650731, and TPS650732 support | ||
15 | * 10 bit touch screen interface. | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/workqueue.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/mfd/tps6507x.h> | ||
24 | #include <linux/input/tps6507x-ts.h> | ||
25 | #include <linux/delay.h> | ||
26 | |||
27 | #define TSC_DEFAULT_POLL_PERIOD 30 /* ms */ | ||
28 | #define TPS_DEFAULT_MIN_PRESSURE 0x30 | ||
29 | #define MAX_10BIT ((1 << 10) - 1) | ||
30 | |||
31 | #define TPS6507X_ADCONFIG_CONVERT_TS (TPS6507X_ADCONFIG_AD_ENABLE | \ | ||
32 | TPS6507X_ADCONFIG_START_CONVERSION | \ | ||
33 | TPS6507X_ADCONFIG_INPUT_REAL_TSC) | ||
34 | #define TPS6507X_ADCONFIG_POWER_DOWN_TS (TPS6507X_ADCONFIG_INPUT_REAL_TSC) | ||
35 | |||
36 | struct ts_event { | ||
37 | u16 x; | ||
38 | u16 y; | ||
39 | u16 pressure; | ||
40 | }; | ||
41 | |||
42 | struct tps6507x_ts { | ||
43 | struct input_dev *input_dev; | ||
44 | struct device *dev; | ||
45 | char phys[32]; | ||
46 | struct workqueue_struct *wq; | ||
47 | struct delayed_work work; | ||
48 | unsigned polling; /* polling is active */ | ||
49 | struct ts_event tc; | ||
50 | struct tps6507x_dev *mfd; | ||
51 | u16 model; | ||
52 | unsigned pendown; | ||
53 | int irq; | ||
54 | void (*clear_penirq)(void); | ||
55 | unsigned long poll_period; /* ms */ | ||
56 | u16 min_pressure; | ||
57 | int vref; /* non-zero to leave vref on */ | ||
58 | }; | ||
59 | |||
60 | static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data) | ||
61 | { | ||
62 | int err; | ||
63 | |||
64 | err = tsc->mfd->read_dev(tsc->mfd, reg, 1, data); | ||
65 | |||
66 | if (err) | ||
67 | return err; | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int tps6507x_write_u8(struct tps6507x_ts *tsc, u8 reg, u8 data) | ||
73 | { | ||
74 | return tsc->mfd->write_dev(tsc->mfd, reg, 1, &data); | ||
75 | } | ||
76 | |||
77 | static s32 tps6507x_adc_conversion(struct tps6507x_ts *tsc, | ||
78 | u8 tsc_mode, u16 *value) | ||
79 | { | ||
80 | s32 ret; | ||
81 | u8 adc_status; | ||
82 | u8 result; | ||
83 | |||
84 | /* Route input signal to A/D converter */ | ||
85 | |||
86 | ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, tsc_mode); | ||
87 | if (ret) { | ||
88 | dev_err(tsc->dev, "TSC mode read failed\n"); | ||
89 | goto err; | ||
90 | } | ||
91 | |||
92 | /* Start A/D conversion */ | ||
93 | |||
94 | ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, | ||
95 | TPS6507X_ADCONFIG_CONVERT_TS); | ||
96 | if (ret) { | ||
97 | dev_err(tsc->dev, "ADC config write failed\n"); | ||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | do { | ||
102 | ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADCONFIG, | ||
103 | &adc_status); | ||
104 | if (ret) { | ||
105 | dev_err(tsc->dev, "ADC config read failed\n"); | ||
106 | goto err; | ||
107 | } | ||
108 | } while (adc_status & TPS6507X_ADCONFIG_START_CONVERSION); | ||
109 | |||
110 | ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_2, &result); | ||
111 | if (ret) { | ||
112 | dev_err(tsc->dev, "ADC result 2 read failed\n"); | ||
113 | goto err; | ||
114 | } | ||
115 | |||
116 | *value = (result & TPS6507X_REG_ADRESULT_2_MASK) << 8; | ||
117 | |||
118 | ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_1, &result); | ||
119 | if (ret) { | ||
120 | dev_err(tsc->dev, "ADC result 1 read failed\n"); | ||
121 | goto err; | ||
122 | } | ||
123 | |||
124 | *value |= result; | ||
125 | |||
126 | dev_dbg(tsc->dev, "TSC channel %d = 0x%X\n", tsc_mode, *value); | ||
127 | |||
128 | err: | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | /* Need to call tps6507x_adc_standby() after using A/D converter for the | ||
133 | * touch screen interrupt to work properly. | ||
134 | */ | ||
135 | |||
136 | static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc) | ||
137 | { | ||
138 | s32 ret; | ||
139 | s32 loops = 0; | ||
140 | u8 val; | ||
141 | |||
142 | ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, | ||
143 | TPS6507X_ADCONFIG_INPUT_TSC); | ||
144 | if (ret) | ||
145 | return ret; | ||
146 | |||
147 | ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, | ||
148 | TPS6507X_TSCMODE_STANDBY); | ||
149 | if (ret) | ||
150 | return ret; | ||
151 | |||
152 | ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | |||
156 | while (val & TPS6507X_REG_TSC_INT) { | ||
157 | mdelay(10); | ||
158 | ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); | ||
159 | if (ret) | ||
160 | return ret; | ||
161 | loops++; | ||
162 | } | ||
163 | |||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | static void tps6507x_ts_handler(struct work_struct *work) | ||
168 | { | ||
169 | struct tps6507x_ts *tsc = container_of(work, | ||
170 | struct tps6507x_ts, work.work); | ||
171 | struct input_dev *input_dev = tsc->input_dev; | ||
172 | int pendown; | ||
173 | int schd; | ||
174 | int poll = 0; | ||
175 | s32 ret; | ||
176 | |||
177 | ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, | ||
178 | &tsc->tc.pressure); | ||
179 | if (ret) | ||
180 | goto done; | ||
181 | |||
182 | pendown = tsc->tc.pressure > tsc->min_pressure; | ||
183 | |||
184 | if (unlikely(!pendown && tsc->pendown)) { | ||
185 | dev_dbg(tsc->dev, "UP\n"); | ||
186 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
187 | input_report_abs(input_dev, ABS_PRESSURE, 0); | ||
188 | input_sync(input_dev); | ||
189 | tsc->pendown = 0; | ||
190 | } | ||
191 | |||
192 | if (pendown) { | ||
193 | |||
194 | if (!tsc->pendown) { | ||
195 | dev_dbg(tsc->dev, "DOWN\n"); | ||
196 | input_report_key(input_dev, BTN_TOUCH, 1); | ||
197 | } else | ||
198 | dev_dbg(tsc->dev, "still down\n"); | ||
199 | |||
200 | ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_X_POSITION, | ||
201 | &tsc->tc.x); | ||
202 | if (ret) | ||
203 | goto done; | ||
204 | |||
205 | ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_Y_POSITION, | ||
206 | &tsc->tc.y); | ||
207 | if (ret) | ||
208 | goto done; | ||
209 | |||
210 | input_report_abs(input_dev, ABS_X, tsc->tc.x); | ||
211 | input_report_abs(input_dev, ABS_Y, tsc->tc.y); | ||
212 | input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure); | ||
213 | input_sync(input_dev); | ||
214 | tsc->pendown = 1; | ||
215 | poll = 1; | ||
216 | } | ||
217 | |||
218 | done: | ||
219 | /* always poll if not using interrupts */ | ||
220 | poll = 1; | ||
221 | |||
222 | if (poll) { | ||
223 | schd = queue_delayed_work(tsc->wq, &tsc->work, | ||
224 | msecs_to_jiffies(tsc->poll_period)); | ||
225 | if (schd) | ||
226 | tsc->polling = 1; | ||
227 | else { | ||
228 | tsc->polling = 0; | ||
229 | dev_err(tsc->dev, "re-schedule failed"); | ||
230 | } | ||
231 | } else | ||
232 | tsc->polling = 0; | ||
233 | |||
234 | ret = tps6507x_adc_standby(tsc); | ||
235 | } | ||
236 | |||
237 | static int tps6507x_ts_probe(struct platform_device *pdev) | ||
238 | { | ||
239 | int error; | ||
240 | struct tps6507x_ts *tsc; | ||
241 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); | ||
242 | struct touchscreen_init_data *init_data; | ||
243 | struct input_dev *input_dev; | ||
244 | struct tps6507x_board *tps_board; | ||
245 | int schd; | ||
246 | |||
247 | /** | ||
248 | * tps_board points to pmic related constants | ||
249 | * coming from the board-evm file. | ||
250 | */ | ||
251 | |||
252 | tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data; | ||
253 | |||
254 | if (!tps_board) { | ||
255 | dev_err(tps6507x_dev->dev, | ||
256 | "Could not find tps6507x platform data\n"); | ||
257 | return -EIO; | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * init_data points to array of regulator_init structures | ||
262 | * coming from the board-evm file. | ||
263 | */ | ||
264 | |||
265 | init_data = tps_board->tps6507x_ts_init_data; | ||
266 | |||
267 | tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL); | ||
268 | if (!tsc) { | ||
269 | dev_err(tps6507x_dev->dev, "failed to allocate driver data\n"); | ||
270 | error = -ENOMEM; | ||
271 | goto err0; | ||
272 | } | ||
273 | |||
274 | tps6507x_dev->ts = tsc; | ||
275 | tsc->mfd = tps6507x_dev; | ||
276 | tsc->dev = tps6507x_dev->dev; | ||
277 | input_dev = input_allocate_device(); | ||
278 | if (!input_dev) { | ||
279 | dev_err(tsc->dev, "Failed to allocate input device.\n"); | ||
280 | error = -ENOMEM; | ||
281 | goto err1; | ||
282 | } | ||
283 | |||
284 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
285 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
286 | |||
287 | input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0); | ||
288 | input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0); | ||
289 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); | ||
290 | |||
291 | input_dev->name = "TPS6507x Touchscreen"; | ||
292 | input_dev->id.bustype = BUS_I2C; | ||
293 | input_dev->dev.parent = tsc->dev; | ||
294 | |||
295 | snprintf(tsc->phys, sizeof(tsc->phys), | ||
296 | "%s/input0", dev_name(tsc->dev)); | ||
297 | input_dev->phys = tsc->phys; | ||
298 | |||
299 | dev_dbg(tsc->dev, "device: %s\n", input_dev->phys); | ||
300 | |||
301 | input_set_drvdata(input_dev, tsc); | ||
302 | |||
303 | tsc->input_dev = input_dev; | ||
304 | |||
305 | INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); | ||
306 | tsc->wq = create_workqueue("TPS6507x Touchscreen"); | ||
307 | |||
308 | if (init_data) { | ||
309 | tsc->poll_period = init_data->poll_period; | ||
310 | tsc->vref = init_data->vref; | ||
311 | tsc->min_pressure = init_data->min_pressure; | ||
312 | input_dev->id.vendor = init_data->vendor; | ||
313 | input_dev->id.product = init_data->product; | ||
314 | input_dev->id.version = init_data->version; | ||
315 | } else { | ||
316 | tsc->poll_period = TSC_DEFAULT_POLL_PERIOD; | ||
317 | tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE; | ||
318 | } | ||
319 | |||
320 | error = tps6507x_adc_standby(tsc); | ||
321 | if (error) | ||
322 | goto err2; | ||
323 | |||
324 | error = input_register_device(input_dev); | ||
325 | if (error) | ||
326 | goto err2; | ||
327 | |||
328 | schd = queue_delayed_work(tsc->wq, &tsc->work, | ||
329 | msecs_to_jiffies(tsc->poll_period)); | ||
330 | |||
331 | if (schd) | ||
332 | tsc->polling = 1; | ||
333 | else { | ||
334 | tsc->polling = 0; | ||
335 | dev_err(tsc->dev, "schedule failed"); | ||
336 | goto err2; | ||
337 | } | ||
338 | platform_set_drvdata(pdev, tps6507x_dev); | ||
339 | |||
340 | return 0; | ||
341 | |||
342 | err2: | ||
343 | cancel_delayed_work_sync(&tsc->work); | ||
344 | destroy_workqueue(tsc->wq); | ||
345 | input_free_device(input_dev); | ||
346 | err1: | ||
347 | kfree(tsc); | ||
348 | tps6507x_dev->ts = NULL; | ||
349 | err0: | ||
350 | return error; | ||
351 | } | ||
352 | |||
353 | static int __devexit tps6507x_ts_remove(struct platform_device *pdev) | ||
354 | { | ||
355 | struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); | ||
356 | struct tps6507x_ts *tsc = tps6507x_dev->ts; | ||
357 | struct input_dev *input_dev = tsc->input_dev; | ||
358 | |||
359 | cancel_delayed_work_sync(&tsc->work); | ||
360 | destroy_workqueue(tsc->wq); | ||
361 | |||
362 | input_unregister_device(input_dev); | ||
363 | |||
364 | tps6507x_dev->ts = NULL; | ||
365 | kfree(tsc); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static struct platform_driver tps6507x_ts_driver = { | ||
371 | .driver = { | ||
372 | .name = "tps6507x-ts", | ||
373 | .owner = THIS_MODULE, | ||
374 | }, | ||
375 | .probe = tps6507x_ts_probe, | ||
376 | .remove = __devexit_p(tps6507x_ts_remove), | ||
377 | }; | ||
378 | |||
379 | static int __init tps6507x_ts_init(void) | ||
380 | { | ||
381 | return platform_driver_register(&tps6507x_ts_driver); | ||
382 | } | ||
383 | module_init(tps6507x_ts_init); | ||
384 | |||
385 | static void __exit tps6507x_ts_exit(void) | ||
386 | { | ||
387 | platform_driver_unregister(&tps6507x_ts_driver); | ||
388 | } | ||
389 | module_exit(tps6507x_ts_exit); | ||
390 | |||
391 | MODULE_AUTHOR("Todd Fischer <todd.fischer@ridgerun.com>"); | ||
392 | MODULE_DESCRIPTION("TPS6507x - TouchScreen driver"); | ||
393 | MODULE_LICENSE("GPL v2"); | ||
394 | MODULE_ALIAS("platform:tps6507x-tsc"); | ||
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 7ef0d1420d3c..80467f262331 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c | |||
@@ -265,7 +265,7 @@ static int __devinit tsc2007_probe(struct i2c_client *client, | |||
265 | const struct i2c_device_id *id) | 265 | const struct i2c_device_id *id) |
266 | { | 266 | { |
267 | struct tsc2007 *ts; | 267 | struct tsc2007 *ts; |
268 | struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data; | 268 | struct tsc2007_platform_data *pdata = client->dev.platform_data; |
269 | struct input_dev *input_dev; | 269 | struct input_dev *input_dev; |
270 | int err; | 270 | int err; |
271 | 271 | ||
@@ -358,7 +358,7 @@ static int __devexit tsc2007_remove(struct i2c_client *client) | |||
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
360 | 360 | ||
361 | static struct i2c_device_id tsc2007_idtable[] = { | 361 | static const struct i2c_device_id tsc2007_idtable[] = { |
362 | { "tsc2007", 0 }, | 362 | { "tsc2007", 0 }, |
363 | { } | 363 | { } |
364 | }; | 364 | }; |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 89dcbe7b4b02..028a5363eea1 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/suspend.h> | 28 | #include <linux/suspend.h> |
29 | #include <linux/slab.h> | ||
30 | #include <linux/kthread.h> | 29 | #include <linux/kthread.h> |
31 | #include <linux/freezer.h> | 30 | #include <linux/freezer.h> |
32 | #include <linux/ucb1400.h> | 31 | #include <linux/ucb1400.h> |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 09a5e7341bd5..f45f80f6d336 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * - GoTop Super_Q2/GogoPen/PenPower tablets | 15 | * - GoTop Super_Q2/GogoPen/PenPower tablets |
16 | * - JASTEC USB touch controller/DigiTech DTR-02U | 16 | * - JASTEC USB touch controller/DigiTech DTR-02U |
17 | * - Zytronic capacitive touchscreen | 17 | * - Zytronic capacitive touchscreen |
18 | * - NEXIO/iNexio | ||
18 | * | 19 | * |
19 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> | 20 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> |
20 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | 21 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) |
@@ -94,7 +95,9 @@ struct usbtouch_device_info { | |||
94 | int (*get_pkt_len) (unsigned char *pkt, int len); | 95 | int (*get_pkt_len) (unsigned char *pkt, int len); |
95 | 96 | ||
96 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); | 97 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); |
98 | int (*alloc) (struct usbtouch_usb *usbtouch); | ||
97 | int (*init) (struct usbtouch_usb *usbtouch); | 99 | int (*init) (struct usbtouch_usb *usbtouch); |
100 | void (*exit) (struct usbtouch_usb *usbtouch); | ||
98 | }; | 101 | }; |
99 | 102 | ||
100 | /* a usbtouch device */ | 103 | /* a usbtouch device */ |
@@ -104,11 +107,12 @@ struct usbtouch_usb { | |||
104 | unsigned char *buffer; | 107 | unsigned char *buffer; |
105 | int buf_len; | 108 | int buf_len; |
106 | struct urb *irq; | 109 | struct urb *irq; |
107 | struct usb_device *udev; | 110 | struct usb_interface *interface; |
108 | struct input_dev *input; | 111 | struct input_dev *input; |
109 | struct usbtouch_device_info *type; | 112 | struct usbtouch_device_info *type; |
110 | char name[128]; | 113 | char name[128]; |
111 | char phys[64]; | 114 | char phys[64]; |
115 | void *priv; | ||
112 | 116 | ||
113 | int x, y; | 117 | int x, y; |
114 | int touch, press; | 118 | int touch, press; |
@@ -132,7 +136,8 @@ enum { | |||
132 | DEVTYPE_JASTEC, | 136 | DEVTYPE_JASTEC, |
133 | DEVTYPE_E2I, | 137 | DEVTYPE_E2I, |
134 | DEVTYPE_ZYTRONIC, | 138 | DEVTYPE_ZYTRONIC, |
135 | DEVTYPE_TC5UH, | 139 | DEVTYPE_TC45USB, |
140 | DEVTYPE_NEXIO, | ||
136 | }; | 141 | }; |
137 | 142 | ||
138 | #define USB_DEVICE_HID_CLASS(vend, prod) \ | 143 | #define USB_DEVICE_HID_CLASS(vend, prod) \ |
@@ -144,7 +149,7 @@ enum { | |||
144 | .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ | 149 | .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ |
145 | .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE | 150 | .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE |
146 | 151 | ||
147 | static struct usb_device_id usbtouch_devices[] = { | 152 | static const struct usb_device_id usbtouch_devices[] = { |
148 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX | 153 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX |
149 | /* ignore the HID capable devices, handled by usbhid */ | 154 | /* ignore the HID capable devices, handled by usbhid */ |
150 | {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE}, | 155 | {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE}, |
@@ -218,8 +223,19 @@ static struct usb_device_id usbtouch_devices[] = { | |||
218 | {USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC}, | 223 | {USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC}, |
219 | #endif | 224 | #endif |
220 | 225 | ||
221 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH | 226 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB |
222 | {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, | 227 | /* TC5UH */ |
228 | {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC45USB}, | ||
229 | /* TC4UM */ | ||
230 | {USB_DEVICE(0x0664, 0x0306), .driver_info = DEVTYPE_TC45USB}, | ||
231 | #endif | ||
232 | |||
233 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
234 | /* data interface only */ | ||
235 | {USB_DEVICE_AND_INTERFACE_INFO(0x10f0, 0x2002, 0x0a, 0x00, 0x00), | ||
236 | .driver_info = DEVTYPE_NEXIO}, | ||
237 | {USB_DEVICE_AND_INTERFACE_INFO(0x1870, 0x0001, 0x0a, 0x00, 0x00), | ||
238 | .driver_info = DEVTYPE_NEXIO}, | ||
223 | #endif | 239 | #endif |
224 | 240 | ||
225 | {} | 241 | {} |
@@ -234,8 +250,9 @@ static struct usb_device_id usbtouch_devices[] = { | |||
234 | static int e2i_init(struct usbtouch_usb *usbtouch) | 250 | static int e2i_init(struct usbtouch_usb *usbtouch) |
235 | { | 251 | { |
236 | int ret; | 252 | int ret; |
253 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | ||
237 | 254 | ||
238 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | 255 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
239 | 0x01, 0x02, 0x0000, 0x0081, | 256 | 0x01, 0x02, 0x0000, 0x0081, |
240 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 257 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
241 | 258 | ||
@@ -344,8 +361,9 @@ static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
344 | static int mtouch_init(struct usbtouch_usb *usbtouch) | 361 | static int mtouch_init(struct usbtouch_usb *usbtouch) |
345 | { | 362 | { |
346 | int ret, i; | 363 | int ret, i; |
364 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | ||
347 | 365 | ||
348 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | 366 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
349 | MTOUCHUSB_RESET, | 367 | MTOUCHUSB_RESET, |
350 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 368 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
351 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); | 369 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); |
@@ -356,7 +374,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) | |||
356 | msleep(150); | 374 | msleep(150); |
357 | 375 | ||
358 | for (i = 0; i < 3; i++) { | 376 | for (i = 0; i < 3; i++) { |
359 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | 377 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
360 | MTOUCHUSB_ASYNC_REPORT, | 378 | MTOUCHUSB_ASYNC_REPORT, |
361 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 379 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
362 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); | 380 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); |
@@ -489,11 +507,11 @@ static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
489 | 507 | ||
490 | static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) | 508 | static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) |
491 | { | 509 | { |
492 | struct usb_device *dev = usbtouch->udev; | 510 | struct usb_device *dev = interface_to_usbdev(usbtouch->interface); |
493 | int ret = -ENOMEM; | 511 | int ret = -ENOMEM; |
494 | unsigned char *buf; | 512 | unsigned char *buf; |
495 | 513 | ||
496 | buf = kmalloc(2, GFP_KERNEL); | 514 | buf = kmalloc(2, GFP_NOIO); |
497 | if (!buf) | 515 | if (!buf) |
498 | goto err_nobuf; | 516 | goto err_nobuf; |
499 | /* reset */ | 517 | /* reset */ |
@@ -560,10 +578,10 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
560 | #endif | 578 | #endif |
561 | 579 | ||
562 | /***************************************************************************** | 580 | /***************************************************************************** |
563 | * ET&T TC5UH part | 581 | * ET&T TC5UH/TC4UM part |
564 | */ | 582 | */ |
565 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH | 583 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB |
566 | static int tc5uh_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | 584 | static int tc45usb_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
567 | { | 585 | { |
568 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; | 586 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; |
569 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; | 587 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; |
@@ -618,8 +636,8 @@ static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
618 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH | 636 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH |
619 | static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | 637 | static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
620 | { | 638 | { |
621 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1] ; | 639 | dev->x = (pkt[2] << 8) | pkt[1]; |
622 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3] ; | 640 | dev->y = (pkt[4] << 8) | pkt[3]; |
623 | dev->press = pkt[5] & 0xff; | 641 | dev->press = pkt[5] & 0xff; |
624 | dev->touch = pkt[0] & 0x01; | 642 | dev->touch = pkt[0] & 0x01; |
625 | 643 | ||
@@ -690,6 +708,242 @@ static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
690 | #endif | 708 | #endif |
691 | 709 | ||
692 | /***************************************************************************** | 710 | /***************************************************************************** |
711 | * NEXIO Part | ||
712 | */ | ||
713 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
714 | |||
715 | #define NEXIO_TIMEOUT 5000 | ||
716 | #define NEXIO_BUFSIZE 1024 | ||
717 | #define NEXIO_THRESHOLD 50 | ||
718 | |||
719 | struct nexio_priv { | ||
720 | struct urb *ack; | ||
721 | unsigned char *ack_buf; | ||
722 | }; | ||
723 | |||
724 | struct nexio_touch_packet { | ||
725 | u8 flags; /* 0xe1 = touch, 0xe1 = release */ | ||
726 | __be16 data_len; /* total bytes of touch data */ | ||
727 | __be16 x_len; /* bytes for X axis */ | ||
728 | __be16 y_len; /* bytes for Y axis */ | ||
729 | u8 data[]; | ||
730 | } __attribute__ ((packed)); | ||
731 | |||
732 | static unsigned char nexio_ack_pkt[2] = { 0xaa, 0x02 }; | ||
733 | static unsigned char nexio_init_pkt[4] = { 0x82, 0x04, 0x0a, 0x0f }; | ||
734 | |||
735 | static void nexio_ack_complete(struct urb *urb) | ||
736 | { | ||
737 | } | ||
738 | |||
739 | static int nexio_alloc(struct usbtouch_usb *usbtouch) | ||
740 | { | ||
741 | struct nexio_priv *priv; | ||
742 | int ret = -ENOMEM; | ||
743 | |||
744 | usbtouch->priv = kmalloc(sizeof(struct nexio_priv), GFP_KERNEL); | ||
745 | if (!usbtouch->priv) | ||
746 | goto out_buf; | ||
747 | |||
748 | priv = usbtouch->priv; | ||
749 | |||
750 | priv->ack_buf = kmemdup(nexio_ack_pkt, sizeof(nexio_ack_pkt), | ||
751 | GFP_KERNEL); | ||
752 | if (!priv->ack_buf) | ||
753 | goto err_priv; | ||
754 | |||
755 | priv->ack = usb_alloc_urb(0, GFP_KERNEL); | ||
756 | if (!priv->ack) { | ||
757 | dbg("%s - usb_alloc_urb failed: usbtouch->ack", __func__); | ||
758 | goto err_ack_buf; | ||
759 | } | ||
760 | |||
761 | return 0; | ||
762 | |||
763 | err_ack_buf: | ||
764 | kfree(priv->ack_buf); | ||
765 | err_priv: | ||
766 | kfree(priv); | ||
767 | out_buf: | ||
768 | return ret; | ||
769 | } | ||
770 | |||
771 | static int nexio_init(struct usbtouch_usb *usbtouch) | ||
772 | { | ||
773 | struct usb_device *dev = interface_to_usbdev(usbtouch->interface); | ||
774 | struct usb_host_interface *interface = usbtouch->interface->cur_altsetting; | ||
775 | struct nexio_priv *priv = usbtouch->priv; | ||
776 | int ret = -ENOMEM; | ||
777 | int actual_len, i; | ||
778 | unsigned char *buf; | ||
779 | char *firmware_ver = NULL, *device_name = NULL; | ||
780 | int input_ep = 0, output_ep = 0; | ||
781 | |||
782 | /* find first input and output endpoint */ | ||
783 | for (i = 0; i < interface->desc.bNumEndpoints; i++) { | ||
784 | if (!input_ep && | ||
785 | usb_endpoint_dir_in(&interface->endpoint[i].desc)) | ||
786 | input_ep = interface->endpoint[i].desc.bEndpointAddress; | ||
787 | if (!output_ep && | ||
788 | usb_endpoint_dir_out(&interface->endpoint[i].desc)) | ||
789 | output_ep = interface->endpoint[i].desc.bEndpointAddress; | ||
790 | } | ||
791 | if (!input_ep || !output_ep) | ||
792 | return -ENXIO; | ||
793 | |||
794 | buf = kmalloc(NEXIO_BUFSIZE, GFP_NOIO); | ||
795 | if (!buf) | ||
796 | goto out_buf; | ||
797 | |||
798 | /* two empty reads */ | ||
799 | for (i = 0; i < 2; i++) { | ||
800 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), | ||
801 | buf, NEXIO_BUFSIZE, &actual_len, | ||
802 | NEXIO_TIMEOUT); | ||
803 | if (ret < 0) | ||
804 | goto out_buf; | ||
805 | } | ||
806 | |||
807 | /* send init command */ | ||
808 | memcpy(buf, nexio_init_pkt, sizeof(nexio_init_pkt)); | ||
809 | ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, output_ep), | ||
810 | buf, sizeof(nexio_init_pkt), &actual_len, | ||
811 | NEXIO_TIMEOUT); | ||
812 | if (ret < 0) | ||
813 | goto out_buf; | ||
814 | |||
815 | /* read replies */ | ||
816 | for (i = 0; i < 3; i++) { | ||
817 | memset(buf, 0, NEXIO_BUFSIZE); | ||
818 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), | ||
819 | buf, NEXIO_BUFSIZE, &actual_len, | ||
820 | NEXIO_TIMEOUT); | ||
821 | if (ret < 0 || actual_len < 1 || buf[1] != actual_len) | ||
822 | continue; | ||
823 | switch (buf[0]) { | ||
824 | case 0x83: /* firmware version */ | ||
825 | if (!firmware_ver) | ||
826 | firmware_ver = kstrdup(&buf[2], GFP_NOIO); | ||
827 | break; | ||
828 | case 0x84: /* device name */ | ||
829 | if (!device_name) | ||
830 | device_name = kstrdup(&buf[2], GFP_NOIO); | ||
831 | break; | ||
832 | } | ||
833 | } | ||
834 | |||
835 | printk(KERN_INFO "Nexio device: %s, firmware version: %s\n", | ||
836 | device_name, firmware_ver); | ||
837 | |||
838 | kfree(firmware_ver); | ||
839 | kfree(device_name); | ||
840 | |||
841 | usb_fill_bulk_urb(priv->ack, dev, usb_sndbulkpipe(dev, output_ep), | ||
842 | priv->ack_buf, sizeof(nexio_ack_pkt), | ||
843 | nexio_ack_complete, usbtouch); | ||
844 | ret = 0; | ||
845 | |||
846 | out_buf: | ||
847 | kfree(buf); | ||
848 | return ret; | ||
849 | } | ||
850 | |||
851 | static void nexio_exit(struct usbtouch_usb *usbtouch) | ||
852 | { | ||
853 | struct nexio_priv *priv = usbtouch->priv; | ||
854 | |||
855 | usb_kill_urb(priv->ack); | ||
856 | usb_free_urb(priv->ack); | ||
857 | kfree(priv->ack_buf); | ||
858 | kfree(priv); | ||
859 | } | ||
860 | |||
861 | static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt) | ||
862 | { | ||
863 | struct nexio_touch_packet *packet = (void *) pkt; | ||
864 | struct nexio_priv *priv = usbtouch->priv; | ||
865 | unsigned int data_len = be16_to_cpu(packet->data_len); | ||
866 | unsigned int x_len = be16_to_cpu(packet->x_len); | ||
867 | unsigned int y_len = be16_to_cpu(packet->y_len); | ||
868 | int x, y, begin_x, begin_y, end_x, end_y, w, h, ret; | ||
869 | |||
870 | /* got touch data? */ | ||
871 | if ((pkt[0] & 0xe0) != 0xe0) | ||
872 | return 0; | ||
873 | |||
874 | if (data_len > 0xff) | ||
875 | data_len -= 0x100; | ||
876 | if (x_len > 0xff) | ||
877 | x_len -= 0x80; | ||
878 | |||
879 | /* send ACK */ | ||
880 | ret = usb_submit_urb(priv->ack, GFP_ATOMIC); | ||
881 | |||
882 | if (!usbtouch->type->max_xc) { | ||
883 | usbtouch->type->max_xc = 2 * x_len; | ||
884 | input_set_abs_params(usbtouch->input, ABS_X, | ||
885 | 0, usbtouch->type->max_xc, 0, 0); | ||
886 | usbtouch->type->max_yc = 2 * y_len; | ||
887 | input_set_abs_params(usbtouch->input, ABS_Y, | ||
888 | 0, usbtouch->type->max_yc, 0, 0); | ||
889 | } | ||
890 | /* | ||
891 | * The device reports state of IR sensors on X and Y axes. | ||
892 | * Each byte represents "darkness" percentage (0-100) of one element. | ||
893 | * 17" touchscreen reports only 64 x 52 bytes so the resolution is low. | ||
894 | * This also means that there's a limited multi-touch capability but | ||
895 | * it's disabled (and untested) here as there's no X driver for that. | ||
896 | */ | ||
897 | begin_x = end_x = begin_y = end_y = -1; | ||
898 | for (x = 0; x < x_len; x++) { | ||
899 | if (begin_x == -1 && packet->data[x] > NEXIO_THRESHOLD) { | ||
900 | begin_x = x; | ||
901 | continue; | ||
902 | } | ||
903 | if (end_x == -1 && begin_x != -1 && packet->data[x] < NEXIO_THRESHOLD) { | ||
904 | end_x = x - 1; | ||
905 | for (y = x_len; y < data_len; y++) { | ||
906 | if (begin_y == -1 && packet->data[y] > NEXIO_THRESHOLD) { | ||
907 | begin_y = y - x_len; | ||
908 | continue; | ||
909 | } | ||
910 | if (end_y == -1 && | ||
911 | begin_y != -1 && packet->data[y] < NEXIO_THRESHOLD) { | ||
912 | end_y = y - 1 - x_len; | ||
913 | w = end_x - begin_x; | ||
914 | h = end_y - begin_y; | ||
915 | #if 0 | ||
916 | /* multi-touch */ | ||
917 | input_report_abs(usbtouch->input, | ||
918 | ABS_MT_TOUCH_MAJOR, max(w,h)); | ||
919 | input_report_abs(usbtouch->input, | ||
920 | ABS_MT_TOUCH_MINOR, min(x,h)); | ||
921 | input_report_abs(usbtouch->input, | ||
922 | ABS_MT_POSITION_X, 2*begin_x+w); | ||
923 | input_report_abs(usbtouch->input, | ||
924 | ABS_MT_POSITION_Y, 2*begin_y+h); | ||
925 | input_report_abs(usbtouch->input, | ||
926 | ABS_MT_ORIENTATION, w > h); | ||
927 | input_mt_sync(usbtouch->input); | ||
928 | #endif | ||
929 | /* single touch */ | ||
930 | usbtouch->x = 2 * begin_x + w; | ||
931 | usbtouch->y = 2 * begin_y + h; | ||
932 | usbtouch->touch = packet->flags & 0x01; | ||
933 | begin_y = end_y = -1; | ||
934 | return 1; | ||
935 | } | ||
936 | } | ||
937 | begin_x = end_x = -1; | ||
938 | } | ||
939 | |||
940 | } | ||
941 | return 0; | ||
942 | } | ||
943 | #endif | ||
944 | |||
945 | |||
946 | /***************************************************************************** | ||
693 | * the different device descriptors | 947 | * the different device descriptors |
694 | */ | 948 | */ |
695 | #ifdef MULTI_PACKET | 949 | #ifdef MULTI_PACKET |
@@ -809,9 +1063,9 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
809 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH | 1063 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH |
810 | [DEVTYPE_GENERAL_TOUCH] = { | 1064 | [DEVTYPE_GENERAL_TOUCH] = { |
811 | .min_xc = 0x0, | 1065 | .min_xc = 0x0, |
812 | .max_xc = 0x0500, | 1066 | .max_xc = 0x7fff, |
813 | .min_yc = 0x0, | 1067 | .min_yc = 0x0, |
814 | .max_yc = 0x0500, | 1068 | .max_yc = 0x7fff, |
815 | .rept_size = 7, | 1069 | .rept_size = 7, |
816 | .read_data = general_touch_read_data, | 1070 | .read_data = general_touch_read_data, |
817 | }, | 1071 | }, |
@@ -863,14 +1117,25 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
863 | }, | 1117 | }, |
864 | #endif | 1118 | #endif |
865 | 1119 | ||
866 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH | 1120 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB |
867 | [DEVTYPE_TC5UH] = { | 1121 | [DEVTYPE_TC45USB] = { |
868 | .min_xc = 0x0, | 1122 | .min_xc = 0x0, |
869 | .max_xc = 0x0fff, | 1123 | .max_xc = 0x0fff, |
870 | .min_yc = 0x0, | 1124 | .min_yc = 0x0, |
871 | .max_yc = 0x0fff, | 1125 | .max_yc = 0x0fff, |
872 | .rept_size = 5, | 1126 | .rept_size = 5, |
873 | .read_data = tc5uh_read_data, | 1127 | .read_data = tc45usb_read_data, |
1128 | }, | ||
1129 | #endif | ||
1130 | |||
1131 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
1132 | [DEVTYPE_NEXIO] = { | ||
1133 | .rept_size = 1024, | ||
1134 | .irq_always = true, | ||
1135 | .read_data = nexio_read_data, | ||
1136 | .alloc = nexio_alloc, | ||
1137 | .init = nexio_init, | ||
1138 | .exit = nexio_exit, | ||
874 | }, | 1139 | }, |
875 | #endif | 1140 | #endif |
876 | }; | 1141 | }; |
@@ -998,6 +1263,7 @@ static void usbtouch_irq(struct urb *urb) | |||
998 | case -ECONNRESET: | 1263 | case -ECONNRESET: |
999 | case -ENOENT: | 1264 | case -ENOENT: |
1000 | case -ESHUTDOWN: | 1265 | case -ESHUTDOWN: |
1266 | case -EPIPE: | ||
1001 | /* this urb is terminated, clean up */ | 1267 | /* this urb is terminated, clean up */ |
1002 | dbg("%s - urb shutting down with status: %d", | 1268 | dbg("%s - urb shutting down with status: %d", |
1003 | __func__, urb->status); | 1269 | __func__, urb->status); |
@@ -1011,6 +1277,7 @@ static void usbtouch_irq(struct urb *urb) | |||
1011 | usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length); | 1277 | usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length); |
1012 | 1278 | ||
1013 | exit: | 1279 | exit: |
1280 | usb_mark_last_busy(interface_to_usbdev(usbtouch->interface)); | ||
1014 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 1281 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
1015 | if (retval) | 1282 | if (retval) |
1016 | err("%s - usb_submit_urb failed with result: %d", | 1283 | err("%s - usb_submit_urb failed with result: %d", |
@@ -1020,41 +1287,115 @@ exit: | |||
1020 | static int usbtouch_open(struct input_dev *input) | 1287 | static int usbtouch_open(struct input_dev *input) |
1021 | { | 1288 | { |
1022 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); | 1289 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); |
1290 | int r; | ||
1023 | 1291 | ||
1024 | usbtouch->irq->dev = usbtouch->udev; | 1292 | usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface); |
1293 | |||
1294 | r = usb_autopm_get_interface(usbtouch->interface) ? -EIO : 0; | ||
1295 | if (r < 0) | ||
1296 | goto out; | ||
1025 | 1297 | ||
1026 | if (!usbtouch->type->irq_always) { | 1298 | if (!usbtouch->type->irq_always) { |
1027 | if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) | 1299 | if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) { |
1028 | return -EIO; | 1300 | r = -EIO; |
1301 | goto out_put; | ||
1302 | } | ||
1029 | } | 1303 | } |
1030 | 1304 | ||
1031 | return 0; | 1305 | usbtouch->interface->needs_remote_wakeup = 1; |
1306 | out_put: | ||
1307 | usb_autopm_put_interface(usbtouch->interface); | ||
1308 | out: | ||
1309 | return r; | ||
1032 | } | 1310 | } |
1033 | 1311 | ||
1034 | static void usbtouch_close(struct input_dev *input) | 1312 | static void usbtouch_close(struct input_dev *input) |
1035 | { | 1313 | { |
1036 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); | 1314 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); |
1315 | int r; | ||
1037 | 1316 | ||
1038 | if (!usbtouch->type->irq_always) | 1317 | if (!usbtouch->type->irq_always) |
1039 | usb_kill_urb(usbtouch->irq); | 1318 | usb_kill_urb(usbtouch->irq); |
1319 | r = usb_autopm_get_interface(usbtouch->interface); | ||
1320 | usbtouch->interface->needs_remote_wakeup = 0; | ||
1321 | if (!r) | ||
1322 | usb_autopm_put_interface(usbtouch->interface); | ||
1323 | } | ||
1324 | |||
1325 | static int usbtouch_suspend | ||
1326 | (struct usb_interface *intf, pm_message_t message) | ||
1327 | { | ||
1328 | struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); | ||
1329 | |||
1330 | usb_kill_urb(usbtouch->irq); | ||
1331 | |||
1332 | return 0; | ||
1333 | } | ||
1334 | |||
1335 | static int usbtouch_resume(struct usb_interface *intf) | ||
1336 | { | ||
1337 | struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); | ||
1338 | struct input_dev *input = usbtouch->input; | ||
1339 | int result = 0; | ||
1340 | |||
1341 | mutex_lock(&input->mutex); | ||
1342 | if (input->users || usbtouch->type->irq_always) | ||
1343 | result = usb_submit_urb(usbtouch->irq, GFP_NOIO); | ||
1344 | mutex_unlock(&input->mutex); | ||
1345 | |||
1346 | return result; | ||
1040 | } | 1347 | } |
1041 | 1348 | ||
1349 | static int usbtouch_reset_resume(struct usb_interface *intf) | ||
1350 | { | ||
1351 | struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); | ||
1352 | struct input_dev *input = usbtouch->input; | ||
1353 | int err = 0; | ||
1354 | |||
1355 | /* reinit the device */ | ||
1356 | if (usbtouch->type->init) { | ||
1357 | err = usbtouch->type->init(usbtouch); | ||
1358 | if (err) { | ||
1359 | dbg("%s - type->init() failed, err: %d", | ||
1360 | __func__, err); | ||
1361 | return err; | ||
1362 | } | ||
1363 | } | ||
1364 | |||
1365 | /* restart IO if needed */ | ||
1366 | mutex_lock(&input->mutex); | ||
1367 | if (input->users) | ||
1368 | err = usb_submit_urb(usbtouch->irq, GFP_NOIO); | ||
1369 | mutex_unlock(&input->mutex); | ||
1370 | |||
1371 | return err; | ||
1372 | } | ||
1042 | 1373 | ||
1043 | static void usbtouch_free_buffers(struct usb_device *udev, | 1374 | static void usbtouch_free_buffers(struct usb_device *udev, |
1044 | struct usbtouch_usb *usbtouch) | 1375 | struct usbtouch_usb *usbtouch) |
1045 | { | 1376 | { |
1046 | usb_buffer_free(udev, usbtouch->type->rept_size, | 1377 | usb_free_coherent(udev, usbtouch->type->rept_size, |
1047 | usbtouch->data, usbtouch->data_dma); | 1378 | usbtouch->data, usbtouch->data_dma); |
1048 | kfree(usbtouch->buffer); | 1379 | kfree(usbtouch->buffer); |
1049 | } | 1380 | } |
1050 | 1381 | ||
1382 | static struct usb_endpoint_descriptor * | ||
1383 | usbtouch_get_input_endpoint(struct usb_host_interface *interface) | ||
1384 | { | ||
1385 | int i; | ||
1386 | |||
1387 | for (i = 0; i < interface->desc.bNumEndpoints; i++) | ||
1388 | if (usb_endpoint_dir_in(&interface->endpoint[i].desc)) | ||
1389 | return &interface->endpoint[i].desc; | ||
1390 | |||
1391 | return NULL; | ||
1392 | } | ||
1051 | 1393 | ||
1052 | static int usbtouch_probe(struct usb_interface *intf, | 1394 | static int usbtouch_probe(struct usb_interface *intf, |
1053 | const struct usb_device_id *id) | 1395 | const struct usb_device_id *id) |
1054 | { | 1396 | { |
1055 | struct usbtouch_usb *usbtouch; | 1397 | struct usbtouch_usb *usbtouch; |
1056 | struct input_dev *input_dev; | 1398 | struct input_dev *input_dev; |
1057 | struct usb_host_interface *interface; | ||
1058 | struct usb_endpoint_descriptor *endpoint; | 1399 | struct usb_endpoint_descriptor *endpoint; |
1059 | struct usb_device *udev = interface_to_usbdev(intf); | 1400 | struct usb_device *udev = interface_to_usbdev(intf); |
1060 | struct usbtouch_device_info *type; | 1401 | struct usbtouch_device_info *type; |
@@ -1064,8 +1405,9 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1064 | if (id->driver_info == DEVTYPE_IGNORE) | 1405 | if (id->driver_info == DEVTYPE_IGNORE) |
1065 | return -ENODEV; | 1406 | return -ENODEV; |
1066 | 1407 | ||
1067 | interface = intf->cur_altsetting; | 1408 | endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting); |
1068 | endpoint = &interface->endpoint[0].desc; | 1409 | if (!endpoint) |
1410 | return -ENXIO; | ||
1069 | 1411 | ||
1070 | usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); | 1412 | usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); |
1071 | input_dev = input_allocate_device(); | 1413 | input_dev = input_allocate_device(); |
@@ -1077,8 +1419,8 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1077 | if (!type->process_pkt) | 1419 | if (!type->process_pkt) |
1078 | type->process_pkt = usbtouch_process_pkt; | 1420 | type->process_pkt = usbtouch_process_pkt; |
1079 | 1421 | ||
1080 | usbtouch->data = usb_buffer_alloc(udev, type->rept_size, | 1422 | usbtouch->data = usb_alloc_coherent(udev, type->rept_size, |
1081 | GFP_KERNEL, &usbtouch->data_dma); | 1423 | GFP_KERNEL, &usbtouch->data_dma); |
1082 | if (!usbtouch->data) | 1424 | if (!usbtouch->data) |
1083 | goto out_free; | 1425 | goto out_free; |
1084 | 1426 | ||
@@ -1094,7 +1436,7 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1094 | goto out_free_buffers; | 1436 | goto out_free_buffers; |
1095 | } | 1437 | } |
1096 | 1438 | ||
1097 | usbtouch->udev = udev; | 1439 | usbtouch->interface = intf; |
1098 | usbtouch->input = input_dev; | 1440 | usbtouch->input = input_dev; |
1099 | 1441 | ||
1100 | if (udev->manufacturer) | 1442 | if (udev->manufacturer) |
@@ -1133,37 +1475,69 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1133 | input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, | 1475 | input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, |
1134 | type->max_press, 0, 0); | 1476 | type->max_press, 0, 0); |
1135 | 1477 | ||
1136 | usb_fill_int_urb(usbtouch->irq, usbtouch->udev, | 1478 | if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) |
1137 | usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress), | 1479 | usb_fill_int_urb(usbtouch->irq, udev, |
1480 | usb_rcvintpipe(udev, endpoint->bEndpointAddress), | ||
1138 | usbtouch->data, type->rept_size, | 1481 | usbtouch->data, type->rept_size, |
1139 | usbtouch_irq, usbtouch, endpoint->bInterval); | 1482 | usbtouch_irq, usbtouch, endpoint->bInterval); |
1483 | else | ||
1484 | usb_fill_bulk_urb(usbtouch->irq, udev, | ||
1485 | usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), | ||
1486 | usbtouch->data, type->rept_size, | ||
1487 | usbtouch_irq, usbtouch); | ||
1140 | 1488 | ||
1141 | usbtouch->irq->dev = usbtouch->udev; | 1489 | usbtouch->irq->dev = udev; |
1142 | usbtouch->irq->transfer_dma = usbtouch->data_dma; | 1490 | usbtouch->irq->transfer_dma = usbtouch->data_dma; |
1143 | usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1491 | usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1144 | 1492 | ||
1145 | /* device specific init */ | 1493 | /* device specific allocations */ |
1494 | if (type->alloc) { | ||
1495 | err = type->alloc(usbtouch); | ||
1496 | if (err) { | ||
1497 | dbg("%s - type->alloc() failed, err: %d", __func__, err); | ||
1498 | goto out_free_urb; | ||
1499 | } | ||
1500 | } | ||
1501 | |||
1502 | /* device specific initialisation*/ | ||
1146 | if (type->init) { | 1503 | if (type->init) { |
1147 | err = type->init(usbtouch); | 1504 | err = type->init(usbtouch); |
1148 | if (err) { | 1505 | if (err) { |
1149 | dbg("%s - type->init() failed, err: %d", __func__, err); | 1506 | dbg("%s - type->init() failed, err: %d", __func__, err); |
1150 | goto out_free_buffers; | 1507 | goto out_do_exit; |
1151 | } | 1508 | } |
1152 | } | 1509 | } |
1153 | 1510 | ||
1154 | err = input_register_device(usbtouch->input); | 1511 | err = input_register_device(usbtouch->input); |
1155 | if (err) { | 1512 | if (err) { |
1156 | dbg("%s - input_register_device failed, err: %d", __func__, err); | 1513 | dbg("%s - input_register_device failed, err: %d", __func__, err); |
1157 | goto out_free_buffers; | 1514 | goto out_do_exit; |
1158 | } | 1515 | } |
1159 | 1516 | ||
1160 | usb_set_intfdata(intf, usbtouch); | 1517 | usb_set_intfdata(intf, usbtouch); |
1161 | 1518 | ||
1162 | if (usbtouch->type->irq_always) | 1519 | if (usbtouch->type->irq_always) { |
1163 | usb_submit_urb(usbtouch->irq, GFP_KERNEL); | 1520 | /* this can't fail */ |
1521 | usb_autopm_get_interface(intf); | ||
1522 | err = usb_submit_urb(usbtouch->irq, GFP_KERNEL); | ||
1523 | if (err) { | ||
1524 | usb_autopm_put_interface(intf); | ||
1525 | err("%s - usb_submit_urb failed with result: %d", | ||
1526 | __func__, err); | ||
1527 | goto out_unregister_input; | ||
1528 | } | ||
1529 | } | ||
1164 | 1530 | ||
1165 | return 0; | 1531 | return 0; |
1166 | 1532 | ||
1533 | out_unregister_input: | ||
1534 | input_unregister_device(input_dev); | ||
1535 | input_dev = NULL; | ||
1536 | out_do_exit: | ||
1537 | if (type->exit) | ||
1538 | type->exit(usbtouch); | ||
1539 | out_free_urb: | ||
1540 | usb_free_urb(usbtouch->irq); | ||
1167 | out_free_buffers: | 1541 | out_free_buffers: |
1168 | usbtouch_free_buffers(udev, usbtouch); | 1542 | usbtouch_free_buffers(udev, usbtouch); |
1169 | out_free: | 1543 | out_free: |
@@ -1186,6 +1560,8 @@ static void usbtouch_disconnect(struct usb_interface *intf) | |||
1186 | /* this will stop IO via close */ | 1560 | /* this will stop IO via close */ |
1187 | input_unregister_device(usbtouch->input); | 1561 | input_unregister_device(usbtouch->input); |
1188 | usb_free_urb(usbtouch->irq); | 1562 | usb_free_urb(usbtouch->irq); |
1563 | if (usbtouch->type->exit) | ||
1564 | usbtouch->type->exit(usbtouch); | ||
1189 | usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); | 1565 | usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); |
1190 | kfree(usbtouch); | 1566 | kfree(usbtouch); |
1191 | } | 1567 | } |
@@ -1196,7 +1572,11 @@ static struct usb_driver usbtouch_driver = { | |||
1196 | .name = "usbtouchscreen", | 1572 | .name = "usbtouchscreen", |
1197 | .probe = usbtouch_probe, | 1573 | .probe = usbtouch_probe, |
1198 | .disconnect = usbtouch_disconnect, | 1574 | .disconnect = usbtouch_disconnect, |
1575 | .suspend = usbtouch_suspend, | ||
1576 | .resume = usbtouch_resume, | ||
1577 | .reset_resume = usbtouch_reset_resume, | ||
1199 | .id_table = usbtouch_devices, | 1578 | .id_table = usbtouch_devices, |
1579 | .supports_autosuspend = 1, | ||
1200 | }; | 1580 | }; |
1201 | 1581 | ||
1202 | static int __init usbtouch_init(void) | 1582 | static int __init usbtouch_init(void) |
diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c index 6ccbdbbf33fe..7a45d68c3516 100644 --- a/drivers/input/touchscreen/w90p910_ts.c +++ b/drivers/input/touchscreen/w90p910_ts.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
17 | #include <linux/input.h> | 17 | #include <linux/input.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/slab.h> | ||
19 | 20 | ||
20 | /* ADC controller bit defines */ | 21 | /* ADC controller bit defines */ |
21 | #define ADC_DELAY 0xf00 | 22 | #define ADC_DELAY 0xf00 |
@@ -232,7 +233,7 @@ static int __devinit w90x900ts_probe(struct platform_device *pdev) | |||
232 | w90p910_ts->state = TS_IDLE; | 233 | w90p910_ts->state = TS_IDLE; |
233 | spin_lock_init(&w90p910_ts->lock); | 234 | spin_lock_init(&w90p910_ts->lock); |
234 | setup_timer(&w90p910_ts->timer, w90p910_check_pen_up, | 235 | setup_timer(&w90p910_ts->timer, w90p910_check_pen_up, |
235 | (unsigned long)&w90p910_ts); | 236 | (unsigned long)w90p910_ts); |
236 | 237 | ||
237 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 238 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
238 | if (!res) { | 239 | if (!res) { |
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 56dc35c94bb1..9ae4c7b16ba7 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Wacom W8001 penabled serial touchscreen driver | 2 | * Wacom W8001 penabled serial touchscreen driver |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Jaya Kumar | 4 | * Copyright (c) 2008 Jaya Kumar |
5 | * Copyright (c) 2010 Red Hat, Inc. | ||
5 | * | 6 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
7 | * License. See the file COPYING in the main directory of this archive for | 8 | * License. See the file COPYING in the main directory of this archive for |
@@ -30,11 +31,24 @@ MODULE_LICENSE("GPL"); | |||
30 | #define W8001_LEAD_BYTE 0x80 | 31 | #define W8001_LEAD_BYTE 0x80 |
31 | #define W8001_TAB_MASK 0x40 | 32 | #define W8001_TAB_MASK 0x40 |
32 | #define W8001_TAB_BYTE 0x40 | 33 | #define W8001_TAB_BYTE 0x40 |
34 | /* set in first byte of touch data packets */ | ||
35 | #define W8001_TOUCH_MASK (0x10 | W8001_LEAD_MASK) | ||
36 | #define W8001_TOUCH_BYTE (0x10 | W8001_LEAD_BYTE) | ||
33 | 37 | ||
34 | #define W8001_QUERY_PACKET 0x20 | 38 | #define W8001_QUERY_PACKET 0x20 |
35 | 39 | ||
36 | #define W8001_CMD_START '1' | 40 | #define W8001_CMD_START '1' |
37 | #define W8001_CMD_QUERY '*' | 41 | #define W8001_CMD_QUERY '*' |
42 | #define W8001_CMD_TOUCHQUERY '%' | ||
43 | |||
44 | /* length of data packets in bytes, depends on device. */ | ||
45 | #define W8001_PKTLEN_TOUCH93 5 | ||
46 | #define W8001_PKTLEN_TOUCH9A 7 | ||
47 | #define W8001_PKTLEN_TPCPEN 9 | ||
48 | #define W8001_PKTLEN_TPCCTL 11 /* control packet */ | ||
49 | #define W8001_PKTLEN_TOUCH2FG 13 | ||
50 | |||
51 | #define MAX_TRACKING_ID 0xFF /* arbitrarily chosen */ | ||
38 | 52 | ||
39 | struct w8001_coord { | 53 | struct w8001_coord { |
40 | u8 rdy; | 54 | u8 rdy; |
@@ -48,6 +62,15 @@ struct w8001_coord { | |||
48 | u8 tilt_y; | 62 | u8 tilt_y; |
49 | }; | 63 | }; |
50 | 64 | ||
65 | /* touch query reply packet */ | ||
66 | struct w8001_touch_query { | ||
67 | u8 panel_res; | ||
68 | u8 capacity_res; | ||
69 | u8 sensor_id; | ||
70 | u16 x; | ||
71 | u16 y; | ||
72 | }; | ||
73 | |||
51 | /* | 74 | /* |
52 | * Per-touchscreen data. | 75 | * Per-touchscreen data. |
53 | */ | 76 | */ |
@@ -62,6 +85,9 @@ struct w8001 { | |||
62 | unsigned char response[W8001_MAX_LENGTH]; | 85 | unsigned char response[W8001_MAX_LENGTH]; |
63 | unsigned char data[W8001_MAX_LENGTH]; | 86 | unsigned char data[W8001_MAX_LENGTH]; |
64 | char phys[32]; | 87 | char phys[32]; |
88 | int type; | ||
89 | unsigned int pktlen; | ||
90 | int trkid[2]; | ||
65 | }; | 91 | }; |
66 | 92 | ||
67 | static void parse_data(u8 *data, struct w8001_coord *coord) | 93 | static void parse_data(u8 *data, struct w8001_coord *coord) |
@@ -88,11 +114,98 @@ static void parse_data(u8 *data, struct w8001_coord *coord) | |||
88 | coord->tilt_y = data[8] & 0x7F; | 114 | coord->tilt_y = data[8] & 0x7F; |
89 | } | 115 | } |
90 | 116 | ||
117 | static void parse_touch(struct w8001 *w8001) | ||
118 | { | ||
119 | static int trkid; | ||
120 | struct input_dev *dev = w8001->dev; | ||
121 | unsigned char *data = w8001->data; | ||
122 | int i; | ||
123 | |||
124 | for (i = 0; i < 2; i++) { | ||
125 | input_mt_slot(dev, i); | ||
126 | |||
127 | if (data[0] & (1 << i)) { | ||
128 | int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]); | ||
129 | int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]); | ||
130 | /* data[5,6] and [11,12] is finger capacity */ | ||
131 | |||
132 | input_report_abs(dev, ABS_MT_POSITION_X, x); | ||
133 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | ||
134 | input_report_abs(dev, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); | ||
135 | if (w8001->trkid[i] < 0) | ||
136 | w8001->trkid[i] = trkid++ & MAX_TRACKING_ID; | ||
137 | } else { | ||
138 | w8001->trkid[i] = -1; | ||
139 | } | ||
140 | input_report_abs(dev, ABS_MT_TRACKING_ID, w8001->trkid[i]); | ||
141 | } | ||
142 | |||
143 | input_sync(dev); | ||
144 | } | ||
145 | |||
146 | static void parse_touchquery(u8 *data, struct w8001_touch_query *query) | ||
147 | { | ||
148 | memset(query, 0, sizeof(*query)); | ||
149 | |||
150 | query->panel_res = data[1]; | ||
151 | query->sensor_id = data[2] & 0x7; | ||
152 | query->capacity_res = data[7]; | ||
153 | |||
154 | query->x = data[3] << 9; | ||
155 | query->x |= data[4] << 2; | ||
156 | query->x |= (data[2] >> 5) & 0x3; | ||
157 | |||
158 | query->y = data[5] << 9; | ||
159 | query->y |= data[6] << 2; | ||
160 | query->y |= (data[2] >> 3) & 0x3; | ||
161 | } | ||
162 | |||
163 | static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) | ||
164 | { | ||
165 | struct input_dev *dev = w8001->dev; | ||
166 | |||
167 | /* | ||
168 | * We have 1 bit for proximity (rdy) and 3 bits for tip, side, | ||
169 | * side2/eraser. If rdy && f2 are set, this can be either pen + side2, | ||
170 | * or eraser. assume | ||
171 | * - if dev is already in proximity and f2 is toggled → pen + side2 | ||
172 | * - if dev comes into proximity with f2 set → eraser | ||
173 | * If f2 disappears after assuming eraser, fake proximity out for | ||
174 | * eraser and in for pen. | ||
175 | */ | ||
176 | |||
177 | if (!w8001->type) { | ||
178 | w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
179 | } else if (w8001->type == BTN_TOOL_RUBBER) { | ||
180 | if (!coord->f2) { | ||
181 | input_report_abs(dev, ABS_PRESSURE, 0); | ||
182 | input_report_key(dev, BTN_TOUCH, 0); | ||
183 | input_report_key(dev, BTN_STYLUS, 0); | ||
184 | input_report_key(dev, BTN_STYLUS2, 0); | ||
185 | input_report_key(dev, BTN_TOOL_RUBBER, 0); | ||
186 | input_sync(dev); | ||
187 | w8001->type = BTN_TOOL_PEN; | ||
188 | } | ||
189 | } else { | ||
190 | input_report_key(dev, BTN_STYLUS2, coord->f2); | ||
191 | } | ||
192 | |||
193 | input_report_abs(dev, ABS_X, coord->x); | ||
194 | input_report_abs(dev, ABS_Y, coord->y); | ||
195 | input_report_abs(dev, ABS_PRESSURE, coord->pen_pressure); | ||
196 | input_report_key(dev, BTN_TOUCH, coord->tsw); | ||
197 | input_report_key(dev, BTN_STYLUS, coord->f1); | ||
198 | input_report_key(dev, w8001->type, coord->rdy); | ||
199 | input_sync(dev); | ||
200 | |||
201 | if (!coord->rdy) | ||
202 | w8001->type = 0; | ||
203 | } | ||
204 | |||
91 | static irqreturn_t w8001_interrupt(struct serio *serio, | 205 | static irqreturn_t w8001_interrupt(struct serio *serio, |
92 | unsigned char data, unsigned int flags) | 206 | unsigned char data, unsigned int flags) |
93 | { | 207 | { |
94 | struct w8001 *w8001 = serio_get_drvdata(serio); | 208 | struct w8001 *w8001 = serio_get_drvdata(serio); |
95 | struct input_dev *dev = w8001->dev; | ||
96 | struct w8001_coord coord; | 209 | struct w8001_coord coord; |
97 | unsigned char tmp; | 210 | unsigned char tmp; |
98 | 211 | ||
@@ -105,26 +218,45 @@ static irqreturn_t w8001_interrupt(struct serio *serio, | |||
105 | } | 218 | } |
106 | break; | 219 | break; |
107 | 220 | ||
108 | case 8: | 221 | case W8001_PKTLEN_TOUCH93 - 1: |
222 | case W8001_PKTLEN_TOUCH9A - 1: | ||
223 | /* ignore one-finger touch packet. */ | ||
224 | if (w8001->pktlen == w8001->idx) | ||
225 | w8001->idx = 0; | ||
226 | break; | ||
227 | |||
228 | /* Pen coordinates packet */ | ||
229 | case W8001_PKTLEN_TPCPEN - 1: | ||
109 | tmp = w8001->data[0] & W8001_TAB_MASK; | 230 | tmp = w8001->data[0] & W8001_TAB_MASK; |
110 | if (unlikely(tmp == W8001_TAB_BYTE)) | 231 | if (unlikely(tmp == W8001_TAB_BYTE)) |
111 | break; | 232 | break; |
112 | 233 | ||
234 | tmp = (w8001->data[0] & W8001_TOUCH_BYTE); | ||
235 | if (tmp == W8001_TOUCH_BYTE) | ||
236 | break; | ||
237 | |||
113 | w8001->idx = 0; | 238 | w8001->idx = 0; |
114 | parse_data(w8001->data, &coord); | 239 | parse_data(w8001->data, &coord); |
115 | input_report_abs(dev, ABS_X, coord.x); | 240 | report_pen_events(w8001, &coord); |
116 | input_report_abs(dev, ABS_Y, coord.y); | ||
117 | input_report_abs(dev, ABS_PRESSURE, coord.pen_pressure); | ||
118 | input_report_key(dev, BTN_TOUCH, coord.tsw); | ||
119 | input_sync(dev); | ||
120 | break; | 241 | break; |
121 | 242 | ||
122 | case 10: | 243 | /* control packet */ |
244 | case W8001_PKTLEN_TPCCTL - 1: | ||
245 | tmp = (w8001->data[0] & W8001_TOUCH_MASK); | ||
246 | if (tmp == W8001_TOUCH_BYTE) | ||
247 | break; | ||
248 | |||
123 | w8001->idx = 0; | 249 | w8001->idx = 0; |
124 | memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); | 250 | memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); |
125 | w8001->response_type = W8001_QUERY_PACKET; | 251 | w8001->response_type = W8001_QUERY_PACKET; |
126 | complete(&w8001->cmd_done); | 252 | complete(&w8001->cmd_done); |
127 | break; | 253 | break; |
254 | |||
255 | /* 2 finger touch packet */ | ||
256 | case W8001_PKTLEN_TOUCH2FG - 1: | ||
257 | w8001->idx = 0; | ||
258 | parse_touch(w8001); | ||
259 | break; | ||
128 | } | 260 | } |
129 | 261 | ||
130 | return IRQ_HANDLED; | 262 | return IRQ_HANDLED; |
@@ -167,6 +299,38 @@ static int w8001_setup(struct w8001 *w8001) | |||
167 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | 299 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); |
168 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); | 300 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); |
169 | 301 | ||
302 | error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); | ||
303 | if (!error) { | ||
304 | struct w8001_touch_query touch; | ||
305 | |||
306 | parse_touchquery(w8001->response, &touch); | ||
307 | |||
308 | switch (touch.sensor_id) { | ||
309 | case 0: | ||
310 | case 2: | ||
311 | w8001->pktlen = W8001_PKTLEN_TOUCH93; | ||
312 | break; | ||
313 | case 1: | ||
314 | case 3: | ||
315 | case 4: | ||
316 | w8001->pktlen = W8001_PKTLEN_TOUCH9A; | ||
317 | break; | ||
318 | case 5: | ||
319 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; | ||
320 | |||
321 | input_mt_create_slots(dev, 2); | ||
322 | input_set_abs_params(dev, ABS_MT_TRACKING_ID, | ||
323 | 0, MAX_TRACKING_ID, 0, 0); | ||
324 | input_set_abs_params(dev, ABS_MT_POSITION_X, | ||
325 | 0, touch.x, 0, 0); | ||
326 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | ||
327 | 0, touch.y, 0, 0); | ||
328 | input_set_abs_params(dev, ABS_MT_TOOL_TYPE, | ||
329 | 0, 0, 0, 0); | ||
330 | break; | ||
331 | } | ||
332 | } | ||
333 | |||
170 | return w8001_command(w8001, W8001_CMD_START, false); | 334 | return w8001_command(w8001, W8001_CMD_START, false); |
171 | } | 335 | } |
172 | 336 | ||
@@ -208,6 +372,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
208 | w8001->serio = serio; | 372 | w8001->serio = serio; |
209 | w8001->id = serio->id.id; | 373 | w8001->id = serio->id.id; |
210 | w8001->dev = input_dev; | 374 | w8001->dev = input_dev; |
375 | w8001->trkid[0] = w8001->trkid[1] = -1; | ||
211 | init_completion(&w8001->cmd_done); | 376 | init_completion(&w8001->cmd_done); |
212 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); | 377 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); |
213 | 378 | ||
@@ -221,6 +386,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
221 | 386 | ||
222 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 387 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
223 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 388 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
389 | input_dev->keybit[BIT_WORD(BTN_TOOL_PEN)] |= BIT_MASK(BTN_TOOL_PEN); | ||
390 | input_dev->keybit[BIT_WORD(BTN_TOOL_RUBBER)] |= BIT_MASK(BTN_TOOL_RUBBER); | ||
391 | input_dev->keybit[BIT_WORD(BTN_STYLUS)] |= BIT_MASK(BTN_STYLUS); | ||
392 | input_dev->keybit[BIT_WORD(BTN_STYLUS2)] |= BIT_MASK(BTN_STYLUS2); | ||
224 | 393 | ||
225 | serio_set_drvdata(serio, w8001); | 394 | serio_set_drvdata(serio, w8001); |
226 | err = serio_open(serio, drv); | 395 | err = serio_open(serio, drv); |
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index f944918466e5..6b75c9f660ae 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/wm97xx.h> | 48 | #include <linux/wm97xx.h> |
49 | #include <linux/uaccess.h> | 49 | #include <linux/uaccess.h> |
50 | #include <linux/io.h> | 50 | #include <linux/io.h> |
51 | #include <linux/slab.h> | ||
51 | 52 | ||
52 | #define TS_NAME "wm97xx" | 53 | #define TS_NAME "wm97xx" |
53 | #define WM_CORE_VERSION "1.00" | 54 | #define WM_CORE_VERSION "1.00" |
@@ -124,6 +125,8 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
124 | { | 125 | { |
125 | int power_adc = 0, auxval; | 126 | int power_adc = 0, auxval; |
126 | u16 power = 0; | 127 | u16 power = 0; |
128 | int rc = 0; | ||
129 | int timeout = 0; | ||
127 | 130 | ||
128 | /* get codec */ | 131 | /* get codec */ |
129 | mutex_lock(&wm->codec_mutex); | 132 | mutex_lock(&wm->codec_mutex); |
@@ -142,7 +145,9 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
142 | 145 | ||
143 | /* Turn polling mode on to read AUX ADC */ | 146 | /* Turn polling mode on to read AUX ADC */ |
144 | wm->pen_probably_down = 1; | 147 | wm->pen_probably_down = 1; |
145 | wm->codec->poll_sample(wm, adcsel, &auxval); | 148 | |
149 | while (rc != RC_VALID && timeout++ < 5) | ||
150 | rc = wm->codec->poll_sample(wm, adcsel, &auxval); | ||
146 | 151 | ||
147 | if (power_adc) | 152 | if (power_adc) |
148 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); | 153 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); |
@@ -151,8 +156,15 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
151 | 156 | ||
152 | wm->pen_probably_down = 0; | 157 | wm->pen_probably_down = 0; |
153 | 158 | ||
159 | if (timeout >= 5) { | ||
160 | dev_err(wm->dev, | ||
161 | "timeout reading auxadc %d, disabling digitiser\n", | ||
162 | adcsel); | ||
163 | wm->codec->dig_enable(wm, false); | ||
164 | } | ||
165 | |||
154 | mutex_unlock(&wm->codec_mutex); | 166 | mutex_unlock(&wm->codec_mutex); |
155 | return auxval & 0xfff; | 167 | return (rc == RC_VALID ? auxval & 0xfff : -EBUSY); |
156 | } | 168 | } |
157 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); | 169 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); |
158 | 170 | ||
@@ -199,7 +211,7 @@ void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio, | |||
199 | mutex_lock(&wm->codec_mutex); | 211 | mutex_lock(&wm->codec_mutex); |
200 | reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS); | 212 | reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS); |
201 | 213 | ||
202 | if (status & WM97XX_GPIO_HIGH) | 214 | if (status == WM97XX_GPIO_HIGH) |
203 | reg |= gpio; | 215 | reg |= gpio; |
204 | else | 216 | else |
205 | reg &= ~gpio; | 217 | reg &= ~gpio; |
@@ -683,8 +695,7 @@ static int wm97xx_probe(struct device *dev) | |||
683 | touch_reg_err: | 695 | touch_reg_err: |
684 | platform_device_put(wm->touch_dev); | 696 | platform_device_put(wm->touch_dev); |
685 | touch_err: | 697 | touch_err: |
686 | platform_device_unregister(wm->battery_dev); | 698 | platform_device_del(wm->battery_dev); |
687 | wm->battery_dev = NULL; | ||
688 | batt_reg_err: | 699 | batt_reg_err: |
689 | platform_device_put(wm->battery_dev); | 700 | platform_device_put(wm->battery_dev); |
690 | batt_err: | 701 | batt_err: |
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index eca54dbdf493..048849867643 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c | |||
@@ -118,6 +118,9 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) | |||
118 | if (pressure) | 118 | if (pressure) |
119 | p = MODR; | 119 | p = MODR; |
120 | 120 | ||
121 | dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n", | ||
122 | x, y, p); | ||
123 | |||
121 | /* are samples valid */ | 124 | /* are samples valid */ |
122 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || | 125 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || |
123 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || | 126 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || |
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c index c721c0a23eb8..ebb11907d402 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/xen-kbdfront.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
24 | #include <linux/slab.h> | ||
24 | 25 | ||
25 | #include <asm/xen/hypervisor.h> | 26 | #include <asm/xen/hypervisor.h> |
26 | 27 | ||
@@ -321,7 +322,7 @@ InitWait: | |||
321 | } | 322 | } |
322 | } | 323 | } |
323 | 324 | ||
324 | static struct xenbus_device_id xenkbd_ids[] = { | 325 | static const struct xenbus_device_id xenkbd_ids[] = { |
325 | { "vkbd" }, | 326 | { "vkbd" }, |
326 | { "" } | 327 | { "" } |
327 | }; | 328 | }; |
@@ -338,7 +339,7 @@ static struct xenbus_driver xenkbd_driver = { | |||
338 | 339 | ||
339 | static int __init xenkbd_init(void) | 340 | static int __init xenkbd_init(void) |
340 | { | 341 | { |
341 | if (!xen_domain()) | 342 | if (!xen_pv_domain()) |
342 | return -ENODEV; | 343 | return -ENODEV; |
343 | 344 | ||
344 | /* Nothing to do if running in dom0. */ | 345 | /* Nothing to do if running in dom0. */ |