Commit 883a2a80 authored by Kai-Heng Feng's avatar Kai-Heng Feng Committed by Dmitry Torokhov

Input: elantech - enable SMBus on new (2018+) systems

There are some new HP laptops with Elantech touchpad that don't support
multitouch.

Currently we use ETP_NEW_IC_SMBUS_HOST_NOTIFY() to check if SMBus is supported,
but in addition to firmware version, the bus type also informs us whether the IC
can support SMBus. To avoid breaking old ICs, we will only enable SMbus support
based the bus type on systems manufactured after 2018.

Lastly, let's consolidate all checks into elantech_use_host_notify() and use it
to determine whether to use PS/2 or SMBus.
Signed-off-by: default avatarKai-Heng Feng <kai.heng.feng@canonical.com>
Acked-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent b1cbb2f0
...@@ -1827,6 +1827,30 @@ static int elantech_create_smbus(struct psmouse *psmouse, ...@@ -1827,6 +1827,30 @@ static int elantech_create_smbus(struct psmouse *psmouse,
leave_breadcrumbs); leave_breadcrumbs);
} }
static bool elantech_use_host_notify(struct psmouse *psmouse,
struct elantech_device_info *info)
{
if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version))
return true;
switch (info->bus) {
case ETP_BUS_PS2_ONLY:
/* expected case */
break;
case ETP_BUS_SMB_HST_NTFY_ONLY:
case ETP_BUS_PS2_SMB_HST_NTFY:
/* SMbus implementation is stable since 2018 */
if (dmi_get_bios_year() >= 2018)
return true;
default:
psmouse_dbg(psmouse,
"Ignoring SMBus bus provider %d\n", info->bus);
break;
}
return false;
}
/** /**
* elantech_setup_smbus - called once the PS/2 devices are enumerated * elantech_setup_smbus - called once the PS/2 devices are enumerated
* and decides to instantiate a SMBus InterTouch device. * and decides to instantiate a SMBus InterTouch device.
...@@ -1846,7 +1870,7 @@ static int elantech_setup_smbus(struct psmouse *psmouse, ...@@ -1846,7 +1870,7 @@ static int elantech_setup_smbus(struct psmouse *psmouse,
* i2c_blacklist_pnp_ids. * i2c_blacklist_pnp_ids.
* Old ICs are up to the user to decide. * Old ICs are up to the user to decide.
*/ */
if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version) || if (!elantech_use_host_notify(psmouse, info) ||
psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids)) psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids))
return -ENXIO; return -ENXIO;
} }
...@@ -1866,34 +1890,6 @@ static int elantech_setup_smbus(struct psmouse *psmouse, ...@@ -1866,34 +1890,6 @@ static int elantech_setup_smbus(struct psmouse *psmouse,
return 0; return 0;
} }
static bool elantech_use_host_notify(struct psmouse *psmouse,
struct elantech_device_info *info)
{
if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version))
return true;
switch (info->bus) {
case ETP_BUS_PS2_ONLY:
/* expected case */
break;
case ETP_BUS_SMB_ALERT_ONLY:
/* fall-through */
case ETP_BUS_PS2_SMB_ALERT:
psmouse_dbg(psmouse, "Ignoring SMBus provider through alert protocol.\n");
break;
case ETP_BUS_SMB_HST_NTFY_ONLY:
/* fall-through */
case ETP_BUS_PS2_SMB_HST_NTFY:
return true;
default:
psmouse_dbg(psmouse,
"Ignoring SMBus bus provider %d.\n",
info->bus);
}
return false;
}
int elantech_init_smbus(struct psmouse *psmouse) int elantech_init_smbus(struct psmouse *psmouse)
{ {
struct elantech_device_info info; struct elantech_device_info info;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment