diff options
Diffstat (limited to 'board/samus_pd/usb_pd_policy.c')
-rw-r--r-- | board/samus_pd/usb_pd_policy.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index 8ba4d7a327..ca16c5759d 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -17,6 +17,7 @@ #include "timer.h" #include "util.h" #include "usb_pd.h" +#include "usb_pd_config.h" #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) @@ -215,10 +216,13 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, return 0; } +static int dp_flags[PD_PORT_COUNT]; + static void svdm_safe_dp_mode(int port) { /* make DP interface safe until configure */ board_set_usb_mux(port, TYPEC_MUX_NONE, pd_get_polarity(port)); + dp_flags[port] = 0; } static int svdm_enter_dp_mode(int port, uint32_t mode_caps) @@ -232,8 +236,6 @@ static int svdm_enter_dp_mode(int port, uint32_t mode_caps) return -1; } -static int dp_on; - static int svdm_dp_status(int port, uint32_t *payload) { payload[0] = VDO(USB_SID_DISPLAYPORT, 1, @@ -243,16 +245,15 @@ static int svdm_dp_status(int port, uint32_t *payload) 0, /* exit DP? ... no */ 0, /* usb mode? ... no */ 0, /* multi-function ... no */ - dp_on, + (!!(dp_flags[port] & DP_FLAGS_DP_ON)), 0, /* power low? ... no */ - dp_on); + (!!(dp_flags[port] & DP_FLAGS_DP_ON))); return 2; }; static int svdm_dp_config(int port, uint32_t *payload) { board_set_usb_mux(port, TYPEC_MUX_DP, pd_get_polarity(port)); - dp_on = 1; payload[0] = VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_CONFIG | VDO_OPOS(pd_alt_mode(port))); payload[1] = VDO_DP_CFG(MODE_DP_PIN_E, /* sink pins */ @@ -262,6 +263,18 @@ static int svdm_dp_config(int port, uint32_t *payload) 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; + + if (port) + gpio_set_level(GPIO_USB_C1_DP_HPD, 1); + else + gpio_set_level(GPIO_USB_C0_DP_HPD, 1); +} + static void hpd0_irq_deferred(void) { gpio_set_level(GPIO_USB_C0_DP_HPD, 1); @@ -284,6 +297,14 @@ static int svdm_dp_attention(int port, uint32_t *payload) int irq = PD_VDO_HPD_IRQ(payload[1]); enum gpio_signal hpd = PORT_TO_HPD(port); cur_lvl = gpio_get_level(hpd); + + /* 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) { gpio_set_level(hpd, 0); /* 250 usecs is minimum, 2msec is max */ @@ -343,6 +364,7 @@ const struct svdm_amode_fx supported_modes[] = { .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, }, |