diff mbox series

[2/2] HID: i2c-hid: Add a quirk to keep the power in shutdown

Message ID 20201204152912.151604-2-hui.wang@canonical.com (mailing list archive)
State New
Delegated to: Jiri Kosina
Headers show
Series [1/2] HID: i2c-hid: expand the quirk lookup table to support dmi_table | expand

Commit Message

Hui Wang Dec. 4, 2020, 3:29 p.m. UTC
On the latest Thinkpad Yoga laptop, the touchscreen module is wacom
I2C WACF2200 (056a:5276), we found the touchscreen could not work
after rebooting, needs to poweroff the machine then poweron the
machine to let it work.

It is highly possible that this is a BIOS issue, but the windows
doesn't have this problem with the same BIOS.

If keeping the power on when calling shutdown, the touchscreen could
work after rebooting. Let us add a quirk for it and apply the quirk
to this machine only.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
---
 drivers/hid/hid-ids.h              |  1 +
 drivers/hid/i2c-hid/i2c-hid-core.c | 20 ++++++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

Comments

Jiri Kosina Jan. 7, 2021, 9:12 a.m. UTC | #1
On Fri, 4 Dec 2020, Hui Wang wrote:

> On the latest Thinkpad Yoga laptop, the touchscreen module is wacom
> I2C WACF2200 (056a:5276), we found the touchscreen could not work
> after rebooting, needs to poweroff the machine then poweron the
> machine to let it work.
> 
> It is highly possible that this is a BIOS issue, but the windows
> doesn't have this problem with the same BIOS.
> 
> If keeping the power on when calling shutdown, the touchscreen could
> work after rebooting. Let us add a quirk for it and apply the quirk
> to this machine only.

I wonder what do Windows do differently here. Perhaps they never put the 
i2c device to sleep while in shutdown anyway? Is there any downside to 
(not) doing the same?

Thanks,
Hui Wang Jan. 7, 2021, 11:46 a.m. UTC | #2
On 1/7/21 5:12 PM, Jiri Kosina wrote:
> On Fri, 4 Dec 2020, Hui Wang wrote:
>
>> On the latest Thinkpad Yoga laptop, the touchscreen module is wacom
>> I2C WACF2200 (056a:5276), we found the touchscreen could not work
>> after rebooting, needs to poweroff the machine then poweron the
>> machine to let it work.
>>
>> It is highly possible that this is a BIOS issue, but the windows
>> doesn't have this problem with the same BIOS.
>>
>> If keeping the power on when calling shutdown, the touchscreen could
>> work after rebooting. Let us add a quirk for it and apply the quirk
>> to this machine only.
> I wonder what do Windows do differently here. Perhaps they never put the
> i2c device to sleep while in shutdown anyway? Is there any downside to
> (not) doing the same?

It is highly possible the Windows doesn't sleep the i2c device in 
shutdown. When calling shutdown, it usually means reboot or poweroff the 
machine, so the sleep is meaningless in this situation. In other 
situations like users manually unload the i2c driver, maybe it will add 
a bit power consumption without sleeping the device.

Anyway, I will try to ask for help from vendor, maybe they could provide 
how Windows do when shutdown.

Thanks.

> Thanks,
>
Jiri Kosina Jan. 8, 2021, 3:01 p.m. UTC | #3
On Thu, 7 Jan 2021, Hui Wang wrote:

> >> On the latest Thinkpad Yoga laptop, the touchscreen module is wacom
> >> I2C WACF2200 (056a:5276), we found the touchscreen could not work
> >> after rebooting, needs to poweroff the machine then poweron the
> >> machine to let it work.
> >>
> >> It is highly possible that this is a BIOS issue, but the windows
> >> doesn't have this problem with the same BIOS.
> >>
> >> If keeping the power on when calling shutdown, the touchscreen could
> >> work after rebooting. Let us add a quirk for it and apply the quirk
> >> to this machine only.
> > I wonder what do Windows do differently here. Perhaps they never put the
> > i2c device to sleep while in shutdown anyway? Is there any downside to
> > (not) doing the same?
> 
> It is highly possible the Windows doesn't sleep the i2c device in shutdown.
> When calling shutdown, it usually means reboot or poweroff the machine, so the
> sleep is meaningless in this situation. In other situations like users
> manually unload the i2c driver, maybe it will add a bit power consumption
> without sleeping the device.

Agreed, but if windows really don't put the device to sleep before 
shutting down, odds are there will be more devices behaving the same, and 
therefore we'd rather make it the default case instead of growing just 
another quirk list.

