summaryrefslogtreecommitdiff
path: root/common/usbc/usb_tc_ctvpd_sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/usbc/usb_tc_ctvpd_sm.c')
-rw-r--r--common/usbc/usb_tc_ctvpd_sm.c1716
1 files changed, 0 insertions, 1716 deletions
diff --git a/common/usbc/usb_tc_ctvpd_sm.c b/common/usbc/usb_tc_ctvpd_sm.c
deleted file mode 100644
index a2babe754a..0000000000
--- a/common/usbc/usb_tc_ctvpd_sm.c
+++ /dev/null
@@ -1,1716 +0,0 @@
-/* Copyright 2019 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "common.h"
-#include "console.h"
-#include "system.h"
-#include "task.h"
-#include "tcpm/tcpm.h"
-#include "usb_pd.h"
-#include "usb_tc_sm.h"
-#include "vpd_api.h"
-
-/* USB Type-C CTVPD module */
-
-#ifdef CONFIG_COMMON_RUNTIME
-#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
-#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-#else /* CONFIG_COMMON_RUNTIME */
-#define CPRINTF(format, args...)
-#define CPRINTS(format, args...)
-#endif
-
-/* Type-C Layer Flags */
-#define TC_FLAGS_VCONN_ON BIT(0)
-
-#define SUPPORT_TIMER_RESET_INIT 0
-#define SUPPORT_TIMER_RESET_REQUEST 1
-#define SUPPORT_TIMER_RESET_COMPLETE 2
-
-/**
- * This is the Type-C Port object that contains information needed to
- * implement a Charge Through VCONN Powered Device.
- */
-static struct type_c {
- /* state machine context */
- struct sm_ctx ctx;
- /* Higher-level power deliver state machines are enabled if true. */
- uint8_t pd_enable;
- /* 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_MAX_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[];
-
-
-/* List of human readable state names for console debugging */
-__maybe_unused const char * const tc_state_names[] = {
-#ifdef CONFIG_COMMON_RUNTIME
- [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 */
-
-enum pd_power_role pd_get_power_role(int port)
-{
- /* Vconn power device is always the sink */
- return PD_ROLE_SINK;
-}
-
-enum pd_cable_plug tc_get_cable_plug(int port)
-{
- /* Vconn power device is always the cable */
- return PD_PLUG_FROM_CABLE;
-}
-
-enum pd_data_role pd_get_data_role(int port)
-{
- /* Vconn power device doesn't have a data role, but UFP matches SNK */
- return PD_ROLE_UFP;
-}
-
-/* Note tc_set_power_role and tc_set_data_role are unimplemented */
-
-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_reset_support_timer(int port)
-{
- tc[port].support_timer_reset |= SUPPORT_TIMER_RESET_REQUEST;
-}
-
-/*
- * TCPC CC/Rp management
- *
- * Stub for linking purposes.
- * This is not supported for ctvpd, we are never the SOP partner.
- */
-void typec_select_pull(int port, enum tcpc_cc_pull pull)
-{
-}
-void typec_select_src_current_limit_rp(int port, enum tcpc_rp_value rp)
-{
-}
-void typec_select_src_collision_rp(int port, enum tcpc_rp_value rp)
-{
-}
-int typec_update_cc(int port)
-{
- return EC_SUCCESS;
-}
-
-void tc_state_init(int port)
-{
- int res = 0;
-
- res = tcpm_init(port);
-
- CPRINTS("C%d: init %s", port, res ? "failed" : "ready");
-
- /* 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;
- tc[port].billboard_presented = 0;
- tc[port].flags = 0;
-}
-
-void tc_event_check(int port, int evt)
-{
- /* Do Nothing */
-}
-
-void tc_run(const int port)
-{
- run_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];
-}
-
-test_mockable_static void print_current_state(const int port)
-{
- CPRINTS("C%d: %s", port, tc_state_names[get_state_tc(port)]);
-}
-
-int pd_is_connected(int port)
-{
- return (get_state_tc(port) == TC_ATTACHED_SNK) ||
- (get_state_tc(port) == TC_ATTACHED_SRC) ||
- (get_state_tc(port) == TC_CT_ATTACHED_UNSUPPORTED) ||
- (get_state_tc(port) == TC_CT_ATTACHED_VPD);
-}
-
-bool pd_is_disconnected(int port)
-{
- return !pd_is_connected(port);
-}
-
-/**
- * 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 void tc_disabled_entry(const int port)
-{
- print_current_state(port);
-}
-
-static void tc_disabled_run(const int port)
-{
- task_wait_event(-1);
-}
-
-static void tc_disabled_exit(const int port)
-{
- if (!IS_ENABLED(CONFIG_USB_PD_TCPC)) {
- if (tcpm_init(port) != 0) {
- CPRINTS("C%d: restart failed!", port);
- return;
- }
- }
-
- CPRINTS("C%d: resumed!", port);
-}
-
-void pd_set_suspend(int port, int suspend)
-{
- /*
- * This shouldn't happen. If it does, we need to send an event to the
- * PD task to put the SM into the disabled state. It is not safe to
- * directly set_state here since this may be in another task.
- */
- assert(false);
-}
-
-/**
- * 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 void tc_error_recovery_entry(const int port)
-{
- print_current_state(port);
- /* Use cc_debounce state variable for error recovery timeout */
- tc[port].cc_debounce = get_time().val + PD_T_ERROR_RECOVERY;
-}
-
-static void tc_error_recovery_run(const int port)
-{
- if (get_time().val > tc[port].cc_debounce)
- set_state_tc(port, TC_UNATTACHED_SNK);
-}
-
-/**
- * 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 void tc_unattached_snk_entry(const int port)
-{
- 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;
-}
-
-static void tc_unattached_snk_run(const 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_tc(port, TC_ATTACH_WAIT_SNK);
- return;
- }
-
- /* 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;
-
- /*
- * 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_tc(port, TC_UNATTACHED_SRC);
- return;
- }
-}
-
-/**
- * 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 void tc_attach_wait_snk_entry(const int port)
-{
- print_current_state(port);
- tc[port].host_cc_state = PD_CC_UNSET;
-}
-
-static void tc_attach_wait_snk_run(const 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;
- }
-
- /* Wait for Host CC debounce */
- if (get_time().val < tc[port].host_cc_debounce)
- return;
-
- /*
- * 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_tc(port, TC_ATTACHED_SNK);
- else if (tc[port].host_cc_state == PD_CC_NONE)
- set_state_tc(port, TC_UNATTACHED_SNK);
-}
-
-/**
- * Attached.SNK
- */
-static void tc_attached_snk_entry(const int port)
-{
- print_current_state(port);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- pd_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;
-}
-
-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()) {
- set_state_tc(port, TC_UNATTACHED_SNK);
- return;
- }
-
- /*
- * 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;
- }
-
- /* Wait for Host CC debounce */
- if (get_time().val < tc[port].host_cc_debounce)
- return;
-
- 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_tc(port, TC_CT_UNATTACHED_VPD);
- return;
- }
- }
-
- /* 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);
- }
-}
-
-static void tc_attached_snk_exit(const int port)
-{
- tc[port].billboard_presented = 0;
- vpd_present_billboard(BB_NONE);
-}
-
-/**
- * Super State HOST_RA_CT_RD
- */
-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);
-}
-
-/**
- * Super State HOST_OPEN_CT_OPEN
- */
-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);
-}
-
-/**
- * Super State VBUS_CC_ISO
- */
-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);
-
- /* Remove Charge-Through side port CCs */
- vpd_ct_cc_sel(CT_OPEN);
-
- /* Enable mcu communication and cc */
- vpd_mcu_cc_en(1);
-}
-
-/**
- * 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 void tc_unattached_src_entry(const int port)
-{
- 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()) {
- set_state_tc(port, TC_ERROR_RECOVERY);
- return;
- }
-
- tc[port].next_role_swap = get_time().val + PD_T_DRP_SRC;
-}
-
-static void tc_unattached_src_run(const 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_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) {
- set_state_tc(port, TC_UNATTACHED_SNK);
- return;
- }
-}
-
-/**
- * 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 void tc_attach_wait_src_entry(const int port)
-{
- print_current_state(port);
-
- tc[port].host_cc_state = PD_CC_UNSET;
-}
-
-static void tc_attach_wait_src_run(const 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_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;
- }
-
- /* Wait for Host CC debounce */
- if (get_time().val < tc[port].cc_debounce)
- return;
-
- /*
- * 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_tc(port, TC_TRY_SNK);
- return;
- }
-}
-
-/**
- * Attached.SRC
- */
-static void tc_attached_src_entry(const int port)
-{
- print_current_state(port);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- pd_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);
-}
-
-static void tc_attached_src_run(const 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_tc(port, TC_UNATTACHED_SNK);
-}
-
-/**
- * Super State HOST_RPU_CT_RD
- */
-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);
-}
-
-/**
- * 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 void tc_try_snk_entry(const int port)
-{
- 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()) {
- 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;
-}
-
-static void tc_try_snk_run(const 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;
-
- /* 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;
- }
-
- /* Wait for Host CC debounce */
- if (get_time().val < tc[port].cc_debounce)
- return;
-
- /*
- * 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_tc(port, TC_ATTACHED_SNK);
- else if (tc[port].host_cc_state == PD_CC_NONE)
- set_state_tc(port, TC_TRY_WAIT_SRC);
-}
-
-/**
- * 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 void tc_try_wait_src_entry(const int port)
-{
- print_current_state(port);
-
- tc[port].host_cc_state = PD_CC_UNSET;
- tc[port].next_role_swap = get_time().val + PD_T_DRP_TRY;
-}
-
-static void tc_try_wait_src_run(const 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;
- }
-
- 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_tc(port, TC_ATTACHED_SRC);
- return;
- }
- }
-
- 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_tc(port, TC_UNATTACHED_SNK);
- return;
- }
- }
-}
-
-/**
- * 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 void tc_ct_try_snk_entry(const int port)
-{
- print_current_state(port);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- pd_set_polarity(port, 0);
-
- tc[port].cc_state = PD_CC_UNSET;
- tc[port].next_role_swap = get_time().val + PD_T_DRP_TRY;
-}
-
-static void tc_ct_try_snk_run(const 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;
-
- /* 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_tc(port, TC_UNATTACHED_SNK);
- return;
- }
-
- /* 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;
- }
-
- 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_tc(port, TC_CT_ATTACHED_VPD);
- return;
- }
- }
-
- 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_tc(port,
- TC_CT_ATTACHED_UNSUPPORTED);
- return;
- }
- }
-}
-
-static void tc_ct_try_snk_exit(const int port)
-{
- /* Disable PD */
- tc[port].pd_enable = 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 void tc_ct_attach_wait_unsupported_entry(const int port)
-{
- print_current_state(port);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- pd_set_polarity(port, 0);
-
- tc[port].cc_state = PD_CC_UNSET;
-}
-
-static void tc_ct_attach_wait_unsupported_run(const 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_UFP_ATTACHED;
- else if (cc_is_audio_acc(cc1, cc2))
- new_cc_state = PD_CC_UFP_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_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;
- }
-
- /* Wait for CC debounce */
- if (get_time().val < tc[port].cc_debounce)
- return;
-
- /*
- * 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_tc(port, TC_CT_UNATTACHED_VPD);
- else /* PD_CC_UFP_ATTACHED or PD_CC_UFP_AUDIO_ACC */
- set_state_tc(port, TC_CT_TRY_SNK);
-}
-
-static void tc_ct_attach_wait_unsupported_exit(const int port)
-{
- /* Disable PD */
- tc[port].pd_enable = 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 void tc_ct_attached_unsupported_entry(const int port)
-{
- print_current_state(port);
-
- /* Present Billboard device */
- vpd_present_billboard(BB_SNK);
-}
-
-static void tc_ct_attached_unsupported_run(const int port)
-{
- int cc1;
- int cc2;
-
- /* Check CT CC for connection */
- vpd_ct_get_cc(&cc1, &cc2);
-
- if (!vpd_is_vconn_present()) {
- set_state_tc(port, TC_UNATTACHED_SNK);
- return;
- }
-
- /*
- * 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_tc(port, TC_CT_UNATTACHED_VPD);
- return;
- }
-}
-
-static void tc_ct_attached_unsupported_exit(const int port)
-{
- vpd_present_billboard(BB_NONE);
-}
-
-/**
- * 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 void tc_ct_unattached_unsupported_entry(const int port)
-{
- if (get_last_state_tc(port) != TC_CT_UNATTACHED_VPD)
- print_current_state(port);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- pd_set_polarity(port, 0);
-
- tc[port].next_role_swap = get_time().val + PD_T_DRP_SRC;
-}
-
-static void tc_ct_unattached_unsupported_run(const 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_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()) {
- 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) {
- set_state_tc(port, TC_CT_UNATTACHED_VPD);
- return;
- }
-}
-
-static void tc_ct_unattached_unsupported_exit(const int port)
-{
- /* Disable PD */
- tc[port].pd_enable = 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 void tc_ct_unattached_vpd_entry(const int port)
-{
- if (get_last_state_tc(port) != TC_CT_UNATTACHED_UNSUPPORTED)
- print_current_state(port);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- pd_set_polarity(port, 0);
-
- tc[port].cc_state = PD_CC_UNSET;
-}
-
-static void tc_ct_unattached_vpd_run(const 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_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()) {
- 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;
- }
-
- if (get_time().val < tc[port].cc_debounce)
- return;
-
- /*
- * 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_tc(port, TC_CT_UNATTACHED_UNSUPPORTED);
- return;
- }
-}
-
-static void tc_ct_unattached_vpd_exit(const int port)
-{
- /* Disable PD */
- tc[port].pd_enable = 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 void tc_ct_disabled_vpd_entry(const int port)
-{
- 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;
-}
-
-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)
- set_state_tc(port, TC_UNATTACHED_SNK);
-}
-
-/**
- * CTAttached.VPD
- */
-static void tc_ct_attached_vpd_entry(const int port)
-{
- int cc1;
- int cc2;
- print_current_state(port);
-
- /* 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;
-}
-
-static void tc_ct_attached_vpd_run(const 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_tc(port, TC_CT_DISABLED_VPD);
- return;
- }
-
- /* 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;
- }
-
- if (get_time().val < tc[port].pd_debounce)
- return;
-
- /*
- * 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_tc(port, TC_CT_UNATTACHED_VPD);
-}
-
-/**
- * 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 void tc_ct_attach_wait_vpd_entry(const int port)
-{
- print_current_state(port);
-
- /* Enable PD */
- tc[port].pd_enable = 1;
- pd_set_polarity(port, 0);
-
- tc[port].cc_state = PD_CC_UNSET;
-}
-
-static void tc_ct_attach_wait_vpd_run(const 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_tc(port, TC_CT_DISABLED_VPD);
- 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_CC_DEBOUNCE;
- tc[port].pd_debounce = get_time().val +
- PD_T_PD_DEBOUNCE;
- return;
- }
-
- 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_tc(port, TC_CT_UNATTACHED_VPD);
- return;
- }
- }
-
- 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_tc(port, TC_CT_ATTACHED_VPD);
- return;
- }
- }
-}
-
-static void tc_ct_attach_wait_vpd_exit(const int port)
-{
- /* Disable PD */
- tc[port].pd_enable = 0;
-}
-
-/**
- * Super State HOST_RP3_CT_RD
- */
-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);
-
- /* 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_tc(port, TC_ERROR_RECOVERY);
-
- /* Get power from VCONN */
- vpd_vconn_pwr_sel_odl(PWR_VCONN);
-}
-
-/**
- * Super State HOST_RP3_CT_RPU
- */
-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);
-
- /* 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_tc(port, TC_ERROR_RECOVERY);
-
- /* Get power from VCONN */
- vpd_vconn_pwr_sel_odl(PWR_VCONN);
-}
-
-/* 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],
- },
-};
-
-#ifdef TEST_BUILD
-const struct test_sm_data test_tc_sm_data[] = {
- {
- .base = tc_states,
- .size = ARRAY_SIZE(tc_states),
- .names = tc_state_names,
- .names_size = ARRAY_SIZE(tc_state_names),
- },
-};
-const int test_tc_sm_data_size = ARRAY_SIZE(test_tc_sm_data);
-#endif