Several devices include a touch on/off switch, such as the Cintiq Pro 13/16/24/32, the 2nd-gen Intuos Pro, and even some Intuos devices. This commit extends the work done earlier to kernels older than 3.17.
Ref: 235cf65108 ("backport: HID: wacom: support touch on/off softkey") Ref: 8681f6e506 ("backport: HID: wacom: generic: support generic touch switch") Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- 2.6.30/wacom_sys.c | 8 ++++++++ 2.6.30/wacom_wac.c | 37 +++++++++++++++++++++++++++++++++++++ 2.6.30/wacom_wac.h | 4 ++++ 2.6.38/wacom_sys.c | 4 +--- 2.6.38/wacom_wac.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 2.6.38/wacom_wac.h | 2 ++ 3.7/wacom_sys.c | 4 +--- 3.7/wacom_wac.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 3.7/wacom_wac.h | 2 ++ 9 files changed, 145 insertions(+), 10 deletions(-) diff --git a/2.6.30/wacom_sys.c b/2.6.30/wacom_sys.c index 92da296..ba17b1b 100644 --- a/2.6.30/wacom_sys.c +++ b/2.6.30/wacom_sys.c @@ -1018,6 +1018,14 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i if (error) goto fail4; + if (wacom_wac->features.touch_max && wacom_wac->shared) { + if (wacom_wac->features.device_type == BTN_TOOL_DOUBLETAP || + wacom_wac->features.device_type == BTN_TOOL_TRIPLETAP) { + wacom_wac->shared->type = wacom_wac->features.type; + wacom_wac->shared->touch_input = wacom_wac->input; + } + } + /* Note that if query fails it is not a hard failure */ wacom_query_tablet_data(intf, features); diff --git a/2.6.30/wacom_wac.c b/2.6.30/wacom_wac.c index fecd24d..4b84413 100644 --- a/2.6.30/wacom_wac.c +++ b/2.6.30/wacom_wac.c @@ -916,6 +916,13 @@ static void wacom_multitouch_generic_finger(struct wacom_wac *wacom, struct input_dev *input = wacom->input; int slot = find_slot_from_contactid(wacom, contact_id); + if (wacom->shared->has_mute_touch_switch && + !wacom->shared->is_touch_on) { + if (!wacom->shared->touch_down) + return; + prox = 0; + } + if (slot < 0) return; @@ -1568,6 +1575,25 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) return 0; } +static void wacom_mspro_touch_switch(struct wacom_wac *wacom, bool enable_touch) +{ + if (!wacom->shared->touch_input) + return; + + wacom->shared->is_touch_on = enable_touch; + input_report_switch(wacom->shared->touch_input, + SW_MUTE_DEVICE, !enable_touch); + input_sync(wacom->shared->touch_input); +} + +static void wacom_mspro_touch_toggle(struct wacom_wac *wacom) +{ + if (!wacom->shared->touch_input) + return; + + wacom_mspro_touch_switch(wacom, !wacom->shared->is_touch_on); +} + static int wacom_mspro_pad_irq(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; @@ -1599,6 +1625,9 @@ static int wacom_mspro_pad_irq(struct wacom_wac *wacom) ring = WACOM_INTUOSP2_RING_UNTOUCHED; /* No ring */ keys = data[1] & 0x0E; /* 0x01 shouldn't make the pad active */ + if (data[1] & 0x01) + wacom_mspro_touch_toggle(wacom); + input_report_key(input, KEY_CONTROLPANEL, (data[1] & 0x02) != 0); input_report_key(input, KEY_ONSCREEN_KEYBOARD, (data[1] & 0x04) != 0); input_report_key(input, KEY_BUTTONCONFIG, (data[1] & 0x08) != 0); @@ -2183,6 +2212,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, } else { __set_bit(BTN_STYLUS3, input_dev->keybit); wacom_wac->previous_ring = WACOM_INTUOSP2_RING_UNTOUCHED; + wacom_wac->shared->has_mute_touch_switch = true; } case INTUOS5: case INTUOS5L: @@ -2258,6 +2288,13 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0); input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0); __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); + + if ((input_dev->id.product >= 0x353 && input_dev->id.product <= 0x356)) { + input_dev->evbit[0] |= BIT_MASK(EV_SW); + __set_bit(SW_MUTE_DEVICE, input_dev->swbit); + wacom_wac->shared->has_mute_touch_switch = true; + wacom_wac->shared->is_touch_on = true; + } } if (features->device_type != BTN_TOOL_PEN) diff --git a/2.6.30/wacom_wac.h b/2.6.30/wacom_wac.h index b6660ef..ea3abd8 100755 --- a/2.6.30/wacom_wac.h +++ b/2.6.30/wacom_wac.h @@ -164,6 +164,10 @@ struct wacom_features { struct wacom_shared { bool stylus_in_proximity; bool touch_down; + int type; + struct input_dev *touch_input; + bool has_mute_touch_switch; + bool is_touch_on; }; struct wacom_wac { diff --git a/2.6.38/wacom_sys.c b/2.6.38/wacom_sys.c index 295c1ea..cbf36b5 100644 --- a/2.6.38/wacom_sys.c +++ b/2.6.38/wacom_sys.c @@ -2035,9 +2035,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i goto fail4; } - if ((wacom_wac->features.type == INTUOSHT || - wacom_wac->features.type == INTUOSHT2) && - wacom_wac->features.touch_max) { + if (wacom_wac->features.touch_max && wacom_wac->shared) { if (wacom_wac->features.device_type == BTN_TOOL_FINGER) { wacom_wac->shared->type = wacom_wac->features.type; wacom_wac->shared->touch_input = wacom_wac->input; diff --git a/2.6.38/wacom_wac.c b/2.6.38/wacom_wac.c index 9f5c3bd..2e6eb29 100644 --- a/2.6.38/wacom_wac.c +++ b/2.6.38/wacom_wac.c @@ -1160,6 +1160,13 @@ static void wacom_multitouch_generic_finger(struct wacom_wac *wacom, struct input_dev *input = wacom->input; int slot = find_slot_from_contactid(wacom, contact_id); + if (wacom->shared->has_mute_touch_switch && + !wacom->shared->is_touch_on) { + if (!wacom->shared->touch_down) + return; + prox = 0; + } + if (slot < 0) return; @@ -1720,8 +1727,9 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) wacom->shared->type == INTUOSHT2) && wacom->shared->touch_input && wacom->shared->touch_max) { + wacom->shared->is_touch_on = !(data[5] & 0x40); input_report_switch(wacom->shared->touch_input, - SW_MUTE_DEVICE, data[5] & 0x40); + SW_MUTE_DEVICE, !wacom->shared->is_touch_on); input_sync(wacom->shared->touch_input); } @@ -1759,8 +1767,9 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) features->type == INTUOSHT2) && wacom_wac->shared->touch_input && features->touch_max) { + wacom_wac->shared->is_touch_on = !(data[8] & 0x40); input_report_switch(wacom_wac->shared->touch_input, - SW_MUTE_DEVICE, data[8] & 0x40); + SW_MUTE_DEVICE, !wacom_wac->shared->is_touch_on); input_sync(wacom_wac->shared->touch_input); } @@ -1786,6 +1795,25 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) return 0; } +static void wacom_mspro_touch_switch(struct wacom_wac *wacom, bool enable_touch) +{ + if (!wacom->shared->touch_input) + return; + + wacom->shared->is_touch_on = enable_touch; + input_report_switch(wacom->shared->touch_input, + SW_MUTE_DEVICE, !enable_touch); + input_sync(wacom->shared->touch_input); +} + +static void wacom_mspro_touch_toggle(struct wacom_wac *wacom) +{ + if (!wacom->shared->touch_input) + return; + + wacom_mspro_touch_switch(wacom, !wacom->shared->is_touch_on); +} + static int wacom_mspro_device_irq(struct wacom_wac *wacom) { struct wacom *w = container_of(wacom, struct wacom, wacom_wac); @@ -1806,6 +1834,8 @@ static int wacom_mspro_device_irq(struct wacom_wac *wacom) wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, battery_level, bat_charging, 1, bat_charging); + wacom_mspro_touch_switch(wacom, (data[2] & 0x80)); + return 0; } @@ -1840,6 +1870,9 @@ static int wacom_mspro_pad_irq(struct wacom_wac *wacom) ring = WACOM_INTUOSP2_RING_UNTOUCHED; /* No ring */ keys = data[1] & 0x0E; /* 0x01 shouldn't make the pad active */ + if (data[1] & 0x01) + wacom_mspro_touch_toggle(wacom); + input_report_key(input, KEY_CONTROLPANEL, (data[1] & 0x02) != 0); input_report_key(input, KEY_ONSCREEN_KEYBOARD, (data[1] & 0x04) != 0); input_report_key(input, KEY_BUTTONCONFIG, (data[1] & 0x08) != 0); @@ -2475,6 +2508,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, if (features->device_type == BTN_TOOL_PEN) { __set_bit(BTN_STYLUS3, input_dev->keybit); wacom_wac->previous_ring = WACOM_INTUOSP2_RING_UNTOUCHED; + wacom_wac->shared->has_mute_touch_switch = true; } err = wacom_create_slots(wacom_wac); if (err) @@ -2577,6 +2611,14 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); + if ((features->device_type == BTN_TOOL_FINGER) && + (input_dev->id.product >= 0x353 && input_dev->id.product <= 0x356)) { + input_dev->evbit[0] |= BIT_MASK(EV_SW); + __set_bit(SW_MUTE_DEVICE, input_dev->swbit); + wacom_wac->shared->has_mute_touch_switch = true; + wacom_wac->shared->is_touch_on = true; + } + if (features->device_type != BTN_TOOL_PEN) break; /* no need to process stylus stuff */ @@ -2616,6 +2658,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, features->device_type == BTN_TOOL_FINGER) { input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); + wacom_wac->shared->has_mute_touch_switch = true; } /* fall through */ diff --git a/2.6.38/wacom_wac.h b/2.6.38/wacom_wac.h index 11cba2d..4d0c1d1 100644 --- a/2.6.38/wacom_wac.h +++ b/2.6.38/wacom_wac.h @@ -189,6 +189,8 @@ struct wacom_shared { unsigned touch_max; int type; struct input_dev *touch_input; + bool has_mute_touch_switch; + bool is_touch_on; }; struct wacom_remote_data { diff --git a/3.7/wacom_sys.c b/3.7/wacom_sys.c index 5f17669..e07d131 100644 --- a/3.7/wacom_sys.c +++ b/3.7/wacom_sys.c @@ -2028,9 +2028,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i goto fail4; } - if ((wacom_wac->features.type == INTUOSHT || - wacom_wac->features.type == INTUOSHT2) && - wacom_wac->features.touch_max) { + if (wacom_wac->features.touch_max && wacom_wac->shared) { if (wacom_wac->features.device_type == BTN_TOOL_FINGER) { wacom_wac->shared->type = wacom_wac->features.type; wacom_wac->shared->touch_input = wacom_wac->input; diff --git a/3.7/wacom_wac.c b/3.7/wacom_wac.c index afdf1b5..c1adc8f 100644 --- a/3.7/wacom_wac.c +++ b/3.7/wacom_wac.c @@ -1141,6 +1141,13 @@ static void wacom_multitouch_generic_finger(struct wacom_wac *wacom, struct input_dev *input = wacom->input; int slot = input_mt_get_slot_by_key(input, contact_id); + if (wacom->shared->has_mute_touch_switch && + !wacom->shared->is_touch_on) { + if (!wacom->shared->touch_down) + return; + prox = 0; + } + if (slot < 0) return; @@ -1702,8 +1709,9 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) wacom->shared->type == INTUOSHT2) && wacom->shared->touch_input && wacom->shared->touch_max) { + wacom->shared->is_touch_on = !(data[5] & 0x40); input_report_switch(wacom->shared->touch_input, - SW_MUTE_DEVICE, data[5] & 0x40); + SW_MUTE_DEVICE, !wacom->shared->is_touch_on); input_sync(wacom->shared->touch_input); } @@ -1741,8 +1749,9 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) features->type == INTUOSHT2) && wacom_wac->shared->touch_input && features->touch_max) { + wacom_wac->shared->is_touch_on = !(data[8] & 0x40); input_report_switch(wacom_wac->shared->touch_input, - SW_MUTE_DEVICE, data[8] & 0x40); + SW_MUTE_DEVICE, !wacom_wac->shared->is_touch_on); input_sync(wacom_wac->shared->touch_input); } @@ -1768,6 +1777,25 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) return 0; } +static void wacom_mspro_touch_switch(struct wacom_wac *wacom, bool enable_touch) +{ + if (!wacom->shared->touch_input) + return; + + wacom->shared->is_touch_on = enable_touch; + input_report_switch(wacom->shared->touch_input, + SW_MUTE_DEVICE, !enable_touch); + input_sync(wacom->shared->touch_input); +} + +static void wacom_mspro_touch_toggle(struct wacom_wac *wacom) +{ + if (!wacom->shared->touch_input) + return; + + wacom_mspro_touch_switch(wacom, !wacom->shared->is_touch_on); +} + static int wacom_mspro_device_irq(struct wacom_wac *wacom) { struct wacom *w = container_of(wacom, struct wacom, wacom_wac); @@ -1788,6 +1816,8 @@ static int wacom_mspro_device_irq(struct wacom_wac *wacom) wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, battery_level, bat_charging, 1, bat_charging); + wacom_mspro_touch_switch(wacom, (data[2] & 0x80)); + return 0; } @@ -1822,6 +1852,9 @@ static int wacom_mspro_pad_irq(struct wacom_wac *wacom) ring = WACOM_INTUOSP2_RING_UNTOUCHED; /* No ring */ keys = data[1] & 0x0E; /* 0x01 shouldn't make the pad active */ + if (data[1] & 0x01) + wacom_mspro_touch_toggle(wacom); + input_report_key(input, KEY_CONTROLPANEL, (data[1] & 0x02) != 0); input_report_key(input, KEY_ONSCREEN_KEYBOARD, (data[1] & 0x04) != 0); input_report_key(input, KEY_BUTTONCONFIG, (data[1] & 0x08) != 0); @@ -2446,6 +2479,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, if (features->device_type == BTN_TOOL_PEN) { __set_bit(BTN_STYLUS3, input_dev->keybit); wacom_wac->previous_ring = WACOM_INTUOSP2_RING_UNTOUCHED; + wacom_wac->shared->has_mute_touch_switch = true; } /* fall through */ @@ -2521,6 +2555,14 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); + if ((features->device_type == BTN_TOOL_FINGER) && + (input_dev->id.product >= 0x353 && input_dev->id.product <= 0x356)) { + input_dev->evbit[0] |= BIT_MASK(EV_SW); + __set_bit(SW_MUTE_DEVICE, input_dev->swbit); + wacom_wac->shared->has_mute_touch_switch = true; + wacom_wac->shared->is_touch_on = true; + } + if (features->device_type != BTN_TOOL_PEN) break; /* no need to process stylus stuff */ @@ -2560,6 +2602,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, features->device_type == BTN_TOOL_FINGER) { input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); + wacom_wac->shared->has_mute_touch_switch = true; } /* fall through */ diff --git a/3.7/wacom_wac.h b/3.7/wacom_wac.h index d13909f..5b69679 100644 --- a/3.7/wacom_wac.h +++ b/3.7/wacom_wac.h @@ -189,6 +189,8 @@ struct wacom_shared { unsigned touch_max; int type; struct input_dev *touch_input; + bool has_mute_touch_switch; + bool is_touch_on; }; struct wacom_remote_data { -- 2.15.1 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel