aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/wacom_wac.c26
-rw-r--r--drivers/hid/wacom_wac.h3
2 files changed, 26 insertions, 3 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 81467c982734..c0d75aee91e5 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1443,6 +1443,7 @@ static int wacom_equivalent_usage(int usage)
1443 1443
1444 if (subpage == WACOM_HID_SP_DIGITIZER || 1444 if (subpage == WACOM_HID_SP_DIGITIZER ||
1445 subpage == WACOM_HID_SP_DIGITIZERINFO || 1445 subpage == WACOM_HID_SP_DIGITIZERINFO ||
1446 usage == WACOM_HID_WD_SENSE ||
1446 usage == WACOM_HID_WD_DISTANCE) { 1447 usage == WACOM_HID_WD_DISTANCE) {
1447 return usage; 1448 return usage;
1448 } 1449 }
@@ -1493,6 +1494,7 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
1493{ 1494{
1494 struct wacom *wacom = hid_get_drvdata(hdev); 1495 struct wacom *wacom = hid_get_drvdata(hdev);
1495 struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1496 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1497 struct wacom_features *features = &wacom_wac->features;
1496 struct input_dev *input = wacom_wac->pen_input; 1498 struct input_dev *input = wacom_wac->pen_input;
1497 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); 1499 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
1498 1500
@@ -1539,6 +1541,10 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
1539 case HID_DG_TOOLSERIALNUMBER: 1541 case HID_DG_TOOLSERIALNUMBER:
1540 wacom_map_usage(input, usage, field, EV_MSC, MSC_SERIAL, 0); 1542 wacom_map_usage(input, usage, field, EV_MSC, MSC_SERIAL, 0);
1541 break; 1543 break;
1544 case WACOM_HID_WD_SENSE:
1545 features->quirks |= WACOM_QUIRK_SENSE;
1546 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0);
1547 break;
1542 case WACOM_HID_WD_FINGERWHEEL: 1548 case WACOM_HID_WD_FINGERWHEEL:
1543 wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0); 1549 wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
1544 break; 1550 break;
@@ -1550,6 +1556,7 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
1550{ 1556{
1551 struct wacom *wacom = hid_get_drvdata(hdev); 1557 struct wacom *wacom = hid_get_drvdata(hdev);
1552 struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1558 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1559 struct wacom_features *features = &wacom_wac->features;
1553 struct input_dev *input = wacom_wac->pen_input; 1560 struct input_dev *input = wacom_wac->pen_input;
1554 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); 1561 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
1555 1562
@@ -1564,6 +1571,8 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
1564 break; 1571 break;
1565 case HID_DG_INRANGE: 1572 case HID_DG_INRANGE:
1566 wacom_wac->hid_data.inrange_state = value; 1573 wacom_wac->hid_data.inrange_state = value;
1574 if (!(features->quirks & WACOM_QUIRK_SENSE))
1575 wacom_wac->hid_data.sense_state = value;
1567 return 0; 1576 return 0;
1568 case HID_DG_INVERT: 1577 case HID_DG_INVERT:
1569 wacom_wac->hid_data.invert_state = value; 1578 wacom_wac->hid_data.invert_state = value;
@@ -1572,6 +1581,9 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
1572 case HID_DG_TIPSWITCH: 1581 case HID_DG_TIPSWITCH:
1573 wacom_wac->hid_data.tipswitch |= value; 1582 wacom_wac->hid_data.tipswitch |= value;
1574 return 0; 1583 return 0;
1584 case WACOM_HID_WD_SENSE:
1585 wacom_wac->hid_data.sense_state = value;
1586 return 0;
1575 } 1587 }
1576 1588
1577 /* send pen events only when touch is up or forced out 1589 /* send pen events only when touch is up or forced out
@@ -1580,6 +1592,10 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
1580 if (!usage->type || delay_pen_events(wacom_wac)) 1592 if (!usage->type || delay_pen_events(wacom_wac))
1581 return 0; 1593 return 0;
1582 1594
1595 /* send pen events only when the pen is in/entering/leaving proximity */
1596 if (!wacom_wac->hid_data.inrange_state && !wacom_wac->tool[0])
1597 return 0;
1598
1583 input_event(input, usage->type, usage->code, value); 1599 input_event(input, usage->type, usage->code, value);
1584 1600
1585 return 0; 1601 return 0;
@@ -1598,16 +1614,17 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
1598 struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1614 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1599 struct input_dev *input = wacom_wac->pen_input; 1615 struct input_dev *input = wacom_wac->pen_input;
1600 bool prox = wacom_wac->hid_data.inrange_state; 1616 bool prox = wacom_wac->hid_data.inrange_state;
1617 bool range = wacom_wac->hid_data.sense_state;
1601 1618
1602 if (!wacom_wac->shared->stylus_in_proximity) /* first in prox */ 1619 if (!wacom_wac->tool[0] && prox) /* first in prox */
1603 /* Going into proximity select tool */ 1620 /* Going into proximity select tool */
1604 wacom_wac->tool[0] = wacom_wac->hid_data.invert_state ? 1621 wacom_wac->tool[0] = wacom_wac->hid_data.invert_state ?
1605 BTN_TOOL_RUBBER : BTN_TOOL_PEN; 1622 BTN_TOOL_RUBBER : BTN_TOOL_PEN;
1606 1623
1607 /* keep pen state for touch events */ 1624 /* keep pen state for touch events */
1608 wacom_wac->shared->stylus_in_proximity = prox; 1625 wacom_wac->shared->stylus_in_proximity = range;
1609 1626
1610 if (!delay_pen_events(wacom_wac)) { 1627 if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) {
1611 input_report_key(input, BTN_TOUCH, 1628 input_report_key(input, BTN_TOUCH,
1612 wacom_wac->hid_data.tipswitch); 1629 wacom_wac->hid_data.tipswitch);
1613 input_report_key(input, wacom_wac->tool[0], prox); 1630 input_report_key(input, wacom_wac->tool[0], prox);
@@ -1616,6 +1633,9 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
1616 1633
1617 input_sync(input); 1634 input_sync(input);
1618 } 1635 }
1636
1637 if (!prox)
1638 wacom_wac->tool[0] = 0;
1619} 1639}
1620 1640
1621static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, 1641static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 544755929c2f..c27b7b40092e 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -74,6 +74,7 @@
74 74
75/* device quirks */ 75/* device quirks */
76#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001 76#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001
77#define WACOM_QUIRK_SENSE 0x0002
77#define WACOM_QUIRK_BATTERY 0x0008 78#define WACOM_QUIRK_BATTERY 0x0008
78 79
79/* device types */ 80/* device types */
@@ -88,6 +89,7 @@
88#define WACOM_HID_SP_DIGITIZER 0x000d0000 89#define WACOM_HID_SP_DIGITIZER 0x000d0000
89#define WACOM_HID_SP_DIGITIZERINFO 0x00100000 90#define WACOM_HID_SP_DIGITIZERINFO 0x00100000
90#define WACOM_HID_WD_DIGITIZER (WACOM_HID_UP_WACOMDIGITIZER | 0x01) 91#define WACOM_HID_WD_DIGITIZER (WACOM_HID_UP_WACOMDIGITIZER | 0x01)
92#define WACOM_HID_WD_SENSE (WACOM_HID_UP_WACOMDIGITIZER | 0x36)
91#define WACOM_HID_WD_DISTANCE (WACOM_HID_UP_WACOMDIGITIZER | 0x0132) 93#define WACOM_HID_WD_DISTANCE (WACOM_HID_UP_WACOMDIGITIZER | 0x0132)
92#define WACOM_HID_WD_FINGERWHEEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0d03) 94#define WACOM_HID_WD_FINGERWHEEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0d03)
93#define WACOM_HID_WD_DATAMODE (WACOM_HID_UP_WACOMDIGITIZER | 0x1002) 95#define WACOM_HID_WD_DATAMODE (WACOM_HID_UP_WACOMDIGITIZER | 0x1002)
@@ -212,6 +214,7 @@ struct wacom_shared {
212struct hid_data { 214struct hid_data {
213 __s16 inputmode; /* InputMode HID feature, -1 if non-existent */ 215 __s16 inputmode; /* InputMode HID feature, -1 if non-existent */
214 __s16 inputmode_index; /* InputMode HID feature index in the report */ 216 __s16 inputmode_index; /* InputMode HID feature index in the report */
217 bool sense_state;
215 bool inrange_state; 218 bool inrange_state;
216 bool invert_state; 219 bool invert_state;
217 bool tipswitch; 220 bool tipswitch;