summaryrefslogtreecommitdiff
path: root/board/glados/board.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/glados/board.c')
-rw-r--r--board/glados/board.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/board/glados/board.c b/board/glados/board.c
index 2d17d671f7..e72e631b17 100644
--- a/board/glados/board.c
+++ b/board/glados/board.c
@@ -7,6 +7,8 @@
#include "adc_chip.h"
#include "button.h"
+#include "charge_manager.h"
+#include "charge_state.h"
#include "charger.h"
#include "console.h"
#include "extpower.h"
@@ -32,6 +34,10 @@
#define I2C_ADDR_BD99992 0x60
+/* Default input current limit when VBUS is present */
+#define DEFAULT_CURR_LIMIT 500 /* mA */
+#define USB_BC12_CHARGE_VOLTAGE 5000 /* mV */
+
/* Exchange status with PD MCU. */
static void pd_mcu_interrupt(enum gpio_signal signal)
{
@@ -95,6 +101,19 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+/* Charge supplier priority: lower number indicates higher priority. */
+const int supplier_priority[] = {
+ [CHARGE_SUPPLIER_PD] = 0,
+ [CHARGE_SUPPLIER_TYPEC] = 1,
+ [CHARGE_SUPPLIER_PROPRIETARY] = 1,
+ [CHARGE_SUPPLIER_BC12_DCP] = 1,
+ [CHARGE_SUPPLIER_BC12_CDP] = 2,
+ [CHARGE_SUPPLIER_BC12_SDP] = 3,
+ [CHARGE_SUPPLIER_OTHER] = 3,
+ [CHARGE_SUPPLIER_VBUS] = 4
+};
+BUILD_ASSERT(ARRAY_SIZE(supplier_priority) == CHARGE_SUPPLIER_COUNT);
+
/**
* Discharge battery when on AC power for factory test.
*/
@@ -137,10 +156,116 @@ DECLARE_HOOK(HOOK_CHIPSET_PRE_INIT, pmic_init, HOOK_PRIO_DEFAULT);
/* Initialize board. */
static void board_init(void)
{
+ int i;
+ struct charge_port_info charge_none, charge_vbus;
+
/* Enable PD MCU interrupt */
gpio_enable_interrupt(GPIO_PD_MCU_INT);
/* Enable VBUS interrupt */
gpio_enable_interrupt(GPIO_USB_C0_VBUS_WAKE_L);
gpio_enable_interrupt(GPIO_USB_C1_VBUS_WAKE_L);
+
+ /* Initialize all pericom charge suppliers to 0 */
+ charge_none.voltage = USB_BC12_CHARGE_VOLTAGE;
+ charge_none.current = 0;
+ for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) {
+ charge_manager_update_charge(CHARGE_SUPPLIER_PROPRIETARY,
+ i,
+ &charge_none);
+ charge_manager_update_charge(CHARGE_SUPPLIER_BC12_CDP,
+ i,
+ &charge_none);
+ charge_manager_update_charge(CHARGE_SUPPLIER_BC12_DCP,
+ i,
+ &charge_none);
+ charge_manager_update_charge(CHARGE_SUPPLIER_BC12_SDP,
+ i,
+ &charge_none);
+ charge_manager_update_charge(CHARGE_SUPPLIER_OTHER,
+ i,
+ &charge_none);
+ }
+
+ /* Initialize VBUS supplier based on whether or not VBUS is present */
+ charge_vbus.voltage = USB_BC12_CHARGE_VOLTAGE;
+ charge_vbus.current = DEFAULT_CURR_LIMIT;
+ if (!gpio_get_level(GPIO_USB_C0_VBUS_WAKE_L))
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 0,
+ &charge_vbus);
+ else
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 0,
+ &charge_none);
+
+ if (!gpio_get_level(GPIO_USB_C1_VBUS_WAKE_L))
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 1,
+ &charge_vbus);
+ else
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 1,
+ &charge_none);
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+
+/**
+ * Set active charge port -- only one port can be active at a time.
+ *
+ * @param charge_port Charge port to enable.
+ *
+ * Returns EC_SUCCESS if charge port is accepted and made active,
+ * EC_ERROR_* otherwise.
+ */
+int board_set_active_charge_port(int charge_port)
+{
+ /* charge port is a realy physical port */
+ int is_real_port = (charge_port >= 0 &&
+ charge_port < CONFIG_USB_PD_PORT_COUNT);
+ /* check if we are source vbus on that port */
+ int source = gpio_get_level(charge_port == 0 ? GPIO_USB_C0_5V_EN :
+ GPIO_USB_C1_5V_EN);
+
+ if (is_real_port && source) {
+ CPRINTS("Skip enable p%d", charge_port);
+ return EC_ERROR_INVAL;
+ }
+
+ CPRINTS("New chg p%d", charge_port);
+
+ if (charge_port == CHARGE_PORT_NONE) {
+ /*
+ * TODO: currently we only get VBUS knowledge when charge
+ * is enabled. so, when not charging, we need to enable
+ * both ports. but, this is dangerous if you have two
+ * chargers plugged in and you set charge override to -1
+ * then it will enable both sides!
+ */
+ gpio_set_level(GPIO_USB_C0_CHARGE_EN_L, 0);
+ gpio_set_level(GPIO_USB_C1_CHARGE_EN_L, 0);
+ } else {
+ /* Make sure non-charging port is disabled */
+ gpio_set_level(charge_port ? GPIO_USB_C0_CHARGE_EN_L :
+ GPIO_USB_C1_CHARGE_EN_L, 1);
+ /* Enable charging port */
+ gpio_set_level(charge_port ? GPIO_USB_C1_CHARGE_EN_L :
+ GPIO_USB_C0_CHARGE_EN_L, 0);
+ }
+
+ return EC_SUCCESS;
+}
+
+/**
+ * Set the charge limit based upon desired maximum.
+ *
+ * @param charge_ma Desired charge limit (mA).
+ */
+void board_set_charge_limit(int charge_ma)
+{
+ charge_set_input_current_limit(MAX(charge_ma,
+ CONFIG_CHARGER_INPUT_CURRENT));
+}
+
+/* Charge manager callback function, called on delayed override timeout */
+void board_charge_manager_override_timeout(void)
+{
+ /* TODO: what to do here? */
+}
+DECLARE_DEFERRED(board_charge_manager_override_timeout);
+