Commit f01c5e65 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Merge branch 'psmouse-passthrough' into next

Bring in changes to limit number of protocols we try on pass-though PS/2
ports so that probe ocmpletes faster.
parents 40e3be39 190e2031
...@@ -49,12 +49,6 @@ int focaltech_detect(struct psmouse *psmouse, bool set_properties) ...@@ -49,12 +49,6 @@ int focaltech_detect(struct psmouse *psmouse, bool set_properties)
return 0; return 0;
} }
static void focaltech_reset(struct psmouse *psmouse)
{
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
psmouse_reset(psmouse);
}
#ifdef CONFIG_MOUSE_PS2_FOCALTECH #ifdef CONFIG_MOUSE_PS2_FOCALTECH
/* /*
...@@ -300,6 +294,12 @@ static int focaltech_switch_protocol(struct psmouse *psmouse) ...@@ -300,6 +294,12 @@ static int focaltech_switch_protocol(struct psmouse *psmouse)
return 0; return 0;
} }
static void focaltech_reset(struct psmouse *psmouse)
{
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
psmouse_reset(psmouse);
}
static void focaltech_disconnect(struct psmouse *psmouse) static void focaltech_disconnect(struct psmouse *psmouse)
{ {
focaltech_reset(psmouse); focaltech_reset(psmouse);
...@@ -456,14 +456,4 @@ int focaltech_init(struct psmouse *psmouse) ...@@ -456,14 +456,4 @@ int focaltech_init(struct psmouse *psmouse)
kfree(priv); kfree(priv);
return error; return error;
} }
#else /* CONFIG_MOUSE_PS2_FOCALTECH */
int focaltech_init(struct psmouse *psmouse)
{
focaltech_reset(psmouse);
return 0;
}
#endif /* CONFIG_MOUSE_PS2_FOCALTECH */ #endif /* CONFIG_MOUSE_PS2_FOCALTECH */
...@@ -18,6 +18,14 @@ ...@@ -18,6 +18,14 @@
#define _FOCALTECH_H #define _FOCALTECH_H
int focaltech_detect(struct psmouse *psmouse, bool set_properties); int focaltech_detect(struct psmouse *psmouse, bool set_properties);
#ifdef CONFIG_MOUSE_PS2_FOCALTECH
int focaltech_init(struct psmouse *psmouse); int focaltech_init(struct psmouse *psmouse);
#else
static inline int focaltech_init(struct psmouse *psmouse)
{
return -ENOSYS;
}
#endif
#endif #endif
...@@ -325,7 +325,7 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, ...@@ -325,7 +325,7 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
* that support it. * that support it.
*/ */
int ps2pp_init(struct psmouse *psmouse, bool set_properties) int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
{ {
struct ps2dev *ps2dev = &psmouse->ps2dev; struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4]; unsigned char param[4];
......
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
#define _LOGIPS2PP_H #define _LOGIPS2PP_H
#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
int ps2pp_init(struct psmouse *psmouse, bool set_properties); int ps2pp_detect(struct psmouse *psmouse, bool set_properties);
#else #else
inline int ps2pp_init(struct psmouse *psmouse, bool set_properties) static inline int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
{ {
return -ENOSYS; return -ENOSYS;
} }
......
...@@ -119,6 +119,7 @@ struct psmouse_protocol { ...@@ -119,6 +119,7 @@ struct psmouse_protocol {
enum psmouse_type type; enum psmouse_type type;
bool maxproto; bool maxproto;
bool ignore_parity; /* Protocol should ignore parity errors from KBC */ bool ignore_parity; /* Protocol should ignore parity errors from KBC */
bool try_passthru; /* Try protocol also on passthrough ports */
const char *name; const char *name;
const char *alias; const char *alias;
int (*detect)(struct psmouse *, bool); int (*detect)(struct psmouse *, bool);
...@@ -129,7 +130,6 @@ struct psmouse_protocol { ...@@ -129,7 +130,6 @@ struct psmouse_protocol {
* psmouse_process_byte() analyzes the PS/2 data stream and reports * psmouse_process_byte() analyzes the PS/2 data stream and reports
* relevant events to the input module once full packet has arrived. * relevant events to the input module once full packet has arrived.
*/ */
psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
{ {
struct input_dev *dev = psmouse->dev; struct input_dev *dev = psmouse->dev;
...@@ -138,22 +138,16 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) ...@@ -138,22 +138,16 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
if (psmouse->pktcnt < psmouse->pktsize) if (psmouse->pktcnt < psmouse->pktsize)
return PSMOUSE_GOOD_DATA; return PSMOUSE_GOOD_DATA;
/* /* Full packet accumulated, process it */
* Full packet accumulated, process it
*/
/* switch (psmouse->type) {
* Scroll wheel on IntelliMice, scroll buttons on NetMice case PSMOUSE_IMPS:
*/ /* IntelliMouse has scroll wheel */
if (psmouse->type == PSMOUSE_IMPS || psmouse->type == PSMOUSE_GENPS)
input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]); input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]);
break;
/* case PSMOUSE_IMEX:
* Scroll wheel and buttons on IntelliMouse Explorer /* Scroll wheel and buttons on IntelliMouse Explorer */
*/
if (psmouse->type == PSMOUSE_IMEX) {
switch (packet[3] & 0xC0) { switch (packet[3] & 0xC0) {
case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */
input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31));
...@@ -168,39 +162,42 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) ...@@ -168,39 +162,42 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1);
break; break;
} }
} break;
/* case PSMOUSE_GENPS:
* Extra buttons on Genius NewNet 3D /* Report scroll buttons on NetMice */
*/ input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]);
if (psmouse->type == PSMOUSE_GENPS) { /* Extra buttons on Genius NewNet 3D */
input_report_key(dev, BTN_SIDE, (packet[0] >> 6) & 1); input_report_key(dev, BTN_SIDE, (packet[0] >> 6) & 1);
input_report_key(dev, BTN_EXTRA, (packet[0] >> 7) & 1); input_report_key(dev, BTN_EXTRA, (packet[0] >> 7) & 1);
} break;
/* case PSMOUSE_THINKPS:
* Extra button on ThinkingMouse /* Extra button on ThinkingMouse */
*/
if (psmouse->type == PSMOUSE_THINKPS) {
input_report_key(dev, BTN_EXTRA, (packet[0] >> 3) & 1); input_report_key(dev, BTN_EXTRA, (packet[0] >> 3) & 1);
/* Without this bit of weirdness moving up gives wildly high Y changes. */
/*
* Without this bit of weirdness moving up gives wildly
* high Y changes.
*/
packet[1] |= (packet[0] & 0x40) << 1; packet[1] |= (packet[0] & 0x40) << 1;
} break;
/* case PSMOUSE_CORTRON:
* Cortron PS2 Trackball reports SIDE button on the 4th bit of the first /*
* byte. * Cortron PS2 Trackball reports SIDE button in the
*/ * 4th bit of the first byte.
if (psmouse->type == PSMOUSE_CORTRON) { */
input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1); input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1);
packet[0] |= 0x08; packet[0] |= 0x08;
} break;
/* default:
* Generic PS/2 Mouse break;
*/ }
/* Generic PS/2 Mouse */
input_report_key(dev, BTN_LEFT, packet[0] & 1); input_report_key(dev, BTN_LEFT, packet[0] & 1);
input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
...@@ -222,7 +219,6 @@ void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, ...@@ -222,7 +219,6 @@ void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
/* /*
* __psmouse_set_state() sets new psmouse state and resets all flags. * __psmouse_set_state() sets new psmouse state and resets all flags.
*/ */
static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
{ {
psmouse->state = new_state; psmouse->state = new_state;
...@@ -231,13 +227,11 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta ...@@ -231,13 +227,11 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta
psmouse->last = jiffies; psmouse->last = jiffies;
} }
/* /*
* psmouse_set_state() sets new psmouse state and resets all flags and * psmouse_set_state() sets new psmouse state and resets all flags and
* counters while holding serio lock so fighting with interrupt handler * counters while holding serio lock so fighting with interrupt handler
* is not a concern. * is not a concern.
*/ */
void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
{ {
serio_pause_rx(psmouse->ps2dev.serio); serio_pause_rx(psmouse->ps2dev.serio);
...@@ -249,7 +243,6 @@ void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) ...@@ -249,7 +243,6 @@ void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
* psmouse_handle_byte() processes one byte of the input data stream * psmouse_handle_byte() processes one byte of the input data stream
* by calling corresponding protocol handler. * by calling corresponding protocol handler.
*/ */
static int psmouse_handle_byte(struct psmouse *psmouse) static int psmouse_handle_byte(struct psmouse *psmouse)
{ {
psmouse_ret_t rc = psmouse->protocol_handler(psmouse); psmouse_ret_t rc = psmouse->protocol_handler(psmouse);
...@@ -292,7 +285,6 @@ static int psmouse_handle_byte(struct psmouse *psmouse) ...@@ -292,7 +285,6 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
* psmouse_interrupt() handles incoming characters, either passing them * psmouse_interrupt() handles incoming characters, either passing them
* for normal processing or gathering them as command response. * for normal processing or gathering them as command response.
*/ */
static irqreturn_t psmouse_interrupt(struct serio *serio, static irqreturn_t psmouse_interrupt(struct serio *serio,
unsigned char data, unsigned int flags) unsigned char data, unsigned int flags)
{ {
...@@ -335,9 +327,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -335,9 +327,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
} }
psmouse->packet[psmouse->pktcnt++] = data; psmouse->packet[psmouse->pktcnt++] = data;
/*
* Check if this is a new device announcement (0xAA 0x00) /* Check if this is a new device announcement (0xAA 0x00) */
*/
if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) { if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
if (psmouse->pktcnt == 1) { if (psmouse->pktcnt == 1) {
psmouse->last = jiffies; psmouse->last = jiffies;
...@@ -351,9 +342,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -351,9 +342,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
serio_reconnect(serio); serio_reconnect(serio);
goto out; goto out;
} }
/*
* Not a new device, try processing first byte normally /* Not a new device, try processing first byte normally */
*/
psmouse->pktcnt = 1; psmouse->pktcnt = 1;
if (psmouse_handle_byte(psmouse)) if (psmouse_handle_byte(psmouse))
goto out; goto out;
...@@ -361,9 +351,10 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -361,9 +351,10 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
psmouse->packet[psmouse->pktcnt++] = data; psmouse->packet[psmouse->pktcnt++] = data;
} }
/* /*
* See if we need to force resync because mouse was idle for too long * See if we need to force resync because mouse was idle for
*/ * too long.
*/
if (psmouse->state == PSMOUSE_ACTIVATED && if (psmouse->state == PSMOUSE_ACTIVATED &&
psmouse->pktcnt == 1 && psmouse->resync_time && psmouse->pktcnt == 1 && psmouse->resync_time &&
time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) { time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
...@@ -380,7 +371,6 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -380,7 +371,6 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/* /*
* psmouse_sliced_command() sends an extended PS/2 command to the mouse * psmouse_sliced_command() sends an extended PS/2 command to the mouse
* using sliced syntax, understood by advanced devices, such as Logitech * using sliced syntax, understood by advanced devices, such as Logitech
...@@ -404,7 +394,6 @@ int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command) ...@@ -404,7 +394,6 @@ int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command)
return 0; return 0;
} }
/* /*
* psmouse_reset() resets the mouse into power-on state. * psmouse_reset() resets the mouse into power-on state.
*/ */
...@@ -424,7 +413,6 @@ int psmouse_reset(struct psmouse *psmouse) ...@@ -424,7 +413,6 @@ int psmouse_reset(struct psmouse *psmouse)
/* /*
* Here we set the mouse resolution. * Here we set the mouse resolution.
*/ */
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
{ {
static const unsigned char params[] = { 0, 1, 2, 2, 3 }; static const unsigned char params[] = { 0, 1, 2, 2, 3 };
...@@ -441,7 +429,6 @@ void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) ...@@ -441,7 +429,6 @@ void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
/* /*
* Here we set the mouse report rate. * Here we set the mouse report rate.
*/ */
static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
{ {
static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 }; static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
...@@ -457,7 +444,6 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) ...@@ -457,7 +444,6 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
/* /*
* Here we set the mouse scaling. * Here we set the mouse scaling.
*/ */
static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale) static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale)
{ {
ps2_command(&psmouse->ps2dev, NULL, ps2_command(&psmouse->ps2dev, NULL,
...@@ -468,7 +454,6 @@ static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale) ...@@ -468,7 +454,6 @@ static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale)
/* /*
* psmouse_poll() - default poll handler. Everyone except for ALPS uses it. * psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
*/ */
static int psmouse_poll(struct psmouse *psmouse) static int psmouse_poll(struct psmouse *psmouse)
{ {
return ps2_command(&psmouse->ps2dev, psmouse->packet, return ps2_command(&psmouse->ps2dev, psmouse->packet,
...@@ -602,7 +587,7 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) ...@@ -602,7 +587,7 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
if (param[0] != 4) if (param[0] != 4)
return -1; return -1;
/* Magic to enable horizontal scrolling on IntelliMouse 4.0 */ /* Magic to enable horizontal scrolling on IntelliMouse 4.0 */
param[0] = 200; param[0] = 200;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
param[0] = 80; param[0] = 80;
...@@ -672,10 +657,10 @@ static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) ...@@ -672,10 +657,10 @@ static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
if (!psmouse->name) if (!psmouse->name)
psmouse->name = "Mouse"; psmouse->name = "Mouse";
/* /*
* We have no way of figuring true number of buttons so let's * We have no way of figuring true number of buttons so let's
* assume that the device has 3. * assume that the device has 3.
*/ */
__set_bit(BTN_MIDDLE, psmouse->dev->keybit); __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
} }
...@@ -699,284 +684,6 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties) ...@@ -699,284 +684,6 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties)
return 0; return 0;
} }
/*
* Apply default settings to the psmouse structure. Most of them will
* be overridden by individual protocol initialization routines.
*/
static void psmouse_apply_defaults(struct psmouse *psmouse)
{
struct input_dev *input_dev = psmouse->dev;
memset(input_dev->evbit, 0, sizeof(input_dev->evbit));
memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
memset(input_dev->relbit, 0, sizeof(input_dev->relbit));
memset(input_dev->absbit, 0, sizeof(input_dev->absbit));
memset(input_dev->mscbit, 0, sizeof(input_dev->mscbit));
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(EV_REL, input_dev->evbit);
__set_bit(BTN_LEFT, input_dev->keybit);
__set_bit(BTN_RIGHT, input_dev->keybit);
__set_bit(REL_X, input_dev->relbit);
__set_bit(REL_Y, input_dev->relbit);
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
psmouse->set_rate = psmouse_set_rate;
psmouse->set_resolution = psmouse_set_resolution;
psmouse->set_scale = psmouse_set_scale;
psmouse->poll = psmouse_poll;
psmouse->protocol_handler = psmouse_process_byte;
psmouse->pktsize = 3;
psmouse->reconnect = NULL;
psmouse->disconnect = NULL;
psmouse->cleanup = NULL;
psmouse->pt_activate = NULL;
psmouse->pt_deactivate = NULL;
}
/*
* Apply default settings to the psmouse structure and call specified
* protocol detection or initialization routine.
*/
static int psmouse_do_detect(int (*detect)(struct psmouse *psmouse,
bool set_properties),
struct psmouse *psmouse, bool set_properties)
{
if (set_properties)
psmouse_apply_defaults(psmouse);
return detect(psmouse, set_properties);
}
/*
* psmouse_extensions() probes for any extensions to the basic PS/2 protocol
* the mouse may have.
*/
static int psmouse_extensions(struct psmouse *psmouse,
unsigned int max_proto, bool set_properties)
{
bool synaptics_hardware = false;
/* Always check for focaltech, this is safe as it uses pnp-id matching */
if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) {
if (max_proto > PSMOUSE_IMEX) {
if (!set_properties || focaltech_init(psmouse) == 0) {
if (IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH))
return PSMOUSE_FOCALTECH;
/*
* Note that we need to also restrict
* psmouse_max_proto so that psmouse_initialize()
* does not try to reset rate and resolution,
* because even that upsets the device.
*/
psmouse_max_proto = PSMOUSE_PS2;
return PSMOUSE_PS2;
}
}
}
/*
* We always check for lifebook because it does not disturb mouse
* (it only checks DMI information).
*/
if (psmouse_do_detect(lifebook_detect, psmouse, set_properties) == 0) {
if (max_proto > PSMOUSE_IMEX) {
if (!set_properties || lifebook_init(psmouse) == 0)
return PSMOUSE_LIFEBOOK;
}
}
if (psmouse_do_detect(vmmouse_detect, psmouse, set_properties) == 0) {
if (max_proto > PSMOUSE_IMEX) {
if (!set_properties || vmmouse_init(psmouse) == 0)
return PSMOUSE_VMMOUSE;
}
}
/*
* Try Kensington ThinkingMouse (we try first, because synaptics probe
* upsets the thinkingmouse).
*/
if (max_proto > PSMOUSE_IMEX &&
psmouse_do_detect(thinking_detect, psmouse, set_properties) == 0) {
return PSMOUSE_THINKPS;
}
/*
* Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol
* support is disabled in config - we need to know if it is synaptics so we
* can reset it properly after probing for intellimouse.
*/
if (max_proto > PSMOUSE_PS2 &&
psmouse_do_detect(synaptics_detect, psmouse, set_properties) == 0) {
synaptics_hardware = true;
if (max_proto > PSMOUSE_IMEX) {
/*
* Try activating protocol, but check if support is enabled first, since
* we try detecting Synaptics even when protocol is disabled.
*/
if (IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS) &&
(!set_properties || synaptics_init(psmouse) == 0)) {
return PSMOUSE_SYNAPTICS;
}
/*
* Some Synaptics touchpads can emulate extended protocols (like IMPS/2).
* Unfortunately Logitech/Genius probes confuse some firmware versions so
* we'll have to skip them.
*/
max_proto = PSMOUSE_IMEX;
}
/*
* Make sure that touchpad is in relative mode, gestures (taps) are enabled
*/
synaptics_reset(psmouse);
}
/*
* Try Cypress Trackpad.
* Must try it before Finger Sensing Pad because Finger Sensing Pad probe
* upsets some modules of Cypress Trackpads.
*/
if (max_proto > PSMOUSE_IMEX &&
cypress_detect(psmouse, set_properties) == 0) {
if (IS_ENABLED(CONFIG_MOUSE_PS2_CYPRESS)) {
if (cypress_init(psmouse) == 0)
return PSMOUSE_CYPRESS;
/*
* Finger Sensing Pad probe upsets some modules of
* Cypress Trackpad, must avoid Finger Sensing Pad
* probe if Cypress Trackpad device detected.
*/
return PSMOUSE_PS2;
}
max_proto = PSMOUSE_IMEX;
}
/*
* Try ALPS TouchPad
*/
if (max_proto > PSMOUSE_IMEX) {
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
if (psmouse_do_detect(alps_detect,
psmouse, set_properties) == 0) {
if (!set_properties || alps_init(psmouse) == 0)
return PSMOUSE_ALPS;
/*
* Init failed, try basic relative protocols
*/
max_proto = PSMOUSE_IMEX;
}
}
/*
* Try OLPC HGPK touchpad.
*/
if (max_proto > PSMOUSE_IMEX &&
psmouse_do_detect(hgpk_detect, psmouse, set_properties) == 0) {
if (!set_properties || hgpk_init(psmouse) == 0)
return PSMOUSE_HGPK;
/*
* Init failed, try basic relative protocols
*/
max_proto = PSMOUSE_IMEX;
}
/*
* Try Elantech touchpad.
*/
if (max_proto > PSMOUSE_IMEX &&
psmouse_do_detect(elantech_detect, psmouse, set_properties) == 0) {
if (!set_properties || elantech_init(psmouse) == 0)
return PSMOUSE_ELANTECH;
/*
* Init failed, try basic relative protocols
*/
max_proto = PSMOUSE_IMEX;
}
if (max_proto > PSMOUSE_IMEX) {
if (psmouse_do_detect(genius_detect,
psmouse, set_properties) == 0)
return PSMOUSE_GENPS;
if (psmouse_do_detect(ps2pp_init,
psmouse, set_properties) == 0)
return PSMOUSE_PS2PP;
if (psmouse_do_detect(trackpoint_detect,
psmouse, set_properties) == 0)
return PSMOUSE_TRACKPOINT;
if (psmouse_do_detect(touchkit_ps2_detect,
psmouse, set_properties) == 0)
return PSMOUSE_TOUCHKIT_PS2;
}
/*
* Try Finger Sensing Pad. We do it here because its probe upsets
* Trackpoint devices (causing TP_READ_ID command to time out).
*/
if (max_proto > PSMOUSE_IMEX) {
if (psmouse_do_detect(fsp_detect,
psmouse, set_properties) == 0) {
if (!set_properties || fsp_init(psmouse) == 0)
return PSMOUSE_FSP;
/*
* Init failed, try basic relative protocols
*/
max_proto = PSMOUSE_IMEX;
}
}
/*
* Reset to defaults in case the device got confused by extended
* protocol probes. Note that we follow up with full reset because
* some mice put themselves to sleep when they see PSMOUSE_RESET_DIS.
*/
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
psmouse_reset(psmouse);
if (max_proto >= PSMOUSE_IMEX &&
psmouse_do_detect(im_explorer_detect,
psmouse, set_properties) == 0) {
return PSMOUSE_IMEX;
}
if (max_proto >= PSMOUSE_IMPS &&
psmouse_do_detect(intellimouse_detect,
psmouse, set_properties) == 0) {
return PSMOUSE_IMPS;
}
/*
* Okay, all failed, we have a standard mouse here. The number of the buttons
* is still a question, though. We assume 3.
*/
psmouse_do_detect(ps2bare_detect, psmouse, set_properties);
if (synaptics_hardware) {
/*
* We detected Synaptics hardware but it did not respond to IMPS/2 probes.
* We need to reset the touchpad because if there is a track point on the
* pass through port it could get disabled while probing for protocol
* extensions.
*/
psmouse_reset(psmouse);
}
return PSMOUSE_PS2;
}
static const struct psmouse_protocol psmouse_protocols[] = { static const struct psmouse_protocol psmouse_protocols[] = {
{ {
.type = PSMOUSE_PS2, .type = PSMOUSE_PS2,
...@@ -985,13 +692,14 @@ static const struct psmouse_protocol psmouse_protocols[] = { ...@@ -985,13 +692,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.maxproto = true, .maxproto = true,
.ignore_parity = true, .ignore_parity = true,
.detect = ps2bare_detect, .detect = ps2bare_detect,
.try_passthru = true,
}, },
#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
{ {
.type = PSMOUSE_PS2PP, .type = PSMOUSE_PS2PP,
.name = "PS2++", .name = "PS2++",
.alias = "logitech", .alias = "logitech",
.detect = ps2pp_init, .detect = ps2pp_detect,
}, },
#endif #endif
{ {
...@@ -1022,6 +730,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { ...@@ -1022,6 +730,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.maxproto = true, .maxproto = true,
.ignore_parity = true, .ignore_parity = true,
.detect = intellimouse_detect, .detect = intellimouse_detect,
.try_passthru = true,
}, },
{ {
.type = PSMOUSE_IMEX, .type = PSMOUSE_IMEX,
...@@ -1030,6 +739,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { ...@@ -1030,6 +739,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.maxproto = true, .maxproto = true,
.ignore_parity = true, .ignore_parity = true,
.detect = im_explorer_detect, .detect = im_explorer_detect,
.try_passthru = true,
}, },
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS #ifdef CONFIG_MOUSE_PS2_SYNAPTICS
{ {
...@@ -1061,6 +771,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { ...@@ -1061,6 +771,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
...@@ -1070,6 +781,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { ...@@ -1070,6 +781,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.name = "TPPS/2", .name = "TPPS/2",
.alias = "trackpoint", .alias = "trackpoint",
.detect = trackpoint_detect, .detect = trackpoint_detect,
.try_passthru = true,
}, },
#endif #endif
#ifdef CONFIG_MOUSE_PS2_TOUCHKIT #ifdef CONFIG_MOUSE_PS2_TOUCHKIT
...@@ -1138,7 +850,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { ...@@ -1138,7 +850,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;
...@@ -1146,6 +858,17 @@ static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type ...@@ -1146,6 +858,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];
} }
...@@ -1166,23 +889,288 @@ static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name, ...@@ -1166,23 +889,288 @@ static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name,
return NULL; return NULL;
} }
/*
* Apply default settings to the psmouse structure. Most of them will
* be overridden by individual protocol initialization routines.
*/
static void psmouse_apply_defaults(struct psmouse *psmouse)
{
struct input_dev *input_dev = psmouse->dev;
memset(input_dev->evbit, 0, sizeof(input_dev->evbit));
memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
memset(input_dev->relbit, 0, sizeof(input_dev->relbit));
memset(input_dev->absbit, 0, sizeof(input_dev->absbit));
memset(input_dev->mscbit, 0, sizeof(input_dev->mscbit));
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(EV_REL, input_dev->evbit);
__set_bit(BTN_LEFT, input_dev->keybit);
__set_bit(BTN_RIGHT, input_dev->keybit);
__set_bit(REL_X, input_dev->relbit);
__set_bit(REL_Y, input_dev->relbit);
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
psmouse->set_rate = psmouse_set_rate;
psmouse->set_resolution = psmouse_set_resolution;
psmouse->set_scale = psmouse_set_scale;
psmouse->poll = psmouse_poll;
psmouse->protocol_handler = psmouse_process_byte;
psmouse->pktsize = 3;
psmouse->reconnect = NULL;
psmouse->disconnect = NULL;
psmouse->cleanup = NULL;
psmouse->pt_activate = NULL;
psmouse->pt_deactivate = NULL;
}
static bool psmouse_try_protocol(struct psmouse *psmouse,
enum psmouse_type type,
unsigned int *max_proto,
bool set_properties, bool init_allowed)
{
const struct psmouse_protocol *proto;
proto = __psmouse_protocol_by_type(type);
if (!proto)
return false;
if (psmouse->ps2dev.serio->id.type == SERIO_PS_PSTHRU &&
!proto->try_passthru) {
return false;
}
if (set_properties)
psmouse_apply_defaults(psmouse);
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;
}
/* /*
* psmouse_probe() probes for a PS/2 mouse. * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
* the mouse may have.
*/ */
static int psmouse_extensions(struct psmouse *psmouse,
unsigned int max_proto, bool set_properties)
{
bool synaptics_hardware = false;
/*
* Always check for focaltech, this is safe as it uses pnp-id
* matching.
*/
if (psmouse_try_protocol(psmouse, PSMOUSE_FOCALTECH,
&max_proto, set_properties, false)) {
if (max_proto > PSMOUSE_IMEX &&
IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH) &&
(!set_properties || focaltech_init(psmouse) == 0)) {
return PSMOUSE_FOCALTECH;
}
/*
* Restrict psmouse_max_proto so that psmouse_initialize()
* does not try to reset rate and resolution, because even
* that upsets the device.
* This also causes us to basically fall through to basic
* protocol detection, where we fully reset the mouse,
* and set it up as bare PS/2 protocol device.
*/
psmouse_max_proto = max_proto = PSMOUSE_PS2;
}
/*
* We always check for LifeBook because it does not disturb mouse
* (it only checks DMI information).
*/
if (psmouse_try_protocol(psmouse, PSMOUSE_LIFEBOOK, &max_proto,
set_properties, max_proto > PSMOUSE_IMEX))
return PSMOUSE_LIFEBOOK;
if (psmouse_try_protocol(psmouse, PSMOUSE_VMMOUSE, &max_proto,
set_properties, max_proto > PSMOUSE_IMEX))
return PSMOUSE_VMMOUSE;
/*
* Try Kensington ThinkingMouse (we try first, because Synaptics
* probe upsets the ThinkingMouse).
*/
if (max_proto > PSMOUSE_IMEX &&
psmouse_try_protocol(psmouse, PSMOUSE_THINKPS, &max_proto,
set_properties, true)) {
return PSMOUSE_THINKPS;
}
/*
* Try Synaptics TouchPad. Note that probing is done even if
* Synaptics protocol support is disabled in config - we need to
* know if it is Synaptics so we can reset it properly after
* probing for IntelliMouse.
*/
if (max_proto > PSMOUSE_PS2 &&
psmouse_try_protocol(psmouse, PSMOUSE_SYNAPTICS, &max_proto,
set_properties, false)) {
synaptics_hardware = true;
if (max_proto > PSMOUSE_IMEX) {
/*
* Try activating protocol, but check if support is
* enabled first, since we try detecting Synaptics
* even when protocol is disabled.
*/
if (IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS) &&
(!set_properties || synaptics_init(psmouse) == 0)) {
return PSMOUSE_SYNAPTICS;
}
/*
* Some Synaptics touchpads can emulate extended
* protocols (like IMPS/2). Unfortunately
* Logitech/Genius probes confuse some firmware
* versions so we'll have to skip them.
*/
max_proto = PSMOUSE_IMEX;
}
/*
* Make sure that touchpad is in relative mode, gestures
* (taps) are enabled.
*/
synaptics_reset(psmouse);
}
/*
* Try Cypress Trackpad. We must try it before Finger Sensing Pad
* because Finger Sensing Pad probe upsets some modules of Cypress
* Trackpads.
*/
if (max_proto > PSMOUSE_IMEX &&
psmouse_try_protocol(psmouse, PSMOUSE_CYPRESS, &max_proto,
set_properties, true)) {
return PSMOUSE_CYPRESS;
}
/* Try ALPS TouchPad */
if (max_proto > PSMOUSE_IMEX) {
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
if (psmouse_try_protocol(psmouse, PSMOUSE_ALPS,
&max_proto, set_properties, true))
return PSMOUSE_ALPS;
}
/* Try OLPC HGPK touchpad */
if (max_proto > PSMOUSE_IMEX &&
psmouse_try_protocol(psmouse, PSMOUSE_HGPK, &max_proto,
set_properties, true)) {
return PSMOUSE_HGPK;
}
/* Try Elantech touchpad */
if (max_proto > PSMOUSE_IMEX &&
psmouse_try_protocol(psmouse, PSMOUSE_ELANTECH,
&max_proto, set_properties, true)) {
return PSMOUSE_ELANTECH;
}
if (max_proto > PSMOUSE_IMEX) {
if (psmouse_try_protocol(psmouse, PSMOUSE_GENPS,
&max_proto, set_properties, true))
return PSMOUSE_GENPS;
if (psmouse_try_protocol(psmouse, PSMOUSE_PS2PP,
&max_proto, set_properties, true))
return PSMOUSE_PS2PP;
if (psmouse_try_protocol(psmouse, PSMOUSE_TRACKPOINT,
&max_proto, set_properties, true))
return PSMOUSE_TRACKPOINT;
if (psmouse_try_protocol(psmouse, PSMOUSE_TOUCHKIT_PS2,
&max_proto, set_properties, true))
return PSMOUSE_TOUCHKIT_PS2;
}
/*
* Try Finger Sensing Pad. We do it here because its probe upsets
* Trackpoint devices (causing TP_READ_ID command to time out).
*/
if (max_proto > PSMOUSE_IMEX &&
psmouse_try_protocol(psmouse, PSMOUSE_FSP,
&max_proto, set_properties, true)) {
return PSMOUSE_FSP;
}
/*
* Reset to defaults in case the device got confused by extended
* protocol probes. Note that we follow up with full reset because
* some mice put themselves to sleep when they see PSMOUSE_RESET_DIS.
*/
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
psmouse_reset(psmouse);
if (max_proto >= PSMOUSE_IMEX &&
psmouse_try_protocol(psmouse, PSMOUSE_IMEX,
&max_proto, set_properties, true)) {
return PSMOUSE_IMEX;
}
if (max_proto >= PSMOUSE_IMPS &&
psmouse_try_protocol(psmouse, PSMOUSE_IMPS,
&max_proto, set_properties, true)) {
return PSMOUSE_IMPS;
}
/*
* Okay, all failed, we have a standard mouse here. The number of
* the buttons is still a question, though. We assume 3.
*/
psmouse_try_protocol(psmouse, PSMOUSE_PS2,
&max_proto, set_properties, true);
if (synaptics_hardware) {
/*
* We detected Synaptics hardware but it did not respond to
* IMPS/2 probes. We need to reset the touchpad because if
* there is a track point on the pass through port it could
* get disabled while probing for protocol extensions.
*/
psmouse_reset(psmouse);
}
return PSMOUSE_PS2;
}
/*
* psmouse_probe() probes for a PS/2 mouse.
*/
static int psmouse_probe(struct psmouse *psmouse) static int psmouse_probe(struct psmouse *psmouse)
{ {
struct ps2dev *ps2dev = &psmouse->ps2dev; struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[2]; unsigned char param[2];
/* /*
* First, we check if it's a mouse. It should send 0x00 or 0x03 * First, we check if it's a mouse. It should send 0x00 or 0x03 in
* in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. * case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer.
* Sunrex K8561 IR Keyboard/Mouse reports 0xff on second and subsequent * Sunrex K8561 IR Keyboard/Mouse reports 0xff on second and
* ID queries, probably due to a firmware bug. * subsequent ID queries, probably due to a firmware bug.
*/ */
param[0] = 0xa5; param[0] = 0xa5;
if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
return -1; return -1;
...@@ -1191,10 +1179,10 @@ static int psmouse_probe(struct psmouse *psmouse) ...@@ -1191,10 +1179,10 @@ static int psmouse_probe(struct psmouse *psmouse)
param[0] != 0x04 && param[0] != 0xff) param[0] != 0x04 && param[0] != 0xff)
return -1; return -1;
/* /*
* Then we reset and disable the mouse so that it doesn't generate events. * Then we reset and disable the mouse so that it doesn't generate
*/ * events.
*/
if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS)) if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS))
psmouse_warn(psmouse, "Failed to reset mouse on %s\n", psmouse_warn(psmouse, "Failed to reset mouse on %s\n",
ps2dev->serio->phys); ps2dev->serio->phys);
...@@ -1205,13 +1193,11 @@ static int psmouse_probe(struct psmouse *psmouse) ...@@ -1205,13 +1193,11 @@ static int psmouse_probe(struct psmouse *psmouse)
/* /*
* psmouse_initialize() initializes the mouse to a sane state. * psmouse_initialize() initializes the mouse to a sane state.
*/ */
static void psmouse_initialize(struct psmouse *psmouse) static void psmouse_initialize(struct psmouse *psmouse)
{ {
/* /*
* We set the mouse report rate, resolution and scaling. * We set the mouse report rate, resolution and scaling.
*/ */
if (psmouse_max_proto != PSMOUSE_PS2) { if (psmouse_max_proto != PSMOUSE_PS2) {
psmouse->set_rate(psmouse, psmouse->rate); psmouse->set_rate(psmouse, psmouse->rate);
psmouse->set_resolution(psmouse, psmouse->resolution); psmouse->set_resolution(psmouse, psmouse->resolution);
...@@ -1222,7 +1208,6 @@ static void psmouse_initialize(struct psmouse *psmouse) ...@@ -1222,7 +1208,6 @@ static void psmouse_initialize(struct psmouse *psmouse)
/* /*
* psmouse_activate() enables the mouse so that we get motion reports from it. * psmouse_activate() enables the mouse so that we get motion reports from it.
*/ */
int psmouse_activate(struct psmouse *psmouse) int psmouse_activate(struct psmouse *psmouse)
{ {
if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
...@@ -1236,10 +1221,9 @@ int psmouse_activate(struct psmouse *psmouse) ...@@ -1236,10 +1221,9 @@ int psmouse_activate(struct psmouse *psmouse)
} }
/* /*
* psmouse_deactivate() puts the mouse into poll mode so that we don't get motion * psmouse_deactivate() puts the mouse into poll mode so that we don't get
* reports from it unless we explicitly request it. * motion reports from it unless we explicitly request it.
*/ */
int psmouse_deactivate(struct psmouse *psmouse) int psmouse_deactivate(struct psmouse *psmouse)
{ {
if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) { if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) {
...@@ -1252,11 +1236,9 @@ int psmouse_deactivate(struct psmouse *psmouse) ...@@ -1252,11 +1236,9 @@ int psmouse_deactivate(struct psmouse *psmouse)
return 0; return 0;
} }
/* /*
* psmouse_resync() attempts to re-validate current protocol. * psmouse_resync() attempts to re-validate current protocol.
*/ */
static void psmouse_resync(struct work_struct *work) static void psmouse_resync(struct work_struct *work)
{ {
struct psmouse *parent = NULL, *psmouse = struct psmouse *parent = NULL, *psmouse =
...@@ -1276,16 +1258,16 @@ static void psmouse_resync(struct work_struct *work) ...@@ -1276,16 +1258,16 @@ static void psmouse_resync(struct work_struct *work)
psmouse_deactivate(parent); psmouse_deactivate(parent);
} }
/* /*
* Some mice don't ACK commands sent while they are in the middle of * Some mice don't ACK commands sent while they are in the middle of
* transmitting motion packet. To avoid delay we use ps2_sendbyte() * transmitting motion packet. To avoid delay we use ps2_sendbyte()
* instead of ps2_command() which would wait for 200ms for an ACK * instead of ps2_command() which would wait for 200ms for an ACK
* that may never come. * that may never come.
* As an additional quirk ALPS touchpads may not only forget to ACK * As an additional quirk ALPS touchpads may not only forget to ACK
* disable command but will stop reporting taps, so if we see that * disable command but will stop reporting taps, so if we see that
* mouse at least once ACKs disable we will do full reconnect if ACK * mouse at least once ACKs disable we will do full reconnect if ACK
* is missing. * is missing.
*/ */
psmouse->num_resyncs++; psmouse->num_resyncs++;
if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) { if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) {
...@@ -1294,13 +1276,13 @@ static void psmouse_resync(struct work_struct *work) ...@@ -1294,13 +1276,13 @@ static void psmouse_resync(struct work_struct *work)
} else } else
psmouse->acks_disable_command = true; psmouse->acks_disable_command = true;
/* /*
* Poll the mouse. If it was reset the packet will be shorter than * Poll the mouse. If it was reset the packet will be shorter than
* psmouse->pktsize and ps2_command will fail. We do not expect and * psmouse->pktsize and ps2_command will fail. We do not expect and
* do not handle scenario when mouse "upgrades" its protocol while * do not handle scenario when mouse "upgrades" its protocol while
* disconnected since it would require additional delay. If we ever * disconnected since it would require additional delay. If we ever
* see a mouse that does it we'll adjust the code. * see a mouse that does it we'll adjust the code.
*/ */
if (!failed) { if (!failed) {
if (psmouse->poll(psmouse)) if (psmouse->poll(psmouse))
failed = true; failed = true;
...@@ -1317,11 +1299,12 @@ static void psmouse_resync(struct work_struct *work) ...@@ -1317,11 +1299,12 @@ static void psmouse_resync(struct work_struct *work)
psmouse_set_state(psmouse, PSMOUSE_RESYNCING); psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
} }
} }
/*
* Now try to enable mouse. We try to do that even if poll failed and also /*
* repeat our attempts 5 times, otherwise we may be left out with disabled * Now try to enable mouse. We try to do that even if poll failed
* mouse. * and also repeat our attempts 5 times, otherwise we may be left
*/ * out with disabled mouse.
*/
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
enabled = true; enabled = true;
...@@ -1353,7 +1336,6 @@ static void psmouse_resync(struct work_struct *work) ...@@ -1353,7 +1336,6 @@ static void psmouse_resync(struct work_struct *work)
/* /*
* psmouse_cleanup() resets the mouse into power-on state. * psmouse_cleanup() resets the mouse into power-on state.
*/ */
static void psmouse_cleanup(struct serio *serio) static void psmouse_cleanup(struct serio *serio)
{ {
struct psmouse *psmouse = serio_get_drvdata(serio); struct psmouse *psmouse = serio_get_drvdata(serio);
...@@ -1378,15 +1360,15 @@ static void psmouse_cleanup(struct serio *serio) ...@@ -1378,15 +1360,15 @@ static void psmouse_cleanup(struct serio *serio)
if (psmouse->cleanup) if (psmouse->cleanup)
psmouse->cleanup(psmouse); psmouse->cleanup(psmouse);
/* /*
* Reset the mouse to defaults (bare PS/2 protocol). * Reset the mouse to defaults (bare PS/2 protocol).
*/ */
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
/* /*
* Some boxes, such as HP nx7400, get terribly confused if mouse * Some boxes, such as HP nx7400, get terribly confused if mouse
* is not fully enabled before suspending/shutting down. * is not fully enabled before suspending/shutting down.
*/ */
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
if (parent) { if (parent) {
...@@ -1402,7 +1384,6 @@ static void psmouse_cleanup(struct serio *serio) ...@@ -1402,7 +1384,6 @@ static void psmouse_cleanup(struct serio *serio)
/* /*
* psmouse_disconnect() closes and frees. * psmouse_disconnect() closes and frees.
*/ */
static void psmouse_disconnect(struct serio *serio) static void psmouse_disconnect(struct serio *serio)
{ {
struct psmouse *psmouse, *parent = NULL; struct psmouse *psmouse, *parent = NULL;
...@@ -1602,7 +1583,6 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) ...@@ -1602,7 +1583,6 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
goto out; goto out;
} }
static int psmouse_reconnect(struct serio *serio) static int psmouse_reconnect(struct serio *serio)
{ {
struct psmouse *psmouse = serio_get_drvdata(serio); struct psmouse *psmouse = serio_get_drvdata(serio);
......
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