diff options
Diffstat (limited to 'baseboard/kukui/usb_pd_policy.c')
-rw-r--r-- | baseboard/kukui/usb_pd_policy.c | 298 |
1 files changed, 0 insertions, 298 deletions
diff --git a/baseboard/kukui/usb_pd_policy.c b/baseboard/kukui/usb_pd_policy.c deleted file mode 100644 index 28ef005ee8..0000000000 --- a/baseboard/kukui/usb_pd_policy.c +++ /dev/null @@ -1,298 +0,0 @@ -/* Copyright 2018 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "charge_manager.h" -#include "charge_state_v2.h" -#include "charger.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "system.h" -#include "timer.h" -#include "usb_mux.h" -#include "usb_pd.h" -#include "usb_pd_policy.h" -#include "util.h" - -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) - -static int board_get_polarity(int port) -{ - /* Krane's aux mux polarity is reversed. Workaround to flip it back. */ - if (IS_ENABLED(BOARD_KRANE) && board_get_version() == 3) - return !polarity_rm_dts(pd_get_polarity(port)); - - return polarity_rm_dts(pd_get_polarity(port)); -} - -static uint8_t vbus_en; - -#define VBUS_EN_SYSJUMP_TAG 0x5645 /* VE */ -#define VBUS_EN_HOOK_VERSION 1 - -static void vbus_en_preserve_state(void) -{ - system_add_jump_tag(VBUS_EN_SYSJUMP_TAG, VBUS_EN_HOOK_VERSION, - sizeof(vbus_en), &vbus_en); -} -DECLARE_HOOK(HOOK_SYSJUMP, vbus_en_preserve_state, HOOK_PRIO_DEFAULT); - -static void vbus_en_restore_state(void) -{ - const uint8_t *prev_vbus_en; - int size, version; - - prev_vbus_en = (const uint8_t *)system_get_jump_tag( - VBUS_EN_SYSJUMP_TAG, &version, &size); - - if (prev_vbus_en && version == VBUS_EN_HOOK_VERSION && - size == sizeof(*prev_vbus_en)) { - memcpy(&vbus_en, prev_vbus_en, sizeof(vbus_en)); - } -} -DECLARE_HOOK(HOOK_INIT, vbus_en_restore_state, HOOK_PRIO_DEFAULT); - -int board_vbus_source_enabled(int port) -{ - return vbus_en; -} - -int board_is_sourcing_vbus(int port) -{ - if (IS_ENABLED(BOARD_KUKUI) && board_get_version() <= 1) - return charger_is_sourcing_otg_power(port); - else - return board_vbus_source_enabled(port); -} - -int pd_set_power_supply_ready(int port) -{ - if (port != CHARGE_PORT_USB_C) - return EC_ERROR_INVAL; - - pd_set_vbus_discharge(port, 0); - /* Provide VBUS */ - vbus_en = 1; - -#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT - /* Ensure we advertise the proper available current quota */ - charge_manager_source_port(port, 1); -#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */ - - if (IS_ENABLED(VARIANT_KUKUI_CHARGER_ISL9238)) - charge_set_output_current_limit(CHARGER_SOLO, 3300, 5000); - else - charger_enable_otg_power(CHARGER_SOLO, 1); - - gpio_set_level(GPIO_EN_USBC_CHARGE_L, 1); - gpio_set_level(GPIO_EN_PP5000_USBC, 1); - if (IS_ENABLED(CONFIG_CHARGER_OTG) && IS_ENABLED(CONFIG_CHARGER_ISL9238C)) - charger_set_current(CHARGER_SOLO, 0); - - /* notify host of power info change */ - pd_send_host_event(PD_EVENT_POWER_CHANGE); - - return EC_SUCCESS; /* we are ready */ -} - -void pd_power_supply_reset(int port) -{ - int prev_en; - - if (port != CHARGE_PORT_USB_C) - return; - - prev_en = vbus_en; - /* Disable VBUS */ - vbus_en = 0; - /* Enable discharge if we were previously sourcing 5V */ - if (prev_en) - pd_set_vbus_discharge(port, 1); - -#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT - /* Give back the current quota we are no longer using */ - charge_manager_source_port(port, 0); -#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */ - - if (IS_ENABLED(VARIANT_KUKUI_CHARGER_ISL9238)) - charge_set_output_current_limit(CHARGER_SOLO, 0, 0); - else - charger_enable_otg_power(CHARGER_SOLO, 0); - - gpio_set_level(GPIO_EN_PP5000_USBC, 0); - - /* notify host of power info change */ - pd_send_host_event(PD_EVENT_POWER_CHANGE); -} - -int pd_check_vconn_swap(int port) -{ - /* always allow vconn swap, since PSYS sources VCONN */ - return 1; -} - -/* ----------------- Vendor Defined Messages ------------------ */ -#ifdef CONFIG_USB_PD_ALT_MODE_DFP -__overridable int board_has_virtual_mux(void) -{ - return IS_ENABLED(CONFIG_USB_MUX_VIRTUAL); -} - -static void board_usb_mux_set(int port, mux_state_t mux_mode, - enum usb_switch usb_mode, int polarity) -{ - usb_mux_set(port, mux_mode, usb_mode, polarity); - - if (!board_has_virtual_mux()) - /* b:149181702: Inform AP of DP status */ - host_set_single_event(EC_HOST_EVENT_USB_MUX); -} - -__override void svdm_safe_dp_mode(int port) -{ - /* make DP interface safe until configure */ - dp_flags[port] = 0; - dp_status[port] = 0; - board_usb_mux_set(port, USB_PD_MUX_NONE, USB_SWITCH_CONNECT, - board_get_polarity(port)); -} - -__override int svdm_enter_dp_mode(int port, uint32_t mode_caps) -{ - /* Kukui/Krane doesn't support superspeed lanes. */ - const uint32_t support_pin_mode = board_has_virtual_mux() ? - (MODE_DP_PIN_C | MODE_DP_PIN_E) : MODE_DP_PIN_ALL; - - /** - * Only enter mode if device is DFP_D (and PIN_C/E for Kukui/Krane) - * capable - */ - if ((mode_caps & MODE_DP_SNK) && - (mode_caps & ((support_pin_mode << MODE_DP_DFP_PIN_SHIFT) | - (support_pin_mode << MODE_DP_UFP_PIN_SHIFT)))) { - svdm_safe_dp_mode(port); - return 0; - } - - CPRINTS("ERR:DP mode SNK or C&E missing! 0x%x", mode_caps); - return -1; -} - -__override int svdm_dp_config(int port, uint32_t *payload) -{ - int opos = pd_alt_mode(port, TCPCI_MSG_SOP, USB_SID_DISPLAYPORT); - int status = dp_status[port]; - int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]); - int pin_mode; - - /* Kukui doesn't support multi-function mode, mask it out. */ - if (board_has_virtual_mux()) - status &= ~PD_VDO_DPSTS_MF_MASK; - - pin_mode = pd_dfp_dp_get_pin_mode(port, status); - - if (!pin_mode) - return 0; - - if (board_has_virtual_mux()) - board_usb_mux_set(port, USB_PD_MUX_DP_ENABLED, - USB_SWITCH_CONNECT, board_get_polarity(port)); - else - board_usb_mux_set( - port, mf_pref ? USB_PD_MUX_DOCK : USB_PD_MUX_DP_ENABLED, - USB_SWITCH_CONNECT, board_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; -}; - -__override 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(GPIO_USB_C0_HPD_OD, 1); -#ifdef VARIANT_KUKUI_DP_MUX_GPIO - board_set_dp_mux_control(1, board_get_polarity(port)); -#endif - - /* set the minimum time delay (2ms) for the next HPD IRQ */ - svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; - - usb_mux_hpd_update(port, USB_PD_MUX_HPD_LVL | - USB_PD_MUX_HPD_IRQ_DEASSERTED); -} - -__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]); - int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); - mux_state_t mux_state; - - 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_state = (lvl ? USB_PD_MUX_HPD_LVL : USB_PD_MUX_HPD_LVL_DEASSERTED) | - (irq ? USB_PD_MUX_HPD_IRQ : USB_PD_MUX_HPD_IRQ_DEASSERTED); - usb_mux_hpd_update(port, mux_state); - - if (irq & cur_lvl) { - uint64_t now = get_time().val; - /* wait for the minimum spacing between IRQ_HPD if needed */ - if (now < svdm_hpd_deadline[port]) - usleep(svdm_hpd_deadline[port] - now); - - /* generate IRQ_HPD pulse */ - gpio_set_level(GPIO_USB_C0_HPD_OD, 0); - usleep(HPD_DSTREAM_DEBOUNCE_IRQ); - gpio_set_level(GPIO_USB_C0_HPD_OD, 1); - -#ifdef VARIANT_KUKUI_DP_MUX_GPIO - board_set_dp_mux_control(1, board_get_polarity(port)); -#endif - - /* set the minimum time delay (2ms) for the next HPD IRQ */ - svdm_hpd_deadline[port] = get_time().val + - HPD_USTREAM_DEBOUNCE_LVL; - } else if (irq & !lvl) { - CPRINTF("ERR:HPD:IRQ&LOW\n"); - return 0; /* nak */ - } else { - gpio_set_level(GPIO_USB_C0_HPD_OD, lvl); -#ifdef VARIANT_KUKUI_DP_MUX_GPIO - board_set_dp_mux_control(lvl, board_get_polarity(port)); -#endif - /* set the minimum time delay (2ms) for the next HPD IRQ */ - svdm_hpd_deadline[port] = get_time().val + - HPD_USTREAM_DEBOUNCE_LVL; - } - - /* ack */ - return 1; -} - -__override void svdm_exit_dp_mode(int port) -{ - gpio_set_level(GPIO_USB_C0_HPD_OD, 0); -#ifdef VARIANT_KUKUI_DP_MUX_GPIO - board_set_dp_mux_control(0, 0); -#endif - usb_mux_hpd_update(port, USB_PD_MUX_HPD_LVL_DEASSERTED | - USB_PD_MUX_HPD_IRQ_DEASSERTED); -} -#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ |