diff options
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/mouse/alps.c | 13 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 22 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.h | 1 |
3 files changed, 34 insertions, 2 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 15d6bffdea77..e6708f6efb4d 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -251,6 +251,14 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) return; } + /* Non interleaved V2 dualpoint has separate stick button bits */ + if (priv->proto_version == ALPS_PROTO_V2 && + priv->flags == (ALPS_PASS | ALPS_DUALPOINT)) { + left |= packet[0] & 1; + right |= packet[0] & 2; + middle |= packet[0] & 4; + } + alps_report_buttons(dev, dev2, left, right, middle); /* Convert hardware tap to a reasonable Z value */ @@ -1337,13 +1345,14 @@ static void alps_report_bare_ps2_packet(struct psmouse *psmouse, bool report_buttons) { struct alps_data *priv = psmouse->private; - struct input_dev *dev; + struct input_dev *dev, *dev2 = NULL; /* Figure out which device to use to report the bare packet */ if (priv->proto_version == ALPS_PROTO_V2 && (priv->flags & ALPS_DUALPOINT)) { /* On V2 devices the DualPoint Stick reports bare packets */ dev = priv->dev2; + dev2 = psmouse->dev; } else if (unlikely(IS_ERR_OR_NULL(priv->dev3))) { /* Register dev3 mouse if we received PS/2 packet first time */ if (!IS_ERR(priv->dev3)) @@ -1355,7 +1364,7 @@ static void alps_report_bare_ps2_packet(struct psmouse *psmouse, } if (report_buttons) - alps_report_buttons(dev, NULL, + alps_report_buttons(dev, dev2, packet[0] & 1, packet[0] & 2, packet[0] & 4); input_report_rel(dev, REL_X, diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 6e22682c8255..991dc6b20a58 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -893,6 +893,21 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) } /* + * This writes the reg_07 value again to the hardware at the end of every + * set_rate call because the register loses its value. reg_07 allows setting + * absolute mode on v4 hardware + */ +static void elantech_set_rate_restore_reg_07(struct psmouse *psmouse, + unsigned int rate) +{ + struct elantech_data *etd = psmouse->private; + + etd->original_set_rate(psmouse, rate); + if (elantech_write_reg(psmouse, 0x07, etd->reg_07)) + psmouse_err(psmouse, "restoring reg_07 failed\n"); +} + +/* * Put the touchpad into absolute mode */ static int elantech_set_absolute_mode(struct psmouse *psmouse) @@ -1094,6 +1109,8 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, * Asus K53SV 0x450f01 78, 15, 0c 2 hw buttons * Asus G46VW 0x460f02 00, 18, 0c 2 hw buttons * Asus G750JX 0x360f00 00, 16, 0c 2 hw buttons + * Asus TP500LN 0x381f17 10, 14, 0e clickpad + * Asus X750JN 0x381f17 10, 14, 0e clickpad * Asus UX31 0x361f00 20, 15, 0e clickpad * Asus UX32VD 0x361f02 00, 15, 0e clickpad * Avatar AVIU-145A2 0x361f00 ? clickpad @@ -1635,6 +1652,11 @@ int elantech_init(struct psmouse *psmouse) goto init_fail; } + if (etd->fw_version == 0x381f17) { + etd->original_set_rate = psmouse->set_rate; + psmouse->set_rate = elantech_set_rate_restore_reg_07; + } + if (elantech_set_input_params(psmouse)) { psmouse_err(psmouse, "failed to query touchpad range.\n"); goto init_fail; diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 6f3afec02f03..f965d1569cc3 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h @@ -142,6 +142,7 @@ struct elantech_data { struct finger_pos mt[ETP_MAX_FINGERS]; unsigned char parity[256]; int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param); + void (*original_set_rate)(struct psmouse *psmouse, unsigned int rate); }; #ifdef CONFIG_MOUSE_PS2_ELANTECH |