diff options
| -rw-r--r-- | drivers/hid/wacom_wac.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 0c4eb31c1c71..a48ed4ebd5a9 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
| @@ -34,6 +34,10 @@ | |||
| 34 | */ | 34 | */ |
| 35 | #define WACOM_CONTACT_AREA_SCALE 2607 | 35 | #define WACOM_CONTACT_AREA_SCALE 2607 |
| 36 | 36 | ||
| 37 | static bool touch_arbitration = 1; | ||
| 38 | module_param(touch_arbitration, bool, 0644); | ||
| 39 | MODULE_PARM_DESC(touch_arbitration, " on (Y) off (N)"); | ||
| 40 | |||
| 37 | static void wacom_report_numbered_buttons(struct input_dev *input_dev, | 41 | static void wacom_report_numbered_buttons(struct input_dev *input_dev, |
| 38 | int button_count, int mask); | 42 | int button_count, int mask); |
| 39 | 43 | ||
| @@ -882,6 +886,16 @@ static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) | |||
| 882 | wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE); | 886 | wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE); |
| 883 | } | 887 | } |
| 884 | 888 | ||
| 889 | static inline bool report_touch_events(struct wacom_wac *wacom) | ||
| 890 | { | ||
| 891 | return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1); | ||
| 892 | } | ||
| 893 | |||
| 894 | static inline bool delay_pen_events(struct wacom_wac *wacom) | ||
| 895 | { | ||
| 896 | return (wacom->shared->touch_down && touch_arbitration); | ||
| 897 | } | ||
| 898 | |||
| 885 | static int wacom_intuos_general(struct wacom_wac *wacom) | 899 | static int wacom_intuos_general(struct wacom_wac *wacom) |
| 886 | { | 900 | { |
| 887 | struct wacom_features *features = &wacom->features; | 901 | struct wacom_features *features = &wacom->features; |
| @@ -895,7 +909,7 @@ static int wacom_intuos_general(struct wacom_wac *wacom) | |||
| 895 | data[0] != WACOM_REPORT_INTUOS_PEN) | 909 | data[0] != WACOM_REPORT_INTUOS_PEN) |
| 896 | return 0; | 910 | return 0; |
| 897 | 911 | ||
| 898 | if (wacom->shared->touch_down) | 912 | if (delay_pen_events(wacom)) |
| 899 | return 1; | 913 | return 1; |
| 900 | 914 | ||
| 901 | /* don't report events if we don't know the tool ID */ | 915 | /* don't report events if we don't know the tool ID */ |
| @@ -1155,7 +1169,7 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom) | |||
| 1155 | 1169 | ||
| 1156 | if (touch_max == 1) | 1170 | if (touch_max == 1) |
| 1157 | return test_bit(BTN_TOUCH, input->key) && | 1171 | return test_bit(BTN_TOUCH, input->key) && |
| 1158 | !wacom->shared->stylus_in_proximity; | 1172 | report_touch_events(wacom); |
| 1159 | 1173 | ||
| 1160 | for (i = 0; i < input->mt->num_slots; i++) { | 1174 | for (i = 0; i < input->mt->num_slots; i++) { |
| 1161 | struct input_mt_slot *ps = &input->mt->slots[i]; | 1175 | struct input_mt_slot *ps = &input->mt->slots[i]; |
| @@ -1196,7 +1210,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
| 1196 | 1210 | ||
| 1197 | for (i = 0; i < contacts_to_send; i++) { | 1211 | for (i = 0; i < contacts_to_send; i++) { |
| 1198 | int offset = (byte_per_packet * i) + 1; | 1212 | int offset = (byte_per_packet * i) + 1; |
| 1199 | bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity; | 1213 | bool touch = (data[offset] & 0x1) && report_touch_events(wacom); |
| 1200 | int slot = input_mt_get_slot_by_key(input, data[offset + 1]); | 1214 | int slot = input_mt_get_slot_by_key(input, data[offset + 1]); |
| 1201 | 1215 | ||
| 1202 | if (slot < 0) | 1216 | if (slot < 0) |
| @@ -1260,7 +1274,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) | |||
| 1260 | 1274 | ||
| 1261 | for (i = 0; i < contacts_to_send; i++) { | 1275 | for (i = 0; i < contacts_to_send; i++) { |
| 1262 | int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; | 1276 | int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; |
| 1263 | bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity; | 1277 | bool touch = (data[offset] & 0x1) && report_touch_events(wacom); |
| 1264 | int id = get_unaligned_le16(&data[offset + 1]); | 1278 | int id = get_unaligned_le16(&data[offset + 1]); |
| 1265 | int slot = input_mt_get_slot_by_key(input, id); | 1279 | int slot = input_mt_get_slot_by_key(input, id); |
| 1266 | 1280 | ||
| @@ -1294,7 +1308,7 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom) | |||
| 1294 | 1308 | ||
| 1295 | for (i = 0; i < 2; i++) { | 1309 | for (i = 0; i < 2; i++) { |
| 1296 | int p = data[1] & (1 << i); | 1310 | int p = data[1] & (1 << i); |
| 1297 | bool touch = p && !wacom->shared->stylus_in_proximity; | 1311 | bool touch = p && report_touch_events(wacom); |
| 1298 | 1312 | ||
| 1299 | input_mt_slot(input, i); | 1313 | input_mt_slot(input, i); |
| 1300 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | 1314 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
| @@ -1318,7 +1332,7 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) | |||
| 1318 | { | 1332 | { |
| 1319 | unsigned char *data = wacom->data; | 1333 | unsigned char *data = wacom->data; |
| 1320 | struct input_dev *input = wacom->touch_input; | 1334 | struct input_dev *input = wacom->touch_input; |
| 1321 | bool prox = !wacom->shared->stylus_in_proximity; | 1335 | bool prox = report_touch_events(wacom); |
| 1322 | int x = 0, y = 0; | 1336 | int x = 0, y = 0; |
| 1323 | 1337 | ||
| 1324 | if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG) | 1338 | if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG) |
| @@ -1363,8 +1377,10 @@ static int wacom_tpc_pen(struct wacom_wac *wacom) | |||
| 1363 | /* keep pen state for touch events */ | 1377 | /* keep pen state for touch events */ |
| 1364 | wacom->shared->stylus_in_proximity = prox; | 1378 | wacom->shared->stylus_in_proximity = prox; |
| 1365 | 1379 | ||
| 1366 | /* send pen events only when touch is up or forced out */ | 1380 | /* send pen events only when touch is up or forced out |
| 1367 | if (!wacom->shared->touch_down) { | 1381 | * or touch arbitration is off |
| 1382 | */ | ||
| 1383 | if (!delay_pen_events(wacom)) { | ||
| 1368 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); | 1384 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); |
| 1369 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); | 1385 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); |
| 1370 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); | 1386 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); |
| @@ -1506,8 +1522,10 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field, | |||
| 1506 | return 0; | 1522 | return 0; |
| 1507 | } | 1523 | } |
| 1508 | 1524 | ||
| 1509 | /* send pen events only when touch is up or forced out */ | 1525 | /* send pen events only when touch is up or forced out |
| 1510 | if (!usage->type || wacom_wac->shared->touch_down) | 1526 | * or touch arbitration is off |
| 1527 | */ | ||
| 1528 | if (!usage->type || delay_pen_events(wacom_wac)) | ||
| 1511 | return 0; | 1529 | return 0; |
| 1512 | 1530 | ||
| 1513 | input_event(input, usage->type, usage->code, value); | 1531 | input_event(input, usage->type, usage->code, value); |
| @@ -1537,8 +1555,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, | |||
| 1537 | /* keep pen state for touch events */ | 1555 | /* keep pen state for touch events */ |
| 1538 | wacom_wac->shared->stylus_in_proximity = prox; | 1556 | wacom_wac->shared->stylus_in_proximity = prox; |
| 1539 | 1557 | ||
| 1540 | /* send pen events only when touch is up or forced out */ | 1558 | if (!delay_pen_events(wacom_wac)) { |
| 1541 | if (!wacom_wac->shared->touch_down) { | ||
| 1542 | input_report_key(input, BTN_TOUCH, | 1559 | input_report_key(input, BTN_TOUCH, |
| 1543 | wacom_wac->hid_data.tipswitch); | 1560 | wacom_wac->hid_data.tipswitch); |
| 1544 | input_report_key(input, wacom_wac->tool[0], prox); | 1561 | input_report_key(input, wacom_wac->tool[0], prox); |
| @@ -1609,7 +1626,7 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, | |||
| 1609 | struct hid_data *hid_data = &wacom_wac->hid_data; | 1626 | struct hid_data *hid_data = &wacom_wac->hid_data; |
| 1610 | bool mt = wacom_wac->features.touch_max > 1; | 1627 | bool mt = wacom_wac->features.touch_max > 1; |
| 1611 | bool prox = hid_data->tipswitch && | 1628 | bool prox = hid_data->tipswitch && |
| 1612 | !wacom_wac->shared->stylus_in_proximity; | 1629 | report_touch_events(wacom_wac); |
| 1613 | 1630 | ||
| 1614 | wacom_wac->hid_data.num_received++; | 1631 | wacom_wac->hid_data.num_received++; |
| 1615 | if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected) | 1632 | if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected) |
| @@ -1835,15 +1852,8 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) | |||
| 1835 | 1852 | ||
| 1836 | for (i = 0; i < 2; i++) { | 1853 | for (i = 0; i < 2; i++) { |
| 1837 | int offset = (data[1] & 0x80) ? (8 * i) : (9 * i); | 1854 | int offset = (data[1] & 0x80) ? (8 * i) : (9 * i); |
| 1838 | bool touch = data[offset + 3] & 0x80; | 1855 | bool touch = report_touch_events(wacom) |
| 1839 | 1856 | && (data[offset + 3] & 0x80); | |
| 1840 | /* | ||
| 1841 | * Touch events need to be disabled while stylus is | ||
| 1842 | * in proximity because user's hand is resting on touchpad | ||
| 1843 | * and sending unwanted events. User expects tablet buttons | ||
| 1844 | * to continue working though. | ||
| 1845 | */ | ||
| 1846 | touch = touch && !wacom->shared->stylus_in_proximity; | ||
| 1847 | 1857 | ||
| 1848 | input_mt_slot(input, i); | 1858 | input_mt_slot(input, i); |
| 1849 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | 1859 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
| @@ -1880,7 +1890,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) | |||
| 1880 | if (slot < 0) | 1890 | if (slot < 0) |
| 1881 | return; | 1891 | return; |
| 1882 | 1892 | ||
| 1883 | touch = touch && !wacom->shared->stylus_in_proximity; | 1893 | touch = touch && report_touch_events(wacom); |
| 1884 | 1894 | ||
| 1885 | input_mt_slot(input, slot); | 1895 | input_mt_slot(input, slot); |
| 1886 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | 1896 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
| @@ -1993,7 +2003,7 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) | |||
| 1993 | } | 2003 | } |
| 1994 | 2004 | ||
| 1995 | wacom->shared->stylus_in_proximity = prox; | 2005 | wacom->shared->stylus_in_proximity = prox; |
| 1996 | if (wacom->shared->touch_down) | 2006 | if (delay_pen_events(wacom)) |
| 1997 | return 0; | 2007 | return 0; |
| 1998 | 2008 | ||
| 1999 | if (prox) { | 2009 | if (prox) { |
| @@ -2087,7 +2097,7 @@ static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom, | |||
| 2087 | 2097 | ||
| 2088 | for (id = 0; id < wacom->features.touch_max; id++) { | 2098 | for (id = 0; id < wacom->features.touch_max; id++) { |
| 2089 | valid = !!(prefix & BIT(id)) && | 2099 | valid = !!(prefix & BIT(id)) && |
| 2090 | !wacom->shared->stylus_in_proximity; | 2100 | report_touch_events(wacom); |
| 2091 | 2101 | ||
| 2092 | input_mt_slot(input, id); | 2102 | input_mt_slot(input, id); |
| 2093 | input_mt_report_slot_state(input, MT_TOOL_FINGER, valid); | 2103 | input_mt_report_slot_state(input, MT_TOOL_FINGER, valid); |
| @@ -2109,8 +2119,7 @@ static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom, | |||
| 2109 | input_report_key(input, BTN_RIGHT, prefix & 0x80); | 2119 | input_report_key(input, BTN_RIGHT, prefix & 0x80); |
| 2110 | 2120 | ||
| 2111 | /* keep touch state for pen event */ | 2121 | /* keep touch state for pen event */ |
| 2112 | wacom->shared->touch_down = !!prefix && | 2122 | wacom->shared->touch_down = !!prefix && report_touch_events(wacom); |
| 2113 | !wacom->shared->stylus_in_proximity; | ||
| 2114 | 2123 | ||
| 2115 | return 1; | 2124 | return 1; |
| 2116 | } | 2125 | } |
