summaryrefslogtreecommitdiff
path: root/common/usbc/usb_tc_ctvpd_sm.c
diff options
context:
space:
mode:
authorJett Rink <jettrink@chromium.org>2019-08-02 16:20:50 -0600
committerCommit Bot <commit-bot@chromium.org>2019-08-20 15:53:16 +0000
commit2a7996a3caf25d358164a48e80723758e8be1fd1 (patch)
treea6dd0682b7ab1c3cc408450137e5f10988cf9da7 /common/usbc/usb_tc_ctvpd_sm.c
parenta1aea89ae15c85d56f52976289a329e7c58bc8f6 (diff)
downloadchrome-ec-2a7996a3caf25d358164a48e80723758e8be1fd1.tar.gz
usb: update state machine framework
- OBJ is renamed to context (CTX) for current and last state - State definition now includes its parent (no need for the boiler plate function that takes in a signal) - The init_state, set_state, and exe_state have been re-written to take advantages of new state machine definition. I had to add more logic to handle hierarchical states fully. - Explicitly create the USB states at the bottom of the file with all of the statics. Don't need to use macros (even though I did suggest them) - Use NULL when we do_nothing instead of calling into a function - Created a "private" enum in the C file that lists all of the states in the file, that we can use to refer to a state (it is also the index into the states array for that state). - Changed prototype of state function to return void, since we aren't really using the return value and it cleans up a lot of return 0 that aren't needed. - Add const to int port since we can and should - Moves struct definition to implementation file only to keep implementation details private. We can access data through accessor if needed. BRANCH=none BUG=none TEST=all unit tests passes Change-Id: I482a63e08f7d63022d5102b891a2fac0b0faa46f Signed-off-by: Jett Rink <jettrink@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1733744 Commit-Queue: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'common/usbc/usb_tc_ctvpd_sm.c')
-rw-r--r--common/usbc/usb_tc_ctvpd_sm.c1080
1 files changed, 557 insertions, 523 deletions
diff --git a/common/usbc/usb_tc_ctvpd_sm.c b/common/usbc/usb_tc_ctvpd_sm.c
index 447db85be5..f837b27dbc 100644
--- a/common/usbc/usb_tc_ctvpd_sm.c
+++ b/common/usbc/usb_tc_ctvpd_sm.c
@@ -9,7 +9,6 @@
#include "task.h"
#include "tcpm.h"
#include "usb_pd.h"
-#include "usb_tc_ctvpd_sm.h"
#include "usb_tc_sm.h"
#include "vpd_api.h"
@@ -24,7 +23,7 @@
#endif
/* Type-C Layer Flags */
-#define TC_FLAGS_VCONN_ON (1 << 0)
+#define TC_FLAGS_VCONN_ON BIT(0)
#define SUPPORT_TIMER_RESET_INIT 0
#define SUPPORT_TIMER_RESET_REQUEST 1
@@ -34,56 +33,164 @@
* This is the Type-C Port object that contains information needed to
* implement a Charge Through VCONN Powered Device.
*/
-struct type_c tc[CONFIG_USB_PD_PORT_COUNT];
-
-/* Type-C states */
-DECLARE_STATE(tc, disabled, WITH_RUN, WITH_EXIT);
-DECLARE_STATE(tc, error_recovery, WITH_RUN, NOOP);
-DECLARE_STATE(tc, unattached_snk, WITH_RUN, NOOP);
-DECLARE_STATE(tc, attach_wait_snk, WITH_RUN, NOOP);
-DECLARE_STATE(tc, attached_snk, WITH_RUN, WITH_EXIT);
-DECLARE_STATE(tc, try_snk, WITH_RUN, NOOP);
-DECLARE_STATE(tc, unattached_src, WITH_RUN, NOOP);
-DECLARE_STATE(tc, attach_wait_src, WITH_RUN, NOOP);
-DECLARE_STATE(tc, try_wait_src, WITH_RUN, NOOP);
-DECLARE_STATE(tc, attached_src, WITH_RUN, NOOP);
-DECLARE_STATE(tc, ct_try_snk, WITH_RUN, WITH_EXIT);
-DECLARE_STATE(tc, ct_attach_wait_unsupported, WITH_RUN, WITH_EXIT);
-DECLARE_STATE(tc, ct_attached_unsupported, WITH_RUN, WITH_EXIT);
-DECLARE_STATE(tc, ct_unattached_unsupported, WITH_RUN, WITH_EXIT);
-DECLARE_STATE(tc, ct_unattached_vpd, WITH_RUN, WITH_EXIT);
-DECLARE_STATE(tc, ct_disabled_vpd, WITH_RUN, NOOP);
-DECLARE_STATE(tc, ct_attached_vpd, WITH_RUN, NOOP);
-DECLARE_STATE(tc, ct_attach_wait_vpd, WITH_RUN, WITH_EXIT);
-
-/* Super States */
-DECLARE_STATE(tc, host_rard_ct_rd, NOOP, NOOP);
-DECLARE_STATE(tc, host_open_ct_open, NOOP, NOOP);
-DECLARE_STATE(tc, vbus_cc_iso, NOOP, NOOP);
-DECLARE_STATE(tc, host_rp3_ct_rd, NOOP, NOOP);
-DECLARE_STATE(tc, host_rp3_ct_rpu, NOOP, NOOP);
-DECLARE_STATE(tc, host_rpu_ct_rd, NOOP, NOOP);
+static struct type_c {
+ /* state machine context */
+ struct sm_ctx ctx;
+ /* current port power role (VPD, SOURCE or SINK) */
+ uint8_t power_role;
+ /* current port data role (DFP or UFP) */
+ uint8_t data_role;
+ /* Higher-level power deliver state machines are enabled if true. */
+ uint8_t pd_enable;
+ /* event timeout */
+ uint64_t evt_timeout;
+ /* port flags, see TC_FLAGS_* */
+ uint32_t flags;
+ /*
+ * Time a charge-through port shall wait before it can determine it
+ * is attached
+ */
+ uint64_t cc_debounce;
+ /* Time a host port shall wait before it can determine it is attached */
+ uint64_t host_cc_debounce;
+ /* Time a Sink port shall wait before it can determine it is detached
+ * due to the potential for USB PD signaling on CC as described in
+ * the state definitions.
+ */
+ uint64_t pd_debounce;
+ /* Maintains state of billboard device */
+ int billboard_presented;
+ /*
+ * Time a port shall wait before it can determine it is
+ * re-attached during the try-wait process.
+ */
+ uint64_t try_wait_debounce;
+ /* charge-through support timer */
+ uint64_t support_timer;
+ /* reset the charge-through support timer */
+ uint8_t support_timer_reset;
+ /* VPD host port cc state */
+ enum pd_cc_states host_cc_state;
+ uint8_t ct_cc;
+ /* The cc state */
+ enum pd_cc_states cc_state;
+ uint64_t next_role_swap;
+} tc[CONFIG_USB_PD_PORT_COUNT];
+
+/* List of all TypeC-level states */
+enum usb_tc_state {
+ /* Normal States */
+ TC_DISABLED,
+ TC_UNATTACHED_SNK,
+ TC_ATTACH_WAIT_SNK,
+ TC_ATTACHED_SNK,
+ TC_ERROR_RECOVERY,
+ TC_TRY_SNK,
+ TC_UNATTACHED_SRC,
+ TC_ATTACH_WAIT_SRC,
+ TC_TRY_WAIT_SRC,
+ TC_ATTACHED_SRC,
+ TC_CT_TRY_SNK,
+ TC_CT_ATTACH_WAIT_UNSUPPORTED,
+ TC_CT_ATTACHED_UNSUPPORTED,
+ TC_CT_UNATTACHED_UNSUPPORTED,
+ TC_CT_UNATTACHED_VPD,
+ TC_CT_DISABLED_VPD,
+ TC_CT_ATTACHED_VPD,
+ TC_CT_ATTACH_WAIT_VPD,
+ /* Super States */
+ TC_VBUS_CC_ISO,
+ TC_HOST_RARD_CT_RD,
+ TC_HOST_OPEN_CT_OPEN,
+ TC_HOST_RP3_CT_RD,
+ TC_HOST_RP3_CT_RPU,
+ TC_HOST_RPU_CT_RD,
+};
+
+/* Forward declare the full list of states. This is indexed by usb_tc_state */
+static const struct usb_state tc_states[];
+
+
+#ifdef CONFIG_COMMON_RUNTIME
+/* List of human readable state names for console debugging */
+const char * const tc_state_names[] = {
+ [TC_DISABLED] = "Disabled",
+ [TC_UNATTACHED_SNK] = "Unattached.SNK",
+ [TC_ATTACH_WAIT_SNK] = "AttachWait.SNK",
+ [TC_ATTACHED_SNK] = "Attached.SNK",
+ [TC_ERROR_RECOVERY] = "ErrorRecovery",
+ [TC_TRY_SNK] = "Try.SNK",
+ [TC_UNATTACHED_SRC] = "Unattached.SRC",
+ [TC_ATTACH_WAIT_SRC] = "AttachWait.SRC",
+ [TC_TRY_WAIT_SRC] = "TryWait.SRC",
+ [TC_ATTACHED_SRC] = "Attached.SRC",
+ [TC_CT_TRY_SNK] = "CTTry.SNK",
+ [TC_CT_ATTACH_WAIT_UNSUPPORTED] = "CTAttachWait.Unsupported",
+ [TC_CT_ATTACHED_UNSUPPORTED] = "CTAttached.Unsupported",
+ [TC_CT_UNATTACHED_UNSUPPORTED] = "CTUnattached.Unsupported",
+ [TC_CT_UNATTACHED_VPD] = "CTUnattached.VPD",
+ [TC_CT_DISABLED_VPD] = "CTDisabled.VPD",
+ [TC_CT_ATTACHED_VPD] = "CTAttached.VPD",
+ [TC_CT_ATTACH_WAIT_VPD] = "CTAttachWait.VPD",
+};
+#endif
+
+/* Forward declare private, common functions */
+static void set_state_tc(const int port, enum usb_tc_state new_state);
+
+/* Public TypeC functions */
+
+int tc_get_power_role(int port)
+{
+ return tc[port].power_role;
+}
+
+int tc_get_data_role(int port)
+{
+ return tc[port].data_role;
+}
+
+uint8_t tc_get_polarity(int port)
+{
+ /* Does not track polarity */
+ return 0;
+}
+
+uint8_t tc_get_pd_enabled(int port)
+{
+ return tc[port].pd_enable;
+}
+
+void tc_set_power_role(int port, int role)
+{
+ tc[port].power_role = role;
+}
+
+uint64_t tc_get_timeout(int port)
+{
+ return tc[port].evt_timeout;
+}
+
+void tc_set_timeout(int port, uint64_t timeout)
+{
+ tc[port].evt_timeout = timeout;
+}
void tc_reset_support_timer(int port)
{
tc[port].support_timer_reset |= SUPPORT_TIMER_RESET_REQUEST;
}
-void tc_state_init(int port, enum typec_state_id start_state)
+void tc_state_init(int port)
{
int res = 0;
- sm_state this_state;
res = tc_restart_tcpc(port);
- if (res)
- this_state = tc_disabled;
- else
- this_state = (start_state == TC_UNATTACHED_SRC) ?
- tc_unattached_src : tc_unattached_snk;
CPRINTS("TCPC p%d init %s", port, res ? "failed" : "ready");
- sm_init_state(port, TC_OBJ(port), this_state);
+ /* Disable if restart failed, otherwise start in default state. */
+ set_state_tc(port, res ? TC_DISABLED : TC_UNATTACHED_SNK);
/* Disable pd state machines */
tc[port].pd_enable = 0;
@@ -99,6 +206,36 @@ void tc_event_check(int port, int evt)
/* Do Nothing */
}
+void tc_run(const int port)
+{
+ exe_state(port, &tc[port].ctx);
+}
+
+/* Internal Functions */
+
+/* Set the TypeC state machine to a new state. */
+static void set_state_tc(const int port, enum usb_tc_state new_state)
+{
+ set_state(port, &tc[port].ctx, &tc_states[new_state]);
+}
+
+/* Get the current TypeC state. */
+test_export_static enum usb_tc_state get_state_tc(const int port)
+{
+ return tc[port].ctx.current - &tc_states[0];
+}
+
+/* Get the previous TypeC state. */
+static enum usb_tc_state get_last_state_tc(const int port)
+{
+ return tc[port].ctx.previous - &tc_states[0];
+}
+
+static void print_current_state(const int port)
+{
+ CPRINTS("C%d: %s", port, tc_state_names[get_state_tc(port)]);
+}
+
/**
* Disabled
*
@@ -108,38 +245,26 @@ void tc_event_check(int port, int evt)
* Remove the terminations from Host
* Remove the terminations from Charge-Through
*/
-static int tc_disabled(int port, enum sm_signal sig)
+static void tc_disabled_entry(const int port)
{
- int ret = 0;
-
- ret = (*tc_disabled_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_open_ct_open);
+ print_current_state(port);
}
-static int tc_disabled_entry(int port)
-{
- tc[port].state_id = TC_DISABLED;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
- return 0;
-}
-
-static int tc_disabled_run(int port)
+static void tc_disabled_run(const int port)
{
task_wait_event(-1);
- return SM_RUN_SUPER;
}
-static int tc_disabled_exit(int port)
+static void tc_disabled_exit(const int port)
{
-#ifndef CONFIG_USB_PD_TCPC
- if (tc_restart_tcpc(port) != 0) {
- CPRINTS("TCPC p%d restart failed!", port);
- return 0;
+ if (!IS_ENABLED(CONFIG_USB_PD_TCPC)) {
+ if (tc_restart_tcpc(port) != 0) {
+ CPRINTS("TCPC p%d restart failed!", port);
+ return;
+ }
}
-#endif
- CPRINTS("TCPC p%d resumed!", port);
- return 0;
+ CPRINTS("TCPC p%d resumed!", port);
}
/**
@@ -151,29 +276,17 @@ static int tc_disabled_exit(int port)
* Remove the terminations from Host
* Remove the terminations from Charge-Through
*/
-static int tc_error_recovery(int port, enum sm_signal sig)
+static void tc_error_recovery_entry(const int port)
{
- int ret = 0;
-
- ret = (*tc_error_recovery_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_open_ct_open);
-}
-
-static int tc_error_recovery_entry(int port)
-{
- tc[port].state_id = TC_ERROR_RECOVERY;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Use cc_debounce state variable for error recovery timeout */
tc[port].cc_debounce = get_time().val + PD_T_ERROR_RECOVERY;
- return 0;
}
-static int tc_error_recovery_run(int port)
+static void tc_error_recovery_run(const int port)
{
if (get_time().val > tc[port].cc_debounce)
- return sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
-
- return SM_RUN_SUPER;
+ set_state_tc(port, TC_UNATTACHED_SNK);
}
/**
@@ -185,27 +298,16 @@ static int tc_error_recovery_run(int port)
* Place Ra on VCONN and Rd on Host CC
* Place Rd on Charge-Through CCs
*/
-static int tc_unattached_snk(int port, enum sm_signal sig)
-{
- int ret = 0;
-
- ret = (*tc_unattached_snk_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rard_ct_rd);
-}
-
-static int tc_unattached_snk_entry(int port)
+static void tc_unattached_snk_entry(const int port)
{
- tc[port].state_id = TC_UNATTACHED_SNK;
- if (tc[port].obj.last_state != tc_unattached_src)
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ if (get_last_state_tc(port) != TC_UNATTACHED_SRC)
+ print_current_state(port);
tc[port].flags &= ~TC_FLAGS_VCONN_ON;
tc[port].cc_state = PD_CC_UNSET;
-
- return 0;
}
-static int tc_unattached_snk_run(int port)
+static void tc_unattached_snk_run(const int port)
{
int host_cc;
int new_cc_state;
@@ -220,8 +322,10 @@ static int tc_unattached_snk_run(int port)
* detected, as indicated by the SNK.Rp state on its Host-side
* port’s CC pin.
*/
- if (cc_is_rp(host_cc))
- return sm_set_state(port, TC_OBJ(port), tc_attach_wait_snk);
+ if (cc_is_rp(host_cc)) {
+ set_state_tc(port, TC_ATTACH_WAIT_SNK);
+ return;
+ }
/* Check Charge-Through CCs for connection */
vpd_ct_get_cc(&cc1, &cc2);
@@ -241,7 +345,7 @@ static int tc_unattached_snk_run(int port)
/* Wait for Charge-Through CC debounce */
if (get_time().val < tc[port].cc_debounce)
- return 0;
+ return;
/*
* A Charge-Through VCONN-Powered USB Device shall transition to
@@ -253,10 +357,10 @@ static int tc_unattached_snk_run(int port)
* 2) VBUS is detected
*/
if (vpd_is_ct_vbus_present() &&
- tc[port].cc_state == PD_CC_DFP_ATTACHED)
- return sm_set_state(port, TC_OBJ(port), tc_unattached_src);
-
- return SM_RUN_SUPER;
+ tc[port].cc_state == PD_CC_DFP_ATTACHED) {
+ set_state_tc(port, TC_UNATTACHED_SRC);
+ return;
+ }
}
/**
@@ -268,24 +372,13 @@ static int tc_unattached_snk_run(int port)
* Place Ra on VCONN and Rd on Host CC
* Place Rd on Charge-Through CCs
*/
-static int tc_attach_wait_snk(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_attach_wait_snk_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rard_ct_rd);
-}
-
-static int tc_attach_wait_snk_entry(int port)
+static void tc_attach_wait_snk_entry(const int port)
{
- tc[port].state_id = TC_ATTACH_WAIT_SNK;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
tc[port].host_cc_state = PD_CC_UNSET;
-
- return 0;
}
-static int tc_attach_wait_snk_run(int port)
+static void tc_attach_wait_snk_run(const int port)
{
int host_new_cc_state;
int host_cc;
@@ -307,12 +400,12 @@ static int tc_attach_wait_snk_run(int port)
else
tc[port].host_cc_debounce = get_time().val +
PD_T_PD_DEBOUNCE;
- return 0;
+ return;
}
/* Wait for Host CC debounce */
if (get_time().val < tc[port].host_cc_debounce)
- return 0;
+ return;
/*
* A Charge-Through VCONN-Powered USB Device shall transition to
@@ -325,28 +418,17 @@ static int tc_attach_wait_snk_run(int port)
*/
if (tc[port].host_cc_state == PD_CC_DFP_ATTACHED &&
(vpd_is_vconn_present() || vpd_is_host_vbus_present()))
- sm_set_state(port, TC_OBJ(port), tc_attached_snk);
+ set_state_tc(port, TC_ATTACHED_SNK);
else if (tc[port].host_cc_state == PD_CC_NONE)
- sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
-
- return 0;
+ set_state_tc(port, TC_UNATTACHED_SNK);
}
/**
* Attached.SNK
*/
-static int tc_attached_snk(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_attached_snk_sig[sig])(port);
- return SM_SUPER(ret, sig, 0);
-}
-
-static int tc_attached_snk_entry(int port)
+static void tc_attached_snk_entry(const int port)
{
- tc[port].state_id = TC_ATTACHED_SNK;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Enable PD */
tc[port].pd_enable = 1;
@@ -368,18 +450,18 @@ static int tc_attached_snk_entry(int port)
/* Sample host CC every 2ms */
tc_set_timeout(port, 2*MSEC);
-
- return 0;
}
-static int tc_attached_snk_run(int port)
+static void tc_attached_snk_run(const int port)
{
int host_new_cc_state;
int host_cc;
/* Has host vbus and vconn been removed */
- if (!vpd_is_host_vbus_present() && !vpd_is_vconn_present())
- return sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
+ if (!vpd_is_host_vbus_present() && !vpd_is_vconn_present()) {
+ set_state_tc(port, TC_UNATTACHED_SNK);
+ return;
+ }
/*
* Reset the Charge-Through Support Timer when it first
@@ -404,12 +486,12 @@ static int tc_attached_snk_run(int port)
if (tc[port].host_cc_state != host_new_cc_state) {
tc[port].host_cc_state = host_new_cc_state;
tc[port].host_cc_debounce = get_time().val + PD_T_VPDCTDD;
- return 0;
+ return;
}
/* Wait for Host CC debounce */
if (get_time().val < tc[port].host_cc_debounce)
- return 0;
+ return;
if (vpd_is_vconn_present()) {
if (!(tc[port].flags & TC_FLAGS_VCONN_ON)) {
@@ -423,9 +505,10 @@ static int tc_attached_snk_run(int port)
* to CTUnattached.VPD if VCONN is present and the state of
* its Host-side port’s CC pin is SNK.Open for tVPDCTDD.
*/
- if (tc[port].host_cc_state == PD_CC_NONE)
- return sm_set_state(port, TC_OBJ(port),
- tc_ct_unattached_vpd);
+ if (tc[port].host_cc_state == PD_CC_NONE) {
+ set_state_tc(port, TC_CT_UNATTACHED_VPD);
+ return;
+ }
}
/* Check the Support Timer */
@@ -438,76 +521,44 @@ static int tc_attached_snk_run(int port)
tc[port].billboard_presented = 1;
vpd_present_billboard(BB_SNK);
}
-
- return 0;
}
-static int tc_attached_snk_exit(int port)
+static void tc_attached_snk_exit(const int port)
{
/* Reset timeout value to 10ms */
tc_set_timeout(port, 10*MSEC);
tc[port].billboard_presented = 0;
vpd_present_billboard(BB_NONE);
-
- return 0;
}
/**
* Super State HOST_RA_CT_RD
*/
-static int tc_host_rard_ct_rd(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_host_rard_ct_rd_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_vbus_cc_iso);
-}
-
-static int tc_host_rard_ct_rd_entry(int port)
+static void tc_host_rard_ct_rd_entry(const int port)
{
/* Place Ra on VCONN and Rd on Host CC */
vpd_host_set_pull(TYPEC_CC_RA_RD, 0);
/* Place Rd on Charge-Through CCs */
vpd_ct_set_pull(TYPEC_CC_RD, 0);
-
- return 0;
}
/**
* Super State HOST_OPEN_CT_OPEN
*/
-static int tc_host_open_ct_open(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_host_open_ct_open_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_vbus_cc_iso);
-}
-
-static int tc_host_open_ct_open_entry(int port)
+static void tc_host_open_ct_open_entry(const int port)
{
/* Remove the terminations from Host */
vpd_host_set_pull(TYPEC_CC_OPEN, 0);
/* Remove the terminations from Charge-Through */
vpd_ct_set_pull(TYPEC_CC_OPEN, 0);
-
- return 0;
}
/**
* Super State VBUS_CC_ISO
*/
-static int tc_vbus_cc_iso(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_vbus_cc_iso_sig[sig])(port);
- return SM_SUPER(ret, sig, 0);
-}
-
-static int tc_vbus_cc_iso_entry(int port)
+static void tc_vbus_cc_iso_entry(const int port)
{
/* Isolate the Host-side port from the Charge-Through port */
vpd_vbus_pass_en(0);
@@ -517,8 +568,6 @@ static int tc_vbus_cc_iso_entry(int port)
/* Enable mcu communication and cc */
vpd_mcu_cc_en(1);
-
- return 0;
}
/**
@@ -530,33 +579,24 @@ static int tc_vbus_cc_iso_entry(int port)
* Place RpUSB on Host CC
* Place Rd on Charge-Through CCs
*/
-static int tc_unattached_src(int port, enum sm_signal sig)
+static void tc_unattached_src_entry(const int port)
{
- int ret;
-
- ret = (*tc_unattached_src_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rpu_ct_rd);
-}
-
-static int tc_unattached_src_entry(int port)
-{
- tc[port].state_id = TC_UNATTACHED_SRC;
- if (tc[port].obj.last_state != tc_unattached_snk)
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ if (get_last_state_tc(port) != TC_UNATTACHED_SNK)
+ print_current_state(port);
/* Get power from VBUS */
vpd_vconn_pwr_sel_odl(PWR_VBUS);
/* Make sure it's the Charge-Through Port's VBUS */
- if (!vpd_is_ct_vbus_present())
- return sm_set_state(port, TC_OBJ(port), tc_error_recovery);
+ if (!vpd_is_ct_vbus_present()) {
+ set_state_tc(port, TC_ERROR_RECOVERY);
+ return;
+ }
tc[port].next_role_swap = get_time().val + PD_T_DRP_SRC;
-
- return 0;
}
-static int tc_unattached_src_run(int port)
+static void tc_unattached_src_run(const int port)
{
int host_cc;
@@ -568,18 +608,20 @@ static int tc_unattached_src_run(int port)
* vSafe0V and SRC.Rd state is detected on the Host-side
* port’s CC pin.
*/
- if (!vpd_is_host_vbus_present() && host_cc == TYPEC_CC_VOLT_RD)
- return sm_set_state(port, TC_OBJ(port), tc_attach_wait_src);
+ if (!vpd_is_host_vbus_present() && host_cc == TYPEC_CC_VOLT_RD) {
+ set_state_tc(port, TC_ATTACH_WAIT_SRC);
+ return;
+ }
/*
* Transition to Unattached.SNK within tDRPTransition or
* if Charge-Through VBUS is removed.
*/
if (!vpd_is_ct_vbus_present() ||
- get_time().val > tc[port].next_role_swap)
- return sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
-
- return SM_RUN_SUPER;
+ get_time().val > tc[port].next_role_swap) {
+ set_state_tc(port, TC_UNATTACHED_SNK);
+ return;
+ }
}
/**
@@ -591,25 +633,14 @@ static int tc_unattached_src_run(int port)
* Place RpUSB on Host CC
* Place Rd on Charge-Through CCs
*/
-static int tc_attach_wait_src(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_attach_wait_src_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rpu_ct_rd);
-}
-
-static int tc_attach_wait_src_entry(int port)
+static void tc_attach_wait_src_entry(const int port)
{
- tc[port].state_id = TC_ATTACH_WAIT_SRC;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
tc[port].host_cc_state = PD_CC_UNSET;
-
- return 0;
}
-static int tc_attach_wait_src_run(int port)
+static void tc_attach_wait_src_run(const int port)
{
int host_new_cc_state;
int host_cc;
@@ -630,19 +661,21 @@ static int tc_attach_wait_src_run(int port)
* shall detect the SRC.Open state within tSRCDisconnect, but
* should detect it as quickly as possible.
*/
- if (host_new_cc_state == PD_CC_NONE || !vpd_is_ct_vbus_present())
- return sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
+ if (host_new_cc_state == PD_CC_NONE || !vpd_is_ct_vbus_present()) {
+ set_state_tc(port, TC_UNATTACHED_SNK);
+ return;
+ }
/* Debounce the Host CC state */
if (tc[port].host_cc_state != host_new_cc_state) {
tc[port].host_cc_state = host_new_cc_state;
tc[port].cc_debounce = get_time().val + PD_T_CC_DEBOUNCE;
- return 0;
+ return;
}
/* Wait for Host CC debounce */
if (get_time().val < tc[port].cc_debounce)
- return 0;
+ return;
/*
* A Charge-Through VCONN-Powered USB Device shall transition to
@@ -650,27 +683,18 @@ static int tc_attach_wait_src_run(int port)
* state is on the Host-side port’s CC pin for at least tCCDebounce.
*/
if (tc[port].host_cc_state == PD_CC_UFP_ATTACHED &&
- !vpd_is_host_vbus_present())
- return sm_set_state(port, TC_OBJ(port), tc_try_snk);
-
- return SM_RUN_SUPER;
+ !vpd_is_host_vbus_present()) {
+ set_state_tc(port, TC_TRY_SNK);
+ return;
+ }
}
/**
* Attached.SRC
*/
-static int tc_attached_src(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_attached_src_sig[sig])(port);
- return SM_SUPER(ret, sig, 0);
-}
-
-static int tc_attached_src_entry(int port)
+static void tc_attached_src_entry(const int port)
{
- tc[port].state_id = TC_ATTACHED_SRC;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Enable PD */
tc[port].pd_enable = 1;
@@ -685,11 +709,9 @@ static int tc_attached_src_entry(int port)
* VBUS
*/
vpd_vconn_pwr_sel_odl(PWR_VBUS);
-
- return 0;
}
-static int tc_attached_src_run(int port)
+static void tc_attached_src_run(const int port)
{
int host_cc;
@@ -704,31 +726,19 @@ static int tc_attached_src_run(int port)
* tSRCDisconnect, but should detect it as quickly as possible.
*/
if (!vpd_is_ct_vbus_present() || host_cc == TYPEC_CC_VOLT_OPEN)
- sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
-
- return 0;
+ set_state_tc(port, TC_UNATTACHED_SNK);
}
/**
* Super State HOST_RPU_CT_RD
*/
-static int tc_host_rpu_ct_rd(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_host_rpu_ct_rd_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_vbus_cc_iso);
-}
-
-static int tc_host_rpu_ct_rd_entry(int port)
+static void tc_host_rpu_ct_rd_entry(const int port)
{
/* Place RpUSB on Host CC */
vpd_host_set_pull(TYPEC_CC_RP, TYPEC_RP_USB);
/* Place Rd on Charge-Through CCs */
vpd_ct_set_pull(TYPEC_CC_RD, 0);
-
- return 0;
}
/**
@@ -740,35 +750,26 @@ static int tc_host_rpu_ct_rd_entry(int port)
* Place Ra on VCONN and Rd on Host CC
* Place Rd on Charge-Through CCs
*/
-static int tc_try_snk(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_try_snk_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rard_ct_rd);
-}
-
-static int tc_try_snk_entry(int port)
+static void tc_try_snk_entry(const int port)
{
- tc[port].state_id = TC_TRY_SNK;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Get power from VBUS */
vpd_vconn_pwr_sel_odl(PWR_VBUS);
/* Make sure it's the Charge-Through Port's VBUS */
- if (!vpd_is_ct_vbus_present())
- return sm_set_state(port, TC_OBJ(port), tc_error_recovery);
+ if (!vpd_is_ct_vbus_present()) {
+ set_state_tc(port, TC_ERROR_RECOVERY);
+ return;
+ }
tc[port].host_cc_state = PD_CC_UNSET;
/* Using next_role_swap timer as try_src timer */
tc[port].next_role_swap = get_time().val + PD_T_DRP_TRY;
-
- return 0;
}
-static int tc_try_snk_run(int port)
+static void tc_try_snk_run(const int port)
{
int host_new_cc_state;
int host_cc;
@@ -778,7 +779,7 @@ static int tc_try_snk_run(int port)
* port’s CC pins for the SNK.Rp
*/
if (get_time().val < tc[port].next_role_swap)
- return 0;
+ return;
/* Check Host CC for connection */
vpd_host_get_cc(&host_cc);
@@ -792,12 +793,12 @@ static int tc_try_snk_run(int port)
if (tc[port].host_cc_state != host_new_cc_state) {
tc[port].host_cc_state = host_new_cc_state;
tc[port].cc_debounce = get_time().val + PD_T_DEBOUNCE;
- return 0;
+ return;
}
/* Wait for Host CC debounce */
if (get_time().val < tc[port].cc_debounce)
- return 0;
+ return;
/*
* The Charge-Through VCONN-Powered USB Device shall then transition to
@@ -811,11 +812,9 @@ static int tc_try_snk_run(int port)
*/
if (tc[port].host_cc_state == PD_CC_DFP_ATTACHED &&
(vpd_is_host_vbus_present() || vpd_is_vconn_present()))
- sm_set_state(port, TC_OBJ(port), tc_attached_snk);
+ set_state_tc(port, TC_ATTACHED_SNK);
else if (tc[port].host_cc_state == PD_CC_NONE)
- sm_set_state(port, TC_OBJ(port), tc_try_wait_src);
-
- return 0;
+ set_state_tc(port, TC_TRY_WAIT_SRC);
}
/**
@@ -827,26 +826,15 @@ static int tc_try_snk_run(int port)
* Place RpUSB on Host CC
* Place Rd on Charge-Through CCs
*/
-static int tc_try_wait_src(int port, enum sm_signal sig)
+static void tc_try_wait_src_entry(const int port)
{
- int ret;
-
- ret = (*tc_try_wait_src_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rpu_ct_rd);
-}
-
-static int tc_try_wait_src_entry(int port)
-{
- tc[port].state_id = TC_TRY_WAIT_SRC;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
tc[port].host_cc_state = PD_CC_UNSET;
tc[port].next_role_swap = get_time().val + PD_T_DRP_TRY;
-
- return 0;
}
-static int tc_try_wait_src_run(int port)
+static void tc_try_wait_src_run(const int port)
{
int host_new_cc_state;
int host_cc;
@@ -864,7 +852,7 @@ static int tc_try_wait_src_run(int port)
tc[port].host_cc_state = host_new_cc_state;
tc[port].host_cc_debounce =
get_time().val + PD_T_TRY_CC_DEBOUNCE;
- return 0;
+ return;
}
if (get_time().val > tc[port].host_cc_debounce) {
@@ -875,9 +863,10 @@ static int tc_try_wait_src_run(int port)
* at least tTryCCDebounce.
*/
if (tc[port].host_cc_state == PD_CC_UFP_ATTACHED &&
- !vpd_is_host_vbus_present())
- return sm_set_state(port, TC_OBJ(port),
- tc_attached_src);
+ !vpd_is_host_vbus_present()) {
+ set_state_tc(port, TC_ATTACHED_SRC);
+ return;
+ }
}
if (get_time().val > tc[port].next_role_swap) {
@@ -886,12 +875,11 @@ static int tc_try_wait_src_run(int port)
* to Unattached.SNK after tDRPTry if the Host-side port’s CC
* pin is not in the SRC.Rd state.
*/
- if (tc[port].host_cc_state == PD_CC_NONE)
- return sm_set_state(port, TC_OBJ(port),
- tc_unattached_snk);
+ if (tc[port].host_cc_state == PD_CC_NONE) {
+ set_state_tc(port, TC_UNATTACHED_SNK);
+ return;
+ }
}
-
- return SM_RUN_SUPER;
}
/**
@@ -904,18 +892,9 @@ static int tc_try_wait_src_run(int port)
* Connect Charge-Through Rd
* Get power from VCONN
*/
-static int tc_ct_try_snk(int port, enum sm_signal sig)
+static void tc_ct_try_snk_entry(const int port)
{
- int ret;
-
- ret = (*tc_ct_try_snk_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rp3_ct_rd);
-}
-
-static int tc_ct_try_snk_entry(int port)
-{
- tc[port].state_id = TC_CTTRY_SNK;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Enable PD */
tc[port].pd_enable = 1;
@@ -923,11 +902,9 @@ static int tc_ct_try_snk_entry(int port)
tc[port].cc_state = PD_CC_UNSET;
tc[port].next_role_swap = get_time().val + PD_T_DRP_TRY;
-
- return 0;
}
-static int tc_ct_try_snk_run(int port)
+static void tc_ct_try_snk_run(const int port)
{
int new_cc_state;
int cc1;
@@ -938,7 +915,7 @@ static int tc_ct_try_snk_run(int port)
* port’s CC pins for the SNK.Rp
*/
if (get_time().val < tc[port].next_role_swap)
- return 0;
+ return;
/* Check CT CC for connection */
vpd_ct_get_cc(&cc1, &cc2);
@@ -952,8 +929,10 @@ static int tc_ct_try_snk_run(int port)
* The Charge-Through VCONN-Powered USB Device shall transition
* to Unattached.SNK if VCONN falls below vVCONNDisconnect.
*/
- if (!vpd_is_vconn_present())
- return sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
+ if (!vpd_is_vconn_present()) {
+ set_state_tc(port, TC_UNATTACHED_SNK);
+ return;
+ }
/* Debounce the CT CC state */
if (tc[port].cc_state != new_cc_state) {
@@ -961,7 +940,7 @@ static int tc_ct_try_snk_run(int port)
tc[port].cc_debounce = get_time().val + PD_T_DEBOUNCE;
tc[port].try_wait_debounce = get_time().val + PD_T_TRY_WAIT;
- return 0;
+ return;
}
if (get_time().val > tc[port].cc_debounce) {
@@ -973,9 +952,10 @@ static int tc_ct_try_snk_run(int port)
* Charge-Through port.
*/
if (tc[port].cc_state == PD_CC_DFP_ATTACHED &&
- vpd_is_ct_vbus_present())
- return sm_set_state(port, TC_OBJ(port),
- tc_ct_attached_vpd);
+ vpd_is_ct_vbus_present()) {
+ set_state_tc(port, TC_CT_ATTACHED_VPD);
+ return;
+ }
}
if (get_time().val > tc[port].try_wait_debounce) {
@@ -984,20 +964,18 @@ static int tc_ct_try_snk_run(int port)
* to CTAttached.Unsupported if SNK.Rp state is not detected
* for tDRPTryWait.
*/
- if (tc[port].cc_state == PD_CC_NONE)
- return sm_set_state(port, TC_OBJ(port),
- tc_ct_attached_unsupported);
+ if (tc[port].cc_state == PD_CC_NONE) {
+ set_state_tc(port,
+ TC_CT_ATTACHED_UNSUPPORTED);
+ return;
+ }
}
-
- return SM_RUN_SUPER;
}
-static int tc_ct_try_snk_exit(int port)
+static void tc_ct_try_snk_exit(const int port)
{
/* Disable PD */
tc[port].pd_enable = 0;
-
- return 0;
}
/**
@@ -1010,29 +988,18 @@ static int tc_ct_try_snk_exit(int port)
* Place RPUSB on Charge-Through CC
* Get power from VCONN
*/
-static int tc_ct_attach_wait_unsupported(int port, enum sm_signal sig)
+static void tc_ct_attach_wait_unsupported_entry(const int port)
{
- int ret;
-
- ret = (*tc_ct_attach_wait_unsupported_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rp3_ct_rpu);
-}
-
-static int tc_ct_attach_wait_unsupported_entry(int port)
-{
- tc[port].state_id = TC_CTATTACH_WAIT_UNSUPPORTED;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Enable PD */
tc[port].pd_enable = 1;
set_polarity(port, 0);
tc[port].cc_state = PD_CC_UNSET;
-
- return 0;
}
-static int tc_ct_attach_wait_unsupported_run(int port)
+static void tc_ct_attach_wait_unsupported_run(const int port)
{
int new_cc_state;
int cc1;
@@ -1052,19 +1019,21 @@ static int tc_ct_attach_wait_unsupported_run(int port)
* A Charge-Through VCONN-Powered USB Device shall transition to
* Unattached.SNK if VCONN falls below vVCONNDisconnect.
*/
- if (!vpd_is_vconn_present())
- return sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
+ if (!vpd_is_vconn_present()) {
+ set_state_tc(port, TC_UNATTACHED_SNK);
+ return;
+ }
/* Debounce the cc state */
if (tc[port].cc_state != new_cc_state) {
tc[port].cc_state = new_cc_state;
tc[port].cc_debounce = get_time().val + PD_T_CC_DEBOUNCE;
- return 0;
+ return;
}
/* Wait for CC debounce */
if (get_time().val < tc[port].cc_debounce)
- return 0;
+ return;
/*
* A Charge-Through VCONN-Powered USB Device shall transition to
@@ -1077,19 +1046,15 @@ static int tc_ct_attach_wait_unsupported_run(int port)
* pins is SRC.Ra. for at least tCCDebounce.
*/
if (new_cc_state == PD_CC_NONE)
- sm_set_state(port, TC_OBJ(port), tc_ct_unattached_vpd);
+ set_state_tc(port, TC_CT_UNATTACHED_VPD);
else /* PD_CC_DFP_ATTACHED or PD_CC_AUDIO_ACC */
- sm_set_state(port, TC_OBJ(port), tc_ct_try_snk);
-
- return 0;
+ set_state_tc(port, TC_CT_TRY_SNK);
}
-static int tc_ct_attach_wait_unsupported_exit(int port)
+static void tc_ct_attach_wait_unsupported_exit(const int port)
{
/* Disable PD */
tc[port].pd_enable = 0;
-
- return 0;
}
/**
@@ -1102,26 +1067,15 @@ static int tc_ct_attach_wait_unsupported_exit(int port)
* Place RPUSB on Charge-Through CC
* Get power from VCONN
*/
-static int tc_ct_attached_unsupported(int port, enum sm_signal sig)
+static void tc_ct_attached_unsupported_entry(const int port)
{
- int ret;
-
- ret = (*tc_ct_attached_unsupported_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rp3_ct_rpu);
-}
-
-static int tc_ct_attached_unsupported_entry(int port)
-{
- tc[port].state_id = TC_CTATTACHED_UNSUPPORTED;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Present Billboard device */
vpd_present_billboard(BB_SNK);
-
- return 0;
}
-static int tc_ct_attached_unsupported_run(int port)
+static void tc_ct_attached_unsupported_run(const int port)
{
int cc1;
int cc2;
@@ -1129,8 +1083,10 @@ static int tc_ct_attached_unsupported_run(int port)
/* Check CT CC for connection */
vpd_ct_get_cc(&cc1, &cc2);
- if (!vpd_is_vconn_present())
- return sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
+ if (!vpd_is_vconn_present()) {
+ set_state_tc(port, TC_UNATTACHED_SNK);
+ return;
+ }
/*
* The Charge-Through VCONN-Powered USB Device shall transition to
@@ -1140,17 +1096,15 @@ static int tc_ct_attached_unsupported_run(int port)
*/
if ((cc1 == TYPEC_CC_VOLT_OPEN && cc2 == TYPEC_CC_VOLT_OPEN) ||
(cc1 == TYPEC_CC_VOLT_OPEN && cc2 == TYPEC_CC_VOLT_RA) ||
- (cc1 == TYPEC_CC_VOLT_RA && cc2 == TYPEC_CC_VOLT_OPEN))
- return sm_set_state(port, TC_OBJ(port), tc_ct_unattached_vpd);
-
- return SM_RUN_SUPER;
+ (cc1 == TYPEC_CC_VOLT_RA && cc2 == TYPEC_CC_VOLT_OPEN)) {
+ set_state_tc(port, TC_CT_UNATTACHED_VPD);
+ return;
+ }
}
-static int tc_ct_attached_unsupported_exit(int port)
+static void tc_ct_attached_unsupported_exit(const int port)
{
vpd_present_billboard(BB_NONE);
-
- return 0;
}
/**
@@ -1163,30 +1117,19 @@ static int tc_ct_attached_unsupported_exit(int port)
* Place RPUSB on Charge-Through CC
* Get power from VCONN
*/
-static int tc_ct_unattached_unsupported(int port, enum sm_signal sig)
+static void tc_ct_unattached_unsupported_entry(const int port)
{
- int ret;
-
- ret = (*tc_ct_unattached_unsupported_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rp3_ct_rpu);
-}
-
-static int tc_ct_unattached_unsupported_entry(int port)
-{
- tc[port].state_id = TC_CTUNATTACHED_UNSUPPORTED;
- if (tc[port].obj.last_state != tc_ct_unattached_vpd)
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ if (get_last_state_tc(port) != TC_CT_UNATTACHED_VPD)
+ print_current_state(port);
/* Enable PD */
tc[port].pd_enable = 1;
set_polarity(port, 0);
tc[port].next_role_swap = get_time().val + PD_T_DRP_SRC;
-
- return 0;
}
-static int tc_ct_unattached_unsupported_run(int port)
+static void tc_ct_unattached_unsupported_run(const int port)
{
int cc1;
int cc2;
@@ -1201,33 +1144,35 @@ static int tc_ct_unattached_unsupported_run(int port)
* least one of the Charge-Through port’s CC pins or SRC.Ra state
* on both the CC1 and CC2 pins.
*/
- if (cc_is_at_least_one_rd(cc1, cc2) || cc_is_audio_acc(cc1, cc2))
- return sm_set_state(port, TC_OBJ(port),
- tc_ct_attach_wait_unsupported);
+ if (cc_is_at_least_one_rd(cc1, cc2) || cc_is_audio_acc(cc1, cc2)) {
+ set_state_tc(port,
+ TC_CT_ATTACH_WAIT_UNSUPPORTED);
+ return;
+ }
/*
* A Charge-Through VCONN-Powered USB Device shall transition to
* Unattached.SNK if VCONN falls below vVCONNDisconnect.
*/
- if (!vpd_is_vconn_present())
- return sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
+ if (!vpd_is_vconn_present()) {
+ set_state_tc(port, TC_UNATTACHED_SNK);
+ return;
+ }
/*
* A Charge-Through VCONN-Powered USB Device shall transition to
* CTUnattached.VPD within tDRPTransition after dcSRC.DRP ∙ tDRP.
*/
- if (get_time().val > tc[port].next_role_swap)
- return sm_set_state(port, TC_OBJ(port), tc_ct_unattached_vpd);
-
- return SM_RUN_SUPER;
+ if (get_time().val > tc[port].next_role_swap) {
+ set_state_tc(port, TC_CT_UNATTACHED_VPD);
+ return;
+ }
}
-static int tc_ct_unattached_unsupported_exit(int port)
+static void tc_ct_unattached_unsupported_exit(const int port)
{
/* Disable PD */
tc[port].pd_enable = 0;
-
- return 0;
}
/**
@@ -1240,30 +1185,19 @@ static int tc_ct_unattached_unsupported_exit(int port)
* Connect Charge-Through Rd
* Get power from VCONN
*/
-static int tc_ct_unattached_vpd(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_ct_unattached_vpd_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rp3_ct_rd);
-}
-
-static int tc_ct_unattached_vpd_entry(int port)
+static void tc_ct_unattached_vpd_entry(const int port)
{
- tc[port].state_id = TC_CTUNATTACHED_VPD;
- if (tc[port].obj.last_state != tc_ct_unattached_unsupported)
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ if (get_last_state_tc(port) != TC_CT_UNATTACHED_UNSUPPORTED)
+ print_current_state(port);
/* Enable PD */
tc[port].pd_enable = 1;
set_polarity(port, 0);
tc[port].cc_state = PD_CC_UNSET;
-
- return 0;
}
-static int tc_ct_unattached_vpd_run(int port)
+static void tc_ct_unattached_vpd_run(const int port)
{
int new_cc_state;
int cc1;
@@ -1285,27 +1219,29 @@ static int tc_ct_unattached_vpd_run(int port)
* Charge-Through port, as indicated by the SNK.Rp state on
* exactly one of the Charge-Through port’s CC pins.
*/
- if (new_cc_state == PD_CC_DFP_ATTACHED)
- return sm_set_state(port, TC_OBJ(port),
- tc_ct_attach_wait_vpd);
+ if (new_cc_state == PD_CC_DFP_ATTACHED) {
+ set_state_tc(port, TC_CT_ATTACH_WAIT_VPD);
+ return;
+ }
/*
* A Charge-Through VCONN-Powered USB Device shall transition to
* Unattached.SNK if VCONN falls below vVCONNDisconnect.
*/
- if (!vpd_is_vconn_present())
- return sm_set_state(port, TC_OBJ(port),
- tc_unattached_snk);
+ if (!vpd_is_vconn_present()) {
+ set_state_tc(port, TC_UNATTACHED_SNK);
+ return;
+ }
/* Debounce the cc state */
if (new_cc_state != tc[port].cc_state) {
tc[port].cc_state = new_cc_state;
tc[port].cc_debounce = get_time().val + PD_T_DRP_SRC;
- return 0;
+ return;
}
if (get_time().val < tc[port].cc_debounce)
- return 0;
+ return;
/*
* A Charge-Through VCONN-Powered USB Device shall transition to
@@ -1313,19 +1249,16 @@ static int tc_ct_unattached_vpd_run(int port)
* of both the Charge-Through port’s CC1 and CC2 pins is SNK.Open
* for tDRP-dcSRC.DRP ∙ tDRP, or if directed.
*/
- if (tc[port].cc_state == PD_CC_NONE)
- return sm_set_state(port, TC_OBJ(port),
- tc_ct_unattached_unsupported);
-
- return SM_RUN_SUPER;
+ if (tc[port].cc_state == PD_CC_NONE) {
+ set_state_tc(port, TC_CT_UNATTACHED_UNSUPPORTED);
+ return;
+ }
}
-static int tc_ct_unattached_vpd_exit(int port)
+static void tc_ct_unattached_vpd_exit(const int port)
{
/* Disable PD */
tc[port].pd_enable = 0;
-
- return 0;
}
/**
@@ -1337,57 +1270,34 @@ static int tc_ct_unattached_vpd_exit(int port)
* Remove the terminations from Host
* Remove the terminations from Charge-Through
*/
-static int tc_ct_disabled_vpd(int port, enum sm_signal sig)
+static void tc_ct_disabled_vpd_entry(const int port)
{
- int ret;
-
- ret = (*tc_ct_disabled_vpd_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_open_ct_open);
-}
-
-static int tc_ct_disabled_vpd_entry(int port)
-{
- tc[port].state_id = TC_CTDISABLED_VPD;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Get power from VBUS */
vpd_vconn_pwr_sel_odl(PWR_VBUS);
tc[port].next_role_swap = get_time().val + PD_T_VPDDISABLE;
-
- return 0;
}
-static int tc_ct_disabled_vpd_run(int port)
+static void tc_ct_disabled_vpd_run(const int port)
{
/*
* A Charge-Through VCONN-Powered USB Device shall transition
* to Unattached.SNK after tVPDDisable.
*/
if (get_time().val > tc[port].next_role_swap)
- sm_set_state(port, TC_OBJ(port), tc_unattached_snk);
-
- return 0;
+ set_state_tc(port, TC_UNATTACHED_SNK);
}
/**
* CTAttached.VPD
*/
-static int tc_ct_attached_vpd(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_ct_attached_vpd_sig[sig])(port);
- return SM_SUPER(ret, sig, 0);
-}
-
-static int tc_ct_attached_vpd_entry(int port)
+static void tc_ct_attached_vpd_entry(const int port)
{
int cc1;
int cc2;
-
- tc[port].state_id = TC_CTATTACHED_VPD;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Get power from VCONN */
vpd_vconn_pwr_sel_odl(PWR_VCONN);
@@ -1430,11 +1340,9 @@ static int tc_ct_attached_vpd_entry(int port)
vpd_vbus_pass_en(1);
tc[port].cc_state = PD_CC_UNSET;
-
- return 0;
}
-static int tc_ct_attached_vpd_run(int port)
+static void tc_ct_attached_vpd_run(const int port)
{
int new_cc_state;
int cc1;
@@ -1444,8 +1352,10 @@ static int tc_ct_attached_vpd_run(int port)
* A Charge-Through VCONN-Powered USB Device shall transition to
* CTDisabled.VPD if VCONN falls below vVCONNDisconnect.
*/
- if (!vpd_is_vconn_present())
- return sm_set_state(port, TC_OBJ(port), tc_ct_disabled_vpd);
+ if (!vpd_is_vconn_present()) {
+ set_state_tc(port, TC_CT_DISABLED_VPD);
+ return;
+ }
/* Check CT CC for connection */
vpd_ct_get_cc(&cc1, &cc2);
@@ -1458,11 +1368,11 @@ static int tc_ct_attached_vpd_run(int port)
if (new_cc_state != tc[port].cc_state) {
tc[port].cc_state = new_cc_state;
tc[port].cc_debounce = get_time().val + PD_T_VPDCTDD;
- return 0;
+ return;
}
if (get_time().val < tc[port].pd_debounce)
- return 0;
+ return;
/*
* A Charge-Through VCONN-Powered USB Device shall transition to
@@ -1470,9 +1380,7 @@ static int tc_ct_attached_vpd_run(int port)
* state of the passed-through CC pin is SNK.Open for tVPDCTDD.
*/
if (tc[port].cc_state == PD_CC_NONE && !vpd_is_ct_vbus_present())
- sm_set_state(port, TC_OBJ(port), tc_ct_unattached_vpd);
-
- return 0;
+ set_state_tc(port, TC_CT_UNATTACHED_VPD);
}
/**
@@ -1485,18 +1393,9 @@ static int tc_ct_attached_vpd_run(int port)
* Connect Charge-Through Rd
* Get power from VCONN
*/
-static int tc_ct_attach_wait_vpd(int port, enum sm_signal sig)
+static void tc_ct_attach_wait_vpd_entry(const int port)
{
- int ret;
-
- ret = (*tc_ct_attach_wait_vpd_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_host_rp3_ct_rd);
-}
-
-static int tc_ct_attach_wait_vpd_entry(int port)
-{
- tc[port].state_id = TC_CTATTACH_WAIT_VPD;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
+ print_current_state(port);
/* Enable PD */
tc[port].pd_enable = 1;
@@ -1506,10 +1405,9 @@ static int tc_ct_attach_wait_vpd_entry(int port)
/* Sample CCs every 2ms */
tc_set_timeout(port, 2 * MSEC);
- return 0;
}
-static int tc_ct_attach_wait_vpd_run(int port)
+static void tc_ct_attach_wait_vpd_run(const int port)
{
int new_cc_state;
int cc1;
@@ -1529,8 +1427,10 @@ static int tc_ct_attach_wait_vpd_run(int port)
* A Charge-Through VCONN-Powered USB Device shall transition to
* CTDisabled.VPD if VCONN falls below vVCONNDisconnect.
*/
- if (!vpd_is_vconn_present())
- return sm_set_state(port, TC_OBJ(port), tc_ct_disabled_vpd);
+ if (!vpd_is_vconn_present()) {
+ set_state_tc(port, TC_CT_DISABLED_VPD);
+ return;
+ }
/* Debounce the cc state */
if (new_cc_state != tc[port].cc_state) {
@@ -1539,7 +1439,7 @@ static int tc_ct_attach_wait_vpd_run(int port)
PD_T_CC_DEBOUNCE;
tc[port].pd_debounce = get_time().val +
PD_T_PD_DEBOUNCE;
- return 0;
+ return;
}
if (get_time().val > tc[port].pd_debounce) {
@@ -1549,9 +1449,10 @@ static int tc_ct_attach_wait_vpd_run(int port)
* port’s CC1 and CC2 pins are SNK.Open for at least
* tPDDebounce.
*/
- if (tc[port].cc_state == PD_CC_NONE)
- return sm_set_state(port, TC_OBJ(port),
- tc_ct_unattached_vpd);
+ if (tc[port].cc_state == PD_CC_NONE) {
+ set_state_tc(port, TC_CT_UNATTACHED_VPD);
+ return;
+ }
}
if (get_time().val > tc[port].cc_debounce) {
@@ -1563,38 +1464,26 @@ static int tc_ct_attach_wait_vpd_run(int port)
* detected.
*/
if (tc[port].cc_state == PD_CC_DFP_ATTACHED &&
- vpd_is_ct_vbus_present())
- return sm_set_state(port, TC_OBJ(port),
- tc_ct_attached_vpd);
+ vpd_is_ct_vbus_present()) {
+ set_state_tc(port, TC_CT_ATTACHED_VPD);
+ return;
+ }
}
-
- return SM_RUN_SUPER;
}
-static int tc_ct_attach_wait_vpd_exit(int port)
+static void tc_ct_attach_wait_vpd_exit(const int port)
{
/* Disable PD */
tc[port].pd_enable = 0;
/* Reset timeout value to 10ms */
tc_set_timeout(port, 10 * MSEC);
-
- return 0;
}
/**
* Super State HOST_RP3_CT_RD
*/
-static int tc_host_rp3_ct_rd(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_host_rp3_ct_rd_sig[sig])(port);
-
- return SM_SUPER(ret, sig, tc_vbus_cc_iso);
-}
-
-static int tc_host_rp3_ct_rd_entry(int port)
+static void tc_host_rp3_ct_rd_entry(const int port)
{
/* Place RP3A0 on Host CC */
vpd_host_set_pull(TYPEC_CC_RP, TYPEC_RP_3A0);
@@ -1609,26 +1498,16 @@ static int tc_host_rp3_ct_rd_entry(int port)
/* Make sure vconn is on */
if (!vpd_is_vconn_present())
- sm_set_state(port, TC_OBJ(port), tc_error_recovery);
+ set_state_tc(port, TC_ERROR_RECOVERY);
/* Get power from VCONN */
vpd_vconn_pwr_sel_odl(PWR_VCONN);
-
- return 0;
}
/**
* Super State HOST_RP3_CT_RPU
*/
-static int tc_host_rp3_ct_rpu(int port, enum sm_signal sig)
-{
- int ret;
-
- ret = (*tc_host_rp3_ct_rpu_sig[sig])(port);
- return SM_SUPER(ret, sig, tc_vbus_cc_iso);
-}
-
-static int tc_host_rp3_ct_rpu_entry(int port)
+static void tc_host_rp3_ct_rpu_entry(const int port)
{
/* Place RP3A0 on Host CC */
vpd_host_set_pull(TYPEC_CC_RP, TYPEC_RP_3A0);
@@ -1643,10 +1522,165 @@ static int tc_host_rp3_ct_rpu_entry(int port)
/* Make sure vconn is on */
if (!vpd_is_vconn_present())
- sm_set_state(port, TC_OBJ(port), tc_error_recovery);
+ set_state_tc(port, TC_ERROR_RECOVERY);
/* Get power from VCONN */
vpd_vconn_pwr_sel_odl(PWR_VCONN);
-
- return 0;
}
+
+/* All necessary Type-C states */
+
+/*
+ * Type-C State Hierarchy (Sub-States are listed inside the boxes)
+ *
+ * | TC_VBUS_CC_ISO ------------------------------------------------------|
+ * | |
+ * | | TC_HOST_RARD_CT_RD -----------| | TC_HOST_OPEN_CT_OPEN ---------| |
+ * | | | | | |
+ * | | TC_UNATTACHED_SNK | | TC_DISABLED | |
+ * | | TC_ATTACH_WAIT_SNK | | TC_ERROR_RECOVERY | |
+ * | | TC_TRY_SNK | |-------------------------------| |
+ * | |-------------------------------| |
+ * | |
+ * | | TC_HOST_RP3_CT_RD ------------| | TC_HOST_RPU_CT_RD ------------| |
+ * | | | | | |
+ * | | TC_CT_TRY_SNK | | TC_UNATTACHED_SRC | |
+ * | | TC_CT_UNATTACHED_VPD | | TC_ATTACH_WAIT_SRC | |
+ * | | TC_CT_ATTACH_WAIT_VPD | | TC_TRY_WAIT_SR | |
+ * | |-------------------------------| |-------------------------------| |
+ * | |
+ * | | TC_HOST_RP3_CT_RPU -----------| |
+ * | | | |
+ * | | TC_CT_ATTACH_WAIT_UNSUPPORTED | |
+ * | | TC_CT_ATTACHED_UNSUPPORTED | |
+ * | | TC_CT_UNATTACHED_UNSUPPORTED | |
+ * | |-------------------------------| |
+ * |----------------------------------------------------------------------|
+ *
+ * TC_ATTACHED_SNK
+ * TC_ATTACHED_SRC
+ * TC_CT_ATTACHED_VPD
+ *
+ */
+static const struct usb_state tc_states[] = {
+ /* Super States */
+ [TC_VBUS_CC_ISO] = {
+ .entry = tc_vbus_cc_iso_entry,
+ },
+ [TC_HOST_RARD_CT_RD] = {
+ .entry = tc_host_rard_ct_rd_entry,
+ .parent = &tc_states[TC_VBUS_CC_ISO],
+ },
+ [TC_HOST_OPEN_CT_OPEN] = {
+ .entry = tc_host_open_ct_open_entry,
+ .parent = &tc_states[TC_VBUS_CC_ISO],
+ },
+ [TC_HOST_RP3_CT_RD] = {
+ .entry = tc_host_rp3_ct_rd_entry,
+ .parent = &tc_states[TC_VBUS_CC_ISO],
+ },
+ [TC_HOST_RP3_CT_RPU] = {
+ .entry = tc_host_rp3_ct_rpu_entry,
+ .parent = &tc_states[TC_VBUS_CC_ISO],
+ },
+ [TC_HOST_RPU_CT_RD] = {
+ .entry = tc_host_rpu_ct_rd_entry,
+ .parent = &tc_states[TC_VBUS_CC_ISO],
+ },
+ /* Normal States */
+ [TC_DISABLED] = {
+ .entry = tc_disabled_entry,
+ .run = tc_disabled_run,
+ .exit = tc_disabled_exit,
+ .parent = &tc_states[TC_HOST_OPEN_CT_OPEN],
+ },
+ [TC_UNATTACHED_SNK] = {
+ .entry = tc_unattached_snk_entry,
+ .run = tc_unattached_snk_run,
+ .parent = &tc_states[TC_HOST_RARD_CT_RD],
+ },
+ [TC_ATTACH_WAIT_SNK] = {
+ .entry = tc_attach_wait_snk_entry,
+ .run = tc_attach_wait_snk_run,
+ .parent = &tc_states[TC_HOST_RARD_CT_RD],
+ },
+ [TC_ATTACHED_SNK] = {
+ .entry = tc_attached_snk_entry,
+ .run = tc_attached_snk_run,
+ .exit = tc_attached_snk_exit,
+ },
+ [TC_ERROR_RECOVERY] = {
+ .entry = tc_error_recovery_entry,
+ .run = tc_error_recovery_run,
+ .parent = &tc_states[TC_HOST_OPEN_CT_OPEN],
+ },
+ [TC_TRY_SNK] = {
+ .entry = tc_try_snk_entry,
+ .run = tc_try_snk_run,
+ .parent = &tc_states[TC_HOST_RARD_CT_RD],
+ },
+ [TC_UNATTACHED_SRC] = {
+ .entry = tc_unattached_src_entry,
+ .run = tc_unattached_src_run,
+ .parent = &tc_states[TC_HOST_RPU_CT_RD],
+ },
+ [TC_ATTACH_WAIT_SRC] = {
+ .entry = tc_attach_wait_src_entry,
+ .run = tc_attach_wait_src_run,
+ .parent = &tc_states[TC_HOST_RPU_CT_RD],
+ },
+ [TC_TRY_WAIT_SRC] = {
+ .entry = tc_try_wait_src_entry,
+ .run = tc_try_wait_src_run,
+ .parent = &tc_states[TC_HOST_RPU_CT_RD],
+ },
+ [TC_ATTACHED_SRC] = {
+ .entry = tc_attached_src_entry,
+ .run = tc_attached_src_run,
+ },
+ [TC_CT_TRY_SNK] = {
+ .entry = tc_ct_try_snk_entry,
+ .run = tc_ct_try_snk_run,
+ .exit = tc_ct_try_snk_exit,
+ .parent = &tc_states[TC_HOST_RP3_CT_RD],
+ },
+ [TC_CT_ATTACH_WAIT_UNSUPPORTED] = {
+ .entry = tc_ct_attach_wait_unsupported_entry,
+ .run = tc_ct_attach_wait_unsupported_run,
+ .exit = tc_ct_attach_wait_unsupported_exit,
+ .parent = &tc_states[TC_HOST_RP3_CT_RPU],
+ },
+ [TC_CT_ATTACHED_UNSUPPORTED] = {
+ .entry = tc_ct_attached_unsupported_entry,
+ .run = tc_ct_attached_unsupported_run,
+ .exit = tc_ct_attached_unsupported_exit,
+ .parent = &tc_states[TC_HOST_RP3_CT_RPU],
+ },
+ [TC_CT_UNATTACHED_UNSUPPORTED] = {
+ .entry = tc_ct_unattached_unsupported_entry,
+ .run = tc_ct_unattached_unsupported_run,
+ .exit = tc_ct_unattached_unsupported_exit,
+ .parent = &tc_states[TC_HOST_RP3_CT_RPU],
+ },
+ [TC_CT_UNATTACHED_VPD] = {
+ .entry = tc_ct_unattached_vpd_entry,
+ .run = tc_ct_unattached_vpd_run,
+ .exit = tc_ct_unattached_vpd_exit,
+ .parent = &tc_states[TC_HOST_RP3_CT_RD],
+ },
+ [TC_CT_DISABLED_VPD] = {
+ .entry = tc_ct_disabled_vpd_entry,
+ .run = tc_ct_disabled_vpd_run,
+ .parent = &tc_states[TC_HOST_OPEN_CT_OPEN],
+ },
+ [TC_CT_ATTACHED_VPD] = {
+ .entry = tc_ct_attached_vpd_entry,
+ .run = tc_ct_attached_vpd_run,
+ },
+ [TC_CT_ATTACH_WAIT_VPD] = {
+ .entry = tc_ct_attach_wait_vpd_entry,
+ .run = tc_ct_attach_wait_vpd_run,
+ .exit = tc_ct_attach_wait_vpd_exit,
+ .parent = &tc_states[TC_HOST_RP3_CT_RD],
+ },
+};