From d2ec58aee8b1d68d309656a0561c81c12197a987 Mon Sep 17 00:00:00 2001 From: Aaron Armstrong Skomra Date: Wed, 25 Jan 2017 12:08:41 -0800 Subject: [PATCH] HID: wacom: generic: support generic touch switch The second generation Intuos Pro is the first device in the generic codepath which has a touchswitch. We utilize a flag in wacom_shared in order to report this switch event received from the pad on the touch input. Signed-off-by: Aaron Skomra Reviewed-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 26 +++++++++++++++++++------- drivers/hid/wacom_wac.c | 19 ++++++++++++++++++- drivers/hid/wacom_wac.h | 4 +++- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index a4884e78b3f8..a8e68dc2ca99 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2053,6 +2053,24 @@ static void wacom_release_resources(struct wacom *wacom) wacom->wacom_wac.pad_input = NULL; } +static void wacom_set_shared_values(struct wacom_wac *wacom_wac) +{ + if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) { + wacom_wac->shared->type = wacom_wac->features.type; + wacom_wac->shared->touch_input = wacom_wac->touch_input; + } + + if (wacom_wac->has_mute_touch_switch) + wacom_wac->shared->has_mute_touch_switch = true; + + if (wacom_wac->shared->has_mute_touch_switch && + wacom_wac->shared->touch_input) { + set_bit(EV_SW, wacom_wac->shared->touch_input->evbit); + input_set_capability(wacom_wac->shared->touch_input, EV_SW, + SW_MUTE_DEVICE); + } +} + static int wacom_parse_and_register(struct wacom *wacom, bool wireless) { struct wacom_wac *wacom_wac = &wacom->wacom_wac; @@ -2172,13 +2190,7 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless) if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) error = hid_hw_open(hdev); - if ((wacom_wac->features.type == INTUOSHT || - wacom_wac->features.type == INTUOSHT2) && - (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)) { - wacom_wac->shared->type = wacom_wac->features.type; - wacom_wac->shared->touch_input = wacom_wac->touch_input; - } - + wacom_set_shared_values(wacom_wac); devres_close_group(&hdev->dev, wacom); return 0; diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 2eeaa05e2068..06d152a286a0 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1728,7 +1728,17 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, features->device_type |= WACOM_DEVICETYPE_PAD; break; case WACOM_HID_WD_TOUCHONOFF: - wacom_map_usage(input, usage, field, EV_SW, SW_MUTE_DEVICE, 0); + /* + * This usage, which is used to mute touch events, comes + * from the pad packet, but is reported on the touch + * interface. Because the touch interface may not have + * been created yet, we cannot call wacom_map_usage(). In + * order to process this usage when we receive it, we set + * the usage type and code directly. + */ + wacom_wac->has_mute_touch_switch = true; + usage->type = EV_SW; + usage->code = SW_MUTE_DEVICE; features->device_type |= WACOM_DEVICETYPE_PAD; break; case WACOM_HID_WD_TOUCHSTRIP: @@ -1807,6 +1817,13 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field input_event(input, usage->type, usage->code, 0); break; + case WACOM_HID_WD_TOUCHONOFF: + if (wacom_wac->shared->touch_input) { + input_report_switch(wacom_wac->shared->touch_input, + SW_MUTE_DEVICE, !value); + input_sync(wacom_wac->shared->touch_input); + } + break; default: input_event(input, usage->type, usage->code, value); break; diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index da38f7736a7a..4feaf94fb08b 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -115,6 +115,7 @@ #define WACOM_HID_WD_ACCELEROMETER_Y (WACOM_HID_UP_WACOMDIGITIZER | 0x0402) #define WACOM_HID_WD_ACCELEROMETER_Z (WACOM_HID_UP_WACOMDIGITIZER | 0x0403) #define WACOM_HID_WD_BATTERY_CHARGING (WACOM_HID_UP_WACOMDIGITIZER | 0x0404) +#define WACOM_HID_WD_TOUCHONOFF (WACOM_HID_UP_WACOMDIGITIZER | 0x0454) #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) #define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) @@ -124,7 +125,6 @@ #define WACOM_HID_WD_BUTTONLEFT (WACOM_HID_UP_WACOMDIGITIZER | 0x0993) #define WACOM_HID_WD_BUTTONRIGHT (WACOM_HID_UP_WACOMDIGITIZER | 0x0994) #define WACOM_HID_WD_BUTTONCENTER (WACOM_HID_UP_WACOMDIGITIZER | 0x0995) -#define WACOM_HID_WD_TOUCHONOFF (WACOM_HID_UP_WACOMDIGITIZER | 0x0996) #define WACOM_HID_WD_FINGERWHEEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0d03) #define WACOM_HID_WD_OFFSETLEFT (WACOM_HID_UP_WACOMDIGITIZER | 0x0d30) #define WACOM_HID_WD_OFFSETTOP (WACOM_HID_UP_WACOMDIGITIZER | 0x0d31) @@ -268,6 +268,7 @@ struct wacom_shared { struct input_dev *touch_input; struct hid_device *pen; struct hid_device *touch; + bool has_mute_touch_switch; }; struct hid_data { @@ -324,6 +325,7 @@ struct wacom_wac { int mode_report; int mode_value; struct hid_data hid_data; + bool has_mute_touch_switch; }; #endif