Merge branch 'next' into for-linus
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 4 Apr 2018 23:11:49 +0000 (16:11 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 4 Apr 2018 23:11:49 +0000 (16:11 -0700)
Prepare input updates for 4.17 merge window.

1  2 
drivers/input/mouse/alps.c
drivers/input/mouse/synaptics.c
drivers/input/serio/i8042-x86ia64io.h

index 4a3bc168a4a78866a007e619c0c61d5a2ccb656e,f0b1060a7feef35f54d72c29566a96f67add9c06..0a67f235ba88a7b6e25877a43b35488a31d8fdf5
@@@ -139,11 -139,11 +139,11 @@@ static const struct alps_model_info alp
  };
  
  static const struct alps_protocol_info alps_v3_protocol_data = {
-       ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT
+       ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
  };
  
  static const struct alps_protocol_info alps_v3_rushmore_data = {
-       ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT
+       ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
  };
  
  static const struct alps_protocol_info alps_v4_protocol_data = {
@@@ -155,7 -155,7 +155,7 @@@ static const struct alps_protocol_info 
  };
  
  static const struct alps_protocol_info alps_v7_protocol_data = {
-       ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT
+       ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
  };
  
  static const struct alps_protocol_info alps_v8_protocol_data = {
@@@ -583,7 -583,7 +583,7 @@@ static void alps_process_trackstick_pac
  
        x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f));
        y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f));
-       z = (packet[4] & 0x7c) >> 2;
+       z = packet[4] & 0x7c;
  
        /*
         * The x and y values tend to be quite large, and when used
  
        input_report_rel(dev, REL_X, x);
        input_report_rel(dev, REL_Y, -y);
+       input_report_abs(dev, ABS_PRESSURE, z);
  
        /*
         * Most ALPS models report the trackstick buttons in the touchpad
@@@ -827,7 -828,7 +828,7 @@@ static void alps_process_packet_v6(stru
        unsigned char *packet = psmouse->packet;
        struct input_dev *dev = psmouse->dev;
        struct input_dev *dev2 = priv->dev2;
-       int x, y, z, left, right, middle;
+       int x, y, z;
  
        /*
         * We can use Byte5 to distinguish if the packet is from Touchpad
                x = packet[1] | ((packet[3] & 0x20) << 2);
                y = packet[2] | ((packet[3] & 0x40) << 1);
                z = packet[4];
-               left = packet[3] & 0x01;
-               right = packet[3] & 0x02;
-               middle = packet[3] & 0x04;
  
                /* To prevent the cursor jump when finger lifted */
                if (x == 0x7F && y == 0x7F && z == 0x7F)
                input_report_rel(dev2, REL_X, (char)x / 4);
                input_report_rel(dev2, REL_Y, -((char)y / 4));
  
-               input_report_key(dev2, BTN_LEFT, left);
-               input_report_key(dev2, BTN_RIGHT, right);
-               input_report_key(dev2, BTN_MIDDLE, middle);
+               psmouse_report_standard_buttons(dev2, packet[3]);
  
                input_sync(dev2);
                return;
        x = packet[1] | ((packet[3] & 0x78) << 4);
        y = packet[2] | ((packet[4] & 0x78) << 4);
        z = packet[5];
-       left = packet[3] & 0x01;
-       right = packet[3] & 0x02;
  
        if (z > 30)
                input_report_key(dev, BTN_TOUCH, 1);
        input_report_key(dev, BTN_TOOL_FINGER, z > 0);
  
        /* v6 touchpad does not have middle button */
-       input_report_key(dev, BTN_LEFT, left);
-       input_report_key(dev, BTN_RIGHT, right);
+       packet[3] &= ~BIT(2);
+       psmouse_report_standard_buttons(dev2, packet[3]);
  
        input_sync(dev);
  }
@@@ -1098,7 -1092,7 +1092,7 @@@ static void alps_process_trackstick_pac
        struct alps_data *priv = psmouse->private;
        unsigned char *packet = psmouse->packet;
        struct input_dev *dev2 = priv->dev2;
-       int x, y, z, left, right, middle;
+       int x, y, z;
  
        /* It should be a DualPoint when received trackstick packet */
        if (!(priv->flags & ALPS_DUALPOINT)) {
            ((packet[3] & 0x20) << 1);
        z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1);
  
