aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet/wacom_wac.c
diff options
context:
space:
mode:
authorPing Cheng <pinglinux@gmail.com>2012-04-30 00:09:18 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-04-30 00:13:53 -0400
commit1963518b9b1b8019d33b4b08deee6f873ffa2730 (patch)
tree5bcdd926950a9b75799232f7f5b6dd3d95905a7f /drivers/input/tablet/wacom_wac.c
parentf393ee2b814e3291c12565000210b3cf10aa5c1d (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.c99
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
771static 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
790static 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
771static int wacom_tpc_mt_touch(struct wacom_wac *wacom) 837static 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
1271void wacom_setup_input_capabilities(struct input_dev *input_dev, 1345int 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
1557static const struct wacom_features wacom_features_0x00 = 1642static 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 };
1872static 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 };
1787static const struct wacom_features wacom_features_0xE6 = 1875static 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) },