diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-01-15 09:46:14 -0800 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-01-15 09:46:14 -0800 |
commit | 0c49cd295d42d0032af11d55e2140dbec11dc8d0 (patch) | |
tree | 1e7d0e50b6b6d6e4de1fb6bb0b6d856c3932da58 /drivers/input/mouse/alps.c | |
parent | 0c3e99437a66e4c869c60c2398449e6d98f3a988 (diff) | |
parent | eaa27f34e91a14cdceed26ed6c6793ec1d186115 (diff) |
Merge tag 'v3.19-rc4' into next
Merge with mainline to bring in the latest thermal and other changes.
Diffstat (limited to 'drivers/input/mouse/alps.c')
-rw-r--r-- | drivers/input/mouse/alps.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index dd2fd397466a..f719f28d370c 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -846,8 +846,8 @@ static void alps_process_packet_v4(struct psmouse *psmouse) f->fingers = alps_process_bitmap(priv, f); } - f->left = packet[4] & 0x01; - f->right = packet[4] & 0x02; + f->left = !!(packet[4] & 0x01); + f->right = !!(packet[4] & 0x02); f->st.x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) | ((packet[0] & 0x30) >> 4); @@ -1238,7 +1238,13 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; - if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ + /* + * Check if we are dealing with a bare PS/2 packet, presumably from + * a device connected to the external PS/2 port. Because bare PS/2 + * protocol does not have enough constant bits to self-synchronize + * properly we only do this if the device is fully synchronized. + */ + if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) { if (psmouse->pktcnt == 3) { alps_report_bare_ps2_packet(psmouse, psmouse->packet, true); @@ -1262,12 +1268,27 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) } /* Bytes 2 - pktsize should have 0 in the highest bit */ - if ((priv->proto_version < ALPS_PROTO_V5) && + if (priv->proto_version < ALPS_PROTO_V5 && psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]); + + if (priv->proto_version == ALPS_PROTO_V3 && + psmouse->pktcnt == psmouse->pktsize) { + /* + * Some Dell boxes, such as Latitude E6440 or E7440 + * with closed lid, quite often smash last byte of + * otherwise valid packet with 0xff. Given that the + * next packet is very likely to be valid let's + * report PSMOUSE_FULL_PACKET but not process data, + * rather than reporting PSMOUSE_BAD_DATA and + * filling the logs. + */ + return PSMOUSE_FULL_PACKET; + } + return PSMOUSE_BAD_DATA; } @@ -2481,6 +2502,9 @@ int alps_init(struct psmouse *psmouse) /* We are having trouble resyncing ALPS touchpads so disable it for now */ psmouse->resync_time = 0; + /* Allow 2 invalid packets without resetting device */ + psmouse->resetafter = psmouse->pktsize * 2; + return 0; init_fail: |