Message ID | 1414884310-19842-5-git-send-email-pali.rohar@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Pali, On Sun, Nov 02, 2014 at 12:25:10AM +0100, Pali Rohár wrote: > int alps_detect(struct psmouse *psmouse, bool set_properties) > { > - struct alps_data dummy; > + unsigned char e6[4]; > > - if (alps_identify(psmouse, &dummy) < 0) > - return -1; > + /* > + * Try "E6 report". > + * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed. > + * The bits 0-2 of the first byte will be 1s if some buttons are > + * pressed. > + */ > + if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, > + PSMOUSE_CMD_SETSCALE11, e6)) > + return -EIO; > + > + if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && e6[2] != 100)) > + return -EINVAL; > > if (set_properties) { > + /* > + * NOTE: To detect model and trackstick presence we need to do > + * full device reset. To speed up detection and prevent > + * calling duplicate initialization sequence (both in > + * alps_detect() and alps_init()) we set model/protocol > + * version and correct name in alps_init() (which will > + * do full device reset). For now set name to DualPoint. > + */ > psmouse->vendor = "ALPS"; > - psmouse->name = dummy.flags & ALPS_DUALPOINT ? > - "DualPoint TouchPad" : "GlidePoint"; > - psmouse->model = dummy.proto_version << 8; > + psmouse->name = "DualPoint TouchPad"; > } > + > return 0; We can't do this; going by e6 only will give us false positives and alps_detect is supposed to be authoritative. Thanks.
On Sunday 09 November 2014 09:05:04 Dmitry Torokhov wrote: > Hi Pali, > > On Sun, Nov 02, 2014 at 12:25:10AM +0100, Pali Rohár wrote: > > int alps_detect(struct psmouse *psmouse, bool > > set_properties) { > > > > - struct alps_data dummy; > > + unsigned char e6[4]; > > > > - if (alps_identify(psmouse, &dummy) < 0) > > - return -1; > > + /* > > + * Try "E6 report". > > + * ALPS should return 0,0,10 or 0,0,100 if no buttons are > > pressed. + * The bits 0-2 of the first byte will be 1s if > > some buttons are + * pressed. > > + */ > > + if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, > > + PSMOUSE_CMD_SETSCALE11, e6)) > > + return -EIO; > > + > > + if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && > > e6[2] != 100)) + return -EINVAL; > > > > if (set_properties) { > > > > + /* > > + * NOTE: To detect model and trackstick presence we need > > to do + * full device reset. To speed up detection > > and prevent + * calling duplicate initialization > > sequence (both in + * alps_detect() and > > alps_init()) we set model/protocol + * version and > > correct name in alps_init() (which will + * do full > > device reset). For now set name to DualPoint. + */ > > > > psmouse->vendor = "ALPS"; > > > > - psmouse->name = dummy.flags & ALPS_DUALPOINT ? > > - "DualPoint TouchPad" : "GlidePoint"; > > - psmouse->model = dummy.proto_version << 8; > > + psmouse->name = "DualPoint TouchPad"; > > > > } > > > > + > > > > return 0; > > We can't do this; going by e6 only will give us false > positives and alps_detect is supposed to be authoritative. > > Thanks. psmouse-base.c is calling alps_detect() and alps_init() consecutively so it does not matter if code is in _detect or _init function. Just need to make sure that correct order will be used. So this patch could not bring any problems. If psmouse-base.c detect device false-positive as ALPS (with alps_detect()) then it immediately calls alps_init() which fails and psmouse-base.c will try to use another protocol.
On Sunday 09 November 2014 12:30:03 Pali Rohár wrote: > On Sunday 09 November 2014 09:05:04 Dmitry Torokhov wrote: > > Hi Pali, > > > > On Sun, Nov 02, 2014 at 12:25:10AM +0100, Pali Rohár wrote: > > > int alps_detect(struct psmouse *psmouse, bool > > > set_properties) { > > > > > > - struct alps_data dummy; > > > + unsigned char e6[4]; > > > > > > - if (alps_identify(psmouse, &dummy) < 0) > > > - return -1; > > > + /* > > > + * Try "E6 report". > > > + * ALPS should return 0,0,10 or 0,0,100 if no buttons > > > are pressed. + * The bits 0-2 of the first byte will be > > > 1s if some buttons are + * pressed. > > > + */ > > > + if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, > > > + PSMOUSE_CMD_SETSCALE11, e6)) > > > + return -EIO; > > > + > > > + if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && > > > e6[2] != 100)) + return -EINVAL; > > > > > > if (set_properties) { > > > > > > + /* > > > + * NOTE: To detect model and trackstick presence we > > need > > > > to do + * full device reset. To speed up > > detection > > > > and prevent + * calling duplicate initialization > > > sequence (both in + * alps_detect() and > > > alps_init()) we set model/protocol + * version and > > > correct name in alps_init() (which will + * do > > full > > > > device reset). For now set name to DualPoint. + */ > > > > > > psmouse->vendor = "ALPS"; > > > > > > - psmouse->name = dummy.flags & ALPS_DUALPOINT ? > > > - "DualPoint TouchPad" : "GlidePoint"; > > > - psmouse->model = dummy.proto_version << 8; > > > + psmouse->name = "DualPoint TouchPad"; > > > > > > } > > > > > > + > > > > > > return 0; > > > > We can't do this; going by e6 only will give us false > > positives and alps_detect is supposed to be authoritative. > > > > Thanks. > > psmouse-base.c is calling alps_detect() and alps_init() > consecutively so it does not matter if code is in _detect or > _init function. Just need to make sure that correct order will > be used. So this patch could not bring any problems. > > If psmouse-base.c detect device false-positive as ALPS (with > alps_detect()) then it immediately calls alps_init() which > fails and psmouse-base.c will try to use another protocol. Dmitry: PING Also see my comment for PATCH v3 3/4.
On Friday 14 November 2014 12:22:33 Pali Rohár wrote: > On Sunday 09 November 2014 12:30:03 Pali Rohár wrote: > > On Sunday 09 November 2014 09:05:04 Dmitry Torokhov wrote: > > > Hi Pali, > > > > > > On Sun, Nov 02, 2014 at 12:25:10AM +0100, Pali Rohár wrote: > > > > int alps_detect(struct psmouse *psmouse, bool > > > > set_properties) { > > > > > > > > - struct alps_data dummy; > > > > + unsigned char e6[4]; > > > > > > > > - if (alps_identify(psmouse, &dummy) < 0) > > > > - return -1; > > > > + /* > > > > + * Try "E6 report". > > > > + * ALPS should return 0,0,10 or 0,0,100 if no buttons > > > > are pressed. + * The bits 0-2 of the first byte will be > > > > 1s if some buttons are + * pressed. > > > > + */ > > > > + if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, > > > > + PSMOUSE_CMD_SETSCALE11, e6)) > > > > + return -EIO; > > > > + > > > > + if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 > > && > > > > > e6[2] != 100)) + return -EINVAL; > > > > > > > > if (set_properties) { > > > > > > > > + /* > > > > + * NOTE: To detect model and trackstick presence we > > > > need > > > > > > to do + * full device reset. To speed up > > > > detection > > > > > > and prevent + * calling duplicate > > initialization > > > > > sequence (both in + * alps_detect() and > > > > alps_init()) we set model/protocol + * version > > and > > > > > correct name in alps_init() (which will + * do > > > > full > > > > > > device reset). For now set name to DualPoint. + */ > > > > > > > > psmouse->vendor = "ALPS"; > > > > > > > > - psmouse->name = dummy.flags & ALPS_DUALPOINT ? > > > > - "DualPoint TouchPad" : "GlidePoint"; > > > > - psmouse->model = dummy.proto_version << 8; > > > > + psmouse->name = "DualPoint TouchPad"; > > > > > > > > } > > > > > > > > + > > > > > > > > return 0; > > > > > > We can't do this; going by e6 only will give us false > > > positives and alps_detect is supposed to be authoritative. > > > > > > Thanks. > > > > psmouse-base.c is calling alps_detect() and alps_init() > > consecutively so it does not matter if code is in _detect or > > _init function. Just need to make sure that correct order > > will be used. So this patch could not bring any problems. > > > > If psmouse-base.c detect device false-positive as ALPS (with > > alps_detect()) then it immediately calls alps_init() which > > fails and psmouse-base.c will try to use another protocol. > > Dmitry: PING > Also see my comment for PATCH v3 3/4. Dmitry, finally I split this big patch into more smaller and tried to fix what you did not like. I sent new series of patches, so drop this one 4/4.
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index e802d28..04161b6 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -1732,6 +1732,7 @@ error: static int alps_hw_init_v3(struct psmouse *psmouse) { + struct alps_data *priv = psmouse->private; struct ps2dev *ps2dev = &psmouse->ps2dev; int reg_val; unsigned char param[4]; @@ -1740,9 +1741,15 @@ static int alps_hw_init_v3(struct psmouse *psmouse) if (reg_val == -EIO) goto error; - if (reg_val == 0 && - alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO) - goto error; + if (reg_val == 0) { + reg_val = alps_setup_trackstick_v3(psmouse, + ALPS_REG_BASE_PINNACLE); + if (reg_val == -EIO) + goto error; + } + + if (reg_val == -ENODEV) + priv->flags &= ~ALPS_DUALPOINT; if (alps_enter_command_mode(psmouse) || alps_absolute_mode_v3(psmouse)) { @@ -1849,15 +1856,20 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse) struct ps2dev *ps2dev = &psmouse->ps2dev; int reg_val, ret = -1; - if (priv->flags & ALPS_DUALPOINT) { + reg_val = alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE); + if (reg_val == -EIO) + goto error; + + if (reg_val == 0) { reg_val = alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE); if (reg_val == -EIO) goto error; - if (reg_val == -ENODEV) - priv->flags &= ~ALPS_DUALPOINT; } + if (reg_val == -ENODEV) + priv->flags &= ~ALPS_DUALPOINT; + if (alps_enter_command_mode(psmouse) || alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 || alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00)) @@ -2176,20 +2188,15 @@ static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) { - unsigned char e6[4], e7[4], ec[4]; + unsigned char e7[4], ec[4]; + int ret; /* * First try "E6 report". - * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed. - * The bits 0-2 of the first byte will be 1s if some buttons are - * pressed. */ - if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, - PSMOUSE_CMD_SETSCALE11, e6)) - return -EIO; - - if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && e6[2] != 100)) - return -EINVAL; + ret = alps_detect(psmouse, false); + if (ret < 0) + return ret; /* * Now get the "E7" and "EC" reports. These will uniquely identify @@ -2231,12 +2238,6 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) priv->y_bits = 12; priv->flags |= ALPS_IS_RUSHMORE; - /* hack to make addr_command, nibble_command available */ - psmouse->private = priv; - - if (alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE)) - priv->flags &= ~ALPS_DUALPOINT; - return 0; } else if (ec[0] == 0x88 && ec[1] == 0x07 && ec[2] >= 0x90 && ec[2] <= 0x9d) { @@ -2370,14 +2371,24 @@ int alps_init(struct psmouse *psmouse) dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE); } + if (priv->flags & ALPS_DUALPOINT) { + /* + * format of device name is: "protocol vendor name" + * see function psmouse_switch_protocol() in psmouse-base.c + */ + dev2->name = "AlpsPS/2 ALPS DualPoint Stick"; + dev2->id.product = PSMOUSE_ALPS; + dev2->id.version = priv->proto_version; + } else { + dev2->name = "PS/2 ALPS Mouse"; + dev2->id.product = PSMOUSE_PS2; + dev2->id.version = 0x0000; + } + snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); dev2->phys = priv->phys; - dev2->name = (priv->flags & ALPS_DUALPOINT) ? - "DualPoint Stick" : "ALPS PS/2 Device"; dev2->id.bustype = BUS_I8042; dev2->id.vendor = 0x0002; - dev2->id.product = PSMOUSE_ALPS; - dev2->id.version = 0x0000; dev2->dev.parent = &psmouse->ps2dev.serio->dev; dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); @@ -2392,6 +2403,10 @@ int alps_init(struct psmouse *psmouse) if (input_register_device(priv->dev2)) goto init_fail; + if (!(priv->flags & ALPS_DUALPOINT)) + psmouse->name = "GlidePoint TouchPad"; + psmouse->model = priv->proto_version; + psmouse->protocol_handler = alps_process_byte; psmouse->poll = alps_poll; psmouse->disconnect = alps_disconnect; @@ -2416,17 +2431,34 @@ init_fail: int alps_detect(struct psmouse *psmouse, bool set_properties) { - struct alps_data dummy; + unsigned char e6[4]; - if (alps_identify(psmouse, &dummy) < 0) - return -1; + /* + * Try "E6 report". + * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed. + * The bits 0-2 of the first byte will be 1s if some buttons are + * pressed. + */ + if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, + PSMOUSE_CMD_SETSCALE11, e6)) + return -EIO; + + if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && e6[2] != 100)) + return -EINVAL; if (set_properties) { + /* + * NOTE: To detect model and trackstick presence we need to do + * full device reset. To speed up detection and prevent + * calling duplicate initialization sequence (both in + * alps_detect() and alps_init()) we set model/protocol + * version and correct name in alps_init() (which will + * do full device reset). For now set name to DualPoint. + */ psmouse->vendor = "ALPS"; - psmouse->name = dummy.flags & ALPS_DUALPOINT ? - "DualPoint TouchPad" : "GlidePoint"; - psmouse->model = dummy.proto_version << 8; + psmouse->name = "DualPoint TouchPad"; } + return 0; }