Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: Force ELAN06FA touchpad I2C bus freq to 100KHz

When a 400KHz freq is used on this model of ELAN touchpad in Linux,
excessive smoothing (similar to when the touchpad's firmware detects
a noisy signal) is sometimes applied. As some devices' (e.g, Lenovo
V15 G4) ACPI tables specify a 400KHz frequency for this device and
some I2C busses (e.g, Designware I2C) default to a 400KHz freq,
force the speed to 100KHz as a workaround.

For future investigation: This problem may be related to the default
HCNT/LCNT values given by some busses' drivers, because they are not
specified in the aforementioned devices' ACPI tables, and because
the device works without issues on Windows at what is expected to be
a 400KHz frequency. The root cause of the issue is not known.

Signed-off-by: Randolph Ha <rha051117@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

authored by

Randolph Ha and committed by
Wolfram Sang
bfd74cd1 b31addf2

+22
+22
drivers/i2c/i2c-core-acpi.c
··· 355 355 {} 356 356 }; 357 357 358 + static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = { 359 + /* 360 + * When a 400KHz freq is used on this model of ELAN touchpad in Linux, 361 + * excessive smoothing (similar to when the touchpad's firmware detects 362 + * a noisy signal) is sometimes applied. As some devices' (e.g, Lenovo 363 + * V15 G4) ACPI tables specify a 400KHz frequency for this device and 364 + * some I2C busses (e.g, Designware I2C) default to a 400KHz freq, 365 + * force the speed to 100KHz as a workaround. 366 + * 367 + * For future investigation: This problem may be related to the default 368 + * HCNT/LCNT values given by some busses' drivers, because they are not 369 + * specified in the aforementioned devices' ACPI tables, and because 370 + * the device works without issues on Windows at what is expected to be 371 + * a 400KHz frequency. The root cause of the issue is not known. 372 + */ 373 + { "ELAN06FA", 0 }, 374 + {} 375 + }; 376 + 358 377 static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, 359 378 void *data, void **return_value) 360 379 { ··· 391 372 392 373 if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0) 393 374 lookup->force_speed = I2C_MAX_FAST_MODE_FREQ; 375 + 376 + if (acpi_match_device_ids(adev, i2c_acpi_force_100khz_device_ids) == 0) 377 + lookup->force_speed = I2C_MAX_STANDARD_MODE_FREQ; 394 378 395 379 return AE_OK; 396 380 }