summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2016-10-26 13:58:25 +0200
committerchrome-bot <chrome-bot@chromium.org>2016-10-31 03:27:49 -0700
commitcf7ff32b92275f9d4cce4bc3bcaa7d8890b0cb2e (patch)
tree37b80e9f034a01ef8c2a38901500266273a9db92
parent34066e92a92b6ff0f1b4b311b46d13b6a4ab45e3 (diff)
downloadchrome-ec-cf7ff32b92275f9d4cce4bc3bcaa7d8890b0cb2e.tar.gz
kevin: set accurate current limit on USB load switch
When sourcing current on the type-C port, set the OCP limit on the VBUS load switch according to current dynamic capability. (3.0A when only one port is a power source, 1.5A else) Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BRANCH=gru BUG=chrome-os-partner:56110 TEST=manual: connect Caroline to Kevin with Twinkie in between, ask Caroline to sink current through the UI. without anything else connected on Kevin, see 3A flowing when measuring with Twinkie ('tw vbus'), plug a dangling C-to-A receptacle dongle on the other Kevin port and see 1.5A flowing through Twinkie. Force the input current limit on Caroline to 3.0A and see Kevin cutting VBUS. Change-Id: Ib879b1ed720b20aa702c5f3643948ba0575d1193 Reviewed-on: https://chromium-review.googlesource.com/403869 Commit-Ready: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--board/eve/usb_pd_policy.c5
-rw-r--r--board/kevin/board.c7
-rw-r--r--board/kevin/usb_pd_policy.c47
-rw-r--r--board/pyro/usb_pd_policy.c5
-rw-r--r--board/reef/usb_pd_policy.c5
-rw-r--r--board/snappy/usb_pd_policy.c5
-rw-r--r--common/charge_manager.c1
-rw-r--r--common/usb_pd_policy.c3
-rw-r--r--include/charge_manager.h8
-rw-r--r--include/usb_pd.h8
10 files changed, 81 insertions, 13 deletions
diff --git a/board/eve/usb_pd_policy.c b/board/eve/usb_pd_policy.c
index 74c1c54c80..3311f13b73 100644
--- a/board/eve/usb_pd_policy.c
+++ b/board/eve/usb_pd_policy.c
@@ -51,6 +51,11 @@ void pd_transition_voltage(int idx)
/* No-operation: we are always 5V */
}
+int board_vbus_source_enabled(int port)
+{
+ return gpio_get_level(port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN);
+}
+
int pd_set_power_supply_ready(int port)
{
/* Ensure we're not charging from this port */
diff --git a/board/kevin/board.c b/board/kevin/board.c
index 0b9e77e22b..940c2e4045 100644
--- a/board/kevin/board.c
+++ b/board/kevin/board.c
@@ -220,8 +220,7 @@ int board_set_active_charge_port(int charge_port)
switch (charge_port) {
case 0: case 1:
/* Don't charge from a source port */
- if (gpio_get_level(charge_port == 0 ?
- GPIO_USB_C0_5V_EN : GPIO_USB_C1_5V_EN))
+ if (board_vbus_source_enabled(charge_port))
return -1;
bd9995x_port = bd9995x_pd_port_to_chg_port(charge_port);
@@ -261,8 +260,8 @@ void board_set_charge_limit(int port, int supplier, int charge_ma, int max_ma)
int extpower_is_present(void)
{
int port;
- int p0_src = gpio_get_level(GPIO_USB_C0_5V_EN);
- int p1_src = gpio_get_level(GPIO_USB_C1_5V_EN);
+ int p0_src = board_vbus_source_enabled(0);
+ int p1_src = board_vbus_source_enabled(1);
/*
* The charger will indicate VBUS presence if we're sourcing 5V,
diff --git a/board/kevin/usb_pd_policy.c b/board/kevin/usb_pd_policy.c
index 4f145dc1ad..4e753d76a9 100644
--- a/board/kevin/usb_pd_policy.c
+++ b/board/kevin/usb_pd_policy.c
@@ -18,6 +18,7 @@
#include "util.h"
#include "usb_mux.h"
#include "usb_pd.h"
+#include "usb_pd_tcpm.h"
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
@@ -51,6 +52,31 @@ void pd_transition_voltage(int idx)
/* No-operation: we are always 5V */
}
+static uint8_t vbus_en[CONFIG_USB_PD_PORT_COUNT];
+static uint8_t vbus_rp[CONFIG_USB_PD_PORT_COUNT] = {TYPEC_RP_1A5, TYPEC_RP_1A5};
+
+int board_vbus_source_enabled(int port)
+{
+ return vbus_en[port];
+}
+
+static void board_vbus_update_source_current(int port)
+{
+ enum gpio_signal gpio = port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN;
+ int flags = (vbus_rp[port] == TYPEC_RP_1A5 && vbus_en[port]) ?
+ (GPIO_INPUT | GPIO_PULL_UP) : GPIO_OUTPUT;
+
+ /*
+ * Driving USB_Cx_5V_EN high, actually put a 16.5k resistance
+ * (2x 33k in parallel) on the NX5P3290 load switch ILIM pin,
+ * setting a minimum OCP current of 3186 mA.
+ * Putting an internal pull-up on USB_Cx_5V_EN, effectively put a 33k
+ * resistor on ILIM, setting a minimum OCP current of 1505 mA.
+ */
+ gpio_set_level(gpio, vbus_en[port]);
+ gpio_set_flags(gpio, flags);
+}
+
int pd_set_power_supply_ready(int port)
{
/* Ensure we're not charging from this port */
@@ -59,10 +85,10 @@ int pd_set_power_supply_ready(int port)
/* Ensure we advertise the proper available current quota */
charge_manager_source_port(port, 1);
- /* Provide VBUS */
- gpio_set_level(port ? GPIO_USB_C1_5V_EN :
- GPIO_USB_C0_5V_EN, 1);
pd_set_vbus_discharge(port, 0);
+ /* Provide VBUS */
+ vbus_en[port] = 1;
+ board_vbus_update_source_current(port);
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
@@ -72,13 +98,12 @@ int pd_set_power_supply_ready(int port)
void pd_power_supply_reset(int port)
{
- enum gpio_signal gpio;
int prev_en;
- gpio = port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN;
- prev_en = gpio_get_level(gpio);
+ prev_en = vbus_en[port];
/* Disable VBUS */
- gpio_set_level(gpio, 0);
+ vbus_en[port] = 0;
+ board_vbus_update_source_current(port);
/* Enable discharge if we were previously sourcing 5V */
if (prev_en)
pd_set_vbus_discharge(port, 1);
@@ -114,6 +139,14 @@ void typec_set_input_current_limit(int port, uint32_t max_ma,
#endif
}
+void typec_set_source_current_limit(int port, int rp)
+{
+ vbus_rp[port] = rp;
+
+ /* change the GPIO driving the load switch if needed */
+ board_vbus_update_source_current(port);
+}
+
int pd_board_checks(void)
{
return EC_SUCCESS;
diff --git a/board/pyro/usb_pd_policy.c b/board/pyro/usb_pd_policy.c
index e2f8157dc3..cf83ea05bc 100644
--- a/board/pyro/usb_pd_policy.c
+++ b/board/pyro/usb_pd_policy.c
@@ -51,6 +51,11 @@ void pd_transition_voltage(int idx)
/* No-operation: we are always 5V */
}
+int board_vbus_source_enabled(int port)
+{
+ return gpio_get_level(port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN);
+}
+
int pd_set_power_supply_ready(int port)
{
/* Ensure we're not charging from this port */
diff --git a/board/reef/usb_pd_policy.c b/board/reef/usb_pd_policy.c
index 6e515abf81..693bd6e2e4 100644
--- a/board/reef/usb_pd_policy.c
+++ b/board/reef/usb_pd_policy.c
@@ -51,6 +51,11 @@ void pd_transition_voltage(int idx)
/* No-operation: we are always 5V */
}
+int board_vbus_source_enabled(int port)
+{
+ return gpio_get_level(port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN);
+}
+
int pd_set_power_supply_ready(int port)
{
/* Ensure we're not charging from this port */
diff --git a/board/snappy/usb_pd_policy.c b/board/snappy/usb_pd_policy.c
index e2f8157dc3..cf83ea05bc 100644
--- a/board/snappy/usb_pd_policy.c
+++ b/board/snappy/usb_pd_policy.c
@@ -51,6 +51,11 @@ void pd_transition_voltage(int idx)
/* No-operation: we are always 5V */
}
+int board_vbus_source_enabled(int port)
+{
+ return gpio_get_level(port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN);
+}
+
int pd_set_power_supply_ready(int port)
{
/* Ensure we're not charging from this port */
diff --git a/common/charge_manager.c b/common/charge_manager.c
index eeae350f10..3455c8e3f6 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -939,6 +939,7 @@ void charge_manager_source_port(int port, int enable)
charge_manager_save_log(p);
#endif
+ typec_set_source_current_limit(p, rp);
tcpm_select_rp_value(p, rp);
pd_update_contract(p);
}
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index 87f6fbe3d1..5a37a943e3 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -968,8 +968,7 @@ void pd_set_vbus_discharge(int port, int enable)
static struct mutex discharge_lock[CONFIG_USB_PD_PORT_COUNT];
mutex_lock(&discharge_lock[port]);
- enable &= !gpio_get_level(port ? GPIO_USB_C1_5V_EN :
- GPIO_USB_C0_5V_EN);
+ enable &= !board_vbus_source_enabled(port);
#ifdef CONFIG_USB_PD_DISCHARGE_GPIO
gpio_set_level(port ? GPIO_USB_C1_DISCHARGE :
GPIO_USB_C0_DISCHARGE, enable);
diff --git a/include/charge_manager.h b/include/charge_manager.h
index 51007f3d7b..939471163b 100644
--- a/include/charge_manager.h
+++ b/include/charge_manager.h
@@ -120,4 +120,12 @@ int board_set_active_charge_port(int charge_port);
*/
void board_set_charge_limit(int port, int supplier, int charge_ma, int max_ma);
+/*
+ * Get whether the port is sourcing power on VBUS.
+ *
+ * @param port PD port.
+ * @return VBUS power state.
+ */
+int board_vbus_source_enabled(int port);
+
#endif /* __CROS_EC_CHARGE_MANAGER_H */
diff --git a/include/usb_pd.h b/include/usb_pd.h
index c588596e4c..a6be237102 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -1002,6 +1002,14 @@ void typec_set_input_current_limit(int port, uint32_t max_ma,
uint32_t supply_voltage);
/**
+ * Set the type-C current limit when sourcing current..
+ *
+ * @param port USB-C port number
+ * @param rp One of enum tcpc_rp_value (eg TYPEC_RP_3A0) defining the limit.
+ */
+void typec_set_source_current_limit(int port, int rp);
+
+/**
* Verify board specific health status : current, voltages...
*
* @return EC_SUCCESS if the board is good, <0 else.