]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-4.1/upstream' into for-next
authorJiri Kosina <jkosina@suse.cz>
Tue, 7 Apr 2015 13:17:11 +0000 (15:17 +0200)
committerJiri Kosina <jkosina@suse.cz>
Tue, 7 Apr 2015 13:17:11 +0000 (15:17 +0200)
1  2 
drivers/input/input-mt.c

diff --combined drivers/input/input-mt.c
index cb150a1dbaff9c9e788885747113e83e8f1dbe52,f4b58f77c524a5188146dd02ba2727354ed1412b..34feb3e1127b2b64c31e8d803f98fcb5ec2aaffc
@@@ -88,10 -88,13 +88,13 @@@ int input_mt_init_slots(struct input_de
                        goto err_mem;
        }
  
-       /* Mark slots as 'unused' */
+       /* Mark slots as 'inactive' */
        for (i = 0; i < num_slots; i++)
                input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1);
  
+       /* Mark slots as 'unused' */
+       mt->frame = 1;
        dev->mt = mt;
        return 0;
  err_mem:
@@@ -293,7 -296,7 +296,7 @@@ void input_mt_sync_frame(struct input_d
  }
  EXPORT_SYMBOL(input_mt_sync_frame);
  
 -static int adjust_dual(int *begin, int step, int *end, int eq)
 +static int adjust_dual(int *begin, int step, int *end, int eq, int mu)
  {
        int f, *p, s, c;
  
                        s = *p;
  
        c = (f + s + 1) / 2;
 -      if (c == 0 || (c > 0 && !eq))
 +      if (c == 0 || (c > mu && (!eq || mu > 0)))
                return 0;
 -      if (s < 0)
 +      /* Improve convergence for positive matrices by penalizing overcovers */
 +      if (s < 0 && mu <= 0)
                c *= 2;
  
        for (p = begin; p != end; p += step)
        return (c < s && s <= 0) || (f >= 0 && f < c);
  }
  
 -static void find_reduced_matrix(int *w, int nr, int nc, int nrc)
 +static void find_reduced_matrix(int *w, int nr, int nc, int nrc, int mu)
  {
        int i, k, sum;
  
        for (k = 0; k < nrc; k++) {
                for (i = 0; i < nr; i++)
 -                      adjust_dual(w + i, nr, w + i + nrc, nr <= nc);
 +                      adjust_dual(w + i, nr, w + i + nrc, nr <= nc, mu);
                sum = 0;
                for (i = 0; i < nrc; i += nr)
 -                      sum += adjust_dual(w + i, 1, w + i + nr, nc <= nr);
 +                      sum += adjust_dual(w + i, 1, w + i + nr, nc <= nr, mu);
                if (!sum)
                        break;
        }
  }
  
  static int input_mt_set_matrix(struct input_mt *mt,
 -                             const struct input_mt_pos *pos, int num_pos)
 +                             const struct input_mt_pos *pos, int num_pos,
 +                             int mu)
  {
        const struct input_mt_pos *p;
        struct input_mt_slot *s;
                y = input_mt_get_value(s, ABS_MT_POSITION_Y);
                for (p = pos; p != pos + num_pos; p++) {
                        int dx = x - p->x, dy = y - p->y;
 -                      *w++ = dx * dx + dy * dy;
 +                      *w++ = dx * dx + dy * dy - mu;
                }
        }
  
@@@ -395,24 -396,17 +398,24 @@@ static void input_mt_set_slots(struct i
   * @slots: the slot assignment to be filled
   * @pos: the position array to match
   * @num_pos: number of positions
 + * @dmax: maximum ABS_MT_POSITION displacement (zero for infinite)
   *
   * Performs a best match against the current contacts and returns
   * the slot assignment list. New contacts are assigned to unused
   * slots.
   *
 + * The assignments are balanced so that all coordinate displacements are
 + * below the euclidian distance dmax. If no such assignment can be found,
 + * some contacts are assigned to unused slots.
 + *
   * Returns zero on success, or negative error in case of failure.
   */
  int input_mt_assign_slots(struct input_dev *dev, int *slots,
 -                        const struct input_mt_pos *pos, int num_pos)
 +                        const struct input_mt_pos *pos, int num_pos,
 +                        int dmax)
  {
        struct input_mt *mt = dev->mt;
 +      int mu = 2 * dmax * dmax;
        int nrc;
  
        if (!mt || !mt->red)
        if (num_pos < 1)
                return 0;
  
 -      nrc = input_mt_set_matrix(mt, pos, num_pos);
 -      find_reduced_matrix(mt->red, num_pos, nrc / num_pos, nrc);
 +      nrc = input_mt_set_matrix(mt, pos, num_pos, mu);
 +      find_reduced_matrix(mt->red, num_pos, nrc / num_pos, nrc, mu);
        input_mt_set_slots(mt, slots, num_pos);
  
        return 0;
@@@ -439,6 -433,8 +442,8 @@@ EXPORT_SYMBOL(input_mt_assign_slots)
   * set the key on the first unused slot and return.
   *
   * If no available slot can be found, -1 is returned.
+  * Note that for this function to work properly, input_mt_sync_frame() has
+  * to be called at each frame.
   */
  int input_mt_get_slot_by_key(struct input_dev *dev, int key)
  {
                        return s - mt->slots;
  
        for (s = mt->slots; s != mt->slots + mt->num_slots; s++)
-               if (!input_mt_is_active(s)) {
+               if (!input_mt_is_active(s) && !input_mt_is_used(mt, s)) {
                        s->key = key;
                        return s - mt->slots;
                }