diff options
Diffstat (limited to 'drivers/input/tablet/wacom_wac.c')
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 305 |
1 files changed, 128 insertions, 177 deletions
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 435b0af401e..5597637cfd4 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include "wacom_wac.h" | 15 | #include "wacom_wac.h" |
16 | #include "wacom.h" | 16 | #include "wacom.h" |
17 | #include <linux/input/mt.h> | ||
17 | 18 | ||
18 | static int wacom_penpartner_irq(struct wacom_wac *wacom) | 19 | static int wacom_penpartner_irq(struct wacom_wac *wacom) |
19 | { | 20 | { |
@@ -674,169 +675,87 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
674 | return 1; | 675 | return 1; |
675 | } | 676 | } |
676 | 677 | ||
677 | 678 | static int wacom_tpc_mt_touch(struct wacom_wac *wacom) | |
678 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, char *data, int idx) | ||
679 | { | 679 | { |
680 | struct input_dev *input = wacom->input; | 680 | struct input_dev *input = wacom->input; |
681 | int finger = idx + 1; | 681 | unsigned char *data = wacom->data; |
682 | int x = le16_to_cpup((__le16 *)&data[finger * 2]) & 0x7fff; | 682 | int contact_with_no_pen_down_count = 0; |
683 | int y = le16_to_cpup((__le16 *)&data[4 + finger * 2]) & 0x7fff; | 683 | int i; |
684 | 684 | ||
685 | /* | 685 | for (i = 0; i < 2; i++) { |
686 | * Work around input core suppressing "duplicate" events since | 686 | int p = data[1] & (1 << i); |
687 | * we are abusing ABS_X/ABS_Y to transmit multi-finger data. | 687 | bool touch = p && !wacom->shared->stylus_in_proximity; |
688 | * This should go away once we switch to true multitouch | ||
689 | * protocol. | ||
690 | */ | ||
691 | if (wacom->last_finger != finger) { | ||
692 | if (x == input_abs_get_val(input, ABS_X)) | ||
693 | x++; | ||
694 | 688 | ||
695 | if (y == input_abs_get_val(input, ABS_Y)) | 689 | input_mt_slot(input, i); |
696 | y++; | 690 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
691 | if (touch) { | ||
692 | int x = le16_to_cpup((__le16 *)&data[i * 2 + 2]) & 0x7fff; | ||
693 | int y = le16_to_cpup((__le16 *)&data[i * 2 + 6]) & 0x7fff; | ||
694 | |||
695 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
696 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
697 | contact_with_no_pen_down_count++; | ||
698 | } | ||
697 | } | 699 | } |
698 | 700 | ||
699 | input_report_abs(input, ABS_X, x); | 701 | /* keep touch state for pen event */ |
700 | input_report_abs(input, ABS_Y, y); | 702 | wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); |
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 | 703 | ||
708 | wacom->last_finger = finger; | 704 | input_mt_report_pointer_emulation(input, true); |
709 | } | ||
710 | 705 | ||
711 | static void wacom_tpc_touch_out(struct wacom_wac *wacom, int idx) | 706 | return 1; |
712 | { | ||
713 | struct input_dev *input = wacom->input; | ||
714 | int finger = idx + 1; | ||
715 | |||
716 | input_report_abs(input, ABS_X, 0); | ||
717 | input_report_abs(input, ABS_Y, 0); | ||
718 | input_report_abs(input, ABS_MISC, 0); | ||
719 | input_report_key(input, wacom->tool[finger], 0); | ||
720 | if (!idx) | ||
721 | input_report_key(input, BTN_TOUCH, 0); | ||
722 | input_event(input, EV_MSC, MSC_SERIAL, finger); | ||
723 | input_sync(input); | ||
724 | } | 707 | } |
725 | 708 | ||
726 | static void wacom_tpc_touch_in(struct wacom_wac *wacom, size_t len) | 709 | static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) |
727 | { | 710 | { |
728 | char *data = wacom->data; | 711 | char *data = wacom->data; |
729 | struct input_dev *input = wacom->input; | 712 | struct input_dev *input = wacom->input; |
713 | bool prox; | ||
714 | int x = 0, y = 0; | ||
730 | 715 | ||
731 | wacom->tool[1] = BTN_TOOL_DOUBLETAP; | 716 | if (!wacom->shared->stylus_in_proximity) { |
732 | wacom->id[0] = TOUCH_DEVICE_ID; | 717 | if (len == WACOM_PKGLEN_TPC1FG) { |
733 | wacom->tool[2] = BTN_TOOL_TRIPLETAP; | 718 | prox = data[0] & 0x01; |
734 | 719 | x = get_unaligned_le16(&data[1]); | |
735 | if (len != WACOM_PKGLEN_TPC1FG) { | 720 | y = get_unaligned_le16(&data[3]); |
736 | 721 | } else { /* with capacity */ | |
737 | switch (data[0]) { | 722 | prox = data[1] & 0x01; |
723 | x = le16_to_cpup((__le16 *)&data[2]); | ||
724 | y = le16_to_cpup((__le16 *)&data[4]); | ||
725 | } | ||
726 | } else | ||
727 | /* force touch out when pen is in prox */ | ||
728 | prox = 0; | ||
738 | 729 | ||
739 | case WACOM_REPORT_TPC1FG: | 730 | if (prox) { |
740 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); | 731 | input_report_abs(input, ABS_X, x); |
741 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); | 732 | input_report_abs(input, ABS_Y, y); |
742 | input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6])); | 733 | } |
743 | input_report_key(input, BTN_TOUCH, le16_to_cpup((__le16 *)&data[6])); | 734 | input_report_key(input, BTN_TOUCH, prox); |
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; | ||
748 | 735 | ||
749 | case WACOM_REPORT_TPC2FG: | 736 | /* keep touch state for pen events */ |
750 | if (data[1] & 0x01) | 737 | wacom->shared->touch_down = prox; |
751 | wacom_tpc_finger_in(wacom, data, 0); | ||
752 | else if (wacom->id[1] & 0x01) | ||
753 | wacom_tpc_touch_out(wacom, 0); | ||
754 | 738 | ||
755 | if (data[1] & 0x02) | 739 | return 1; |
756 | wacom_tpc_finger_in(wacom, data, 1); | ||
757 | else if (wacom->id[1] & 0x02) | ||
758 | wacom_tpc_touch_out(wacom, 1); | ||
759 | break; | ||
760 | } | ||
761 | } else { | ||
762 | input_report_abs(input, ABS_X, get_unaligned_le16(&data[1])); | ||
763 | input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3])); | ||
764 | input_report_key(input, BTN_TOUCH, 1); | ||
765 | input_report_abs(input, ABS_MISC, wacom->id[1]); | ||
766 | input_report_key(input, wacom->tool[1], 1); | ||
767 | input_sync(input); | ||
768 | } | ||
769 | } | 740 | } |
770 | 741 | ||
771 | static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | 742 | static int wacom_tpc_pen(struct wacom_wac *wacom) |
772 | { | 743 | { |
773 | struct wacom_features *features = &wacom->features; | 744 | struct wacom_features *features = &wacom->features; |
774 | char *data = wacom->data; | 745 | char *data = wacom->data; |
775 | struct input_dev *input = wacom->input; | 746 | struct input_dev *input = wacom->input; |
776 | int prox = 0, pressure; | 747 | int pressure; |
777 | int retval = 0; | 748 | bool prox = data[1] & 0x20; |
778 | |||
779 | dbg("wacom_tpc_irq: received report #%d", data[0]); | ||
780 | |||
781 | if (len == WACOM_PKGLEN_TPC1FG || /* single touch */ | ||
782 | data[0] == WACOM_REPORT_TPC1FG || /* single touch */ | ||
783 | data[0] == WACOM_REPORT_TPC2FG) { /* 2FG 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 */ | ||
797 | prox = data[0] & 0x01; | ||
798 | } else { /* with capacity */ | ||
799 | if (data[0] == WACOM_REPORT_TPC1FG) | ||
800 | /* single touch */ | ||
801 | prox = data[1] & 0x01; | ||
802 | else | ||
803 | /* 2FG touch data */ | ||
804 | prox = data[1] & 0x03; | ||
805 | } | ||
806 | |||
807 | if (prox) { | ||
808 | if (!wacom->id[1]) | ||
809 | wacom->last_finger = 1; | ||
810 | wacom_tpc_touch_in(wacom, len); | ||
811 | } else { | ||
812 | if (data[0] == WACOM_REPORT_TPC2FG) { | ||
813 | /* 2FGT out-prox */ | ||
814 | if (wacom->id[1] & 0x01) | ||
815 | wacom_tpc_touch_out(wacom, 0); | ||
816 | 749 | ||
817 | if (wacom->id[1] & 0x02) | 750 | if (!wacom->shared->stylus_in_proximity) /* first in prox */ |
818 | wacom_tpc_touch_out(wacom, 1); | 751 | /* Going into proximity select tool */ |
819 | } else | 752 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
820 | /* one finger touch */ | ||
821 | wacom_tpc_touch_out(wacom, 0); | ||
822 | 753 | ||
823 | wacom->id[0] = 0; | 754 | /* keep pen state for touch events */ |
824 | } | 755 | wacom->shared->stylus_in_proximity = prox; |
825 | /* keep prox bit to send proper out-prox event */ | ||
826 | wacom->id[1] = prox; | ||
827 | } else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */ | ||
828 | prox = data[1] & 0x20; | ||
829 | |||
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; | ||
837 | 756 | ||
838 | wacom->shared->stylus_in_proximity = true; | 757 | /* send pen events only when touch is up or forced out */ |
839 | } | 758 | if (!wacom->shared->touch_down) { |
840 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); | 759 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); |
841 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); | 760 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); |
842 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); | 761 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); |
@@ -846,15 +765,27 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
846 | pressure = features->pressure_max + pressure + 1; | 765 | pressure = features->pressure_max + pressure + 1; |
847 | input_report_abs(input, ABS_PRESSURE, pressure); | 766 | input_report_abs(input, ABS_PRESSURE, pressure); |
848 | input_report_key(input, BTN_TOUCH, data[1] & 0x05); | 767 | 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); | 768 | input_report_key(input, wacom->tool[0], prox); |
854 | input_report_abs(input, ABS_MISC, wacom->id[0]); | 769 | return 1; |
855 | retval = 1; | ||
856 | } | 770 | } |
857 | return retval; | 771 | |
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | ||
776 | { | ||
777 | char *data = wacom->data; | ||
778 | |||
779 | dbg("wacom_tpc_irq: received report #%d", data[0]); | ||
780 | |||
781 | if (len == WACOM_PKGLEN_TPC1FG || data[0] == WACOM_REPORT_TPC1FG) | ||
782 | return wacom_tpc_single_touch(wacom, len); | ||
783 | else if (data[0] == WACOM_REPORT_TPC2FG) | ||
784 | return wacom_tpc_mt_touch(wacom); | ||
785 | else if (data[0] == WACOM_REPORT_PENABLED) | ||
786 | return wacom_tpc_pen(wacom); | ||
787 | |||
788 | return 0; | ||
858 | } | 789 | } |
859 | 790 | ||
860 | static int wacom_bpt_touch(struct wacom_wac *wacom) | 791 | static int wacom_bpt_touch(struct wacom_wac *wacom) |
@@ -862,19 +793,21 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) | |||
862 | struct wacom_features *features = &wacom->features; | 793 | struct wacom_features *features = &wacom->features; |
863 | struct input_dev *input = wacom->input; | 794 | struct input_dev *input = wacom->input; |
864 | unsigned char *data = wacom->data; | 795 | unsigned char *data = wacom->data; |
865 | int sp = 0, sx = 0, sy = 0, count = 0; | ||
866 | int i; | 796 | int i; |
867 | 797 | ||
868 | for (i = 0; i < 2; i++) { | 798 | for (i = 0; i < 2; i++) { |
869 | int p = data[9 * i + 2]; | 799 | int p = data[9 * i + 2]; |
800 | bool touch = p && !wacom->shared->stylus_in_proximity; | ||
801 | |||
870 | input_mt_slot(input, i); | 802 | input_mt_slot(input, i); |
803 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | ||
871 | /* | 804 | /* |
872 | * Touch events need to be disabled while stylus is | 805 | * Touch events need to be disabled while stylus is |
873 | * in proximity because user's hand is resting on touchpad | 806 | * in proximity because user's hand is resting on touchpad |
874 | * and sending unwanted events. User expects tablet buttons | 807 | * and sending unwanted events. User expects tablet buttons |
875 | * to continue working though. | 808 | * to continue working though. |
876 | */ | 809 | */ |
877 | if (p && !wacom->shared->stylus_in_proximity) { | 810 | if (touch) { |
878 | int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; | 811 | int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; |
879 | int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; | 812 | int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; |
880 | if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { | 813 | if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { |
@@ -884,23 +817,10 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) | |||
884 | input_report_abs(input, ABS_MT_PRESSURE, p); | 817 | input_report_abs(input, ABS_MT_PRESSURE, p); |
885 | input_report_abs(input, ABS_MT_POSITION_X, x); | 818 | input_report_abs(input, ABS_MT_POSITION_X, x); |
886 | input_report_abs(input, ABS_MT_POSITION_Y, y); | 819 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
887 | if (wacom->id[i] < 0) | ||
888 | wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID; | ||
889 | if (!count++) | ||
890 | sp = p, sx = x, sy = y; | ||
891 | } else { | ||
892 | wacom->id[i] = -1; | ||
893 | } | 820 | } |
894 | input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]); | ||
895 | } | 821 | } |
896 | 822 | ||
897 | input_report_key(input, BTN_TOUCH, count > 0); | 823 | input_mt_report_pointer_emulation(input, true); |
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 | 824 | ||
905 | input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); | 825 | input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); |
906 | input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); | 826 | input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); |
@@ -1088,7 +1008,7 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
1088 | { | 1008 | { |
1089 | 1009 | ||
1090 | /* touch device found but size is not defined. use default */ | 1010 | /* touch device found but size is not defined. use default */ |
1091 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | 1011 | if (features->device_type == BTN_TOOL_FINGER && !features->x_max) { |
1092 | features->x_max = 1023; | 1012 | features->x_max = 1023; |
1093 | features->y_max = 1023; | 1013 | features->y_max = 1023; |
1094 | } | 1014 | } |
@@ -1100,7 +1020,7 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
1100 | 1020 | ||
1101 | /* quirks for bamboo touch */ | 1021 | /* quirks for bamboo touch */ |
1102 | if (features->type == BAMBOO_PT && | 1022 | if (features->type == BAMBOO_PT && |
1103 | features->device_type == BTN_TOOL_TRIPLETAP) { | 1023 | features->device_type == BTN_TOOL_DOUBLETAP) { |
1104 | features->x_max <<= 5; | 1024 | features->x_max <<= 5; |
1105 | features->y_max <<= 5; | 1025 | features->y_max <<= 5; |
1106 | features->x_fuzz <<= 5; | 1026 | features->x_fuzz <<= 5; |
@@ -1111,6 +1031,13 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
1111 | } | 1031 | } |
1112 | } | 1032 | } |
1113 | 1033 | ||
1034 | static unsigned int wacom_calculate_touch_res(unsigned int logical_max, | ||
1035 | unsigned int physical_max) | ||
1036 | { | ||
1037 | /* Touch physical dimensions are in 100th of mm */ | ||
1038 | return (logical_max * 100) / physical_max; | ||
1039 | } | ||
1040 | |||
1114 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 1041 | void wacom_setup_input_capabilities(struct input_dev *input_dev, |
1115 | struct wacom_wac *wacom_wac) | 1042 | struct wacom_wac *wacom_wac) |
1116 | { | 1043 | { |
@@ -1229,23 +1156,30 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1229 | break; | 1156 | break; |
1230 | 1157 | ||
1231 | case TABLETPC2FG: | 1158 | case TABLETPC2FG: |
1232 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | 1159 | if (features->device_type == BTN_TOOL_DOUBLETAP) { |
1233 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 1160 | |
1234 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | 1161 | input_mt_init_slots(input_dev, 2); |
1162 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, | ||
1163 | 0, MT_TOOL_MAX, 0, 0); | ||
1164 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1165 | 0, features->x_max, 0, 0); | ||
1166 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1167 | 0, features->y_max, 0, 0); | ||
1235 | } | 1168 | } |
1236 | /* fall through */ | 1169 | /* fall through */ |
1237 | 1170 | ||
1238 | case TABLETPC: | 1171 | case TABLETPC: |
1239 | if (features->device_type == BTN_TOOL_DOUBLETAP || | 1172 | __clear_bit(ABS_MISC, input_dev->absbit); |
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 | 1173 | ||
1246 | if (features->device_type != BTN_TOOL_PEN) | 1174 | if (features->device_type != BTN_TOOL_PEN) { |
1175 | input_abs_set_res(input_dev, ABS_X, | ||
1176 | wacom_calculate_touch_res(features->x_max, | ||
1177 | features->x_phy)); | ||
1178 | input_abs_set_res(input_dev, ABS_Y, | ||
1179 | wacom_calculate_touch_res(features->y_max, | ||
1180 | features->y_phy)); | ||
1247 | break; /* no need to process stylus stuff */ | 1181 | break; /* no need to process stylus stuff */ |
1248 | 1182 | } | |
1249 | /* fall through */ | 1183 | /* fall through */ |
1250 | 1184 | ||
1251 | case PL: | 1185 | case PL: |
@@ -1263,7 +1197,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1263 | case BAMBOO_PT: | 1197 | case BAMBOO_PT: |
1264 | __clear_bit(ABS_MISC, input_dev->absbit); | 1198 | __clear_bit(ABS_MISC, input_dev->absbit); |
1265 | 1199 | ||
1266 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | 1200 | if (features->device_type == BTN_TOOL_DOUBLETAP) { |
1267 | __set_bit(BTN_LEFT, input_dev->keybit); | 1201 | __set_bit(BTN_LEFT, input_dev->keybit); |
1268 | __set_bit(BTN_FORWARD, input_dev->keybit); | 1202 | __set_bit(BTN_FORWARD, input_dev->keybit); |
1269 | __set_bit(BTN_BACK, input_dev->keybit); | 1203 | __set_bit(BTN_BACK, input_dev->keybit); |
@@ -1272,7 +1206,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1272 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 1206 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
1273 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | 1207 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); |
1274 | 1208 | ||
1275 | input_mt_create_slots(input_dev, 2); | 1209 | input_mt_init_slots(input_dev, 2); |
1276 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1210 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
1277 | 0, features->x_max, | 1211 | 0, features->x_max, |
1278 | features->x_fuzz, 0); | 1212 | features->x_fuzz, 0); |
@@ -1282,8 +1216,12 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1282 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | 1216 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, |
1283 | 0, features->pressure_max, | 1217 | 0, features->pressure_max, |
1284 | features->pressure_fuzz, 0); | 1218 | features->pressure_fuzz, 0); |
1285 | input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, | 1219 | input_abs_set_res(input_dev, ABS_X, |
1286 | MAX_TRACKING_ID, 0, 0); | 1220 | wacom_calculate_touch_res(features->x_max, |
1221 | features->x_phy)); | ||
1222 | input_abs_set_res(input_dev, ABS_Y, | ||
1223 | wacom_calculate_touch_res(features->y_max, | ||
1224 | features->y_phy)); | ||
1287 | } else if (features->device_type == BTN_TOOL_PEN) { | 1225 | } else if (features->device_type == BTN_TOOL_PEN) { |
1288 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | 1226 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
1289 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | 1227 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); |
@@ -1438,17 +1376,27 @@ static struct wacom_features wacom_features_0xD3 = | |||
1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1376 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
1439 | static const struct wacom_features wacom_features_0xD4 = | 1377 | static const struct wacom_features wacom_features_0xD4 = |
1440 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT }; | 1378 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT }; |
1379 | static struct wacom_features wacom_features_0xD6 = | ||
1380 | { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1381 | static struct wacom_features wacom_features_0xD7 = | ||
1382 | { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1441 | static struct wacom_features wacom_features_0xD8 = | 1383 | static struct wacom_features wacom_features_0xD8 = |
1442 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1384 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
1443 | static struct wacom_features wacom_features_0xDA = | 1385 | static struct wacom_features wacom_features_0xDA = |
1444 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | 1386 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; |
1445 | static struct wacom_features wacom_features_0xDB = | 1387 | static struct wacom_features wacom_features_0xDB = |
1446 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1388 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
1389 | static const struct wacom_features wacom_features_0x6004 = | ||
1390 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, 0, TABLETPC }; | ||
1447 | 1391 | ||
1448 | #define USB_DEVICE_WACOM(prod) \ | 1392 | #define USB_DEVICE_WACOM(prod) \ |
1449 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | 1393 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ |
1450 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | 1394 | .driver_info = (kernel_ulong_t)&wacom_features_##prod |
1451 | 1395 | ||
1396 | #define USB_DEVICE_LENOVO(prod) \ | ||
1397 | USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ | ||
1398 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | ||
1399 | |||
1452 | const struct usb_device_id wacom_ids[] = { | 1400 | const struct usb_device_id wacom_ids[] = { |
1453 | { USB_DEVICE_WACOM(0x00) }, | 1401 | { USB_DEVICE_WACOM(0x00) }, |
1454 | { USB_DEVICE_WACOM(0x10) }, | 1402 | { USB_DEVICE_WACOM(0x10) }, |
@@ -1513,6 +1461,8 @@ const struct usb_device_id wacom_ids[] = { | |||
1513 | { USB_DEVICE_WACOM(0xD2) }, | 1461 | { USB_DEVICE_WACOM(0xD2) }, |
1514 | { USB_DEVICE_WACOM(0xD3) }, | 1462 | { USB_DEVICE_WACOM(0xD3) }, |
1515 | { USB_DEVICE_WACOM(0xD4) }, | 1463 | { USB_DEVICE_WACOM(0xD4) }, |
1464 | { USB_DEVICE_WACOM(0xD6) }, | ||
1465 | { USB_DEVICE_WACOM(0xD7) }, | ||
1516 | { USB_DEVICE_WACOM(0xD8) }, | 1466 | { USB_DEVICE_WACOM(0xD8) }, |
1517 | { USB_DEVICE_WACOM(0xDA) }, | 1467 | { USB_DEVICE_WACOM(0xDA) }, |
1518 | { USB_DEVICE_WACOM(0xDB) }, | 1468 | { USB_DEVICE_WACOM(0xDB) }, |
@@ -1525,6 +1475,7 @@ const struct usb_device_id wacom_ids[] = { | |||
1525 | { USB_DEVICE_WACOM(0xE2) }, | 1475 | { USB_DEVICE_WACOM(0xE2) }, |
1526 | { USB_DEVICE_WACOM(0xE3) }, | 1476 | { USB_DEVICE_WACOM(0xE3) }, |
1527 | { USB_DEVICE_WACOM(0x47) }, | 1477 | { USB_DEVICE_WACOM(0x47) }, |
1478 | { USB_DEVICE_LENOVO(0x6004) }, | ||
1528 | { } | 1479 | { } |
1529 | }; | 1480 | }; |
1530 | MODULE_DEVICE_TABLE(usb, wacom_ids); | 1481 | MODULE_DEVICE_TABLE(usb, wacom_ids); |