diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2018-09-12 13:12:31 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2018-09-20 23:28:59 +0000 |
commit | c02b0386f6b0cdbfab2212b80c2dba5980714a75 (patch) | |
tree | 2dc90e8e3482b355e8466e086d2d0bdf808edf44 | |
parent | 31ea5b39983e150ecb8f837a69842c2e673b5371 (diff) | |
download | chrome-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.c | 250 | ||||
-rw-r--r-- | common/charge_manager.c | 4 | ||||
-rw-r--r-- | common/usb_charger.c | 14 | ||||
-rw-r--r-- | driver/bc12/pi3usb9281.c | 8 | ||||
-rw-r--r-- | driver/charger/bd9995x.c | 5 |
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, ®)) + 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, ®); + 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, ®); + 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); |