96 lines
2.5 KiB
C
96 lines
2.5 KiB
C
|
/* Copyright 2019 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 "charger_mt6370.h"
|
||
|
#include "console.h"
|
||
|
#include "driver/tcpm/mt6370.h"
|
||
|
#include "driver/charger/rt946x.h"
|
||
|
#include "hooks.h"
|
||
|
#include "power.h"
|
||
|
#include "usb_pd.h"
|
||
|
#include "util.h"
|
||
|
|
||
|
#define BAT_LEVEL_PD_LIMIT 85
|
||
|
|
||
|
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
|
||
|
|
||
|
#ifndef CONFIG_BATTERY_SMART
|
||
|
int board_cut_off_battery(void)
|
||
|
{
|
||
|
/* The cut-off procedure is recommended by Richtek. b/116682788 */
|
||
|
rt946x_por_reset();
|
||
|
mt6370_vconn_discharge(0);
|
||
|
rt946x_cutoff_battery();
|
||
|
|
||
|
return EC_SUCCESS;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void mt6370_charger_profile_override(struct charge_state_data *curr)
|
||
|
{
|
||
|
static int previous_chg_limit_mv;
|
||
|
int chg_limit_mv;
|
||
|
|
||
|
/* Limit input (=VBUS) to 5V when soc > 85% and charge current < 1A. */
|
||
|
if (!(curr->batt.flags & BATT_FLAG_BAD_CURRENT) &&
|
||
|
charge_get_percent() > BAT_LEVEL_PD_LIMIT &&
|
||
|
curr->batt.current < 1000) {
|
||
|
chg_limit_mv = 5500;
|
||
|
} else if (power_get_state() == POWER_S0) {
|
||
|
/*
|
||
|
* b/134227872: limit power to 5V/2A in S0 to prevent
|
||
|
* overheat
|
||
|
*/
|
||
|
chg_limit_mv = 5500;
|
||
|
} else {
|
||
|
chg_limit_mv = PD_MAX_VOLTAGE_MV;
|
||
|
}
|
||
|
|
||
|
if (chg_limit_mv != previous_chg_limit_mv)
|
||
|
CPRINTS("VBUS limited to %dmV", chg_limit_mv);
|
||
|
previous_chg_limit_mv = chg_limit_mv;
|
||
|
|
||
|
/* Pull down VBUS */
|
||
|
if (pd_get_max_voltage() != chg_limit_mv)
|
||
|
pd_set_external_voltage_limit(0, chg_limit_mv);
|
||
|
|
||
|
/*
|
||
|
* When the charger says it's done charging, even if fuel gauge says
|
||
|
* SOC < BATTERY_LEVEL_NEAR_FULL, we'll overwrite SOC with
|
||
|
* BATTERY_LEVEL_NEAR_FULL. So we can ensure both Chrome OS UI
|
||
|
* and battery LED indicate full charge.
|
||
|
*/
|
||
|
if (rt946x_is_charge_done()) {
|
||
|
curr->batt.state_of_charge = MAX(BATTERY_LEVEL_NEAR_FULL,
|
||
|
curr->batt.state_of_charge);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
static void board_charge_termination(void)
|
||
|
{
|
||
|
static uint8_t te;
|
||
|
/* Enable charge termination when we are sure battery is present. */
|
||
|
if (!te && battery_is_present() == BP_YES) {
|
||
|
if (!rt946x_enable_charge_termination(1))
|
||
|
te = 1;
|
||
|
}
|
||
|
}
|
||
|
DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE,
|
||
|
board_charge_termination,
|
||
|
HOOK_PRIO_DEFAULT);
|
||
|
|
||
|
void board_set_charge_limit(int port, int supplier, int charge_ma,
|
||
|
int max_ma, int charge_mv)
|
||
|
{
|
||
|
/* b/134227872: Limit input current to 2A in S0 to prevent overheat */
|
||
|
if (power_get_state() == POWER_S0)
|
||
|
charge_set_input_current_limit(MIN(charge_ma, 2000), charge_mv);
|
||
|
else
|
||
|
charge_set_input_current_limit(
|
||
|
MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT),
|
||
|
charge_mv);
|
||
|
}
|