summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2018-09-12 13:12:31 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-09-20 23:28:59 +0000
commitc02b0386f6b0cdbfab2212b80c2dba5980714a75 (patch)
tree2dc90e8e3482b355e8466e086d2d0bdf808edf44
parent31ea5b39983e150ecb8f837a69842c2e673b5371 (diff)
downloadchrome-ec-c02b0386f6b0cdbfab2212b80c2dba5980714a75.tar.gz
chgmgr: Set available voltage to 0 on disconnect
Currently, available current is consistently set to zero when a supplier is disconnected across BC 1.2 drivers, PD task, usb charger task but voltage is set to zero only in some places. This patch will set available voltage consistently to 0 on disconnected ports. This change should have no impact externally or internally because currently ports are treated as a disconnected port as long as available current is zero. Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> BUG=chromium:841944 BRANCH=none TEST=Verify ectool usbpdpower 1 return 'Port 1: Disconnected' and 'Port 1: SNK (not charging)' without and with a BJ adapter connected respectively on Fizz. Verify ectool usbpdpower prints 'Disconnected' and 'SNK Charger PD' on Vayne without and with USB-C charger, respectively. Verify ectool usbpdpower prints 'Disconnected' and 'SNK Charger Type-C' on Vayne without and with a phone USB-C charger, respectively. Change-Id: I9aca575a4a4240ec1f669c55437decaedf758a77 Reviewed-on: https://chromium-review.googlesource.com/1236849 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--board/glkrvp_ite/chg_usb_pd.c250
-rw-r--r--common/charge_manager.c4
-rw-r--r--common/usb_charger.c14
-rw-r--r--driver/bc12/pi3usb9281.c8
-rw-r--r--driver/charger/bd9995x.c5
5 files changed, 262 insertions, 19 deletions
diff --git a/board/glkrvp_ite/chg_usb_pd.c b/board/glkrvp_ite/chg_usb_pd.c
new file mode 100644
index 0000000000..5ef8d7a77e
--- /dev/null
+++ b/board/glkrvp_ite/chg_usb_pd.c
@@ -0,0 +1,250 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "charge_manager.h"
+#include "charge_state_v2.h"
+#include "console.h"
+#include "hooks.h"
+#include "task.h"
+#include "tcpci.h"
+#include "system.h"
+#include "usb_mux.h"
+#include "util.h"
+
+#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
+
+#define PTN5110_EXT_GPIO_CONFIG 0x92
+#define PTN5110_EXT_GPIO_CONTROL 0x93
+
+#define PTN5110_EXT_GPIO_FRS_EN (1 << 6)
+#define PTN5110_EXT_GPIO_EN_SRC (1 << 5)
+#define PTN5110_EXT_GPIO_EN_SNK1 (1 << 4)
+#define PTN5110_EXT_GPIO_IILIM_5V_VBUS_L (1 << 3)
+
+enum glkrvp_charge_ports {
+ TYPE_C_PORT_0,
+ TYPE_C_PORT_1,
+ DC_JACK_PORT_0 = DEDICATED_CHARGE_PORT,
+};
+
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
+ {IT83XX_I2C_CH_B, 0xA0, &tcpci_tcpm_drv, TCPC_ALERT_ACTIVE_LOW},
+ {IT83XX_I2C_CH_B, 0xA4, &tcpci_tcpm_drv, TCPC_ALERT_ACTIVE_LOW},
+};
+BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == CONFIG_USB_PD_PORT_COUNT);
+
+struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_COUNT] = {
+ {
+ .port_addr = 0x20,
+ .driver = &ps874x_usb_mux_driver,
+ },
+ {
+ .port_addr = 0x22,
+ .driver = &ps874x_usb_mux_driver,
+ },
+};
+
+/* TODO: Implement this function and move to appropriate file */
+void usb_charger_set_switches(int port, enum usb_switch setting)
+{
+}
+
+static int board_charger_port_is_sourcing_vbus(int port)
+{
+ int reg;
+
+ /* DC Jack can't source VBUS */
+ if (port == DC_JACK_PORT_0)
+ return 0;
+
+ if (tcpc_read(port, PTN5110_EXT_GPIO_CONTROL, &reg))
+ return 0;
+
+ return !!(reg & PTN5110_EXT_GPIO_EN_SRC);
+}
+
+static int ptn5110_ext_gpio_enable(int port, int enable, int gpio)
+{
+ int reg;
+ int rv;
+
+ rv = tcpc_read(port, PTN5110_EXT_GPIO_CONTROL, &reg);
+ if (rv)
+ return rv;
+
+ if (enable)
+ reg |= gpio;
+ else
+ reg &= ~gpio;
+
+ return tcpc_write(port, PTN5110_EXT_GPIO_CONTROL, reg);
+}
+
+void board_charging_enable(int port, int enable)
+{
+ ptn5110_ext_gpio_enable(port, enable, PTN5110_EXT_GPIO_EN_SNK1);
+}
+
+void board_vbus_enable(int port, int enable)
+{
+ ptn5110_ext_gpio_enable(port, enable, PTN5110_EXT_GPIO_EN_SRC);
+}
+
+void tcpc_alert_event(enum gpio_signal signal)
+{
+#ifdef HAS_TASK_PDCMD
+ /* Exchange status with TCPCs */
+ host_command_pd_send_status(PD_CHARGE_NO_CHANGE);
+#endif
+}
+
+void board_tcpc_init(void)
+{
+ /* Only reset TCPC if not sysjump */
+ if (!system_jumped_to_this_image())
+ board_reset_pd_mcu();
+
+ /* Enable TCPC0/1 interrupt */
+ gpio_enable_interrupt(GPIO_USB_C0_PD_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C1_PD_INT_ODL);
+}
+DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1);
+
+int board_tcpc_post_init(int port)
+{
+ int reg;
+ int rv;
+
+ rv = tcpc_read(port, PTN5110_EXT_GPIO_CONFIG, &reg);
+ if (rv)
+ return rv;
+
+ /* Configure PTN5110 External GPIOs as output */
+ reg |= PTN5110_EXT_GPIO_EN_SRC | PTN5110_EXT_GPIO_EN_SNK1 |
+ PTN5110_EXT_GPIO_IILIM_5V_VBUS_L;
+ rv = tcpc_write(port, PTN5110_EXT_GPIO_CONFIG, reg);
+ if (rv)
+ return rv;
+
+ return ptn5110_ext_gpio_enable(port, 1,
+ PTN5110_EXT_GPIO_IILIM_5V_VBUS_L);
+}
+
+/* Reset PD MCU */
+void board_reset_pd_mcu(void)
+{
+ /* TODO: Add reset logic */
+}
+
+static inline int board_dc_jack_present(void)
+{
+ return !gpio_get_level(GPIO_DC_JACK_PRESENT_L);
+}
+
+static void board_dc_jack_handle(void)
+{
+ struct charge_port_info charge_dc_jack;
+
+ /* System is booted from DC Jack */
+ if (board_dc_jack_present()) {
+ charge_dc_jack.current = (PD_MAX_POWER_MW * 1000) /
+ DC_JACK_MAX_VOLTAGE_MV;
+ charge_dc_jack.voltage = DC_JACK_MAX_VOLTAGE_MV;
+ } else {
+ charge_dc_jack.current = 0;
+ charge_dc_jack.voltage = USB_CHARGER_VOLTAGE_MV;
+ }
+
+ charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED,
+ DC_JACK_PORT_0, &charge_dc_jack);
+}
+DECLARE_HOOK(HOOK_AC_CHANGE, board_dc_jack_handle, HOOK_PRIO_FIRST);
+
+static void board_charge_init(void)
+{
+ int port, supplier;
+ struct charge_port_info charge_init = {0};
+
+ /* Initialize all charge suppliers to seed the charge manager */
+ for (port = 0; port < CHARGE_PORT_COUNT; port++) {
+ for (supplier = 0; supplier < CHARGE_SUPPLIER_COUNT; supplier++)
+ charge_manager_update_charge(supplier, port,
+ &charge_init);
+ }
+
+ board_dc_jack_handle();
+}
+DECLARE_HOOK(HOOK_INIT, board_charge_init, HOOK_PRIO_DEFAULT);
+
+int board_set_active_charge_port(int port)
+{
+ /* charge port is a realy physical 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);
+
+ if (is_real_port && source) {
+ CPRINTS("Skip enable p%d", port);
+ return EC_ERROR_INVAL;
+ }
+
+ /*
+ * Do not enable Type-C port if the DC Jack is present.
+ * When the Type-C is active port, hardware circuit will
+ * block DC jack from enabling +VADP_OUT.
+ */
+ if (port != DC_JACK_PORT_0 && board_dc_jack_present()) {
+ CPRINTS("DC Jack present, Skip enable p%d", port);
+ return EC_ERROR_INVAL;
+ }
+
+ /* Make sure non-charging port is disabled */
+ switch (port) {
+ case TYPE_C_PORT_0:
+ board_charging_enable(TYPE_C_PORT_1, 0);
+ board_charging_enable(TYPE_C_PORT_0, 1);
+ break;
+ case TYPE_C_PORT_1:
+ board_charging_enable(TYPE_C_PORT_0, 0);
+ board_charging_enable(TYPE_C_PORT_1, 1);
+ break;
+ case DC_JACK_PORT_0:
+ case CHARGE_PORT_NONE:
+ default:
+ /* Disable both Type-C ports */
+ board_charging_enable(TYPE_C_PORT_0, 0);
+ board_charging_enable(TYPE_C_PORT_1, 0);
+ break;
+ }
+
+ return EC_SUCCESS;
+}
+
+uint16_t tcpc_get_alert_status(void)
+{
+ uint16_t status = 0;
+
+ if (!gpio_get_level(GPIO_USB_C0_PD_INT_ODL))
+ status |= PD_STATUS_TCPC_ALERT_0;
+
+ if (!gpio_get_level(GPIO_USB_C1_PD_INT_ODL))
+ status |= PD_STATUS_TCPC_ALERT_1;
+
+ return status;
+}
+
+void board_set_charge_limit(int port, int supplier, int charge_ma,
+ int max_ma, int charge_mv)
+{
+ charge_set_input_current_limit(MAX(charge_ma,
+ CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
+}
+
+int adc_read_channel(enum adc_channel ch)
+{
+ return 0;
+}
diff --git a/common/charge_manager.c b/common/charge_manager.c
index d1912ccbd3..afe1fc21ed 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -585,8 +585,10 @@ static void charge_manager_refresh(void)
* Zero the available charge on the rejected port so that
* it is no longer chosen.
*/
- for (i = 0; i < CHARGE_SUPPLIER_COUNT; ++i)
+ for (i = 0; i < CHARGE_SUPPLIER_COUNT; ++i) {
available_charge[i][new_port].current = 0;
+ available_charge[i][new_port].voltage = 0;
+ }
}
active_charge_port_initialized = 1;
diff --git a/common/usb_charger.c b/common/usb_charger.c
index 554ed93b9c..1b88adb444 100644
--- a/common/usb_charger.c
+++ b/common/usb_charger.c
@@ -24,14 +24,12 @@
static void update_vbus_supplier(int port, int vbus_level)
{
- struct charge_port_info charge;
+ struct charge_port_info charge = {0};
- charge.voltage = USB_CHARGER_VOLTAGE_MV;
-
- if (vbus_level && !usb_charger_port_is_sourcing_vbus(port))
+ if (vbus_level && !usb_charger_port_is_sourcing_vbus(port)) {
+ charge.voltage = USB_CHARGER_VOLTAGE_MV;
charge.current = USB_CHARGER_MIN_CURR_MA;
- else
- charge.current = 0;
+ }
charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, port, &charge);
}
@@ -82,11 +80,9 @@ void usb_charger_vbus_change(int port, int vbus_level)
static void usb_charger_init(void)
{
int i;
- struct charge_port_info charge_none;
+ struct charge_port_info charge_none = {0};
/* Initialize all charge suppliers */
- charge_none.voltage = USB_CHARGER_VOLTAGE_MV;
- charge_none.current = 0;
for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) {
charge_manager_update_charge(CHARGE_SUPPLIER_PROPRIETARY,
i,
diff --git a/driver/bc12/pi3usb9281.c b/driver/bc12/pi3usb9281.c
index be1bfdee18..9bdf875468 100644
--- a/driver/bc12/pi3usb9281.c
+++ b/driver/bc12/pi3usb9281.c
@@ -289,11 +289,9 @@ void usb_charger_set_switches(int port, enum usb_switch setting)
static void bc12_detect(int port)
{
int device_type, charger_status;
- struct charge_port_info charge;
+ struct charge_port_info charge = {0};
int type;
- charge.voltage = USB_CHARGER_VOLTAGE_MV;
-
if (usb_charger_port_is_sourcing_vbus(port)) {
/* If we're sourcing VBUS then we're not charging */
device_type = charger_status = 0;
@@ -364,11 +362,11 @@ static void bc12_detect(int port)
else
type = CHARGE_SUPPLIER_OTHER;
+ charge.voltage = USB_CHARGER_VOLTAGE_MV;
charge.current = pi3usb9281_get_ilim(device_type,
charger_status);
charge_manager_update_charge(type, port, &charge);
- } else { /* Detachment: update available charge to 0 */
- charge.current = 0;
+ } else { /* Detachment */
charge_manager_update_charge(
CHARGE_SUPPLIER_PROPRIETARY,
port,
diff --git a/driver/charger/bd9995x.c b/driver/charger/bd9995x.c
index 7cdbdc4893..4fb5e9a347 100644
--- a/driver/charger/bd9995x.c
+++ b/driver/charger/bd9995x.c
@@ -407,10 +407,7 @@ static int bd9995x_bc12_check_type(int port)
static void bd9995x_bc12_detach(int port, int type)
{
- struct charge_port_info charge = {
- .voltage = USB_CHARGER_VOLTAGE_MV,
- .current = 0,
- };
+ struct charge_port_info charge = {0};
/* Update charge manager */
charge_manager_update_charge(type, port, &charge);