diff options
author | Ping Cheng <pinglinux@gmail.com> | 2012-04-30 00:09:18 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-04-30 00:13:53 -0400 |
commit | 1963518b9b1b8019d33b4b08deee6f873ffa2730 (patch) | |
tree | 5bcdd926950a9b75799232f7f5b6dd3d95905a7f /drivers/input/tablet/wacom_wac.c | |
parent | f393ee2b814e3291c12565000210b3cf10aa5c1d (diff) |
Input: wacom - add 0xE5 (MT device) support
Main part of patch is adding support for a new Wacom MT touch
packet and labels these devices using MTSCREEN type.
Other items of interest:
Delete some duplicate code in HID parsing for Y info since
its already done in X path.
In wacom_query_tablet_data(), only invoke the set report
that requests tablets to send Wacom Touch packets for
Finger interfaces. Mostly, this is to make code intent clear.
Tested-by: Jason Gerecke <killertofu@gmail.com>
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/tablet/wacom_wac.c')
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 99 |
1 files changed, 94 insertions, 5 deletions
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index e5cd0e57d178..10e5cf870359 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -768,6 +768,72 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
768 | return 1; | 768 | return 1; |
769 | } | 769 | } |
770 | 770 | ||
771 | static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid) | ||
772 | { | ||
773 | int touch_max = wacom->features.touch_max; | ||
774 | int i; | ||
775 | |||
776 | if (!wacom->slots) | ||
777 | return -1; | ||
778 | |||
779 | for (i = 0; i < touch_max; ++i) { | ||
780 | if (wacom->slots[i] == contactid) | ||
781 | return i; | ||
782 | } | ||
783 | for (i = 0; i < touch_max; ++i) { | ||
784 | if (wacom->slots[i] == -1) | ||
785 | return i; | ||
786 | } | ||
787 | return -1; | ||
788 | } | ||
789 | |||
790 | static int wacom_mt_touch(struct wacom_wac *wacom) | ||
791 | { | ||
792 | struct input_dev *input = wacom->input; | ||
793 | char *data = wacom->data; | ||
794 | int i; | ||
795 | int current_num_contacts = data[2]; | ||
796 | int contacts_to_send = 0; | ||
797 | |||
798 | /* | ||
799 | * First packet resets the counter since only the first | ||
800 | * packet in series will have non-zero current_num_contacts. | ||
801 | */ | ||
802 | if (current_num_contacts) | ||
803 | wacom->num_contacts_left = current_num_contacts; | ||
804 | |||
805 | /* There are at most 5 contacts per packet */ | ||
806 | contacts_to_send = min(5, wacom->num_contacts_left); | ||
807 | |||
808 | for (i = 0; i < contacts_to_send; i++) { | ||
809 | int offset = (WACOM_BYTES_PER_MT_PACKET * i) + 3; | ||
810 | bool touch = data[offset] & 0x1; | ||
811 | int id = le16_to_cpup((__le16 *)&data[offset + 1]); | ||
812 | int slot = find_slot_from_contactid(wacom, id); | ||
813 | |||
814 | if (slot < 0) | ||
815 | continue; | ||
816 | |||
817 | input_mt_slot(input, slot); | ||
818 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | ||
819 | if (touch) { | ||
820 | int x = le16_to_cpup((__le16 *)&data[offset + 7]); | ||
821 | int y = le16_to_cpup((__le16 *)&data[offset + 9]); | ||
822 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
823 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
824 | } | ||
825 | wacom->slots[slot] = touch ? id : -1; | ||
826 | } | ||
827 | |||
828 | input_mt_report_pointer_emulation(input, true); | ||
829 | |||
830 | wacom->num_contacts_left -= contacts_to_send; | ||
831 | if (wacom->num_contacts_left < 0) | ||
832 | wacom->num_contacts_left = 0; | ||
833 | |||
834 | return 1; | ||
835 | } | ||
836 | |||
771 | static int wacom_tpc_mt_touch(struct wacom_wac *wacom) | 837 | static int wacom_tpc_mt_touch(struct wacom_wac *wacom) |
772 | { | 838 | { |
773 | struct input_dev *input = wacom->input; | 839 | struct input_dev *input = wacom->input; |
@@ -806,6 +872,9 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) | |||
806 | bool prox; | 872 | bool prox; |
807 | int x = 0, y = 0; | 873 | int x = 0, y = 0; |
808 | 874 | ||
875 | if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG) | ||
876 | return 0; | ||
877 | |||
809 | if (!wacom->shared->stylus_in_proximity) { | 878 | if (!wacom->shared->stylus_in_proximity) { |
810 | if (len == WACOM_PKGLEN_TPC1FG) { | 879 | if (len == WACOM_PKGLEN_TPC1FG) { |
811 | prox = data[0] & 0x01; | 880 | prox = data[0] & 0x01; |
@@ -873,10 +942,10 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
873 | 942 | ||
874 | switch (len) { | 943 | switch (len) { |
875 | case WACOM_PKGLEN_TPC1FG: | 944 | case WACOM_PKGLEN_TPC1FG: |
876 | return wacom_tpc_single_touch(wacom, len); | 945 | return wacom_tpc_single_touch(wacom, len); |
877 | 946 | ||
878 | case WACOM_PKGLEN_TPC2FG: | 947 | case WACOM_PKGLEN_TPC2FG: |
879 | return wacom_tpc_mt_touch(wacom); | 948 | return wacom_tpc_mt_touch(wacom); |
880 | 949 | ||
881 | default: | 950 | default: |
882 | switch (data[0]) { | 951 | switch (data[0]) { |
@@ -885,6 +954,9 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
885 | case WACOM_REPORT_TPCST: | 954 | case WACOM_REPORT_TPCST: |
886 | return wacom_tpc_single_touch(wacom, len); | 955 | return wacom_tpc_single_touch(wacom, len); |
887 | 956 | ||
957 | case WACOM_REPORT_TPCMT: | ||
958 | return wacom_mt_touch(wacom); | ||
959 | |||
888 | case WACOM_REPORT_PENABLED: | 960 | case WACOM_REPORT_PENABLED: |
889 | return wacom_tpc_pen(wacom); | 961 | return wacom_tpc_pen(wacom); |
890 | } | 962 | } |
@@ -1164,6 +1236,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1164 | 1236 | ||
1165 | case TABLETPC: | 1237 | case TABLETPC: |
1166 | case TABLETPC2FG: | 1238 | case TABLETPC2FG: |
1239 | case MTSCREEN: | ||
1167 | sync = wacom_tpc_irq(wacom_wac, len); | 1240 | sync = wacom_tpc_irq(wacom_wac, len); |
1168 | break; | 1241 | break; |
1169 | 1242 | ||
@@ -1237,7 +1310,8 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
1237 | /* these device have multiple inputs */ | 1310 | /* these device have multiple inputs */ |
1238 | if (features->type == TABLETPC || features->type == TABLETPC2FG || | 1311 | if (features->type == TABLETPC || features->type == TABLETPC2FG || |
1239 | features->type == BAMBOO_PT || features->type == WIRELESS || | 1312 | features->type == BAMBOO_PT || features->type == WIRELESS || |
1240 | (features->type >= INTUOS5S && features->type <= INTUOS5L)) | 1313 | (features->type >= INTUOS5S && features->type <= INTUOS5L) || |
1314 | features->type == MTSCREEN) | ||
1241 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; | 1315 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; |
1242 | 1316 | ||
1243 | /* quirk for bamboo touch with 2 low res touches */ | 1317 | /* quirk for bamboo touch with 2 low res touches */ |
@@ -1268,8 +1342,8 @@ static unsigned int wacom_calculate_touch_res(unsigned int logical_max, | |||
1268 | return (logical_max * 100) / physical_max; | 1342 | return (logical_max * 100) / physical_max; |
1269 | } | 1343 | } |
1270 | 1344 | ||
1271 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 1345 | int wacom_setup_input_capabilities(struct input_dev *input_dev, |
1272 | struct wacom_wac *wacom_wac) | 1346 | struct wacom_wac *wacom_wac) |
1273 | { | 1347 | { |
1274 | struct wacom_features *features = &wacom_wac->features; | 1348 | struct wacom_features *features = &wacom_wac->features; |
1275 | int i; | 1349 | int i; |
@@ -1465,8 +1539,18 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1465 | break; | 1539 | break; |
1466 | 1540 | ||
1467 | case TABLETPC2FG: | 1541 | case TABLETPC2FG: |
1542 | case MTSCREEN: | ||
1468 | if (features->device_type == BTN_TOOL_FINGER) { | 1543 | if (features->device_type == BTN_TOOL_FINGER) { |
1469 | 1544 | ||
1545 | wacom_wac->slots = kmalloc(features->touch_max * | ||
1546 | sizeof(int), | ||
1547 | GFP_KERNEL); | ||
1548 | if (!wacom_wac->slots) | ||
1549 | return -ENOMEM; | ||
1550 | |||
1551 | for (i = 0; i < features->touch_max; i++) | ||
1552 | wacom_wac->slots[i] = -1; | ||
1553 | |||
1470 | input_mt_init_slots(input_dev, features->touch_max); | 1554 | input_mt_init_slots(input_dev, features->touch_max); |
1471 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, | 1555 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, |
1472 | 0, MT_TOOL_MAX, 0, 0); | 1556 | 0, MT_TOOL_MAX, 0, 0); |
@@ -1552,6 +1636,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1552 | } | 1636 | } |
1553 | break; | 1637 | break; |
1554 | } | 1638 | } |
1639 | return 0; | ||
1555 | } | 1640 | } |
1556 | 1641 | ||
1557 | static const struct wacom_features wacom_features_0x00 = | 1642 | static const struct wacom_features wacom_features_0x00 = |
@@ -1784,6 +1869,9 @@ static const struct wacom_features wacom_features_0xE3 = | |||
1784 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, | 1869 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, |
1785 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | 1870 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1786 | .touch_max = 2 }; | 1871 | .touch_max = 2 }; |
1872 | static const struct wacom_features wacom_features_0xE5 = | ||
1873 | { "Wacom ISDv4 E5", WACOM_PKGLEN_MTOUCH, 26202, 16325, 255, | ||
1874 | 0, MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1787 | static const struct wacom_features wacom_features_0xE6 = | 1875 | static const struct wacom_features wacom_features_0xE6 = |
1788 | { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, | 1876 | { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, |
1789 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | 1877 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
@@ -1962,6 +2050,7 @@ const struct usb_device_id wacom_ids[] = { | |||
1962 | { USB_DEVICE_WACOM(0x9F) }, | 2050 | { USB_DEVICE_WACOM(0x9F) }, |
1963 | { USB_DEVICE_WACOM(0xE2) }, | 2051 | { USB_DEVICE_WACOM(0xE2) }, |
1964 | { USB_DEVICE_WACOM(0xE3) }, | 2052 | { USB_DEVICE_WACOM(0xE3) }, |
2053 | { USB_DEVICE_WACOM(0xE5) }, | ||
1965 | { USB_DEVICE_WACOM(0xE6) }, | 2054 | { USB_DEVICE_WACOM(0xE6) }, |
1966 | { USB_DEVICE_WACOM(0xEC) }, | 2055 | { USB_DEVICE_WACOM(0xEC) }, |
1967 | { USB_DEVICE_WACOM(0x47) }, | 2056 | { USB_DEVICE_WACOM(0x47) }, |