summaryrefslogtreecommitdiff
path: root/include/usb_tc_ctvpd_sm.h
diff options
context:
space:
mode:
authorSam Hurst <shurst@google.com>2019-05-22 14:13:40 -0700
committerCommit Bot <commit-bot@chromium.org>2019-06-05 21:43:03 +0000
commitd76c396bf65e912c2aa2ca1e905daa74996cdb27 (patch)
treec34654adeebeb793d548215c2eaf6f4f4ba3bdfe /include/usb_tc_ctvpd_sm.h
parent184701a33a0f77dfbe38d231d05741db1f8ddbc6 (diff)
downloadchrome-ec-d76c396bf65e912c2aa2ca1e905daa74996cdb27.tar.gz
chocodile_vpdmcu: Firmware refactoring
Move code in header files into c source files. BUG=b:133341676 BRANCH=none TEST=manual Charge-Through was tested on an Atlas running a DRP USB-C/PD state machine with CTUnattached.SNK and CTAttached.SNK states. Change-Id: Ib1b51a778b937e02908f0bc8866bc91a39831163 Signed-off-by: Sam Hurst <shurst@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1626036 Reviewed-by: Jett Rink <jettrink@chromium.org> Commit-Queue: Sam Hurst <shurst@google.com> Tested-by: Sam Hurst <shurst@google.com>
Diffstat (limited to 'include/usb_tc_ctvpd_sm.h')
-rw-r--r--include/usb_tc_ctvpd_sm.h1993
1 files changed, 11 insertions, 1982 deletions
diff --git a/include/usb_tc_ctvpd_sm.h b/include/usb_tc_ctvpd_sm.h
index 8e0e1eaf2f..72ce16f317 100644
--- a/include/usb_tc_ctvpd_sm.h
+++ b/include/usb_tc_ctvpd_sm.h
@@ -3,29 +3,17 @@
* found in the LICENSE file.
*/
-#include "vpd_api.h"
+#ifndef __CROS_EC_USB_TC_CTVPD_SM_H
+#define __CROS_EC_USB_TC_CTVPD_SM_H
-/* USB Type-C CTVPD module */
+#include "usb_sm.h"
+#include "usb_tc_sm.h"
-#ifndef __CROS_EC_USB_TC_VPD_H
-#define __CROS_EC_USB_TC_VPD_H
-
-/* Type-C Layer Flags */
-#define TC_FLAGS_VCONN_ON (1 << 0)
-
-
-#undef PD_DEFAULT_STATE
-/* Port default state at startup */
-#define PD_DEFAULT_STATE(port) tc_state_unattached_snk
-
-#define TC_OBJ(port) (SM_OBJ(tc[port]))
-#define TC_TEST_OBJ(port) (SM_OBJ(tc[(port)].obj))
-
-#define SUPPORT_TIMER_RESET_INIT 0
-#define SUPPORT_TIMER_RESET_REQUEST 1
-#define SUPPORT_TIMER_RESET_COMPLETE 2
-
-static struct type_c {
+/**
+ * This is the Type-C Port object that contains information needed to
+ * implement a Charge Through VCONN Powered Device.
+ */
+struct type_c {
/* struct sm_obj must be first */
struct sm_obj obj;
/* state id */
@@ -71,1967 +59,8 @@ static struct type_c {
/* The cc state */
enum pd_cc_states cc_state;
uint64_t next_role_swap;
-} tc[CONFIG_USB_PD_PORT_COUNT];
-
-/* Type-C states */
-static unsigned int tc_state_disabled(int port, enum signal sig);
-static unsigned int tc_state_disabled_entry(int port);
-static unsigned int tc_state_disabled_run(int port);
-static unsigned int tc_state_disabled_exit(int port);
-
-static unsigned int tc_state_error_recovery(int port, enum signal sig);
-static unsigned int tc_state_error_recovery_entry(int port);
-static unsigned int tc_state_error_recovery_run(int port);
-
-static unsigned int tc_state_unattached_snk(int port, enum signal sig);
-static unsigned int tc_state_unattached_snk_entry(int port);
-static unsigned int tc_state_unattached_snk_run(int port);
-
-static unsigned int tc_state_attach_wait_snk(int port, enum signal sig);
-static unsigned int tc_state_attach_wait_snk_entry(int port);
-static unsigned int tc_state_attach_wait_snk_run(int port);
-
-static unsigned int tc_state_attached_snk(int port, enum signal sig);
-static unsigned int tc_state_attached_snk_entry(int port);
-static unsigned int tc_state_attached_snk_run(int port);
-static unsigned int tc_state_attached_snk_exit(int port);
-
-static unsigned int tc_state_try_snk(int port, enum signal sig);
-static unsigned int tc_state_try_snk_entry(int port);
-static unsigned int tc_state_try_snk_run(int port);
-
-static unsigned int tc_state_unattached_src(int port, enum signal sig);
-static unsigned int tc_state_unattached_src_entry(int port);
-static unsigned int tc_state_unattached_src_run(int port);
-
-static unsigned int tc_state_attach_wait_src(int port, enum signal sig);
-static unsigned int tc_state_attach_wait_src_entry(int port);
-static unsigned int tc_state_attach_wait_src_run(int port);
-
-static unsigned int tc_state_try_wait_src(int port, enum signal sig);
-static unsigned int tc_state_try_wait_src_entry(int port);
-static unsigned int tc_state_try_wait_src_run(int port);
-
-static unsigned int tc_state_attached_src(int port, enum signal sig);
-static unsigned int tc_state_attached_src_entry(int port);
-static unsigned int tc_state_attached_src_run(int port);
-
-static unsigned int tc_state_ct_try_snk(int port, enum signal sig);
-static unsigned int tc_state_ct_try_snk_entry(int port);
-static unsigned int tc_state_ct_try_snk_run(int port);
-static unsigned int tc_state_ct_try_snk_exit(int port);
-
-static unsigned int
- tc_state_ct_attach_wait_unsupported(int port, enum signal sig);
-static unsigned int tc_state_ct_attach_wait_unsupported_entry(int port);
-static unsigned int tc_state_ct_attach_wait_unsupported_run(int port);
-static unsigned int tc_state_ct_attach_wait_unsupported_exit(int port);
-
-static unsigned int tc_state_ct_attached_unsupported(int port, enum signal sig);
-static unsigned int tc_state_ct_attached_unsupported_entry(int port);
-static unsigned int tc_state_ct_attached_unsupported_run(int port);
-static unsigned int tc_state_ct_attached_unsupported_exit(int port);
-
-static unsigned int
- tc_state_ct_unattached_unsupported(int port, enum signal sig);
-static unsigned int tc_state_ct_unattached_unsupported_entry(int port);
-static unsigned int tc_state_ct_unattached_unsupported_run(int port);
-static unsigned int tc_state_ct_unattached_unsupported_exit(int port);
-
-static unsigned int tc_state_ct_unattached_vpd(int port, enum signal sig);
-static unsigned int tc_state_ct_unattached_vpd_entry(int port);
-static unsigned int tc_state_ct_unattached_vpd_run(int port);
-static unsigned int tc_state_ct_unattached_vpd_exit(int port);
-
-static unsigned int tc_state_ct_disabled_vpd(int port, enum signal sig);
-static unsigned int tc_state_ct_disabled_vpd_entry(int port);
-static unsigned int tc_state_ct_disabled_vpd_run(int port);
-
-static unsigned int tc_state_ct_attached_vpd(int port, enum signal sig);
-static unsigned int tc_state_ct_attached_vpd_entry(int port);
-static unsigned int tc_state_ct_attached_vpd_run(int port);
-
-static unsigned int tc_state_ct_attach_wait_vpd(int port, enum signal sig);
-static unsigned int tc_state_ct_attach_wait_vpd_entry(int port);
-static unsigned int tc_state_ct_attach_wait_vpd_run(int port);
-static unsigned int tc_state_ct_attach_wait_vpd_exit(int port);
-
-
-/* Super States */
-static unsigned int tc_state_host_rard_ct_rd(int port, enum signal sig);
-static unsigned int tc_state_host_rard_ct_rd_entry(int port);
-static unsigned int tc_state_host_rard_ct_rd_run(int port);
-
-static unsigned int tc_state_host_open_ct_open(int port, enum signal sig);
-static unsigned int tc_state_host_open_ct_open_entry(int port);
-static unsigned int tc_state_host_open_ct_open_run(int port);
-
-static unsigned int tc_state_vbus_cc_iso(int port, enum signal sig);
-static unsigned int tc_state_vbus_cc_iso_entry(int port);
-static unsigned int tc_state_vbus_cc_iso_run(int port);
-
-static unsigned int tc_state_host_rp3_ct_rd(int port, enum signal sig);
-static unsigned int tc_state_host_rp3_ct_rd_entry(int port);
-static unsigned int tc_state_host_rp3_ct_rd_run(int port);
-
-static unsigned int tc_state_host_rp3_ct_rpu(int port, enum signal sig);
-static unsigned int tc_state_host_rp3_ct_rpu_entry(int port);
-static unsigned int tc_state_host_rp3_ct_rpu_run(int port);
-
-static unsigned int tc_state_host_rpu_ct_rd(int port, enum signal sig);
-static unsigned int tc_state_host_rpu_ct_rd_entry(int port);
-static unsigned int tc_state_host_rpu_ct_rd_run(int port);
-
-static unsigned int do_nothing_exit(int port);
-static unsigned int get_super_state(int port);
-
-
-static const state_sig tc_state_disabled_sig[] = {
- tc_state_disabled_entry,
- tc_state_disabled_run,
- tc_state_disabled_exit,
- get_super_state
-};
-
-static const state_sig tc_state_error_recovery_sig[] = {
- tc_state_error_recovery_entry,
- tc_state_error_recovery_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_unattached_snk_sig[] = {
- tc_state_unattached_snk_entry,
- tc_state_unattached_snk_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_attach_wait_snk_sig[] = {
- tc_state_attach_wait_snk_entry,
- tc_state_attach_wait_snk_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_attached_snk_sig[] = {
- tc_state_attached_snk_entry,
- tc_state_attached_snk_run,
- tc_state_attached_snk_exit,
- get_super_state
-};
-
-static const state_sig tc_state_try_snk_sig[] = {
- tc_state_try_snk_entry,
- tc_state_try_snk_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_unattached_src_sig[] = {
- tc_state_unattached_src_entry,
- tc_state_unattached_src_run,
- do_nothing_exit,
- get_super_state
};
-static const state_sig tc_state_attach_wait_src_sig[] = {
- tc_state_attach_wait_src_entry,
- tc_state_attach_wait_src_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_try_wait_src_sig[] = {
- tc_state_try_wait_src_entry,
- tc_state_try_wait_src_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_attached_src_sig[] = {
- tc_state_attached_src_entry,
- tc_state_attached_src_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_ct_try_snk_sig[] = {
- tc_state_ct_try_snk_entry,
- tc_state_ct_try_snk_run,
- tc_state_ct_try_snk_exit,
- get_super_state
-};
-
-static const state_sig tc_state_ct_attach_wait_unsupported_sig[] = {
- tc_state_ct_attach_wait_unsupported_entry,
- tc_state_ct_attach_wait_unsupported_run,
- tc_state_ct_attach_wait_unsupported_exit,
- get_super_state
-};
-
-static const state_sig tc_state_ct_attached_unsupported_sig[] = {
- tc_state_ct_attached_unsupported_entry,
- tc_state_ct_attached_unsupported_run,
- tc_state_ct_attached_unsupported_exit,
- get_super_state
-};
-
-static const state_sig tc_state_ct_unattached_unsupported_sig[] = {
- tc_state_ct_unattached_unsupported_entry,
- tc_state_ct_unattached_unsupported_run,
- tc_state_ct_unattached_unsupported_exit,
- get_super_state
-};
-
-static const state_sig tc_state_ct_unattached_vpd_sig[] = {
- tc_state_ct_unattached_vpd_entry,
- tc_state_ct_unattached_vpd_run,
- tc_state_ct_unattached_vpd_exit,
- get_super_state
-};
-
-static const state_sig tc_state_ct_disabled_vpd_sig[] = {
- tc_state_ct_disabled_vpd_entry,
- tc_state_ct_disabled_vpd_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_ct_attached_vpd_sig[] = {
- tc_state_ct_attached_vpd_entry,
- tc_state_ct_attached_vpd_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_ct_attach_wait_vpd_sig[] = {
- tc_state_ct_attach_wait_vpd_entry,
- tc_state_ct_attach_wait_vpd_run,
- tc_state_ct_attach_wait_vpd_exit,
- get_super_state
-};
-
-static const state_sig tc_state_host_rard_ct_rd_sig[] = {
- tc_state_host_rard_ct_rd_entry,
- tc_state_host_rard_ct_rd_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_host_open_ct_open_sig[] = {
- tc_state_host_open_ct_open_entry,
- tc_state_host_open_ct_open_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_vbus_cc_iso_sig[] = {
- tc_state_vbus_cc_iso_entry,
- tc_state_vbus_cc_iso_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_host_rp3_ct_rd_sig[] = {
- tc_state_host_rp3_ct_rd_entry,
- tc_state_host_rp3_ct_rd_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_host_rp3_ct_rpu_sig[] = {
- tc_state_host_rp3_ct_rpu_entry,
- tc_state_host_rp3_ct_rpu_run,
- do_nothing_exit,
- get_super_state
-};
-
-static const state_sig tc_state_host_rpu_ct_rd_sig[] = {
- tc_state_host_rpu_ct_rd_entry,
- tc_state_host_rpu_ct_rd_run,
- do_nothing_exit,
- get_super_state
-};
-
-void tc_reset_support_timer(int port)
-{
- tc[port].support_timer_reset |= SUPPORT_TIMER_RESET_REQUEST;
-}
-
-static void tc_state_init(int port)
-{
- int res = 0;
- sm_state this_state;
-
- res = tc_restart_tcpc(port);
-
- CPRINTS("TCPC p%d init %s", port, res ? "failed" : "ready");
- this_state = res ? tc_state_disabled : PD_DEFAULT_STATE(port);
-
- init_state(port, TC_OBJ(port), this_state);
-
- /* Disable pd state machines */
- tc[port].pd_enable = 0;
- tc[port].evt_timeout = 10*MSEC;
- tc[port].power_role = PD_PLUG_CABLE_VPD;
- tc[port].data_role = 0; /* Reserved for VPD */
- tc[port].billboard_presented = 0;
- tc[port].flags = 0;
-}
-
-static void tc_event_check(int port, int evt)
-{
- /* Do Nothing */
-}
-
-/**
- * Disabled
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Remove the terminations from Host
- * Remove the terminations from Charge-Through
- */
-static unsigned int tc_state_disabled(int port, enum signal sig)
-{
- int ret = 0;
-
- ret = (*tc_state_disabled_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_open_ct_open);
-}
-
-static unsigned int tc_state_disabled_entry(int port)
-{
- tc[port].state_id = DISABLED;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
- return 0;
-}
-
-static unsigned int tc_state_disabled_run(int port)
-{
- task_wait_event(-1);
- return RUN_SUPER;
-}
-
-static unsigned int tc_state_disabled_exit(int port)
-{
-#ifndef CONFIG_USB_PD_TCPC
- if (tc_restart_tcpc(port) != 0) {
- CPRINTS("TCPC p%d restart failed!", port);
- return 0;
- }
-#endif
- CPRINTS("TCPC p%d resumed!", port);
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
-
- return 0;
-}
-
-/**
- * ErrorRecovery
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Remove the terminations from Host
- * Remove the terminations from Charge-Through
- */
-static unsigned int tc_state_error_recovery(int port, enum signal sig)
-{
- int ret = 0;
-
- ret = (*tc_state_error_recovery_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_open_ct_open);
-}
-
-static unsigned int tc_state_error_recovery_entry(int port)
-{
- tc[port].state_id = ERROR_RECOVERY;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
- /* Use cc_debounce state variable for error recovery timeout */
- tc[port].cc_debounce = get_time().val + PD_T_ERROR_RECOVERY;
- return 0;
-}
-
-static unsigned int tc_state_error_recovery_run(int port)
-{
- if (get_time().val > tc[port].cc_debounce) {
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
- return 0;
- }
-
- return RUN_SUPER;
-}
-
-/**
- * Unattached.SNK
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place Ra on VCONN and Rd on Host CC
- * Place Rd on Charge-Through CCs
- */
-static unsigned int tc_state_unattached_snk(int port, enum signal sig)
-{
- int ret = 0;
-
- ret = (*tc_state_unattached_snk_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rard_ct_rd);
-}
-
-static unsigned int tc_state_unattached_snk_entry(int port)
-{
- tc[port].state_id = UNATTACHED_SNK;
- if (tc[port].obj.last_state != tc_state_unattached_src)
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- tc[port].flags &= ~TC_FLAGS_VCONN_ON;
- tc[port].cc_state = PD_CC_UNSET;
-
- return 0;
-}
-
-static unsigned int tc_state_unattached_snk_run(int port)
-{
- int host_cc;
- int new_cc_state;
- int cc1;
- int cc2;
-
- /* Check Host CC for connection */
- vpd_host_get_cc(&host_cc);
-
- /*
- * Transition to AttachWait.SNK when a Source connection is
- * detected, as indicated by the SNK.Rp state on its Host-side
- * port’s CC pin.
- */
- if (cc_is_rp(host_cc)) {
- set_state(port, TC_OBJ(port), tc_state_attach_wait_snk);
- return 0;
- }
-
- /* Check Charge-Through CCs for connection */
- vpd_ct_get_cc(&cc1, &cc2);
-
- if (cc_is_rp(cc1) != cc_is_rp(cc2))
- new_cc_state = PD_CC_DFP_ATTACHED;
- else
- new_cc_state = PD_CC_NONE;
-
- /* Debounce Charge-Through 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;
- }
-
- /* If we are here, Host CC must be open */
-
- /* Wait for Charge-Through CC debounce */
- if (get_time().val < tc[port].cc_debounce)
- return 0;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * Unattached.SRC when the state of the Host-side port’s CC pin is
- * SNK.Open for tDRP − dcSRC.DRP ∙ tDRP and both of the following
- * is detected on the Charge-Through port.
- * 1) SNK.Rp state is detected on exactly one of the CC1 or CC2
- * pins for at least tCCDebounce
- * 2) VBUS is detected
- */
- if (vpd_is_ct_vbus_present() &&
- tc[port].cc_state == PD_CC_DFP_ATTACHED) {
- set_state(port, TC_OBJ(port), tc_state_unattached_src);
- return 0;
- }
-
- return RUN_SUPER;
-}
-
-/**
- * AttachWait.SNK
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place Ra on VCONN and Rd on Host CC
- * Place Rd on Charge-Through CCs
- */
-static unsigned int tc_state_attach_wait_snk(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_attach_wait_snk_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rard_ct_rd);
-}
-
-static unsigned int tc_state_attach_wait_snk_entry(int port)
-{
- tc[port].state_id = ATTACH_WAIT_SNK;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
- tc[port].host_cc_state = PD_CC_UNSET;
-
- return 0;
-}
-
-static unsigned int tc_state_attach_wait_snk_run(int port)
-{
- int host_new_cc_state;
- int host_cc;
-
- /* Check Host CC for connection */
- vpd_host_get_cc(&host_cc);
-
- if (cc_is_rp(host_cc))
- host_new_cc_state = PD_CC_DFP_ATTACHED;
- else
- host_new_cc_state = PD_CC_NONE;
-
- /* Debounce the Host CC state */
- if (tc[port].host_cc_state != host_new_cc_state) {
- tc[port].host_cc_state = host_new_cc_state;
- if (host_new_cc_state == PD_CC_DFP_ATTACHED)
- tc[port].host_cc_debounce = get_time().val +
- PD_T_CC_DEBOUNCE;
- else
- tc[port].host_cc_debounce = get_time().val +
- PD_T_PD_DEBOUNCE;
- return 0;
- }
-
- /* Wait for Host CC debounce */
- if (get_time().val < tc[port].host_cc_debounce)
- return 0;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * Attached.SNK after the state of the Host-side port’s CC pin is
- * SNK.Rp for at least tCCDebounce and either host-side VCONN or
- * VBUS is detected.
- *
- * Transition to Unattached.SNK when the state of both the CC1 and
- * CC2 pins is SNK.Open for at least tPDDebounce.
- */
- if (tc[port].host_cc_state == PD_CC_DFP_ATTACHED &&
- (vpd_is_vconn_present() || vpd_is_host_vbus_present()))
- set_state(port, TC_OBJ(port), tc_state_attached_snk);
- else if (tc[port].host_cc_state == PD_CC_NONE)
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
-
- return 0;
-}
-
-/**
- * Attached.SNK
- */
-static unsigned int tc_state_attached_snk(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_attached_snk_sig[sig])(port);
- return SUPER(ret, sig, 0);
-}
-
-static unsigned int tc_state_attached_snk_entry(int port)
-{
- tc[port].state_id = ATTACHED_SNK;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- set_polarity(port, 0);
-
- /*
- * This state can only be entered from states AttachWait.SNK
- * and Try.SNK. So the Host port is isolated from the
- * Charge-Through port. We only need to High-Z the
- * Charge-Through ports CC1 and CC2 pins.
- */
- vpd_ct_set_pull(TYPEC_CC_OPEN, 0);
-
- tc[port].host_cc_state = PD_CC_UNSET;
-
- /* Start Charge-Through support timer */
- tc[port].support_timer_reset = SUPPORT_TIMER_RESET_INIT;
- tc[port].support_timer = get_time().val + PD_T_AME;
-
- /* Sample host CC every 2ms */
- tc_set_timeout(port, 2*MSEC);
-
- return 0;
-}
-
-static unsigned int tc_state_attached_snk_run(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()) {
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
- return 0;
- }
-
- /*
- * Reset the Charge-Through Support Timer when it first
- * receives any USB PD Structured VDM Command it supports,
- * which is the Discover Identity command. And this is only
- * done one time.
- */
- if (tc[port].support_timer_reset == SUPPORT_TIMER_RESET_REQUEST) {
- tc[port].support_timer_reset |= SUPPORT_TIMER_RESET_COMPLETE;
- tc[port].support_timer = get_time().val + PD_T_AME;
- }
-
- /* Check Host CC for connection */
- vpd_host_get_cc(&host_cc);
-
- if (cc_is_rp(host_cc))
- host_new_cc_state = PD_CC_DFP_ATTACHED;
- else
- host_new_cc_state = PD_CC_NONE;
-
- /* 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].host_cc_debounce = get_time().val + PD_T_VPDCTDD;
- return 0;
- }
-
- /* Wait for Host CC debounce */
- if (get_time().val < tc[port].host_cc_debounce)
- return 0;
-
- if (vpd_is_vconn_present()) {
- if (!(tc[port].flags & TC_FLAGS_VCONN_ON)) {
- /* VCONN detected. Remove RA */
- vpd_host_set_pull(TYPEC_CC_RD, 0);
- tc[port].flags |= TC_FLAGS_VCONN_ON;
- }
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition
- * 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) {
- set_state(port, TC_OBJ(port),
- tc_state_ct_unattached_vpd);
- return 0;
- }
- }
-
- /* Check the Support Timer */
- if (get_time().val > tc[port].support_timer &&
- !tc[port].billboard_presented) {
- /*
- * Present USB Billboard Device Class interface
- * indicating that Charge-Through is not supported
- */
- tc[port].billboard_presented = 1;
- vpd_present_billboard(BB_SNK);
- }
-
- return 0;
-}
-
-static unsigned int tc_state_attached_snk_exit(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 unsigned int tc_state_host_rard_ct_rd(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_host_rard_ct_rd_sig[sig])(port);
- return SUPER(ret, sig, tc_state_vbus_cc_iso);
-}
-
-static unsigned int tc_state_host_rard_ct_rd_entry(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;
-}
-
-static unsigned int tc_state_host_rard_ct_rd_run(int port)
-{
- return RUN_SUPER;
-}
-
-/**
- * Super State HOST_OPEN_CT_OPEN
- */
-static unsigned int tc_state_host_open_ct_open(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_host_open_ct_open_sig[sig])(port);
- return SUPER(ret, sig, tc_state_vbus_cc_iso);
-}
-
-static unsigned int tc_state_host_open_ct_open_entry(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;
-}
-
-static unsigned int tc_state_host_open_ct_open_run(int port)
-{
- return RUN_SUPER;
-}
-
-/**
- * Super State VBUS_CC_ISO
- */
-static unsigned int tc_state_vbus_cc_iso(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_vbus_cc_iso_sig[sig])(port);
- return SUPER(ret, sig, 0);
-}
-
-static unsigned int tc_state_vbus_cc_iso_entry(int port)
-{
- /* Isolate the Host-side port from the Charge-Through port */
- vpd_vbus_pass_en(0);
-
- /* Remove Charge-Through side port CCs */
- vpd_ct_cc_sel(CT_OPEN);
-
- /* Enable mcu communication and cc */
- vpd_mcu_cc_en(1);
-
- return 0;
-}
-
-static unsigned int tc_state_vbus_cc_iso_run(int port)
-{
- return 0;
-}
-
-/**
- * Unattached.SRC
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place RpUSB on Host CC
- * Place Rd on Charge-Through CCs
- */
-static unsigned int tc_state_unattached_src(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_unattached_src_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rpu_ct_rd);
-}
-
-static unsigned int tc_state_unattached_src_entry(int port)
-{
- tc[port].state_id = UNATTACHED_SRC;
- if (tc[port].obj.last_state != tc_state_unattached_snk)
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* 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()) {
- set_state(port, TC_OBJ(port), tc_state_error_recovery);
- return 0;
- }
-
- tc[port].next_role_swap = get_time().val + PD_T_DRP_SRC;
-
- return 0;
-}
-
-static unsigned int tc_state_unattached_src_run(int port)
-{
- int host_cc;
-
- /* Check Host CC for connection */
- vpd_host_get_cc(&host_cc);
-
- /*
- * Transition to AttachWait.SRC when host-side VBUS is
- * 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) {
- set_state(port, TC_OBJ(port), tc_state_attach_wait_src);
- return 0;
- }
-
- /*
- * 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) {
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
- return 0;
- }
-
- return RUN_SUPER;
-}
-
-/**
- * AttachWait.SRC
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place RpUSB on Host CC
- * Place Rd on Charge-Through CCs
- */
-static unsigned int tc_state_attach_wait_src(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_attach_wait_src_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rpu_ct_rd);
-}
-
-static unsigned int tc_state_attach_wait_src_entry(int port)
-{
- tc[port].state_id = ATTACH_WAIT_SRC;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- tc[port].host_cc_state = PD_CC_UNSET;
-
- return 0;
-}
-
-static unsigned int tc_state_attach_wait_src_run(int port)
-{
- int host_new_cc_state;
- int host_cc;
-
- /* Check Host CC for connection */
- vpd_host_get_cc(&host_cc);
-
- if (host_cc == TYPEC_CC_VOLT_RD)
- host_new_cc_state = PD_CC_UFP_ATTACHED;
- else
- host_new_cc_state = PD_CC_NONE;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition
- * to Unattached.SNK when the SRC.Open state is detected on the
- * Host-side port’s CC or if Charge-Through VBUS falls below
- * vSinkDisconnect. The Charge-Through VCONN-Powered USB Device
- * 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()) {
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
- return 0;
- }
-
- /* 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;
- }
-
- /* Wait for Host CC debounce */
- if (get_time().val < tc[port].cc_debounce)
- return 0;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * Try.SNK when the host-side VBUS is at vSafe0V and the SRC.Rd
- * 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()) {
- set_state(port, TC_OBJ(port), tc_state_try_snk);
- return 0;
- }
-
- return RUN_SUPER;
-}
-
-/**
- * Attached.SRC
- */
-static unsigned int tc_state_attached_src(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_attached_src_sig[sig])(port);
- return SUPER(ret, sig, 0);
-}
-
-static unsigned int tc_state_attached_src_entry(int port)
-{
- tc[port].state_id = ATTACHED_SRC;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- set_polarity(port, 0);
-
- /* Connect Charge-Through VBUS to Host VBUS */
- vpd_vbus_pass_en(1);
-
- /*
- * Get power from VBUS. No need to test because
- * the Host VBUS is connected to the Charge-Through
- * VBUS
- */
- vpd_vconn_pwr_sel_odl(PWR_VBUS);
-
- return 0;
-}
-
-static unsigned int tc_state_attached_src_run(int port)
-{
- int host_cc;
-
- /* Check Host CC for connection */
- vpd_host_get_cc(&host_cc);
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * Unattached.SNK when VBUS falls below vSinkDisconnect or the
- * Host-side port’s CC pin is SRC.Open. The Charge-Through
- * VCONNPowered USB Device shall detect the SRC.Open state within
- * tSRCDisconnect, but should detect it as quickly as possible.
- */
- if (!vpd_is_ct_vbus_present() || host_cc == TYPEC_CC_VOLT_OPEN)
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
-
- return 0;
-}
-
-/**
- * Super State HOST_RPU_CT_RD
- */
-static unsigned int tc_state_host_rpu_ct_rd(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_host_rpu_ct_rd_sig[sig])(port);
- return SUPER(ret, sig, tc_state_vbus_cc_iso);
-}
-
-static unsigned int tc_state_host_rpu_ct_rd_entry(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;
-}
-
-static unsigned int tc_state_host_rpu_ct_rd_run(int port)
-{
- return RUN_SUPER;
-}
-
-/**
- * Try.SNK
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place Ra on VCONN and Rd on Host CC
- * Place Rd on Charge-Through CCs
- */
-static unsigned int tc_state_try_snk(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_try_snk_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rard_ct_rd);
-}
-
-static unsigned int tc_state_try_snk_entry(int port)
-{
- tc[port].state_id = TRY_SNK;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* 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()) {
- set_state(port, TC_OBJ(port), tc_state_error_recovery);
- return 0;
- }
-
- 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 unsigned int tc_state_try_snk_run(int port)
-{
- int host_new_cc_state;
- int host_cc;
-
- /*
- * Wait for tDRPTry before monitoring the Charge-Through
- * port’s CC pins for the SNK.Rp
- */
- if (get_time().val < tc[port].next_role_swap)
- return 0;
-
- /* Check Host CC for connection */
- vpd_host_get_cc(&host_cc);
-
- if (cc_is_rp(host_cc))
- host_new_cc_state = PD_CC_DFP_ATTACHED;
- else
- host_new_cc_state = PD_CC_NONE;
-
- /* 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_DEBOUNCE;
- return 0;
- }
-
- /* Wait for Host CC debounce */
- if (get_time().val < tc[port].cc_debounce)
- return 0;
-
- /*
- * The Charge-Through VCONN-Powered USB Device shall then transition to
- * Attached.SNK when the SNK.Rp state is detected on the Host-side
- * port’s CC pin for at least tTryCCDebounce and VBUS or VCONN is
- * detected on Host-side port.
- *
- * Alternatively, the Charge-Through VCONN-Powered USB Device shall
- * transition to TryWait.SRC if Host-side SNK.Rp state is not detected
- * for tTryCCDebounce.
- */
- if (tc[port].host_cc_state == PD_CC_DFP_ATTACHED &&
- (vpd_is_host_vbus_present() || vpd_is_vconn_present()))
- set_state(port, TC_OBJ(port), tc_state_attached_snk);
- else if (tc[port].host_cc_state == PD_CC_NONE)
- set_state(port, TC_OBJ(port), tc_state_try_wait_src);
-
- return 0;
-}
-
-/**
- * TryWait.SRC
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place RpUSB on Host CC
- * Place Rd on Charge-Through CCs
- */
-static unsigned int tc_state_try_wait_src(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_try_wait_src_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rpu_ct_rd);
-}
-
-static unsigned int tc_state_try_wait_src_entry(int port)
-{
- tc[port].state_id = TRY_WAIT_SRC;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- tc[port].host_cc_state = PD_CC_UNSET;
- tc[port].next_role_swap = get_time().val + PD_T_DRP_TRY;
-
- return 0;
-}
-
-static unsigned int tc_state_try_wait_src_run(int port)
-{
- int host_new_cc_state;
- int host_cc;
-
- /* Check Host CC for connection */
- vpd_host_get_cc(&host_cc);
-
- if (host_cc == TYPEC_CC_VOLT_RD)
- host_new_cc_state = PD_CC_UFP_ATTACHED;
- else
- host_new_cc_state = PD_CC_NONE;
-
- /* 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].host_cc_debounce =
- get_time().val + PD_T_TRY_CC_DEBOUNCE;
- return 0;
- }
-
- if (get_time().val > tc[port].host_cc_debounce) {
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition
- * to Attached.SRC when host-side VBUS is at vSafe0V and the
- * SRC.Rd state is detected on the Host-side port’s CC pin for
- * at least tTryCCDebounce.
- */
- if (tc[port].host_cc_state == PD_CC_UFP_ATTACHED &&
- !vpd_is_host_vbus_present()) {
- set_state(port, TC_OBJ(port), tc_state_attached_src);
- return 0;
- }
- }
-
- if (get_time().val > tc[port].next_role_swap) {
- /*
- * The Charge-Through VCONN-Powered USB Device shall transition
- * 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) {
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
- return 0;
- }
- }
-
- return RUN_SUPER;
-}
-
-/**
- * CTTry.SNK
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place RP3A0 on Host CC
- * Connect Charge-Through Rd
- * Get power from VCONN
- */
-static unsigned int tc_state_ct_try_snk(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_ct_try_snk_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rp3_ct_rd);
-}
-
-static unsigned int tc_state_ct_try_snk_entry(int port)
-{
- tc[port].state_id = CTTRY_SNK;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- set_polarity(port, 0);
-
- tc[port].cc_state = PD_CC_UNSET;
- tc[port].next_role_swap = get_time().val + PD_T_DRP_TRY;
-
- return 0;
-}
-
-static unsigned int tc_state_ct_try_snk_run(int port)
-{
- int new_cc_state;
- int cc1;
- int cc2;
-
- /*
- * Wait for tDRPTry before monitoring the Charge-Through
- * port’s CC pins for the SNK.Rp
- */
- if (get_time().val < tc[port].next_role_swap)
- return 0;
-
- /* Check CT CC for connection */
- vpd_ct_get_cc(&cc1, &cc2);
-
- if (cc_is_rp(cc1) || cc_is_rp(cc2))
- new_cc_state = PD_CC_DFP_ATTACHED;
- else
- new_cc_state = PD_CC_NONE;
-
- /*
- * The Charge-Through VCONN-Powered USB Device shall transition
- * to Unattached.SNK if VCONN falls below vVCONNDisconnect.
- */
- if (!vpd_is_vconn_present()) {
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
- return 0;
- }
-
- /* Debounce the CT 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_DEBOUNCE;
- tc[port].try_wait_debounce = get_time().val + PD_T_TRY_WAIT;
-
- return 0;
- }
-
- if (get_time().val > tc[port].cc_debounce) {
- /*
- * The Charge-Through VCONN-Powered USB Device shall then
- * transition to CTAttached.VPD when the SNK.Rp state is
- * detected on the Charge-Through port’s CC pins for at
- * least tTryCCDebounce and VBUS is detected on
- * Charge-Through port.
- */
- if (tc[port].cc_state == PD_CC_DFP_ATTACHED &&
- vpd_is_ct_vbus_present()) {
- set_state(port, TC_OBJ(port), tc_state_ct_attached_vpd);
- return 0;
- }
- }
-
- if (get_time().val > tc[port].try_wait_debounce) {
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition
- * to CTAttached.Unsupported if SNK.Rp state is not detected
- * for tDRPTryWait.
- */
- if (tc[port].cc_state == PD_CC_NONE) {
- set_state(port, TC_OBJ(port),
- tc_state_ct_attached_unsupported);
- return 0;
- }
- }
-
- return RUN_SUPER;
-}
-
-static unsigned int tc_state_ct_try_snk_exit(int port)
-{
- /* Disable PD */
- tc[port].pd_enable = 0;
-
- return 0;
-}
-
-/**
- * CTAttachWait.Unsupported
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place RP3A0 on Host CC
- * Place RPUSB on Charge-Through CC
- * Get power from VCONN
- */
-static unsigned int
- tc_state_ct_attach_wait_unsupported(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_ct_attach_wait_unsupported_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rp3_ct_rpu);
-}
-
-static unsigned int tc_state_ct_attach_wait_unsupported_entry(int port)
-{
- tc[port].state_id = CTATTACH_WAIT_UNSUPPORTED;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- set_polarity(port, 0);
-
- tc[port].cc_state = PD_CC_UNSET;
-
- return 0;
-}
-
-static unsigned int tc_state_ct_attach_wait_unsupported_run(int port)
-{
- int new_cc_state;
- int cc1;
- int cc2;
-
- /* Check CT CC for connection */
- vpd_ct_get_cc(&cc1, &cc2);
-
- if (cc_is_at_least_one_rd(cc1, cc2))
- new_cc_state = PD_CC_DFP_ATTACHED;
- else if (cc_is_audio_acc(cc1, cc2))
- new_cc_state = PD_CC_AUDIO_ACC;
- else /* (cc1 == TYPEC_CC_VOLT_OPEN or cc2 == TYPEC_CC_VOLT_OPEN */
- new_cc_state = PD_CC_NONE;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * Unattached.SNK if VCONN falls below vVCONNDisconnect.
- */
- if (!vpd_is_vconn_present()) {
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
- return 0;
- }
-
- /* 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;
- }
-
- /* Wait for CC debounce */
- if (get_time().val < tc[port].cc_debounce)
- return 0;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * CTUnattached.VPD when the state of either the Charge-Through
- * Port’s CC1 or CC2 pin is SRC.Open for at least tCCDebounce.
- *
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * CTTry.SNK if the state of at least one of the Charge-Through
- * port’s CC pins is SRC.Rd, or if the state of both the CC1 and CC2
- * pins is SRC.Ra. for at least tCCDebounce.
- */
- if (new_cc_state == PD_CC_NONE)
- set_state(port, TC_OBJ(port), tc_state_ct_unattached_vpd);
- else /* PD_CC_DFP_ATTACHED or PD_CC_AUDIO_ACC */
- set_state(port, TC_OBJ(port), tc_state_ct_try_snk);
-
- return 0;
-}
-
-static unsigned int tc_state_ct_attach_wait_unsupported_exit(int port)
-{
- /* Disable PD */
- tc[port].pd_enable = 0;
-
- return 0;
-}
-
-/**
- * CTAttached.Unsupported
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place RP3A0 on Host CC
- * Place RPUSB on Charge-Through CC
- * Get power from VCONN
- */
-static unsigned int tc_state_ct_attached_unsupported(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_ct_attached_unsupported_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rp3_ct_rpu);
-}
-
-static unsigned int tc_state_ct_attached_unsupported_entry(int port)
-{
- tc[port].state_id = CTATTACHED_UNSUPPORTED;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* Present Billboard device */
- vpd_present_billboard(BB_SNK);
-
- return 0;
-}
-
-static unsigned int tc_state_ct_attached_unsupported_run(int port)
-{
- int cc1;
- int cc2;
-
- /* Check CT CC for connection */
- vpd_ct_get_cc(&cc1, &cc2);
-
- if (!vpd_is_vconn_present()) {
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
- return 0;
- }
-
- /*
- * The Charge-Through VCONN-Powered USB Device shall transition to
- * CTUnattached.VPD when SRC.Open state is detected on both the
- * Charge-Through port’s CC pins or the SRC.Open state is detected
- * on one CC pin and SRC.Ra is detected on the other CC pin.
- */
- 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)) {
- set_state(port, TC_OBJ(port), tc_state_ct_unattached_vpd);
- return 0;
- }
-
- return RUN_SUPER;
-}
-
-static unsigned int tc_state_ct_attached_unsupported_exit(int port)
-{
- vpd_present_billboard(BB_NONE);
-
- return 0;
-}
-
-/**
- * CTUnattached.Unsupported
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place RP3A0 on Host CC
- * Place RPUSB on Charge-Through CC
- * Get power from VCONN
- */
-static unsigned int
- tc_state_ct_unattached_unsupported(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_ct_unattached_unsupported_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rp3_ct_rpu);
-}
-
-static unsigned int tc_state_ct_unattached_unsupported_entry(int port)
-{
- tc[port].state_id = CTUNATTACHED_UNSUPPORTED;
- if (tc[port].obj.last_state != tc_state_ct_unattached_vpd)
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* 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 unsigned int tc_state_ct_unattached_unsupported_run(int port)
-{
- int cc1;
- int cc2;
-
- /* Check CT CC for connection */
- vpd_ct_get_cc(&cc1, &cc2);
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * CTAttachWait.Unsupported when a Sink connection is detected on
- * the Charge-Through port, as indicated by the SRC.Rd state on at
- * 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)) {
- set_state(port, TC_OBJ(port),
- tc_state_ct_attach_wait_unsupported);
- return 0;
- }
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * Unattached.SNK if VCONN falls below vVCONNDisconnect.
- */
- if (!vpd_is_vconn_present()) {
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
- return 0;
- }
-
- /*
- * 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) {
- set_state(port, TC_OBJ(port), tc_state_ct_unattached_vpd);
- return 0;
- }
-
- return RUN_SUPER;
-}
-
-static unsigned int tc_state_ct_unattached_unsupported_exit(int port)
-{
- /* Disable PD */
- tc[port].pd_enable = 0;
-
- return 0;
-}
-
-/**
- * CTUnattached.VPD
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place RP3A0 on Host CC
- * Connect Charge-Through Rd
- * Get power from VCONN
- */
-static unsigned int tc_state_ct_unattached_vpd(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_ct_unattached_vpd_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rp3_ct_rd);
-}
-
-static unsigned int tc_state_ct_unattached_vpd_entry(int port)
-{
- tc[port].state_id = CTUNATTACHED_VPD;
- if (tc[port].obj.last_state != tc_state_ct_unattached_unsupported)
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- set_polarity(port, 0);
-
- tc[port].cc_state = PD_CC_UNSET;
-
- return 0;
-}
-
-static unsigned int tc_state_ct_unattached_vpd_run(int port)
-{
- int new_cc_state;
- int cc1;
- int cc2;
-
- /* Check CT CC for connection */
- vpd_ct_get_cc(&cc1, &cc2);
-
- if (cc_is_rp(cc1) != cc_is_rp(cc2))
- new_cc_state = PD_CC_DFP_ATTACHED;
- else if (!cc_is_rp(cc1) && !cc_is_rp(cc2))
- new_cc_state = PD_CC_NONE;
- else
- new_cc_state = PD_CC_UNSET;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * CTAttachWait.VPD when a Source connection is detected on the
- * 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) {
- set_state(port, TC_OBJ(port),
- tc_state_ct_attach_wait_vpd);
- return 0;
- }
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * Unattached.SNK if VCONN falls below vVCONNDisconnect.
- */
- if (!vpd_is_vconn_present()) {
- set_state(port, TC_OBJ(port),
- tc_state_unattached_snk);
- return 0;
- }
-
- /* 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;
- }
-
- if (get_time().val < tc[port].cc_debounce)
- return 0;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * CTUnattached.Unsupported within tDRPTransition after the state
- * 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) {
- set_state(port, TC_OBJ(port),
- tc_state_ct_unattached_unsupported);
- return 0;
- }
-
- return RUN_SUPER;
-}
-
-static unsigned int tc_state_ct_unattached_vpd_exit(int port)
-{
- /* Disable PD */
- tc[port].pd_enable = 0;
-
- return 0;
-}
-
-/**
- * CTDisabled.VPD
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Remove the terminations from Host
- * Remove the terminations from Charge-Through
- */
-static unsigned int tc_state_ct_disabled_vpd(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_ct_disabled_vpd_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_open_ct_open);
-}
-
-static unsigned int tc_state_ct_disabled_vpd_entry(int port)
-{
- tc[port].state_id = CTDISABLED_VPD;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* 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 unsigned int tc_state_ct_disabled_vpd_run(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)
- set_state(port, TC_OBJ(port), tc_state_unattached_snk);
-
- return 0;
-}
-
-/**
- * CTAttached.VPD
- */
-static unsigned int tc_state_ct_attached_vpd(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_ct_attached_vpd_sig[sig])(port);
- return SUPER(ret, sig, 0);
-}
-
-static unsigned int tc_state_ct_attached_vpd_entry(int port)
-{
- int cc1;
- int cc2;
-
- tc[port].state_id = CTATTACHED_VPD;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* Get power from VCONN */
- vpd_vconn_pwr_sel_odl(PWR_VCONN);
-
- /*
- * Detect which of the Charge-Through port’s CC1 or CC2
- * pins is connected through the cable
- */
- vpd_ct_get_cc(&cc1, &cc2);
- tc[port].ct_cc = cc_is_rp(cc2) ? CT_CC2 : CT_CC1;
-
- /*
- * 1. Remove or reduce any additional capacitance on the
- * Host-side CC port
- */
- vpd_mcu_cc_en(0);
-
- /*
- * 2. Disable the Rp termination advertising 3.0 A on the
- * host port’s CC pin
- */
- vpd_host_set_pull(TYPEC_CC_OPEN, 0);
-
- /*
- * 3. Passively multiplex the detected Charge-Through port’s
- * CC pin through to the host port’s CC
- */
- vpd_ct_cc_sel(tc[port].ct_cc);
-
- /*
- * 4. Disable the Rd on the Charge-Through port’s CC1 and CC2
- * pins
- */
- vpd_ct_set_pull(TYPEC_CC_OPEN, 0);
-
- /*
- * 5. Connect the Charge-Through port’s VBUS through to the
- * host port’s VBUS
- */
- vpd_vbus_pass_en(1);
-
- tc[port].cc_state = PD_CC_UNSET;
-
- return 0;
-}
-
-static unsigned int tc_state_ct_attached_vpd_run(int port)
-{
- int new_cc_state;
- int cc1;
- int cc2;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * CTDisabled.VPD if VCONN falls below vVCONNDisconnect.
- */
- if (!vpd_is_vconn_present()) {
- set_state(port, TC_OBJ(port), tc_state_ct_disabled_vpd);
- return 0;
- }
-
- /* Check CT CC for connection */
- vpd_ct_get_cc(&cc1, &cc2);
- if ((tc[port].ct_cc ? cc2 : cc1) == TYPEC_CC_VOLT_OPEN)
- new_cc_state = PD_CC_NONE;
- else
- new_cc_state = PD_CC_DFP_ATTACHED;
-
- /* 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_VPDCTDD;
- return 0;
- }
-
- if (get_time().val < tc[port].pd_debounce)
- return 0;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * CTUnattached.VPD when VBUS falls below vSinkDisconnect and the
- * 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())
- set_state(port, TC_OBJ(port), tc_state_ct_unattached_vpd);
-
- return 0;
-}
-
-/**
- * CTAttachWait.VPD
- *
- * Super State Entry Actions:
- * Isolate the Host-side port from the Charge-Through port
- * Enable mcu communication
- * Place RP3A0 on Host CC
- * Connect Charge-Through Rd
- * Get power from VCONN
- */
-static unsigned int tc_state_ct_attach_wait_vpd(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_ct_attach_wait_vpd_sig[sig])(port);
- return SUPER(ret, sig, tc_state_host_rp3_ct_rd);
-}
-
-static unsigned int tc_state_ct_attach_wait_vpd_entry(int port)
-{
- tc[port].state_id = CTATTACH_WAIT_VPD;
- CPRINTS("C%d: %s", port, tc_state_names[tc[port].state_id]);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- set_polarity(port, 0);
-
- tc[port].cc_state = PD_CC_UNSET;
-
- /* Sample CCs every 2ms */
- tc_set_timeout(port, 2 * MSEC);
- return 0;
-}
-
-static unsigned int tc_state_ct_attach_wait_vpd_run(int port)
-{
- int new_cc_state;
- int cc1;
- int cc2;
-
- /* Check CT CC for connection */
- vpd_ct_get_cc(&cc1, &cc2);
-
- if (cc_is_rp(cc1) != cc_is_rp(cc2))
- new_cc_state = PD_CC_DFP_ATTACHED;
- else if (!cc_is_rp(cc1) && !cc_is_rp(cc2))
- new_cc_state = PD_CC_NONE;
- else
- new_cc_state = PD_CC_UNSET;
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * CTDisabled.VPD if VCONN falls below vVCONNDisconnect.
- */
- if (!vpd_is_vconn_present()) {
- set_state(port, TC_OBJ(port), tc_state_ct_disabled_vpd);
- return 0;
- }
-
- /* 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_CC_DEBOUNCE;
- tc[port].pd_debounce = get_time().val +
- PD_T_PD_DEBOUNCE;
- return 0;
- }
-
- if (get_time().val > tc[port].pd_debounce) {
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition
- * to CTUnattached.VPD when the state of both the Charge-Through
- * port’s CC1 and CC2 pins are SNK.Open for at least
- * tPDDebounce.
- */
- if (tc[port].cc_state == PD_CC_NONE) {
- set_state(port, TC_OBJ(port),
- tc_state_ct_unattached_vpd);
- return 0;
- }
- }
-
- if (get_time().val > tc[port].cc_debounce) {
- /*
- * A Charge-Through VCONN-Powered USB Device shall transition to
- * CTAttached.VPD after the state of only one of the
- * Charge-Through port’s CC1 or CC2 pins is SNK.Rp for at
- * least tCCDebounce and VBUS on the Charge-Through port is
- * detected.
- */
- if (tc[port].cc_state == PD_CC_DFP_ATTACHED &&
- vpd_is_ct_vbus_present()) {
- set_state(port, TC_OBJ(port), tc_state_ct_attached_vpd);
- return 0;
- }
- }
-
- return RUN_SUPER;
-}
-
-static unsigned int tc_state_ct_attach_wait_vpd_exit(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 unsigned int tc_state_host_rp3_ct_rd(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_host_rp3_ct_rd_sig[sig])(port);
-
- return SUPER(ret, sig, tc_state_vbus_cc_iso);
-}
-
-static unsigned int tc_state_host_rp3_ct_rd_entry(int port)
-{
- /* Place RP3A0 on Host CC */
- vpd_host_set_pull(TYPEC_CC_RP, TYPEC_RP_3A0);
-
- /* Connect Charge-Through Rd */
- vpd_ct_set_pull(TYPEC_CC_RD, 0);
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall
- * ensure that it is powered by VCONN
- */
-
- /* Make sure vconn is on */
- if (!vpd_is_vconn_present())
- set_state(port, TC_OBJ(port), tc_state_error_recovery);
-
- /* Get power from VCONN */
- vpd_vconn_pwr_sel_odl(PWR_VCONN);
-
- return 0;
-}
-
-static unsigned int tc_state_host_rp3_ct_rd_run(int port)
-{
- return 0;
-}
-
-/**
- * Super State HOST_RP3_CT_RPU
- */
-static unsigned int tc_state_host_rp3_ct_rpu(int port, enum signal sig)
-{
- int ret;
-
- ret = (*tc_state_host_rp3_ct_rpu_sig[sig])(port);
- return SUPER(ret, sig, tc_state_vbus_cc_iso);
-}
-
-static unsigned int tc_state_host_rp3_ct_rpu_entry(int port)
-{
- /* Place RP3A0 on Host CC */
- vpd_host_set_pull(TYPEC_CC_RP, TYPEC_RP_3A0);
-
- /* Place RPUSB on Charge-Through CC */
- vpd_ct_set_pull(TYPEC_CC_RP, TYPEC_RP_USB);
-
- /*
- * A Charge-Through VCONN-Powered USB Device shall
- * ensure that it is powered by VCONN
- */
-
- /* Make sure vconn is on */
- if (!vpd_is_vconn_present())
- set_state(port, TC_OBJ(port), tc_state_error_recovery);
-
- /* Get power from VCONN */
- vpd_vconn_pwr_sel_odl(PWR_VCONN);
-
- return 0;
-}
-
-static unsigned int tc_state_host_rp3_ct_rpu_run(int port)
-{
- return 0;
-}
-
-static unsigned int do_nothing_exit(int port)
-{
- return 0;
-}
-
-static unsigned int get_super_state(int port)
-{
- return RUN_SUPER;
-}
+extern struct type_c tc[];
-#endif /* CONFIG_USB_TYPEC_CTVPD */
+#endif /* __CROS_EC_USB_TC_CTVPD_SM_H */