aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/synaptics.c
diff options
context:
space:
mode:
authorDaniel Kurtz <djkurtz@chromium.org>2011-08-24 02:02:56 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-08-24 02:08:32 -0400
commit6b4b49fea15ea3034e22ad4ca85f23c000b88e92 (patch)
treecefa2220d3e9dc8906390f2abec84cc48a9d5cb3 /drivers/input/mouse/synaptics.c
parentd5051272fc4860e056e34c92080369a1b63c9378 (diff)
Input: synaptics - process finger (<=5) transitions
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. 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/synaptics.c')
-rw-r--r--drivers/input/mouse/synaptics.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index aec9cf7124f8..30c85a5b7184 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -762,6 +762,10 @@ static void synaptics_image_sensor_1f(struct synaptics_data *priv,
762 synaptics_mt_state_set(mt_state, 1, -1, -1); 762 synaptics_mt_state_set(mt_state, 1, -1, -1);
763 priv->mt_state_lost = true; 763 priv->mt_state_lost = true;
764 break; 764 break;
765 case 4:
766 case 5:
767 /* mt_state was updated by AGM-CONTACT packet */
768 break;
765 } 769 }
766} 770}
767 771
@@ -816,6 +820,10 @@ static void synaptics_image_sensor_2f(struct synaptics_data *priv,
816 synaptics_mt_state_set(mt_state, 2, -1, -1); 820 synaptics_mt_state_set(mt_state, 2, -1, -1);
817 priv->mt_state_lost = true; 821 priv->mt_state_lost = true;
818 break; 822 break;
823 case 4:
824 case 5:
825 /* mt_state was updated by AGM-CONTACT packet */
826 break;
819 } 827 }
820} 828}
821 829
@@ -844,6 +852,22 @@ static void synaptics_image_sensor_3f(struct synaptics_data *priv,
844 break; 852 break;
845 case 2: 853 case 2:
846 /* 854 /*
855 * If the AGM previously contained slot 3 or higher, then the
856 * newly touching finger is in the lowest available slot.
857 *
858 * If SGM was previously 1 or higher, then the new SGM is
859 * now slot 0 (with a new finger), otherwise, the new finger
860 * is now in a hidden slot between 0 and AGM's slot.
861 *
862 * In all such cases, the SGM now contains slot 0, and the AGM
863 * continues to contain the same slot as before.
864 */
865 if (old->agm >= 3) {
866 synaptics_mt_state_set(mt_state, 3, 0, old->agm);
867 break;
868 }
869
870 /*
847 * After some 3->1 and all 3->2 transitions, we lose track 871 * After some 3->1 and all 3->2 transitions, we lose track
848 * of which slot is reported by SGM and AGM. 872 * of which slot is reported by SGM and AGM.
849 * 873 *
@@ -883,9 +907,22 @@ static void synaptics_image_sensor_3f(struct synaptics_data *priv,
883 * received AGM-CONTACT packet. 907 * received AGM-CONTACT packet.
884 */ 908 */
885 break; 909 break;
910
911 case 4:
912 case 5:
913 /* mt_state was updated by AGM-CONTACT packet */
914 break;
886 } 915 }
887} 916}
888 917
918/* Handle case where mt_state->count = 4, or = 5 */
919static void synaptics_image_sensor_45f(struct synaptics_data *priv,
920 struct synaptics_mt_state *mt_state)
921{
922 /* mt_state was updated correctly by AGM-CONTACT packet */
923 priv->mt_state_lost = false;
924}
925
889static void synaptics_image_sensor_process(struct psmouse *psmouse, 926static void synaptics_image_sensor_process(struct psmouse *psmouse,
890 struct synaptics_hw_state *sgm) 927 struct synaptics_hw_state *sgm)
891{ 928{
@@ -905,8 +942,10 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse,
905 synaptics_image_sensor_1f(priv, &mt_state); 942 synaptics_image_sensor_1f(priv, &mt_state);
906 else if (sgm->w == 0) 943 else if (sgm->w == 0)
907 synaptics_image_sensor_2f(priv, &mt_state); 944 synaptics_image_sensor_2f(priv, &mt_state);
908 else if (sgm->w == 1) 945 else if (sgm->w == 1 && mt_state.count <= 3)
909 synaptics_image_sensor_3f(priv, &mt_state); 946 synaptics_image_sensor_3f(priv, &mt_state);
947 else
948 synaptics_image_sensor_45f(priv, &mt_state);
910 949
911 /* Send resulting input events to user space */ 950 /* Send resulting input events to user space */
912 synaptics_report_mt_data(psmouse, &mt_state, sgm); 951 synaptics_report_mt_data(psmouse, &mt_state, sgm);
@@ -1110,6 +1149,10 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
1110 ABS_MT_POSITION_Y); 1149 ABS_MT_POSITION_Y);
1111 /* Image sensors can report per-contact pressure */ 1150 /* Image sensors can report per-contact pressure */
1112 input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); 1151 input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
1152
1153 /* Image sensors can signal 4 and 5 finger clicks */
1154 __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
1155 __set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
1113 } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { 1156 } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
1114 /* Non-image sensors with AGM use semi-mt */ 1157 /* Non-image sensors with AGM use semi-mt */
1115 __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); 1158 __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);