> Anyway, I will try to ask for help from vendor, maybe they could provide 
> how Windows do when shutdown.

Thank you,
Hui Wang Jan. 26, 2021, 8:57 a.m. UTC | #4
On 1/8/21 11:01 PM, Jiri Kosina wrote:
> On Thu, 7 Jan 2021, Hui Wang wrote:
>
>>>> On the latest Thinkpad Yoga laptop, the touchscreen module is wacom
>>>> I2C WACF2200 (056a:5276), we found the touchscreen could not work
>>>> after rebooting, needs to poweroff the machine then poweron the
>>>> machine to let it work.
>>>>
>>>> It is highly possible that this is a BIOS issue, but the windows
>>>> doesn't have this problem with the same BIOS.
>>>>
>>>> If keeping the power on when calling shutdown, the touchscreen could
>>>> work after rebooting. Let us add a quirk for it and apply the quirk
>>>> to this machine only.
>>> I wonder what do Windows do differently here. Perhaps they never put the
>>> i2c device to sleep while in shutdown anyway? Is there any downside to
>>> (not) doing the same?
>> It is highly possible the Windows doesn't sleep the i2c device in shutdown.
>> When calling shutdown, it usually means reboot or poweroff the machine, so the
>> sleep is meaningless in this situation. In other situations like users
>> manually unload the i2c driver, maybe it will add a bit power consumption
>> without sleeping the device.
> Agreed, but if windows really don't put the device to sleep before
> shutting down, odds are there will be more devices behaving the same, and
> therefore we'd rather make it the default case instead of growing just
> another quirk list.

Got the feedback from the ODM, the root cause of this issue is the I2C 
device will send clock stretching when changing from PWR_SLEEP to 
PWR_ON, but the driver in the BIOS doesn't handle the clock stretching 
or the timeout is not enough. ODM already provided a testing BIOS and 
this issue is fixed by the testing BIOS.

And ODM captured the I2C data transfer log under Windows, according to 
the log, the Windows also set the I2C touchscreen to PWR_SLEEP before 
rebooting, it is same as the current Linux hid i2c driver.

Regards,

Hui.

>> Anyway, I will try to ask for help from vendor, maybe they could provide
>> how Windows do when shutdown.
> Thank you,
>
diff mbox series

Patch

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index f170feaac40b..ecc1d4040b6f 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1223,6 +1223,7 @@ 
 #define USB_VENDOR_ID_WACOM		0x056a
 #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH	0x81
 #define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH   0x00BD
+#define USB_DEVICE_ID_WACOM_5276		0x5276
 
 #define USB_VENDOR_ID_WALTOP				0x172f
 #define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH	0x0032
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 953877cf1051..7c6d5b8175fd 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -51,7 +51,7 @@ 
 #define I2C_HID_QUIRK_BOGUS_IRQ			BIT(4)
 #define I2C_HID_QUIRK_RESET_ON_RESUME		BIT(5)
 #define I2C_HID_QUIRK_BAD_INPUT_SIZE		BIT(6)
-
+#define I2C_HID_QUIRK_KEEP_PWR_ON_SHUTDOWN	BIT(7)
 
 /* flags */
 #define I2C_HID_STARTED		0
@@ -183,6 +183,20 @@  static const struct i2c_hid_quirks {
 		 I2C_HID_QUIRK_RESET_ON_RESUME },
 	{ USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720,
 		I2C_HID_QUIRK_BAD_INPUT_SIZE },
+	{
+		.idVendor = USB_VENDOR_ID_WACOM,
+		.idProduct = USB_DEVICE_ID_WACOM_5276,
+		.quirks = I2C_HID_QUIRK_KEEP_PWR_ON_SHUTDOWN,
+		.dmi_table = (const struct dmi_system_id []) {
+			{
+				.matches = {
+					DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "LENOVO_MT_20XY_BU_Think_FM_ThinkPad X1 Yoga Gen 6"),
+				}
+			},
+			{}
+		}
+	},
 	{ 0, 0 }
 };
 
@@ -1182,7 +1196,9 @@  static void i2c_hid_shutdown(struct i2c_client *client)
 {
 	struct i2c_hid *ihid = i2c_get_clientdata(client);
 
-	i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+	if (!(ihid->quirks & I2C_HID_QUIRK_KEEP_PWR_ON_SHUTDOWN))
+		i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+
 	free_irq(client->irq, ihid);
 
 	i2c_hid_acpi_shutdown(&client->dev);