diff options
author | Vijay Hiremath <vijay.p.hiremath@intel.com> | 2020-02-03 21:34:18 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-06 20:43:06 +0000 |
commit | 1b886ec3bb3a8212ea0902956382b4fed503bfd9 (patch) | |
tree | 53dfa663ba1834c7bd40741bc3a55a8eada6d5db | |
parent | be915c8339500ce81ff2b9944ca5d1ecc6395455 (diff) | |
download | chrome-ec-1b886ec3bb3a8212ea0902956382b4fed503bfd9.tar.gz |
usb_pd: Move common alt mode DFP functions to it's file
BUG=b:148528713
BRANCH=none
TEST=make buildall -j
Change-Id: I5a9a70095940aa57408685584352e602b42b298e
Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2037133
Reviewed-by: Keith Short <keithshort@chromium.org>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
-rw-r--r-- | common/usb_common.c | 338 | ||||
-rw-r--r-- | common/usb_pd_alt_mode_dfp.c | 340 |
2 files changed, 340 insertions, 338 deletions
diff --git a/common/usb_common.c b/common/usb_common.c index 9ac17802d2..708d06404d 100644 --- a/common/usb_common.c +++ b/common/usb_common.c @@ -407,19 +407,6 @@ void pd_build_request(uint32_t src_cap_cnt, const uint32_t * const src_caps, } #endif -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -void notify_sysjump_ready(volatile const task_id_t * const sysjump_task_waiting) -{ - /* - * If event was set from pd_prepare_sysjump, wake the - * task waiting on us to complete. - */ - if (*sysjump_task_waiting != TASK_ID_INVALID) - task_set_event(*sysjump_task_waiting, - TASK_EVENT_SYSJUMP_READY, 0); -} -#endif - __attribute__((weak)) uint8_t board_get_usb_pd_port_count(void) { return CONFIG_USB_PD_PORT_MAX_COUNT; @@ -780,328 +767,3 @@ __overridable int pd_custom_vdm(int port, int cnt, uint32_t *payload, return 0; } - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -/* - * Before entering into alternate mode, state of the USB-C MUX - * needs to be in safe mode. - * Ref: USB Type-C Cable and Connector Specification - * Section E.2.2 Alternate Mode Electrical Requirements - */ -void usb_mux_set_safe_mode(int port) -{ - usb_mux_set(port, IS_ENABLED(CONFIG_USB_MUX_VIRTUAL) ? - USB_PD_MUX_SAFE_MODE : USB_PD_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); - - /* Isolate the SBU lines. */ - if (IS_ENABLED(CONFIG_USBC_PPC_SBU)) - ppc_set_sbu(port, 0); -} - -__overridable const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -__overridable void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - - usb_mux_set_safe_mode(port); -} - -__overridable int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* - * Don't enter the mode if the SoC is off. - * - * There's no need to enter the mode while the SoC is off; we'll - * actually enter the mode on the chipset resume hook. Entering DP Alt - * Mode twice will confuse some monitors and require and unplug/replug - * to get them to work again. The DP Alt Mode on USB-C spec says that - * if we don't need to maintain HPD connectivity info in a low power - * mode, then we shall exit DP Alt Mode. (This is why we don't enter - * when the SoC is off as opposed to suspend where adding a display - * could cause a wake up.) - */ - if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) - return -1; - - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - - if (IS_ENABLED(CONFIG_MKBP_EVENT) && - chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) - /* - * Wake the system up since we're entering DP AltMode. - */ - pd_notify_dp_alt_mode_entry(); - - return 0; - } - - return -1; -} - -__overridable int svdm_dp_status(int port, uint32_t *payload) -{ - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); - - payload[0] = VDO(USB_SID_DISPLAYPORT, 1, - CMD_DP_STATUS | VDO_OPOS(opos)); - payload[1] = VDO_DP_STATUS(0, /* HPD IRQ ... not applicable */ - 0, /* HPD level ... not applicable */ - 0, /* exit DP? ... no */ - 0, /* usb mode? ... no */ - 0, /* multi-function ... no */ - (!!(dp_flags[port] & DP_FLAGS_DP_ON)), - 0, /* power low? ... no */ - (!!DP_FLAGS_DP_ON)); - return 2; -}; - -__overridable uint8_t get_dp_pin_mode(int port) -{ - return pd_dfp_dp_get_pin_mode(port, dp_status[port]); -} - -__overridable int svdm_dp_config(int port, uint32_t *payload) -{ - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); - int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]); - uint8_t pin_mode = get_dp_pin_mode(port); - mux_state_t mux_mode; - - if (!pin_mode) - return 0; - - /* - * Multi-function operation is only allowed if that pin config is - * supported. - */ - mux_mode = ((pin_mode & MODE_DP_PIN_MF_MASK) && mf_pref) ? - USB_PD_MUX_DOCK : USB_PD_MUX_DP_ENABLED; - CPRINTS("pin_mode: %x, mf: %d, mux: %d", pin_mode, mf_pref, mux_mode); - - /* Connect the SBU and USB lines to the connector. */ - if (IS_ENABLED(CONFIG_USBC_PPC_SBU)) - ppc_set_sbu(port, 1); - usb_mux_set(port, mux_mode, USB_SWITCH_CONNECT, pd_get_polarity(port)); - - payload[0] = VDO(USB_SID_DISPLAYPORT, 1, - CMD_DP_CONFIG | VDO_OPOS(opos)); - payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */ - 1, /* DPv1.3 signaling */ - 2); /* UFP connected */ - return 2; -}; - -/* - * timestamp of the next possible toggle to ensure the 2-ms spacing - * between IRQ_HPD. Since this is used in overridable functions, this - * has to be global. - */ -uint64_t svdm_hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; - -#ifndef PORT_TO_HPD -#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) -#endif /* PORT_TO_HPD */ - -__overridable void svdm_dp_post_config(int port) -{ - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - -#ifdef CONFIG_USB_PD_DP_HPD_GPIO - gpio_set_level(PORT_TO_HPD(port), 1); - - /* set the minimum time delay (2ms) for the next HPD IRQ */ - svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; -#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ - - usb_mux_hpd_update(port, 1, 0); - -#ifdef USB_PD_PORT_TCPC_MST - if (port == USB_PD_PORT_TCPC_MST) - baseboard_mst_enable_control(port, 1); -#endif -} - -__overridable int svdm_dp_attention(int port, uint32_t *payload) -{ - int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); - int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); -#ifdef CONFIG_USB_PD_DP_HPD_GPIO - enum gpio_signal hpd = PORT_TO_HPD(port); - int cur_lvl = gpio_get_level(hpd); -#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ - - dp_status[port] = payload[1]; - - if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - (irq || lvl)) - /* - * Wake up the AP. IRQ or level high indicates a DP sink is now - * present. - */ - if (IS_ENABLED(CONFIG_MKBP_EVENT)) - pd_notify_dp_alt_mode_entry(); - - /* Its initial DP status message prior to config */ - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - -#ifdef CONFIG_USB_PD_DP_HPD_GPIO - if (irq & cur_lvl) { - uint64_t now = get_time().val; - /* wait for the minimum spacing between IRQ_HPD if needed */ - if (now < svdm_hpd_deadline[port]) - usleep(svdm_hpd_deadline[port] - now); - - /* generate IRQ_HPD pulse */ - gpio_set_level(hpd, 0); - usleep(HPD_DSTREAM_DEBOUNCE_IRQ); - gpio_set_level(hpd, 1); - - /* set the minimum time delay (2ms) for the next HPD IRQ */ - svdm_hpd_deadline[port] = get_time().val + - HPD_USTREAM_DEBOUNCE_LVL; - } else if (irq & !lvl) { - /* - * IRQ can only be generated when the level is high, because - * the IRQ is signaled by a short low pulse from the high level. - */ - CPRINTF("ERR:HPD:IRQ&LOW\n"); - return 0; /* nak */ - } else { - gpio_set_level(hpd, lvl); - /* set the minimum time delay (2ms) for the next HPD IRQ */ - svdm_hpd_deadline[port] = get_time().val + - HPD_USTREAM_DEBOUNCE_LVL; - } -#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ - - usb_mux_hpd_update(port, lvl, irq); - -#ifdef USB_PD_PORT_TCPC_MST - if (port == USB_PD_PORT_TCPC_MST) - baseboard_mst_enable_control(port, lvl); -#endif - - /* ack */ - return 1; -} - -__overridable void svdm_exit_dp_mode(int port) -{ - svdm_safe_dp_mode(port); -#ifdef CONFIG_USB_PD_DP_HPD_GPIO - gpio_set_level(PORT_TO_HPD(port), 0); -#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ - usb_mux_hpd_update(port, 0, 0); -#ifdef USB_PD_PORT_TCPC_MST - if (port == USB_PD_PORT_TCPC_MST) - baseboard_mst_enable_control(port, 0); -#endif -} - -__overridable int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -__overridable void svdm_exit_gfu_mode(int port) -{ -} - -__overridable int svdm_gfu_status(int port, uint32_t *payload) -{ - /* - * This is called after enter mode is successful, send unstructured - * VDM to read info. - */ - pd_send_vdm(port, USB_VID_GOOGLE, VDO_CMD_READ_INFO, NULL, 0); - return 0; -} - -__overridable int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -__overridable int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -#ifdef CONFIG_USB_PD_TBT_COMPAT_MODE -__overridable int svdm_tbt_compat_enter_mode(int port, uint32_t mode_caps) -{ - return 0; -} - -__overridable void svdm_tbt_compat_exit_mode(int port) -{ -} - -__overridable int svdm_tbt_compat_status(int port, uint32_t *payload) -{ - return 0; -} - -__overridable int svdm_tbt_compat_config(int port, uint32_t *payload) -{ - return 0; -} - -__overridable int svdm_tbt_compat_attention(int port, uint32_t *payload) -{ - return 0; -} -#endif /* CONFIG_USB_PD_TBT_COMPAT_MODE */ - -const struct svdm_amode_fx supported_modes[] = { - { - .svid = USB_SID_DISPLAYPORT, - .enter = &svdm_enter_dp_mode, - .status = &svdm_dp_status, - .config = &svdm_dp_config, - .post_config = &svdm_dp_post_config, - .attention = &svdm_dp_attention, - .exit = &svdm_exit_dp_mode, - }, - - { - .svid = USB_VID_GOOGLE, - .enter = &svdm_enter_gfu_mode, - .status = &svdm_gfu_status, - .config = &svdm_gfu_config, - .attention = &svdm_gfu_attention, - .exit = &svdm_exit_gfu_mode, - }, -#ifdef CONFIG_USB_PD_TBT_COMPAT_MODE - { - .svid = USB_VID_INTEL, - .enter = &svdm_tbt_compat_enter_mode, - .status = &svdm_tbt_compat_status, - .config = &svdm_tbt_compat_config, - .attention = &svdm_tbt_compat_attention, - .exit = &svdm_tbt_compat_exit_mode, - }, -#endif /* CONFIG_USB_PD_TBT_COMPAT_MODE */ -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/common/usb_pd_alt_mode_dfp.c b/common/usb_pd_alt_mode_dfp.c index 80f45ebb01..1315ef1fcd 100644 --- a/common/usb_pd_alt_mode_dfp.c +++ b/common/usb_pd_alt_mode_dfp.c @@ -5,8 +5,15 @@ * Alternate Mode Downstream Facing Port (DFP) USB-PD module. */ +#include "chipset.h" #include "console.h" +#include "task.h" +#include "task_id.h" +#include "timer.h" +#include "usb_charge.h" +#include "usb_mux.h" #include "usb_pd.h" +#include "usbc_ppc.h" #include "util.h" #ifdef CONFIG_COMMON_RUNTIME @@ -17,6 +24,27 @@ #define CPRINTF(format, args...) #endif +#ifndef PORT_TO_HPD +#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) +#endif /* PORT_TO_HPD */ + +/* + * timestamp of the next possible toggle to ensure the 2-ms spacing + * between IRQ_HPD. Since this is used in overridable functions, this + * has to be global. + */ +uint64_t svdm_hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; + +int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; + +uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; + +__overridable const struct svdm_response svdm_rsp = { + .identity = NULL, + .svids = NULL, + .modes = NULL, +}; + static int pd_get_mode_idx(int port, uint16_t svid) { int i; @@ -380,3 +408,315 @@ uint32_t *pd_get_mode_vdo(int port, uint16_t svid_idx) return pe->svids[svid_idx].mode_vdo; } + +void notify_sysjump_ready(volatile const task_id_t * const sysjump_task_waiting) +{ + /* + * If event was set from pd_prepare_sysjump, wake the + * task waiting on us to complete. + */ + if (*sysjump_task_waiting != TASK_ID_INVALID) + task_set_event(*sysjump_task_waiting, + TASK_EVENT_SYSJUMP_READY, 0); +} + +/* + * Before entering into alternate mode, state of the USB-C MUX + * needs to be in safe mode. + * Ref: USB Type-C Cable and Connector Specification + * Section E.2.2 Alternate Mode Electrical Requirements + */ +void usb_mux_set_safe_mode(int port) +{ + usb_mux_set(port, IS_ENABLED(CONFIG_USB_MUX_VIRTUAL) ? + USB_PD_MUX_SAFE_MODE : USB_PD_MUX_NONE, + USB_SWITCH_CONNECT, pd_get_polarity(port)); + + /* Isolate the SBU lines. */ + if (IS_ENABLED(CONFIG_USBC_PPC_SBU)) + ppc_set_sbu(port, 0); +} + +__overridable void svdm_safe_dp_mode(int port) +{ + /* make DP interface safe until configure */ + dp_flags[port] = 0; + dp_status[port] = 0; + + usb_mux_set_safe_mode(port); +} + +__overridable int svdm_enter_dp_mode(int port, uint32_t mode_caps) +{ + /* + * Don't enter the mode if the SoC is off. + * + * There's no need to enter the mode while the SoC is off; we'll + * actually enter the mode on the chipset resume hook. Entering DP Alt + * Mode twice will confuse some monitors and require and unplug/replug + * to get them to work again. The DP Alt Mode on USB-C spec says that + * if we don't need to maintain HPD connectivity info in a low power + * mode, then we shall exit DP Alt Mode. (This is why we don't enter + * when the SoC is off as opposed to suspend where adding a display + * could cause a wake up.) + */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return -1; + + /* Only enter mode if device is DFP_D capable */ + if (mode_caps & MODE_DP_SNK) { + svdm_safe_dp_mode(port); + + if (IS_ENABLED(CONFIG_MKBP_EVENT) && + chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + /* + * Wake the system up since we're entering DP AltMode. + */ + pd_notify_dp_alt_mode_entry(); + + return 0; + } + + return -1; +} + +__overridable int svdm_dp_status(int port, uint32_t *payload) +{ + int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + + payload[0] = VDO(USB_SID_DISPLAYPORT, 1, + CMD_DP_STATUS | VDO_OPOS(opos)); + payload[1] = VDO_DP_STATUS(0, /* HPD IRQ ... not applicable */ + 0, /* HPD level ... not applicable */ + 0, /* exit DP? ... no */ + 0, /* usb mode? ... no */ + 0, /* multi-function ... no */ + (!!(dp_flags[port] & DP_FLAGS_DP_ON)), + 0, /* power low? ... no */ + (!!DP_FLAGS_DP_ON)); + return 2; +}; + +__overridable uint8_t get_dp_pin_mode(int port) +{ + return pd_dfp_dp_get_pin_mode(port, dp_status[port]); +} + +__overridable int svdm_dp_config(int port, uint32_t *payload) +{ + int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]); + uint8_t pin_mode = get_dp_pin_mode(port); + mux_state_t mux_mode; + + if (!pin_mode) + return 0; + + /* + * Multi-function operation is only allowed if that pin config is + * supported. + */ + mux_mode = ((pin_mode & MODE_DP_PIN_MF_MASK) && mf_pref) ? + USB_PD_MUX_DOCK : USB_PD_MUX_DP_ENABLED; + CPRINTS("pin_mode: %x, mf: %d, mux: %d", pin_mode, mf_pref, mux_mode); + + /* Connect the SBU and USB lines to the connector. */ + if (IS_ENABLED(CONFIG_USBC_PPC_SBU)) + ppc_set_sbu(port, 1); + usb_mux_set(port, mux_mode, USB_SWITCH_CONNECT, pd_get_polarity(port)); + + payload[0] = VDO(USB_SID_DISPLAYPORT, 1, + CMD_DP_CONFIG | VDO_OPOS(opos)); + payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */ + 1, /* DPv1.3 signaling */ + 2); /* UFP connected */ + return 2; +}; + +__overridable void svdm_dp_post_config(int port) +{ + dp_flags[port] |= DP_FLAGS_DP_ON; + if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) + return; + +#ifdef CONFIG_USB_PD_DP_HPD_GPIO + gpio_set_level(PORT_TO_HPD(port), 1); + + /* set the minimum time delay (2ms) for the next HPD IRQ */ + svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; +#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ + + usb_mux_hpd_update(port, 1, 0); + +#ifdef USB_PD_PORT_TCPC_MST + if (port == USB_PD_PORT_TCPC_MST) + baseboard_mst_enable_control(port, 1); +#endif +} + +__overridable int svdm_dp_attention(int port, uint32_t *payload) +{ + int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); + int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); +#ifdef CONFIG_USB_PD_DP_HPD_GPIO + enum gpio_signal hpd = PORT_TO_HPD(port); + int cur_lvl = gpio_get_level(hpd); +#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ + + dp_status[port] = payload[1]; + + if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && + (irq || lvl)) + /* + * Wake up the AP. IRQ or level high indicates a DP sink is now + * present. + */ + if (IS_ENABLED(CONFIG_MKBP_EVENT)) + pd_notify_dp_alt_mode_entry(); + + /* Its initial DP status message prior to config */ + if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { + if (lvl) + dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; + return 1; + } + +#ifdef CONFIG_USB_PD_DP_HPD_GPIO + if (irq & !lvl) { + /* + * IRQ can only be generated when the level is high, because + * the IRQ is signaled by a short low pulse from the high level. + */ + CPRINTF("ERR:HPD:IRQ&LOW\n"); + return 0; /* nak */ + } + + if (irq & cur_lvl) { + uint64_t now = get_time().val; + /* wait for the minimum spacing between IRQ_HPD if needed */ + if (now < svdm_hpd_deadline[port]) + usleep(svdm_hpd_deadline[port] - now); + + /* generate IRQ_HPD pulse */ + gpio_set_level(hpd, 0); + usleep(HPD_DSTREAM_DEBOUNCE_IRQ); + gpio_set_level(hpd, 1); + } else { + gpio_set_level(hpd, lvl); + } + + /* set the minimum time delay (2ms) for the next HPD IRQ */ + svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; +#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ + + usb_mux_hpd_update(port, lvl, irq); + +#ifdef USB_PD_PORT_TCPC_MST + if (port == USB_PD_PORT_TCPC_MST) + baseboard_mst_enable_control(port, lvl); +#endif + + /* ack */ + return 1; +} + +__overridable void svdm_exit_dp_mode(int port) +{ + svdm_safe_dp_mode(port); +#ifdef CONFIG_USB_PD_DP_HPD_GPIO + gpio_set_level(PORT_TO_HPD(port), 0); +#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ + usb_mux_hpd_update(port, 0, 0); +#ifdef USB_PD_PORT_TCPC_MST + if (port == USB_PD_PORT_TCPC_MST) + baseboard_mst_enable_control(port, 0); +#endif +} + +__overridable int svdm_enter_gfu_mode(int port, uint32_t mode_caps) +{ + /* Always enter GFU mode */ + return 0; +} + +__overridable void svdm_exit_gfu_mode(int port) +{ +} + +__overridable int svdm_gfu_status(int port, uint32_t *payload) +{ + /* + * This is called after enter mode is successful, send unstructured + * VDM to read info. + */ + pd_send_vdm(port, USB_VID_GOOGLE, VDO_CMD_READ_INFO, NULL, 0); + return 0; +} + +__overridable int svdm_gfu_config(int port, uint32_t *payload) +{ + return 0; +} + +__overridable int svdm_gfu_attention(int port, uint32_t *payload) +{ + return 0; +} + +#ifdef CONFIG_USB_PD_TBT_COMPAT_MODE +__overridable int svdm_tbt_compat_enter_mode(int port, uint32_t mode_caps) +{ + return 0; +} + +__overridable void svdm_tbt_compat_exit_mode(int port) +{ +} + +__overridable int svdm_tbt_compat_status(int port, uint32_t *payload) +{ + return 0; +} + +__overridable int svdm_tbt_compat_config(int port, uint32_t *payload) +{ + return 0; +} + +__overridable int svdm_tbt_compat_attention(int port, uint32_t *payload) +{ + return 0; +} +#endif /* CONFIG_USB_PD_TBT_COMPAT_MODE */ + +const struct svdm_amode_fx supported_modes[] = { + { + .svid = USB_SID_DISPLAYPORT, + .enter = &svdm_enter_dp_mode, + .status = &svdm_dp_status, + .config = &svdm_dp_config, + .post_config = &svdm_dp_post_config, + .attention = &svdm_dp_attention, + .exit = &svdm_exit_dp_mode, + }, + + { + .svid = USB_VID_GOOGLE, + .enter = &svdm_enter_gfu_mode, + .status = &svdm_gfu_status, + .config = &svdm_gfu_config, + .attention = &svdm_gfu_attention, + .exit = &svdm_exit_gfu_mode, + }, +#ifdef CONFIG_USB_PD_TBT_COMPAT_MODE + { + .svid = USB_VID_INTEL, + .enter = &svdm_tbt_compat_enter_mode, + .status = &svdm_tbt_compat_status, + .config = &svdm_tbt_compat_config, + .attention = &svdm_tbt_compat_attention, + .exit = &svdm_tbt_compat_exit_mode, + }, +#endif /* CONFIG_USB_PD_TBT_COMPAT_MODE */ +}; +const int supported_modes_cnt = ARRAY_SIZE(supported_modes); |