diff options
Diffstat (limited to 'board')
-rw-r--r-- | board/dingdong/usb_pd_policy.c | 46 | ||||
-rw-r--r-- | board/fruitpie/usb_pd_policy.c | 7 | ||||
-rw-r--r-- | board/hoho/usb_pd_policy.c | 46 | ||||
-rw-r--r-- | board/samus_pd/usb_pd_policy.c | 42 |
4 files changed, 92 insertions, 49 deletions
diff --git a/board/dingdong/usb_pd_policy.c b/board/dingdong/usb_pd_policy.c index fa0894e509..97504a1cbf 100644 --- a/board/dingdong/usb_pd_policy.c +++ b/board/dingdong/usb_pd_policy.c @@ -124,7 +124,14 @@ static int svdm_response_svids(int port, uint32_t *payload) return 2; } -const uint32_t vdo_dp_mode[1] = { +/* Will only ever be a single mode for this UFP_D device as it has no USB + * support (2.0 or 3.0) making it only PIN_E configureable nor does it have any + * source functionality. + */ +#define MODE_CNT 1 +#define OPOS 1 + +const uint32_t vdo_dp_mode[MODE_CNT] = { VDO_MODE_DP(0, /* UFP pin cfg supported : none */ MODE_DP_PIN_E, /* DFP pin cfg supported */ 1, /* no usb2.0 signalling in AMode */ @@ -135,57 +142,46 @@ const uint32_t vdo_dp_mode[1] = { static int svdm_response_modes(int port, uint32_t *payload) { - int mode_cnt = ARRAY_SIZE(vdo_dp_mode); - if (PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) { /* TODO(tbroch) USB billboard enabled here then */ return 1; /* will generate a NAK */ } memcpy(payload + 1, vdo_dp_mode, sizeof(vdo_dp_mode)); - 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); + return MODE_CNT + 1; } 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 */ + int opos = PD_VDO_OPOS(payload[0]); + int hpd = gpio_get_level(GPIO_DP_HPD); + if (opos != OPOS) + return 0; /* nak */ + + payload[1] = VDO_DP_STATUS(0, /* IRQ_HPD */ + (hpd == 1), /* 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)); + 0x2); return 2; } static int dp_config(int port, uint32_t *payload) { - if (PD_DP_CFG_DPON(payload[1])) { + if (PD_DP_CFG_DPON(payload[1])) gpio_set_level(GPIO_PD_SBU_ENABLE, 1); - payload[1] = 0; - } - return 2; + + return 1; } 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)) + (PD_VDO_OPOS(payload[0]) != OPOS)) return 0; /* will generate NAK */ return 1; } diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c index 6caea5692f..aa63911cc9 100644 --- a/board/fruitpie/usb_pd_policy.c +++ b/board/fruitpie/usb_pd_policy.c @@ -224,6 +224,12 @@ static int svdm_dp_config(int port, uint32_t *payload) return 2; }; +static int svdm_dp_attention(int port, uint32_t *payload) +{ + CPRINTF("dp sts:%08x\n", payload[1]); + return 1; /* ack */ +} + static void svdm_exit_dp_mode(int port) { CPRINTF("Exiting mode\n"); @@ -236,6 +242,7 @@ const struct svdm_amode_fx supported_modes[] = { .enter = &svdm_enter_dp_mode, .status = &svdm_dp_status, .config = &svdm_dp_config, + .attention = &svdm_dp_attention, .exit = &svdm_exit_dp_mode, }, }; diff --git a/board/hoho/usb_pd_policy.c b/board/hoho/usb_pd_policy.c index 61457d3d6c..b747766aa9 100644 --- a/board/hoho/usb_pd_policy.c +++ b/board/hoho/usb_pd_policy.c @@ -124,7 +124,14 @@ static int svdm_response_svids(int port, uint32_t *payload) return 2; } -const uint32_t vdo_dp_mode[1] = { +/* Will only ever be a single mode for this UFP_D device as it has no USB + * support (2.0 or 3.0) making it only PIN_E configureable nor does it have any + * source functionality. + */ +#define MODE_CNT 1 +#define OPOS 1 + +const uint32_t vdo_dp_mode[MODE_CNT] = { VDO_MODE_DP(0, /* UFP pin cfg supported : none */ MODE_DP_PIN_C, /* DFP pin cfg supported */ 1, /* no usb2.0 signalling in AMode */ @@ -135,39 +142,30 @@ const uint32_t vdo_dp_mode[1] = { static int svdm_response_modes(int port, uint32_t *payload) { - int mode_cnt = ARRAY_SIZE(vdo_dp_mode); - if (PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) { /* TODO(tbroch) USB billboard enabled here then */ return 1; /* will generate a NAK */ } memcpy(payload + 1, vdo_dp_mode, sizeof(vdo_dp_mode)); - 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) -{ - return gpio_get_level(GPIO_DP_HPD); + return MODE_CNT + 1; } 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 */ + int opos = PD_VDO_OPOS(payload[0]); + int hpd = gpio_get_level(GPIO_DP_HPD); + if (opos != OPOS) + return 0; /* nak */ + + payload[1] = VDO_DP_STATUS(0, /* IRQ_HPD */ + (hpd == 1), /* 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)); + 0, /* power low */ + 0x2); return 2; } @@ -182,7 +180,7 @@ 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)) + (PD_VDO_OPOS(payload[0]) != OPOS)) return 0; /* will generate a NAK */ return 1; } diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index e8ffd2a886..507c6d3bce 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -7,6 +7,7 @@ #include "common.h" #include "console.h" #include "gpio.h" +#include "hooks.h" #include "host_command.h" #include "registers.h" #include "task.h" @@ -275,9 +276,49 @@ static int svdm_dp_config(int port, uint32_t *payload) return 2; }; +static void hpd0_irq_deferred(void) +{ + gpio_set_level(GPIO_USB_C0_DP_HPD, 1); +} + +static void hpd1_irq_deferred(void) +{ + gpio_set_level(GPIO_USB_C1_DP_HPD, 1); +} + +DECLARE_DEFERRED(hpd0_irq_deferred); +DECLARE_DEFERRED(hpd1_irq_deferred); + +#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) + +static int svdm_dp_attention(int port, uint32_t *payload) +{ + int cur_lvl; + int lvl = PD_VDO_HPD_LVL(payload[1]); + int irq = PD_VDO_HPD_IRQ(payload[1]); + enum gpio_signal hpd = PORT_TO_HPD(port); + cur_lvl = gpio_get_level(hpd); + if (irq & cur_lvl) { + gpio_set_level(hpd, 0); + /* 250 usecs is minimum, 2msec is max */ + if (port) + hook_call_deferred(hpd1_irq_deferred, 300); + else + hook_call_deferred(hpd0_irq_deferred, 300); + } else if (irq & !cur_lvl) { + CPRINTF("PE ERR: IRQ_HPD w/ HPD_LOW\n"); + return 0; /* nak */ + } else { + gpio_set_level(hpd, lvl); + } + /* ack */ + return 1; +} + static void svdm_exit_dp_mode(int port) { svdm_safe_dp_mode(port); + gpio_set_level(PORT_TO_HPD(port), 0); } const struct svdm_amode_fx supported_modes[] = { @@ -286,6 +327,7 @@ const struct svdm_amode_fx supported_modes[] = { .enter = &svdm_enter_dp_mode, .status = &svdm_dp_status, .config = &svdm_dp_config, + .attention = &svdm_dp_attention, .exit = &svdm_exit_dp_mode, }, }; |