Files
OpenCellular/common/usb_charger.c
Jett Rink be6a263638 usb_charger: initialize VBUS supplier at startup
When using VBUS_DETECT_TCPC the charger code relied on the TCPC
alert to initialize the VBUS supply, but that happens too late in
board startup sequence to allow an initally plugged in USB-C power
supply to be chosen as the active charging port.

We can and should initialize the the supplier sooner as to prevent
the charge_manager_is_seeded() check from failing thus preventing
the board from choosing a charging port.

BRANCH=none
BUG=b:77458917
TEST=PS8751 on yorp will negotiate 20V over USB-C (which was prevent
	by the charge_manager not being seeded)

Change-Id: I6f612c508932a90ece0036ce8310a20de02d8467
Signed-off-by: Jett Rink <jettrink@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/994707
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Divya S Sasidharan <divya.s.sasidharan@intel.com>
Reviewed-by: Divya S Sasidharan <divya.s.sasidharan@intel.com>
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2018-04-10 19:12:55 -07:00

115 lines
3.2 KiB
C

/* Copyright 2015 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.
*/
/*
* USB charger interface routines. This code assumes that CONFIG_CHARGE_MANAGER
* is defined and implemented.
* usb_charger_set_switches() must be implemented by a companion
* usb_switch driver.
* In addition, USB switch-specific usb_charger task or interrupt routine
* is necessary to update charge_manager with detected charger attributes.
*/
#include "charge_manager.h"
#include "charger.h"
#include "common.h"
#include "console.h"
#include "gpio.h"
#include "hooks.h"
#include "task.h"
#include "usb_charge.h"
#include "usb_pd.h"
#include "usbc_ppc.h"
static void update_vbus_supplier(int port, int vbus_level)
{
struct charge_port_info charge;
/*
* If VBUS is low, or VBUS is high and we are not outputting VBUS
* ourselves, then update the VBUS supplier.
*/
if (!vbus_level || !usb_charger_port_is_sourcing_vbus(port)) {
charge.voltage = USB_CHARGER_VOLTAGE_MV;
charge.current = vbus_level ? USB_CHARGER_MIN_CURR_MA : 0;
charge_manager_update_charge(CHARGE_SUPPLIER_VBUS,
port,
&charge);
}
}
#ifdef CONFIG_USBC_PPC
#define USB_5V_EN(port) ppc_is_sourcing_vbus(port)
#elif defined(CONFIG_USB_PD_5V_CHARGER_CTRL)
#define USB_5V_EN(port) charger_is_sourcing_otg_power(port)
#elif defined(CONFIG_USB_PD_5V_EN_ACTIVE_LOW)
#define USB_5V_EN(port) !gpio_get_level(GPIO_USB_C##port##_5V_EN_L)
#else
#define USB_5V_EN(port) gpio_get_level(GPIO_USB_C##port##_5V_EN)
#endif
int usb_charger_port_is_sourcing_vbus(int port)
{
if (port == 0)
return USB_5V_EN(0);
#if CONFIG_USB_PD_PORT_COUNT >= 2
else if (port == 1)
return USB_5V_EN(1);
#endif
/* Not a valid port */
return 0;
}
void usb_charger_vbus_change(int port, int vbus_level)
{
/* If VBUS has transitioned low, notify PD module directly */
if (!vbus_level)
pd_vbus_low(port);
/* Update VBUS supplier and signal VBUS change to USB_CHG task */
update_vbus_supplier(port, vbus_level);
#ifdef HAS_TASK_USB_CHG_P0
/* USB Charger task(s) */
task_set_event(USB_CHG_PORT_TO_TASK_ID(port), USB_CHG_EVENT_VBUS, 0);
#endif
#if (defined(CONFIG_USB_PD_VBUS_DETECT_CHARGER) \
|| defined(CONFIG_USB_PD_VBUS_DETECT_PPC))
/* USB PD task */
task_wake(PD_PORT_TO_TASK_ID(port));
#endif
}
static void usb_charger_init(void)
{
int i;
struct charge_port_info charge_none;
/* 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,
&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 VBUS is present. */
update_vbus_supplier(i, pd_is_vbus_present(i));
}
}
DECLARE_HOOK(HOOK_INIT, usb_charger_init, HOOK_PRIO_CHARGE_MANAGER_INIT + 1);