Skip to content

Commit 7574c0d

Browse files
jwrdegoedeWolfram Sang
authored andcommitted
i2c: acpi: Force bus speed to 400KHz if a Silead touchscreen is present
Many cheap devices use Silead touchscreen controllers. Testing has shown repeatedly that these touchscreen controllers work fine at 400KHz, but for unknown reasons do not work properly at 100KHz. This has been seen on both ARM and x86 devices using totally different i2c controllers. On some devices the ACPI tables list another device at the same I2C-bus as only being capable of 100KHz, testing has shown that these other devices work fine at 400KHz (as can be expected of any recent I2C hw). This commit makes i2c_acpi_find_bus_speed() always return 400KHz if a Silead touchscreen controller is present, fixing the touchscreen not working on devices which ACPI tables' wrongly list another device on the same bus as only being capable of 100KHz. Specifically this fixes the touchscreen on the Jumper EZpad 6 m4 not working. Reported-by: youling 257 <[email protected]> Tested-by: youling 257 <[email protected]> Signed-off-by: Hans de Goede <[email protected]> Reviewed-by: Jarkko Nikula <[email protected]> Acked-by: Mika Westerberg <[email protected]> [wsa: rewording warning a little] Signed-off-by: Wolfram Sang <[email protected]> Cc: [email protected]
1 parent 31f4f5b commit 7574c0d

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

drivers/i2c/i2c-core-acpi.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct i2c_acpi_lookup {
3939
int index;
4040
u32 speed;
4141
u32 min_speed;
42+
u32 force_speed;
4243
};
4344

4445
/**
@@ -285,6 +286,19 @@ i2c_acpi_match_device(const struct acpi_device_id *matches,
285286
return acpi_match_device(matches, &client->dev);
286287
}
287288

289+
static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
290+
/*
291+
* These Silead touchscreen controllers only work at 400KHz, for
292+
* some reason they do not work at 100KHz. On some devices the ACPI
293+
* tables list another device at their bus as only being capable
294+
* of 100KHz, testing has shown that these other devices work fine
295+
* at 400KHz (as can be expected of any recent i2c hw) so we force
296+
* the speed of the bus to 400 KHz if a Silead device is present.
297+
*/
298+
{ "MSSL1680", 0 },
299+
{}
300+
};
301+
288302
static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
289303
void *data, void **return_value)
290304
{
@@ -303,6 +317,9 @@ static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
303317
if (lookup->speed <= lookup->min_speed)
304318
lookup->min_speed = lookup->speed;
305319

320+
if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0)
321+
lookup->force_speed = 400000;
322+
306323
return AE_OK;
307324
}
308325

@@ -340,7 +357,16 @@ u32 i2c_acpi_find_bus_speed(struct device *dev)
340357
return 0;
341358
}
342359

343-
return lookup.min_speed != UINT_MAX ? lookup.min_speed : 0;
360+
if (lookup.force_speed) {
361+
if (lookup.force_speed != lookup.min_speed)
362+
dev_warn(dev, FW_BUG "DSDT uses known not-working I2C bus speed %d, forcing it to %d\n",
363+
lookup.min_speed, lookup.force_speed);
364+
return lookup.force_speed;
365+
} else if (lookup.min_speed != UINT_MAX) {
366+
return lookup.min_speed;
367+
} else {
368+
return 0;
369+
}
344370
}
345371
EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed);
346372

0 commit comments

Comments
 (0)