aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet
diff options
context:
space:
mode:
authorJason Gerecke <killertofu@gmail.com>2012-10-21 03:38:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-25 19:02:36 -0400
commitb1e4279e4ef5549bf6ebf8f6f17dd26f0af8e8a2 (patch)
treed3bcb7957ca8c37bdf579738f0431ce3635b7783 /drivers/input/tablet
parentaea2bf6a57a9e4596bfad164f986ba10ddc6adf3 (diff)
Input: wacom - add touch sensor support for Cintiq 24HD touch
Decode multitouch reports from the touch sensor of the Cintiq 24HD touch. Signed-off-by: Jason Gerecke <killertofu@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/input/tablet')
-rw-r--r--drivers/input/tablet/wacom_sys.c19
-rw-r--r--drivers/input/tablet/wacom_wac.c85
-rw-r--r--drivers/input/tablet/wacom_wac.h3
3 files changed, 104 insertions, 3 deletions
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 8b89e15bcf32..2c1e12bf2ab4 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
391 features->pktlen = WACOM_PKGLEN_TPC2FG; 391 features->pktlen = WACOM_PKGLEN_TPC2FG;
392 } 392 }
393 393
394 if (features->type == MTSCREEN) 394 if (features->type == MTSCREEN || WACOM_24HDT)
395 features->pktlen = WACOM_PKGLEN_MTOUCH; 395 features->pktlen = WACOM_PKGLEN_MTOUCH;
396 396
397 if (features->type == BAMBOO_PT) { 397 if (features->type == BAMBOO_PT) {
@@ -402,6 +402,14 @@ static int wacom_parse_hid(struct usb_interface *intf,
402 features->x_max = 402 features->x_max =
403 get_unaligned_le16(&report[i + 8]); 403 get_unaligned_le16(&report[i + 8]);
404 i += 15; 404 i += 15;
405 } else if (features->type == WACOM_24HDT) {
406 features->x_max =
407 get_unaligned_le16(&report[i + 3]);
408 features->x_phy =
409 get_unaligned_le16(&report[i + 8]);
410 features->unit = report[i - 1];
411 features->unitExpo = report[i - 3];
412 i += 12;
405 } else { 413 } else {
406 features->x_max = 414 features->x_max =
407 get_unaligned_le16(&report[i + 3]); 415 get_unaligned_le16(&report[i + 3]);
@@ -434,6 +442,12 @@ static int wacom_parse_hid(struct usb_interface *intf,
434 features->y_phy = 442 features->y_phy =
435 get_unaligned_le16(&report[i + 6]); 443 get_unaligned_le16(&report[i + 6]);
436 i += 7; 444 i += 7;
445 } else if (type == WACOM_24HDT) {
446 features->y_max =
447 get_unaligned_le16(&report[i + 3]);
448 features->y_phy =
449 get_unaligned_le16(&report[i - 2]);
450 i += 7;
437 } else if (type == BAMBOO_PT) { 451 } else if (type == BAMBOO_PT) {
438 features->y_phy = 452 features->y_phy =
439 get_unaligned_le16(&report[i + 3]); 453 get_unaligned_le16(&report[i + 3]);
@@ -541,6 +555,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
541 /* MT Tablet PC touch */ 555 /* MT Tablet PC touch */
542 return wacom_set_device_mode(intf, 3, 4, 4); 556 return wacom_set_device_mode(intf, 3, 4, 4);
543 } 557 }
558 else if (features->type == WACOM_24HDT) {
559 return wacom_set_device_mode(intf, 18, 3, 2);
560 }
544 } else if (features->device_type == BTN_TOOL_PEN) { 561 } else if (features->device_type == BTN_TOOL_PEN) {
545 if (features->type <= BAMBOO_PT && features->type != WIRELESS) { 562 if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
546 return wacom_set_device_mode(intf, 2, 2, 2); 563 return wacom_set_device_mode(intf, 2, 2, 2);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 21d1f4eaff53..aa6010131179 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -806,6 +806,70 @@ static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid)
806 return -1; 806 return -1;
807} 807}
808 808
809static int int_dist(int x1, int y1, int x2, int y2)
810{
811 int x = x2 - x1;
812 int y = y2 - y1;
813
814 return int_sqrt(x*x + y*y);
815}
816
817static int wacom_24hdt_irq(struct wacom_wac *wacom)
818{
819 struct input_dev *input = wacom->input;
820 char *data = wacom->data;
821 int i;
822 int current_num_contacts = data[61];
823 int contacts_to_send = 0;
824
825 /*
826 * First packet resets the counter since only the first
827 * packet in series will have non-zero current_num_contacts.
828 */
829 if (current_num_contacts)
830 wacom->num_contacts_left = current_num_contacts;
831
832 /* There are at most 4 contacts per packet */
833 contacts_to_send = min(4, wacom->num_contacts_left);
834
835 for (i = 0; i < contacts_to_send; i++) {
836 int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1;
837 bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity;
838 int id = data[offset + 1];
839 int slot = find_slot_from_contactid(wacom, id);
840
841 if (slot < 0)
842 continue;
843 input_mt_slot(input, slot);
844 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
845
846 if (touch) {
847 int t_x = le16_to_cpup((__le16 *)&data[offset + 2]);
848 int c_x = le16_to_cpup((__le16 *)&data[offset + 4]);
849 int t_y = le16_to_cpup((__le16 *)&data[offset + 6]);
850 int c_y = le16_to_cpup((__le16 *)&data[offset + 8]);
851 int w = le16_to_cpup((__le16 *)&data[offset + 10]);
852 int h = le16_to_cpup((__le16 *)&data[offset + 12]);
853
854 input_report_abs(input, ABS_MT_POSITION_X, t_x);
855 input_report_abs(input, ABS_MT_POSITION_Y, t_y);
856 input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));
857 input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y));
858 input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
859 input_report_abs(input, ABS_MT_ORIENTATION, w > h);
860 }
861 wacom->slots[slot] = touch ? id : -1;
862 }
863
864 input_mt_report_pointer_emulation(input, true);
865
866 wacom->num_contacts_left -= contacts_to_send;
867 if (wacom->num_contacts_left <= 0)
868 wacom->num_contacts_left = 0;
869
870 return 1;
871}
872
809static int wacom_mt_touch(struct wacom_wac *wacom) 873static int wacom_mt_touch(struct wacom_wac *wacom)
810{ 874{
811 struct input_dev *input = wacom->input; 875 struct input_dev *input = wacom->input;
@@ -1255,6 +1319,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
1255 sync = wacom_intuos_irq(wacom_wac); 1319 sync = wacom_intuos_irq(wacom_wac);
1256 break; 1320 break;
1257 1321
1322 case WACOM_24HDT:
1323 sync = wacom_24hdt_irq(wacom_wac);
1324 break;
1325
1258 case INTUOS5S: 1326 case INTUOS5S:
1259 case INTUOS5: 1327 case INTUOS5:
1260 case INTUOS5L: 1328 case INTUOS5L:
@@ -1576,6 +1644,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
1576 __set_bit(INPUT_PROP_POINTER, input_dev->propbit); 1644 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1577 break; 1645 break;
1578 1646
1647 case WACOM_24HDT:
1648 if (features->device_type == BTN_TOOL_FINGER) {
1649 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);
1650 input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0);
1651 input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0);
1652 input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
1653 }
1654 /* fall through */
1655
1579 case MTSCREEN: 1656 case MTSCREEN:
1580 if (features->device_type == BTN_TOOL_FINGER) { 1657 if (features->device_type == BTN_TOOL_FINGER) {
1581 wacom_wac->slots = kmalloc(features->touch_max * 1658 wacom_wac->slots = kmalloc(features->touch_max *
@@ -1870,8 +1947,11 @@ static const struct wacom_features wacom_features_0xF4 =
1870 { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, 1947 { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047,
1871 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; 1948 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1872static const struct wacom_features wacom_features_0xF8 = 1949static const struct wacom_features wacom_features_0xF8 =
1873 { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, 1950 { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */
1874 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; 1951 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
1952static const struct wacom_features wacom_features_0xF6 =
1953 { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
1954 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 };
1875static const struct wacom_features wacom_features_0x3F = 1955static const struct wacom_features wacom_features_0x3F =
1876 { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 1956 { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023,
1877 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; 1957 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
@@ -2114,6 +2194,7 @@ const struct usb_device_id wacom_ids[] = {
2114 { USB_DEVICE_WACOM(0x47) }, 2194 { USB_DEVICE_WACOM(0x47) },
2115 { USB_DEVICE_WACOM(0xF4) }, 2195 { USB_DEVICE_WACOM(0xF4) },
2116 { USB_DEVICE_WACOM(0xF8) }, 2196 { USB_DEVICE_WACOM(0xF8) },
2197 { USB_DEVICE_WACOM(0xF6) },
2117 { USB_DEVICE_WACOM(0xFA) }, 2198 { USB_DEVICE_WACOM(0xFA) },
2118 { USB_DEVICE_LENOVO(0x6004) }, 2199 { USB_DEVICE_LENOVO(0x6004) },
2119 { } 2200 { }
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 3f926ec19ef9..345f1e76975e 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -29,6 +29,7 @@
29 29
30/* wacom data size per MT contact */ 30/* wacom data size per MT contact */
31#define WACOM_BYTES_PER_MT_PACKET 11 31#define WACOM_BYTES_PER_MT_PACKET 11
32#define WACOM_BYTES_PER_24HDT_PACKET 14
32 33
33/* device IDs */ 34/* device IDs */
34#define STYLUS_DEVICE_ID 0x02 35#define STYLUS_DEVICE_ID 0x02
@@ -49,6 +50,7 @@
49#define WACOM_REPORT_TPCHID 15 50#define WACOM_REPORT_TPCHID 15
50#define WACOM_REPORT_TPCST 16 51#define WACOM_REPORT_TPCST 16
51#define WACOM_REPORT_TPC1FGE 18 52#define WACOM_REPORT_TPC1FGE 18
53#define WACOM_REPORT_24HDT 1
52 54
53/* device quirks */ 55/* device quirks */
54#define WACOM_QUIRK_MULTI_INPUT 0x0001 56#define WACOM_QUIRK_MULTI_INPUT 0x0001
@@ -81,6 +83,7 @@ enum {
81 WACOM_MO, 83 WACOM_MO,
82 WIRELESS, 84 WIRELESS,
83 BAMBOO_PT, 85 BAMBOO_PT,
86 WACOM_24HDT,
84 TABLETPC, /* add new TPC below */ 87 TABLETPC, /* add new TPC below */
85 TABLETPCE, 88 TABLETPCE,
86 TABLETPC2FG, 89 TABLETPC2FG,