-       left = (packet[1] & 0x01);
-       right = (packet[1] & 0x02) >> 1;
-       middle = (packet[1] & 0x04) >> 2;
        input_report_rel(dev2, REL_X, (char)x);
        input_report_rel(dev2, REL_Y, -((char)y));
+       input_report_abs(dev2, ABS_PRESSURE, z);
  
-       input_report_key(dev2, BTN_LEFT, left);
-       input_report_key(dev2, BTN_RIGHT, right);
-       input_report_key(dev2, BTN_MIDDLE, middle);
+       psmouse_report_standard_buttons(dev2, packet[1]);
  
        input_sync(dev2);
  }
@@@ -1503,10 -1492,7 +1492,7 @@@ static void alps_report_bare_ps2_packet
                alps_report_buttons(dev, dev2,
                                packet[0] & 1, packet[0] & 2, packet[0] & 4);
  
-       input_report_rel(dev, REL_X,
-               packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
-       input_report_rel(dev, REL_Y,
-               packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
+       psmouse_report_standard_motion(dev, packet);
  
        input_sync(dev);
  }
@@@ -2544,31 -2530,13 +2530,31 @@@ static int alps_update_btn_info_ss4_v2(
  }
  
  static int alps_update_dual_info_ss4_v2(unsigned char otp[][4],
 -                                     struct alps_data *priv)
 +                                      struct alps_data *priv,
 +                                      struct psmouse *psmouse)
  {
        bool is_dual = false;
 +      int reg_val = 0;
 +      struct ps2dev *ps2dev = &psmouse->ps2dev;
  
 -      if (IS_SS4PLUS_DEV(priv->dev_id))
 +      if (IS_SS4PLUS_DEV(priv->dev_id)) {
                is_dual = (otp[0][0] >> 4) & 0x01;
  
 +              if (!is_dual) {
 +                      /* For support TrackStick of Thinkpad L/E series */
 +                      if (alps_exit_command_mode(psmouse) == 0 &&
 +                              alps_enter_command_mode(psmouse) == 0) {
 +                              reg_val = alps_command_mode_read_reg(psmouse,
 +                                                                      0xD7);
 +                      }
 +                      alps_exit_command_mode(psmouse);
 +                      ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
 +
 +                      if (reg_val == 0x0C || reg_val == 0x1D)
 +                              is_dual = true;
 +              }
 +      }
 +
        if (is_dual)
                priv->flags |= ALPS_DUALPOINT |
                                        ALPS_DUALPOINT_WITH_PRESSURE;
@@@ -2591,7 -2559,7 +2577,7 @@@ static int alps_set_defaults_ss4_v2(str
  
        alps_update_btn_info_ss4_v2(otp, priv);
  
 -      alps_update_dual_info_ss4_v2(otp, priv);
 +      alps_update_dual_info_ss4_v2(otp, priv, psmouse);
  
        return 0;
  }
index a246fc686bb728dbe48b2fc84b90a1734af60c66,0d7c781674ca5afe50eab5561af3868a4817a8cf..60f2c463d1cc7d2805d9a98923ad3934d5ff2294
@@@ -84,7 -84,7 +84,7 @@@ static int synaptics_mode_cmd(struct ps
        u8 param[1];
        int error;
  
-       error = psmouse_sliced_command(psmouse, mode);
+       error = ps2_sliced_command(&psmouse->ps2dev, mode);
        if (error)
                return error;
  
@@@ -173,6 -173,7 +173,6 @@@ static const char * const smbus_pnp_ids
        "LEN0046", /* X250 */
        "LEN004a", /* W541 */
        "LEN200f", /* T450s */
 -      "LEN2018", /* T460p */
        NULL
  };
  
@@@ -189,7 -190,7 +189,7 @@@ static int synaptics_send_cmd(struct ps
  {
        int error;
  
-       error = psmouse_sliced_command(psmouse, cmd);
+       error = ps2_sliced_command(&psmouse->ps2dev, cmd);
        if (error)
                return error;
  
@@@ -546,7 -547,7 +546,7 @@@ static int synaptics_set_advanced_gestu
        static u8 param = 0xc8;
        int error;
  
-       error = psmouse_sliced_command(psmouse, SYN_QUE_MODEL);
+       error = ps2_sliced_command(&psmouse->ps2dev, SYN_QUE_MODEL);
        if (error)
                return error;
  
@@@ -613,7 -614,7 +613,7 @@@ static int synaptics_pt_write(struct se
        u8 rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
        int error;
  
-       error = psmouse_sliced_command(parent, c);
+       error = ps2_sliced_command(&parent->ps2dev, c);
        if (error)
                return error;
  
@@@ -1227,32 -1228,39 +1227,39 @@@ static void set_abs_position_params(str
        input_abs_set_res(dev, y_code, info->y_res);
  }
  
- static void set_input_params(struct psmouse *psmouse,
-                            struct synaptics_data *priv)
+ static int set_input_params(struct psmouse *psmouse,
+                           struct synaptics_data *priv)
  {
        struct input_dev *dev = psmouse->dev;
        struct synaptics_device_info *info = &priv->info;
        int i;
+       int error;
+       /* Reset default psmouse capabilities */
+       __clear_bit(EV_REL, dev->evbit);
+       bitmap_zero(dev->relbit, REL_CNT);
+       bitmap_zero(dev->keybit, KEY_CNT);
  
        /* Things that apply to both modes */
        __set_bit(INPUT_PROP_POINTER, dev->propbit);
-       __set_bit(EV_KEY, dev->evbit);
-       __set_bit(BTN_LEFT, dev->keybit);
-       __set_bit(BTN_RIGHT, dev->keybit);
  
-       if (SYN_CAP_MIDDLE_BUTTON(info->capabilities))
-               __set_bit(BTN_MIDDLE, dev->keybit);
+       input_set_capability(dev, EV_KEY, BTN_LEFT);
+       /* Clickpads report only left button */
+       if (!SYN_CAP_CLICKPAD(info->ext_cap_0c)) {
+               input_set_capability(dev, EV_KEY, BTN_RIGHT);
+               if (SYN_CAP_MIDDLE_BUTTON(info->capabilities))
+                       input_set_capability(dev, EV_KEY, BTN_MIDDLE);
+       }
  
        if (!priv->absolute_mode) {
                /* Relative mode */
-               __set_bit(EV_REL, dev->evbit);
-               __set_bit(REL_X, dev->relbit);
-               __set_bit(REL_Y, dev->relbit);
-               return;
+               input_set_capability(dev, EV_REL, REL_X);
+               input_set_capability(dev, EV_REL, REL_Y);
+               return 0;
        }
  
        /* Absolute mode */
-       __set_bit(EV_ABS, dev->evbit);
        set_abs_position_params(dev, &priv->info, ABS_X, ABS_Y);
        input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
  
                                        ABS_MT_POSITION_X, ABS_MT_POSITION_Y);
                /* Image sensors can report per-contact pressure */
                input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
-               input_mt_init_slots(dev, 2, INPUT_MT_POINTER | INPUT_MT_TRACK);
+               error = input_mt_init_slots(dev, 2,
+                                           INPUT_MT_POINTER | INPUT_MT_TRACK);
+               if (error)
+                       return error;
  
                /* Image sensors can signal 4 and 5 finger clicks */
-               __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
-               __set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
+               input_set_capability(dev, EV_KEY, BTN_TOOL_QUADTAP);
+               input_set_capability(dev, EV_KEY, BTN_TOOL_QUINTTAP);
        } else if (SYN_CAP_ADV_GESTURE(info->ext_cap_0c)) {
                set_abs_position_params(dev, info,
                                        ABS_MT_POSITION_X, ABS_MT_POSITION_Y);
                 * Profile sensor in CR-48 tracks contacts reasonably well,
                 * other non-image sensors with AGM use semi-mt.
                 */
-               input_mt_init_slots(dev, 2,
-                                   INPUT_MT_POINTER |
-                                   (cr48_profile_sensor ?
-                                       INPUT_MT_TRACK : INPUT_MT_SEMI_MT));
+               error = input_mt_init_slots(dev, 2,
+                                           INPUT_MT_POINTER |
+                                            (cr48_profile_sensor ?
+                                             INPUT_MT_TRACK :
+                                             INPUT_MT_SEMI_MT));
+               if (error)
+                       return error;
  
                /*
                 * For semi-mt devices we send ABS_X/Y ourselves instead of
        if (SYN_CAP_PALMDETECT(info->capabilities))
                input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
  
-       __set_bit(BTN_TOUCH, dev->keybit);
-       __set_bit(BTN_TOOL_FINGER, dev->keybit);
+       input_set_capability(dev, EV_KEY, BTN_TOUCH);
+       input_set_capability(dev, EV_KEY, BTN_TOOL_FINGER);
  
        if (synaptics_has_multifinger(priv)) {
-               __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
-               __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
+               input_set_capability(dev, EV_KEY, BTN_TOOL_DOUBLETAP);
+               input_set_capability(dev, EV_KEY, BTN_TOOL_TRIPLETAP);
        }
  
        if (SYN_CAP_FOUR_BUTTON(info->capabilities) ||
            SYN_CAP_MIDDLE_BUTTON(info->capabilities)) {
-               __set_bit(BTN_FORWARD, dev->keybit);
-               __set_bit(BTN_BACK, dev->keybit);
+               input_set_capability(dev, EV_KEY, BTN_FORWARD);
+               input_set_capability(dev, EV_KEY, BTN_BACK);
        }
  
        if (!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
                for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(info->ext_cap); i++)
-                       __set_bit(BTN_0 + i, dev->keybit);
-       __clear_bit(EV_REL, dev->evbit);
-       __clear_bit(REL_X, dev->relbit);
-       __clear_bit(REL_Y, dev->relbit);
+                       input_set_capability(dev, EV_KEY, BTN_0 + i);
  
        if (SYN_CAP_CLICKPAD(info->ext_cap_0c)) {
                __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
                if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
                    !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
                        __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
-               /* Clickpads report only left button */
-               __clear_bit(BTN_RIGHT, dev->keybit);
-               __clear_bit(BTN_MIDDLE, dev->keybit);
        }
+       return 0;
  }
  
  static ssize_t synaptics_show_disable_gesture(struct psmouse *psmouse,
@@@ -1563,7 -1573,12 +1572,12 @@@ static int synaptics_init_ps2(struct ps
                     info->capabilities, info->ext_cap, info->ext_cap_0c,
                     info->ext_cap_10, info->board_id, info->firmware_id);
  
-       set_input_params(psmouse, priv);
+       err = set_input_params(psmouse, priv);
+       if (err) {
+               psmouse_err(psmouse,
+                           "failed to set up capabilities: %d\n", err);
+               goto init_fail;
+       }
  
        /*
         * Encode touchpad model so that it can be used to set
index 6ca00f9ef224765455da5964f17b9c8e04ef352f,87e84a085a2359156f5e2aa1650a24200683f38d..b353d494ad404888bd2884527fe771937cb1416f
@@@ -530,6 -530,20 +530,20 @@@ static const struct dmi_system_id __ini
        { }
  };
  
+ static const struct dmi_system_id i8042_dmi_forcemux_table[] __initconst = {
+       {
+               /*
+                * Sony Vaio VGN-CS series require MUX or the touch sensor
+                * buttons will disturb touchpad operation
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"),
+               },
+       },
+       { }
+ };
  /*
   * On some Asus laptops, just running self tests cause problems.
   */
@@@ -620,13 -634,6 +634,13 @@@ static const struct dmi_system_id __ini
                        DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
                },
        },
 +      {
 +              /* Lenovo ThinkPad L460 */
 +              .matches = {
 +                      DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
 +                      DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"),
 +              },
 +      },
        {
                /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
                .matches = {
@@@ -1170,6 -1177,9 +1184,9 @@@ static int __init i8042_platform_init(v
        if (dmi_check_system(i8042_dmi_nomux_table))
                i8042_nomux = true;
  
+       if (dmi_check_system(i8042_dmi_forcemux_table))
+               i8042_nomux = false;
        if (dmi_check_system(i8042_dmi_notimeout_table))
                i8042_notimeout = true;