Input: psmouse - factor out common protocol probing code

In preparation of limiting protocols that we try on pass-through ports,
let's rework initialization code and factor common code into
psmouse_try_protocol() that accepts protocol type (instead of detec()
function pointer) and can, for most protocols, perform both detection and
initialization.

Note that this removes option of forcing Lifebook protocol on devices that
are not recognized by lifebook_detect() as having the hardware, but I do
not recall anyone using this option.

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Marcin Sochacki <msochacki+kernel@gmail.com>
Tested-by: Till <till2.schaefer@uni-dortmund.de>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
Dmitry Torokhov 2015-11-27 21:17:40 -08:00
parent 5fa75cfe23
commit c378b5119e

View File

@ -767,6 +767,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.type = PSMOUSE_LIFEBOOK, .type = PSMOUSE_LIFEBOOK,
.name = "LBPS/2", .name = "LBPS/2",
.alias = "lifebook", .alias = "lifebook",
.detect = lifebook_detect,
.init = lifebook_init, .init = lifebook_init,
}, },
#endif #endif
@ -844,7 +845,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
}, },
}; };
static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type) static const struct psmouse_protocol *__psmouse_protocol_by_type(enum psmouse_type type)
{ {
int i; int i;
@ -852,6 +853,17 @@ static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type
if (psmouse_protocols[i].type == type) if (psmouse_protocols[i].type == type)
return &psmouse_protocols[i]; return &psmouse_protocols[i];
return NULL;
}
static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
{
const struct psmouse_protocol *proto;
proto = __psmouse_protocol_by_type(type);
if (proto)
return proto;
WARN_ON(1); WARN_ON(1);
return &psmouse_protocols[0]; return &psmouse_protocols[0];
} }
@ -910,18 +922,37 @@ static void psmouse_apply_defaults(struct psmouse *psmouse)
psmouse->pt_deactivate = NULL; psmouse->pt_deactivate = NULL;
} }
/* static bool psmouse_try_protocol(struct psmouse *psmouse,
* Apply default settings to the psmouse structure and call specified enum psmouse_type type,
* protocol detection or initialization routine. unsigned int *max_proto,
*/ bool set_properties, bool init_allowed)
static int psmouse_do_detect(int (*detect)(struct psmouse *psmouse,
bool set_properties),
struct psmouse *psmouse, bool set_properties)
{ {
const struct psmouse_protocol *proto;
proto = __psmouse_protocol_by_type(type);
if (!proto)
return false;
if (set_properties) if (set_properties)
psmouse_apply_defaults(psmouse); psmouse_apply_defaults(psmouse);
return detect(psmouse, set_properties); if (proto->detect(psmouse, set_properties) != 0)
return false;
if (set_properties && proto->init && init_allowed) {
if (proto->init(psmouse) != 0) {
/*
* We detected device, but init failed. Adjust
* max_proto so we only try standard protocols.
*/
if (*max_proto > PSMOUSE_IMEX)
*max_proto = PSMOUSE_IMEX;
return false;
}
}
return true;
} }
/* /*
@ -937,12 +968,12 @@ static int psmouse_extensions(struct psmouse *psmouse,
* Always check for focaltech, this is safe as it uses pnp-id * Always check for focaltech, this is safe as it uses pnp-id
* matching. * matching.
*/ */
if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) { if (psmouse_try_protocol(psmouse, PSMOUSE_FOCALTECH,
if (max_proto > PSMOUSE_IMEX) { &max_proto, set_properties, false)) {
if (IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH) && if (max_proto > PSMOUSE_IMEX &&
(!set_properties || focaltech_init(psmouse) == 0)) { IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH) &&
return PSMOUSE_FOCALTECH; (!set_properties || focaltech_init(psmouse) == 0)) {
} return PSMOUSE_FOCALTECH;
} }
/* /*
* Restrict psmouse_max_proto so that psmouse_initialize() * Restrict psmouse_max_proto so that psmouse_initialize()
@ -959,26 +990,21 @@ static int psmouse_extensions(struct psmouse *psmouse,
* We always check for LifeBook because it does not disturb mouse * We always check for LifeBook because it does not disturb mouse
* (it only checks DMI information). * (it only checks DMI information).
*/ */
if (psmouse_do_detect(lifebook_detect, psmouse, set_properties) == 0) { if (psmouse_try_protocol(psmouse, PSMOUSE_LIFEBOOK, &max_proto,
if (max_proto > PSMOUSE_IMEX) { set_properties, max_proto > PSMOUSE_IMEX))
if (!set_properties || lifebook_init(psmouse) == 0) return PSMOUSE_LIFEBOOK;
return PSMOUSE_LIFEBOOK;
}
}
if (psmouse_do_detect(vmmouse_detect, psmouse, set_properties) == 0) { if (psmouse_try_protocol(psmouse, PSMOUSE_VMMOUSE, &max_proto,
if (max_proto > PSMOUSE_IMEX) { set_properties, max_proto > PSMOUSE_IMEX))
if (!set_properties || vmmouse_init(psmouse) == 0) return PSMOUSE_VMMOUSE;
return PSMOUSE_VMMOUSE;
}
}
/* /*
* Try Kensington ThinkingMouse (we try first, because Synaptics * Try Kensington ThinkingMouse (we try first, because Synaptics
* probe upsets the ThinkingMouse). * probe upsets the ThinkingMouse).
*/ */
if (max_proto > PSMOUSE_IMEX && if (max_proto > PSMOUSE_IMEX &&
psmouse_do_detect(thinking_detect, psmouse, set_properties) == 0) { psmouse_try_protocol(psmouse, PSMOUSE_THINKPS, &max_proto,
set_properties, true)) {
return PSMOUSE_THINKPS; return PSMOUSE_THINKPS;
} }
@ -989,7 +1015,8 @@ static int psmouse_extensions(struct psmouse *psmouse,
* probing for IntelliMouse. * probing for IntelliMouse.
*/ */
if (max_proto > PSMOUSE_PS2 && if (max_proto > PSMOUSE_PS2 &&
psmouse_do_detect(synaptics_detect, psmouse, set_properties) == 0) { psmouse_try_protocol(psmouse, PSMOUSE_SYNAPTICS, &max_proto,
set_properties, false)) {
synaptics_hardware = true; synaptics_hardware = true;
if (max_proto > PSMOUSE_IMEX) { if (max_proto > PSMOUSE_IMEX) {
@ -1025,64 +1052,48 @@ static int psmouse_extensions(struct psmouse *psmouse,
* Trackpads. * Trackpads.
*/ */
if (max_proto > PSMOUSE_IMEX && if (max_proto > PSMOUSE_IMEX &&
psmouse_do_detect(cypress_detect, psmouse, set_properties) == 0) { psmouse_try_protocol(psmouse, PSMOUSE_CYPRESS, &max_proto,
if (!set_properties || cypress_init(psmouse) == 0) set_properties, true)) {
return PSMOUSE_CYPRESS; return PSMOUSE_CYPRESS;
/*
* Finger Sensing Pad probe upsets some modules of
* Cypress Trackpad, must avoid Finger Sensing Pad
* probe if Cypress Trackpad device detected.
*/
max_proto = PSMOUSE_IMEX;
} }
/* Try ALPS TouchPad */ /* Try ALPS TouchPad */
if (max_proto > PSMOUSE_IMEX) { if (max_proto > PSMOUSE_IMEX) {
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
if (psmouse_do_detect(alps_detect, if (psmouse_try_protocol(psmouse, PSMOUSE_ALPS,
psmouse, set_properties) == 0) { &max_proto, set_properties, true))
if (!set_properties || alps_init(psmouse) == 0) return PSMOUSE_ALPS;
return PSMOUSE_ALPS;
/* Init failed, try basic relative protocols */
max_proto = PSMOUSE_IMEX;
}
} }
/* Try OLPC HGPK touchpad */ /* Try OLPC HGPK touchpad */
if (max_proto > PSMOUSE_IMEX && if (max_proto > PSMOUSE_IMEX &&
psmouse_do_detect(hgpk_detect, psmouse, set_properties) == 0) { psmouse_try_protocol(psmouse, PSMOUSE_HGPK, &max_proto,
if (!set_properties || hgpk_init(psmouse) == 0) set_properties, true)) {
return PSMOUSE_HGPK; return PSMOUSE_HGPK;
/* Init failed, try basic relative protocols */
max_proto = PSMOUSE_IMEX;
} }
/* Try Elantech touchpad */ /* Try Elantech touchpad */
if (max_proto > PSMOUSE_IMEX && if (max_proto > PSMOUSE_IMEX &&
psmouse_do_detect(elantech_detect, psmouse, set_properties) == 0) { psmouse_try_protocol(psmouse, PSMOUSE_ELANTECH,
if (!set_properties || elantech_init(psmouse) == 0) &max_proto, set_properties, true)) {
return PSMOUSE_ELANTECH; return PSMOUSE_ELANTECH;
/* Init failed, try basic relative protocols */
max_proto = PSMOUSE_IMEX;
} }
if (max_proto > PSMOUSE_IMEX) { if (max_proto > PSMOUSE_IMEX) {
if (psmouse_do_detect(genius_detect, if (psmouse_try_protocol(psmouse, PSMOUSE_GENPS,
psmouse, set_properties) == 0) &max_proto, set_properties, true))
return PSMOUSE_GENPS; return PSMOUSE_GENPS;
if (psmouse_do_detect(ps2pp_init, if (psmouse_try_protocol(psmouse, PSMOUSE_PS2PP,
psmouse, set_properties) == 0) &max_proto, set_properties, true))
return PSMOUSE_PS2PP; return PSMOUSE_PS2PP;
if (psmouse_do_detect(trackpoint_detect, if (psmouse_try_protocol(psmouse, PSMOUSE_TRACKPOINT,
psmouse, set_properties) == 0) &max_proto, set_properties, true))
return PSMOUSE_TRACKPOINT; return PSMOUSE_TRACKPOINT;
if (psmouse_do_detect(touchkit_ps2_detect, if (psmouse_try_protocol(psmouse, PSMOUSE_TOUCHKIT_PS2,
psmouse, set_properties) == 0) &max_proto, set_properties, true))
return PSMOUSE_TOUCHKIT_PS2; return PSMOUSE_TOUCHKIT_PS2;
} }
@ -1090,14 +1101,10 @@ static int psmouse_extensions(struct psmouse *psmouse,
* Try Finger Sensing Pad. We do it here because its probe upsets * Try Finger Sensing Pad. We do it here because its probe upsets
* Trackpoint devices (causing TP_READ_ID command to time out). * Trackpoint devices (causing TP_READ_ID command to time out).
*/ */
if (max_proto > PSMOUSE_IMEX) { if (max_proto > PSMOUSE_IMEX &&
if (psmouse_do_detect(fsp_detect, psmouse_try_protocol(psmouse, PSMOUSE_FSP,
psmouse, set_properties) == 0) { &max_proto, set_properties, true)) {
if (!set_properties || fsp_init(psmouse) == 0) return PSMOUSE_FSP;
return PSMOUSE_FSP;
/* Init failed, try basic relative protocols */
max_proto = PSMOUSE_IMEX;
}
} }
/* /*
@ -1109,14 +1116,14 @@ static int psmouse_extensions(struct psmouse *psmouse,
psmouse_reset(psmouse); psmouse_reset(psmouse);
if (max_proto >= PSMOUSE_IMEX && if (max_proto >= PSMOUSE_IMEX &&
psmouse_do_detect(im_explorer_detect, psmouse_try_protocol(psmouse, PSMOUSE_IMEX,
psmouse, set_properties) == 0) { &max_proto, set_properties, true)) {
return PSMOUSE_IMEX; return PSMOUSE_IMEX;
} }
if (max_proto >= PSMOUSE_IMPS && if (max_proto >= PSMOUSE_IMPS &&
psmouse_do_detect(intellimouse_detect, psmouse_try_protocol(psmouse, PSMOUSE_IMPS,
psmouse, set_properties) == 0) { &max_proto, set_properties, true)) {
return PSMOUSE_IMPS; return PSMOUSE_IMPS;
} }
@ -1124,7 +1131,8 @@ static int psmouse_extensions(struct psmouse *psmouse,
* Okay, all failed, we have a standard mouse here. The number of * Okay, all failed, we have a standard mouse here. The number of
* the buttons is still a question, though. We assume 3. * the buttons is still a question, though. We assume 3.
*/ */
psmouse_do_detect(ps2bare_detect, psmouse, set_properties); psmouse_try_protocol(psmouse, PSMOUSE_PS2,
&max_proto, set_properties, true);
if (synaptics_hardware) { if (synaptics_hardware) {
/* /*