diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index b06c7ad721fe..3bd8fdf56cd3 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -5,6 +5,7 @@ * Trademarks are the property of their respective owners. */ +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include "psmouse.h" #include "trackpoint.h" @@ -393,6 +395,44 @@ static int trackpoint_reconnect(struct psmouse *psmouse) return 0; } +/* List of known incapable device PNP IDs */ +static const char * const dt_incompatible_devices[] = { + "LEN0304", + "LEN0306", + "LEN0317", + "LEN031A", + "LEN031B", + "LEN031C", + "LEN031D", +}; + +/* + * Checks if it's a doubletap capable device. + * The PNP ID format is "PNP: LEN030d PNP0f13". + */ +static bool trackpoint_is_dt_capable(const char *pnp_id) +{ + size_t i; + + if (!pnp_id) + return false; + + /* Must start with "PNP: LEN03" */ + if (!strstarts(pnp_id, "PNP: LEN03")) + return false; + + /* Ensure enough length before comparing */ + if (strlen(pnp_id) < 12) + return false; + + /* Check deny-list */ + for (i = 0; i < ARRAY_SIZE(dt_incompatible_devices); i++) { + if (!strncmp(pnp_id + 5, dt_incompatible_devices[i], 7)) + return false; + } + return true; +} + int trackpoint_detect(struct psmouse *psmouse, bool set_properties) { struct ps2dev *ps2dev = &psmouse->ps2dev; @@ -470,6 +510,12 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) psmouse->vendor, firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f); + if (trackpoint_is_dt_capable(ps2dev->serio->firmware_id)) { + error = trackpoint_write(ps2dev, TP_DOUBLETAP, TP_DOUBLETAP_ENABLE); + if (error) + psmouse_warn(psmouse, "Failed to enable doubletap: %d\n", error); + } + return 0; } diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index eb5412904fe0..3e03cdb39449 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h @@ -69,6 +69,8 @@ /* (how hard it is to drag */ /* with Z-axis pressed) */ +#define TP_DOUBLETAP 0x58 /* TrackPoint doubletap register */ + #define TP_MINDRAG 0x59 /* Minimum amount of force needed */ /* to trigger dragging */ @@ -110,6 +112,9 @@ external device will be forced to 1 */ #define TP_MASK_EXT_TAG 0x04 +/* Doubletap register values */ +#define TP_DOUBLETAP_ENABLE 0xFF /* Enable value */ +#define TP_DOUBLETAP_DISABLE 0xFE /* Disable value */ /* Power on Self Test Results */ #define TP_POR_SUCCESS 0x3B