Commit 315eb996 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: psmouse - rework setting of BTN_MIDDLE capability

Do not start protocol detection assuming that middle mouse is present,
instead let individual protocols explicitly set this capability.
This fixes issue with Synaptics touchpads pretending that they have
middle button when hardware clearly reports otherwise.
Reported-and-tested-by: default avatarAndrey Borzenkov <arvidjaar@mail.ru>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 0cc1770b
...@@ -430,19 +430,6 @@ static int hgpk_register(struct psmouse *psmouse) ...@@ -430,19 +430,6 @@ static int hgpk_register(struct psmouse *psmouse)
struct input_dev *dev = psmouse->dev; struct input_dev *dev = psmouse->dev;
int err; int err;
/* unset the things that psmouse-base sets which we don't have */
__clear_bit(BTN_MIDDLE, dev->keybit);
/* set the things we do have */
__set_bit(EV_KEY, dev->evbit);
__set_bit(EV_REL, dev->evbit);
__set_bit(REL_X, dev->relbit);
__set_bit(REL_Y, dev->relbit);
__set_bit(BTN_LEFT, dev->keybit);
__set_bit(BTN_RIGHT, dev->keybit);
/* register handlers */ /* register handlers */
psmouse->protocol_handler = hgpk_process_byte; psmouse->protocol_handler = hgpk_process_byte;
psmouse->poll = hgpk_poll; psmouse->poll = hgpk_poll;
......
...@@ -404,8 +404,8 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) ...@@ -404,8 +404,8 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties)
} }
} }
if (buttons < 3) if (buttons >= 3)
__clear_bit(BTN_MIDDLE, psmouse->dev->keybit); __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
if (model_info) if (model_info)
ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
......
...@@ -425,6 +425,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties) ...@@ -425,6 +425,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties)
return -1; return -1;
if (set_properties) { if (set_properties) {
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
__set_bit(BTN_EXTRA, psmouse->dev->keybit); __set_bit(BTN_EXTRA, psmouse->dev->keybit);
__set_bit(BTN_SIDE, psmouse->dev->keybit); __set_bit(BTN_SIDE, psmouse->dev->keybit);
__set_bit(REL_WHEEL, psmouse->dev->relbit); __set_bit(REL_WHEEL, psmouse->dev->relbit);
...@@ -460,8 +461,10 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties) ...@@ -460,8 +461,10 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
__set_bit(BTN_MIDDLE, psmouse->dev->keybit); __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
__set_bit(REL_WHEEL, psmouse->dev->relbit); __set_bit(REL_WHEEL, psmouse->dev->relbit);
if (!psmouse->vendor) psmouse->vendor = "Generic"; if (!psmouse->vendor)
if (!psmouse->name) psmouse->name = "Wheel Mouse"; psmouse->vendor = "Generic";
if (!psmouse->name)
psmouse->name = "Wheel Mouse";
psmouse->pktsize = 4; psmouse->pktsize = 4;
} }
...@@ -504,8 +507,10 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) ...@@ -504,8 +507,10 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
__set_bit(BTN_SIDE, psmouse->dev->keybit); __set_bit(BTN_SIDE, psmouse->dev->keybit);
__set_bit(BTN_EXTRA, psmouse->dev->keybit); __set_bit(BTN_EXTRA, psmouse->dev->keybit);
if (!psmouse->vendor) psmouse->vendor = "Generic"; if (!psmouse->vendor)
if (!psmouse->name) psmouse->name = "Explorer Mouse"; psmouse->vendor = "Generic";
if (!psmouse->name)
psmouse->name = "Explorer Mouse";
psmouse->pktsize = 4; psmouse->pktsize = 4;
} }
...@@ -536,6 +541,7 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties) ...@@ -536,6 +541,7 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties)
return -1; return -1;
if (set_properties) { if (set_properties) {
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
__set_bit(BTN_EXTRA, psmouse->dev->keybit); __set_bit(BTN_EXTRA, psmouse->dev->keybit);
psmouse->vendor = "Kensington"; psmouse->vendor = "Kensington";
...@@ -551,8 +557,16 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties) ...@@ -551,8 +557,16 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties)
static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
{ {
if (set_properties) { if (set_properties) {
if (!psmouse->vendor) psmouse->vendor = "Generic"; if (!psmouse->vendor)
if (!psmouse->name) psmouse->name = "Mouse"; psmouse->vendor = "Generic";
if (!psmouse->name)
psmouse->name = "Mouse";
/*
* We have no way of figuring true number of buttons so let's
* assume that the device has 3.
*/
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
} }
return 0; return 0;
...@@ -567,6 +581,8 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties) ...@@ -567,6 +581,8 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties)
if (set_properties) { if (set_properties) {
psmouse->vendor = "Cortron"; psmouse->vendor = "Cortron";
psmouse->name = "PS/2 Trackball"; psmouse->name = "PS/2 Trackball";
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
__set_bit(BTN_SIDE, psmouse->dev->keybit); __set_bit(BTN_SIDE, psmouse->dev->keybit);
} }
...@@ -1184,15 +1200,16 @@ static void psmouse_disconnect(struct serio *serio) ...@@ -1184,15 +1200,16 @@ static void psmouse_disconnect(struct serio *serio)
mutex_unlock(&psmouse_mutex); mutex_unlock(&psmouse_mutex);
} }
static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse_protocol *proto) static int psmouse_switch_protocol(struct psmouse *psmouse,
const struct psmouse_protocol *proto)
{ {
struct input_dev *input_dev = psmouse->dev; struct input_dev *input_dev = psmouse->dev;
input_dev->dev.parent = &psmouse->ps2dev.serio->dev; input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | input_dev->keybit[BIT_WORD(BTN_MOUSE)] =
BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
psmouse->set_rate = psmouse_set_rate; psmouse->set_rate = psmouse_set_rate;
...@@ -1209,8 +1226,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse ...@@ -1209,8 +1226,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse
return -1; return -1;
psmouse->type = proto->type; psmouse->type = proto->type;
} } else
else
psmouse->type = psmouse_extensions(psmouse, psmouse->type = psmouse_extensions(psmouse,
psmouse_max_proto, true); psmouse_max_proto, true);
......
...@@ -836,6 +836,7 @@ int fsp_init(struct psmouse *psmouse) ...@@ -836,6 +836,7 @@ int fsp_init(struct psmouse *psmouse)
priv->flags |= FSPDRV_FLAG_EN_OPC; priv->flags |= FSPDRV_FLAG_EN_OPC;
/* Set up various supported input event bits */ /* Set up various supported input event bits */
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
__set_bit(BTN_BACK, psmouse->dev->keybit); __set_bit(BTN_BACK, psmouse->dev->keybit);
__set_bit(BTN_FORWARD, psmouse->dev->keybit); __set_bit(BTN_FORWARD, psmouse->dev->keybit);
__set_bit(REL_WHEEL, psmouse->dev->relbit); __set_bit(REL_WHEEL, psmouse->dev->relbit);
......
...@@ -284,7 +284,6 @@ static int trackpoint_reconnect(struct psmouse *psmouse) ...@@ -284,7 +284,6 @@ static int trackpoint_reconnect(struct psmouse *psmouse)
int trackpoint_detect(struct psmouse *psmouse, bool set_properties) int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
{ {
struct trackpoint_data *priv;
struct ps2dev *ps2dev = &psmouse->ps2dev; struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char firmware_id; unsigned char firmware_id;
unsigned char button_info; unsigned char button_info;
...@@ -301,8 +300,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) ...@@ -301,8 +300,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
button_info = 0; button_info = 0;
} }
psmouse->private = priv = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
if (!priv) if (!psmouse->private)
return -1; return -1;
psmouse->vendor = "IBM"; psmouse->vendor = "IBM";
...@@ -311,7 +310,10 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) ...@@ -311,7 +310,10 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
psmouse->reconnect = trackpoint_reconnect; psmouse->reconnect = trackpoint_reconnect;
psmouse->disconnect = trackpoint_disconnect; psmouse->disconnect = trackpoint_disconnect;
trackpoint_defaults(priv); if ((button_info & 0x0f) >= 3)
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
trackpoint_defaults(psmouse->private);
trackpoint_sync(psmouse); trackpoint_sync(psmouse);
error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
...@@ -319,7 +321,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) ...@@ -319,7 +321,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
printk(KERN_ERR printk(KERN_ERR
"trackpoint.c: failed to create sysfs attributes, error: %d\n", "trackpoint.c: failed to create sysfs attributes, error: %d\n",
error); error);
kfree(priv); kfree(psmouse->private);
psmouse->private = NULL;
return -1; return -1;
} }
......
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