diff options
Diffstat (limited to 'board')
-rw-r--r-- | board/dingdong/usb_pd_policy.c | 54 | ||||
-rw-r--r-- | board/fruitpie/usb_pd_policy.c | 30 | ||||
-rw-r--r-- | board/hoho/usb_pd_policy.c | 51 | ||||
-rw-r--r-- | board/samus_pd/usb_pd_policy.c | 40 |
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, }, }; |