diff options
Diffstat (limited to 'drivers/input/mouse/alps.c')
-rw-r--r-- | drivers/input/mouse/alps.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 2b0ae8cc8e51..d125a019383f 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -1156,7 +1156,13 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
1156 | { | 1156 | { |
1157 | struct alps_data *priv = psmouse->private; | 1157 | struct alps_data *priv = psmouse->private; |
1158 | 1158 | ||
1159 | if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ | 1159 | /* |
1160 | * Check if we are dealing with a bare PS/2 packet, presumably from | ||
1161 | * a device connected to the external PS/2 port. Because bare PS/2 | ||
1162 | * protocol does not have enough constant bits to self-synchronize | ||
1163 | * properly we only do this if the device is fully synchronized. | ||
1164 | */ | ||
1165 | if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) { | ||
1160 | if (psmouse->pktcnt == 3) { | 1166 | if (psmouse->pktcnt == 3) { |
1161 | alps_report_bare_ps2_packet(psmouse, psmouse->packet, | 1167 | alps_report_bare_ps2_packet(psmouse, psmouse->packet, |
1162 | true); | 1168 | true); |
@@ -1180,12 +1186,27 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
1180 | } | 1186 | } |
1181 | 1187 | ||
1182 | /* Bytes 2 - pktsize should have 0 in the highest bit */ | 1188 | /* Bytes 2 - pktsize should have 0 in the highest bit */ |
1183 | if ((priv->proto_version < ALPS_PROTO_V5) && | 1189 | if (priv->proto_version < ALPS_PROTO_V5 && |
1184 | psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && | 1190 | psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && |
1185 | (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { | 1191 | (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { |
1186 | psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", | 1192 | psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", |
1187 | psmouse->pktcnt - 1, | 1193 | psmouse->pktcnt - 1, |
1188 | psmouse->packet[psmouse->pktcnt - 1]); | 1194 | psmouse->packet[psmouse->pktcnt - 1]); |
1195 | |||
1196 | if (priv->proto_version == ALPS_PROTO_V3 && | ||
1197 | psmouse->pktcnt == psmouse->pktsize) { | ||
1198 | /* | ||
1199 | * Some Dell boxes, such as Latitude E6440 or E7440 | ||
1200 | * with closed lid, quite often smash last byte of | ||
1201 | * otherwise valid packet with 0xff. Given that the | ||
1202 | * next packet is very likely to be valid let's | ||
1203 | * report PSMOUSE_FULL_PACKET but not process data, | ||
1204 | * rather than reporting PSMOUSE_BAD_DATA and | ||
1205 | * filling the logs. | ||
1206 | */ | ||
1207 | return PSMOUSE_FULL_PACKET; | ||
1208 | } | ||
1209 | |||
1189 | return PSMOUSE_BAD_DATA; | 1210 | return PSMOUSE_BAD_DATA; |
1190 | } | 1211 | } |
1191 | 1212 | ||
@@ -2389,6 +2410,9 @@ int alps_init(struct psmouse *psmouse) | |||
2389 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ | 2410 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ |
2390 | psmouse->resync_time = 0; | 2411 | psmouse->resync_time = 0; |
2391 | 2412 | ||
2413 | /* Allow 2 invalid packets without resetting device */ | ||
2414 | psmouse->resetafter = psmouse->pktsize * 2; | ||
2415 | |||
2392 | return 0; | 2416 | return 0; |
2393 | 2417 | ||
2394 | init_fail: | 2418 | init_fail: |