aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorPing Cheng <pinglinux@gmail.com>2016-08-09 17:38:56 -0400
committerJiri Kosina <jkosina@suse.cz>2016-08-10 05:46:26 -0400
commit1924e05e6014917b23b7648302be39cfee03d047 (patch)
tree335613add6126745c44112ccf81a13b5c11ec436 /drivers/hid
parent41372d5d40e73ef4d8574e53a39c7faabff20260 (diff)
HID: wacom - add touch_arbitration parameter to wacom module
Touch arbitration is always on in wacom.ko. However, there are touch enabled applications use both pen and touch simultaneously. We should provide an option for userland to decide if they want arbitration on or off. This patch sets default touch_arbitration to on since most userland apps are not ready to process pen and touch events simultaneously. In the future, when userland is ready to accept pen and touch events together, we will switch default touch_arbitration to off. Tested-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Ping Cheng <pingc@wacom.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/wacom_wac.c63
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
37static bool touch_arbitration = 1;
38module_param(touch_arbitration, bool, 0644);
39MODULE_PARM_DESC(touch_arbitration, " on (Y) off (N)");
40
37static void wacom_report_numbered_buttons(struct input_dev *input_dev, 41static 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
889static inline bool report_touch_events(struct wacom_wac *wacom)
890{
891 return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1);
892}
893
894static inline bool delay_pen_events(struct wacom_wac *wacom)
895{
896 return (wacom->shared->touch_down && touch_arbitration);
897}
898
885static int wacom_intuos_general(struct wacom_wac *wacom) 899static 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}