summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijay Hiremath <vijay.p.hiremath@intel.com>2019-09-03 11:54:39 -0700
committerCommit Bot <commit-bot@chromium.org>2019-09-05 18:17:34 +0000
commitb47a5ca84dfd6b75a4cd76837d81cac0345c000f (patch)
treea9337e366cdd89ff39e1123b5531c923ed1ca467
parentfa6f77cd0da5b2f17494201e0770d1c8d550b7f4 (diff)
downloadchrome-ec-b47a5ca84dfd6b75a4cd76837d81cac0345c000f.tar.gz
intelrvp: Enable USB-C SRC current limiting
Enable SRC current limit pin of the type C current-limited power switch to provide more current when sourcing on only 1 port. BUG=b:140404596 BRANCH=none TEST=Manually tested on tglrvp a. 1 port is connected: ILIM pin of respective port's current limited power switch is high and able to source 3A. b. 2 ports are connected: ILIM pin of both port's current limited power switch is low and able to source 1.5A on each port. Change-Id: Ic6ce897e25a25b526c3c52bce8cbdc843ad419f9 Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1783517 Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r--baseboard/intelrvp/baseboard.h3
-rw-r--r--baseboard/intelrvp/chg_usb_pd.c41
-rw-r--r--baseboard/intelrvp/usb_pd_policy.c24
-rw-r--r--board/tglrvpu_ite/board.c8
4 files changed, 63 insertions, 13 deletions
diff --git a/baseboard/intelrvp/baseboard.h b/baseboard/intelrvp/baseboard.h
index 751b684906..2180e36a37 100644
--- a/baseboard/intelrvp/baseboard.h
+++ b/baseboard/intelrvp/baseboard.h
@@ -219,6 +219,8 @@ struct tcpc_gpio_config_t {
/* Enable VCONN */
struct vconn_gpio_t vconn;
#endif
+ /* Enable source ILIM */
+ struct tcpc_gpio_t src_ilim;
};
extern const struct tcpc_gpio_config_t tcpc_gpios[];
@@ -228,6 +230,7 @@ void vbus0_evt(enum gpio_signal signal);
void vbus1_evt(enum gpio_signal signal);
void board_charging_enable(int port, int enable);
void board_vbus_enable(int port, int enable);
+void board_set_vbus_source_current_limit(int port, int rp);
int ioexpander_read_intelrvp_version(int *port0, int *port1);
void board_dc_jack_interrupt(enum gpio_signal signal);
diff --git a/baseboard/intelrvp/chg_usb_pd.c b/baseboard/intelrvp/chg_usb_pd.c
index ac3cdd78f3..59fcbaf41b 100644
--- a/baseboard/intelrvp/chg_usb_pd.c
+++ b/baseboard/intelrvp/chg_usb_pd.c
@@ -15,17 +15,40 @@
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-static int board_charger_port_is_sourcing_vbus(int port)
+static inline int is_typec_port(int port)
{
- int src_en;
+ return !(port == DEDICATED_CHARGE_PORT || port == CHARGE_PORT_NONE);
+}
+
+
+int board_vbus_source_enabled(int port)
+{
+ int src_en = 0;
- /* DC Jack can't source VBUS */
- if (port == DEDICATED_CHARGE_PORT || port == CHARGE_PORT_NONE)
- return 0;
+ /* Only Type-C ports can source VBUS */
+ if (is_typec_port(port)) {
+ src_en = gpio_get_level(tcpc_gpios[port].src.pin);
- src_en = gpio_get_level(tcpc_gpios[port].src.pin);
+ src_en = tcpc_gpios[port].src.pin_pol ? src_en : !src_en;
+ }
- return tcpc_gpios[port].src.pin_pol ? src_en : !src_en;
+ return src_en;
+}
+
+void board_set_vbus_source_current_limit(int port, int rp)
+{
+ int ilim_en;
+
+ /* Only Type-C ports can source VBUS */
+ if (is_typec_port(port)) {
+ /* Enable SRC ILIM if rp is MAX single source current */
+ ilim_en = (rp == CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT &&
+ board_vbus_source_enabled(port));
+
+ gpio_set_level(tcpc_gpios[port].src_ilim.pin,
+ tcpc_gpios[port].src_ilim.pin_pol ?
+ ilim_en : !ilim_en);
+ }
}
void board_charging_enable(int port, int enable)
@@ -129,7 +152,7 @@ int board_set_active_charge_port(int port)
int is_real_port = (port >= 0 &&
port < CHARGE_PORT_COUNT);
/* check if we are source vbus on that port */
- int source = board_charger_port_is_sourcing_vbus(port);
+ int source = board_vbus_source_enabled(port);
if (is_real_port && source) {
CPRINTS("Skip enable p%d", port);
@@ -155,7 +178,7 @@ int board_set_active_charge_port(int port)
}
/* Enable charging port */
- if (port != DEDICATED_CHARGE_PORT && port != CHARGE_PORT_NONE)
+ if (is_typec_port(port))
board_charging_enable(port, 1);
CPRINTS("New chg p%d", port);
diff --git a/baseboard/intelrvp/usb_pd_policy.c b/baseboard/intelrvp/usb_pd_policy.c
index e0255ebc6b..c291b75647 100644
--- a/baseboard/intelrvp/usb_pd_policy.c
+++ b/baseboard/intelrvp/usb_pd_policy.c
@@ -3,6 +3,7 @@
* found in the LICENSE file.
*/
+#include "charge_manager.h"
#include "console.h"
#include "gpio.h"
#include "system.h"
@@ -50,6 +51,9 @@ int pd_set_power_supply_ready(int port)
/* Provide VBUS */
board_vbus_enable(port, 1);
+ /* Ensure we advertise the proper available current quota */
+ charge_manager_source_port(port, 1);
+
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
@@ -61,6 +65,9 @@ void pd_power_supply_reset(int port)
/* Disable VBUS */
board_vbus_enable(port, 0);
+ /* Give back the current quota we are no longer using */
+ charge_manager_source_port(port, 0);
+
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
}
@@ -83,12 +90,13 @@ int pd_check_power_swap(int port)
int pd_check_data_swap(int port, int data_role)
{
/* Allow data swap if we are a UFP, otherwise don't allow */
- return (data_role == PD_ROLE_UFP);
+ return data_role == PD_ROLE_UFP;
}
int pd_check_vconn_swap(int port)
{
- return 1;
+ /* Only allow vconn swap if PP5000 rail is enabled */
+ return gpio_get_level(GPIO_EN_PP5000);
}
void pd_execute_data_swap(int port, int data_role)
@@ -98,6 +106,8 @@ void pd_execute_data_swap(int port, int data_role)
void pd_check_pr_role(int port, int pr_role, int flags)
{
+ int partner_extpower;
+
/*
* If partner is dual-role power and dualrole toggling is on, consider
* if a power swap is necessary.
@@ -109,7 +119,7 @@ void pd_check_pr_role(int port, int pr_role, int flags)
* 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;
+ partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER;
if ((!partner_extpower && pr_role == PD_ROLE_SINK) ||
(partner_extpower && pr_role == PD_ROLE_SOURCE))
@@ -120,10 +130,16 @@ void pd_check_pr_role(int port, int pr_role, int flags)
void pd_check_dr_role(int port, int dr_role, int flags)
{
/* If UFP, try to switch to DFP */
- if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP)
+ if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP &&
+ system_get_image_copy() != SYSTEM_IMAGE_RO)
pd_request_data_swap(port);
}
+void typec_set_source_current_limit(int port, int rp)
+{
+ board_set_vbus_source_current_limit(port, rp);
+}
+
/* ----------------- Vendor Defined Messages ------------------ */
const struct svdm_response svdm_rsp = {
.identity = NULL,
diff --git a/board/tglrvpu_ite/board.c b/board/tglrvpu_ite/board.c
index a0cb33d5fd..c98e5035e7 100644
--- a/board/tglrvpu_ite/board.c
+++ b/board/tglrvpu_ite/board.c
@@ -42,6 +42,10 @@ const struct tcpc_gpio_config_t tcpc_gpios[] = {
.cc2_pin = GPIO_USB_C0_CC2_VCONN_EN,
.pin_pol = 1,
},
+ .src_ilim = {
+ .pin = GPIO_USB_C0_SRC_HI_ILIM,
+ .pin_pol = 1,
+ },
},
[TYPE_C_PORT_1] = {
.vbus = {
@@ -61,6 +65,10 @@ const struct tcpc_gpio_config_t tcpc_gpios[] = {
.cc2_pin = GPIO_USB_C1_CC2_VCONN_EN,
.pin_pol = 1,
},
+ .src_ilim = {
+ .pin = GPIO_USB_C1_SRC_HI_ILIM,
+ .pin_pol = 1,
+ },
},
};
BUILD_ASSERT(ARRAY_SIZE(tcpc_gpios) == CONFIG_USB_PD_PORT_COUNT);