aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorDaniel Kurtz <djkurtz@chromium.org>2011-08-24 02:02:31 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-08-24 02:08:16 -0400
commita6ca40c11eb5d98e53176adf527e430f7037a8c9 (patch)
tree74d08548873d3b6a9d58c8f0728025881d818b58 /drivers/input/mouse
parent3cdfee9ea7e98eb6e8c3d4d66f2dfcfffe6afc4d (diff)
Input: synaptics - decode AGM packet types
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 <djkurtz@chromium.org> Acked-by: Chase Douglas <chase.douglas@canonical.com> Acked-by: Henrik Rydberg <rydberg@euromail.se> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/synaptics.c36
-rw-r--r--drivers/input/mouse/synaptics.h14
2 files changed, 43 insertions, 7 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index e6e59c59391d..a7af8565e2de 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)
420 * Functions to interpret the absolute mode packets 420 * Functions to interpret the absolute mode packets
421 ****************************************************************************/ 421 ****************************************************************************/
422 422
423static void synaptics_mt_state_set(struct synaptics_mt_state *state, int count,
424 int sgm, int agm)
425{
426 state->count = count;
427 state->sgm = sgm;
428 state->agm = agm;
429}
430
423static void synaptics_parse_agm(const unsigned char buf[], 431static void synaptics_parse_agm(const unsigned char buf[],
424 struct synaptics_data *priv) 432 struct synaptics_data *priv,
433 struct synaptics_hw_state *hw)
425{ 434{
426 struct synaptics_hw_state *agm = &priv->agm; 435 struct synaptics_hw_state *agm = &priv->agm;
436 int agm_packet_type;
437
438 agm_packet_type = (buf[5] & 0x30) >> 4;
439 switch (agm_packet_type) {
440 case 1:
441 /* Gesture packet: (x, y, z) half resolution */
442 agm->w = hw->w;
443 agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;
444 agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;
445 agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;
446 break;
427 447
428 /* Gesture packet: (x, y, z) at half resolution */ 448 case 2:
429 agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; 449 /* AGM-CONTACT packet: (count, sgm, agm) */
430 agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; 450 synaptics_mt_state_set(&agm->mt_state, buf[1], buf[2], buf[4]);
431 agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; 451 break;
452
453 default:
454 break;
455 }
432} 456}
433 457
434static int synaptics_parse_hw_state(const unsigned char buf[], 458static int synaptics_parse_hw_state(const unsigned char buf[],
@@ -467,7 +491,7 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
467 if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || 491 if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
468 SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) && 492 SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) &&
469 hw->w == 2) { 493 hw->w == 2) {
470 synaptics_parse_agm(buf, priv); 494 synaptics_parse_agm(buf, priv, hw);
471 return 1; 495 return 1;
472 } 496 }
473 497
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 0ea7616e8fe1..20f57dfebed1 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -115,9 +115,18 @@
115#define SYN_REDUCED_FILTER_FUZZ 8 115#define SYN_REDUCED_FILTER_FUZZ 8
116 116
117/* 117/*
118 * A structure to describe the state of the touchpad hardware (buttons and pad) 118 * A structure to describe which internal touchpad finger slots are being
119 * reported in raw packets.
119 */ 120 */
121struct synaptics_mt_state {
122 int count; /* num fingers being tracked */
123 int sgm; /* which slot is reported by sgm pkt */
124 int agm; /* which slot is reported by agm pkt*/
125};
120 126
127/*
128 * A structure to describe the state of the touchpad hardware (buttons and pad)
129 */
121struct synaptics_hw_state { 130struct synaptics_hw_state {
122 int x; 131 int x;
123 int y; 132 int y;
@@ -130,6 +139,9 @@ struct synaptics_hw_state {
130 unsigned int down:1; 139 unsigned int down:1;
131 unsigned char ext_buttons; 140 unsigned char ext_buttons;
132 signed char scroll; 141 signed char scroll;
142
143 /* As reported in last AGM-CONTACT packets */
144 struct synaptics_mt_state mt_state;
133}; 145};
134 146
135struct synaptics_data { 147struct synaptics_data {