aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/wacom_wac.c86
-rw-r--r--drivers/hid/wacom_wac.h1
2 files changed, 59 insertions, 28 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 064fd6cf36c6..26f27bd6b95c 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1381,10 +1381,12 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
1381{ 1381{
1382 struct wacom *wacom = hid_get_drvdata(hdev); 1382 struct wacom *wacom = hid_get_drvdata(hdev);
1383 struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1383 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1384 struct wacom_features *features = &wacom_wac->features;
1384 unsigned touch_max = wacom_wac->features.touch_max; 1385 unsigned touch_max = wacom_wac->features.touch_max;
1385 1386
1386 switch (usage->hid) { 1387 switch (usage->hid) {
1387 case HID_GD_X: 1388 case HID_GD_X:
1389 features->last_slot_field = usage->hid;
1388 if (touch_max == 1) 1390 if (touch_max == 1)
1389 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); 1391 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4);
1390 else 1392 else
@@ -1392,6 +1394,7 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
1392 ABS_MT_POSITION_X, 4); 1394 ABS_MT_POSITION_X, 4);
1393 break; 1395 break;
1394 case HID_GD_Y: 1396 case HID_GD_Y:
1397 features->last_slot_field = usage->hid;
1395 if (touch_max == 1) 1398 if (touch_max == 1)
1396 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); 1399 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4);
1397 else 1400 else
@@ -1399,17 +1402,48 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
1399 ABS_MT_POSITION_Y, 4); 1402 ABS_MT_POSITION_Y, 4);
1400 break; 1403 break;
1401 case HID_DG_CONTACTID: 1404 case HID_DG_CONTACTID:
1405 features->last_slot_field = usage->hid;
1402 break; 1406 break;
1403 case HID_DG_INRANGE: 1407 case HID_DG_INRANGE:
1408 features->last_slot_field = usage->hid;
1404 break; 1409 break;
1405 case HID_DG_INVERT: 1410 case HID_DG_INVERT:
1411 features->last_slot_field = usage->hid;
1406 break; 1412 break;
1407 case HID_DG_TIPSWITCH: 1413 case HID_DG_TIPSWITCH:
1414 features->last_slot_field = usage->hid;
1408 wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); 1415 wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0);
1409 break; 1416 break;
1410 } 1417 }
1411} 1418}
1412 1419
1420static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,
1421 struct input_dev *input)
1422{
1423 struct hid_data *hid_data = &wacom_wac->hid_data;
1424 bool mt = wacom_wac->features.touch_max > 1;
1425 bool prox = hid_data->tipswitch &&
1426 !wacom_wac->shared->stylus_in_proximity;
1427
1428 if (mt) {
1429 int slot;
1430
1431 slot = input_mt_get_slot_by_key(input, hid_data->id);
1432 input_mt_slot(input, slot);
1433 input_mt_report_slot_state(input, MT_TOOL_FINGER, prox);
1434 }
1435 else {
1436 input_report_key(input, BTN_TOUCH, prox);
1437 }
1438
1439 if (prox) {
1440 input_report_abs(input, mt ? ABS_MT_POSITION_X : ABS_X,
1441 hid_data->x);
1442 input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y,
1443 hid_data->y);
1444 }
1445}
1446
1413static int wacom_wac_finger_event(struct hid_device *hdev, 1447static int wacom_wac_finger_event(struct hid_device *hdev,
1414 struct hid_field *field, struct hid_usage *usage, __s32 value) 1448 struct hid_field *field, struct hid_usage *usage, __s32 value)
1415{ 1449{
@@ -1432,36 +1466,35 @@ static int wacom_wac_finger_event(struct hid_device *hdev,
1432 } 1466 }
1433 1467
1434 1468
1469 if (usage->usage_index + 1 == field->report_count) {
1470 if (usage->hid == wacom_wac->features.last_slot_field)
1471 wacom_wac_finger_slot(wacom_wac, wacom_wac->input);
1472 }
1473
1435 return 0; 1474 return 0;
1436} 1475}
1437 1476
1438static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac, 1477static int wacom_wac_finger_count_touches(struct hid_device *hdev)
1439 struct input_dev *input, bool touch)
1440{ 1478{
1441 int slot; 1479 struct wacom *wacom = hid_get_drvdata(hdev);
1442 struct hid_data *hid_data = &wacom_wac->hid_data; 1480 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1481 struct input_dev *input = wacom_wac->input;
1482 unsigned touch_max = wacom_wac->features.touch_max;
1483 int count = 0;
1484 int i;
1443 1485
1444 slot = input_mt_get_slot_by_key(input, hid_data->id); 1486 if (touch_max == 1)
1487 return wacom_wac->hid_data.tipswitch &&
1488 !wacom_wac->shared->stylus_in_proximity;
1445 1489
1446 input_mt_slot(input, slot); 1490 for (i = 0; i < input->mt->num_slots; i++) {
1447 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); 1491 struct input_mt_slot *ps = &input->mt->slots[i];
1448 if (touch) { 1492 int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
1449 input_report_abs(input, ABS_MT_POSITION_X, hid_data->x); 1493 if (id >= 0)
1450 input_report_abs(input, ABS_MT_POSITION_Y, hid_data->y); 1494 count++;
1451 } 1495 }
1452 input_mt_sync_frame(input);
1453}
1454
1455static void wacom_wac_finger_single_touch_report(struct wacom_wac *wacom_wac,
1456 struct input_dev *input, bool touch)
1457{
1458 struct hid_data *hid_data = &wacom_wac->hid_data;
1459 1496
1460 if (touch) { 1497 return count;
1461 input_report_abs(input, ABS_X, hid_data->x);
1462 input_report_abs(input, ABS_Y, hid_data->y);
1463 }
1464 input_report_key(input, BTN_TOUCH, touch);
1465} 1498}
1466 1499
1467static void wacom_wac_finger_report(struct hid_device *hdev, 1500static void wacom_wac_finger_report(struct hid_device *hdev,
@@ -1470,18 +1503,15 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
1470 struct wacom *wacom = hid_get_drvdata(hdev); 1503 struct wacom *wacom = hid_get_drvdata(hdev);
1471 struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1504 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1472 struct input_dev *input = wacom_wac->input; 1505 struct input_dev *input = wacom_wac->input;
1473 bool touch = wacom_wac->hid_data.tipswitch &&
1474 !wacom_wac->shared->stylus_in_proximity;
1475 unsigned touch_max = wacom_wac->features.touch_max; 1506 unsigned touch_max = wacom_wac->features.touch_max;
1476 1507
1477 if (touch_max > 1) 1508 if (touch_max > 1)
1478 wacom_wac_finger_mt_report(wacom_wac, input, touch); 1509 input_mt_sync_frame(input);
1479 else 1510
1480 wacom_wac_finger_single_touch_report(wacom_wac, input, touch);
1481 input_sync(input); 1511 input_sync(input);
1482 1512
1483 /* keep touch state for pen event */ 1513 /* keep touch state for pen event */
1484 wacom_wac->shared->touch_down = touch; 1514 wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(hdev);
1485} 1515}
1486 1516
1487#define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ 1517#define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 5384043778fc..bfad815cda8a 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -145,6 +145,7 @@ struct wacom_features {
145 int pktlen; 145 int pktlen;
146 bool check_for_hid_type; 146 bool check_for_hid_type;
147 int hid_type; 147 int hid_type;
148 int last_slot_field;
148}; 149};
149 150
150struct wacom_shared { 151struct wacom_shared {