Commit 7e4935cc authored by Hui Wang's avatar Hui Wang Committed by Dmitry Torokhov

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: default avatarXiaoXiao Liu <sliuuxiaonxiao@gmail.com>
Signed-off-by: default avatarHui Wang <hui.wang@canonical.com>
Reviewed-by: default avatarPali Rohár <pali.rohar@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 88f28e95
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "psmouse.h" #include "psmouse.h"
#include "alps.h" #include "alps.h"
#include "trackpoint.h"
/* /*
* Definitions for ALPS version 3 and 4 command mode protocol * 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, ...@@ -2861,6 +2862,23 @@ static const struct alps_protocol_info *alps_match_table(unsigned char *e7,
return NULL; return NULL;
} }
static bool alps_is_cs19_trackpoint(struct psmouse *psmouse)
{
u8 param[2] = { 0 };
if (ps2_command(&psmouse->ps2dev,
param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
return false;
/*
* param[0] contains the trackpoint device variant_id while
* param[1] contains the firmware_id. So far all alps
* trackpoint-only devices have their variant_ids equal
* TP_VARIANT_ALPS and their firmware_ids are in 0x20~0x2f range.
*/
return param[0] == TP_VARIANT_ALPS && (param[1] & 0x20);
}
static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
{ {
const struct alps_protocol_info *protocol; const struct alps_protocol_info *protocol;
...@@ -3161,6 +3179,20 @@ int alps_detect(struct psmouse *psmouse, bool set_properties) ...@@ -3161,6 +3179,20 @@ int alps_detect(struct psmouse *psmouse, bool set_properties)
if (error) if (error)
return error; return error;
/*
* ALPS cs19 is a trackpoint-only device, and uses different
* protocol than DualPoint ones, so we return -EINVAL here and let
* trackpoint.c drive this device. If the trackpoint driver is not
* enabled, the device will fall back to a bare PS/2 mouse.
* If ps2_command() fails here, we depend on the immediately
* followed psmouse_reset() to reset the device to normal state.
*/
if (alps_is_cs19_trackpoint(psmouse)) {
psmouse_dbg(psmouse,
"ALPS CS19 trackpoint-only device detected, ignoring\n");
return -EINVAL;
}
/* /*
* Reset the device to make sure it is fully operational: * Reset the device to make sure it is fully operational:
* on some laptops, like certain Dell Latitudes, we may * on some laptops, like certain Dell Latitudes, we may
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment