diff options
-rw-r--r-- | drivers/hid/wacom_sys.c | 7 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 44 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.h | 2 | ||||
-rw-r--r-- | include/uapi/linux/input-event-codes.h | 1 |
4 files changed, 39 insertions, 15 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 906e654fb0ba..ee71ad9b6cc1 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -196,6 +196,13 @@ static void wacom_feature_mapping(struct hid_device *hdev, kfree(data); break; } + + if (hdev->vendor == USB_VENDOR_ID_WACOM && + hdev->product == 0x4200 /* Dell Canvas 27 */ && + field->application == HID_UP_MSVENDOR) { + wacom->wacom_wac.mode_report = field->report->id; + wacom->wacom_wac.mode_value = 2; + } } /* diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index aa692e28b2cd..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); @@ -2217,11 +2223,11 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field if (!usage->type || delay_pen_events(wacom_wac)) return; - /* send pen events only when the pen is in/entering/leaving proximity */ - if (!wacom_wac->hid_data.inrange_state && !wacom_wac->tool[0]) - return; - - input_event(input, usage->type, usage->code, value); + /* send pen events only when the pen is in range */ + if (wacom_wac->hid_data.inrange_state) + input_event(input, usage->type, usage->code, value); + else if (wacom_wac->shared->stylus_in_proximity && !wacom_wac->hid_data.sense_state) + input_event(input, usage->type, usage->code, 0); } static void wacom_wac_pen_pre_report(struct hid_device *hdev, @@ -2236,11 +2242,11 @@ static void wacom_wac_pen_report(struct hid_device *hdev, struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct input_dev *input = wacom_wac->pen_input; - bool prox = wacom_wac->hid_data.inrange_state; - bool range = wacom_wac->hid_data.sense_state; + bool range = wacom_wac->hid_data.inrange_state; + bool sense = wacom_wac->hid_data.sense_state; - if (!wacom_wac->tool[0] && prox) { /* first in prox */ - /* Going into proximity select tool */ + if (!wacom_wac->tool[0] && range) { /* first in range */ + /* Going into range select tool */ if (wacom_wac->hid_data.invert_state) wacom_wac->tool[0] = BTN_TOOL_RUBBER; else if (wacom_wac->id[0]) @@ -2250,10 +2256,16 @@ static void wacom_wac_pen_report(struct hid_device *hdev, } /* keep pen state for touch events */ - wacom_wac->shared->stylus_in_proximity = range; + wacom_wac->shared->stylus_in_proximity = sense; 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 @@ -2269,10 +2281,10 @@ static void wacom_wac_pen_report(struct hid_device *hdev, */ input_report_key(input, BTN_TOUCH, wacom_wac->hid_data.tipswitch); - input_report_key(input, wacom_wac->tool[0], prox); + input_report_key(input, wacom_wac->tool[0], sense); if (wacom_wac->serial[0]) { input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]); - input_report_abs(input, ABS_MISC, prox ? id : 0); + input_report_abs(input, ABS_MISC, sense ? id : 0); } wacom_wac->hid_data.tipswitch = false; @@ -2280,7 +2292,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, input_sync(input); } - if (!prox) { + if (!sense) { wacom_wac->tool[0] = 0; wacom_wac->id[0] = 0; wacom_wac->serial[0] = 0; @@ -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 feb62fd4dfc3..64d8f014602e 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -292,6 +292,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 |