charge_ramp: Move ramp allowed / ilim callbacks to common code

The decision on whether to ramp (and how high) depends on the quirks of
charger identification, so move the decision out of board, into the
drivers that implement usb_charger.

Also, rename CONFIG_CHARGE_RAMP to CONFIG_CHARGE_RAMP_SW, to better
contrast with the existing CONFIG_CHARGE_RAMP_HW.

BUG=None
TEST=Manual on kevin, verify ramp occurs when port plugged into Z840
workstation.
BRANCH=None

Change-Id: I5b395274133837a18a4f4ac34b59b623287be175
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/702681
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Shawn Nematbakhsh
2017-10-05 09:50:08 -07:00
committed by chrome-bot
parent 02045eb040
commit b87fe062ec
34 changed files with 563 additions and 850 deletions

View File

@@ -354,39 +354,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_PROPRIETARY;
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
switch (supplier) {
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 1000;
case CHARGE_SUPPLIER_BC12_CDP:
case CHARGE_SUPPLIER_PROPRIETARY:
return sup_curr;
default:
return 500;
}
}
/* Called on AP S5 -> S3 transition */
static void board_chipset_startup(void)
{

View File

@@ -671,29 +671,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return (supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_OTHER);
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
return bd9995x_get_bc12_ilim(supplier);
}
/**
* Return if board is consuming full amount of input current
*/

View File

@@ -48,7 +48,7 @@
/* Charger */
#define CONFIG_CHARGE_MANAGER
#define CONFIG_CHARGE_RAMP
#define CONFIG_CHARGE_RAMP_SW
#define CONFIG_CHARGE_STATE_DEBUG
#define CONFIG_CHARGER
#define CONFIG_CHARGER_V2

View File

@@ -338,39 +338,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
pd_send_host_event(PD_EVENT_POWER_CHANGE);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_PROPRIETARY;
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
switch (supplier) {
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 1000;
case CHARGE_SUPPLIER_BC12_CDP:
case CHARGE_SUPPLIER_PROPRIETARY:
return sup_curr;
default:
return 500;
}
}
/**
* Set AP reset.
* AP_RESET_L (PC3, CPU_WARM_RESET_L) is connected to PMIC SYSRSTB

View File

@@ -541,29 +541,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return (supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_OTHER);
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
return bd9995x_get_bc12_ilim(supplier);
}
/**
* Return if board is consuming full amount of input current
*/

View File

@@ -88,7 +88,7 @@
/* Charger */
#define CONFIG_CHARGE_MANAGER
#define CONFIG_CHARGE_MANAGER_EXTERNAL_POWER_LIMIT
#define CONFIG_CHARGE_RAMP
#define CONFIG_CHARGE_RAMP_SW
#define CONFIG_CHARGER
#define CONFIG_CHARGER_V2
#define CONFIG_CHARGER_BD9995X

View File

@@ -321,39 +321,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_PROPRIETARY;
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
switch (supplier) {
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 1000;
case CHARGE_SUPPLIER_BC12_CDP:
case CHARGE_SUPPLIER_PROPRIETARY:
return sup_curr;
default:
return 500;
}
}
/* Enable or disable input devices, based upon chipset state and tablet mode */
static void enable_input_devices(void)
{

View File

@@ -416,39 +416,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return (supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_OTHER);
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
switch (supplier) {
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 1000;
case CHARGE_SUPPLIER_BC12_CDP:
case CHARGE_SUPPLIER_PROPRIETARY:
return sup_curr;
default:
return 500;
}
}
/**
* Return if board is consuming full amount of input current
*/

View File

@@ -32,7 +32,7 @@
/* Charger */
#define CONFIG_CHARGE_MANAGER
#define CONFIG_CHARGE_RAMP
#define CONFIG_CHARGE_RAMP_SW
#define CONFIG_CHARGER
#define CONFIG_CHARGER_V2
#define CONFIG_CHARGER_ISL9237

View File

@@ -117,7 +117,7 @@
/* USB PD config */
#define CONFIG_CASE_CLOSED_DEBUG_EXTERNAL
#define CONFIG_CHARGE_MANAGER
#define CONFIG_CHARGE_RAMP
#define CONFIG_CHARGE_RAMP_SW
#define CONFIG_USB_POWER_DELIVERY
#define CONFIG_USB_PD_ALT_MODE
#define CONFIG_USB_PD_ALT_MODE_DFP

View File

@@ -13,21 +13,6 @@
#include "charge_state.h"
#include "system.h"
/**
* Return true if ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_PROPRIETARY;
}
/**
* Return true if VBUS is sagging too low
*/
@@ -36,14 +21,6 @@ int board_is_vbus_too_low(int port, enum chg_ramp_vbus_state ramp_state)
return charger_get_vbus_voltage(port) < BD9995X_BC12_MIN_VOLTAGE;
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
return bd9995x_get_bc12_ilim(supplier);
}
/**
* Return if board is consuming full amount of input current
*/

View File

@@ -320,39 +320,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
pd_send_host_event(PD_EVENT_POWER_CHANGE);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_PROPRIETARY;
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
switch (supplier) {
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 1000;
case CHARGE_SUPPLIER_BC12_CDP:
case CHARGE_SUPPLIER_PROPRIETARY:
return sup_curr;
default:
return 500;
}
}
/*
* timestamp of the next possible toggle to ensure the 2-ms spacing
* between IRQ_HPD.

View File

@@ -770,39 +770,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return (supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_OTHER);
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
switch (supplier) {
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 1000;
case CHARGE_SUPPLIER_BC12_CDP:
case CHARGE_SUPPLIER_PROPRIETARY:
return sup_curr;
default:
return 500;
}
}
/**
* Return if board is consuming full amount of input current
*/

View File

