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

Reply via email to