diff options
Diffstat (limited to 'board')
51 files changed, 117 insertions, 8414 deletions
diff --git a/board/atlas/usb_pd_policy.c b/board/atlas/usb_pd_policy.c index 8b7c8bef97..fb7bd79838 100644 --- a/board/atlas/usb_pd_policy.c +++ b/board/atlas/usb_pd_policy.c @@ -26,35 +26,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -134,41 +105,13 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_PMIC_SLP_SUS_L); } -void pd_execute_data_swap(int port, int data_role) +__override void pd_execute_data_swap(int port, int data_role) { /* Only port 0 supports device mode. */ if (port != 0) @@ -179,282 +122,3 @@ void pd_execute_data_swap(int port, int data_role) gpio_set_level(GPIO_USB2_VBUSSENSE, (data_role == PD_ROLE_UFP) ? 1 : 0); } - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static 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); - return 0; - } - - return -1; -} - -static 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)); - /* - * VESA DisplayPort Alt Mode on USB Type-C Standard Version 1.0b: - * 5.2.3 requries DP_FLAGS_DP_ON permanently set for DFP_D - */ - 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; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - enum typec_mux 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) ? - TYPEC_MUX_DOCK : TYPEC_MUX_DP; - CPRINTS("pin_mode: 0x%X, mf: %d, mux: %d", pin_mode, mf_pref, mux_mode); - - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - - /* 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; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/cheza/usb_pd_policy.c b/board/cheza/usb_pd_policy.c index 061c6bb5df..d8e9c57dea 100644 --- a/board/cheza/usb_pd_policy.c +++ b/board/cheza/usb_pd_policy.c @@ -15,84 +15,13 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO(waihong): Fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Always allow data swap */ - return 1; -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - int pd_check_vconn_swap(int port) { /* TODO(waihong): Check any case we do not allow. */ return 1; } -void pd_execute_data_swap(int port, int data_role) +__override void pd_execute_data_swap(int port, int data_role) { int enable = (data_role == PD_ROLE_UFP); int type; @@ -128,11 +57,6 @@ void pd_execute_data_swap(int port, int data_role) gpio_set_level(GPIO_USB_C1_HS_MUX_SEL, enable ? 1 : 0); } -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -207,17 +131,12 @@ int pd_set_power_supply_ready(int port) return EC_SUCCESS; /* we are ready */ } -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int board_vbus_source_enabled(int port) { return vbus_en[port]; } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) { vbus_rp[port] = rp; board_vbus_update_source_current(port); @@ -230,138 +149,6 @@ int pd_snk_is_vbus_provided(int port) } /* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static int svdm_dp_config(int port, uint32_t *payload) -{ - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - 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; -}; - -static void svdm_dp_post_config(int port) -{ - dp_flags[port] |= DP_FLAGS_DP_ON; -} - /** * Is the port fine to be muxed its DisplayPort lines? * @@ -383,7 +170,8 @@ static int is_dp_muxable(int port) return 1; } -static int svdm_dp_attention(int port, uint32_t *payload) +extern uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; +__override 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]); @@ -411,63 +199,3 @@ static int svdm_dp_attention(int port, uint32_t *payload) /* ack */ return 1; } - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/coffeecake/board.h b/board/coffeecake/board.h index 62dea70847..26f8de88c6 100644 --- a/board/coffeecake/board.h +++ b/board/coffeecake/board.h @@ -49,6 +49,7 @@ #define CONFIG_USB_PD_LOGGING #undef CONFIG_EVENT_LOG_SIZE #define CONFIG_EVENT_LOG_SIZE 256 +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_PORT_MAX_COUNT 1 #define CONFIG_USB_PD_TCPC #define CONFIG_USB_PD_TCPM_STUB diff --git a/board/coral/usb_pd_policy.c b/board/coral/usb_pd_policy.c index 9765b540d1..e071f6ae2a 100644 --- a/board/coral/usb_pd_policy.c +++ b/board/coral/usb_pd_policy.c @@ -26,36 +26,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -130,290 +100,8 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_EN_PP5000); } - -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/dingdong/board.h b/board/dingdong/board.h index 8a0a835f92..51fa51dcd2 100644 --- a/board/dingdong/board.h +++ b/board/dingdong/board.h @@ -28,6 +28,7 @@ #define CONFIG_USB_INHIBIT_CONNECT #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR USB_PD_HW_DEV_ID_DINGDONG #define CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR 2 #define CONFIG_USB_PD_DUAL_ROLE diff --git a/board/elm/usb_pd_policy.c b/board/elm/usb_pd_policy.c index 06ba8d13c2..5cfc60650e 100644 --- a/board/elm/usb_pd_policy.c +++ b/board/elm/usb_pd_policy.c @@ -24,32 +24,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int pd_set_power_supply_ready(int port) { /* Disable charging */ @@ -76,216 +50,15 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since 5V power source is off */ return gpio_get_level(GPIO_5V_POWER_GOOD); } -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} - /* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - #ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - - /* - * Check current status, due to the mux may be switched to SS - * and SS device was attached before (for example: Type-C dock). - * To avoid broken the SS connection, - * keep the current setting if SS connection is enabled already. - */ - usb_mux_set(port, usb_mux_get(port) & USB_PD_MUX_USB_ENABLED ? - TYPEC_MUX_USB : TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; -} - -static int svdm_dp_attention(int port, uint32_t *payload) +__override int svdm_dp_attention(int port, uint32_t *payload) { int cur_lvl; int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); @@ -312,60 +85,9 @@ static int svdm_dp_attention(int port, uint32_t *payload) return ack; } -static void svdm_exit_dp_mode(int port) +__override void svdm_exit_dp_mode(int port) { svdm_safe_dp_mode(port); anx7688_hpd_disable(port); } - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); #endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/eve/usb_pd_policy.c b/board/eve/usb_pd_policy.c index 02e3bab978..3885ed6fc4 100644 --- a/board/eve/usb_pd_policy.c +++ b/board/eve/usb_pd_policy.c @@ -26,36 +26,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -156,34 +126,6 @@ void pd_power_supply_reset(int port) board_update_ac_status(); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ @@ -201,252 +143,3 @@ void pd_execute_data_swap(int port, int data_role) gpio_set_level(GPIO_USB2_OTG_VBUSSENSE, (data_role == PD_ROLE_UFP) ? 1 : 0); } - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/fizz/board.h b/board/fizz/board.h index d375ea5d6a..d88d1ba65c 100644 --- a/board/fizz/board.h +++ b/board/fizz/board.h @@ -96,6 +96,7 @@ #undef CONFIG_USB_CHARGER /* dnojiri: verify */ #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_DISCHARGE_TCPC #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE diff --git a/board/fizz/usb_pd_policy.c b/board/fizz/usb_pd_policy.c index fe4a4c4192..5de57f3c9b 100644 --- a/board/fizz/usb_pd_policy.c +++ b/board/fizz/usb_pd_policy.c @@ -40,16 +40,6 @@ const uint32_t pd_snk_pdo[] = { }; const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int board_vbus_source_enabled(int port) { if (port != 0) @@ -85,12 +75,7 @@ int pd_snk_is_vbus_provided(int port) return !gpio_get_level(GPIO_USB_C0_VBUS_WAKE_L); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) +__override int pd_check_power_swap(int port) { /* If type-c port is supplying power, we never swap PR (to source) */ if (port == charge_manager_get_active_charge_port()) @@ -103,121 +88,12 @@ int pd_check_power_swap(int port) return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; } -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_PMIC_SLP_SUS_L); } -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - int board_set_active_charge_port(int port) { const int active_port = charge_manager_get_active_charge_port(); @@ -264,156 +140,3 @@ int board_get_battery_soc(void) { return 100; } - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - pd_log_event(PD_EVENT_VIDEO_DP_MODE, - PD_LOG_PORT_SIZE(port, 0), 1, NULL); - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - pd_log_event(PD_EVENT_VIDEO_DP_MODE, - PD_LOG_PORT_SIZE(port, 0), 0, NULL); - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/flapjack/board.h b/board/flapjack/board.h index af3f05ce9b..26d299f1b9 100644 --- a/board/flapjack/board.h +++ b/board/flapjack/board.h @@ -151,6 +151,7 @@ #define CONFIG_USBC_VCONN #define CONFIG_USBC_VCONN_SWAP #define CONFIG_USB_PD_COMM_LOCKED +#define CONFIG_USB_PD_DP_HPD_GPIO #define CONFIG_USBC_DISABLE_CHARGE_FROM_RP_DEF #ifdef SECTION_IS_RO #define CONFIG_USB_PD_DEBUG_LEVEL 0 @@ -336,6 +337,8 @@ extern uint8_t board_version; extern uint8_t oem; extern uint32_t sku; +#define PORT_TO_HPD(port) GPIO_USB_C0_HPD_OD + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/flapjack/usb_pd_policy.c b/board/flapjack/usb_pd_policy.c index b2c992b4e2..d47ac5860c 100644 --- a/board/flapjack/usb_pd_policy.c +++ b/board/flapjack/usb_pd_policy.c @@ -24,35 +24,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, - (int)(PD_MAX_VOLTAGE_MV * 1.05), - PD_OPERATING_POWER_MW), - PDO_VAR(4750, - (int)(PD_MAX_VOLTAGE_MV * 1.05), - PD_MAX_CURRENT_MA), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en; int board_vbus_source_enabled(int port) @@ -60,6 +31,15 @@ int board_vbus_source_enabled(int port) return vbus_en; } +int pd_check_vconn_swap(int port) +{ + /* + * VCONN is provided directly by the battery (PPVAR_SYS) + * but use the same rules as power swap. + */ + return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; +} + int pd_set_power_supply_ready(int port) { /* Disable NCP3902 to avoid charging from VBUS */ @@ -93,196 +73,15 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) -{ - /* No-operation */ -} - -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - -int pd_check_vconn_swap(int port) -{ - /* - * VCONN is provided directly by the battery (PPVAR_SYS) - * but use the same rules as power swap. - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} /* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - #ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static int svdm_dp_config(int port, uint32_t *payload) -{ - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - 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. */ static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; -static void svdm_dp_post_config(int port) +__override void svdm_dp_post_config(int port) { const struct usb_mux * const mux = &usb_muxes[port]; @@ -299,7 +98,7 @@ static void svdm_dp_post_config(int port) mux->hpd_update(port, 1, 0); } -static int svdm_dp_attention(int port, uint32_t *payload) +__override int svdm_dp_attention(int port, uint32_t *payload) { int cur_lvl = gpio_get_level(GPIO_USB_C0_HPD_OD); int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); @@ -351,7 +150,7 @@ static int svdm_dp_attention(int port, uint32_t *payload) return 1; } -static void svdm_exit_dp_mode(int port) +__override void svdm_exit_dp_mode(int port) { const struct usb_mux * const mux = &usb_muxes[port]; @@ -360,55 +159,4 @@ static void svdm_exit_dp_mode(int port) gpio_set_level(GPIO_USB_C0_DP_OE_L, 1); mux->hpd_update(port, 0, 0); } - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); #endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/glados/board.h b/board/glados/board.h index d1ac4bb356..ed4939b692 100644 --- a/board/glados/board.h +++ b/board/glados/board.h @@ -71,6 +71,7 @@ #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_DP_HPD_GPIO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING #define CONFIG_USB_PD_PORT_MAX_COUNT 2 diff --git a/board/glados/usb_pd_policy.c b/board/glados/usb_pd_policy.c index 1870791358..72490a8d3c 100644 --- a/board/glados/usb_pd_policy.c +++ b/board/glados/usb_pd_policy.c @@ -21,32 +21,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int pd_set_power_supply_ready(int port) { /* Disable charging */ @@ -78,313 +52,8 @@ int pd_snk_is_vbus_provided(int port) GPIO_USB_C0_VBUS_WAKE_L); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_PMIC_SLP_SUS_L); } - -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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. - */ -static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; - -#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) -static void svdm_dp_post_config(int port) -{ - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - - gpio_set_level(PORT_TO_HPD(port), 1); - - /* set the minimum time delay (2ms) for the next HPD IRQ */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; -} - -static int svdm_dp_attention(int port, uint32_t *payload) -{ - int cur_lvl; - int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); - int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); - enum gpio_signal hpd = PORT_TO_HPD(port); - cur_lvl = gpio_get_level(hpd); - - dp_status[port] = payload[1]; - - /* 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; - } - - if (irq & cur_lvl) { - uint64_t now = get_time().val; - /* wait for the minimum spacing between IRQ_HPD if needed */ - if (now < hpd_deadline[port]) - usleep(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 */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - } else if (irq & !cur_lvl) { - 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 */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - } - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - svdm_safe_dp_mode(port); - gpio_set_level(PORT_TO_HPD(port), 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ - diff --git a/board/glkrvp/usb_pd_policy.c b/board/glkrvp/usb_pd_policy.c index 72c54d3ec3..19572f7063 100644 --- a/board/glkrvp/usb_pd_policy.c +++ b/board/glkrvp/usb_pd_policy.c @@ -15,36 +15,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int pd_set_power_supply_ready(int port) { /* Disable charging */ @@ -68,27 +38,6 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP); -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ @@ -96,172 +45,8 @@ int pd_check_vconn_swap(int port) return 1; } -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} - /* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - /* TODO: usb_mux_flip(port); */ - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - #ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - static void svdm_dp_post_config(int port) { dp_flags[port] |= DP_FLAGS_DP_ON; @@ -287,61 +72,4 @@ static int svdm_dp_attention(int port, uint32_t *payload) /* ack */ return 1; } - -static void svdm_exit_dp_mode(int port) -{ - svdm_safe_dp_mode(port); - /* TODO: Update HPD to host */ -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); #endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/glkrvp_ite/usb_pd_policy.c b/board/glkrvp_ite/usb_pd_policy.c index e269d217f5..05d1c8285f 100644 --- a/board/glkrvp_ite/usb_pd_policy.c +++ b/board/glkrvp_ite/usb_pd_policy.c @@ -15,36 +15,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int pd_set_power_supply_ready(int port) { /* Disable charging */ @@ -68,27 +38,6 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP); -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ @@ -100,248 +49,3 @@ void pd_execute_data_swap(int port, int data_role) { /* Do nothing */ } - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} - -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - /* TODO: usb_mux_flip(port); */ - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - /* TODO: Update HPD to host */ -} - -static int svdm_dp_attention(int port, uint32_t *payload) -{ - int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); - - /* TODO: Read HPD IRQ */ - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - /* TODO: Update HPD to host */ - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - svdm_safe_dp_mode(port); - /* TODO: Update HPD to host */ -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/hoho/board.h b/board/hoho/board.h index f052ad5de4..2698d0f346 100644 --- a/board/hoho/board.h +++ b/board/hoho/board.h @@ -34,6 +34,7 @@ #define CONFIG_USB_INHIBIT_CONNECT #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR USB_PD_HW_DEV_ID_HOHO #define CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR 2 #define CONFIG_USB_PD_DUAL_ROLE diff --git a/board/hoho/usb_pd_policy.c b/board/hoho/usb_pd_policy.c index ebff717363..eac1da8435 100644 --- a/board/hoho/usb_pd_policy.c +++ b/board/hoho/usb_pd_policy.c @@ -22,15 +22,13 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS PDO_FIXED_COMM_CAP - /* Source PDOs */ const uint32_t pd_src_pdo[] = {}; const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); /* Fake PDOs : we just want our pre-defined voltages */ const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), + PDO_FIXED(5000, 500, PDO_FIXED_COMM_CAP), }; const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); @@ -44,17 +42,6 @@ void pd_set_input_current_limit(int port, uint32_t max_ma, return; } -int pd_is_valid_input_voltage(int mv) -{ - /* Any voltage less than the max is allowed */ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No operation: sink only */ -} - int pd_set_power_supply_ready(int port) { return EC_SUCCESS; @@ -69,33 +56,23 @@ int pd_snk_is_vbus_provided(int port) return 1; } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) +__override int pd_check_power_swap(int port) { /* Always refuse power swap */ return 0; } -int pd_check_data_swap(int port, int data_role) +__override int pd_check_data_swap(int port, int data_role) { /* Always refuse data swap */ return 0; } -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) +__override void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int flags) +__override void pd_check_dr_role(int port, int dr_role, int flags) { } /* ----------------- Vendor Defined Messages ------------------ */ diff --git a/board/host/board.h b/board/host/board.h index ac44f31907..b88831e2d9 100644 --- a/board/host/board.h +++ b/board/host/board.h @@ -23,6 +23,9 @@ #define CONFIG_LIBCRYPTOC +#define CONFIG_USB_PD_CUSTOM_PDO +#define CONFIG_USB_PD_DUAL_ROLE + #include "gpio_signal.h" enum temp_sensor_id { diff --git a/board/host/usb_pd_policy.c b/board/host/usb_pd_policy.c index 0dcc5942a8..56a01d6a3b 100644 --- a/board/host/usb_pd_policy.c +++ b/board/host/usb_pd_policy.c @@ -26,17 +26,6 @@ const uint32_t pd_snk_pdo[] = { }; const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); -int pd_is_valid_input_voltage(int mv) -{ - /* Any voltage less than the max is allowed */ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* Not implemented */ -} - int pd_set_power_supply_ready(int port) { /* Not implemented */ @@ -60,37 +49,28 @@ test_mockable int pd_snk_is_vbus_provided(int port) return 1; } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) +__override int pd_check_power_swap(int port) { /* Always allow power swap */ return 1; } -int pd_check_data_swap(int port, int data_role) +__override int pd_check_data_swap(int port, int data_role) { /* Always allow data swap */ return 1; } -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) +__override void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int flags) +__override void pd_check_dr_role(int port, int dr_role, int flags) { } -int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) +__override int pd_custom_vdm(int port, int cnt, uint32_t *payload, + uint32_t **rpayload) { return 0; } diff --git a/board/it83xx_evb/board.h b/board/it83xx_evb/board.h index 8620ba19c6..45571f8423 100644 --- a/board/it83xx_evb/board.h +++ b/board/it83xx_evb/board.h @@ -39,6 +39,7 @@ #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_ALT_MODE_DFP #define CONFIG_USB_PD_CHECK_MAX_REQUEST_ALLOWED +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_PORT_MAX_COUNT 2 #define CONFIG_USB_PD_TCPM_ITE83XX diff --git a/board/it83xx_evb/usb_pd_policy.c b/board/it83xx_evb/usb_pd_policy.c index 03d83f02f3..1ff691ea04 100644 --- a/board/it83xx_evb/usb_pd_policy.c +++ b/board/it83xx_evb/usb_pd_policy.c @@ -43,17 +43,6 @@ int pd_is_max_request_allowed(void) return 1; } -int pd_is_valid_input_voltage(int mv) -{ - /* Any voltage less than the max is allowed */ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int pd_snk_is_vbus_provided(int port) { int mv = adc_read_channel(port == USBPD_PORT_A ? @@ -77,20 +66,6 @@ void pd_power_supply_reset(int port) board_pd_vbus_ctrl(port, 0); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* TODO: use battery level to decide to accept/reject power swap - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} int pd_check_data_swap(int port, int data_role) { @@ -106,220 +81,3 @@ int pd_check_vconn_swap(int port) */ return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; } - -void pd_execute_data_swap(int port, int data_role) -{ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are source and partner is externally powered, - * swap to become a sink. - */ - if ((flags & PD_FLAGS_PARTNER_EXTPOWER) && - pr_role == PD_ROLE_SOURCE) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* if the partner is a DRP (e.g. laptop), try to switch to UFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_DFP) - pd_request_data_swap(port); -} - -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - /* usb_mux_flip(port); */ - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - /* usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); */ -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); */ - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - /* usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - /* TODO: Figure out HPD */ -} - -static int svdm_dp_attention(int port, uint32_t *payload) -{ - /* TODO: Figure out HPD */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - /* TODO: Figure out HPD */ -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/mchpevb1/board.h b/board/mchpevb1/board.h index 33aa2719b9..d93b31cb82 100644 --- a/board/mchpevb1/board.h +++ b/board/mchpevb1/board.h @@ -233,6 +233,7 @@ #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_DP_HPD_GPIO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING #define CONFIG_USB_PD_PORT_MAX_COUNT 2 diff --git a/board/mchpevb1/usb_pd_policy.c b/board/mchpevb1/usb_pd_policy.c index f763c3aa0e..690f8b8a3c 100644 --- a/board/mchpevb1/usb_pd_policy.c +++ b/board/mchpevb1/usb_pd_policy.c @@ -23,32 +23,6 @@ #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int pd_set_power_supply_ready(int port) { /* Disable charging */ @@ -80,320 +54,8 @@ int pd_snk_is_vbus_provided(int port) GPIO_USB_C0_VBUS_WAKE_L); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_PMIC_SLP_SUS_L); } - -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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. - */ -static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; - -#define PORT_TO_HPD(port) \ - ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) - -static void svdm_dp_post_config(int port) -{ - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - - gpio_set_level(PORT_TO_HPD(port), 1); - - /* set the minimum time delay (2ms) for the next HPD IRQ */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; -} - -static int svdm_dp_attention(int port, uint32_t *payload) -{ - int rc; - int cur_lvl; - int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); - int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); - enum gpio_signal hpd = PORT_TO_HPD(port); - - cur_lvl = gpio_get_level(hpd); - - dp_status[port] = payload[1]; - - rc = 1; /* ack */ - /* 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 rc; - } - - if (irq & cur_lvl) { - uint64_t now = get_time().val; - /* wait for the minimum spacing between IRQ_HPD if needed */ - if (now < hpd_deadline[port]) - usleep(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 */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - } else if (irq & !cur_lvl) { - CPRINTF("ERR:HPD:IRQ&LOW\n"); - rc = 0; /* nak */ - } else { - gpio_set_level(hpd, lvl); - /* set the minimum time delay (2ms) for the next HPD IRQ */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - } - - return rc; -} - -static void svdm_exit_dp_mode(int port) -{ - svdm_safe_dp_mode(port); - gpio_set_level(PORT_TO_HPD(port), 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ - diff --git a/board/nami/usb_pd_policy.c b/board/nami/usb_pd_policy.c index 2aa2f66ae3..e42d0ec5b4 100644 --- a/board/nami/usb_pd_policy.c +++ b/board/nami/usb_pd_policy.c @@ -25,40 +25,9 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO(crosbug.com/p/61098): fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; - int board_vbus_source_enabled(int port) { return vbus_en[port]; @@ -72,7 +41,7 @@ static void board_vbus_update_source_current(int port) vbus_en[port]); } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) { vbus_rp[port] = rp; @@ -128,41 +97,13 @@ int pd_snk_is_vbus_provided(int port) GPIO_USB_C0_VBUS_WAKE_L); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_PMIC_SLP_SUS_L); } -void pd_execute_data_swap(int port, int data_role) +__override void pd_execute_data_swap(int port, int data_role) { /* Only port 0 supports device mode. */ if (port != 0) @@ -170,267 +111,3 @@ void pd_execute_data_swap(int port, int data_role) gpio_set_level(GPIO_USB2_ID, (data_role == PD_ROLE_UFP) ? 0 : 1); } - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static 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); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/nautilus/usb_pd_policy.c b/board/nautilus/usb_pd_policy.c index 2c162a47c1..7237b6b3da 100644 --- a/board/nautilus/usb_pd_policy.c +++ b/board/nautilus/usb_pd_policy.c @@ -24,36 +24,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO(crosbug.com/p/61098): fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -97,7 +67,7 @@ static void board_vbus_update_source_current(int port) } } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) { vbus_rp[port] = rp; @@ -154,33 +124,6 @@ int pd_snk_is_vbus_provided(int port) GPIO_USB_C0_VBUS_WAKE_L); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} int pd_check_vconn_swap(int port) { @@ -188,7 +131,7 @@ int pd_check_vconn_swap(int port) return gpio_get_level(GPIO_PMIC_SLP_SUS_L); } -void pd_execute_data_swap(int port, int data_role) +__override void pd_execute_data_swap(int port, int data_role) { /* Only port 0 supports device mode. */ if (port != 0) @@ -199,252 +142,3 @@ void pd_execute_data_swap(int port, int data_role) gpio_set_level(GPIO_USB2_OTG_VBUSSENSE, (data_role == PD_ROLE_UFP) ? 1 : 0); } - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/nocturne/board.h b/board/nocturne/board.h index 2334488fcf..c71aab3f6e 100644 --- a/board/nocturne/board.h +++ b/board/nocturne/board.h @@ -128,6 +128,7 @@ #define CONFIG_USB_PD_ALT_MODE_DFP #define CONFIG_USB_PD_COMM_LOCKED #define CONFIG_USB_PD_DISCHARGE_PPC +#define CONFIG_USB_PD_DP_HPD_GPIO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE #define CONFIG_USB_PD_LOGGING @@ -205,6 +206,8 @@ #define GPIO_VOLUME_DOWN_L GPIO_H1_EC_VOL_DOWN_ODL #define GPIO_WP_L GPIO_EC_WP_L +#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) + #ifndef __ASSEMBLER__ #include "gpio_signal.h" diff --git a/board/nocturne/usb_pd_policy.c b/board/nocturne/usb_pd_policy.c index 4e4474648f..930be05af8 100644 --- a/board/nocturne/usb_pd_policy.c +++ b/board/nocturne/usb_pd_policy.c @@ -19,86 +19,13 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_COMM_CAP|\ - PDO_FIXED_DATA_SWAP) - -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); - -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -/* TODO(aaboagye): Determine correct values. */ -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow. */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} - -/* TODO(aaboagye): re-eval for 3.0 & FRS. */ -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - int pd_check_vconn_swap(int port) { /* Do not allow VCONN swap is 5V is off. */ return gpio_get_level(GPIO_EN_5V); } -void pd_execute_data_swap(int port, int data_role) +__override void pd_execute_data_swap(int port, int data_role) { int level; @@ -112,11 +39,6 @@ void pd_execute_data_swap(int port, int data_role) gpio_set_level(GPIO_USB2_VBUSSENSE, level); } -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - void pd_power_supply_reset(int port) { /* @@ -169,97 +91,10 @@ int pd_set_power_supply_ready(int port) return EC_SUCCESS; } -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - -void typec_set_source_current_limit(int p, enum tcpc_rp_value rp) -{ - ppc_set_vbus_source_current_limit(p, rp); -} - /* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) +__override void svdm_safe_dp_mode(int port) { /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; usb_mux_set(port, TYPEC_MUX_NONE, USB_SWITCH_CONNECT, pd_get_polarity(port)); @@ -274,221 +109,3 @@ static void svdm_safe_dp_mode(int port) else ppc_set_sbu(port, 0); } - -static 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 (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; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - enum typec_mux 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) ? - TYPEC_MUX_DOCK : TYPEC_MUX_DP; - CPRINTS("pin_mode: %x, mf: %d, mux: %d", pin_mode, mf_pref, mux_mode); - - /* Connect the SBU and USB lines to the connector. */ - 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. - */ -static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; - -#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - - gpio_set_level(PORT_TO_HPD(port), 1); - - /* set the minimum time delay (2ms) for the next HPD IRQ */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - - mux->hpd_update(port, 1, 0); -} - -static int svdm_dp_attention(int port, uint32_t *payload) -{ - int cur_lvl; - int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); - int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); - enum gpio_signal hpd = PORT_TO_HPD(port); - const struct usb_mux *mux = &usb_muxes[port]; - - cur_lvl = gpio_get_level(hpd); - 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. - */ - 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; - } - - if (irq & cur_lvl) { - uint64_t now = get_time().val; - /* wait for the minimum spacing between IRQ_HPD if needed */ - if (now < hpd_deadline[port]) - usleep(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 */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - } else if (irq & !lvl) { - 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 */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - } - mux->hpd_update(port, lvl, irq); - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - gpio_set_level(PORT_TO_HPD(port), 0); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/oak/usb_pd_policy.c b/board/oak/usb_pd_policy.c index 77d10730a4..bf2fca3f49 100644 --- a/board/oak/usb_pd_policy.c +++ b/board/oak/usb_pd_policy.c @@ -21,32 +21,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int pd_set_power_supply_ready(int port) { /* Disable charging */ @@ -72,7 +46,7 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -int pd_board_checks(void) +__override int pd_board_checks(void) { #if BOARD_REV <= OAK_REV3 /* wake up VBUS task to check vbus change */ @@ -81,201 +55,15 @@ int pd_board_checks(void) return EC_SUCCESS; } -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since 5V power source is off */ return gpio_get_level(GPIO_5V_POWER_GOOD); } -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} /* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - #ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - - /* - * Check current status, due to the mux may be switched to SS - * and SS device was attached before (for example: Type-C dock). - * To avoid broken the SS connection, - * keep the current setting if SS connection is enabled already. - */ - usb_mux_set(port, usb_mux_get(port) & USB_PD_MUX_USB_ENABLED ? - TYPEC_MUX_USB : TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) +__override void svdm_dp_post_config(int port) { dp_flags[port] |= DP_FLAGS_DP_ON; if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) @@ -283,7 +71,7 @@ static void svdm_dp_post_config(int port) board_typec_dp_set(port, 1); } -static int svdm_dp_attention(int port, uint32_t *payload) +__override int svdm_dp_attention(int port, uint32_t *payload) { int cur_lvl; int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); @@ -311,60 +99,9 @@ static int svdm_dp_attention(int port, uint32_t *payload) return 1; } -static void svdm_exit_dp_mode(int port) +__override void svdm_exit_dp_mode(int port) { svdm_safe_dp_mode(port); board_typec_dp_off(port, dp_flags); } - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); #endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/pdeval-stm32f072/board.h b/board/pdeval-stm32f072/board.h index b008edc860..02d6a541ed 100644 --- a/board/pdeval-stm32f072/board.h +++ b/board/pdeval-stm32f072/board.h @@ -24,6 +24,7 @@ #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_PORT_MAX_COUNT 1 #define CONFIG_USB_PD_TCPM_TCPCI diff --git a/board/pdeval-stm32f072/usb_pd_policy.c b/board/pdeval-stm32f072/usb_pd_policy.c index 5821437f20..27cf027b48 100644 --- a/board/pdeval-stm32f072/usb_pd_policy.c +++ b/board/pdeval-stm32f072/usb_pd_policy.c @@ -43,16 +43,6 @@ struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; #endif -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - #ifdef CONFIG_USB_PD_TCPM_ANX7447 int pd_set_power_supply_ready(int port) { @@ -115,8 +105,8 @@ void pd_set_input_current_limit(int port, uint32_t max_ma, } } -void typec_set_input_current_limit(int port, uint32_t max_ma, - uint32_t supply_voltage) +__override void typec_set_input_current_limit(int port, uint32_t max_ma, + uint32_t supply_voltage) { CPRINTS("TYPEC current limit port %d max %d mA %d mV", port, max_ma, supply_voltage); @@ -145,22 +135,7 @@ int pd_snk_is_vbus_provided(int port) return vbus_present; } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON; -} - -int pd_check_data_swap(int port, int data_role) +__override int pd_check_data_swap(int port, int data_role) { /* Always allow data swap */ return 1; @@ -178,15 +153,11 @@ int pd_check_vconn_swap(int port) } #endif -void pd_execute_data_swap(int port, int data_role) -{ -} - -void pd_check_pr_role(int port, int pr_role, int flags) +__override void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int flags) +__override void pd_check_dr_role(int port, int dr_role, int flags) { } /* ----------------- Vendor Defined Messages ------------------ */ @@ -206,91 +177,21 @@ static int svdm_response_identity(int port, uint32_t *payload) return VDO_I(PRODUCT) + 1; } -const struct svdm_response svdm_rsp = { +__override const struct svdm_response svdm_rsp = { .identity = &svdm_response_identity, .svids = NULL, .modes = NULL, }; -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - } - - return 0; -} - #ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) +__override void svdm_safe_dp_mode(int port) { /* make DP interface safe until configure */ dp_flags[port] = 0; /* board_set_usb_mux(port, TYPEC_MUX_NONE, pd_get_polarity(port)); */ } -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static int svdm_dp_config(int port, uint32_t *payload) +__override int svdm_dp_config(int port, uint32_t *payload) { int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); @@ -331,7 +232,7 @@ static int svdm_dp_config(int port, uint32_t *payload) return 2; } -static void svdm_dp_post_config(int port) +__override void svdm_dp_post_config(int port) { dp_flags[port] |= DP_FLAGS_DP_ON; if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) @@ -342,7 +243,7 @@ static void svdm_dp_post_config(int port) #endif } -static int svdm_dp_attention(int port, uint32_t *payload) +__override int svdm_dp_attention(int port, uint32_t *payload) { #ifdef CONFIG_USB_PD_TCPM_ANX7447 int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); @@ -357,62 +258,11 @@ static int svdm_dp_attention(int port, uint32_t *payload) return 1; } -static void svdm_exit_dp_mode(int port) +__override void svdm_exit_dp_mode(int port) { svdm_safe_dp_mode(port); #ifdef CONFIG_USB_PD_TCPM_ANX7447 anx7447_tcpc_clear_hpd_status(port); #endif } - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); #endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/plankton/board.h b/board/plankton/board.h index 92201ca68b..a23e861293 100644 --- a/board/plankton/board.h +++ b/board/plankton/board.h @@ -20,6 +20,7 @@ #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_COMM_DISABLED +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_DYNAMIC_SRC_CAP #define CONFIG_USB_PD_IDENTITY_HW_VERS 1 diff --git a/board/plankton/usb_pd_policy.c b/board/plankton/usb_pd_policy.c index e94a88517e..abc5f91f53 100644 --- a/board/plankton/usb_pd_policy.c +++ b/board/plankton/usb_pd_policy.c @@ -31,7 +31,7 @@ const uint32_t pd_src_pdo[] = { PDO_FIXED(12000, 3000, PDO_FIXED_FLAGS), PDO_FIXED(20000, 3000, PDO_FIXED_FLAGS), }; -static const int pd_src_pdo_cnts[3] = { +static const int pd_src_pdo_cnts[] = { [SRC_CAP_5V] = 1, [SRC_CAP_12V] = 2, [SRC_CAP_20V] = 3, @@ -68,12 +68,6 @@ void pd_set_input_current_limit(int port, uint32_t max_ma, return; } -int pd_is_valid_input_voltage(int mv) -{ - /* Any voltage less than the max is allowed */ - return 1; -} - int pd_board_check_request(uint32_t rdo, int pdo_cnt) { int idx = RDO_POS(rdo); @@ -83,7 +77,7 @@ int pd_board_check_request(uint32_t rdo, int pdo_cnt) EC_ERROR_INVAL : EC_SUCCESS; } -void pd_transition_voltage(int idx) +__override void pd_transition_voltage(int idx) { gpio_set_level(GPIO_USBC_VSEL_0, idx >= 2); gpio_set_level(GPIO_USBC_VSEL_1, idx >= 3); @@ -110,7 +104,7 @@ int pd_snk_is_vbus_provided(int port) return gpio_get_level(GPIO_VBUS_WAKE); } -int pd_board_checks(void) +__override int pd_board_checks(void) { static int was_connected = -1; if (was_connected != 1 && pd_is_connected(0)) @@ -119,28 +113,23 @@ int pd_board_checks(void) return EC_SUCCESS; } -int pd_check_power_swap(int port) +__override int pd_check_power_swap(int port) { /* Always allow power swap */ return 1; } -int pd_check_data_swap(int port, int data_role) +__override int pd_check_data_swap(int port, int data_role) { /* Always allow data swap */ return 1; } -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) +__override void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int flags) +__override void pd_check_dr_role(int port, int dr_role, int flags) { /* If Plankton is in USB hub mode, always act as UFP */ if (board_in_hub_mode() && dr_role == PD_ROLE_DFP && @@ -233,7 +222,7 @@ static int dp_config(int port, uint32_t *payload) return 1; } -static int svdm_enter_mode(int port, uint32_t *payload) +int svdm_enter_mode(int port, uint32_t *payload) { int usb_mode = gpio_get_level(GPIO_USBC_SS_USB_MODE); @@ -271,7 +260,7 @@ static struct amode_fx dp_fx = { .config = &dp_config, }; -const struct svdm_response svdm_rsp = { +__override const struct svdm_response svdm_rsp = { .identity = &svdm_response_identity, .svids = &svdm_response_svids, .modes = &svdm_response_modes, @@ -280,7 +269,8 @@ const struct svdm_response svdm_rsp = { .exit_mode = &svdm_exit_mode, }; -int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) +__override int pd_custom_vdm(int port, int cnt, uint32_t *payload, + uint32_t **rpayload) { int cmd = PD_VDO_CMD(payload[0]); int rsize = 1; diff --git a/board/poppy/usb_pd_policy.c b/board/poppy/usb_pd_policy.c index e6dbee1729..56fd4c657c 100644 --- a/board/poppy/usb_pd_policy.c +++ b/board/poppy/usb_pd_policy.c @@ -25,36 +25,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO(crosbug.com/p/61098): fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -155,41 +125,13 @@ int pd_snk_is_vbus_provided(int port) GPIO_USB_C0_VBUS_WAKE_L); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_PMIC_SLP_SUS_L); } -void pd_execute_data_swap(int port, int data_role) +__override void pd_execute_data_swap(int port, int data_role) { /* Only port 0 supports device mode. */ if (port != 0) @@ -200,252 +142,3 @@ void pd_execute_data_swap(int port, int data_role) gpio_set_level(GPIO_USB2_OTG_VBUSSENSE, (data_role == PD_ROLE_UFP) ? 1 : 0); } - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/puff/usb_pd_policy.c b/board/puff/usb_pd_policy.c index bcca6774da..0012512f84 100644 --- a/board/puff/usb_pd_policy.c +++ b/board/puff/usb_pd_policy.c @@ -22,92 +22,12 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow. */ - return (data_role == PD_ROLE_UFP); -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - int pd_check_vconn_swap(int port) { /* Only allow vconn swap if pp5000_A rail is enabled */ return gpio_get_level(GPIO_EN_PP5000_A); } -void pd_execute_data_swap(int port, int data_role) -{ - -} - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - void pd_power_supply_reset(int port) { } @@ -117,11 +37,6 @@ int pd_set_power_supply_ready(int port) return EC_SUCCESS; } -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - #ifdef CONFIG_USB_PD_VBUS_DETECT_PPC int pd_snk_is_vbus_provided(int port) { @@ -129,246 +44,7 @@ int pd_snk_is_vbus_provided(int port) } #endif -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) -{ - ppc_set_vbus_source_current_limit(port, rp); -} - int board_vbus_source_enabled(int port) { return 0; } - - -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - 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 -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - 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; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - 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 -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/rainier/usb_pd_policy.c b/board/rainier/usb_pd_policy.c index e6c092ded9..6de1dc9271 100644 --- a/board/rainier/usb_pd_policy.c +++ b/board/rainier/usb_pd_policy.c @@ -21,39 +21,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, - (int)(PD_MAX_VOLTAGE_MV * 1.05), - PD_OPERATING_POWER_MW), - PDO_VAR(4750, - (int)(PD_MAX_VOLTAGE_MV * 1.05), - PD_MAX_CURRENT_MA), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en; int board_vbus_source_enabled(int port) @@ -89,32 +56,6 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) -{ - /* No-operation */ -} - -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* @@ -123,238 +64,3 @@ int pd_check_vconn_swap(int port) */ return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; } - -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static int svdm_dp_config(int port, uint32_t *payload) -{ - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - 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; -}; - -static void svdm_dp_post_config(int port) -{ - dp_flags[port] |= DP_FLAGS_DP_ON; -} - -static int svdm_dp_attention(int port, uint32_t *payload) -{ - const struct usb_mux *mux = &usb_muxes[port]; - int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); - int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); - int mf_pref = PD_VDO_DPSTS_MF_PREF(payload[1]); - - dp_status[port] = payload[1]; - - mux->hpd_update(port, lvl, irq); - - if (lvl) - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - USB_SWITCH_CONNECT, pd_get_polarity(port)); - else - usb_mux_set(port, mf_pref ? TYPEC_MUX_USB : TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); - - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ - diff --git a/board/rammus/usb_pd_policy.c b/board/rammus/usb_pd_policy.c index b46618feb6..2e5fb868ad 100644 --- a/board/rammus/usb_pd_policy.c +++ b/board/rammus/usb_pd_policy.c @@ -24,36 +24,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO(crosbug.com/p/61098): fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -71,7 +41,7 @@ static void board_vbus_update_source_current(int port) vbus_en[port]); } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) { vbus_rp[port] = rp; @@ -127,41 +97,13 @@ int pd_snk_is_vbus_provided(int port) GPIO_USB_C0_VBUS_DET_L); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_SLP_SUS_L_PMIC); } -void pd_execute_data_swap(int port, int data_role) +__override void pd_execute_data_swap(int port, int data_role) { /* Only port 0 supports device mode. */ if (port != 0) @@ -170,252 +112,3 @@ void pd_execute_data_swap(int port, int data_role) gpio_set_level(GPIO_USB2_ID2, (data_role == PD_ROLE_UFP) ? 1 : 0); } - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/reef/usb_pd_policy.c b/board/reef/usb_pd_policy.c index 9765b540d1..2d2ef416b2 100644 --- a/board/reef/usb_pd_policy.c +++ b/board/reef/usb_pd_policy.c @@ -26,36 +26,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -82,7 +52,7 @@ static void board_vbus_update_source_current(int port) gpio_set_flags(gpio, flags); } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) { vbus_rp[port] = rp; @@ -130,290 +100,8 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_EN_PP5000); } - -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/reef_it8320/usb_pd_policy.c b/board/reef_it8320/usb_pd_policy.c index 03c7569682..87b9c8d42e 100644 --- a/board/reef_it8320/usb_pd_policy.c +++ b/board/reef_it8320/usb_pd_policy.c @@ -26,36 +26,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -75,7 +45,7 @@ static void board_vbus_update_source_current(int port) gpio_set_level(gpio, vbus_en[port]); } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) { vbus_rp[port] = rp; @@ -123,291 +93,8 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_EN_PP5000); } - -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/reef_mchp/usb_pd_policy.c b/board/reef_mchp/usb_pd_policy.c index 1d4212fdcb..90f44f8580 100644 --- a/board/reef_mchp/usb_pd_policy.c +++ b/board/reef_mchp/usb_pd_policy.c @@ -28,36 +28,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -84,7 +54,7 @@ static void board_vbus_update_source_current(int port) gpio_set_flags(gpio, flags); } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) { vbus_rp[port] = rp; @@ -132,297 +102,8 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -/* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ -/* - * !!! WARNING !!! - * Do no put debug in such as MCHP TFDP trace calls - * in this function. This function is pulled into the - * util/genvif code. - */ -int pd_check_data_swap(int port, int data_role) -{ - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in G3, do not allow vconn swap since pp5000_A rail is off */ return gpio_get_level(GPIO_EN_PP5000); } - -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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; -}; - -static void svdm_dp_post_config(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - dp_flags[port] |= DP_FLAGS_DP_ON; - if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) - return; - mux->hpd_update(port, 1, 0); -} - -static 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]); - const struct usb_mux *mux = &usb_muxes[port]; - - dp_status[port] = payload[1]; - if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - mux->hpd_update(port, lvl, irq); - - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/samus_pd/board.h b/board/samus_pd/board.h index 9fc09340c1..8d13c4be12 100644 --- a/board/samus_pd/board.h +++ b/board/samus_pd/board.h @@ -58,6 +58,7 @@ #define CONFIG_USB_PD_ALT_MODE_DFP #define CONFIG_USB_PD_CHECK_MAX_REQUEST_ALLOWED #define CONFIG_USB_PD_COMM_LOCKED +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_TRY_SRC #define CONFIG_USB_PD_FLASH_ERASE_CHECK diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index 40277da8f8..9eed4f77b5 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -48,18 +48,13 @@ const uint32_t pd_snk_pdo[] = { }; const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); -int pd_is_valid_input_voltage(int mv) +__override int pd_is_valid_input_voltage(int mv) { /* Allow any voltage not in the boost bypass deadband */ return (mv < INPUT_VOLTAGE_DEADBAND_MIN) || (mv > INPUT_VOLTAGE_DEADBAND_MAX); } -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int pd_set_power_supply_ready(int port) { /* provide VBUS */ @@ -86,195 +81,15 @@ int pd_snk_is_vbus_provided(int port) GPIO_USB_C0_VBUS_WAKE); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* TODO: use battery level to decide to accept/reject power swap */ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* in S5, do not allow vconn swap since pp5000 rail is off */ return gpio_get_level(GPIO_PCH_SLP_S5_L); } -void pd_execute_data_swap(int port, int data_role) -{ - -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} /* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("ver: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; - } - - return 0; -} - -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - usb_mux_set(port, TYPEC_MUX_NONE, USB_SWITCH_CONNECT, 0); - dp_flags[port] = 0; - dp_status[port] = 0; -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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]); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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_U connected as UFP_D */ - return 2; -}; - #define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) -static void svdm_dp_post_config(int port) +__override void svdm_dp_post_config(int port) { dp_flags[port] |= DP_FLAGS_DP_ON; if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) @@ -299,7 +114,7 @@ DECLARE_DEFERRED(hpd1_irq_deferred); &hpd1_irq_deferred_data : \ &hpd0_irq_deferred_data) -static int svdm_dp_attention(int port, uint32_t *payload) +__override int svdm_dp_attention(int port, uint32_t *payload) { int cur_lvl; int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); @@ -330,59 +145,8 @@ static int svdm_dp_attention(int port, uint32_t *payload) return 1; } -static void svdm_exit_dp_mode(int port) +__override void svdm_exit_dp_mode(int port) { svdm_safe_dp_mode(port); gpio_set_level(PORT_TO_HPD(port), 0); } - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); diff --git a/board/scarlet/usb_pd_policy.c b/board/scarlet/usb_pd_policy.c index 69064fdcf6..a47c15ebdb 100644 --- a/board/scarlet/usb_pd_policy.c +++ b/board/scarlet/usb_pd_policy.c @@ -24,35 +24,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, - (int)(PD_MAX_VOLTAGE_MV * 1.05), - PD_OPERATING_POWER_MW), - PDO_VAR(4750, - (int)(PD_MAX_VOLTAGE_MV * 1.05), - PD_MAX_CURRENT_MA), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - static uint8_t vbus_en; int board_vbus_source_enabled(int port) @@ -90,32 +61,6 @@ void pd_power_supply_reset(int port) pd_send_host_event(PD_EVENT_POWER_CHANGE); } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) -{ - /* No-operation */ -} - -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - int pd_check_vconn_swap(int port) { /* @@ -124,238 +69,3 @@ int pd_check_vconn_swap(int port) */ return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; } - -void pd_execute_data_swap(int port, int data_role) -{ - /* Do nothing */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static int svdm_dp_config(int port, uint32_t *payload) -{ - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - 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; -}; - -static void svdm_dp_post_config(int port) -{ - dp_flags[port] |= DP_FLAGS_DP_ON; -} - -static int svdm_dp_attention(int port, uint32_t *payload) -{ - const struct usb_mux *mux = &usb_muxes[port]; - int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); - int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); - int mf_pref = PD_VDO_DPSTS_MF_PREF(payload[1]); - - dp_status[port] = payload[1]; - - mux->hpd_update(port, lvl, irq); - - if (lvl) - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - USB_SWITCH_CONNECT, pd_get_polarity(port)); - else - usb_mux_set(port, mf_pref ? TYPEC_MUX_USB : TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); - - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - const struct usb_mux *mux = &usb_muxes[port]; - - svdm_safe_dp_mode(port); - mux->hpd_update(port, 0, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ - diff --git a/board/servo_v4/board.h b/board/servo_v4/board.h index a4e4bbd45e..2b302517f6 100644 --- a/board/servo_v4/board.h +++ b/board/servo_v4/board.h @@ -103,6 +103,7 @@ #undef CONFIG_CHARGE_MANAGER_SAFE_MODE #define CONFIG_USB_POWER_DELIVERY #define CONFIG_CMD_PD +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_DYNAMIC_SRC_CAP #define CONFIG_USB_PD_INTERNAL_COMP diff --git a/board/servo_v4/usb_pd_policy.c b/board/servo_v4/usb_pd_policy.c index bb171053bd..d96475217c 100644 --- a/board/servo_v4/usb_pd_policy.c +++ b/board/servo_v4/usb_pd_policy.c @@ -606,13 +606,7 @@ int charge_manager_get_source_pdo(const uint32_t **src_pdo, const int port) return pdo_cnt; } -int pd_is_valid_input_voltage(int mv) -{ - /* Any voltage less than the max is allowed */ - return 1; -} - -void pd_transition_voltage(int idx) +__override void pd_transition_voltage(int idx) { timestamp_t deadline; uint32_t ma, mv; @@ -695,12 +689,7 @@ int pd_snk_is_vbus_provided(int port) GPIO_USB_DET_PP_CHG); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) +__override int pd_check_power_swap(int port) { /* * When only host VBUS is available, then servo_v4 is not setting @@ -720,7 +709,7 @@ int pd_check_power_swap(int port) return 0; } -int pd_check_data_swap(int port, int data_role) +__override int pd_check_data_swap(int port, int data_role) { /* * Servo should allow data role swaps to let DUT see the USB hub, but @@ -732,7 +721,7 @@ int pd_check_data_swap(int port, int data_role) return 1; } -void pd_execute_data_swap(int port, int data_role) +__override void pd_execute_data_swap(int port, int data_role) { /* * TODO(b/137887386): Turn on the fastboot/DFU path when data swap to @@ -740,7 +729,7 @@ void pd_execute_data_swap(int port, int data_role) */ } -void pd_check_pr_role(int port, int pr_role, int flags) +__override void pd_check_pr_role(int port, int pr_role, int flags) { /* * Don't define any policy to initiate power role swap. @@ -750,7 +739,7 @@ void pd_check_pr_role(int port, int pr_role, int flags) */ } -void pd_check_dr_role(int port, int dr_role, int flags) +__override void pd_check_dr_role(int port, int dr_role, int flags) { if (port == CHG) return; @@ -762,13 +751,7 @@ void pd_check_dr_role(int port, int dr_role, int flags) /* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, +__override int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int cmd = PD_VDO_CMD(payload[0]); @@ -793,8 +776,8 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, -const struct svdm_amode_fx supported_modes[] = {}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); +__override const struct svdm_amode_fx supported_modes[] = {}; +__override const int supported_modes_cnt = ARRAY_SIZE(supported_modes); static void print_cc_mode(void) diff --git a/board/strago/board.h b/board/strago/board.h index 1b44868e0a..5a68c49c52 100644 --- a/board/strago/board.h +++ b/board/strago/board.h @@ -39,6 +39,7 @@ #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_DP_HPD_GPIO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_PORT_MAX_COUNT 1 #define CONFIG_USB_PD_TCPM_TCPCI @@ -200,6 +201,8 @@ enum als_id { /* Reset PD MCU */ void board_reset_pd_mcu(void); +#define PORT_TO_HPD(port) (GPIO_USB_C0_DP_HPD) + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/strago/usb_pd_policy.c b/board/strago/usb_pd_policy.c index 0a12fec103..b44726ae96 100644 --- a/board/strago/usb_pd_policy.c +++ b/board/strago/usb_pd_policy.c @@ -21,32 +21,6 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -/* TODO: fill in correct source and sink capabilities */ -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int pd_set_power_supply_ready(int port) { /* Disable charging */ @@ -68,292 +42,3 @@ int pd_snk_is_vbus_provided(int port) { return !gpio_get_level(GPIO_USB_C0_VBUS_WAKE_L); } - -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; -} - -void pd_execute_data_swap(int port, int data_role) -{ - /* TODO: need to open/close D+/D- switch based on role */ -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) - pd_request_data_swap(port); -} - -/* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags; -/* DP Status VDM as returned by UFP */ -static uint32_t dp_status; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags = 0; - dp_status = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - return 0; - } - - return -1; -} - -static 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 & DP_FLAGS_DP_ON)), - 0, /* power low? ... no */ - (!!(dp_flags & DP_FLAGS_DP_ON))); - return 2; -}; - -static 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); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status); - - if (!pin_mode) - return 0; - - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - 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. - */ -static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_dp_post_config(int port) -{ - dp_flags |= DP_FLAGS_DP_ON; - if (!(dp_flags & DP_FLAGS_HPD_HI_PENDING)) - return; - - gpio_set_level(GPIO_USB_C0_DP_HPD, 1); - /* set the minimum time delay (2ms) for the next HPD IRQ */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; -} - -static int svdm_dp_attention(int port, uint32_t *payload) -{ - int cur_lvl; - int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); - int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); - enum gpio_signal hpd = GPIO_USB_C0_DP_HPD; - cur_lvl = gpio_get_level(hpd); - - dp_status = payload[1]; - - /* Its initial DP status message prior to config */ - if (!(dp_flags & DP_FLAGS_DP_ON)) { - if (lvl) - dp_flags |= DP_FLAGS_HPD_HI_PENDING; - return 1; - } - - if (irq & cur_lvl) { - uint64_t now = get_time().val; - /* wait for the minimum spacing between IRQ_HPD if needed */ - if (now < hpd_deadline[port]) - usleep(hpd_deadline[port] - now); - - /* generate IRQ_HPD pulse */ - gpio_set_level(hpd, 0); - usleep(HPD_DSTREAM_DEBOUNCE_IRQ); - gpio_set_level(GPIO_USB_C0_DP_HPD, 1); - - /* set the minimum time delay (2ms) for the next HPD IRQ */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - } else if (irq & !cur_lvl) { - 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 */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - } - /* ack */ - return 1; -} - -static void svdm_exit_dp_mode(int port) -{ - svdm_safe_dp_mode(port); - gpio_set_level(GPIO_USB_C0_DP_HPD, 0); -} - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/trogdor/usb_pd_policy.c b/board/trogdor/usb_pd_policy.c index 14c0ead6b6..7494a46f0b 100644 --- a/board/trogdor/usb_pd_policy.c +++ b/board/trogdor/usb_pd_policy.c @@ -16,100 +16,12 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) -#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -const uint32_t pd_src_pdo[] = { - PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); -const uint32_t pd_src_pdo_max[] = { - PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), -}; -const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max); - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_data_swap(int port, int data_role) -{ - /* - * Allow data swap if we are a UFP, otherwise don't allow. - * - * When we are still in the Read-Only firmware, avoid swapping roles - * so we don't jump in RW as a SNK/DFP and potentially confuse the - * power supply by sending a soft-reset with wrong data role. - */ - - return (data_role == PD_ROLE_UFP) && - (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; -} - -void pd_check_dr_role(int port, int dr_role, int flags) -{ - /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && - dr_role == PD_ROLE_UFP && - system_get_image_copy() != SYSTEM_IMAGE_RO) - pd_request_data_swap(port); -} - -int pd_check_power_swap(int port) -{ - /* - * Allow power swap as long as we are acting as a dual role device, - * otherwise assume our role is fixed (not in S0 or console command - * to fix our role). - */ - return pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0; -} - -void pd_check_pr_role(int port, int pr_role, int flags) -{ - /* - * If partner is dual-role power and dualrole toggling is on, consider - * if a power swap is necessary. - */ - if ((flags & PD_FLAGS_PARTNER_DR_POWER) && - pd_get_dual_role(port) == PD_DRP_TOGGLE_ON) { - /* - * If we are a sink and partner is not externally powered, then - * swap to become a source. If we are source and partner is - * externally powered, swap to become a sink. - */ - int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; - - if ((!partner_extpower && pr_role == PD_ROLE_SINK) || - (partner_extpower && pr_role == PD_ROLE_SOURCE)) - pd_request_power_swap(port); - } -} - int pd_check_vconn_swap(int port) { /* In G3, do not allow vconn swap since PP5000 rail is off */ return gpio_get_level(GPIO_EN_PP5000); } -void pd_execute_data_swap(int port, int data_role) -{ - /* Both ports don't support device mode. Should not reach here. */ -} - -int pd_is_valid_input_voltage(int mv) -{ - return 1; -} - static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5}; @@ -164,17 +76,12 @@ int pd_set_power_supply_ready(int port) return EC_SUCCESS; /* we are ready */ } -void pd_transition_voltage(int idx) -{ - /* No-operation: we are always 5V */ -} - int board_vbus_source_enabled(int port) { return vbus_en[port]; } -void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) { vbus_rp[port] = rp; board_vbus_update_source_current(port); @@ -187,141 +94,8 @@ int pd_snk_is_vbus_provided(int port) } /* ----------------- Vendor Defined Messages ------------------ */ -const struct svdm_response svdm_rsp = { - .identity = NULL, - .svids = NULL, - .modes = NULL, -}; - -int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - uint16_t dev_id = 0; - int is_rw, is_latest; - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("version: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_READ_INFO: - case VDO_CMD_SEND_INFO: - /* copy hash */ - if (cnt == 7) { - dev_id = VDO_INFO_HW_DEV_ID(payload[6]); - is_rw = VDO_INFO_IS_RW(payload[6]); - - is_latest = pd_dev_store_rw_hash(port, - dev_id, - payload + 1, - is_rw ? - SYSTEM_IMAGE_RW : - SYSTEM_IMAGE_RO); - /* - * Send update host event unless our RW hash is - * already known to be the latest update RW. - */ - if (!is_rw || !is_latest) - pd_send_host_event(PD_EVENT_UPDATE_DEVICE); - - CPRINTF("DevId:%d.%d SW:%d RW:%d\n", - HW_DEV_ID_MAJ(dev_id), - HW_DEV_ID_MIN(dev_id), - VDO_INFO_SW_DBG_VER(payload[6]), - is_rw); - } else if (cnt == 6) { - /* really old devices don't have last byte */ - pd_dev_store_rw_hash(port, dev_id, payload + 1, - SYSTEM_IMAGE_UNKNOWN); - } - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - case VDO_CMD_FLIP: - usb_mux_flip(port); - break; -#ifdef CONFIG_USB_PD_LOGGING - case VDO_CMD_GET_LOG: - pd_log_recv_vdm(port, cnt, payload); - break; -#endif /* CONFIG_USB_PD_LOGGING */ - } - - return 0; -} - #ifdef CONFIG_USB_PD_ALT_MODE_DFP -static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - usb_mux_set(port, TYPEC_MUX_NONE, - USB_SWITCH_CONNECT, pd_get_polarity(port)); -} - -static int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Only enter mode if device is DFP_D capable */ - if (mode_caps & MODE_DP_SNK) { - svdm_safe_dp_mode(port); - - if (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; -} - -static 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[port] & DP_FLAGS_DP_ON))); - return 2; -}; - -static int svdm_dp_config(int port, uint32_t *payload) -{ - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); - int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); - - if (!pin_mode) - return 0; - - 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; -}; - -static void svdm_dp_post_config(int port) +__override void svdm_dp_post_config(int port) { dp_flags[port] |= DP_FLAGS_DP_ON; } @@ -353,7 +127,7 @@ static int is_dp_muxable(int port) */ static uint64_t hpd_deadline; -static int svdm_dp_attention(int port, uint32_t *payload) +__override int svdm_dp_attention(int port, uint32_t *payload) { enum gpio_signal hpd = GPIO_DP_HOT_PLUG_DET; int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); @@ -436,62 +210,11 @@ static int svdm_dp_attention(int port, uint32_t *payload) return 1; /* Ack */ } -static void svdm_exit_dp_mode(int port) +__override void svdm_exit_dp_mode(int port) { const struct usb_mux *mux = &usb_muxes[port]; svdm_safe_dp_mode(port); mux->hpd_update(port, 0, 0); } - -static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -{ - /* Always enter GFU mode */ - return 0; -} - -static void svdm_exit_gfu_mode(int port) -{ -} - -static 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; -} - -static int svdm_gfu_config(int port, uint32_t *payload) -{ - return 0; -} - -static int svdm_gfu_attention(int port, uint32_t *payload) -{ - return 0; -} - -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, - } -}; -const int supported_modes_cnt = ARRAY_SIZE(supported_modes); #endif /* CONFIG_USB_PD_ALT_MODE_DFP */ diff --git a/board/twinkie/board.h b/board/twinkie/board.h index 42944f37f1..1467871f34 100644 --- a/board/twinkie/board.h +++ b/board/twinkie/board.h @@ -21,6 +21,7 @@ #define CONFIG_WEBUSB_URL "storage.googleapis.com/webtwinkie.org/tool.html" #define CONFIG_USB_POWER_DELIVERY +#define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_INTERNAL_COMP #define CONFIG_USB_PD_PORT_MAX_COUNT 1 diff --git a/board/twinkie/usb_pd_policy.c b/board/twinkie/usb_pd_policy.c index 1b1801fa43..d4fc43d3b9 100644 --- a/board/twinkie/usb_pd_policy.c +++ b/board/twinkie/usb_pd_policy.c @@ -44,16 +44,6 @@ void pd_set_input_current_limit(int port, uint32_t max_ma, gpio_set_level(GPIO_LED_B_L, !blue); } -int pd_is_valid_input_voltage(int mv) -{ - /* Any voltage less than the max is allowed */ - return 1; -} - -void pd_transition_voltage(int idx) -{ -} - int pd_set_power_supply_ready(int port) { return EC_SUCCESS; /* we are ready */ @@ -69,37 +59,27 @@ int pd_snk_is_vbus_provided(int port) return (gpio_get_level(GPIO_VBUS_ALERT_L) == 0); } -int pd_board_checks(void) -{ - return EC_SUCCESS; -} - -int pd_check_power_swap(int port) +__override int pd_check_power_swap(int port) { /* Always refuse power swap */ return 0; } -int pd_check_data_swap(int port, int data_role) +__override int pd_check_data_swap(int port, int data_role) { /* Always allow data swap */ return 1; } -void pd_check_pr_role(int port, int pr_role, int flags) -{ -} - -void pd_check_dr_role(int port, int dr_role, int flags) +__override void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_execute_data_swap(int port, int data_role) +__override void pd_check_dr_role(int port, int dr_role, int flags) { - /* Do nothing */ } -int pd_custom_vdm(int port, int cnt, uint32_t *payload, +__override int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { return 0; diff --git a/board/zinger/board.h b/board/zinger/board.h index 83ec02221c..f79faca03f 100644 --- a/board/zinger/board.h +++ b/board/zinger/board.h @@ -54,6 +54,7 @@ #undef CONFIG_TASK_PROFILING #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE +#define CONFIG_USB_PD_CUSTOM_PDO #undef CONFIG_USB_PD_DUAL_ROLE #undef CONFIG_USB_PD_INTERNAL_COMP #define CONFIG_USB_PD_LOGGING diff --git a/board/zinger/usb_pd_policy.c b/board/zinger/usb_pd_policy.c index 52a87c285b..0ea132945c 100644 --- a/board/zinger/usb_pd_policy.c +++ b/board/zinger/usb_pd_policy.c @@ -524,7 +524,7 @@ const struct svdm_response svdm_rsp = { .exit_mode = &svdm_exit_mode, }; -int pd_custom_vdm(int port, int cnt, uint32_t *payload, +__override int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int cmd = PD_VDO_CMD(payload[0]); |