@@ -654,29 +654,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return (supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_OTHER);
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
return bd9995x_get_bc12_ilim(supplier);
}
/**
* Return if board is consuming full amount of input current
*/

View File

@@ -46,7 +46,7 @@
/* Charger */
#define CONFIG_CHARGE_MANAGER
#define CONFIG_CHARGE_RAMP
#define CONFIG_CHARGE_RAMP_SW
#define CONFIG_CHARGER
#define CONFIG_CHARGER_V2
#define CONFIG_CHARGER_BD9995X

View File

@@ -439,29 +439,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return (supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_OTHER);
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
return bd9995x_get_bc12_ilim(supplier);
}
/**
* Return if board is consuming full amount of input current
*/

View File

@@ -36,7 +36,7 @@
/* Charger */
#define CONFIG_CHARGE_MANAGER
#define CONFIG_CHARGE_RAMP
#define CONFIG_CHARGE_RAMP_SW
#define CONFIG_CHARGER
#define CONFIG_CHARGER_V2
#define CONFIG_CHARGER_BD9995X

View File

@@ -352,39 +352,6 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
pd_send_host_event(PD_EVENT_POWER_CHANGE);
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_PROPRIETARY;
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
switch (supplier) {
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 1000;
case CHARGE_SUPPLIER_BC12_CDP:
case CHARGE_SUPPLIER_PROPRIETARY:
return sup_curr;
default:
return 500;
}
}
/**
* Set AP reset.
* AP_RESET_L (PC3, CPU_WARM_RESET_L) is connected to PMIC SYSRSTB

View File

@@ -360,39 +360,6 @@ int pd_is_max_request_allowed(void)
return charge_state == PD_CHARGE_MAX;
}
/**
* Return whether ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected */
if (!system_is_in_rw() && system_is_locked())
return 0;
else
return supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_PROPRIETARY;
}
/**
* Return the maximum allowed input current
*/
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
switch (supplier) {
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 1000;
case CHARGE_SUPPLIER_BC12_CDP:
case CHARGE_SUPPLIER_PROPRIETARY:
return sup_curr;
default:
return 500;
}
}
/**
* Return if board is consuming full amount of input current
*/

View File

@@ -20,7 +20,7 @@
#undef CONFIG_ADC_WATCHDOG
#define CONFIG_BOARD_PRE_INIT
#define CONFIG_CHARGE_MANAGER
#define CONFIG_CHARGE_RAMP
#define CONFIG_CHARGE_RAMP_SW
#undef CONFIG_CMD_HASH
#undef CONFIG_CMD_HCDEBUG
#undef CONFIG_CMD_I2C_SCAN

View File

