diff options
author | Jett Rink <jettrink@chromium.org> | 2019-08-02 16:20:50 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-08-20 15:53:16 +0000 |
commit | 2a7996a3caf25d358164a48e80723758e8be1fd1 (patch) | |
tree | a6dd0682b7ab1c3cc408450137e5f10988cf9da7 /common/usbc/usb_tc_ctvpd_sm.c | |
parent | a1aea89ae15c85d56f52976289a329e7c58bc8f6 (diff) | |
download | chrome-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.c | 1080 |
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], + }, +}; |