summaryrefslogtreecommitdiff
path: root/board/samus_pd/usb_pd_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/samus_pd/usb_pd_policy.c')
-rw-r--r--board/samus_pd/usb_pd_policy.c32
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,
},