Merge tag 'v3.17' into next
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 11 Oct 2014 18:34:07 +0000 (11:34 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 11 Oct 2014 18:34:07 +0000 (11:34 -0700)
Synchronize with mainline to bring in changes to Synaptics and i8042
drivers.

1  2 
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/synaptics.c

index 3ab941d425ae8837927baf81455aee792b170256,b4e1f014ddc2297affeda8abc73c15954fdfabf0..26994f6a2b2ae7abe3f04a953eab9004b25d40d1
@@@ -35,7 -35,6 +35,7 @@@
  #include "elantech.h"
  #include "sentelic.h"
  #include "cypress_ps2.h"
 +#include "focaltech.h"
  
  #define DRIVER_DESC   "PS/2 mouse driver"
  
@@@ -463,20 -462,6 +463,20 @@@ static int psmouse_poll(struct psmouse 
                           PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
  }
  
 +/*
 + * psmouse_matches_pnp_id - check if psmouse matches one of the passed in ids.
 + */
 +bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[])
 +{
 +      int i;
 +
 +      if (!strncmp(psmouse->ps2dev.serio->firmware_id, "PNP:", 4))
 +              for (i = 0; ids[i]; i++)
 +                      if (strstr(psmouse->ps2dev.serio->firmware_id, ids[i]))
 +                              return true;
 +
 +      return false;
 +}
  
  /*
   * Genius NetMouse magic init.
@@@ -685,6 -670,8 +685,8 @@@ static void psmouse_apply_defaults(stru
        __set_bit(REL_X, input_dev->relbit);
        __set_bit(REL_Y, input_dev->relbit);
  
+       __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
        psmouse->set_rate = psmouse_set_rate;
        psmouse->set_resolution = psmouse_set_resolution;
        psmouse->poll = psmouse_poll;
@@@ -721,21 -708,6 +723,21 @@@ static int psmouse_extensions(struct ps
  {
        bool synaptics_hardware = false;
  
 +/* Always check for focaltech, this is safe as it uses pnp-id matching */
 +      if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) {
 +              if (!set_properties || focaltech_init(psmouse) == 0) {
 +                      /*
 +                       * Not supported yet, use bare protocol.
 +                       * Note that we need to also restrict
 +                       * psmouse_max_proto so that psmouse_initialize()
 +                       * does not try to reset rate and resolution,
 +                       * because even that upsets the device.
 +                       */
 +                      psmouse_max_proto = PSMOUSE_PS2;
 +                      return PSMOUSE_PS2;
 +              }
 +      }
 +
  /*
   * We always check for lifebook because it does not disturb mouse
   * (it only checks DMI information).
index 854caca6e86e2db0e19dfecc1ec549b233221861,fd23181c1fb741112f1cc33fa0fc6111284823c3..6394d9b5bfd35526e7f093543cfab67fcf6ec0e2
@@@ -185,6 -185,18 +185,6 @@@ static const char * const topbuttonpad_
        NULL
  };
  
 -static bool matches_pnp_id(struct psmouse *psmouse, const char * const ids[])
 -{
 -      int i;
 -
 -      if (!strncmp(psmouse->ps2dev.serio->firmware_id, "PNP:", 4))
 -              for (i = 0; ids[i]; i++)
 -                      if (strstr(psmouse->ps2dev.serio->firmware_id, ids[i]))
 -                              return true;
 -
 -      return false;
 -}
 -
  /*****************************************************************************
   *    Synaptics communications functions
   ****************************************************************************/
@@@ -350,8 -362,7 +350,8 @@@ static int synaptics_resolution(struct 
        }
  
        for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) {
 -              if (matches_pnp_id(psmouse, min_max_pnpid_table[i].pnp_ids)) {
 +              if (psmouse_matches_pnp_id(psmouse,
 +                                         min_max_pnpid_table[i].pnp_ids)) {
                        priv->x_min = min_max_pnpid_table[i].x_min;
                        priv->x_max = min_max_pnpid_table[i].x_max;
                        priv->y_min = min_max_pnpid_table[i].y_min;
@@@ -618,10 -629,61 +618,61 @@@ static int synaptics_parse_hw_state(con
                         ((buf[0] & 0x04) >> 1) |
                         ((buf[3] & 0x04) >> 2));
  
+               if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
+                       SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) &&
+                   hw->w == 2) {
+                       synaptics_parse_agm(buf, priv, hw);
+                       return 1;
+               }
+               hw->x = (((buf[3] & 0x10) << 8) |
+                        ((buf[1] & 0x0f) << 8) |
+                        buf[4]);
+               hw->y = (((buf[3] & 0x20) << 7) |
+                        ((buf[1] & 0xf0) << 4) |
+                        buf[5]);
+               hw->z = buf[2];
                hw->left  = (buf[0] & 0x01) ? 1 : 0;
                hw->right = (buf[0] & 0x02) ? 1 : 0;
  
-               if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
+               if (SYN_CAP_FORCEPAD(priv->ext_cap_0c)) {
+                       /*
+                        * ForcePads, like Clickpads, use middle button
+                        * bits to report primary button clicks.
+                        * Unfortunately they report primary button not
+                        * only when user presses on the pad above certain
+                        * threshold, but also when there are more than one
+                        * finger on the touchpad, which interferes with
+                        * out multi-finger gestures.
+                        */
+                       if (hw->z == 0) {
+                               /* No contacts */
+                               priv->press = priv->report_press = false;
+                       } else if (hw->w >= 4 && ((buf[0] ^ buf[3]) & 0x01)) {
+                               /*
+                                * Single-finger touch with pressure above
+                                * the threshold. If pressure stays long
+                                * enough, we'll start reporting primary
+                                * button. We rely on the device continuing
+                                * sending data even if finger does not
+                                * move.
+                                */
+                               if  (!priv->press) {
+                                       priv->press_start = jiffies;
+                                       priv->press = true;
+                               } else if (time_after(jiffies,
+                                               priv->press_start +
+                                                       msecs_to_jiffies(50))) {
+                                       priv->report_press = true;
+                               }
+                       } else {
+                               priv->press = false;
+                       }
+                       hw->left = priv->report_press;
+               } else if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
                        /*
                         * Clickpad's button is transmitted as middle button,
                         * however, since it is primary button, we will report
                        hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
                }
  
-               if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
-                       SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) &&
-                   hw->w == 2) {
-                       synaptics_parse_agm(buf, priv, hw);
-                       return 1;
-               }
-               hw->x = (((buf[3] & 0x10) << 8) |
-                        ((buf[1] & 0x0f) << 8) |
-                        buf[4]);
-               hw->y = (((buf[3] & 0x20) << 7) |
-                        ((buf[1] & 0xf0) << 4) |
-                        buf[5]);
-               hw->z = buf[2];
                if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
                    ((buf[0] ^ buf[3]) & 0x02)) {
                        switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
@@@ -1445,7 -1492,7 +1481,7 @@@ static void set_input_params(struct psm
  
        if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
                __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
 -              if (matches_pnp_id(psmouse, topbuttonpad_pnp_ids))
 +              if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids))
                        __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
                /* Clickpads report only left button */
                __clear_bit(BTN_RIGHT, dev->keybit);