aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerecke <killertofu@gmail.com>2016-10-19 21:03:42 -0400
committerJiri Kosina <jkosina@suse.cz>2016-10-20 03:53:56 -0400
commit50066a042da5457ae5b6397425f0a7ca556231e3 (patch)
tree76c8c01a73f702be505cf3ddff8c6eeea4c07245
parentf2209d4aefac246772152c5294af49f2800f646b (diff)
HID: wacom: generic: Add support for height, tilt, and twist usages
The HID standard defines usages that allow digitizers to report the pen's height, tilt, and rotation and which are used by Wacom's new "MobileStudio Pro" devices. Note that 'hidinput_calc_abs_res' expects ABS_Z (historically used by our driver to report twist) to have linear units. To ensure it calculates a resolution with the actually-angular units provided in the HID descriptor we nedd to lie and tell it we're calculating it for the (rotational) ABS_RZ axis instead. Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/wacom_wac.c28
-rw-r--r--include/linux/hid.h3
2 files changed, 29 insertions, 2 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 8071c18bf9c2..3f4ba53192c0 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1440,6 +1440,11 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
1440{ 1440{
1441 int fmin = field->logical_minimum; 1441 int fmin = field->logical_minimum;
1442 int fmax = field->logical_maximum; 1442 int fmax = field->logical_maximum;
1443 int resolution_code = code;
1444
1445 if (usage->hid == HID_DG_TWIST) {
1446 resolution_code = ABS_RZ;
1447 }
1443 1448
1444 usage->type = type; 1449 usage->type = type;
1445 usage->code = code; 1450 usage->code = code;
@@ -1450,7 +1455,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
1450 case EV_ABS: 1455 case EV_ABS:
1451 input_set_abs_params(input, code, fmin, fmax, fuzz, 0); 1456 input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
1452 input_abs_set_res(input, code, 1457 input_abs_set_res(input, code,
1453 hidinput_calc_abs_res(field, code)); 1458 hidinput_calc_abs_res(field, resolution_code));
1454 break; 1459 break;
1455 case EV_KEY: 1460 case EV_KEY:
1456 input_set_capability(input, EV_KEY, code); 1461 input_set_capability(input, EV_KEY, code);
@@ -1475,6 +1480,9 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
1475 case HID_GD_Y: 1480 case HID_GD_Y:
1476 wacom_map_usage(input, usage, field, EV_ABS, ABS_Y, 4); 1481 wacom_map_usage(input, usage, field, EV_ABS, ABS_Y, 4);
1477 break; 1482 break;
1483 case HID_GD_Z:
1484 wacom_map_usage(input, usage, field, EV_ABS, ABS_DISTANCE, 0);
1485 break;
1478 case HID_DG_TIPPRESSURE: 1486 case HID_DG_TIPPRESSURE:
1479 wacom_map_usage(input, usage, field, EV_ABS, ABS_PRESSURE, 0); 1487 wacom_map_usage(input, usage, field, EV_ABS, ABS_PRESSURE, 0);
1480 break; 1488 break;
@@ -1485,6 +1493,15 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
1485 wacom_map_usage(input, usage, field, EV_KEY, 1493 wacom_map_usage(input, usage, field, EV_KEY,
1486 BTN_TOOL_RUBBER, 0); 1494 BTN_TOOL_RUBBER, 0);
1487 break; 1495 break;
1496 case HID_DG_TILT_X:
1497 wacom_map_usage(input, usage, field, EV_ABS, ABS_TILT_X, 0);
1498 break;
1499 case HID_DG_TILT_Y:
1500 wacom_map_usage(input, usage, field, EV_ABS, ABS_TILT_Y, 0);
1501 break;
1502 case HID_DG_TWIST:
1503 wacom_map_usage(input, usage, field, EV_ABS, ABS_Z, 0);
1504 break;
1488 case HID_DG_ERASER: 1505 case HID_DG_ERASER:
1489 case HID_DG_TIPSWITCH: 1506 case HID_DG_TIPSWITCH:
1490 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0); 1507 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0);
@@ -1508,8 +1525,15 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
1508 struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1525 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1509 struct input_dev *input = wacom_wac->pen_input; 1526 struct input_dev *input = wacom_wac->pen_input;
1510 1527
1511 /* checking which Tool / tip switch to send */
1512 switch (usage->hid) { 1528 switch (usage->hid) {
1529 case HID_GD_Z:
1530 /*
1531 * HID_GD_Z "should increase as the control's position is
1532 * moved from high to low", while ABS_DISTANCE instead
1533 * increases in value as the tool moves from low to high.
1534 */
1535 value = field->logical_maximum - value;
1536 break;
1513 case HID_DG_INRANGE: 1537 case HID_DG_INRANGE:
1514 wacom_wac->hid_data.inrange_state = value; 1538 wacom_wac->hid_data.inrange_state = value;
1515 return 0; 1539 return 0;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index b2ec82712baa..e712101a1670 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -232,6 +232,9 @@ struct hid_item {
232#define HID_DG_TABLETFUNCTIONKEY 0x000d0039 232#define HID_DG_TABLETFUNCTIONKEY 0x000d0039
233#define HID_DG_PROGRAMCHANGEKEY 0x000d003a 233#define HID_DG_PROGRAMCHANGEKEY 0x000d003a
234#define HID_DG_INVERT 0x000d003c 234#define HID_DG_INVERT 0x000d003c
235#define HID_DG_TILT_X 0x000d003d
236#define HID_DG_TILT_Y 0x000d003e
237#define HID_DG_TWIST 0x000d0041
235#define HID_DG_TIPSWITCH 0x000d0042 238#define HID_DG_TIPSWITCH 0x000d0042
236#define HID_DG_TIPSWITCH2 0x000d0043 239#define HID_DG_TIPSWITCH2 0x000d0043
237#define HID_DG_BARRELSWITCH 0x000d0044 240#define HID_DG_BARRELSWITCH 0x000d0044