summaryrefslogtreecommitdiff
path: root/drivers/input/mouse/alps.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse/alps.c')
-rw-r--r--drivers/input/mouse/alps.c65
1 files changed, 37 insertions, 28 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 4e71a66fc7fc..2c5f11a4f6b4 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -251,11 +251,15 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
- for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++);
- *version = (param[0] << 8) | (param[1] << 4) | i;
+ if (version) {
+ for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
+ /* empty */;
+ *version = (param[0] << 8) | (param[1] << 4) | i;
+ }
for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
- if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature)))
+ if (!memcmp(param, alps_model_data[i].signature,
+ sizeof(alps_model_data[i].signature)))
return alps_model_data + i;
return NULL;
@@ -380,32 +384,46 @@ static int alps_poll(struct psmouse *psmouse)
return 0;
}
-static int alps_reconnect(struct psmouse *psmouse)
+static int alps_hw_init(struct psmouse *psmouse, int *version)
{
struct alps_data *priv = psmouse->private;
- int version;
-
- psmouse_reset(psmouse);
- if (!(priv->i = alps_get_model(psmouse, &version)))
+ priv->i = alps_get_model(psmouse, version);
+ if (!priv->i)
return -1;
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
return -1;
if (alps_tap_mode(psmouse, 1)) {
- printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n");
+ printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
return -1;
}
if (alps_absolute_mode(psmouse)) {
- printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n");
+ printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
return -1;
}
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
return -1;
+ /* ALPS needs stream mode, otherwise it won't report any data */
+ if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
+ printk(KERN_ERR "alps.c: Failed to enable stream mode\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int alps_reconnect(struct psmouse *psmouse)
+{
+ psmouse_reset(psmouse);
+
+ if (alps_hw_init(psmouse, NULL))
+ return -1;
+
return 0;
}
@@ -424,28 +442,15 @@ int alps_init(struct psmouse *psmouse)
struct input_dev *dev1 = psmouse->dev, *dev2;
int version;
- psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
+ priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
dev2 = input_allocate_device();
if (!priv || !dev2)
goto init_fail;
priv->dev2 = dev2;
+ psmouse->private = priv;
- if (!(priv->i = alps_get_model(psmouse, &version)))
- goto init_fail;
-
- if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
- goto init_fail;
-
- if (alps_tap_mode(psmouse, 1))
- printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
-
- if (alps_absolute_mode(psmouse)) {
- printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
- goto init_fail;
- }
-
- if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
+ if (alps_hw_init(psmouse, &version))
goto init_fail;
dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
@@ -480,7 +485,8 @@ int alps_init(struct psmouse *psmouse)
dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- input_register_device(priv->dev2);
+ if (input_register_device(priv->dev2))
+ goto init_fail;
psmouse->protocol_handler = alps_process_byte;
psmouse->poll = alps_poll;
@@ -494,8 +500,10 @@ int alps_init(struct psmouse *psmouse)
return 0;
init_fail:
+ psmouse_reset(psmouse);
input_free_device(dev2);
kfree(priv);
+ psmouse->private = NULL;
return -1;
}
@@ -504,7 +512,8 @@ int alps_detect(struct psmouse *psmouse, int set_properties)
int version;
const struct alps_model_info *model;
- if (!(model = alps_get_model(psmouse, &version)))
+ model = alps_get_model(psmouse, &version);
+ if (!model)
return -1;
if (set_properties) {