summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Marheine <pmarheine@chromium.org>2019-12-10 11:11:18 +1100
committerCommit Bot <commit-bot@chromium.org>2019-12-31 02:02:02 +0000
commitbc28967ad0ee8b684bea9146eff7f89045587678 (patch)
tree30cffedf2aa625cc1cb610a8efd5dcd78ded3523
parentdbc522bb9677d5b34ee989f8e961d5be40c354d7 (diff)
downloadchrome-ec-bc28967ad0ee8b684bea9146eff7f89045587678.tar.gz
puff: support switching between USB-C and barrel jack power
We let the charge controller decide which port to use, watching the presence signal to tell the charge control what is connected. We only allow switching the input when the system is off, since switching may cause us to brown out. This is mostly copied from Fizz; I'm unsure if we need to do anything with the TCPPC when switching (Fizz has a GPIO that physically connects or disconnects the type-C port). BUG=b:143975429 TEST=booted on hardware, verified chgsup output with barrel jack BRANCH=None Change-Id: I6d2f8365c03aa44f272195708dd534fdc35cd2f6 Signed-off-by: Peter Marheine <pmarheine@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1958387 Reviewed-by: Andrew McRae <amcrae@chromium.org> Commit-Queue: Andrew McRae <amcrae@chromium.org>
-rw-r--r--board/puff/board.c99
-rw-r--r--board/puff/board.h5
-rw-r--r--board/puff/gpio.inc2
3 files changed, 104 insertions, 2 deletions
diff --git a/board/puff/board.c b/board/puff/board.c
index f5057a9c0a..5a19defffa 100644
--- a/board/puff/board.c
+++ b/board/puff/board.c
@@ -10,6 +10,7 @@
#include "button.h"
#include "charge_manager.h"
#include "charge_state_v2.h"
+#include "chipset.h"
#include "common.h"
#include "cros_board_info.h"
#include "driver/ina3221.h"
@@ -144,6 +145,69 @@ static void port_ocp_interrupt(enum gpio_signal signal)
hook_call_deferred(&update_port_limits_data, 0);
}
+/******************************************************************************/
+/*
+ * Barrel jack power supply handling
+ *
+ * EN_PPVAR_BJ_ADP_L must default active to ensure we can power on when the
+ * barrel jack is connected, and the USB-C port can bring the EC up fine in
+ * dead-battery mode. Both the USB-C and barrel jack switches do reverse
+ * protection, so we're safe to turn one on then the other off- but we should
+ * only do that if the system is off since it might still brown out.
+ */
+#define ADP_DEBOUNCE_MS 1000 /* Debounce time for BJ plug/unplug */
+/* Debounced connection state of the barrel jack */
+static int adp_connected = 1;
+static void adp_state_init(void)
+{
+ adp_connected = !gpio_get_level(GPIO_BJ_ADP_PRESENT_L);
+
+ /* Disable BJ power if not connected (we're on USB-C). */
+ gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, !adp_connected);
+}
+DECLARE_HOOK(HOOK_INIT, adp_state_init, HOOK_PRIO_INIT_EXTPOWER);
+
+static void adp_connect_deferred(void)
+{
+ struct charge_port_info pi = { 0 };
+ int connected = gpio_get_level(GPIO_BJ_ADP_PRESENT_L);
+
+ /* Debounce */
+ if (connected == adp_connected)
+ return;
+ if (connected) {
+ pi.voltage = 19500;
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ /*
+ * TODO(b:143975429) set current according to SKU.
+ * Different SKUs will ship with different power bricks
+ * that have varying power, though setting this to the
+ * maximum current available on any SKU may be okay
+ * (assume the included brick is sufficient to run the
+ * system at max power and over-reporting available
+ * power will have no effect).
+ */
+ pi.current = 4740;
+ }
+ charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED,
+ DEDICATED_CHARGE_PORT, &pi);
+ /*
+ * Explicitly notifies the host that BJ is plugged or unplugged
+ * (when running on a type-c adapter).
+ */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
+ adp_connected = connected;
+}
+DECLARE_DEFERRED(adp_connect_deferred);
+
+/* IRQ for BJ plug/unplug. It shouldn't be called if BJ is the power source. */
+void adp_connect_interrupt(enum gpio_signal signal)
+{
+ if (adp_connected == !gpio_get_level(GPIO_BJ_ADP_PRESENT_L))
+ return;
+ hook_call_deferred(&adp_connect_deferred_data, ADP_DEBOUNCE_MS * MSEC);
+}
+
#include "gpio_list.h" /* Must come after other header files. */
/******************************************************************************/
@@ -378,9 +442,42 @@ void board_reset_pd_mcu(void)
msleep(BOARD_TCPC_C0_RESET_POST_DELAY);
}
-/* TODO: set the active charge port */
int board_set_active_charge_port(int port)
{
+ const int active_port = charge_manager_get_active_charge_port();
+
+ if (port < 0 || CHARGE_PORT_COUNT <= port)
+ return EC_ERROR_INVAL;
+
+ if (port == active_port)
+ return EC_SUCCESS;
+
+ /* Don't charge from a source port */
+ if (board_vbus_source_enabled(port))
+ return EC_ERROR_INVAL;
+
+ /* Change is only permitted while the system is off */
+ if (!chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ return EC_ERROR_INVAL;
+
+ CPRINTS("New charger p%d", port);
+
+ switch (port) {
+ case CHARGE_PORT_TYPEC0:
+ /* TODO(b/143975429) need to touch the PD controller? */
+ gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 1);
+ break;
+ case CHARGE_PORT_BARRELJACK:
+ /* Make sure BJ adapter is sourcing power */
+ if (gpio_get_level(GPIO_BJ_ADP_PRESENT_L))
+ return EC_ERROR_INVAL;
+ /* TODO(b/143975429) need to touch the PD controller? */
+ gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 0);
+ break;
+ default:
+ return EC_ERROR_INVAL;
+ }
+
return EC_SUCCESS;
}
diff --git a/board/puff/board.h b/board/puff/board.h
index 6ad0ef4162..2073738029 100644
--- a/board/puff/board.h
+++ b/board/puff/board.h
@@ -177,6 +177,11 @@
#include "gpio_signal.h"
#include "registers.h"
+enum charge_port {
+ CHARGE_PORT_TYPEC0,
+ CHARGE_PORT_BARRELJACK,
+};
+
enum adc_channel {
ADC_SNS_PP3300, /* ADC2 */
ADC_SNS_PP1050, /* ADC7 */
diff --git a/board/puff/gpio.inc b/board/puff/gpio.inc
index e5e5610b3d..4e479c7484 100644
--- a/board/puff/gpio.inc
+++ b/board/puff/gpio.inc
@@ -37,6 +37,7 @@ GPIO_INT(IMVP8_VRRDY_OD, PIN(1, 6), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(USB_C0_TCPPC_INT_ODL, PIN(E, 0), GPIO_INT_FALLING, ppc_interrupt)
GPIO_INT(USB_C0_TCPC_INT_ODL, PIN(6, 2), GPIO_INT_FALLING, tcpc_alert_event)
GPIO_INT(H1_EC_RECOVERY_BTN_ODL, PIN(2, 4), GPIO_INT_BOTH, button_interrupt)
+GPIO_INT(BJ_ADP_PRESENT_L, PIN(8, 2), GPIO_INT_BOTH, adp_connect_interrupt)
/* Port power control interrupts */
GPIO_INT(HDMI_CONN0_OC_ODL, PIN(0, 7), GPIO_INT_BOTH, port_ocp_interrupt)
@@ -70,7 +71,6 @@ GPIO(EN_IMVP8_VR, PIN(F, 4), GPIO_OUT_LOW)
/* Barreljack */
GPIO(EN_PPVAR_BJ_ADP_L, PIN(0, 4), GPIO_OUT_LOW)
-GPIO(BJ_ADP_PRESENT_L, PIN(8, 2), GPIO_INPUT)
/* USB type A */
GPIO(EN_PP5000_USB_VBUS, PIN(8, 3), GPIO_OUT_LOW)