Skip to content

Commit 7e4935c

Browse files
jason77-wangdtor
authored andcommitted
Input: alps - don't handle ALPS cs19 trackpoint-only device
On a latest Lenovo laptop, the trackpoint and 3 buttons below it don't work at all, when we move the trackpoint or press those 3 buttons, the kernel will print out: "Rejected trackstick packet from non DualPoint device" This device is identified as an alps touchpad but the packet has trackpoint format, so the alps.c drops the packet and prints out the message above. According to XiaoXiao's explanation, this device is named cs19 and is trackpoint-only device, its firmware is only for trackpoint, it is independent of touchpad and is a device completely different from DualPoint ones. To drive this device with mininal changes to the existing driver, we just let the alps driver not handle this device, then the trackpoint.c will be the driver of this device if the trackpoint driver is enabled. (if not, this device will fallback to a bare PS/2 device) With the trackpoint.c, this trackpoint and 3 buttons all work well, they have all features that the trackpoint should have, like scrolling-screen, drag-and-drop and frame-selection. Signed-off-by: XiaoXiao Liu <[email protected]> Signed-off-by: Hui Wang <[email protected]> Reviewed-by: Pali Rohár <[email protected]> Cc: [email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 88f28e9 commit 7e4935c

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

drivers/input/mouse/alps.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "psmouse.h"
2323
#include "alps.h"
24+
#include "trackpoint.h"
2425

2526
/*
2627
* Definitions for ALPS version 3 and 4 command mode protocol
@@ -2861,6 +2862,23 @@ static const struct alps_protocol_info *alps_match_table(unsigned char *e7,
28612862
return NULL;
28622863
}
28632864

2865+
static bool alps_is_cs19_trackpoint(struct psmouse *psmouse)
2866+
{
2867+
u8 param[2] = { 0 };
2868+
2869+
if (ps2_command(&psmouse->ps2dev,
2870+
param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
2871+
return false;
2872+
2873+
/*
2874+
* param[0] contains the trackpoint device variant_id while
2875+
* param[1] contains the firmware_id. So far all alps
2876+
* trackpoint-only devices have their variant_ids equal
2877+
* TP_VARIANT_ALPS and their firmware_ids are in 0x20~0x2f range.
2878+
*/
2879+
return param[0] == TP_VARIANT_ALPS && (param[1] & 0x20);
2880+
}
2881+
28642882
static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
28652883
{
28662884
const struct alps_protocol_info *protocol;
@@ -3161,6 +3179,20 @@ int alps_detect(struct psmouse *psmouse, bool set_properties)
31613179
if (error)
31623180
return error;
31633181

3182+
/*
3183+
* ALPS cs19 is a trackpoint-only device, and uses different
3184+
* protocol than DualPoint ones, so we return -EINVAL here and let
3185+
* trackpoint.c drive this device. If the trackpoint driver is not
3186+
* enabled, the device will fall back to a bare PS/2 mouse.
3187+
* If ps2_command() fails here, we depend on the immediately
3188+
* followed psmouse_reset() to reset the device to normal state.
3189+
*/
3190+
if (alps_is_cs19_trackpoint(psmouse)) {
3191+
psmouse_dbg(psmouse,
3192+
"ALPS CS19 trackpoint-only device detected, ignoring\n");
3193+
return -EINVAL;
3194+
}
3195+
31643196
/*
31653197
* Reset the device to make sure it is fully operational:
31663198
* on some laptops, like certain Dell Latitudes, we may

0 commit comments

Comments
 (0)