diff options
Diffstat (limited to 'drivers/input/mouse/synaptics.c')
-rw-r--r-- | drivers/input/mouse/synaptics.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index aec9cf7124f..30c85a5b718 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 */ | ||
919 | static 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 | |||
889 | static void synaptics_image_sensor_process(struct psmouse *psmouse, | 926 | static 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); |