From 4f210c2938053e894ee00500dd0661f7a27a6ff4 Mon Sep 17 00:00:00 2001 From: Jaejoong Kim Date: Wed, 20 Sep 2017 18:40:36 +0900 Subject: HID: add comment for power callback in struct hid_ll_driver There is a missing comment in struct hid_ll_driver. So, add it. Signed-off-by: Jaejoong Kim Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/hid.h b/include/linux/hid.h index ab05a86269dc..7c3d4a17bbde 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -753,6 +753,7 @@ struct hid_driver { * @stop: called on remove * @open: called by input layer on open * @close: called by input layer on close + * @power: request underlying hardware to enter requested power mode * @parse: this method is called only once to parse the device data, * shouldn't allocate anything to not leak memory * @request: send report request to device (e.g. feature report) -- cgit v1.2.3 From 29cc309d8bf19a36c5196bf626662319af6e3c0b Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Tue, 22 Aug 2017 09:10:11 +0800 Subject: HID: hid-multitouch: forward MSC_TIMESTAMP Computes and forwards the device timestamp according to the specification. Many devices use a 16-bit timestamp field, with a resolution of 100us, therefore rolling around very frequently (every 6.5 seconds). To make sure there is no ambiguity, the timestamp reported to the input stack reset to 0 whenever the time between 2 received events is greater than MAX_TIMESTAMP_INTERVAL (1 second). Signed-off-by: Nicolas Boichat Acked-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 42 ++++++++++++++++++++++++++++++++++++++++++ include/linux/hid.h | 1 + 2 files changed, 43 insertions(+) (limited to 'include') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 440b999304a5..996bdc9bf0e5 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -136,6 +137,9 @@ struct mt_device { bool serial_maybe; /* need to check for serial protocol */ bool curvalid; /* is the current contact valid? */ unsigned mt_flags; /* flags to pass to input-mt */ + __s32 dev_time; /* the scan time provided by the device */ + unsigned long jiffies; /* the frame's jiffies */ + int timestamp; /* the timestamp to be sent */ }; static void mt_post_parse_default_settings(struct mt_device *td); @@ -177,6 +181,12 @@ static void mt_post_parse(struct mt_device *td); #define MT_DEFAULT_MAXCONTACT 10 #define MT_MAX_MAXCONTACT 250 +/* + * Resync device and local timestamps after that many microseconds without + * receiving data. + */ +#define MAX_TIMESTAMP_INTERVAL 1000000 + #define MT_USB_DEVICE(v, p) HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH, v, p) #define MT_BT_DEVICE(v, p) HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH, v, p) @@ -583,6 +593,12 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, cls->sn_pressure); mt_store_field(usage, td, hi); return 1; + case HID_DG_SCANTIME: + hid_map_usage(hi, usage, bit, max, + EV_MSC, MSC_TIMESTAMP); + input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP); + mt_store_field(usage, td, hi); + return 1; case HID_DG_CONTACTCOUNT: /* Ignore if indexes are out of bounds. */ if (field->index >= field->report->maxfield || @@ -718,6 +734,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) static void mt_sync_frame(struct mt_device *td, struct input_dev *input) { input_mt_sync_frame(input); + input_event(input, EV_MSC, MSC_TIMESTAMP, td->timestamp); input_sync(input); td->num_received = 0; if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags)) @@ -727,6 +744,28 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input) clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); } +static int mt_compute_timestamp(struct mt_device *td, struct hid_field *field, + __s32 value) +{ + long delta = value - td->dev_time; + unsigned long jdelta = jiffies_to_usecs(jiffies - td->jiffies); + + td->jiffies = jiffies; + td->dev_time = value; + + if (delta < 0) + delta += field->logical_maximum; + + /* HID_DG_SCANTIME is expressed in 100us, we want it in us. */ + delta *= 100; + + if (jdelta > MAX_TIMESTAMP_INTERVAL) + /* No data received for a while, resync the timestamp. */ + return 0; + else + return td->timestamp + delta; +} + static int mt_touch_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { @@ -787,6 +826,9 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, case HID_DG_HEIGHT: td->curdata.h = value; break; + case HID_DG_SCANTIME: + td->timestamp = mt_compute_timestamp(td, field, value); + break; case HID_DG_CONTACTCOUNT: break; case HID_DG_TOUCH: diff --git a/include/linux/hid.h b/include/linux/hid.h index ab05a86269dc..47dd962d9a7a 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -289,6 +289,7 @@ struct hid_item { #define HID_DG_DEVICEINDEX 0x000d0053 #define HID_DG_CONTACTCOUNT 0x000d0054 #define HID_DG_CONTACTMAX 0x000d0055 +#define HID_DG_SCANTIME 0x000d0056 #define HID_DG_BUTTONTYPE 0x000d0059 #define HID_DG_BARRELSWITCH2 0x000d005a #define HID_DG_TOOLSERIALNUMBER 0x000d005b -- cgit v1.2.3 From 9e429d564926d3bca49907fa03031da705ad6f2c Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Tue, 7 Nov 2017 08:25:17 -0800 Subject: HID: wacom: generic: Send BTN_STYLUS3 when both barrel switches are set The Wacom Pro Pen 3D includes a third barrel switch which is intended to be particularly useful in applications where one frequency uses pan, zoom, and rotate to navigate around a scene or model. The pen is compatible with the MobileStudio Pro, 2nd-gen Intuos Pro, and Cintiq Pro. When the third button is pressed, these devices set both the HID_DG_BARRELSWITCH and HID_DG_BARRELSWITCH2 usages since their HID descriptors do not include a usage specific to the button. Rather than send both BTN_STYLUS and BTN_STYLUS2 when the third button is pressed, userspace (libinput) has requested that we detect this condition and report a newly-defined BTN_STYLUS3 event instead. We could define a quirk specific to devices compatible with the Pro Pen 3D, but the liklihood of seeing both barrel switch bits set with other pens/devices is low enough to not worry about (pens mechanically prevent accidental activation of multiple switches). Signed-off-by: Jason Gerecke Acked-by: Dmitry Torokhov Acked-by: Peter Hutterer Acked-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 18 ++++++++++++++++-- drivers/hid/wacom_wac.h | 2 ++ include/uapi/linux/input-event-codes.h | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index e3223b0c4f90..16af6886e828 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2140,6 +2140,12 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field case HID_DG_TIPSWITCH: wacom_wac->hid_data.tipswitch |= value; return; + case HID_DG_BARRELSWITCH: + wacom_wac->hid_data.barrelswitch = value; + return; + case HID_DG_BARRELSWITCH2: + wacom_wac->hid_data.barrelswitch2 = value; + return; case HID_DG_TOOLSERIALNUMBER: if (value) { wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); @@ -2254,6 +2260,12 @@ static void wacom_wac_pen_report(struct hid_device *hdev, if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) { int id = wacom_wac->id[0]; + int sw_state = wacom_wac->hid_data.barrelswitch | + (wacom_wac->hid_data.barrelswitch2 << 1); + + input_report_key(input, BTN_STYLUS, sw_state == 1); + input_report_key(input, BTN_STYLUS2, sw_state == 2); + input_report_key(input, BTN_STYLUS3, sw_state == 3); /* * Non-USI EMR tools should have their IDs mangled to @@ -3300,9 +3312,11 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, else __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - if (features->type == HID_GENERIC) - /* setup has already been done */ + if (features->type == HID_GENERIC) { + /* setup has already been done; apply otherwise-undetectible quirks */ + input_set_capability(input_dev, EV_KEY, BTN_STYLUS3); return 0; + } __set_bit(BTN_TOUCH, input_dev->keybit); __set_bit(ABS_MISC, input_dev->absbit); diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 8a03654048bf..69dda27e8dde 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -291,6 +291,8 @@ struct hid_data { bool inrange_state; bool invert_state; bool tipswitch; + bool barrelswitch; + bool barrelswitch2; int x; int y; int pressure; diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 179891074b3c..9b3a522f50d1 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -406,6 +406,7 @@ #define BTN_TOOL_MOUSE 0x146 #define BTN_TOOL_LENS 0x147 #define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */ +#define BTN_STYLUS3 0x149 #define BTN_TOUCH 0x14a #define BTN_STYLUS 0x14b #define BTN_STYLUS2 0x14c -- cgit v1.2.3