From patchwork Thu Aug 18 11:28:04 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Kurtz X-Patchwork-Id: 1076262 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p7IBTsSh024772 for ; Thu, 18 Aug 2011 11:30:03 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755744Ab1HRLaA (ORCPT ); Thu, 18 Aug 2011 07:30:00 -0400 Received: from smtp-out.google.com ([74.125.121.67]:26716 "EHLO smtp-out.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755547Ab1HRL2S (ORCPT ); Thu, 18 Aug 2011 07:28:18 -0400 Received: from hpaq11.eem.corp.google.com (hpaq11.eem.corp.google.com [172.25.149.11]) by smtp-out.google.com with ESMTP id p7IBSDTc024507; Thu, 18 Aug 2011 04:28:13 -0700 Received: from puck.tpe.corp.google.com (puck.tpe.corp.google.com [172.30.210.35]) by hpaq11.eem.corp.google.com with ESMTP id p7IBSAdJ011185; Thu, 18 Aug 2011 04:28:11 -0700 Received: by puck.tpe.corp.google.com (Postfix, from userid 116377) id F15F380A4B; Thu, 18 Aug 2011 19:28:09 +0800 (CST) From: Daniel Kurtz To: chase.douglas@canonical.com, dmitry.torokhov@gmail.com, rydberg@euromail.se Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, olofj@chromium.org, chris@cnpbagwell.com, Daniel Kurtz Subject: [PATCH 5/9 v4] Input: synaptics - decode AGM packet types Date: Thu, 18 Aug 2011 19:28:04 +0800 Message-Id: <1313666888-18939-6-git-send-email-djkurtz@chromium.org> X-Mailer: git-send-email 1.7.3.1 In-Reply-To: <1313666888-18939-1-git-send-email-djkurtz@chromium.org> References: <1313666888-18939-1-git-send-email-djkurtz@chromium.org> X-System-Of-Record: true Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 18 Aug 2011 11:30:03 +0000 (UTC) A Synaptics image sensor tracks 5 fingers, but can only report 2. The algorithm for choosing which 2 fingers to report and in which packet: Touchpad maintains 5 slots, numbered 0 to 4 Initially all slots are empty As new fingers are detected, assign them to the lowest available slots The touchpad always reports: SGM: lowest numbered non-empty slot AGM: highest numbered non-empty slot, if there is one In addition, these touchpads have a special AGM packet type which reports the number of fingers currently being tracked, and which finger is in each of the two slots. Unfortunately, these "TYPE=2" packets are only used when more than 3 fingers are being tracked. When less than 4 fingers are present, the 'w' value must be used to track how many fingers are present, and knowing which fingers are being reported is much more difficult, if not impossible. Signed-off-by: Daniel Kurtz Acked-by: Chase Douglas --- drivers/input/mouse/synaptics.c | 38 +++++++++++++++++++++++++++++++------- drivers/input/mouse/synaptics.h | 14 +++++++++++++- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index a49420f..ad0a5aa 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -420,15 +420,39 @@ static void synaptics_pt_create(struct psmouse *psmouse) * Functions to interpret the absolute mode packets ****************************************************************************/ +static void synaptics_mt_state_set(struct synaptics_mt_state *state, int count, + int sgm, int agm) +{ + state->count = count; + state->sgm = sgm; + state->agm = agm; +} + static void synaptics_parse_agm(const unsigned char buf[], - struct synaptics_data *priv) + struct synaptics_data *priv, + struct synaptics_hw_state *hw) { struct synaptics_hw_state *agm = &priv->agm; + int agm_packet_type; + + agm_packet_type = (buf[5] & 0x30) >> 4; + switch (agm_packet_type) { + case 1: + /* Gesture packet: (x, y, z) half resolution */ + agm->w = hw->w; + agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; + agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; + agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; + break; - /* Gesture packet: (x, y, z) at half resolution */ - agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; - agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; - agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; + case 2: + /* AGM-CONTACT packet: (count, sgm, agm) */ + synaptics_mt_state_set(&agm->mt_state, buf[1], buf[2], buf[4]); + break; + + default: + break; + } } static int synaptics_parse_hw_state(const unsigned char buf[], @@ -467,7 +491,7 @@ static int synaptics_parse_hw_state(const unsigned char buf[], 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); + synaptics_parse_agm(buf, priv, hw); return 1; } diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 0ea7616..20f57df 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -115,9 +115,18 @@ #define SYN_REDUCED_FILTER_FUZZ 8 /* - * A structure to describe the state of the touchpad hardware (buttons and pad) + * A structure to describe which internal touchpad finger slots are being + * reported in raw packets. */ +struct synaptics_mt_state { + int count; /* num fingers being tracked */ + int sgm; /* which slot is reported by sgm pkt */ + int agm; /* which slot is reported by agm pkt*/ +}; +/* + * A structure to describe the state of the touchpad hardware (buttons and pad) + */ struct synaptics_hw_state { int x; int y; @@ -130,6 +139,9 @@ struct synaptics_hw_state { unsigned int down:1; unsigned char ext_buttons; signed char scroll; + + /* As reported in last AGM-CONTACT packets */ + struct synaptics_mt_state mt_state; }; struct synaptics_data {