Commit f0d5c6f4 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: psmouse - attempt to re-synchronize mouse every 5 seconds

This should help driver to deal vith KVMs that reset mice when
switching between boxes.
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent b65d0d1b
......@@ -348,6 +348,40 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable)
return 0;
}
/*
* alps_poll() - poll the touchpad for current motion packet.
* Used in resync.
*/
static int alps_poll(struct psmouse *psmouse)
{
struct alps_data *priv = psmouse->private;
unsigned char buf[6];
int poll_failed;
if (priv->i->flags & ALPS_PASS)
alps_passthrough_mode(psmouse, 1);
poll_failed = ps2_command(&psmouse->ps2dev, buf,
PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
if (priv->i->flags & ALPS_PASS)
alps_passthrough_mode(psmouse, 0);
if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
return -1;
if ((psmouse->badbyte & 0xc8) == 0x08) {
/*
* Poll the track stick ...
*/
if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8)))
return -1;
}
memcpy(psmouse->packet, buf, sizeof(buf));
return 0;
}
static int alps_reconnect(struct psmouse *psmouse)
{
struct alps_data *priv = psmouse->private;
......@@ -451,10 +485,14 @@ int alps_init(struct psmouse *psmouse)
input_register_device(priv->dev2);
psmouse->protocol_handler = alps_process_byte;
psmouse->poll = alps_poll;
psmouse->disconnect = alps_disconnect;
psmouse->reconnect = alps_reconnect;
psmouse->pktsize = 6;
/* We are having trouble resyncing ALPS touchpads so disable it for now */
psmouse->resync_time = 0;
return 0;
init_fail:
......
......@@ -117,7 +117,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
if (psmouse_sliced_command(psmouse, command))
return -1;
if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL))
if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300))
return -1;
return 0;
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
#define PSMOUSE_CMD_GETINFO 0x03e9
#define PSMOUSE_CMD_SETSTREAM 0x00ea
#define PSMOUSE_CMD_SETPOLL 0x00f0
#define PSMOUSE_CMD_POLL 0x03eb
#define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */
#define PSMOUSE_CMD_GETID 0x02f2
#define PSMOUSE_CMD_SETRATE 0x10f3
#define PSMOUSE_CMD_ENABLE 0x00f4
......@@ -23,6 +23,7 @@
enum psmouse_state {
PSMOUSE_IGNORE,
PSMOUSE_INITIALIZING,
PSMOUSE_RESYNCING,
PSMOUSE_CMD_MODE,
PSMOUSE_ACTIVATED,
};
......@@ -38,15 +39,19 @@ struct psmouse {
void *private;
struct input_dev *dev;
struct ps2dev ps2dev;
struct work_struct resync_work;
char *vendor;
char *name;
unsigned char packet[8];
unsigned char badbyte;
unsigned char pktcnt;
unsigned char pktsize;
unsigned char type;
unsigned char acks_disable_command;
unsigned int model;
unsigned long last;
unsigned long out_of_sync;
unsigned long num_resyncs;
enum psmouse_state state;
char devname[64];
char phys[32];
......@@ -54,6 +59,7 @@ struct psmouse {
unsigned int rate;
unsigned int resolution;
unsigned int resetafter;
unsigned int resync_time;
unsigned int smartscroll; /* Logitech only */
psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
......@@ -62,6 +68,7 @@ struct psmouse {
int (*reconnect)(struct psmouse *psmouse);
void (*disconnect)(struct psmouse *psmouse);
int (*poll)(struct psmouse *psmouse);
void (*pt_activate)(struct psmouse *psmouse);
void (*pt_deactivate)(struct psmouse *psmouse);
......
......@@ -652,6 +652,8 @@ int synaptics_init(struct psmouse *psmouse)
psmouse->disconnect = synaptics_disconnect;
psmouse->reconnect = synaptics_reconnect;
psmouse->pktsize = 6;
/* Synaptics can usually stay in sync without extra help */
psmouse->resync_time = 0;
if (SYN_CAP_PASS_THROUGH(priv->capabilities))
synaptics_pt_create(psmouse);
......
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