]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Sep 2017 17:43:37 +0000 (10:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Sep 2017 17:43:37 +0000 (10:43 -0700)
Pull input fixes from Dmitry Torokhov:
 "Just a couple drivers fixes (Synaptics PS/2, Xpad)"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: xpad - fix PowerA init quirk for some gamepad models
  Input: synaptics - fix device info appearing different on reconnect

drivers/input/joystick/xpad.c
drivers/input/mouse/synaptics.c

index 298a6ba51411a2d68795f34b41c380df85fdfbc6..ca0e19ae7a90f0a2854938f926c5d7ece0675686 100644 (file)
@@ -476,10 +476,21 @@ static const u8 xboxone_hori_init[] = {
 };
 
 /*
- * A rumble packet is required for some PowerA pads to start
+ * A specific rumble packet is required for some PowerA pads to start
  * sending input reports. One of those pads is (0x24c6:0x543a).
  */
-static const u8 xboxone_zerorumble_init[] = {
+static const u8 xboxone_rumblebegin_init[] = {
+       0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
+       0x1D, 0x1D, 0xFF, 0x00, 0x00
+};
+
+/*
+ * A rumble packet with zero FF intensity will immediately
+ * terminate the rumbling required to init PowerA pads.
+ * This should happen fast enough that the motors don't
+ * spin up to enough speed to actually vibrate the gamepad.
+ */
+static const u8 xboxone_rumbleend_init[] = {
        0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00
 };
@@ -494,9 +505,12 @@ static const struct xboxone_init_packet xboxone_init_packets[] = {
        XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
        XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
        XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
-       XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_zerorumble_init),
-       XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_zerorumble_init),
-       XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_zerorumble_init),
+       XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
+       XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init),
+       XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init),
+       XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumbleend_init),
+       XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumbleend_init),
+       XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumbleend_init),
 };
 
 struct xpad_output_packet {
index 16c30460ef041b13686db7f6efe36860b725a4bd..5af0b7d200bc23ff0f2287d6e0b69a631fb8bb22 100644 (file)
@@ -535,16 +535,17 @@ static void synaptics_apply_quirks(struct psmouse *psmouse,
        }
 }
 
+static bool synaptics_has_agm(struct synaptics_data *priv)
+{
+       return (SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) ||
+               SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c));
+}
+
 static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
 {
        static u8 param = 0xc8;
-       struct synaptics_data *priv = psmouse->private;
        int error;
 
-       if (!(SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) ||
-             SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c)))
-               return 0;
-
        error = psmouse_sliced_command(psmouse, SYN_QUE_MODEL);
        if (error)
                return error;
@@ -553,9 +554,6 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
        if (error)
                return error;
 
-       /* Advanced gesture mode also sends multi finger data */
-       priv->info.capabilities |= BIT(1);
-
        return 0;
 }
 
@@ -578,7 +576,7 @@ static int synaptics_set_mode(struct psmouse *psmouse)
        if (error)
                return error;
 
-       if (priv->absolute_mode) {
+       if (priv->absolute_mode && synaptics_has_agm(priv)) {
                error = synaptics_set_advanced_gesture_mode(psmouse);
                if (error) {
                        psmouse_err(psmouse,
@@ -766,9 +764,7 @@ static int synaptics_parse_hw_state(const u8 buf[],
                         ((buf[0] & 0x04) >> 1) |
                         ((buf[3] & 0x04) >> 2));
 
-               if ((SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) ||
-                       SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c)) &&
-                   hw->w == 2) {
+               if (synaptics_has_agm(priv) && hw->w == 2) {
                        synaptics_parse_agm(buf, priv, hw);
                        return 1;
                }
@@ -1033,6 +1029,15 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse,
        synaptics_report_mt_data(psmouse, sgm, num_fingers);
 }
 
+static bool synaptics_has_multifinger(struct synaptics_data *priv)
+{
+       if (SYN_CAP_MULTIFINGER(priv->info.capabilities))
+               return true;
+
+       /* Advanced gesture mode also sends multi finger data */
+       return synaptics_has_agm(priv);
+}
+
 /*
  *  called for each full received packet from the touchpad
  */
@@ -1079,7 +1084,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
                if (SYN_CAP_EXTENDED(info->capabilities)) {
                        switch (hw.w) {
                        case 0 ... 1:
-                               if (SYN_CAP_MULTIFINGER(info->capabilities))
+                               if (synaptics_has_multifinger(priv))
                                        num_fingers = hw.w + 2;
                                break;
                        case 2:
@@ -1123,7 +1128,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
                input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
 
        input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
-       if (SYN_CAP_MULTIFINGER(info->capabilities)) {
+       if (synaptics_has_multifinger(priv)) {
                input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
                input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
        }
@@ -1283,7 +1288,7 @@ static void set_input_params(struct psmouse *psmouse,
        __set_bit(BTN_TOUCH, dev->keybit);
        __set_bit(BTN_TOOL_FINGER, dev->keybit);
 
-       if (SYN_CAP_MULTIFINGER(info->capabilities)) {
+       if (synaptics_has_multifinger(priv)) {
                __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
                __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
        }