@@ -180,15 +180,6 @@ static void board_chipset_shutdown(void)
}
DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, board_chipset_shutdown, HOOK_PRIO_DEFAULT);
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
/* Use the current limit that was decided by the BQ24392 driver. */
if (supplier == CHARGE_SUPPLIER_OTHER)
return sup_curr;
else
return 500;
}
static void board_init(void)
{
/* Enable TCPC interrupts. */
@@ -198,20 +189,6 @@ static void board_init(void)
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
int board_is_ramp_allowed(int supplier)
{
/* Don't allow ramping in RO when write protected. */
if (!system_is_in_rw() && system_is_locked())
return 0;
/*
* Due to the limitations in the application of the BQ24392, we
* don't quite know exactly what we're plugged into. Therefore,
* the supplier type will be CHARGE_SUPPLIER_OTHER.
*/
return supplier == CHARGE_SUPPLIER_OTHER;
}
void board_reset_pd_mcu(void)
{
/* GPIO_USB_PD_RST_L resets all the TCPCs. */

View File

@@ -35,7 +35,8 @@ common-$(CONFIG_BUTTON_COUNT)+=button.o
common-$(CONFIG_CAPSENSE)+=capsense.o
common-$(CONFIG_CASE_CLOSED_DEBUG_V1)+=ccd_config.o
common-$(CONFIG_CHARGE_MANAGER)+=charge_manager.o
common-$(CONFIG_CHARGE_RAMP)+=charge_ramp.o
common-$(CONFIG_CHARGE_RAMP_HW)+=charge_ramp.o
common-$(CONFIG_CHARGE_RAMP_SW)+=charge_ramp.o charge_ramp_sw.o
common-$(CONFIG_CHARGER)+=charger.o
common-$(CONFIG_CHARGER_PROFILE_OVERRIDE_COMMON)+=charger_profile_override.o
common-$(CONFIG_CHARGER_V2)+=charge_state_v2.o

View File

@@ -324,10 +324,10 @@ static void charge_manager_fill_power_info(int port,
* If ramp is not allowed, max current is just the
* available charge current.
*/
if (board_is_ramp_allowed(sup)) {
if (chg_ramp_allowed(sup)) {
r->meas.current_max = chg_ramp_is_stable() ?
r->meas.current_lim :
board_get_ramp_current_limit(
chg_ramp_max(
sup,
available_charge[sup][port].current);
} else {
@@ -591,10 +591,10 @@ static void charge_manager_refresh(void)
* Allow to set the maximum current value, so the hardware can
* know the range of acceptable current values for its ramping.
*/
if (board_is_ramp_allowed(new_supplier))
if (chg_ramp_allowed(new_supplier))
new_charge_current_uncapped =
board_get_ramp_current_limit(new_supplier,
new_charge_current_uncapped);
chg_ramp_max(new_supplier,
new_charge_current_uncapped);
#endif /* CONFIG_CHARGE_RAMP_HW */
/* Enforce port charge ceiling. */
ceil = charge_manager_get_ceil(new_port);
@@ -619,7 +619,7 @@ static void charge_manager_refresh(void)
#else
#ifdef CONFIG_CHARGE_RAMP_HW
/* Enable or disable charge ramp */
charger_set_hw_ramp(board_is_ramp_allowed(new_supplier));
charger_set_hw_ramp(chg_ramp_allowed(new_supplier));
#endif
board_set_charge_limit(new_port, new_supplier,
new_charge_current,

View File

@@ -1,386 +1,26 @@
/* Copyright 2015 The Chromium OS Authors. All rights reserved.
/* Copyright 2017 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.
*/
/* Charge input current limit ramp module for Chrome EC */
#include "charge_manager.h"
#include "charge_ramp.h"
#include "common.h"
#include "console.h"
#include "ec_commands.h"
#include "task.h"
#include "timer.h"
#include "usb_pd.h"
#include "util.h"
#include "system.h"
#include "usb_charge.h"
#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
/* Number of times to ramp current searching for limit before stable charging */
#define RAMP_COUNT 3
/* Maximum allowable time charger can be unplugged to be considered an OCP */
#define OC_RECOVER_MAX_TIME (SECOND)
/* Delay for running state machine when board is not consuming full current */
#define CURRENT_DRAW_DELAY (5*SECOND)
/* Current ramp increment */
#define RAMP_CURR_INCR_MA 64
#define RAMP_CURR_DELAY (500*MSEC)
#define RAMP_CURR_START_MA 500
/* How much to backoff the input current limit when limit has been found */
#define RAMP_ICL_BACKOFF (2*RAMP_CURR_INCR_MA)
/* Interval at which VBUS voltage is monitored in stable state */
#define STABLE_VBUS_MONITOR_INTERVAL (SECOND)
/* Time to delay for stablizing the charging current */
#define STABLIZE_DELAY (5*SECOND)
enum chg_ramp_state {
CHG_RAMP_DISCONNECTED,
CHG_RAMP_CHARGE_DETECT_DELAY,
CHG_RAMP_OVERCURRENT_DETECT,
CHG_RAMP_RAMP,
CHG_RAMP_STABILIZE,
CHG_RAMP_STABLE,
};
static enum chg_ramp_state ramp_st;
struct oc_info {
timestamp_t ts;
int oc_detected;
int sup;
int icl;
};
/* OCP info for each over-current */
static struct oc_info oc_info[CONFIG_USB_PD_PORT_COUNT][RAMP_COUNT];
static int oc_info_idx[CONFIG_USB_PD_PORT_COUNT];
#define ACTIVE_OC_INFO (oc_info[active_port][oc_info_idx[active_port]])
/* Active charging information */
static int active_port = CHARGE_PORT_NONE;
static int active_sup;
static int active_icl;
static int active_vtg;
static timestamp_t reg_time;
static int stablize_port;
static int stablize_sup;
/* Maximum/minimum input current limit for active charger */
static int max_icl;
static int min_icl;
void chg_ramp_charge_supplier_change(int port, int supplier, int current,
timestamp_t registration_time, int voltage)
test_mockable int chg_ramp_allowed(int supplier)
{
/*
* If the last active port was a valid port and the port
* has changed, then this may have been an over-current.
*/
if (active_port != CHARGE_PORT_NONE &&
port != active_port) {
if (oc_info_idx[active_port] == RAMP_COUNT - 1)
oc_info_idx[active_port] = 0;
else
oc_info_idx[active_port]++;
ACTIVE_OC_INFO.ts = get_time();
ACTIVE_OC_INFO.sup = active_sup;
ACTIVE_OC_INFO.icl = active_icl;
}
/* Don't allow ramping in RO when write protected. */
if (!system_is_in_rw() && system_is_locked())
return 0;
/* Set new active port, set ramp state, and wake ramp task */
active_port = port;
active_sup = supplier;
active_vtg = voltage;
/* Set min and max input current limit based on if ramp is allowed */
if (board_is_ramp_allowed(active_sup)) {
min_icl = RAMP_CURR_START_MA;
max_icl = board_get_ramp_current_limit(active_sup, current);
} else {
min_icl = max_icl = current;
}
reg_time = registration_time;
if (ramp_st != CHG_RAMP_STABILIZE) {
ramp_st = (active_port == CHARGE_PORT_NONE) ?
CHG_RAMP_DISCONNECTED : CHG_RAMP_CHARGE_DETECT_DELAY;
CPRINTS("Ramp reset: st%d", ramp_st);
task_wake(TASK_ID_CHG_RAMP);
}
/* Othewise ask the BC1.2 detect module */
return usb_charger_ramp_allowed(supplier);
}
int chg_ramp_get_current_limit(void)
test_mockable int chg_ramp_max(int supplier, int sup_curr)
{
/*
* If we are ramping or stable, then use the active input
* current limit. Otherwise, use the minimum input current
* limit.
*/
switch (ramp_st) {
case CHG_RAMP_RAMP:
case CHG_RAMP_STABILIZE:
case CHG_RAMP_STABLE:
return active_icl;
default:
return min_icl;
}
/* Ask the BC1.2 detect module */
return usb_charger_ramp_max(supplier, sup_curr);
}
int chg_ramp_is_detected(void)
{
/* Charger detected (charge detect delay has passed) */
return ramp_st > CHG_RAMP_CHARGE_DETECT_DELAY;
}
int chg_ramp_is_stable(void)
{
return ramp_st == CHG_RAMP_STABLE;
}
void chg_ramp_task(void *u)
{
int task_wait_time = -1;
int i, lim;
uint64_t detect_end_time_us = 0, time_us;
int last_active_port = CHARGE_PORT_NONE;
/*
* Static initializer so that we don't clobber early calls to this
* module.
*/
static enum chg_ramp_state ramp_st_prev = CHG_RAMP_DISCONNECTED,
ramp_st_new = CHG_RAMP_DISCONNECTED;
int active_icl_new;
static uint8_t values_have_changed_at_least_once;
/* Clear last OCP supplier to guarantee we ramp on first connect */
for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
oc_info[i][0].sup = CHARGE_SUPPLIER_NONE;
while (1) {
ramp_st_new = ramp_st;
active_icl_new = active_icl;
switch (ramp_st) {
case CHG_RAMP_DISCONNECTED:
/* Do nothing */
task_wait_time = -1;
break;
case CHG_RAMP_CHARGE_DETECT_DELAY:
/* Delay for charge_manager to determine supplier */
/*
* On entry to state, or if port changes, check
* timestamps to determine if this was likely an
* OC event (check if we lost VBUS and it came back
* within OC_RECOVER_MAX_TIME).
*/
if (ramp_st_prev != ramp_st ||
active_port != last_active_port) {
last_active_port = active_port;
if (reg_time.val <
ACTIVE_OC_INFO.ts.val +
OC_RECOVER_MAX_TIME) {
ACTIVE_OC_INFO.oc_detected = 1;
} else {
for (i = 0; i < RAMP_COUNT; ++i)
oc_info[active_port][i].
oc_detected = 0;
}
detect_end_time_us = get_time().val +
CHARGE_DETECT_DELAY;
task_wait_time = CHARGE_DETECT_DELAY;
break;
}
/* If detect delay has not passed, set wait time */
time_us = get_time().val;
if (time_us < detect_end_time_us) {
task_wait_time = detect_end_time_us - time_us;
break;
}
/* Detect delay is over, fall through to next state */
ramp_st_new = CHG_RAMP_OVERCURRENT_DETECT;
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
case CHG_RAMP_OVERCURRENT_DETECT:
/* Check if we should ramp or go straight to stable */
task_wait_time = SECOND;
/* Skip ramp for specific suppliers */
if (!board_is_ramp_allowed(active_sup)) {
active_icl_new = min_icl;
ramp_st_new = CHG_RAMP_STABLE;
break;
}
/*
* If we are not drawing full charge, then don't ramp,
* just wait in this state, until we are.
*/
if (!board_is_consuming_full_charge()) {
task_wait_time = CURRENT_DRAW_DELAY;
break;
}
/*
* Compare recent OCP events, if all info matches,
* then we don't need to ramp anymore.
*/
for (i = 0; i < RAMP_COUNT; i++) {
if (oc_info[active_port][i].sup != active_sup ||
!oc_info[active_port][i].oc_detected)
break;
}
if (i == RAMP_COUNT) {
/* Found OC threshold! */
active_icl_new = ACTIVE_OC_INFO.icl -
RAMP_ICL_BACKOFF;
ramp_st_new = CHG_RAMP_STABLE;
} else {
/*
* Need to ramp to find OC threshold, start
* at the minimum input current limit.
*/
active_icl_new = min_icl;
ramp_st_new = CHG_RAMP_RAMP;
}
break;
case CHG_RAMP_RAMP:
/* Keep ramping until we find the limit */
task_wait_time = RAMP_CURR_DELAY;
/* Pause ramping if we are not drawing full current */
if (!board_is_consuming_full_charge()) {
task_wait_time = CURRENT_DRAW_DELAY;
break;
}
/* If VBUS is sagging a lot, then stop ramping */
if (board_is_vbus_too_low(active_port,
CHG_RAMP_VBUS_RAMPING)) {
CPRINTS("VBUS low");
active_icl_new = MAX(min_icl, active_icl -
RAMP_ICL_BACKOFF);
ramp_st_new = CHG_RAMP_STABILIZE;
task_wait_time = STABLIZE_DELAY;
stablize_port = active_port;
stablize_sup = active_sup;
break;
}
/* Ramp the current limit if we haven't reached max */
if (active_icl == max_icl)
ramp_st_new = CHG_RAMP_STABLE;
else if (active_icl + RAMP_CURR_INCR_MA > max_icl)
active_icl_new = max_icl;
else
active_icl_new = active_icl + RAMP_CURR_INCR_MA;
break;
case CHG_RAMP_STABILIZE:
/* Wait for current to stabilize after ramp is done */
/* Use default delay for exiting this state */
task_wait_time = SECOND;
if (active_port == stablize_port &&
active_sup == stablize_sup) {
ramp_st_new = CHG_RAMP_STABLE;
break;
}
ramp_st_new = active_port == CHARGE_PORT_NONE ?
CHG_RAMP_DISCONNECTED :
CHG_RAMP_CHARGE_DETECT_DELAY;
break;
case CHG_RAMP_STABLE:
/* Maintain input current limit */
/* On entry log charging stats */
if (ramp_st_prev != ramp_st) {
#ifdef CONFIG_USB_PD_LOGGING
charge_manager_save_log(active_port);
#endif
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
}
/* Keep an eye on VBUS and restart ramping if it dips */
if (board_is_ramp_allowed(active_sup) &&
board_is_vbus_too_low(active_port,
CHG_RAMP_VBUS_STABLE)) {
CPRINTS("VBUS low; Re-ramp");
max_icl = MAX(min_icl,
max_icl - RAMP_ICL_BACKOFF);
active_icl_new = min_icl;
ramp_st_new = CHG_RAMP_RAMP;
}
task_wait_time = STABLE_VBUS_MONITOR_INTERVAL;
break;
}
if (ramp_st != ramp_st_new || active_icl != active_icl_new) {
CPRINTS("Ramp p%d st%d %dmA %dmA",
active_port, ramp_st_new, min_icl,
active_icl_new);
values_have_changed_at_least_once = 1;
}
ramp_st_prev = ramp_st;
ramp_st = ramp_st_new;
active_icl = active_icl_new;
/*
* Don't perform any action unless something has changed.
* Otherwise, when the task starts, we may try and set a current
* limit that's invalid/uninitialized.
*/
if (values_have_changed_at_least_once) {
/* Set the input current limit */
lim = chg_ramp_get_current_limit();
board_set_charge_limit(active_port, active_sup, lim,
lim, active_vtg);
}
if (ramp_st == CHG_RAMP_STABILIZE)
/*
* When in stabilize state, supplier/port may change
* and we don't want to wake up task until we have
* slept this amount of time.
*/
usleep(task_wait_time);
else
task_wait_event(task_wait_time);
}
}
#ifdef CONFIG_CMD_CHGRAMP
static int command_chgramp(int argc, char **argv)
{
int i;
int port;
ccprintf("Chg Ramp:\nState: %d\nMin ICL: %d\nActive ICL: %d\n",
ramp_st, min_icl, active_icl);
for (port = 0; port < CONFIG_USB_PD_PORT_COUNT; port++) {
ccprintf("Port %d:\n", port);
ccprintf(" OC idx:%d\n", oc_info_idx[port]);
for (i = 0; i < RAMP_COUNT; i++) {
ccprintf(" OC %d: s%d oc_det%d icl%d\n", i,
oc_info[port][i].sup,
oc_info[port][i].oc_detected,
oc_info[port][i].icl);
}
}
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(chgramp, command_chgramp,
"",
"Dump charge ramp state info");
#endif

385
common/charge_ramp_sw.c Normal file
View File

@@ -0,0 +1,385 @@
/* Copyright 2017 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.
*/
/* Charge input current limit ramp module for Chrome EC */
#include "charge_manager.h"
#include "charge_ramp.h"
#include "common.h"
#include "console.h"
#include "ec_commands.h"
#include "task.h"
#include "timer.h"
#include "usb_pd.h"
#include "util.h"
#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
/* Number of times to ramp current searching for limit before stable charging */
#define RAMP_COUNT 3
/* Maximum allowable time charger can be unplugged to be considered an OCP */
#define OC_RECOVER_MAX_TIME (SECOND)
/* Delay for running state machine when board is not consuming full current */
#define CURRENT_DRAW_DELAY (5*SECOND)
/* Current ramp increment */
#define RAMP_CURR_INCR_MA 64
#define RAMP_CURR_DELAY (500*MSEC)
#define RAMP_CURR_START_MA 500
/* How much to backoff the input current limit when limit has been found */
#define RAMP_ICL_BACKOFF (2*RAMP_CURR_INCR_MA)
/* Interval at which VBUS voltage is monitored in stable state */
#define STABLE_VBUS_MONITOR_INTERVAL (SECOND)
/* Time to delay for stablizing the charging current */
#define STABLIZE_DELAY (5*SECOND)
enum chg_ramp_state {
CHG_RAMP_DISCONNECTED,
CHG_RAMP_CHARGE_DETECT_DELAY,
CHG_RAMP_OVERCURRENT_DETECT,
CHG_RAMP_RAMP,
CHG_RAMP_STABILIZE,
CHG_RAMP_STABLE,
};
static enum chg_ramp_state ramp_st;
struct oc_info {
timestamp_t ts;
int oc_detected;
int sup;
int icl;
};
/* OCP info for each over-current */
static struct oc_info oc_info[CONFIG_USB_PD_PORT_COUNT][RAMP_COUNT];
static int oc_info_idx[CONFIG_USB_PD_PORT_COUNT];
#define ACTIVE_OC_INFO (oc_info[active_port][oc_info_idx[active_port]])
/* Active charging information */
static int active_port = CHARGE_PORT_NONE;
static int active_sup;
static int active_icl;
static int active_vtg;
static timestamp_t reg_time;
static int stablize_port;
static int stablize_sup;
/* Maximum/minimum input current limit for active charger */
static int max_icl;
static int min_icl;
void chg_ramp_charge_supplier_change(int port, int supplier, int current,
timestamp_t registration_time, int voltage)
{
/*
* If the last active port was a valid port and the port
* has changed, then this may have been an over-current.
*/
if (active_port != CHARGE_PORT_NONE &&
port != active_port) {
if (oc_info_idx[active_port] == RAMP_COUNT - 1)
oc_info_idx[active_port] = 0;
else
oc_info_idx[active_port]++;
ACTIVE_OC_INFO.ts = get_time();
ACTIVE_OC_INFO.sup = active_sup;
ACTIVE_OC_INFO.icl = active_icl;
}
/* Set new active port, set ramp state, and wake ramp task */
active_port = port;
active_sup = supplier;
active_vtg = voltage;
/* Set min and max input current limit based on if ramp is allowed */
if (chg_ramp_allowed(active_sup)) {
min_icl = RAMP_CURR_START_MA;
max_icl = chg_ramp_max(active_sup, current);
} else {
min_icl = max_icl = current;
}
reg_time = registration_time;
if (ramp_st != CHG_RAMP_STABILIZE) {
ramp_st = (active_port == CHARGE_PORT_NONE) ?
CHG_RAMP_DISCONNECTED : CHG_RAMP_CHARGE_DETECT_DELAY;
CPRINTS("Ramp reset: st%d", ramp_st);
task_wake(TASK_ID_CHG_RAMP);
}
}
int chg_ramp_get_current_limit(void)
{
/*
* If we are ramping or stable, then use the active input
* current limit. Otherwise, use the minimum input current
* limit.
*/
switch (ramp_st) {
case CHG_RAMP_RAMP:
case CHG_RAMP_STABILIZE:
case CHG_RAMP_STABLE:
return active_icl;
default:
return min_icl;
}
}
int chg_ramp_is_detected(void)
{
/* Charger detected (charge detect delay has passed) */
return ramp_st > CHG_RAMP_CHARGE_DETECT_DELAY;
}
int chg_ramp_is_stable(void)
{
return ramp_st == CHG_RAMP_STABLE;
}
void chg_ramp_task(void *u)
{
int task_wait_time = -1;
int i, lim;
uint64_t detect_end_time_us = 0, time_us;
int last_active_port = CHARGE_PORT_NONE;
/*
* Static initializer so that we don't clobber early calls to this
* module.
*/
static enum chg_ramp_state ramp_st_prev = CHG_RAMP_DISCONNECTED,
ramp_st_new = CHG_RAMP_DISCONNECTED;
int active_icl_new;
static uint8_t values_have_changed_at_least_once;
/* Clear last OCP supplier to guarantee we ramp on first connect */
for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
oc_info[i][0].sup = CHARGE_SUPPLIER_NONE;
while (1) {
ramp_st_new = ramp_st;
active_icl_new = active_icl;
switch (ramp_st) {
case CHG_RAMP_DISCONNECTED:
/* Do nothing */
task_wait_time = -1;
break;
case CHG_RAMP_CHARGE_DETECT_DELAY:
/* Delay for charge_manager to determine supplier */
/*
* On entry to state, or if port changes, check
* timestamps to determine if this was likely an
* OC event (check if we lost VBUS and it came back
* within OC_RECOVER_MAX_TIME).
*/
if (ramp_st_prev != ramp_st ||
active_port != last_active_port) {
last_active_port = active_port;
if (reg_time.val <
ACTIVE_OC_INFO.ts.val +
OC_RECOVER_MAX_TIME) {
ACTIVE_OC_INFO.oc_detected = 1;
} else {
for (i = 0; i < RAMP_COUNT; ++i)
oc_info[active_port][i].
oc_detected = 0;
}
detect_end_time_us = get_time().val +
CHARGE_DETECT_DELAY;
task_wait_time = CHARGE_DETECT_DELAY;
break;
}
/* If detect delay has not passed, set wait time */
time_us = get_time().val;
if (time_us < detect_end_time_us) {
task_wait_time = detect_end_time_us - time_us;
break;
}
/* Detect delay is over, fall through to next state */
ramp_st_new = CHG_RAMP_OVERCURRENT_DETECT;
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
case CHG_RAMP_OVERCURRENT_DETECT:
/* Check if we should ramp or go straight to stable */
task_wait_time = SECOND;
/* Skip ramp for specific suppliers */
if (!chg_ramp_allowed(active_sup)) {
active_icl_new = min_icl;
ramp_st_new = CHG_RAMP_STABLE;
break;
}
/*
* If we are not drawing full charge, then don't ramp,
* just wait in this state, until we are.
*/
if (!board_is_consuming_full_charge()) {
task_wait_time = CURRENT_DRAW_DELAY;
break;
}
/*
* Compare recent OCP events, if all info matches,
* then we don't need to ramp anymore.
*/
for (i = 0; i < RAMP_COUNT; i++) {
if (oc_info[active_port][i].sup != active_sup ||
!oc_info[active_port][i].oc_detected)
break;
}
if (i == RAMP_COUNT) {
/* Found OC threshold! */
active_icl_new = ACTIVE_OC_INFO.icl -
RAMP_ICL_BACKOFF;
ramp_st_new = CHG_RAMP_STABLE;
} else {
/*
* Need to ramp to find OC threshold, start
* at the minimum input current limit.
*/
active_icl_new = min_icl;
ramp_st_new = CHG_RAMP_RAMP;
}
break;
case CHG_RAMP_RAMP:
/* Keep ramping until we find the limit */
task_wait_time = RAMP_CURR_DELAY;
/* Pause ramping if we are not drawing full current */
if (!board_is_consuming_full_charge()) {
task_wait_time = CURRENT_DRAW_DELAY;
break;
}
/* If VBUS is sagging a lot, then stop ramping */
if (board_is_vbus_too_low(active_port,
CHG_RAMP_VBUS_RAMPING)) {
CPRINTS("VBUS low");
active_icl_new = MAX(min_icl, active_icl -
RAMP_ICL_BACKOFF);
ramp_st_new = CHG_RAMP_STABILIZE;
task_wait_time = STABLIZE_DELAY;
stablize_port = active_port;
stablize_sup = active_sup;
break;
}
/* Ramp the current limit if we haven't reached max */
if (active_icl == max_icl)
ramp_st_new = CHG_RAMP_STABLE;
else if (active_icl + RAMP_CURR_INCR_MA > max_icl)
active_icl_new = max_icl;
else
active_icl_new = active_icl + RAMP_CURR_INCR_MA;
break;
case CHG_RAMP_STABILIZE:
/* Wait for current to stabilize after ramp is done */
/* Use default delay for exiting this state */
task_wait_time = SECOND;
if (active_port == stablize_port &&
active_sup == stablize_sup) {
ramp_st_new = CHG_RAMP_STABLE;
break;
}
ramp_st_new = active_port == CHARGE_PORT_NONE ?
CHG_RAMP_DISCONNECTED :
CHG_RAMP_CHARGE_DETECT_DELAY;
break;
case CHG_RAMP_STABLE:
/* Maintain input current limit */
/* On entry log charging stats */
if (ramp_st_prev != ramp_st) {
#ifdef CONFIG_USB_PD_LOGGING
charge_manager_save_log(active_port);
#endif
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
}
/* Keep an eye on VBUS and restart ramping if it dips */
if (chg_ramp_allowed(active_sup) &&
board_is_vbus_too_low(active_port,
CHG_RAMP_VBUS_STABLE)) {
CPRINTS("VBUS low; Re-ramp");
max_icl = MAX(min_icl,
max_icl - RAMP_ICL_BACKOFF);
active_icl_new = min_icl;
ramp_st_new = CHG_RAMP_RAMP;
}
task_wait_time = STABLE_VBUS_MONITOR_INTERVAL;
break;
}
if (ramp_st != ramp_st_new || active_icl != active_icl_new) {
CPRINTS("Ramp p%d st%d %dmA %dmA",
active_port, ramp_st_new, min_icl,
active_icl_new);
values_have_changed_at_least_once = 1;
}
ramp_st_prev = ramp_st;
ramp_st = ramp_st_new;
active_icl = active_icl_new;
/*
* Don't perform any action unless something has changed.
* Otherwise, when the task starts, we may try and set a current
* limit that's invalid/uninitialized.
*/
if (values_have_changed_at_least_once) {
/* Set the input current limit */
lim = chg_ramp_get_current_limit();
board_set_charge_limit(active_port, active_sup, lim,
lim, active_vtg);
}
if (ramp_st == CHG_RAMP_STABILIZE)
/*
* When in stabilize state, supplier/port may change
* and we don't want to wake up task until we have
* slept this amount of time.
*/
usleep(task_wait_time);
else
task_wait_event(task_wait_time);
}
}
#ifdef CONFIG_CMD_CHGRAMP
static int command_chgramp(int argc, char **argv)
{
int i;
int port;
ccprintf("Chg Ramp:\nState: %d\nMin ICL: %d\nActive ICL: %d\n",
ramp_st, min_icl, active_icl);
for (port = 0; port < CONFIG_USB_PD_PORT_COUNT; port++) {
ccprintf("Port %d:\n", port);
ccprintf(" OC idx:%d\n", oc_info_idx[port]);
for (i = 0; i < RAMP_COUNT; i++) {
ccprintf(" OC %d: s%d oc_det%d icl%d\n", i,
oc_info[port][i].sup,
oc_info[port][i].oc_detected,
oc_info[port][i].icl);
}
}
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(chgramp, command_chgramp,
"",
"Dump charge ramp state info");
#endif

View File

@@ -52,7 +52,7 @@ static void bc12_detect(const int port)
gpio_set_level(pin_tbl[port].chip_enable, 1);
new_chg.voltage = USB_CHARGER_VOLTAGE_MV;
#if defined(CONFIG_CHARGE_RAMP) || defined(CONFIG_CHARGE_RAMP_HW)
#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW)
/*
* Apple or TomTom charger detection can take as long as 600ms. Wait a
* little bit longer for margin.
@@ -73,7 +73,7 @@ static void bc12_detect(const int port)
* charging port (DCP) which can only supply 500mA.
*/
new_chg.current = 500;
#endif /* !defined(CONFIG_CHARGE_RAMP && CONFIG_CHARGE_RAMP_HW) */
#endif /* !defined(CONFIG_CHARGE_RAMP_SW && CONFIG_CHARGE_RAMP_HW) */
charge_manager_update_charge(CHARGE_SUPPLIER_OTHER, port, &new_chg);
}
@@ -136,3 +136,24 @@ void usb_charger_set_switches(int port, enum usb_switch setting)
{
/* The BQ24392 automatically sets up the USB 2.0 high-speed switches. */
}
#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW)
int usb_charger_ramp_allowed(int supplier)
{
/*
* Due to the limitations in the application of the BQ24392, we
* don't quite know exactly what we're plugged into. Therefore,
* the supplier type will be CHARGE_SUPPLIER_OTHER.
*/
return supplier == CHARGE_SUPPLIER_OTHER;
}
int usb_charger_ramp_max(int supplier, int sup_curr)
{
/* Use the current limit that was decided by the BQ24392. */
if (supplier == CHARGE_SUPPLIER_OTHER)
return sup_curr;
else
return 500;
}
#endif /* CONFIG_CHARGE_RAMP_SW || CONFIG_CHARGE_RAMP_HW */

View File

@@ -431,3 +431,28 @@ void usb_charger_task(void *u)
}
}
}
#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW)
int usb_charger_ramp_allowed(int supplier)
{
return supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_PROPRIETARY;
}
int usb_charger_ramp_max(int supplier, int sup_curr)
{
switch (supplier) {
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 1000;
case CHARGE_SUPPLIER_BC12_CDP:
case CHARGE_SUPPLIER_PROPRIETARY:
return sup_curr;
default:
return 500;
}
}
#endif /* CONFIG_CHARGE_RAMP_SW || CONFIG_CHARGE_RAMP_HW */

View File

@@ -60,7 +60,31 @@ static enum usb_switch usb_switch_state[BD9995X_CHARGE_PORT_COUNT] = {
USB_SWITCH_DISCONNECT,
USB_SWITCH_DISCONNECT,
};
static int bd9995x_get_bc12_ilim(int charge_supplier)
{
switch (charge_supplier) {
case CHARGE_SUPPLIER_BC12_CDP:
return 1500;
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 900;
case CHARGE_SUPPLIER_OTHER:
#ifdef CONFIG_CHARGE_RAMP_SW
return 2400;
#else
/*
* Setting the higher limit of current may result in an
* anti-collapse hence limiting the current to 1A.
*/
return 1000;
#endif
default:
return 500;
}
}
#endif /* HAS_TASK_USB_CHG */
static inline int ch_raw_read16(int cmd, int *param,
enum bd9995x_command map_cmd)
@@ -482,6 +506,21 @@ static int usb_charger_process(enum bd9995x_charge_port port)
/* No need for the task to schedule a wait event */
return 0;
}
#ifdef CONFIG_CHARGE_RAMP_SW
int usb_charger_ramp_allowed(int supplier)
{
return supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP ||
supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_OTHER;
}
int usb_charger_ramp_max(int supplier, int sup_curr)
{
return bd9995x_get_bc12_ilim(supplier);
}
#endif /* CONFIG_CHARGE_RAMP_SW */
#endif /* HAS_TASK_USB_CHG */
/* chip specific interfaces */
@@ -1036,30 +1075,6 @@ int bd9995x_get_battery_voltage(void)
}
#ifdef HAS_TASK_USB_CHG
int bd9995x_get_bc12_ilim(int charge_supplier)
{
switch (charge_supplier) {
case CHARGE_SUPPLIER_BC12_CDP:
return 1500;
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 900;
case CHARGE_SUPPLIER_OTHER:
#ifdef CONFIG_CHARGE_RAMP
return 2400;
#else
/*
* Setting the higher limit of current may result in an
* anti-collapse hence limiting the current to 1A.
*/
return 1000;
#endif
default:
return 500;
}
}
int bd9995x_bc12_enable_charging(enum bd9995x_charge_port port, int enable)
{
int rv;

View File

@@ -345,8 +345,6 @@ static inline enum bd9995x_charge_port bd9995x_pd_port_to_chg_port(int port)
int bd9995x_is_vbus_provided(enum bd9995x_charge_port port);
/* Select or deselect input port from {VCC, VBUS, VCC&VBUS}. */
int bd9995x_select_input_port(enum bd9995x_charge_port port, int select);
/* Get input current limit for BC1.2 suppliers */
int bd9995x_get_bc12_ilim(int charge_supplier);
/* Enable/Disable charging triggered by BC1.2 */
int bd9995x_bc12_enable_charging(enum bd9995x_charge_port port, int enable);
/* Interrupt handler for USB charger VBUS */

View File

@@ -16,25 +16,6 @@ enum chg_ramp_vbus_state {
CHG_RAMP_VBUS_STABLE
};
/**
* Check if ramping is allowed for given supplier
*
* @supplier Supplier to check
*
* @return Ramping is allowed for given supplier
*/
int board_is_ramp_allowed(int supplier);
/**
* Get the maximum current limit that we are allowed to ramp to
*
* @supplier Active supplier type
* @sup_curr Input current limit based on supplier
*
* @return Maximum current in mA
*/
int board_get_ramp_current_limit(int supplier, int sup_curr);
/**
* Check if board is consuming full input current
*
@@ -52,6 +33,25 @@ int board_is_consuming_full_charge(void);
*/
int board_is_vbus_too_low(int port, enum chg_ramp_vbus_state ramp_state);
/**
* Check if ramping is allowed for given supplier
*
* @supplier Supplier to check
*
* @return Ramping is allowed for given supplier
*/
int chg_ramp_allowed(int supplier);
/**
* Get the maximum current limit that we are allowed to ramp to
*
* @supplier Active supplier type
* @sup_curr Input current limit based on supplier
*
* @return Maximum current in mA
*/
int chg_ramp_max(int supplier, int sup_curr);
/**
* Get the input current limit set by ramp module
*

View File

@@ -434,12 +434,12 @@
/* Handle the external power limit host command in charge manager */
#undef CONFIG_CHARGE_MANAGER_EXTERNAL_POWER_LIMIT
/* Compile input current ramping support */
#undef CONFIG_CHARGE_RAMP
/* The hardware has some input current ramping/back-off mechanism */
#undef CONFIG_CHARGE_RAMP_HW
/* Compile input current ramping support using software control */
#undef CONFIG_CHARGE_RAMP_SW
/*****************************************************************************/
/* Charger config */

View File

@@ -88,4 +88,22 @@ void usb_charger_set_switches(int port, enum usb_switch setting);
*/
void usb_charger_vbus_change(int port, int vbus_level);
/**
* Check if ramping is allowed for given supplier
*
* @supplier Supplier to check
*
* @return Ramping is allowed for given supplier
*/
int usb_charger_ramp_allowed(int supplier);
/**
* Get the maximum current limit that we are allowed to ramp to
*
* @supplier Active supplier type
* @sup_curr Input current limit based on supplier
*
* @return Maximum current in mA
*/
int usb_charger_ramp_max(int supplier, int sup_curr);
#endif /* __CROS_EC_USB_CHARGE_H */

View File

@@ -36,12 +36,34 @@ static int charge_limit_ma;
/* Mock functions */
int board_is_ramp_allowed(int supplier)
/* Override test_mockable implementations in charge_ramp module */
int chg_ramp_allowed(int supplier)
{
/* Ramp for TEST4-TEST8 */
return supplier > CHARGE_SUPPLIER_TEST3;
}
int chg_ramp_max(int supplier, int sup_curr)
{
if (supplier == CHARGE_SUPPLIER_TEST7)
return 1600;
else if (supplier == CHARGE_SUPPLIER_TEST8)
return 2400;
else
return 3000;
}
/* These usb_charger functions are unused, but necessary to link */
int usb_charger_ramp_allowed(int supplier)
{
return 0;
}
int usb_charger_ramp_max(int supplier, int sup_curr)
{
return 0;
}
int board_is_consuming_full_charge(void)
{
return charge_limit_ma <= system_load_current_ma;
@@ -61,16 +83,6 @@ void board_set_charge_limit(int port, int supplier, int limit_ma,
task_set_event(TASK_ID_TEST_RUNNER, TASK_EVENT_OVERCURRENT, 0);
}
int board_get_ramp_current_limit(int supplier, int sup_curr)
{
if (supplier == CHARGE_SUPPLIER_TEST7)
return 1600;
else if (supplier == CHARGE_SUPPLIER_TEST8)
return 2400;
else
return 3000;
}
/* Test utilities */
static void plug_charger_with_ts(int supplier_type, int port, int min_current,

View File

@@ -195,7 +195,7 @@ int ncp15wb_calculate_temp(uint16_t adc);
#endif
#ifdef TEST_CHARGE_RAMP
#define CONFIG_CHARGE_RAMP
#define CONFIG_CHARGE_RAMP_SW
#define CONFIG_USB_PD_PORT_COUNT 2
#endif