diff options
Diffstat (limited to 'drivers/input/mouse/alps.c')
-rw-r--r-- | drivers/input/mouse/alps.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4e71a66fc7f..2c5f11a4f6b 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) { |