From patchwork Tue Mar 19 16:27:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "James M. Leddy" X-Patchwork-Id: 229125 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 02C312C00A2 for ; Wed, 20 Mar 2013 03:27:34 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1UHzNn-00073G-Jd; Tue, 19 Mar 2013 16:27:27 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1UHzNm-00071v-7n for kernel-team@lists.ubuntu.com; Tue, 19 Mar 2013 16:27:26 +0000 Received: from ool-43509a93.dyn.optonline.net ([67.80.154.147] helo=neptune) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1UHzNm-0000Kd-10 for kernel-team@lists.ubuntu.com; Tue, 19 Mar 2013 16:27:26 +0000 From: James M Leddy To: kernel-team@lists.ubuntu.com Subject: [Raring][PATCH 05/13] Input: ALPS - rework detection sequence Date: Tue, 19 Mar 2013 12:27:04 -0400 Message-Id: <1363710432-6172-6-git-send-email-james.leddy@canonical.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1363710432-6172-1-git-send-email-james.leddy@canonical.com> References: <1363710432-6172-1-git-send-email-james.leddy@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: Kevin Cernekee If the E6 report test passes, get the E7 and EC reports right away and then try to match an entry in the table. Pass in the alps_data struct, so that the detection code will be able to set operating parameters based on information found during detection. Change the version (psmouse->model) to report the protocol version only, in preparation for supporting models that do not show up in the ID table. Signed-off-by: Kevin Cernekee Tested-by: Dave Turvene Signed-off-by: Dmitry Torokhov (cherry picked from commit b5d6b851eab7f346ea5e69f46247b363b32b3670) --- drivers/input/mouse/alps.c | 124 +++++++++++++++++++------------------------- drivers/input/mouse/alps.h | 8 +-- 2 files changed, 56 insertions(+), 76 deletions(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 1ca854b..e6a27a5 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -1451,86 +1451,76 @@ static int alps_hw_init(struct psmouse *psmouse) return ret; } -static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version) +static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, + unsigned char *e7, unsigned char *ec) { - static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 }; - unsigned char param[4]; - const struct alps_model_info *model = NULL; + const struct alps_model_info *model; int i; + for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) { + model = &alps_model_data[i]; + + if (!memcmp(e7, model->signature, sizeof(model->signature)) && + (!model->command_mode_resp || + model->command_mode_resp == ec[2])) { + + priv->proto_version = model->proto_version; + priv->flags = model->flags; + priv->byte0 = model->byte0; + priv->mask0 = model->mask0; + + return 0; + } + } + + return -EINVAL; +} + +static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) +{ + unsigned char e6[4], e7[4], ec[4]; + /* * 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, - param)) - return NULL; + if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, + PSMOUSE_CMD_SETSCALE11, e6)) + return -EIO; - if ((param[0] & 0xf8) != 0 || param[1] != 0 || - (param[2] != 10 && param[2] != 100)) - return NULL; + if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && e6[2] != 100)) + return -EINVAL; /* - * Now try "E7 report". Allowed responses are in - * alps_model_data[].signature + * Now get the "E7" and "EC" reports. These will uniquely identify + * most ALPS touchpads. */ - if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, PSMOUSE_CMD_SETSCALE21, - param)) - return NULL; - - 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))) { - model = alps_model_data + i; - break; - } - } + if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, + PSMOUSE_CMD_SETSCALE21, e7) || + alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, + PSMOUSE_CMD_RESET_WRAP, ec) || + alps_exit_command_mode(psmouse)) + return -EIO; - if (model && model->proto_version > ALPS_PROTO_V2) { - /* - * Need to check command mode response to identify - * model - */ - model = NULL; - if (alps_enter_command_mode(psmouse, param)) { - psmouse_warn(psmouse, - "touchpad failed to enter command mode\n"); - } else { - for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) { - if (alps_model_data[i].proto_version > ALPS_PROTO_V2 && - alps_model_data[i].command_mode_resp == param[0]) { - model = alps_model_data + i; - break; - } - } - alps_exit_command_mode(psmouse); + if (alps_match_table(psmouse, priv, e7, ec) == 0) + return 0; - if (!model) - psmouse_dbg(psmouse, - "Unknown command mode response %2.2x\n", - param[0]); - } - } + psmouse_info(psmouse, + "Unknown ALPS touchpad: E7=%2.2x %2.2x %2.2x, EC=%2.2x %2.2x %2.2x\n", + e7[0], e7[1], e7[2], ec[0], ec[1], ec[2]); - return model; + return -EINVAL; } static int alps_reconnect(struct psmouse *psmouse) { - const struct alps_model_info *model; + struct alps_data *priv = psmouse->private; psmouse_reset(psmouse); - model = alps_get_model(psmouse, NULL); - if (!model) + if (alps_identify(psmouse, priv) < 0) return -1; return alps_hw_init(psmouse); @@ -1549,9 +1539,7 @@ static void alps_disconnect(struct psmouse *psmouse) int alps_init(struct psmouse *psmouse) { struct alps_data *priv; - const struct alps_model_info *model; struct input_dev *dev1 = psmouse->dev, *dev2; - int version; priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); dev2 = input_allocate_device(); @@ -1565,15 +1553,9 @@ int alps_init(struct psmouse *psmouse) psmouse_reset(psmouse); - model = alps_get_model(psmouse, &version); - if (!model) + if (alps_identify(psmouse, priv) < 0) goto init_fail; - priv->proto_version = model->proto_version; - priv->byte0 = model->byte0; - priv->mask0 = model->mask0; - priv->flags = model->flags; - if (alps_hw_init(psmouse)) goto init_fail; @@ -1678,18 +1660,16 @@ init_fail: int alps_detect(struct psmouse *psmouse, bool set_properties) { - int version; - const struct alps_model_info *model; + struct alps_data dummy; - model = alps_get_model(psmouse, &version); - if (!model) + if (alps_identify(psmouse, &dummy) < 0) return -1; if (set_properties) { psmouse->vendor = "ALPS"; - psmouse->name = model->flags & ALPS_DUALPOINT ? + psmouse->name = dummy.flags & ALPS_DUALPOINT ? "DualPoint TouchPad" : "GlidePoint"; - psmouse->model = version; + psmouse->model = dummy.proto_version << 8; } return 0; } diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index efd0eea..a81b318 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -12,10 +12,10 @@ #ifndef _ALPS_H #define _ALPS_H -#define ALPS_PROTO_V1 0 -#define ALPS_PROTO_V2 1 -#define ALPS_PROTO_V3 2 -#define ALPS_PROTO_V4 3 +#define ALPS_PROTO_V1 1 +#define ALPS_PROTO_V2 2 +#define ALPS_PROTO_V3 3 +#define ALPS_PROTO_V4 4 /** * struct alps_model_info - touchpad ID table