summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
Diffstat (limited to 'board')
-rw-r--r--board/dingdong/usb_pd_policy.c54
-rw-r--r--board/fruitpie/usb_pd_policy.c30
-rw-r--r--board/hoho/usb_pd_policy.c51
-rw-r--r--board/samus_pd/usb_pd_policy.c40
4 files changed, 151 insertions, 24 deletions
diff --git a/board/dingdong/usb_pd_policy.c b/board/dingdong/usb_pd_policy.c
index 61a3bd8f33..64663172f3 100644
--- a/board/dingdong/usb_pd_policy.c
+++ b/board/dingdong/usb_pd_policy.c
@@ -143,35 +143,67 @@ static int svdm_response_modes(int port, uint32_t *payload)
return mode_cnt + 1;
}
+static int hpd_get_irq(int port)
+{
+ /* TODO(tbroch) FIXME */
+ return 0;
+}
+
+static enum hpd_level hpd_get_level(int port)
+{
+ /* TODO(tbroch) FIXME: needs debounce */
+ return gpio_get_level(GPIO_DP_HPD);
+}
+
+static int dp_status(int port, uint32_t *payload)
+{
+ uint32_t ufp_dp_sts = payload[1] & 0x3;
+ payload[1] = VDO_DP_STATUS(hpd_get_irq(port), /* IRQ_HPD */
+ hpd_get_level(port), /* HPD_HI|LOW */
+ 0, /* request exit DP */
+ 0, /* request exit USB */
+ 0, /* MF pref */
+ gpio_get_level(GPIO_PD_SBU_ENABLE),
+ 0, /* power low */
+ (ufp_dp_sts | 0x2));
+ return 2;
+}
+
+static int dp_config(int port, uint32_t *payload)
+{
+ if (PD_DP_CFG_DPON(payload[1])) {
+ gpio_set_level(GPIO_PD_SBU_ENABLE, 1);
+ payload[1] = 0;
+ }
+ return 2;
+}
+
static int svdm_enter_mode(int port, uint32_t *payload)
{
/* SID & mode request is valid */
if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) ||
(PD_VDO_OPOS(payload[0]) != 1))
- return 1; /* will generate a NAK */
-
- gpio_set_level(GPIO_PD_SBU_ENABLE, 1);
- payload[1] = 0;
+ return 0; /* will generate NAK */
return 1;
}
static int svdm_exit_mode(int port, uint32_t *payload)
{
- /* SID & mode request is valid */
- if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) ||
- (PD_VDO_OPOS(payload[0]) != 1))
- return 1; /* will generate a NAK */
-
gpio_set_level(GPIO_PD_SBU_ENABLE, 0);
- payload[1] = 0;
- return 1;
+ return 1; /* Must return ACK */
}
+static struct amode_fx dp_fx = {
+ .status = &dp_status,
+ .config = &dp_config,
+};
+
const struct svdm_response svdm_rsp = {
.identity = &svdm_response_identity,
.svids = &svdm_response_svids,
.modes = &svdm_response_modes,
.enter_mode = &svdm_enter_mode,
+ .amode = &dp_fx,
.exit_mode = &svdm_exit_mode,
};
diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c
index 1cceb0b6b6..8a80175c4f 100644
--- a/board/fruitpie/usb_pd_policy.c
+++ b/board/fruitpie/usb_pd_policy.c
@@ -192,6 +192,34 @@ static void svdm_enter_dp_mode(int port, uint32_t mode_caps)
CPRINTF("Entering mode w/ vdo = %08x\n", mode_caps);
}
+static int dp_on;
+
+static int svdm_dp_status(int port, uint32_t *payload)
+{
+ payload[0] = VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_STATUS);
+ 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_on,
+ 0, /* power low? ... no */
+ 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);
+ payload[1] = VDO_DP_CFG(MODE_DP_PIN_E, /* sink pins */
+ MODE_DP_PIN_E, /* src pins */
+ 0, /* signalling unspec'd */
+ 2); /* UFP connected */
+ return 2;
+};
+
static void svdm_exit_dp_mode(int port)
{
CPRINTF("Exiting mode\n");
@@ -202,6 +230,8 @@ const struct svdm_amode_fx supported_modes[] = {
{
.svid = USB_SID_DISPLAYPORT,
.enter = &svdm_enter_dp_mode,
+ .status = &svdm_dp_status,
+ .config = &svdm_dp_config,
.exit = &svdm_exit_dp_mode,
},
};
diff --git a/board/hoho/usb_pd_policy.c b/board/hoho/usb_pd_policy.c
index dd94ed1413..7560821c1d 100644
--- a/board/hoho/usb_pd_policy.c
+++ b/board/hoho/usb_pd_policy.c
@@ -143,35 +143,64 @@ static int svdm_response_modes(int port, uint32_t *payload)
return mode_cnt + 1;
}
-static int svdm_enter_mode(int port, uint32_t *payload)
+static int hpd_get_irq(int port)
{
- /* SID & mode request is valid */
- if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) ||
- (PD_VDO_OPOS(payload[0]) != 1))
- return 1; /* will generate a NAK */
+ /* TODO(tbroch) FIXME */
+ return 0;
+}
+
+static enum hpd_level hpd_get_level(int port)
+{
+ return gpio_get_level(GPIO_DP_HPD);
+}
+
+static int dp_status(int port, uint32_t *payload)
+{
+ uint32_t ufp_dp_sts = payload[1] & 0x3;
+ payload[1] = VDO_DP_STATUS(hpd_get_irq(port), /* IRQ_HPD */
+ hpd_get_level(port), /* HPD_HI|LOW */
+ 0, /* request exit DP */
+ 0, /* request exit USB */
+ 0, /* MF pref */
+ gpio_get_level(GPIO_PD_SBU_ENABLE),
+ 0, /* power low */
+ (ufp_dp_sts | 0x2));
+ return 2;
+}
- gpio_set_level(GPIO_PD_SBU_ENABLE, 1);
- payload[1] = 0;
+static int dp_config(int port, uint32_t *payload)
+{
+ if (PD_DP_CFG_DPON(payload[1]))
+ gpio_set_level(GPIO_PD_SBU_ENABLE, 1);
return 1;
}
-static int svdm_exit_mode(int port, uint32_t *payload)
+static int svdm_enter_mode(int port, uint32_t *payload)
{
/* SID & mode request is valid */
if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) ||
(PD_VDO_OPOS(payload[0]) != 1))
- return 1; /* will generate a NAK */
+ return 0; /* will generate a NAK */
+ return 1;
+}
+static int svdm_exit_mode(int port, uint32_t *payload)
+{
gpio_set_level(GPIO_PD_SBU_ENABLE, 0);
- payload[1] = 0;
- return 1;
+ return 1; /* Must return ACK */
}
+static struct amode_fx dp_fx = {
+ .status = &dp_status,
+ .config = &dp_config,
+};
+
const struct svdm_response svdm_rsp = {
.identity = &svdm_response_identity,
.svids = &svdm_response_svids,
.modes = &svdm_response_modes,
.enter_mode = &svdm_enter_mode,
+ .amode = &dp_fx,
.exit_mode = &svdm_exit_mode,
};
diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c
index 4d5b4e4d12..403adb9af1 100644
--- a/board/samus_pd/usb_pd_policy.c
+++ b/board/samus_pd/usb_pd_policy.c
@@ -218,20 +218,56 @@ int pd_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
return pd_custom_vdm(port, cnt, payload, rpayload);
}
+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));
+}
+
static void svdm_enter_dp_mode(int port, uint32_t mode_caps)
{
- board_set_usb_mux(port, TYPEC_MUX_DP, pd_get_polarity(port));
+ svdm_safe_dp_mode(port);
}
+static int dp_on;
+
+static int svdm_dp_status(int port, uint32_t *payload)
+{
+ payload[0] = VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_STATUS);
+ 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_on,
+ 0, /* power low? ... no */
+ 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);
+ payload[1] = VDO_DP_CFG(MODE_DP_PIN_E, /* sink pins */
+ MODE_DP_PIN_E, /* src pins */
+ 0, /* signalling unspec'd */
+ 2); /* UFP connected */
+ return 2;
+};
+
static void svdm_exit_dp_mode(int port)
{
- board_set_usb_mux(port, TYPEC_MUX_NONE, pd_get_polarity(port));
+ svdm_safe_dp_mode(port);
}
const struct svdm_amode_fx supported_modes[] = {
{
.svid = USB_SID_DISPLAYPORT,
.enter = &svdm_enter_dp_mode,
+ .status = &svdm_dp_status,
+ .config = &svdm_dp_config,
.exit = &svdm_exit_dp_mode,
},
};