diff options
| -rw-r--r-- | drivers/hid/wacom_wac.c | 86 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.h | 1 |
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 | ||
| 1420 | static 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 | |||
| 1413 | static int wacom_wac_finger_event(struct hid_device *hdev, | 1447 | static 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 | ||
| 1438 | static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac, | 1477 | static 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 | |||
| 1455 | static 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 | ||
| 1467 | static void wacom_wac_finger_report(struct hid_device *hdev, | 1500 | static 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 | ||
| 150 | struct wacom_shared { | 151 | struct wacom_shared { |
