lkml.org 
[lkml]   [2011]   [Jul]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRe: [PATCH 9/9 v2] Input: synaptics - process finger (<=5) transitions
    Hi Chase,

    Thanks for all of your reviews!

    On Sat, Jul 23, 2011 at 9:02 AM, Chase Douglas
    <chase.douglas@canonical.com> wrote:
    >
    > On 07/20/2011 06:39 AM, djkurtz@chromium.org wrote:
    > > From: Daniel Kurtz <djkurtz@chromium.org>
    > >
    > > Synaptics image sensor touchpads track up to 5 fingers, but only report 2.
    > > They use a special "TYPE=2" (AGM-CONTACT) packet type that reports
    > > the number of tracked fingers and which finger is reported in the SGM
    > > and AGM packets.
    > >
    > > With this new packet type, it is possible to tell userspace when 4 or 5
    > > fingers are touching.
    >
    > Maybe I'm blind, but I don't see where the QUADTAP and QUINTAP values
    > are set in the events. I see where the bits are set during
    > initialization, but not during use.

    It's subtle.
    The firmware actually report 4/5 in the AGM-CONTACT packet, which the
    agm packet parser sets directly in mt_state->count.
    This is then reported to userspace when synaptics_report_mt() calls
    input_mt_report_finger_count(dev, mt_state->count), which now supports
    QUINTTAP (see patch #8).

    -Daniel

    >
    > > Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
    > > ---
    > >  drivers/input/mouse/synaptics.c |   44 ++++++++++++++++++++++++++++++++++++++-
    > >  1 files changed, 43 insertions(+), 1 deletions(-)
    > >
    > > diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
    > > index 893e567..2a1e05f 100644
    > > --- a/drivers/input/mouse/synaptics.c
    > > +++ b/drivers/input/mouse/synaptics.c
    > > @@ -729,6 +729,10 @@ static void synaptics_image_sensor_1f(struct synaptics_data *priv,
    > >               synaptics_mt_state_set(mt_state, 0, -1, -1);
    > >               priv->mt_state_lost = true;
    > >               break;
    > > +     case 4:
    > > +     case 5:
    > > +             /* mt_state was updated by AGM-CONTACT packet */
    > > +             break;
    > >       }
    > >  }
    > >
    > > @@ -775,6 +779,10 @@ static void synaptics_image_sensor_2f(struct synaptics_data *priv,
    > >               synaptics_mt_state_set(mt_state, 0, -1, -1);
    > >               priv->mt_state_lost = true;
    > >               break;
    > > +     case 4:
    > > +     case 5:
    > > +             /* mt_state was updated by AGM-CONTACT packet */
    > > +             break;
    > >       }
    > >  }
    > >
    > > @@ -803,6 +811,22 @@ static void synaptics_image_sensor_3f(struct synaptics_data *priv,
    > >               break;
    > >       case 2:
    > >               /*
    > > +              * If the AGM previously contained slot 3 or higher, then the
    > > +              * newly touching finger is in the lowest available slot.
    > > +              *
    > > +              * If SGM was previously 1 or higher, then the new SGM is
    > > +              * now slot 0 (with a new finger), otherwise, the new finger
    > > +              * is now in a hidden slot between 0 and AGM's slot.
    > > +              *
    > > +              * In all such cases, the SGM now contains slot 0, and the AGM
    > > +              * continues to contain the same slot as before.
    > > +              */
    > > +             if (old->agm >= 3) {
    > > +                     synaptics_mt_state_set(mt_state, 3, 0, old->agm);
    > > +                     break;
    > > +             }
    > > +
    > > +             /*
    > >                * After some 3->1 and all 3->2 transitions, we lose track
    > >                * of which slot is reported by sgm and agm.
    > >                *
    > > @@ -836,9 +860,22 @@ static void synaptics_image_sensor_3f(struct synaptics_data *priv,
    > >                * received AGM-CONTACT packet.
    > >                */
    > >               break;
    > > +
    > > +     case 4:
    > > +     case 5:
    > > +             /* mt_state was updated by AGM-CONTACT packet */
    > > +             break;
    > >       }
    > >  }
    > >
    > > +/* Handle case where mt_state->count = 4, or = 5 */
    > > +static void synaptics_image_sensor_45f(struct synaptics_data *priv,
    > > +                                    struct synaptics_mt_state *mt_state)
    > > +{
    > > +     /* mt_state was updated correctly by AGM-CONTACT packet */
    > > +     priv->mt_state_lost = false;
    > > +}
    > > +
    > >  static void synaptics_image_sensor_process(struct psmouse *psmouse,
    > >                                          struct synaptics_hw_state *sgm)
    > >  {
    > > @@ -858,8 +895,10 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse,
    > >               synaptics_image_sensor_1f(priv, &mt_state);
    > >       else if (sgm->w == 0)
    > >               synaptics_image_sensor_2f(priv, &mt_state);
    > > -     else if (sgm->w == 1)
    > > +     else if (sgm->w == 1 && mt_state.count <= 3)
    > >               synaptics_image_sensor_3f(priv, &mt_state);
    > > +     else
    > > +             synaptics_image_sensor_45f(priv, &mt_state);
    > >
    > >       /* Send resulting input events to user space */
    > >       synaptics_report_mt(psmouse, &mt_state, sgm);
    > > @@ -1078,6 +1117,9 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
    > >               input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
    > >               /* Image sensors can sometimes report per-contact width */
    > >               input_set_abs_params(dev, ABS_MT_TOUCH_MAJOR, 4, 15, 0, 0);
    > > +             /* Image sensors can signal 4 and 5 finger clicks */
    > > +             __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
    > > +             __set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
    > >       } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
    > >               /* Non-image sensors with AGM use semi-mt */
    > >               __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
    >
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2011-07-23 06:15    [W:0.031 / U:1.256 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site