summaryrefslogtreecommitdiff
path: root/board/snappy/usb_pd_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/snappy/usb_pd_policy.c')
-rw-r--r--board/snappy/usb_pd_policy.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/board/snappy/usb_pd_policy.c b/board/snappy/usb_pd_policy.c
index cf83ea05bc..3a77eb6cad 100644
--- a/board/snappy/usb_pd_policy.c
+++ b/board/snappy/usb_pd_policy.c
@@ -21,6 +21,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)
@@ -33,6 +34,10 @@ const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS),
};
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
+const uint32_t pd_src_pdo_max[] = {
+ PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS),
+};
+const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max);
const uint32_t pd_snk_pdo[] = {
PDO_FIXED(5000, 500, PDO_FIXED_FLAGS),
@@ -51,9 +56,37 @@ 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 gpio_get_level(port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN);
+ 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 | GPIO_PULL_UP);
+
+ /*
+ * 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);
+}
+
+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_set_power_supply_ready(int port)
@@ -61,11 +94,13 @@ int pd_set_power_supply_ready(int port)
/* Ensure we're not charging from this port */
bd9995x_select_input_port(bd9995x_pd_port_to_chg_port(port), 0);
- /* Provide VBUS */
- gpio_set_level(port ? GPIO_USB_C1_5V_EN :
- GPIO_USB_C0_5V_EN, 1);
+ /* Ensure we advertise the proper available current quota */
+ charge_manager_source_port(port, 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);
@@ -75,19 +110,21 @@ 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);
+ /* 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);
}