Bug 204991

Summary: Goodix touchpad needs a 60ms delay after i2c-hid SET_POWER ON command when resuming from s2idle
Product: Drivers Reporter: You-Sheng Yang (vicamo)
Component: I2CAssignee: Drivers/I2C virtual user (drivers-i2c)
Status: RESOLVED CODE_FIX    
Severity: normal CC: kai.heng.feng
Priority: P1    
Hardware: All   
OS: Linux   
URL: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1842532
Kernel Version: 5.3.1 Tree: Mainline
Regression: No
Attachments: dmesg, v5.3.1, i2c-hid.debug=1 hid.debug=1

Description You-Sheng Yang 2019-09-25 04:51:35 UTC
Created attachment 285163 [details]
dmesg, v5.3.1, i2c-hid.debug=1 hid.debug=1

I2C traffic after resume:

[ 275.148083] i2c_hid i2c-CUST0000:00: i2c_hid_set_power
[ 275.148084] i2c_hid i2c-CUST0000:00: __i2c_hid_command: cmd=05 00 01 08
[ 275.312190] i2c_hid i2c-DELL096E:00: i2c_hid_set_power
[ 275.312191] i2c_hid i2c-DELL096E:00: __i2c_hid_command: cmd=05 00 01 08
[ 283.926905] i2c_hid i2c-DELL096E:00: i2c_hid_set_power
[ 283.926910] i2c_hid i2c-DELL096E:00: __i2c_hid_command: cmd=05 00 00 08
[ 283.927146] i2c_hid i2c-DELL096E:00: i2c_hid_set_or_send_report
[ 283.927149] i2c_hid i2c-DELL096E:00: __i2c_hid_command: cmd=05 00 37 03 06 00 05 00 07 00 00
[ 283.927872] i2c_hid i2c-DELL096E:00: i2c_hid_set_or_send_report
[ 283.927874] i2c_hid i2c-DELL096E:00: __i2c_hid_command: cmd=05 00 33 03 06 00 05 00 03 03 00
[ 283.929148] i2c_hid i2c-DELL096E:00: i2c_hid_set_or_send_report
[ 283.929151] i2c_hid i2c-DELL096E:00: __i2c_hid_command: cmd=05 00 35 03 06 00 05 00 05 03 00
[ 284.077891] i2c_hid i2c-CUST0000:00: i2c_hid_set_power
[ 284.077892] i2c_hid i2c-CUST0000:00: __i2c_hid_command: cmd=05 00 00 08

# when touching touchpad:
[ 289.262675] i2c_hid i2c-DELL096E:00: input: 0b 00 01 00 00 00 00 00 00 00 00
[ 289.270314] i2c_hid i2c-DELL096E:00: input: 0b 00 01 00 fe 00 00 00 00 00 00
[ 289.276806] i2c_hid i2c-DELL096E:00: input: 0b 00 01 00 fd 00 00 00 00 00 00
[ 289.283863] i2c_hid i2c-DELL096E:00: input: 0b 00 01 00 fb 01 00 00 00 00 00
[ 289.291213] i2c_hid i2c-DELL096E:00: input: 0b 00 01 00 fa 02 00 00 00 00 00
[ 289.297932] i2c_hid i2c-DELL096E:00: input: 0b 00 01 00 f9 03 00 00 00 00 00
[ 289.304775] i2c_hid i2c-DELL096E:00: input: 0b 00 01 00 f9 03 00 00 00 00 00

On this device, both Precision Touchpad mode and a legacy Mouse mode are supported. When I2C SET_POWER ON is issued, it would take as long as 60ms to complete state transition and is then able to receive and execute further commands. On boot the device is running under Mouse mode for legacy platform support, and will be put to PTP mode with a SET_OR_SEND_REPORT command. If somehow the time gap between the first SET_POWER ON and further SET_OR_SEND_REPORT commands is less than 60ms, the device will still operating under Mouse mode and gives reports like "0b 00 01 00 fe 00 00 00 00 00 00".

On Linux system boot, it may take 500ms from i2c probe (SET_POWER ON) to hid initialization (SET_OR_SEND_REPORT), so it will always be put to PTP mode successfully. But when the device is put under suspend and resumed, the hid reset resume process will be right after i2c resume, so the device won't have enough time to complete its state transition, which fails following SET_OR_SEND_REPORT executing and therefore it operates under Mouse mode instead.

Currently Linux has a at most 5ms sleep in i2c_hid_hwreset(), but according to HID over I2C Specification[1] section 7.2.8 "SET_POWER":

> The DEVICE must ensure that it transitions to the HOST
> specified Power State in under 1 second.

it can take as long as 1 second.
Comment 2 You-Sheng Yang 2019-09-25 15:51:46 UTC
Proposed changeset: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2112500.html
Comment 3 You-Sheng Yang 2020-05-26 02:45:23 UTC
This was obsoleted by following commits that disable runtime pm for i2c-hid:

  1. [HID: i2c-hid: Remove runtime power management](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=67b18dfb8cfc6d6c2f45ba8c546088f5c14f5bd5)
  2. [HID: i2c-hid: Send power-on command after reset](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43b7029f475e7497da1de1f4a1742241812bf266)

Nothing else to do.