From 00768a757b560a469dd8e25962426318433bed8d Mon Sep 17 00:00:00 2001 From: Rolando Trevino Date: Fri, 6 Nov 2026 18:48:03 -0500 Subject: [PATCH] HID: dockchannel-hid: settle 50 ms after releasing the AFE reset Power method 2 with a host-driven AFE reset releases the line for a power-on and sends HasChanged immediately. The sequence validated on the J716s (MacBook Pro 16-inch, M5 Pro, MTP firmware 6320.86.1; "Touch MT ready" on 3 of 3 boots, with the reset on SMC gp1c, active low) waits 50 ms after the release before HasChanged, as this driver already does for a firmware-managed reset. Do the same for the host-driven line. Log a failure to drive the line as an error. Each assert and release is logged at debug level only, so dynamic debug can trace the line without adding a message to the boot log on every power transition. Signed-off-by: Rolando Trevino Assisted-by: LLM Claude --- drivers/hid/dockchannel-hid/dockchannel-hid.c | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/hid/dockchannel-hid/dockchannel-hid.c b/drivers/hid/dockchannel-hid/dockchannel-hid.c index da0f2ab1403d9..737963b424964 100644 --- a/drivers/hid/dockchannel-hid/dockchannel-hid.c +++ b/drivers/hid/dockchannel-hid/dockchannel-hid.c @@ -535,7 +535,8 @@ static int dchid_register_ring(struct dockchannel_hid *dchid) /* * Power method 2: announce the transition, drive the AFE reset line to the * new state and confirm the transition. The reset is asserted for a power-off - * and held for 50 ms, and released for a power-on. + * and held for 50 ms, and released for a power-on and given 50 ms to settle + * before the transition is confirmed. */ static int dchid_pm2_set_power(struct dchid_iface *iface, u8 state) { @@ -553,12 +554,23 @@ static int dchid_pm2_set_power(struct dchid_iface *iface, u8 state) if (state == DCHID_POWER_STATE_ON) fsleep(50 * USEC_PER_MSEC); } else { - ret = gpiod_set_value_cansleep(dchid->afe_reset, - state == DCHID_POWER_STATE_OFF); - if (ret < 0) + bool off = state == DCHID_POWER_STATE_OFF; + + ret = gpiod_set_value_cansleep(dchid->afe_reset, off); + if (ret < 0) { + dev_err(dchid->dev, "%s: failed to %s the AFE reset: %d\n", + iface->name, off ? "assert" : "release", ret); return ret; - if (state == DCHID_POWER_STATE_OFF) - fsleep(50 * USEC_PER_MSEC); + } + dev_dbg(dchid->dev, "%s: AFE reset %s\n", iface->name, + off ? "asserted" : "released"); + /* + * The sequence validated on J716s (M5 Pro, MTP firmware + * 6320.86.1, "Touch MT ready" on 3 of 3 boots) also waits + * 50 ms after the release before HasChanged, as the + * firmware-managed path above does. + */ + fsleep(50 * USEC_PER_MSEC); } dchid_pm2_command(iface->index, state, true, msg);