summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorVijay Hiremath <vijay.p.hiremath@intel.com>2015-07-16 19:18:07 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-07-22 05:02:48 +0000
commit2302647f574852f3a76813dc8adf2a9dc7d81235 (patch)
tree606478b650d82200b9b9be9f5979cdf38f3f1837 /board
parentdfcb1dc9e16a0e0f1bdf95033d60663ce5b76f93 (diff)
downloadchrome-ec-2302647f574852f3a76813dc8adf2a9dc7d81235.tar.gz
kunimitsu: add HPD handling to policy layer
Ported the HPD handling to policy from Glados Change-Id: I293224fa5189c8827f1837877ffb791fddc7fb77 Reviewed-on: https://chromium-review.googlesource.com/285743 BUG=none TEST=make buildall -j BRANCH=none Change-Id: I72e2f0853902bfa3536ba083f8ece5785be625c4 Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com> Reviewed-on: https://chromium-review.googlesource.com/287410 Reviewed-by: Alec Berg <alecaberg@chromium.org>
Diffstat (limited to 'board')
-rw-r--r--board/kunimitsu/board.h3
-rw-r--r--board/kunimitsu/gpio.inc4
-rw-r--r--board/kunimitsu/usb_pd_policy.c84
3 files changed, 78 insertions, 13 deletions
diff --git a/board/kunimitsu/board.h b/board/kunimitsu/board.h
index 87af8b45c1..788559d558 100644
--- a/board/kunimitsu/board.h
+++ b/board/kunimitsu/board.h
@@ -52,6 +52,7 @@
#define CONFIG_USB_SWITCH_PI3USB9281
#define CONFIG_USB_SWITCH_PI3USB9281_CHIP_COUNT 2
#define CONFIG_USBC_SS_MUX
+#define CONFIG_USBC_VCONN
#define CONFIG_SCI_GPIO GPIO_PCH_SCI_L
#define CONFIG_SPI_PORT 1
@@ -84,7 +85,7 @@
#define I2C_PORT_USB_CHARGER_2 MEC1322_I2C3
#undef DEFERRABLE_MAX_COUNT
-#define DEFERRABLE_MAX_COUNT 11
+#define DEFERRABLE_MAX_COUNT 13
#define CONFIG_ALS
#define CONFIG_ALS_OPT3001
diff --git a/board/kunimitsu/gpio.inc b/board/kunimitsu/gpio.inc
index e578cbd9bb..7c9e9e8ecb 100644
--- a/board/kunimitsu/gpio.inc
+++ b/board/kunimitsu/gpio.inc
@@ -48,8 +48,8 @@ GPIO(USB2_ENABLE, PIN(67), GPIO_OUT_HIGH)
GPIO(ENTERING_RW, PIN(41), GPIO_OUT_LOW)
GPIO(PCH_SMI_L, PIN(44), GPIO_ODR_HIGH)
GPIO(PCH_PWRBTN_L, PIN(45), GPIO_OUT_HIGH)
-GPIO(USB_C0_DP_HPD, PIN(46), GPIO_OUT_HIGH)
-GPIO(USB_C1_DP_HPD, PIN(51), GPIO_OUT_HIGH)
+GPIO(USB_C0_DP_HPD, PIN(46), GPIO_OUT_LOW)
+GPIO(USB_C1_DP_HPD, PIN(51), GPIO_OUT_LOW)
GPIO(CPU_PROCHOT, PIN(52), GPIO_OUT_LOW)
GPIO(ENABLE_TOUCHPAD, PIN(53), GPIO_OUT_HIGH)
GPIO(BAT_PRESENT_L, PIN(56), GPIO_INPUT)
diff --git a/board/kunimitsu/usb_pd_policy.c b/board/kunimitsu/usb_pd_policy.c
index 304b809994..3ff8a76c53 100644
--- a/board/kunimitsu/usb_pd_policy.c
+++ b/board/kunimitsu/usb_pd_policy.c
@@ -157,18 +157,30 @@ void pd_execute_data_swap(int port, int data_role)
/* TODO: need to open/close D+/D- switch based on role */
}
-void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
+void pd_check_pr_role(int port, int pr_role, int flags)
{
- /* If sink, and dual role toggling is on, then switch to source */
- if (partner_pr_swap && pr_role == PD_ROLE_SINK &&
- pd_get_dual_role() == PD_DRP_TOGGLE_ON)
- pd_request_power_swap(port);
+ /*
+ * If partner is dual-role power and dualrole toggling is on, consider
+ * if a power swap is necessary.
+ */
+ if ((flags & PD_FLAGS_PARTNER_DR_POWER) &&
+ pd_get_dual_role() == PD_DRP_TOGGLE_ON) {
+ /*
+ * If we are a sink and partner is not externally powered, then
+ * swap to become a source. If we are source and partner is
+ * externally powered, swap to become a sink.
+ */
+ int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER;
+ if ((!partner_extpower && pr_role == PD_ROLE_SINK) ||
+ (partner_extpower && pr_role == PD_ROLE_SOURCE))
+ pd_request_power_swap(port);
+ }
}
-void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
+void pd_check_dr_role(int port, int dr_role, int flags)
{
/* If UFP, try to switch to DFP */
- if (partner_dr_swap && dr_role == PD_ROLE_UFP)
+ if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP)
pd_request_data_swap(port);
}
/* ----------------- Vendor Defined Messages ------------------ */
@@ -231,11 +243,14 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload,
#ifdef CONFIG_USB_PD_ALT_MODE_DFP
static int dp_flags[CONFIG_USB_PD_PORT_COUNT];
+/* DP Status VDM as returned by UFP */
+static uint32_t dp_status[CONFIG_USB_PD_PORT_COUNT];
static void svdm_safe_dp_mode(int port)
{
/* make DP interface safe until configure */
dp_flags[port] = 0;
+ dp_status[port] = 0;
usb_mux_set(port, TYPEC_MUX_NONE,
USB_SWITCH_CONNECT, pd_get_polarity(port));
}
@@ -270,26 +285,75 @@ static int svdm_dp_status(int port, uint32_t *payload)
static int svdm_dp_config(int port, uint32_t *payload)
{
int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT);
+ int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]);
+ int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]);
+
+ if (!pin_mode)
+ return 0;
- usb_mux_set(port, TYPEC_MUX_DP,
+ usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP,
USB_SWITCH_CONNECT, pd_get_polarity(port));
+
payload[0] = VDO(USB_SID_DISPLAYPORT, 1,
CMD_DP_CONFIG | VDO_OPOS(opos));
- payload[1] = VDO_DP_CFG(MODE_DP_PIN_E, /* pin mode */
+ payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */
1, /* DPv1.3 signaling */
2); /* UFP connected */
return 2;
};
+#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD)
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;
+
+ gpio_set_level(PORT_TO_HPD(port), 1);
}
+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_IRQ_DEFERRED(port) ((port) ? hpd1_irq_deferred : \
+ hpd0_irq_deferred)
+
static int svdm_dp_attention(int port, uint32_t *payload)
{
+ int cur_lvl;
+ int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
+ int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
+ enum gpio_signal hpd = PORT_TO_HPD(port);
+ cur_lvl = gpio_get_level(hpd);
+
+ dp_status[port] = payload[1];
+
+ /* 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);
+ hook_call_deferred(PORT_TO_HPD_IRQ_DEFERRED(port),
+ HPD_DSTREAM_DEBOUNCE_IRQ);
+ } else if (irq & !cur_lvl) {
+ CPRINTF("ERR:HPD:IRQ&LOW\n");
+ return 0; /* nak */
+ } else {
+ gpio_set_level(hpd, lvl);
+ }
/* ack */
return 1;
}
@@ -297,7 +361,7 @@ static int svdm_dp_attention(int port, uint32_t *payload)
static void svdm_exit_dp_mode(int port)
{
svdm_safe_dp_mode(port);
- /* gpio_set_level(PORT_TO_HPD(port), 0); */
+ gpio_set_level(PORT_TO_HPD(port), 0);
}
static int svdm_enter_gfu_mode(int port, uint32_t mode_caps)