diff mbox series

Force ELAN06FA touchpad I2C bus freq to 100KHz

Message ID 20250111155744.2874-1-rha051117@gmail.com
State New
Headers show
Series Force ELAN06FA touchpad I2C bus freq to 100KHz | expand

Commit Message

R Ha Jan. 11, 2025, 3:57 p.m. UTC
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 do not specify a 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.

This problem may be related to the default HCNT/LCNT values given by
some busses' drivers, because they are also not specified in the
aforementioned devices' ACPI tables, and because the device works at
what appears to be a 400KHz frequency in Windows without issues.

Signed-off-by: Randolph Ha <rha051117@gmail.com>
---
 drivers/i2c/i2c-core-acpi.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

Comments

Mika Westerberg Jan. 13, 2025, 6:48 a.m. UTC | #1
Hi,

On Sat, Jan 11, 2025 at 09:57:10AM -0600, Randolph Ha wrote:
> 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 do not specify a 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.

Actually the ACPI tables provide the speed:

	I2cSerialBusV2 (0x002C, ControllerInitiated, 0x00061A80,
	    AddressingMode7Bit, "\\_SB.PC00.I2C1",
	    0x00, ResourceConsumer, _Y53, Exclusive,
	    )

It's that 0x00061A80 == 400kHz. Linux uses that and I would expect Windows
to do the same.

However, since the behavior is different between the OSses we are missing
something in Linux side. And because we cannot figure out what that is the
current workaround is to quirk the speed down to 100kHz which seems to cure
the problem.

> This problem may be related to the default HCNT/LCNT values given by
> some busses' drivers, because they are also not specified in the
> aforementioned devices' ACPI tables, and because the device works at
> what appears to be a 400KHz frequency in Windows without issues.
> 
> Signed-off-by: Randolph Ha <rha051117@gmail.com>

This is fine by me if we cannot figure out a better way but please correct
the commit message and the comment below to match the fact that the speed
is specified and that we don't know the root cause.

Once done, freel free to add my,

Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>

> ---
>  drivers/i2c/i2c-core-acpi.c | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> index 14ae0cfc325e..6f1c2377db0a 100644
> --- a/drivers/i2c/i2c-core-acpi.c
> +++ b/drivers/i2c/i2c-core-acpi.c
> @@ -355,6 +355,24 @@ static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
>  	{}
>  };
>  
> +static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = {
> +	/*
> +	 * 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 do not specify a 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.
> +	 *
> +	 * This problem may be related to the default HCNT/LCNT values given by
> +	 * some busses' drivers, because they are also not specified in the
> +	 * aforementioned devices' ACPI tables, and because the device works at
> +	 * what appears to be a 400KHz frequency in Windows without issues.
> +	 */
> +	{ "ELAN06FA", 0 },
> +	{}
> +};
> +
>  static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
>  					   void *data, void **return_value)
>  {
> @@ -373,6 +391,9 @@ static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
>  	if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0)
>  		lookup->force_speed = I2C_MAX_FAST_MODE_FREQ;
>  
> +	if (acpi_match_device_ids(adev, i2c_acpi_force_100khz_device_ids) == 0)
> +		lookup->force_speed = I2C_MAX_STANDARD_MODE_FREQ;
> +
>  	return AE_OK;
>  }
>  
> -- 
> 2.47.1
R Ha Jan. 15, 2025, 7:39 p.m. UTC | #2
Hello, and thanks for letting me know.

I'll keep your suggestions in mind the next time I have something to
post. Thanks to everyone for helping debug and get my patch into the
kernel, now I can use my laptop more easily! :)

On Tue, Jan 14, 2025 at 6:58 AM Wolfram Sang
<wsa+renesas@sang-engineering.com> wrote:
>
> On Mon, Jan 13, 2025 at 02:52:37PM -0500, Randolph Ha wrote:
> > 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>
>
> Applied to for-next, thanks!
>
> Some comments for next contributions. Please send new patches always in
> a new thread. It was a bit confusing here to find the latest one.
>
> Also, while the code change looks easy, this is not a trivial change, so
> trivial@ is not appropriate here. Trivial patches are more like typos or
> whitespace fixes.
>
> Nonetheless, thanks again for your efforts in timely debugging this!
>
diff mbox series

Patch

diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index 14ae0cfc325e..6f1c2377db0a 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -355,6 +355,24 @@  static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
 	{}
 };
 
+static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = {
+	/*
+	 * 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 do not specify a 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.
+	 *
+	 * This problem may be related to the default HCNT/LCNT values given by
+	 * some busses' drivers, because they are also not specified in the
+	 * aforementioned devices' ACPI tables, and because the device works at
+	 * what appears to be a 400KHz frequency in Windows without issues.
+	 */
+	{ "ELAN06FA", 0 },
+	{}
+};
+
 static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
 					   void *data, void **return_value)
 {
@@ -373,6 +391,9 @@  static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
 	if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0)
 		lookup->force_speed = I2C_MAX_FAST_MODE_FREQ;
 
+	if (acpi_match_device_ids(adev, i2c_acpi_force_100khz_device_ids) == 0)
+		lookup->force_speed = I2C_MAX_STANDARD_MODE_FREQ;
+
 	return AE_OK;
 }