aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2023-11-06 10:00:32 +0000
committerMarc Zyngier <maz@kernel.org>2023-11-06 10:01:13 +0000
commit1039ad6b8abc5771fc6d104713bf40e495d43118 (patch)
tree361f0cd1f6edcacd89a053ace80ca295847cf1e1
parentd3d964d7690cb0c49af6ff911b6651b48440170f (diff)
downloadcs-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.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/vdmtool.c b/vdmtool.c
index 91411e0..209c0f7 100644
--- a/vdmtool.c
+++ b/vdmtool.c
@@ -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);
}