summaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/elan_i2c_i2c.c30
-rw-r--r--drivers/input/mouse/synaptics.c37
2 files changed, 44 insertions, 23 deletions
diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c
index a679e56c44cd..f431da07f861 100644
--- a/drivers/input/mouse/elan_i2c_i2c.c
+++ b/drivers/input/mouse/elan_i2c_i2c.c
@@ -554,32 +554,34 @@ static int elan_i2c_finish_fw_update(struct i2c_client *client,
struct completion *completion)
{
struct device *dev = &client->dev;
- long ret;
int error;
int len;
- u8 buffer[ETP_I2C_INF_LENGTH];
+ u8 buffer[ETP_I2C_REPORT_LEN];
+
+ len = i2c_master_recv(client, buffer, ETP_I2C_REPORT_LEN);
+ if (len != ETP_I2C_REPORT_LEN) {
+ error = len < 0 ? len : -EIO;
+ dev_warn(dev, "failed to read I2C data after FW WDT reset: %d (%d)\n",
+ error, len);
+ }
reinit_completion(completion);
enable_irq(client->irq);
error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, ETP_I2C_RESET);
- if (!error)
- ret = wait_for_completion_interruptible_timeout(completion,
- msecs_to_jiffies(300));
- disable_irq(client->irq);
-
if (error) {
dev_err(dev, "device reset failed: %d\n", error);
- return error;
- } else if (ret == 0) {
+ } else if (!wait_for_completion_timeout(completion,
+ msecs_to_jiffies(300))) {
dev_err(dev, "timeout waiting for device reset\n");
- return -ETIMEDOUT;
- } else if (ret < 0) {
- error = ret;
- dev_err(dev, "error waiting for device reset: %d\n", error);
- return error;
+ error = -ETIMEDOUT;
}
+ disable_irq(client->irq);
+
+ if (error)
+ return error;
+
len = i2c_master_recv(client, buffer, ETP_I2C_INF_LENGTH);
if (len != ETP_I2C_INF_LENGTH) {
error = len < 0 ? len : -EIO;
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 131df9d3660f..16c30460ef04 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -176,6 +176,12 @@ static const char * const smbus_pnp_ids[] = {
NULL
};
+static const char * const forcepad_pnp_ids[] = {
+ "SYN300D",
+ "SYN3014",
+ NULL
+};
+
/*
* Send a command to the synpatics touchpad by special commands
*/
@@ -397,6 +403,8 @@ static int synaptics_query_hardware(struct psmouse *psmouse,
{
int error;
+ memset(info, 0, sizeof(*info));
+
error = synaptics_identify(psmouse, info);
if (error)
return error;
@@ -480,13 +488,6 @@ static const struct min_max_quirk min_max_pnpid_table[] = {
{ }
};
-/* This list has been kindly provided by Synaptics. */
-static const char * const forcepad_pnp_ids[] = {
- "SYN300D",
- "SYN3014",
- NULL
-};
-
/*****************************************************************************
* Synaptics communications functions
****************************************************************************/
@@ -1687,7 +1688,8 @@ enum {
SYNAPTICS_INTERTOUCH_ON,
};
-static int synaptics_intertouch = SYNAPTICS_INTERTOUCH_NOT_SET;
+static int synaptics_intertouch = IS_ENABLED(CONFIG_RMI4_SMB) ?
+ SYNAPTICS_INTERTOUCH_NOT_SET : SYNAPTICS_INTERTOUCH_OFF;
module_param_named(synaptics_intertouch, synaptics_intertouch, int, 0644);
MODULE_PARM_DESC(synaptics_intertouch, "Use a secondary bus for the Synaptics device.");
@@ -1737,8 +1739,16 @@ static int synaptics_setup_intertouch(struct psmouse *psmouse,
if (synaptics_intertouch == SYNAPTICS_INTERTOUCH_NOT_SET) {
if (!psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
- !psmouse_matches_pnp_id(psmouse, smbus_pnp_ids))
+ !psmouse_matches_pnp_id(psmouse, smbus_pnp_ids)) {
+
+ if (!psmouse_matches_pnp_id(psmouse, forcepad_pnp_ids))
+ psmouse_info(psmouse,
+ "Your touchpad (%s) says it can support a different bus. "
+ "If i2c-hid and hid-rmi are not used, you might want to try setting psmouse.synaptics_intertouch to 1 and report this to linux-input@vger.kernel.org.\n",
+ psmouse->ps2dev.serio->firmware_id);
+
return -ENXIO;
+ }
}
psmouse_info(psmouse, "Trying to set up SMBus access\n");
@@ -1810,6 +1820,15 @@ int synaptics_init(struct psmouse *psmouse)
}
if (SYN_CAP_INTERTOUCH(info.ext_cap_0c)) {
+ if ((!IS_ENABLED(CONFIG_RMI4_SMB) ||
+ !IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS)) &&
+ /* Forcepads need F21, which is not ready */
+ !psmouse_matches_pnp_id(psmouse, forcepad_pnp_ids)) {
+ psmouse_warn(psmouse,
+ "The touchpad can support a better bus than the too old PS/2 protocol. "
+ "Make sure MOUSE_PS2_SYNAPTICS_SMBUS and RMI4_SMB are enabled to get a better touchpad experience.\n");
+ }
+
error = synaptics_setup_intertouch(psmouse, &info, true);
if (!error)
return PSMOUSE_SYNAPTICS_SMBUS;
OpenPOWER on IntegriCloud