diff options
author | Marc Zyngier <maz@kernel.org> | 2023-11-06 10:00:32 +0000 |
---|---|---|
committer | Marc Zyngier <maz@kernel.org> | 2023-11-06 10:01:13 +0000 |
commit | 1039ad6b8abc5771fc6d104713bf40e495d43118 (patch) | |
tree | 361f0cd1f6edcacd89a053ace80ca295847cf1e1 | |
parent | d3d964d7690cb0c49af6ff911b6651b48440170f (diff) | |
download | cs-sw-1039ad6b8abc5771fc6d104713bf40e495d43118.tar.gz |
Reinstate "Don't measure CC lines twice"
After having dropped the "single CC measurement" patch, I managed
to investigate things a bit: it looks like doing a measurement
right on the back of an interrupt is what causes my issues with
the M1 mini. Instead, inserting a 100ms delay *before* performing
the measurement makes it reliable (50ms was enough, but I'm being
extra cautious).
I couldn't find anythning in the documentation that hints as this
behaviour, so it isn't unlikely that something is happening on the
opposite end of the cable.
The other unknown is the M1 mini itself. Why is this machine so
different, I have no idea. M2 MBA and M2 Pro do not have this
problem. But this particular Mini is running a positively
ancient version of the firmware (everything is still on 11.0,
something I doubt anyone else is doing). Should I upgrade?
On the bright side, I've been able to drop the delays before
hitting VCONN, irrespective of the FUSB versions, so we're
in an even better place than before!
Signed-off-by: Marc Zyngier <maz@kernel.org>
-rw-r--r-- | vdmtool.c | 25 |
1 files changed, 12 insertions, 13 deletions
@@ -87,18 +87,9 @@ void debug_poke(struct vdm_context *cxt) fusb302_tcpm_transmit(PORT(cxt), TCPC_TX_SOP_DEBUG_PRIME_PRIME, hdr, &x); } -static void evt_dfpconnect(struct vdm_context *cxt) +static void evt_dfpconnect(struct vdm_context *cxt, int16_t cc1, int16_t cc2) { - int16_t cc1 = -1, cc2 = -1; - fusb302_tcpm_get_cc(PORT(cxt), &cc1, &cc2); - cprintf(cxt, "Connected: cc1=%d cc2=%d\n", cc1, cc2); - if (cc1 < 2 && cc2 < 2) { - cprintf(cxt, "Nope.\n"); - return; - } - fusb302_tcpm_set_vconn(PORT(cxt), 0); - fusb302_pd_reset(PORT(cxt)); fusb302_tcpm_set_msg_header(PORT(cxt), 1, 1); // Source cxt->cc_line = !(cc1 > cc2); @@ -123,8 +114,8 @@ static void evt_disconnect(struct vdm_context *cxt) { vbus_off(cxt); cprintf(cxt, "Disconnected\n"); - fusb302_pd_reset(PORT(cxt)); fusb302_tcpm_set_vconn(PORT(cxt), 0); + fusb302_pd_reset(PORT(cxt)); fusb302_tcpm_set_rx_enable(PORT(cxt), 0); fusb302_tcpm_select_rp_value(PORT(cxt), TYPEC_RP_USB); fusb302_tcpm_set_cc(PORT(cxt), TYPEC_CC_RP); // DFP mode @@ -575,11 +566,19 @@ static void state_machine(struct vdm_context *cxt) switch (cxt->state) { case STATE_DISCONNECTED:{ int16_t cc1 = -1, cc2 = -1; + + /* + * Immediately performing the CC measurement after an + * interrupt returns wrong results on my M1 mini. + * Waiting 100ms here makes it work... Don't you love + * computers? + */ + sleep_ms(100); + fusb302_tcpm_get_cc(PORT(cxt), &cc1, &cc2); dprintf(cxt, "Poll: cc1=%d cc2=%d\n", (int)cc1, (int)cc2); if (cc1 >= 2 || cc2 >= 2) { - sleep_ms(500); - evt_dfpconnect(cxt); + evt_dfpconnect(cxt, cc1, cc2); } else { vbus_off(cxt); } |